Java Code Examples for kodkod.instance.Bounds#bound()

The following examples show how to use kodkod.instance.Bounds#bound() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: EnumerationTest.java    From org.alloytools.alloy with Apache License 2.0 6 votes vote down vote up
public final void testTrivial() {
    final Relation r = Relation.unary("r");
    final Universe u = new Universe(Arrays.asList("a", "b", "c"));
    final TupleFactory f = u.factory();
    final Bounds b = new Bounds(u);
    b.bound(r, f.setOf("a"), f.allOf(1));
    final Formula someR = r.some();

    Iterator<Solution> sol = solver.solveAll(someR, b);
    // has a trivial instance, followed by 2 non-trivial instances
    assertEquals(Solution.Outcome.TRIVIALLY_SATISFIABLE, sol.next().outcome());
    assertEquals(Solution.Outcome.SATISFIABLE, sol.next().outcome());
    assertEquals(Solution.Outcome.SATISFIABLE, sol.next().outcome());
    assertEquals(Solution.Outcome.UNSATISFIABLE, sol.next().outcome());
    assertFalse(sol.hasNext());

}
 
Example 2
Source File: ToyLists.java    From org.alloytools.alloy with Apache License 2.0 6 votes vote down vote up
/**
 * Returns the bounds for the toy lists problem with the given number of lists
 * and things.
 *
 * @return bounds for the toy lists problem with the given number of lists and
 *         things.
 */
public Bounds bounds(int lists, int things) {
    final List<String> atoms = new ArrayList<String>(lists + things);
    for (int i = 0; i < lists; i++) {
        atoms.add("list" + i);
    }
    for (int i = 0; i < things; i++) {
        atoms.add("thing" + i);
    }
    final Universe univ = new Universe(atoms);
    final TupleFactory f = univ.factory();
    final Bounds b = new Bounds(univ);

    b.bound(list, f.range(f.tuple("list0"), f.tuple("list" + (lists - 1))));
    b.bound(nonEmptyList, b.upperBound(list));
    b.bound(emptyList, b.upperBound(list));

    b.bound(thing, f.range(f.tuple("thing0"), f.tuple("thing" + (things - 1))));

    b.bound(car, b.upperBound(nonEmptyList).product(b.upperBound(thing)));
    b.bound(cdr, b.upperBound(nonEmptyList).product(b.upperBound(list)));
    b.bound(equivTo, b.upperBound(list).product(b.upperBound(list)));
    b.bound(prefixes, b.upperBound(list).product(b.upperBound(list)));

    return b;
}
 
Example 3
Source File: Pigeonhole.java    From kodkod with MIT License 6 votes vote down vote up
/**
 * Returns the bounds for the given number of pigeons and holes.
 * @return bounds
 */
public Bounds bounds(int pigeons, int holes) {
	final List<String> atoms = new ArrayList<String>(pigeons + holes);
	for(int i = 0; i < pigeons; i++) {
		atoms.add("Pigeon"+i);
	}
	for(int i = 0; i < holes; i++) {
		atoms.add("Hole"+i);
	}
	final Universe u = new Universe(atoms);
	final TupleFactory f = u.factory();
	
	final Bounds b = new Bounds(u);
	
	final TupleSet pbound = f.range(f.tuple("Pigeon0"), f.tuple("Pigeon" + (pigeons-1)));
	final TupleSet hbound = f.range(f.tuple("Hole0"), f.tuple("Hole" + (holes-1)));
	b.boundExactly(Pigeon, pbound);
	b.boundExactly(Hole, hbound);
	b.bound(hole, pbound.product(hbound));
	return b;
}
 
Example 4
Source File: Viktor.java    From kodkod with MIT License 6 votes vote down vote up
/**
 * Returns the bounds for the problem.
 * @return bounds
 */
public final Bounds bounds() {
	List<String> atoms = new ArrayList<String>(cols+1);
	for(int i = 0; i < cols; i++) {
		atoms.add(String.valueOf(i));
	}
	atoms.add("a");
	final Universe u = new Universe(atoms);
	final TupleFactory f = u.factory();
	final Bounds b = new Bounds(u);
	
	final TupleSet abound = f.setOf("a");
	for(int i = 0; i < rows; i++) {
		for(int j = 0; j < cols; j++) {
			b.bound(a[i][j], abound);
		}
	}
	final TupleSet xbound = f.range(f.tuple(String.valueOf(0)), f.tuple(String.valueOf(cols-1)));
	for(int j = 0; j < cols; j++) {
		b.bound(x[j], xbound);
		b.boundExactly(j, f.setOf(String.valueOf(j)));
	}
	
	return b;
}
 
