Beispiel #1
0
 /** Allocate relations for SubsetSig top-down. */
 private Expression allocateSubsetSig(SubsetSig sig) throws Err {
   // We must not visit the same SubsetSig more than once, so if we've been here already, then
   // return the old value right away
   Expression sum = sol.a2k(sig);
   if (sum != null && sum != Expression.NONE) return sum;
   // Recursively form the union of all parent expressions
   TupleSet ts = factory.noneOf(1);
   for (Sig parent : sig.parents) {
     Expression p =
         (parent instanceof PrimSig) ? sol.a2k(parent) : allocateSubsetSig((SubsetSig) parent);
     ts.addAll(sol.query(true, p, false));
     if (sum == null) sum = p;
     else sum = sum.union(p);
   }
   // If subset is exact, then just use the "sum" as is
   if (sig.exact) {
     sol.addSig(sig, sum);
     return sum;
   }
   // Allocate a relation for this subset sig, then bound it
   rep.bound("Sig " + sig + " in " + ts + "\n");
   Relation r = sol.addRel(sig.label, null, ts);
   sol.addSig(sig, r);
   // Add a constraint that it is INDEED a subset of the union of its parents
   sol.addFormula(r.in(sum), sig.isSubset);
   return r;
 }
 /** Prints the given solution using the given options to the console */
 void print(Instance instance, Options options) {
   final Evaluator eval = new Evaluator(instance, options);
   final int n = instance.tuples(queen).size();
   for (int i = 0; i < n; i++) {
     Expression ci = IntConstant.constant(i).toExpression();
     for (int j = 0; j < n; j++) {
       Expression cj = IntConstant.constant(j).toExpression();
       if (eval.evaluate(x.join(ci).intersection(y.join(cj)).some())) {
         System.out.print(" Q");
       } else {
         System.out.print(" .");
       }
     }
     System.out.println();
   }
   //		System.out.println(instance);
 }
  @Test
  public final void testTotalOrdering() {
    bounds.bound(to1, factory.area(factory.tuple("0", "0"), factory.tuple("4", "4")));
    bounds.bound(ord1, factory.setOf("0", "1", "2", "3", "4"));
    bounds.bound(first1, bounds.upperBound(ord1));
    bounds.bound(last1, bounds.upperBound(ord1));
    final Formula ordered1 = to1.totalOrder(ord1, first1, last1);
    assertNotNull(solve(to1.some().and(ordered1)));
    assertPrimVarNum(0);
    assertAuxVarNum(0);
    assertClauseNum(0);

    bounds.bound(r1, factory.range(factory.tuple("0"), factory.tuple("4")));
    assertNotNull(solve(to1.join(r1).some().and(ordered1)));
    assertPrimVarNum(bounds.upperBound(r1).size());

    bounds.boundExactly(r1, bounds.upperBound(r1));
    assertNotNull(solve(to1.join(r1).some().and(ordered1)));
    assertPrimVarNum(0);

    bounds.bound(to2, factory.setOf("5", "6", "7", "8", "9").product(factory.setOf("5", "7", "8")));
    bounds.bound(ord2, factory.setOf("5", "7", "8"));
    bounds.bound(first2, bounds.upperBound(ord2));
    bounds.bound(last2, bounds.upperBound(ord2));
    final Formula ordered2 = to2.totalOrder(ord2, first2, last2);
    assertNotNull(solve(to1.difference(to2).some().and(ordered2).and(ordered1)));
    assertPrimVarNum(0);
    assertAuxVarNum(0);
    assertClauseNum(0);

    bounds.bound(to3, factory.allOf(2));
    bounds.bound(ord3, factory.allOf(1));
    bounds.bound(first3, factory.setOf("9"));
    bounds.bound(last3, factory.setOf("8"));
    final Formula ordered3 = to3.totalOrder(ord3, first3, last3);
    assertNotNull(solve(to3.product(to1).some().and(ordered1).and(ordered3)));
    assertPrimVarNum(bounds.upperBound(to3).size() + bounds.upperBound(ord3).size() + 2);

    // SAT solver takes a while
    //		bounds.boundExactly(r2, factory.setOf(factory.tuple("9","8")));
    //		assertNotNull(solve(r2.in(to3).and(ordered3)));
    bounds.bound(to3, factory.allOf(2));
    bounds.bound(ord3, factory.setOf("3"));
    bounds.bound(first3, factory.allOf(1));
    bounds.bound(last3, factory.allOf(1));

    Instance instance = solve(ordered3);
    assertNotNull(instance);
    assertTrue(instance.tuples(to3).isEmpty());
    assertTrue(instance.tuples(ord3).equals(bounds.upperBound(ord3)));
    assertTrue(instance.tuples(first3).equals(bounds.upperBound(ord3)));
    assertTrue(instance.tuples(last3).equals(bounds.upperBound(ord3)));
  }
Beispiel #4
0
 /**
  * Sets the lower and upper bounds for the given relation.
  *
  * @requires lower.tuples in upper.tuples && lower.arity = upper.arity = r.arity && lower.universe
  *     = upper.universe = this.universe
  * @ensures this.relations' = this.relations + r && this.lowerBound' = this.lowerBound ++ r->lower
  *     && this.upperBound' = this.upperBound ++ r->upper
  * @throws NullPointerException r = null || lower = null || upper = null
  * @throws IllegalArgumentException lower.arity != r.arity || upper.arity != r.arity
  * @throws IllegalArgumentException lower.universe != this.universe || upper.universe !=
  *     this.universe
  * @throws IllegalArgumentException lower.tuples !in upper.tuples
  */
 public void bound(Relation r, TupleSet lower, TupleSet upper) {
   if (!upper.containsAll(lower))
     throw new IllegalArgumentException("lower.tuples !in upper.tuples");
   if (upper.size() == lower.size()) {
     // upper.containsAll(lower) && upper.size()==lower.size() => upper.equals(lower)
     boundExactly(r, lower);
   } else {
     checkBound(r.arity(), lower);
     checkBound(r.arity(), upper);
     lowers.put(r, lower.clone().unmodifiableView());
     uppers.put(r, upper.clone().unmodifiableView());
   }
 }
Beispiel #5
0
  /**
   * Returns all facts in the model.
   *
   * @return the facts.
   */
  public final Formula facts() {
    // sig File extends Object {} { some d: Dir | this in d.entries.contents }
    final Variable file = Variable.unary("this");
    final Variable d = Variable.unary("d");
    final Formula f0 =
        file.in(d.join(entries).join(contents)).forSome(d.oneOf(Dir)).forAll(file.oneOf(File));

    //		sig Dir extends Object {
    //			  entries: set DirEntry,
    //			  parent: lone Dir
    //			} {
    //			  parent = this.~@contents.~@entries
    //			  all e1, e2 : entries | e1.name = e2.name => e1 = e2
    //			  this !in this.^@parent
    //			  this != Root => Root in this.^@parent
    //			}

    final Variable dir = Variable.unary("this");
    final Variable e1 = Variable.unary("e1"), e2 = Variable.unary("e2");

    final Formula f1 =
        (dir.join(parent)).eq(dir.join(contents.transpose()).join(entries.transpose()));
    final Expression e0 = dir.join(entries);
    final Formula f2 =
        e1.join(name).eq(e2.join(name)).implies(e1.eq(e2)).forAll(e1.oneOf(e0).and(e2.oneOf(e0)));
    final Formula f3 = dir.in(dir.join(parent.closure())).not();
    final Formula f4 = dir.eq(Root).not().implies(Root.in(dir.join(parent.closure())));
    final Formula f5 = f1.and(f2).and(f3).and(f4).forAll(dir.oneOf(Dir));

    //		one sig Root extends Dir {} { no parent }
    final Formula f6 = Root.join(parent).no();

    //		sig DirEntry {
    //			  name: Name,
    //			  contents: Object
    //			} { one this.~entries }

    final Variable entry = Variable.unary("this");
    final Formula f7 = entry.join(entries.transpose()).one().forAll(entry.oneOf(DirEntry));

    //		fact OneParent {
    //		    // all directories besides root xhave one parent
    //		    all d: Dir - Root | one d.parent
    //		}

    final Formula f8 = d.join(parent).one().forAll(d.oneOf(Dir.difference(Root)));

    return f0.and(f5).and(f6).and(f7).and(f8);
  }
 /** Constructs an instance of BlockedNQueens from the file with the given name. */
 public BlockedNQueens(final String file) {
   this.file = file;
   this.queen = Relation.unary("Queen");
   this.x = Relation.binary("x");
   this.y = Relation.binary("y");
   this.blocked = Relation.binary("blocked");
   this.num = Relation.unary("num");
   this.ord = Relation.binary("ord");
 }
  /**
   * Returns a relational encoding of the problem.
   *
   * @return a relational encoding of the problem.
   */
  public Formula rules() {
    final List<Formula> rules = new ArrayList<Formula>();

    rules.add(x.function(queen, num));
    rules.add(y.function(queen, num));

    final Variable i = Variable.unary("n");
    final Variable q1 = Variable.unary("q1"), q2 = Variable.unary("q2");

    // at most one queen in each row: all i: num | lone x.i

    rules.add(x.join(i).lone().forAll(i.oneOf(num)));

    // at most one queen in each column: all i: num | lone y.i
    rules.add(y.join(i).lone().forAll(i.oneOf(num)));

    // no queen in a blocked position:  all q: Queen | q.x->q.y !in blocked
    rules.add(q1.join(x).product(q1.join(y)).intersection(blocked).no().forAll(q1.oneOf(queen)));

    // at most one queen on each diagonal
    //		all q1: Queen, q2: Queen - q1 |
    //		let xu = prevs[q2.x] + prevs[q1.x],
    //		     xi =  prevs[q2.x] & prevs[q1.x],
    //                yu = prevs[q2.y] + prevs[q1.y],
    //                yi = prevs[q2.y] & prevs[q1.y] |
    //		#(xu - xi) != #(yu - yi)
    final Expression ordClosure = ord.closure();
    final Expression q2xPrevs = ordClosure.join(q2.join(x)), q1xPrevs = ordClosure.join(q1.join(x));
    final Expression q2yPrevs = ordClosure.join(q2.join(y)), q1yPrevs = ordClosure.join(q1.join(y));

    final IntExpression xDiff =
        (q2xPrevs.union(q1xPrevs)).difference(q2xPrevs.intersection(q1xPrevs)).count();
    final IntExpression yDiff =
        (q2yPrevs.union(q1yPrevs)).difference(q2yPrevs.intersection(q1yPrevs)).count();

    rules.add(xDiff.eq(yDiff).not().forAll(q1.oneOf(queen).and(q2.oneOf(queen.difference(q1)))));

    return Formula.and(rules);
  }
Beispiel #8
0
 /**
  * Makes the specified tupleset the upper bound on the contents of the given relation. The lower
  * bound automatically becomen an empty tupleset with the same arity as the relation.
  *
  * @requires upper.arity = r.arity && upper.universe = this.universe
  * @ensures this.relations' = this.relations + r this.lowerBound' = this.lowerBound ++ r->{s:
  *     TupleSet | s.universe = this.universe && s.arity = r.arity && no s.tuples} &&
  *     this.upperBound' = this.upperBound ++ r->upper
  * @throws NullPointerException r = null || upper = null
  * @throws IllegalArgumentException upper.arity != r.arity || upper.universe != this.universe
  */
 public void bound(Relation r, TupleSet upper) {
   checkBound(r.arity(), upper);
   lowers.put(r, factory.noneOf(r.arity()).unmodifiableView());
   uppers.put(r, upper.clone().unmodifiableView());
 }