Example 5
Source File: NQueens.java    From kodkod with MIT License 6 votes vote down vote up
/**
 * Returns a bounds for the explicit integer encoding.
 * @requires n > 0
 * @return bounds for the explicit integer encoding.
 */
public Bounds bounds() { 
	
	final List<Integer> atoms = new ArrayList<Integer>(n);
	for(int i =0; i < n; i++) { 
		atoms.add(Integer.valueOf(i));
	}
	
	final Universe u = new Universe(atoms);
	final Bounds b = new Bounds(u);
	final TupleFactory f = u.factory();
	
	b.boundExactly(queen, f.allOf(1));
	b.bound(x, f.allOf(2));
	b.bound(y, f.allOf(2));
	
	for(int i = 0; i < n; i++) { 
		b.boundExactly(i, f.setOf(Integer.valueOf(i)));
	}
	
	return b;
}
 
Example 6
Source File: IncrementalSolverTest.java    From kodkod with MIT License 6 votes vote down vote up
@Test
public void testBadBounds() {
	final Bounds b = new Bounds(new Universe("A0", "A1", "A2"));
	final TupleFactory t = b.universe().factory();
	final Relation r0 = Relation.unary("r0");
	final Relation r1 = Relation.unary("r1");
	b.bound(r0, t.setOf("A0"));
	final Solution sol = solver.solve(r0.some(), b);
	assertEquals(SATISFIABLE, sol.outcome());
	b.bound(r1, t.setOf("A1"));
	try {
		solver.solve(r1.some(), b);
		fail("Expected an IllegalArgumentException when solving with bounds that do not induce a coarser set of symmetries than the initial bounds.");
	} catch (IllegalArgumentException iae) {
		// fine
	}
	assertFalse(solver.usable());
}
 
Example 7
Source File: Quasigroups7.java    From kodkod with MIT License 5 votes vote down vote up
/**
 * Returns the partial bounds the problem (axioms 1, 4, 9-11).
 * @return the partial bounds for the problem
 */
public Bounds bounds() {
	final List<String> atoms = new ArrayList<String>(14);
	for(int i = 0; i < 7; i++)
		atoms.add("e1"+i);
	for(int i = 0; i < 7; i++)
		atoms.add("e2"+i);
	
	final Universe u = new Universe(atoms);
	final Bounds b = new Bounds(u);
	final TupleFactory f = u.factory();
	
	b.boundExactly(s1, f.range(f.tuple("e10"), f.tuple("e16")));
	b.boundExactly(s2, f.range(f.tuple("e20"), f.tuple("e26")));
	
	// axioms 9, 10, 11
	for(int i = 0; i < 7; i++) {
		b.boundExactly(e1[i], f.setOf("e1"+i));
		b.boundExactly(e2[i], f.setOf("e2"+i));
	}
	
	// axom 1
	final TupleSet op1h = f.area(f.tuple("e10", "e10", "e10"), f.tuple("e16", "e16", "e16"));
	// axiom 4
	final TupleSet op2h = f.area(f.tuple("e20", "e20", "e20"), f.tuple("e26", "e26", "e26"));
	
	b.bound(op1, op1h);
	b.bound(op2, op2h);
	
	return b;
}
 
Example 8
Source File: BasicUniverse.java    From quetzal with Eclipse Public License 2.0 5 votes vote down vote up
protected void bound(Set<Relation> liveRelations, Set<Object> liveAtoms, Bounds b, Relation r, LazyTupleSet lower, LazyTupleSet upper) throws URISyntaxException {
	if (liveRelations == null || liveRelations.contains(r)) {
		TupleSet ls = lower.tuples();
		TupleSet us = upper.tuples();
		b.bound(r, ls, us);
		collectAtoms(liveAtoms, ls);
		collectAtoms(liveAtoms, us);
	}
}
 
Example 9
Source File: MagicSeries.java    From kodkod with MIT License 5 votes vote down vote up
/**
	 * Bounds for a series with the given maximum.
	 * @return bounds for a series with the given maximum.
	 */
	public final Bounds bounds(int max) { 
		if (max<1) throw new IllegalArgumentException("max must be 1 or greater: " + max);
		final List<Integer> atoms = new ArrayList<Integer>(max);
		for(int i = 0; i <= max; i++) { 
			atoms.add(i);
		}
		final Universe u = new Universe(atoms);
		final TupleFactory f = u.factory();
		final Bounds b = new Bounds(u);
		b.boundExactly(num, f.allOf(1));
		final int numBits = 32-Integer.numberOfLeadingZeros(max);
		final TupleSet bitAtoms = f.noneOf(1);
		for(int i = 0; i < numBits; i++) { 
			bitAtoms.add(f.tuple(1<<i));
			b.boundExactly(1<<i, f.setOf(1<<i));
		}
		b.bound(el, f.allOf(1).product(bitAtoms));
		final TupleSet num2bits = f.noneOf(2);
		for(int i = 0; i <= max; i++) { 
			for(int j = 0; j < numBits; j++) { 
				final int bit = 1<<j;
				if ((i&bit)!=0) num2bits.add(f.tuple((Object)i, bit));
			}
		}
		b.boundExactly(bits, num2bits);
//		b.bound(el, f.allOf(2));
//		for(int i = 0; i<=max; i++) { 
//			b.boundExactly(i, f.setOf(i));
//		}
		return b;
	}
 
Example 10
Source File: Transpose4x4UnaryL.java    From kodkod with MIT License 5 votes vote down vote up
/**
 * Returns relation bounds over a universe of interpretation consisting of integers 0 - 15, inclusive.
 * @return relation bounds over a universe of interpretation consisting of integers 0 - 15, inclusive.
 */
final Bounds bounds() {
	final Universe u = new Universe(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15);
	final TupleFactory f = u.factory();
	
	final Bounds b = new Bounds(u);
	
	// tell the solver to interpret integer objects as their corresponding integer values
	for (int i = 0; i < 16; i++)
		b.boundExactly(i, f.setOf(i));
	
	final TupleSet s3 = f.setOf(0, 1, 2, 3);        										// { 0, 1, 2, 3 }
	final TupleSet s12 = f.setOf(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12); 	// { 0, ..., 12 }
	for(int i = 0; i < 4; i++) {
		b.bound(mx1[i], s12);
		b.bound(mx2[i], s12);		
		b.bound(sx1[i], s12);
		b.bound(sx2[i], s12);
		for(int j = 0; j < 4; j++) {
			b.bound(mi[i][j], s3);
			b.bound(si[i][j], s3);
		}
	}
	
	final TupleSet ord = f.noneOf(2);  				// { [0, 1], [1, 2], [2, 3], ..., [14, 15] }
	for(int i = 0; i < 15; i++)
		ord.add(f.tuple((Object)i, i+1));
	b.boundExactly(succ, ord);
	
	return b;
}
 
Example 11
Source File: BugTests.java    From org.alloytools.alloy with Apache License 2.0 5 votes vote down vote up
public final void testFelix_05152007_1() {
    Relation x5 = Relation.nary("A", 1);

    List<String> atomlist = Arrays.asList("A0", "A1", "A2");

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

    TupleSet x5_upper = factory.noneOf(1);
    x5_upper.add(factory.tuple("A2"));
    x5_upper.add(factory.tuple("A1"));
    x5_upper.add(factory.tuple("A0"));

    bounds.bound(x5, x5_upper);

    Formula x7 = x5.some();
    Formula x8 = x5.no();

    Formula x6 = x7.and(x8);

    Solver solver = new Solver();
    solver.options().setLogTranslation(1);

    solver.options().setSolver(SATFactory.MiniSatProver);
    solver.options().setBitwidth(4);
    solver.options().setIntEncoding(Options.IntEncoding.TWOSCOMPLEMENT);

    Solution sol = solver.solve(x6, bounds);

    // System.out.println("Sol="+sol);

    Set<Formula> core = Nodes.minRoots(x6, sol.proof().highLevelCore().values());
    assertEquals(2, core.size());
    assertTrue(core.contains(x7));
    assertTrue(core.contains(x8));

}
 
Example 12
Source File: Quasigroups7.java    From org.alloytools.alloy with Apache License 2.0 5 votes vote down vote up
/**
 * Returns the partial bounds the problem (axioms 1, 4, 9-11).
 *
 * @return the partial bounds for the problem
 */