Beispiel #9
0
 /**
  * Sets both the lower and upper bounds of the given relation to the given set of tuples.
  *
  * @requires tuples.arity = r.arity && tuples.universe = this.universe
  * @ensures this.relations' = this.relations + r this.lowerBound' = this.lowerBound' ++ r->tuples
  *     && this.upperBound' = this.lowerBound' ++ r->tuples
  * @throws NullPointerException r = null || tuples = null
  * @throws IllegalArgumentException tuples.arity != r.arity || tuples.universe != this.universe
  */
 public void boundExactly(Relation r, TupleSet tuples) {
   checkBound(r.arity(), tuples);
   final TupleSet unmodifiableTuplesCopy = tuples.clone().unmodifiableView();
   lowers.put(r, unmodifiableTuplesCopy);
   uppers.put(r, unmodifiableTuplesCopy);
 }
  public static void main(String[] args) throws Exception {

    Relation x0 = Relation.unary("Int/min");
    Relation x1 = Relation.unary("Int/zero");
    Relation x2 = Relation.unary("Int/max");
    Relation x3 = Relation.nary("Int/next", 2);
    Relation x4 = Relation.unary("seq/Int");
    Relation x5 = Relation.unary("String");
    Relation x6 = Relation.unary("this/A");
    Relation x7 = Relation.unary("this/Relation");
    Relation x8 = Relation.nary("this/Relation.r", 4);

    List<String> atomlist =
        Arrays.asList(
            "-1",
            "-2",
            "-3",
            "-4",
            "-5",
            "-6",
            "-7",
            "-8",
            "0",
            "1",
            "2",
            "3",
            "4",
            "5",
            "6",
            "7",
            "A$0",
            "A$1",
            "A$2",
            "Relation$0",
            "unused0",
            "unused1");

    Universe universe = new Universe(atomlist);
    TupleFactory factory = universe.factory();
    Bounds bounds = new Bounds(universe);

    TupleSet x0_upper = factory.noneOf(1);
    x0_upper.add(factory.tuple("-8"));
    bounds.boundExactly(x0, x0_upper);

    TupleSet x1_upper = factory.noneOf(1);
    x1_upper.add(factory.tuple("0"));
    bounds.boundExactly(x1, x1_upper);

    TupleSet x2_upper = factory.noneOf(1);
    x2_upper.add(factory.tuple("7"));
    bounds.boundExactly(x2, x2_upper);

    TupleSet x3_upper = factory.noneOf(2);
    x3_upper.add(factory.tuple("-8").product(factory.tuple("-7")));
    x3_upper.add(factory.tuple("-7").product(factory.tuple("-6")));
    x3_upper.add(factory.tuple("-6").product(factory.tuple("-5")));
    x3_upper.add(factory.tuple("-5").product(factory.tuple("-4")));
    x3_upper.add(factory.tuple("-4").product(factory.tuple("-3")));
    x3_upper.add(factory.tuple("-3").product(factory.tuple("-2")));
    x3_upper.add(factory.tuple("-2").product(factory.tuple("-1")));
    x3_upper.add(factory.tuple("-1").product(factory.tuple("0")));
    x3_upper.add(factory.tuple("0").product(factory.tuple("1")));
    x3_upper.add(factory.tuple("1").product(factory.tuple("2")));
    x3_upper.add(factory.tuple("2").product(factory.tuple("3")));
    x3_upper.add(factory.tuple("3").product(factory.tuple("4")));
    x3_upper.add(factory.tuple("4").product(factory.tuple("5")));
    x3_upper.add(factory.tuple("5").product(factory.tuple("6")));
    x3_upper.add(factory.tuple("6").product(factory.tuple("7")));
    bounds.boundExactly(x3, x3_upper);

    TupleSet x4_upper = factory.noneOf(1);
    x4_upper.add(factory.tuple("0"));
    x4_upper.add(factory.tuple("1"));
    x4_upper.add(factory.tuple("2"));
    bounds.boundExactly(x4, x4_upper);

    TupleSet x5_upper = factory.noneOf(1);
    bounds.boundExactly(x5, x5_upper);

    TupleSet x6_upper = factory.noneOf(1);
    x6_upper.add(factory.tuple("A$0"));
    x6_upper.add(factory.tuple("A$1"));
    x6_upper.add(factory.tuple("A$2"));
    bounds.boundExactly(x6, x6_upper);

    TupleSet x7_upper = factory.noneOf(1);
    x7_upper.add(factory.tuple("unused0"));
    x7_upper.add(factory.tuple("unused1"));
    x7_upper.add(factory.tuple("Relation$0"));
    bounds.bound(x7, x7_upper);

    TupleSet x8_upper = factory.noneOf(4);
    x8_upper.add(
        factory
            .tuple("unused0")
            .product(factory.tuple("A$0"))
            .product(factory.tuple("A$0"))
            .product(factory.tuple("A$0")));
    x8_upper.add(
        factory
            .tuple("unused0")
            .product(factory.tuple("A$0"))
            .product(factory.tuple("A$0"))
            .product(factory.tuple("A$1")));
    x8_upper.add(
        factory
            .tuple("unused0")
            .product(factory.tuple("A$0"))
            .product(factory.tuple("A$0"))
            .product(factory.tuple("A$2")));
    x8_upper.add(
        factory
            .tuple("unused0")
            .product(factory.tuple("A$0"))
            .product(factory.tuple("A$1"))
            .product(factory.tuple("A$0")));
    x8_upper.add(
        factory
            .tuple("unused0")
            .product(factory.tuple("A$0"))
            .product(factory.tuple("A$1"))
            .product(factory.tuple("A$1")));
    x8_upper.add(
        factory
            .tuple("unused0")
            .product(factory.tuple("A$0"))
            .product(factory.tuple("A$1"))
            .product(factory.tuple("A$2")));
    x8_upper.add(
        factory
            .tuple("unused0")
            .product(factory.tuple("A$0"))
            .product(factory.tuple("A$2"))
            .product(factory.tuple("A$0")));
    x8_upper.add(
        factory
            .tuple("unused0")
            .product(factory.tuple("A$0"))
            .product(factory.tuple("A$2"))
            .product(factory.tuple("A$1")));
    x8_upper.add(
        factory
            .tuple("unused0")
            .product(factory.tuple("A$0"))
            .product(factory.tuple("A$2"))
            .product(factory.tuple("A$2")));
    x8_upper.add(
        factory
            .tuple("unused0")
            .product(factory.tuple("A$1"))
            .product(factory.tuple("A$0"))
            .product(factory.tuple("A$0")));
    x8_upper.add(
        factory
            .tuple("unused0")
            .product(factory.tuple("A$1"))
            .product(factory.tuple("A$0"))
            .product(factory.tuple("A$1")));
    x8_upper.add(
        factory
            .tuple("unused0")
            .product(factory.tuple("A$1"))
            .product(factory.tuple("A$0"))
            .product(factory.tuple("A$2")));
    x8_upper.add(
        factory
            .tuple("unused0")
            .product(factory.tuple("A$1"))
            .product(factory.tuple("A$1"))
            .product(factory.tuple("A$0")));
    x8_upper.add(
        factory
            .tuple("unused0")
            .product(factory.tuple("A$1"))
            .product(factory.tuple("A$1"))
            .product(factory.tuple("A$1")));
    x8_upper.add(
        factory
            .tuple("unused0")
            .product(factory.tuple("A$1"))
            .product(factory.tuple("A$1"))
            .product(factory.tuple("A$2")));
    x8_upper.add(
        factory
            .tuple("unused0")
            .product(factory.tuple("A$1"))
            .product(factory.tuple("A$2"))
            .product(factory.tuple("A$0")));
    x8_upper.add(
        factory
            .tuple("unused0")
            .product(factory.tuple("A$1"))
            .product(factory.tuple("A$2"))
            .product(factory.tuple("A$1")));
    x8_upper.add(
        factory
            .tuple("unused0")
            .product(factory.tuple("A$1"))
            .product(factory.tuple("A$2"))
            .product(factory.tuple("A$2")));
    x8_upper.add(
        factory
            .tuple("unused0")
            .product(factory.tuple("A$2"))
            .product(factory.tuple("A$0"))
            .product(factory.tuple("A$0")));
    x8_upper.add(
        factory
            .tuple("unused0")
            .product(factory.tuple("A$2"))
            .product(factory.tuple("A$0"))
            .product(factory.tuple("A$1")));
    x8_upper.add(
        factory
            .tuple("unused0")
            .product(factory.tuple("A$2"))
            .product(factory.tuple("A$0"))
            .product(factory.tuple("A$2")));
    x8_upper.add(
        factory
            .tuple("unused0")
            .product(factory.tuple("A$2"))
            .product(factory.tuple("A$1"))
            .product(factory.tuple("A$0")));
    x8_upper.add(
        factory
            .tuple("unused0")
            .product(factory.tuple("A$2"))
            .product(factory.tuple("A$1"))
            .product(factory.tuple("A$1")));
    x8_upper.add(
        factory
            .tuple("unused0")
            .product(factory.tuple("A$2"))
            .product(factory.tuple("A$1"))
            .product(factory.tuple("A$2")));
    x8_upper.add(
        factory
            .tuple("unused0")
            .product(factory.tuple("A$2"))
            .product(factory.tuple("A$2"))
            .product(factory.tuple("A$0")));
    x8_upper.add(
        factory
            .tuple("unused0")
            .product(factory.tuple("A$2"))
            .product(factory.tuple("A$2"))
            .product(factory.tuple("A$1")));
    x8_upper.add(
        factory
            .tuple("unused0")
            .product(factory.tuple("A$2"))
            .product(factory.tuple("A$2"))
            .product(factory.tuple("A$2")));
    x8_upper.add(
        factory
            .tuple("unused1")
            .product(factory.tuple("A$0"))
            .product(factory.tuple("A$0"))
            .product(factory.tuple("A$0")));
    x8_upper.add(
        factory
            .tuple("unused1")
            .product(factory.tuple("A$0"))
            .product(factory.tuple("A$0"))
            .product(factory.tuple("A$1")));
    x8_upper.add(
        factory
            .tuple("unused1")
            .product(factory.tuple("A$0"))
            .product(factory.tuple("A$0"))
            .product(factory.tuple("A$2")));
    x8_upper.add(
        factory
            .tuple("unused1")
            .product(factory.tuple("A$0"))
            .product(factory.tuple("A$1"))
            .product(factory.tuple("A$0")));
    x8_upper.add(
        factory
            .tuple("unused1")
            .product(factory.tuple("A$0"))
            .product(factory.tuple("A$1"))
            .product(factory.tuple("A$1")));
    x8_upper.add(
        factory
            .tuple("unused1")
            .product(factory.tuple("A$0"))
            .product(factory.tuple("A$1"))
            .product(factory.tuple("A$2")));
    x8_upper.add(
        factory
            .tuple("unused1")
            .product(factory.tuple("A$0"))
            .product(factory.tuple("A$2"))
            .product(factory.tuple("A$0")));
    x8_upper.add(
        factory
            .tuple("unused1")
            .product(factory.tuple("A$0"))
            .product(factory.tuple("A$2"))
            .product(factory.tuple("A$1")));
    x8_upper.add(
        factory
            .tuple("unused1")
            .product(factory.tuple("A$0"))
            .product(factory.tuple("A$2"))
            .product(factory.tuple("A$2")));
    x8_upper.add(
        factory
            .tuple("unused1")
            .product(factory.tuple("A$1"))
            .product(factory.tuple("A$0"))
            .product(factory.tuple("A$0")));
    x8_upper.add(
        factory
            .tuple("unused1")
            .product(factory.tuple("A$1"))
            .product(factory.tuple("A$0"))
            .product(factory.tuple("A$1")));
    x8_upper.add(
        factory
            .tuple("unused1")
            .product(factory.tuple("A$1"))
            .product(factory.tuple("A$0"))
            .product(factory.tuple("A$2")));
    x8_upper.add(
        factory
            .tuple("unused1")
            .product(factory.tuple("A$1"))
            .product(factory.tuple("A$1"))
            .product(factory.tuple("A$0")));
    x8_upper.add(
        factory
            .tuple("unused1")
            .product(factory.tuple("A$1"))
            .product(factory.tuple("A$1"))
            .product(factory.tuple("A$1")));
    x8_upper.add(
        factory
            .tuple("unused1")
            .product(factory.tuple("A$1"))
            .product(factory.tuple("A$1"))
            .product(factory.tuple("A$2")));
    x8_upper.add(
        factory
            .tuple("unused1")
            .product(factory.tuple("A$1"))
            .product(factory.tuple("A$2"))
            .product(factory.tuple("A$0")));
    x8_upper.add(
        factory
            .tuple("unused1")
            .product(factory.tuple("A$1"))
            .product(factory.tuple("A$2"))
            .product(factory.tuple("A$1")));
    x8_upper.add(
        factory
            .tuple("unused1")
            .product(factory.tuple("A$1"))
            .product(factory.tuple("A$2"))
            .product(factory.tuple("A$2")));
    x8_upper.add(
        factory
            .tuple("unused1")
            .product(factory.tuple("A$2"))
            .product(factory.tuple("A$0"))
            .product(factory.tuple("A$0")));
    x8_upper.add(
        factory
            .tuple("unused1")
            .product(factory.tuple("A$2"))
            .product(factory.tuple("A$0"))
            .product(factory.tuple("A$1")));
    x8_upper.add(
        factory
            .tuple("unused1")
            .product(factory.tuple("A$2"))
            .product(factory.tuple("A$0"))
            .product(factory.tuple("A$2")));
    x8_upper.add(
        factory
            .tuple("unused1")
            .product(factory.tuple("A$2"))
            .product(factory.tuple("A$1"))
            .product(factory.tuple("A$0")));
    x8_upper.add(
        factory
            .tuple("unused1")
            .product(factory.tuple("A$2"))
            .product(factory.tuple("A$1"))
            .product(factory.tuple("A$1")));
    x8_upper.add(
        factory
            .tuple("unused1")
            .product(factory.tuple("A$2"))
            .product(factory.tuple("A$1"))
            .product(factory.tuple("A$2")));
    x8_upper.add(
        factory
            .tuple("unused1")
            .product(factory.tuple("A$2"))
            .product(factory.tuple("A$2"))
            .product(factory.tuple("A$0")));
    x8_upper.add(
        factory
            .tuple("unused1")
            .product(factory.tuple("A$2"))
            .product(factory.tuple("A$2"))
            .product(factory.tuple("A$1")));
    x8_upper.add(
        factory
            .tuple("unused1")
            .product(factory.tuple("A$2"))
            .product(factory.tuple("A$2"))
            .product(factory.tuple("A$2")));
    x8_upper.add(
        factory
            .tuple("Relation$0")
            .product(factory.tuple("A$0"))
            .product(factory.tuple("A$0"))
            .product(factory.tuple("A$0")));
    x8_upper.add(
        factory
            .tuple("Relation$0")
            .product(factory.tuple("A$0"))
            .product(factory.tuple("A$0"))
            .product(factory.tuple("A$1")));
    x8_upper.add(
        factory
            .tuple("Relation$0")
            .product(factory.tuple("A$0"))
            .product(factory.tuple("A$0"))
            .product(factory.tuple("A$2")));
    x8_upper.add(
        factory
            .tuple("Relation$0")
            .product(factory.tuple("A$0"))
            .product(factory.tuple("A$1"))
            .product(factory.tuple("A$0")));
    x8_upper.add(
        factory
            .tuple("Relation$0")
            .product(factory.tuple("A$0"))
            .product(factory.tuple("A$1"))
            .product(factory.tuple("A$1")));
    x8_upper.add(
        factory
            .tuple("Relation$0")
            .product(factory.tuple("A$0"))
            .product(factory.tuple("A$1"))
            .product(factory.tuple("A$2")));
    x8_upper.add(
        factory
            .tuple("Relation$0")
            .product(factory.tuple("A$0"))
            .product(factory.tuple("A$2"))
            .product(factory.tuple("A$0")));
    x8_upper.add(
        factory
            .tuple("Relation$0")
            .product(factory.tuple("A$0"))
            .product(factory.tuple("A$2"))
            .product(factory.tuple("A$1")));
    x8_upper.add(
        factory
            .tuple("Relation$0")
            .product(factory.tuple("A$0"))
            .product(factory.tuple("A$2"))
            .product(factory.tuple("A$2")));
    x8_upper.add(
        factory
            .tuple("Relation$0")
            .product(factory.tuple("A$1"))
            .product(factory.tuple("A$0"))
            .product(factory.tuple("A$0")));
    x8_upper.add(
        factory
            .tuple("Relation$0")
            .product(factory.tuple("A$1"))
            .product(factory.tuple("A$0"))
            .product(factory.tuple("A$1")));
    x8_upper.add(
        factory
            .tuple("Relation$0")
            .product(factory.tuple("A$1"))
            .product(factory.tuple("A$0"))
            .product(factory.tuple("A$2")));
    x8_upper.add(
        factory
            .tuple("Relation$0")
            .product(factory.tuple("A$1"))
            .product(factory.tuple("A$1"))
            .product(factory.tuple("A$0")));
    x8_upper.add(
        factory
            .tuple("Relation$0")
            .product(factory.tuple("A$1"))
            .product(factory.tuple("A$1"))
            .product(factory.tuple("A$1")));
    x8_upper.add(
        factory
            .tuple("Relation$0")
            .product(factory.tuple("A$1"))
            .product(factory.tuple("A$1"))
            .product(factory.tuple("A$2")));
    x8_upper.add(
        factory
            .tuple("Relation$0")
            .product(factory.tuple("A$1"))
            .product(factory.tuple("A$2"))
            .product(factory.tuple("A$0")));
    x8_upper.add(
        factory
            .tuple("Relation$0")
            .product(factory.tuple("A$1"))
            .product(factory.tuple("A$2"))
            .product(factory.tuple("A$1")));
    x8_upper.add(
        factory
            .tuple("Relation$0")
            .product(factory.tuple("A$1"))
            .product(factory.tuple("A$2"))
            .product(factory.tuple("A$2")));
    x8_upper.add(
        factory
            .tuple("Relation$0")
            .product(factory.tuple("A$2"))
            .product(factory.tuple("A$0"))
            .product(factory.tuple("A$0")));
    x8_upper.add(
        factory
            .tuple("Relation$0")
            .product(factory.tuple("A$2"))
            .product(factory.tuple("A$0"))
            .product(factory.tuple("A$1")));
    x8_upper.add(
        factory
            .tuple("Relation$0")
            .product(factory.tuple("A$2"))
            .product(factory.tuple("A$0"))
            .product(factory.tuple("A$2")));
    x8_upper.add(
        factory
            .tuple("Relation$0")
            .product(factory.tuple("A$2"))
            .product(factory.tuple("A$1"))
            .product(factory.tuple("A$0")));
    x8_upper.add(
        factory
            .tuple("Relation$0")
            .product(factory.tuple("A$2"))
            .product(factory.tuple("A$1"))
            .product(factory.tuple("A$1")));
    x8_upper.add(
        factory
            .tuple("Relation$0")
            .product(factory.tuple("A$2"))
            .product(factory.tuple("A$1"))
            .product(factory.tuple("A$2")));
    x8_upper.add(
        factory
            .tuple("Relation$0")
            .product(factory.tuple("A$2"))
            .product(factory.tuple("A$2"))
            .product(factory.tuple("A$0")));
    x8_upper.add(
        factory
            .tuple("Relation$0")
            .product(factory.tuple("A$2"))
            .product(factory.tuple("A$2"))
            .product(factory.tuple("A$1")));
    x8_upper.add(
        factory
            .tuple("Relation$0")
            .product(factory.tuple("A$2"))
            .product(factory.tuple("A$2"))
            .product(factory.tuple("A$2")));
    bounds.bound(x8, x8_upper);

    bounds.boundExactly(-8, factory.range(factory.tuple("-8"), factory.tuple("-8")));
    bounds.boundExactly(-7, factory.range(factory.tuple("-7"), factory.tuple("-7")));
    bounds.boundExactly(-6, factory.range(factory.tuple("-6"), factory.tuple("-6")));
    bounds.boundExactly(-5, factory.range(factory.tuple("-5"), factory.tuple("-5")));
    bounds.boundExactly(-4, factory.range(factory.tuple("-4"), factory.tuple("-4")));
    bounds.boundExactly(-3, factory.range(factory.tuple("-3"), factory.tuple("-3")));
    bounds.boundExactly(-2, factory.range(factory.tuple("-2"), factory.tuple("-2")));
    bounds.boundExactly(-1, factory.range(factory.tuple("-1"), factory.tuple("-1")));
    bounds.boundExactly(0, factory.range(factory.tuple("0"), factory.tuple("0")));
    bounds.boundExactly(1, factory.range(factory.tuple("1"), factory.tuple("1")));
    bounds.boundExactly(2, factory.range(factory.tuple("2"), factory.tuple("2")));
    bounds.boundExactly(3, factory.range(factory.tuple("3"), factory.tuple("3")));
    bounds.boundExactly(4, factory.range(factory.tuple("4"), factory.tuple("4")));
    bounds.boundExactly(5, factory.range(factory.tuple("5"), factory.tuple("5")));
    bounds.boundExactly(6, factory.range(factory.tuple("6"), factory.tuple("6")));
    bounds.boundExactly(7, factory.range(factory.tuple("7"), factory.tuple("7")));

    Variable x12 = Variable.unary("this");
    Decls x11 = x12.oneOf(x7);
    Expression x16 = x12.join(x8);
    Expression x18 = x6.product(x6);
    Expression x17 = x6.product(x18);
    Formula x15 = x16.in(x17);
    Variable x21 = Variable.unary("x21");
    Decls x20 = x21.oneOf(x6);
    Expression x25 = x21.join(x16);
    Expression x26 = x6.product(x6);
    Formula x24 = x25.in(x26);
    Variable x29 = Variable.unary("x29");
    Decls x28 = x29.oneOf(x6);
    Expression x32 = x29.join(x25);
    Formula x31 = x32.one();
    Formula x33 = x32.in(x6);
    Formula x30 = x31.and(x33);
    Formula x27 = x30.forAll(x28);
    Formula x23 = x24.and(x27);
    Variable x36 = Variable.unary("x36");
    Decls x35 = x36.oneOf(x6);
    Expression x38 = x25.join(x36);
    Formula x37 = x38.in(x6);
    Formula x34 = x37.forAll(x35);
    Formula x22 = x23.and(x34);
    Formula x19 = x22.forAll(x20);
    Formula x14 = x15.and(x19);
    Variable x42 = Variable.unary("x42");
    Decls x41 = x42.oneOf(Expression.UNIV);
    Variable x45 = Variable.unary("x45");
    Decls x44 = x45.oneOf(Expression.UNIV);
    Decls x40 = x41.and(x44);
    Expression x50 = x42.product(x45);
    Expression x51 = x6.product(x6);
    Formula x49 = x50.in(x51);
    Variable x54 = Variable.unary("x54");
    Decls x53 = x54.oneOf(x6);
    Expression x57 = x54.join(x50);
    Formula x56 = x57.one();
    Formula x58 = x57.in(x6);
    Formula x55 = x56.and(x58);
    Formula x52 = x55.forAll(x53);
    Formula x48 = x49.and(x52);
    Variable x61 = Variable.unary("x61");
    Decls x60 = x61.oneOf(x6);
    Expression x63 = x50.join(x61);
    Formula x62 = x63.in(x6);
    Formula x59 = x62.forAll(x60);
    Formula x47 = x48.and(x59);
    Expression x66 = x16.join(x45);
    Expression x65 = x66.join(x42);
    Formula x64 = x65.in(x6);
    Formula x46 = x47.implies(x64);
    Formula x39 = x46.forAll(x40);
    Formula x13 = x14.and(x39);
    Formula x10 = x13.forAll(x11);
    Expression x70 = x8.join(Expression.UNIV);
    Expression x69 = x70.join(Expression.UNIV);
    Expression x68 = x69.join(Expression.UNIV);
    Formula x67 = x68.in(x7);
    Formula x71 = x0.eq(x0);
    Formula x72 = x1.eq(x1);
    Formula x73 = x2.eq(x2);
    Formula x74 = x3.eq(x3);
    Formula x75 = x4.eq(x4);
    Formula x76 = x5.eq(x5);
    Formula x77 = x6.eq(x6);
    Formula x78 = x7.eq(x7);
    Formula x79 = x8.eq(x8);
    Formula x9 =
        Formula.compose(FormulaOperator.AND, x10, x67, x71, x72, x73, x74, x75, x76, x77, x78, x79);

    Solver solver = new Solver();
    solver.options().setSolver(SATFactory.DefaultSAT4J);
    solver.options().setBitwidth(4);
    solver.options().setFlatten(false);
    solver.options().setIntEncoding(Options.IntEncoding.TWOSCOMPLEMENT);
    solver.options().setSymmetryBreaking(20);
    solver.options().setSkolemDepth(0);

    System.out.println(PrettyPrinter.print(x9, 0));
    System.out.println(bounds);

    System.out.println("Solving...");
    System.out.flush();
    Solution sol = solver.solve(x9, bounds);
    System.out.println(sol.toString());

    Instance inst = sol.instance();
    Evaluator ev = new Evaluator(inst);

    System.out.println("Universe: " + ev.evaluate(Expression.UNIV));
    Formula xx = x46.forAll(x40).forAll(x11);
    System.out.println(PrettyPrinter.print(xx, 2));
    System.out.println(ev.evaluate(xx));

    System.out.println(PrettyPrinter.print(x46, 4));

    //        Variable r = Variable.unary("this");
    //        Variable u1 = Variable.unary("u1");
    //        Variable u2 = Variable.unary("u2");
    //
    //        Formula ff =
    // u1.product(u2).in(x6.product(x6)).forAll(u1.oneOf(Expression.UNIV).and(u2.oneOf(Expression.UNIV))).forAll(r.oneOf(x7));
    //        System.out.println(PrettyPrinter.print(ff, 0));
    //        System.out.println(ev.evaluate(ff));

  }
  public SymmetryBreakingTest() {
    this.solver = new Solver();

    List<String> atoms = new ArrayList<String>(USIZE);
    for (int i = 0; i < USIZE; i++) {
      atoms.add("" + i);
    }
    final Universe universe = new Universe(atoms);
    this.factory = universe.factory();

    to1 = Relation.binary("to1");
    ord1 = Relation.unary("ord1");
    first1 = Relation.unary("first1");
    last1 = Relation.unary("last1");

    to2 = Relation.binary("to2");
    ord2 = Relation.unary("ord2");
    first2 = Relation.unary("first2");
    last2 = Relation.unary("last2");

    to3 = Relation.binary("to3");
    ord3 = Relation.unary("ord3");
    first3 = Relation.unary("first3");
    last3 = Relation.unary("last3");

    ac1 = Relation.binary("ac1");
    ac2 = Relation.binary("ac2");
    ac3 = Relation.binary("ac3");

    r1 = Relation.unary("r1");
    r2 = Relation.binary("r2");
  }
  @Test
  public final void testAcyclic() {
    bounds.bound(ac1, factory.area(factory.tuple("0", "0"), factory.tuple("4", "4")));
    assertNotNull(solve(ac1.some().and(ac1.acyclic())));
    assertPrimVarNum(10);

    bounds.bound(r1, factory.range(factory.tuple("0"), factory.tuple("4")));
    assertNotNull(solve(ac1.join(r1).some().and(ac1.acyclic())));
    assertPrimVarNum(10 + bounds.upperBound(r1).size());

    TupleSet ac2b = factory.setOf("5", "6", "7", "8");
    ac2b = ac2b.product(ac2b);
    bounds.bound(ac2, ac2b);
    assertNotNull(solve(ac1.difference(ac2).some().and(ac1.acyclic()).and(ac2.acyclic())));
    assertPrimVarNum(10 + 6);

    bounds.boundExactly(r2, factory.setOf(factory.tuple("5", "6")));
    assertNotNull(solve(ac2.join(r2).some().and(ac2.acyclic())));

    final TupleSet ac3Bound = factory.allOf(2);
    ac3Bound.remove(factory.tuple("9", "9"));
    bounds.bound(ac3, ac3Bound);

    assertNotNull(
        solve(ac1.difference(ac2).union(ac3).some().and(ac1.acyclic()).and(ac2.acyclic())));
    assertPrimVarNum(ac3Bound.size() + 10 + 6);

    bounds.bound(to3, factory.allOf(2));
    bounds.bound(ord3, factory.setOf("0", "1", "2"));
    bounds.bound(first3, bounds.upperBound(ord3));
    bounds.bound(last3, bounds.upperBound(ord3));
    assertNotNull(
        solve(to3.product(ac1).some().and(ac1.acyclic()).and(to3.totalOrder(ord3, first3, last3))));
    assertPrimVarNum(bounds.upperBound(ac1).size());
  }
  public static void main(String[] args) throws Exception {

    Relation x0 = Relation.unary("Int/min");
    Relation x1 = Relation.unary("Int/zero");
    Relation x2 = Relation.unary("Int/max");
    Relation x3 = Relation.nary("Int/next", 2);
    Relation x4 = Relation.unary("seq/Int");
    Relation x5 = Relation.unary("String");
    Relation x6 = Relation.unary("this/Test");
    Relation x7 = Relation.nary("this/Test.weight", 2);
    Relation x8 = Relation.nary("this/Test.x", 2);
    Relation x9 = Relation.nary("this/Test.y", 2);

    List<String> atomlist =
        Arrays.asList(
            "-1", "-2", "-3", "-4", "-5", "-6", "-7", "-8", "0", "1", "2", "3", "4", "5", "6", "7",
            "Test$0", "Test$1", "Test$2");

    Universe universe = new Universe(atomlist);
    TupleFactory factory = universe.factory();
    Bounds bounds = new Bounds(universe);

    TupleSet x0_upper = factory.noneOf(1);
    x0_upper.add(factory.tuple("-8"));
    bounds.boundExactly(x0, x0_upper);

    TupleSet x1_upper = factory.noneOf(1);
    x1_upper.add(factory.tuple("0"));
    bounds.boundExactly(x1, x1_upper);

    TupleSet x2_upper = factory.noneOf(1);
    x2_upper.add(factory.tuple("7"));
    bounds.boundExactly(x2, x2_upper);

    TupleSet x3_upper = factory.noneOf(2);
    x3_upper.add(factory.tuple("-8").product(factory.tuple("-7")));
    x3_upper.add(factory.tuple("-7").product(factory.tuple("-6")));
    x3_upper.add(factory.tuple("-6").product(factory.tuple("-5")));
    x3_upper.add(factory.tuple("-5").product(factory.tuple("-4")));
    x3_upper.add(factory.tuple("-4").product(factory.tuple("-3")));
    x3_upper.add(factory.tuple("-3").product(factory.tuple("-2")));
    x3_upper.add(factory.tuple("-2").product(factory.tuple("-1")));
    x3_upper.add(factory.tuple("-1").product(factory.tuple("0")));
    x3_upper.add(factory.tuple("0").product(factory.tuple("1")));
    x3_upper.add(factory.tuple("1").product(factory.tuple("2")));
    x3_upper.add(factory.tuple("2").product(factory.tuple("3")));
    x3_upper.add(factory.tuple("3").product(factory.tuple("4")));
    x3_upper.add(factory.tuple("4").product(factory.tuple("5")));
    x3_upper.add(factory.tuple("5").product(factory.tuple("6")));
    x3_upper.add(factory.tuple("6").product(factory.tuple("7")));
    bounds.boundExactly(x3, x3_upper);

    TupleSet x4_upper = factory.noneOf(1);
    x4_upper.add(factory.tuple("0"));
    x4_upper.add(factory.tuple("1"));
    x4_upper.add(factory.tuple("2"));
    x4_upper.add(factory.tuple("3"));
    bounds.boundExactly(x4, x4_upper);

    TupleSet x5_upper = factory.noneOf(1);
    bounds.boundExactly(x5, x5_upper);

    TupleSet x6_upper = factory.noneOf(1);
    x6_upper.add(factory.tuple("Test$0"));
    x6_upper.add(factory.tuple("Test$1"));
    x6_upper.add(factory.tuple("Test$2"));
    bounds.boundExactly(x6, x6_upper);

    TupleSet x7_upper = factory.noneOf(2);
    x7_upper.add(factory.tuple("Test$0").product(factory.tuple("-8")));
    x7_upper.add(factory.tuple("Test$0").product(factory.tuple("-7")));
    x7_upper.add(factory.tuple("Test$0").product(factory.tuple("-6")));
    x7_upper.add(factory.tuple("Test$0").product(factory.tuple("-5")));
    x7_upper.add(factory.tuple("Test$0").product(factory.tuple("-4")));
    x7_upper.add(factory.tuple("Test$0").product(factory.tuple("-3")));
    x7_upper.add(factory.tuple("Test$0").product(factory.tuple("-2")));
    x7_upper.add(factory.tuple("Test$0").product(factory.tuple("-1")));
    x7_upper.add(factory.tuple("Test$0").product(factory.tuple("0")));
    x7_upper.add(factory.tuple("Test$0").product(factory.tuple("1")));
    x7_upper.add(factory.tuple("Test$0").product(factory.tuple("2")));
    x7_upper.add(factory.tuple("Test$0").product(factory.tuple("3")));
    x7_upper.add(factory.tuple("Test$0").product(factory.tuple("4")));
    x7_upper.add(factory.tuple("Test$0").product(factory.tuple("5")));
    x7_upper.add(factory.tuple("Test$0").product(factory.tuple("6")));
    x7_upper.add(factory.tuple("Test$0").product(factory.tuple("7")));
    x7_upper.add(factory.tuple("Test$1").product(factory.tuple("-8")));
    x7_upper.add(factory.tuple("Test$1").product(factory.tuple("-7")));
    x7_upper.add(factory.tuple("Test$1").product(factory.tuple("-6")));
    x7_upper.add(factory.tuple("Test$1").product(factory.tuple("-5")));
    x7_upper.add(factory.tuple("Test$1").product(factory.tuple("-4")));
    x7_upper.add(factory.tuple("Test$1").product(factory.tuple("-3")));
    x7_upper.add(factory.tuple("Test$1").product(factory.tuple("-2")));
    x7_upper.add(factory.tuple("Test$1").product(factory.tuple("-1")));
    x7_upper.add(factory.tuple("Test$1").product(factory.tuple("0")));
    x7_upper.add(factory.tuple("Test$1").product(factory.tuple("1")));
    x7_upper.add(factory.tuple("Test$1").product(factory.tuple("2")));
    x7_upper.add(factory.tuple("Test$1").product(factory.tuple("3")));
    x7_upper.add(factory.tuple("Test$1").product(factory.tuple("4")));
    x7_upper.add(factory.tuple("Test$1").product(factory.tuple("5")));
    x7_upper.add(factory.tuple("Test$1").product(factory.tuple("6")));
    x7_upper.add(factory.tuple("Test$1").product(factory.tuple("7")));
    x7_upper.add(factory.tuple("Test$2").product(factory.tuple("-8")));
    x7_upper.add(factory.tuple("Test$2").product(factory.tuple("-7")));
    x7_upper.add(factory.tuple("Test$2").product(factory.tuple("-6")));
    x7_upper.add(factory.tuple("Test$2").product(factory.tuple("-5")));
    x7_upper.add(factory.tuple("Test$2").product(factory.tuple("-4")));
    x7_upper.add(factory.tuple("Test$2").product(factory.tuple("-3")));
    x7_upper.add(factory.tuple("Test$2").product(factory.tuple("-2")));
    x7_upper.add(factory.tuple("Test$2").product(factory.tuple("-1")));
    x7_upper.add(factory.tuple("Test$2").product(factory.tuple("0")));
    x7_upper.add(factory.tuple("Test$2").product(factory.tuple("1")));
    x7_upper.add(factory.tuple("Test$2").product(factory.tuple("2")));
    x7_upper.add(factory.tuple("Test$2").product(factory.tuple("3")));
    x7_upper.add(factory.tuple("Test$2").product(factory.tuple("4")));
    x7_upper.add(factory.tuple("Test$2").product(factory.tuple("5")));
    x7_upper.add(factory.tuple("Test$2").product(factory.tuple("6")));
    x7_upper.add(factory.tuple("Test$2").product(factory.tuple("7")));
    bounds.bound(x7, x7_upper);

    TupleSet x8_upper = factory.noneOf(2);
    x8_upper.add(factory.tuple("Test$0").product(factory.tuple("-8")));
    x8_upper.add(factory.tuple("Test$0").product(factory.tuple("-7")));
    x8_upper.add(factory.tuple("Test$0").product(factory.tuple("-6")));
    x8_upper.add(factory.tuple("Test$0").product(factory.tuple("-5")));
    x8_upper.add(factory.tuple("Test$0").product(factory.tuple("-4")));
    x8_upper.add(factory.tuple("Test$0").product(factory.tuple("-3")));
    x8_upper.add(factory.tuple("Test$0").product(factory.tuple("-2")));
    x8_upper.add(factory.tuple("Test$0").product(factory.tuple("-1")));
    x8_upper.add(factory.tuple("Test$0").product(factory.tuple("0")));
    x8_upper.add(factory.tuple("Test$0").product(factory.tuple("1")));
    x8_upper.add(factory.tuple("Test$0").product(factory.tuple("2")));
    x8_upper.add(factory.tuple("Test$0").product(factory.tuple("3")));
    x8_upper.add(factory.tuple("Test$0").product(factory.tuple("4")));
    x8_upper.add(factory.tuple("Test$0").product(factory.tuple("5")));
    x8_upper.add(factory.tuple("Test$0").product(factory.tuple("6")));
    x8_upper.add(factory.tuple("Test$0").product(factory.tuple("7")));
    x8_upper.add(factory.tuple("Test$1").product(factory.tuple("-8")));
    x8_upper.add(factory.tuple("Test$1").product(factory.tuple("-7")));
    x8_upper.add(factory.tuple("Test$1").product(factory.tuple("-6")));
    x8_upper.add(factory.tuple("Test$1").product(factory.tuple("-5")));
    x8_upper.add(factory.tuple("Test$1").product(factory.tuple("-4")));
    x8_upper.add(factory.tuple("Test$1").product(factory.tuple("-3")));
    x8_upper.add(factory.tuple("Test$1").product(factory.tuple("-2")));
    x8_upper.add(factory.tuple("Test$1").product(factory.tuple("-1")));
    x8_upper.add(factory.tuple("Test$1").product(factory.tuple("0")));
    x8_upper.add(factory.tuple("Test$1").product(factory.tuple("1")));
    x8_upper.add(factory.tuple("Test$1").product(factory.tuple("2")));
    x8_upper.add(factory.tuple("Test$1").product(factory.tuple("3")));
    x8_upper.add(factory.tuple("Test$1").product(factory.tuple("4")));
    x8_upper.add(factory.tuple("Test$1").product(factory.tuple("5")));
    x8_upper.add(factory.tuple("Test$1").product(factory.tuple("6")));
    x8_upper.add(factory.tuple("Test$1").product(factory.tuple("7")));
    x8_upper.add(factory.tuple("Test$2").product(factory.tuple("-8")));
    x8_upper.add(factory.tuple("Test$2").product(factory.tuple("-7")));
    x8_upper.add(factory.tuple("Test$2").product(factory.tuple("-6")));
    x8_upper.add(factory.tuple("Test$2").product(factory.tuple("-5")));
    x8_upper.add(factory.tuple("Test$2").product(factory.tuple("-4")));
    x8_upper.add(factory.tuple("Test$2").product(factory.tuple("-3")));
    x8_upper.add(factory.tuple("Test$2").product(factory.tuple("-2")));
    x8_upper.add(factory.tuple("Test$2").product(factory.tuple("-1")));
    x8_upper.add(factory.tuple("Test$2").product(factory.tuple("0")));
    x8_upper.add(factory.tuple("Test$2").product(factory.tuple("1")));
    x8_upper.add(factory.tuple("Test$2").product(factory.tuple("2")));
    x8_upper.add(factory.tuple("Test$2").product(factory.tuple("3")));
    x8_upper.add(factory.tuple("Test$2").product(factory.tuple("4")));
    x8_upper.add(factory.tuple("Test$2").product(factory.tuple("5")));
    x8_upper.add(factory.tuple("Test$2").product(factory.tuple("6")));
    x8_upper.add(factory.tuple("Test$2").product(factory.tuple("7")));
    bounds.bound(x8, x8_upper);

    TupleSet x9_upper = factory.noneOf(2);
    x9_upper.add(factory.tuple("Test$0").product(factory.tuple("-8")));
    x9_upper.add(factory.tuple("Test$0").product(factory.tuple("-7")));
    x9_upper.add(factory.tuple("Test$0").product(factory.tuple("-6")));
    x9_upper.add(factory.tuple("Test$0").product(factory.tuple("-5")));
    x9_upper.add(factory.tuple("Test$0").product(factory.tuple("-4")));
    x9_upper.add(factory.tuple("Test$0").product(factory.tuple("-3")));
    x9_upper.add(factory.tuple("Test$0").product(factory.tuple("-2")));
    x9_upper.add(factory.tuple("Test$0").product(factory.tuple("-1")));
    x9_upper.add(factory.tuple("Test$0").product(factory.tuple("0")));
    x9_upper.add(factory.tuple("Test$0").product(factory.tuple("1")));
    x9_upper.add(factory.tuple("Test$0").product(factory.tuple("2")));
    x9_upper.add(factory.tuple("Test$0").product(factory.tuple("3")));
    x9_upper.add(factory.tuple("Test$0").product(factory.tuple("4")));
    x9_upper.add(factory.tuple("Test$0").product(factory.tuple("5")));
    x9_upper.add(factory.tuple("Test$0").product(factory.tuple("6")));
    x9_upper.add(factory.tuple("Test$0").product(factory.tuple("7")));
    x9_upper.add(factory.tuple("Test$1").product(factory.tuple("-8")));
    x9_upper.add(factory.tuple("Test$1").product(factory.tuple("-7")));
    x9_upper.add(factory.tuple("Test$1").product(factory.tuple("-6")));
    x9_upper.add(factory.tuple("Test$1").product(factory.tuple("-5")));
    x9_upper.add(factory.tuple("Test$1").product(factory.tuple("-4")));
    x9_upper.add(factory.tuple("Test$1").product(factory.tuple("-3")));
    x9_upper.add(factory.tuple("Test$1").product(factory.tuple("-2")));
    x9_upper.add(factory.tuple("Test$1").product(factory.tuple("-1")));
    x9_upper.add(factory.tuple("Test$1").product(factory.tuple("0")));
    x9_upper.add(factory.tuple("Test$1").product(factory.tuple("1")));
    x9_upper.add(factory.tuple("Test$1").product(factory.tuple("2")));
    x9_upper.add(factory.tuple("Test$1").product(factory.tuple("3")));
    x9_upper.add(factory.tuple("Test$1").product(factory.tuple("4")));
    x9_upper.add(factory.tuple("Test$1").product(factory.tuple("5")));
    x9_upper.add(factory.tuple("Test$1").product(factory.tuple("6")));
    x9_upper.add(factory.tuple("Test$1").product(factory.tuple("7")));
    x9_upper.add(factory.tuple("Test$2").product(factory.tuple("-8")));
    x9_upper.add(factory.tuple("Test$2").product(factory.tuple("-7")));
    x9_upper.add(factory.tuple("Test$2").product(factory.tuple("-6")));
    x9_upper.add(factory.tuple("Test$2").product(factory.tuple("-5")));
    x9_upper.add(factory.tuple("Test$2").product(factory.tuple("-4")));
    x9_upper.add(factory.tuple("Test$2").product(factory.tuple("-3")));
    x9_upper.add(factory.tuple("Test$2").product(factory.tuple("-2")));
    x9_upper.add(factory.tuple("Test$2").product(factory.tuple("-1")));
    x9_upper.add(factory.tuple("Test$2").product(factory.tuple("0")));
    x9_upper.add(factory.tuple("Test$2").product(factory.tuple("1")));
    x9_upper.add(factory.tuple("Test$2").product(factory.tuple("2")));
    x9_upper.add(factory.tuple("Test$2").product(factory.tuple("3")));
    x9_upper.add(factory.tuple("Test$2").product(factory.tuple("4")));
    x9_upper.add(factory.tuple("Test$2").product(factory.tuple("5")));
    x9_upper.add(factory.tuple("Test$2").product(factory.tuple("6")));
    x9_upper.add(factory.tuple("Test$2").product(factory.tuple("7")));
    bounds.bound(x9, x9_upper);

    bounds.boundExactly(-8, factory.range(factory.tuple("-8"), factory.tuple("-8")));
    bounds.boundExactly(-7, factory.range(factory.tuple("-7"), factory.tuple("-7")));
    bounds.boundExactly(-6, factory.range(factory.tuple("-6"), factory.tuple("-6")));
    bounds.boundExactly(-5, factory.range(factory.tuple("-5"), factory.tuple("-5")));
    bounds.boundExactly(-4, factory.range(factory.tuple("-4"), factory.tuple("-4")));
    bounds.boundExactly(-3, factory.range(factory.tuple("-3"), factory.tuple("-3")));
    bounds.boundExactly(-2, factory.range(factory.tuple("-2"), factory.tuple("-2")));
    bounds.boundExactly(-1, factory.range(factory.tuple("-1"), factory.tuple("-1")));
    bounds.boundExactly(0, factory.range(factory.tuple("0"), factory.tuple("0")));
    bounds.boundExactly(1, factory.range(factory.tuple("1"), factory.tuple("1")));
    bounds.boundExactly(2, factory.range(factory.tuple("2"), factory.tuple("2")));
    bounds.boundExactly(3, factory.range(factory.tuple("3"), factory.tuple("3")));
    bounds.boundExactly(4, factory.range(factory.tuple("4"), factory.tuple("4")));
    bounds.boundExactly(5, factory.range(factory.tuple("5"), factory.tuple("5")));
    bounds.boundExactly(6, factory.range(factory.tuple("6"), factory.tuple("6")));
    bounds.boundExactly(7, factory.range(factory.tuple("7"), factory.tuple("7")));

    Variable x13 = Variable.unary("this");
    Decls x12 = x13.oneOf(x6);
    Expression x16 = x13.join(x7);
    Formula x15 = x16.one();
    Formula x17 = x16.in(Expression.INTS);
    Formula x14 = x15.and(x17);
    Formula x11 = x14.forAll(x12);
    Expression x20 = x7.join(Expression.UNIV);
    Formula x19 = x20.in(x6);
    Variable x24 = Variable.unary("this");
    Decls x23 = x24.oneOf(x6);
    Expression x27 = x24.join(x8);
    Formula x26 = x27.lone();
    Formula x28 = x27.in(Expression.INTS);
    Formula x25 = x26.and(x28);
    Formula x22 = x25.forAll(x23);
    Expression x30 = x8.join(Expression.UNIV);
    Formula x29 = x30.in(x6);
    Variable x33 = Variable.unary("this");
    Decls x32 = x33.oneOf(x6);
    Expression x36 = x33.join(x9);
    Formula x35 = x36.one();
    Formula x37 = x36.in(Expression.INTS);
    Formula x34 = x35.and(x37);
    Formula x31 = x34.forAll(x32);
    Expression x39 = x9.join(Expression.UNIV);
    Formula x38 = x39.in(x6);
    Variable x42 = Variable.unary("this");
    Decls x41 = x42.oneOf(x6);
    Expression x44 = x42.join(x7);
    Expression x48 = x42.join(x8);
    IntExpression x47 = x48.sum();
    Expression x50 = x42.join(x9);
    IntExpression x49 = x50.sum();
    IntExpression x46 = x47.plus(x49);
    Expression x45 = x46.toExpression();
    Formula x43 = x44.eq(x45);
    Formula x40 = x43.forAll(x41);
    Formula x51 = x0.eq(x0);
    Formula x52 = x1.eq(x1);
    Formula x53 = x2.eq(x2);
    Formula x54 = x3.eq(x3);
    Formula x55 = x4.eq(x4);
    Formula x56 = x5.eq(x5);
    Formula x57 = x6.eq(x6);
    Formula x58 = x7.eq(x7);
    Formula x59 = x8.eq(x8);
    Formula x60 = x9.eq(x9);
    IntExprReduction ier = new IntExprReduction();
    Formula[] formulas =
        ier.reduceIntExpressions(
            x11, x19, x22, x29, x31, x38, x40, x51, x52, x53, x54, x55, x56, x57, x58, x59, x60);
    Formula newFormula = Formula.compose(FormulaOperator.AND, formulas);
    ier.solve(newFormula, bounds, factory, universe, 32);
  }