public Bounds bounds() {
    final List<String> atoms = new ArrayList<String>(14);
    for (int i = 0; i < 7; i++)
        atoms.add("e1" + i);
    for (int i = 0; i < 7; i++)
        atoms.add("e2" + i);

    final Universe u = new Universe(atoms);
    final Bounds b = new Bounds(u);
    final TupleFactory f = u.factory();

    b.boundExactly(s1, f.range(f.tuple("e10"), f.tuple("e16")));
    b.boundExactly(s2, f.range(f.tuple("e20"), f.tuple("e26")));

    // axioms 9, 10, 11
    for (int i = 0; i < 7; i++) {
        b.boundExactly(e1[i], f.setOf("e1" + i));
        b.boundExactly(e2[i], f.setOf("e2" + i));
    }

    // axom 1
    final TupleSet op1h = f.area(f.tuple("e10", "e10", "e10"), f.tuple("e16", "e16", "e16"));
    // axiom 4
    final TupleSet op2h = f.area(f.tuple("e20", "e20", "e20"), f.tuple("e26", "e26", "e26"));

    b.bound(op1, op1h);
    b.bound(op2, op2h);

    return b;
}
 
Example 13
Source File: RingElection.java    From kodkod with MIT License 5 votes vote down vote up
/**
 * Returns a bounds object that scopes Process, Time, and their
 * fields according to given values.
 * @return bounds
 */
public Bounds bounds(int processes, int times) {
	final List<String> atoms = new ArrayList<String>(processes + times);
	for(int i = 0; i < processes; i++) {
		atoms.add("Process"+i);
	}
	for(int i = 0; i < times; i++) {
		atoms.add("Time"+i);
	}
	final Universe u = new Universe(atoms);
	final TupleFactory f = u.factory();
	final Bounds b = new Bounds(u);
	
	final TupleSet pb = f.range(f.tuple("Process0"), f.tuple("Process"+ (processes-1)));
	final TupleSet tb = f.range(f.tuple("Time0"), f.tuple("Time"+(times-1)));
	
	b.bound(Process, pb);
	b.bound(succ, pb.product(pb));
	b.bound(toSend, pb.product(pb).product(tb));
	b.bound(elected, pb.product(tb));
	b.bound(pord, pb.product(pb));
	b.bound(pfirst, pb);
	b.bound(plast, pb);
	
	b.bound(Time, tb);
	b.bound(tord, tb.product(tb));
	b.bound(tfirst, tb);
	b.bound(tlast, tb);
	
	return b;
}
 
Example 14
Source File: ALG195_1.java    From org.alloytools.alloy with Apache License 2.0 5 votes vote down vote up
/**
 * Returns the partial bounds the problem (axioms 1, 4, 9-11).
 *
 * @return the partial bounds for the problem
 */
public Bounds bounds() {
    final List<String> atoms = new ArrayList<String>(14);
    for (int i = 0; i < 7; i++)
        atoms.add("e1" + i);
    for (int i = 0; i < 7; i++)
        atoms.add("e2" + i);

    final Universe u = new Universe(atoms);
    final Bounds b = new Bounds(u);
    final TupleFactory f = u.factory();

    final TupleSet s1bound = f.range(f.tuple("e10"), f.tuple("e16"));
    final TupleSet s2bound = f.range(f.tuple("e20"), f.tuple("e26"));

    b.boundExactly(s1, s1bound);
    b.boundExactly(s2, s2bound);

    // axioms 9, 10, 11
    for (int i = 0; i < 7; i++) {
        b.boundExactly(e1[i], f.setOf("e1" + i));
        b.boundExactly(e2[i], f.setOf("e2" + i));
    }

    // axom 1
    b.bound(op1, f.area(f.tuple("e10", "e10", "e10"), f.tuple("e16", "e16", "e16")));
    // axiom 4
    b.bound(op2, f.area(f.tuple("e20", "e20", "e20"), f.tuple("e26", "e26", "e26")));

    final TupleSet hbound = s1bound.product(s2bound);
    for (Relation r : h) {
        b.bound(r, hbound);
    }

    return b;
}
 