Beispiel #14
0
 /**
  * Returns the declaration constraints.
  *
  * @return declaration constraints
  */
 public final Formula decls() {
   // File and Dir partition object
   final Formula f0 = Obj.eq(File.union(Dir)).and(File.intersection(Dir).no());
   // Root and Cur are in Dir and do not intersect
   final Formula f1 = Root.in(Dir).and(Cur.in(Dir)).and(Root.intersection(Cur).no());
   // don't need to specify that Dir, Name, and DirEntry are disjoint; implied by bounds
   final Formula f2 = entries.in(Dir.product(DirEntry));
   final Formula f3 = parent.partialFunction(Dir, Dir);
   final Formula f4 = name.function(DirEntry, Name);
   final Formula f5 = contents.function(DirEntry, Obj);
   return f0.and(f1).and(f2).and(f3).and(f4).and(f5);
 }
Beispiel #15
0
 /** Constructs a new instance of the file system problem. */
 public FileSystem() {
   Obj = Relation.unary("Object");
   Name = Relation.unary("Name");
   File = Relation.unary("File");
   Dir = Relation.unary("Dir");
   Root = Relation.unary("Root");
   Cur = Relation.unary("Cur");
   DirEntry = Relation.unary("DirEntry");
   entries = Relation.binary("entries");
   parent = Relation.binary("parent");
   name = Relation.binary("name");
   contents = Relation.binary("contents");
 }
Beispiel #16
0
 /**
  * Returns the no aliases assertion.
  *
  * @return the no aliases assertion.
  */
 public final Formula noDirAliases() {
   // all o: Dir | lone o.~contents
   final Variable o = Variable.unary("o");
   return o.join(contents.transpose()).lone().forAll(o.oneOf(Dir));
 }