Example 15
Source File: GEO159.java    From org.alloytools.alloy with Apache License 2.0 5 votes vote down vote up
/**
 * Returns a bounds with the given number of maximum curves and points
 *
 * @return a bounds with the given number of maximum curves and points
 */
@Override
public Bounds bounds(int scope) {
    final Bounds b = super.bounds(scope);
    final TupleSet c = b.upperBound(curve);
    final TupleSet p = b.upperBound(point);
    b.bound(between, c.product(p).product(p).product(p));
    return b;
}
 
Example 16
Source File: ListEncoding.java    From kodkod with MIT License 5 votes vote down vote up
Bounds bounds(int size) {			 
	
	final Universe u = universe(size);
	final Bounds b = new Bounds(u);
	final TupleFactory t = u.factory();
	final int max = size-1;
	
	b.bound(list, t.setOf("l0"));
	b.bound(node, t.range(t.tuple("n0"), t.tuple("n" + max)));
	b.bound(string, t.range(t.tuple("s0"), t.tuple("s" + max)));
	b.bound(thisList, b.upperBound(list));
	b.boundExactly(nil, t.setOf("nil"));
	
	TupleSet ran = t.range(t.tuple("n0"), t.tuple("n" + max)); 
	ran.add(t.tuple("nil"));
	b.bound(head, b.upperBound(list).product(ran));
	
	ran = t.range(t.tuple("n0"), t.tuple("n" + max)); 
	ran.add(t.tuple("nil"));
	b.bound(next, b.upperBound(node).product(ran));
	
	ran = t.range(t.tuple("s0"), t.tuple("s" + max)); 
	ran.add(t.tuple("nil"));
	b.bound(data, b.upperBound(node).product(ran));
	
	return b;
}
 
Example 17
Source File: RegressionTests.java    From kodkod with MIT License 4 votes vote down vote up
@Test
public final void testFelix_06192008() {
	Relation x5 = Relation.unary("R");

	List<String> atomlist = Arrays.asList("X");

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

	TupleSet x5_upper = factory.noneOf(1);
	x5_upper.add(factory.tuple("X"));
	bounds.bound(x5, x5_upper);

	Variable x10=Variable.unary("a");
	Expression x11=x5.difference(x5);
	Decls x9=x10.oneOf(x11);
	Variable x14=Variable.nary("b",2);
	Expression x15=x5.product(x5);
	Decls x13=x14.setOf(x15);
	Expression x19=x5.product(x5);
	Formula x17=x14.in(x19);
	Expression x22=x10.product(x10);
	Formula x21=x22.eq(x14);
	Formula x16=x17.and(x21);
	Formula x12=x16.forSome(x13);
	Formula x7= x12.forAll(x9);

	//		System.out.println(x7);

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

	//		System.out.println("Depth=0..."); System.out.flush();
	solver.options().setSkolemDepth(0);
	assertEquals(Solution.Outcome.TRIVIALLY_SATISFIABLE, solver.solve(x7, bounds).outcome());

	//		System.out.println("Depth=1..."); System.out.flush();
	solver.options().setSkolemDepth(1);
	final Solution sol = solver.solve(x7, bounds);
	assertEquals(Solution.Outcome.SATISFIABLE, sol.outcome());
	assertEquals(2, sol.instance().relations().size());
	for(Relation r : sol.instance().relations()) { 
		assertTrue(sol.instance().tuples(r).isEmpty());
	}
}
 
Example 18
Source File: ALG195.java    From org.alloytools.alloy with Apache License 2.0 4 votes vote down vote up
/**
 * Returns the bounds the problem (axioms 1, 4, 9-13, second formula of 14-15,
 * and first formula of 16-22).
 *
 * @return the bounds for the problem
 */
@Override
public final Bounds bounds() {
    final Bounds b = super.bounds();
    final TupleFactory f = b.universe().factory();

    final TupleSet op1h = b.upperBound(op1).clone();
    final TupleSet op2h = b.upperBound(op2).clone();

    for (int i = 0; i < 7; i++) {
        op1h.remove(f.tuple("e1" + i, "e1" + i, "e1" + i)); // axiom 12
        op2h.remove(f.tuple("e2" + i, "e2" + i, "e2" + i)); // axiom 13
    }

    final TupleSet op1l = f.setOf(f.tuple("e15", "e15", "e11")); // axiom
                                                                // 14,
                                                                // line
                                                                // 2
    final TupleSet op2l = f.setOf(f.tuple("e25", "e25", "e21")); // axiom
                                                                // 15,
                                                                // line
                                                                // 2

    op1h.removeAll(f.area(f.tuple("e15", "e15", "e10"), f.tuple("e15", "e15", "e16")));
    op1h.addAll(op1l);

    op2h.removeAll(f.area(f.tuple("e25", "e25", "e20"), f.tuple("e25", "e25", "e26")));
    op2h.addAll(op2l);

    b.bound(op1, op1l, op1h);
    b.bound(op2, op2l, op2h);

    final TupleSet high = f.area(f.tuple("e10", "e20"), f.tuple("e14", "e26"));
    high.addAll(f.area(f.tuple("e16", "e20"), f.tuple("e16", "e26")));

    // first line of axioms 16-22
    for (int i = 0; i < 7; i++) {
        Tuple t = f.tuple("e15", "e2" + i);
        high.add(t);
        b.bound(h[i], f.setOf(t), high);
        high.remove(t);
    }

    return b;
}
 
Example 19
Source File: IntConstraints.java    From org.alloytools.alloy with Apache License 2.0 4 votes vote down vote up
/**
 * Returns a bounds for the problem.
 */
public final Bounds bounds() {
    final List<Integer> atoms = new ArrayList<Integer>(14);
    for (int i = 0; i < 32; i++) {
        atoms.add(Integer.valueOf(1 << i));
    }

    final Universe u = new Universe(atoms);
    final TupleFactory f = u.factory();
    final Bounds b = new Bounds(u);

    // bound the integers
    for (int i = 0; i < 32; i++) {
        b.boundExactly(1 << i, f.setOf(Integer.valueOf(1 << i)));
    }

    // bound the relations, making sure to specify the partial
    // instance based on the low/high range for each variable.
    for (int i = 0; i < 1000; i++) {
        TupleSet lower = f.noneOf(1), upper = f.noneOf(1);
        int min = low + i * 10, max = min + 10, bit = 31;

        // get the common high order bit pattern into lower/upper bound
        // constraints
        while (bit >= 0) {
            int bitVal = 1 << bit;
            if ((min & bitVal) == (max & bitVal)) {
                if ((min & bitVal) != 0) {
                    Tuple bitTuple = f.tuple(Integer.valueOf(bitVal));
                    lower.add(bitTuple);
                    upper.add(bitTuple);
                }
            } else {
                break; // get out of the loop as soon as patterns diverge
            }
            bit--;
        }

        // the bits on which min/max disagree should be variables, so put
        // them into upper bound but not lower
        while (bit >= 0) {
            upper.add(f.tuple(Integer.valueOf(1 << bit)));
            bit--;
        }

        b.bound(var[i], lower, upper);

    }

    return b;
}
 
Example 20
Source File: BugTests.java    From org.alloytools.alloy with Apache License 2.0 4 votes vote down vote up
public final void testFelix_03162009() {
    Relation x = Relation.unary("X");
    Relation y = Relation.unary("Y");
    Relation q = Relation.unary("Q");
    Relation f = Relation.nary("f", 2);

    List<String> atomlist = Arrays.asList("X", "Y");

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

    TupleSet x_upper = factory.noneOf(1);
    x_upper.add(factory.tuple("X"));
    bounds.boundExactly(x, x_upper);

    TupleSet y_upper = factory.noneOf(1);
    y_upper.add(factory.tuple("Y"));
    bounds.boundExactly(y, y_upper);

    TupleSet q_upper = factory.noneOf(1);
    q_upper.add(factory.tuple("X"));
    q_upper.add(factory.tuple("Y"));
    bounds.bound(q, q_upper);

    TupleSet f_upper = factory.noneOf(2);
    f_upper.add(factory.tuple("X").product(factory.tuple("X")));
    f_upper.add(factory.tuple("X").product(factory.tuple("Y")));
    f_upper.add(factory.tuple("Y").product(factory.tuple("X")));
    f_upper.add(factory.tuple("Y").product(factory.tuple("Y")));
    bounds.bound(f, f_upper);

    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);

    Expression test = f.override(q.product(y));
    TupleSet approx = factory.setOf(test.arity(), Translator.approximate(test, bounds, solver.options()).denseIndices());
    assertEquals(f_upper, approx);
}