kodkod.ast.Formula Java Examples

The following examples show how to use kodkod.ast.Formula. 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: Drivers.java    From quetzal with Eclipse Public License 2.0 6 votes vote down vote up
public static TupleSet check(UniverseFactory uf,
		Pair<Formula, Pair<Formula, Formula>> answer,
		String relation)
		throws URISyntaxException {
	Instance rels = check(uf, answer);
	if (rels != null) {
		for(Relation r : rels.relations()) {
			if (r.toString().equals(relation)) {
				return rels.tuples(r);
			}
		}
		return null;
	} else {
		return null;
	}
}
 
Example #2
Source File: ResolutionBasedProof.java    From org.alloytools.alloy with Apache License 2.0 6 votes vote down vote up
/**
 * {@inheritDoc}
 *
 * @see kodkod.engine.Proof#core()
 */
@Override
public final Iterator<TranslationRecord> core() {
    if (coreFilter == null) {
        coreFilter = new RecordFilter() {

            final IntSet       coreVariables = StrategyUtils.coreVars(solver.proof());
            final Set<Formula> coreNodes     = connectedCore(coreVariables);

            @Override
            public boolean accept(Node node, Formula translated, int literal, Map<Variable,TupleSet> env) {
                return coreNodes.contains(translated) && coreVariables.contains(StrictMath.abs(literal));
            }
        };
    }
    return log().replay(coreFilter);
}
 
Example #3
Source File: HOLSolver.java    From org.alloytools.alloy with Apache License 2.0 6 votes vote down vote up
@Override
public Iterator<Solution> solveAll(final Formula formula, final Bounds bounds) throws HigherOrderDeclException, UnboundLeafException, AbortedException {
    return new Iterator<Solution>() {

        private Solution lastSol = null;

        @Override
        public boolean hasNext() {
            return lastSol == null || lastSol.sat();
        }

        @Override
        public Solution next() {
            if (!hasNext())
                throw new NoSuchElementException();
            lastSol = (lastSol == null) ? solve(formula, bounds) : solveNext();
            return lastSol;
        }

        @Override
        public void remove() {
            throw new IllegalStateException("can't remove solution");
        }
    };
}
 
Example #4
Source File: DNACuts.java    From org.alloytools.alloy with Apache License 2.0 6 votes vote down vote up
/**
 * Usage: java examples.alloy.DNACuts [cut chain length] [# links]
 */
public static void main(String[] args) {
    if (args.length < 2)
        usage();

    try {
        final DNACuts model = new DNACuts(Integer.parseInt(args[0]));
        final Solver solver = new Solver();
        solver.options().setSolver(SATFactory.DefaultSAT4J);
        Formula f = model.show();
        Bounds b = model.bounds(Integer.parseInt(args[1]));
        System.out.println("solving...");
        Solution sol = solver.solve(f, b);
        // System.out.println(f);
        // System.out.println(b);
        System.out.println(sol.outcome());
        System.out.println(sol.stats());
    } catch (NumberFormatException nfe) {
        usage();
    }
}
 
Example #5
Source File: CeilingsAndFloors.java    From kodkod with MIT License 6 votes vote down vote up
/**
 * Usage: java examples.CeilingsAndFloors [# men] [# platforms]
 */
public static void main(String[] args) {
	if (args.length < 2) usage();
	
	final CeilingsAndFloors model = new CeilingsAndFloors();
	final Solver solver = new Solver();
	solver.options().setSolver(SATFactory.MiniSat);
	try {
		final int m = Integer.parseInt(args[0]);
		final int p = Integer.parseInt(args[1]);
		final Formula show = model.checkBelowTooDoublePrime();
		final Solution sol = solver.solve(show, model.bounds(m,p));
		System.out.println(show);
		System.out.println(sol);
		
	} catch (NumberFormatException nfe) {
		usage();
	}
}
 
Example #6
Source File: TranslateAlloyToKodkod.java    From org.alloytools.alloy with Apache License 2.0 6 votes vote down vote up
/**
 * Helper method that merge a list of conjuncts or disjoints while minimizing
 * the AST depth (external caller should use i==1)
 */
private Formula getSingleFormula(boolean isConjunct, int i, List<Expr> formulas) throws Err {
    // We actually build a "binary heap" where node X's two children are
    // node 2X and node 2X+1
    int n = formulas.size();
    if (n == 0)
        return isConjunct ? Formula.TRUE : Formula.FALSE;
    Formula me = cform(formulas.get(i - 1)), other;
    int child1 = i + i, child2 = child1 + 1;
    if (child1 < i || child1 > n)
        return me;
    other = getSingleFormula(isConjunct, child1, formulas);
    if (isConjunct)
        me = me.and(other);
    else
        me = me.or(other);
    if (child2 < 1 || child2 > n)
        return me;
    other = getSingleFormula(isConjunct, child2, formulas);
    if (isConjunct)
        me = me.and(other);
    else
        me = me.or(other);
    return me;
}
 
Example #7
Source File: TOP020.java    From org.alloytools.alloy with Apache License 2.0 6 votes vote down vote up
/**
 * Usage: java examples.tptp.TOP020 [univ size]
 */
public static void main(String[] args) {
    if (args.length < 1)
        usage();

    try {
        final int n = Integer.parseInt(args[0]);
        if (n < 1)
            usage();
        final TOP020 model = new TOP020();
        final Solver solver = new Solver();
        solver.options().setSolver(SATFactory.MiniSat);
        final Formula f = model.checkChallenge_AMR_1_4_4();
        final Bounds b = model.bounds(n);
        // System.out.println(f);
        // System.out.println(b);
        final Solution sol = solver.solve(f, b);
        System.out.println(sol);
    } catch (NumberFormatException nfe) {
        usage();
    }
}
 
Example #8
Source File: MED001.java    From kodkod with MIT License 5 votes vote down vote up
/**
 * Returns the sn_cure_1 axiom.
 * @return sn_cure_1
 */
public final Formula sn_cure_1() {
	final Variable x0 = Variable.unary("X0");
	final Expression x1 = UNIV.difference(x0.join(gt));
	final Formula f0 = x1.in(bsecretioni).and(x0.in(bcapacitysn)).
		and(x0.in(qilt27)).and(x0.join(gt).in(conditionhyper));
	return f0.implies(x1.in(conditionnormo)).forAll(x0.oneOf(UNIV));
}
 
Example #9
Source File: LAT258.java    From kodkod with MIT License 5 votes vote down vote up
/**
 * Returns the upper_bound_join axiom.
 * @return the upper_bound_join axiom.
 */
public final Formula upperBoundJoin() {
	final Variable c = Variable.unary("C");
	final Expression e0 = lessThan.join(c);
	final Formula f0 = join.join(c).in(e0.product(e0));
	// all c: univ | join.c in lessThan.c->lessThan.c
	return f0.forAll(c.oneOf(UNIV));
}
 
Example #10
Source File: DNACuts.java    From kodkod with MIT License 5 votes vote down vote up
/**
 * Returns the cutLinkUniqueness constraint.
 * @return the cutLinkUniqueness constraint.
 */
public Formula cutLinkUniqueness() {
	final Variable c1 = Variable.unary("c1");
	final Variable c2 = Variable.unary("c2");
	final Formula f0 = c1.eq(c2).not().and(next.join(c1).in(JoinLink)).and(next.join(c2).in(JoinLink));
	Formula f = c1.join(base).in(c2.join(base).union(c2.join(base).join(partner))).not();
	for(int i = 0; i < neighbor.length; i++) {
		Expression c1n = c1.join(neighbor[i]), c2n = c2.join(neighbor[i]);
		f = f.or(c1n.in(JoinLink)).or(c2n.in(JoinLink));
		f = f.or(c1n.join(base).in(c2n.join(base).union(c2n.join(base).join(partner))).not());
	}
	return f0.implies(f).forAll(c1.oneOf(CutLink).and(c2.oneOf(CutLink)));
}
 
Example #11
Source File: MED001.java    From kodkod with MIT License 5 votes vote down vote up
/**
 * Returns the conjunction of all  axioms.
 * @return conjunction of all  axioms.
 */
public final Formula axioms() { 
	return Formula.and(trans_ax2(), trans_ax3(), transitivity_gt(), decls(), irreflexivity_gt(), 
		normo(), xorcapacity1_4(), xorcondition1_4(), insulin_effect(),
		liver_glucose(), sulfonylurea_effect(), biguanide_effect(), bg_completion(),
		sn_cure_1(), sn_cure_2(), ne_cure(), ex_cure(), su_completion(), 
		xorstep1_7(),  step1_4(), comp(), insulin_completion(),
		uptake_completion(), trans_ax1());
}
 
Example #12
Source File: NUM378.java    From kodkod with MIT License 5 votes vote down vote up
/**
 * Returns the declarations.
 * @return one a && one b && one c
 */
public final Formula decls() { 
	final Variable x = Variable.unary("X");
	final Variable y = Variable.unary("Y");
	return succ.function(UNIV, UNIV).
		and(sum(x,y).one().forAll(x.oneOf(UNIV).and(y.oneOf(UNIV))));
}
 
Example #13
Source File: AbstractReplacer.java    From org.alloytools.alloy with Apache License 2.0 5 votes vote down vote up
/**
 * Calls lookup(binFormula) and returns the cached value, if any. If a
 * replacement has not been cached, visits the formula's children. If nothing
 * changes, the argument is cached and returned, otherwise a replacement formula
 * is cached and returned.
 *
 * @return { b: BinaryFormula | b.left = binExpr.left.accept(delegate) &&
 *         b.right = binExpr.right.accept(delegate) && b.op = binExpr.op }
 */
@Override
public Formula visit(BinaryFormula binFormula) {
    Formula ret = lookup(binFormula);
    if (ret != null)
        return ret;

    final Formula left = binFormula.left().accept(delegate);
    final Formula right = binFormula.right().accept(delegate);
    ret = (left == binFormula.left() && right == binFormula.right()) ? binFormula : left.compose(binFormula.op(), right);
    return cache(binFormula, ret);
}
 
Example #14
Source File: Quasigroups7.java    From org.alloytools.alloy with Apache License 2.0 5 votes vote down vote up
/**
 * Returns lines 2-7 of axioms 16-22.
 *
 * @return lines 2-7 of axioms 16-22.
 */
public final Formula ax16_22() {
    final List<Formula> formulas = new ArrayList<Formula>();
    for (int i = 0; i < 7; i++) {
        formulas.add(ax16_22(e2[i], h[i]));
    }
    return Formula.and(formulas);
}
 
Example #15
Source File: AbstractReplacer.java    From org.alloytools.alloy with Apache License 2.0 5 votes vote down vote up
/**
 * Calls lookup(compFormula) and returns the cached value, if any. If a
 * replacement has not been cached, visits the formula's children. If nothing
 * changes, the argument is cached and returned, otherwise a replacement formula
 * is cached and returned.
 *
 * @return { c: ComparisonFormula | c.left = compFormula.left.accept(delegate)
 *         && c.right = compFormula.right.accept(delegate) && c.op =
 *         compFormula.op }
 */
@Override
public Formula visit(ComparisonFormula compFormula) {
    Formula ret = lookup(compFormula);
    if (ret != null)
        return ret;

    final Expression left = compFormula.left().accept(delegate);
    final Expression right = compFormula.right().accept(delegate);
    ret = (left == compFormula.left() && right == compFormula.right()) ? compFormula : left.compare(compFormula.op(), right);
    return cache(compFormula, ret);
}
 
Example #16
Source File: A4Solution.java    From org.alloytools.alloy with Apache License 2.0 5 votes vote down vote up
/**
 * Add the given formula to the list of Kodkod formulas, and associate it with
 * the given Expr object (expr can be null if unknown)
 */
void addFormula(Formula newFormula, Expr expr) throws Err {
    if (solved)
        throw new ErrorFatal("Cannot add an additional formula since solve() has completed.");
    if (formulas.size() > 0 && formulas.get(0) == Formula.FALSE)
        return; // If one formula is false, we don't need the others
    if (newFormula == Formula.FALSE)
        formulas.clear(); // If one formula is false, we don't need the
                         // others
    formulas.add(newFormula);
    if (expr != null)
        k2pos(newFormula, expr);
}
 
Example #17
Source File: TranslateAlloyToKodkod.java    From org.alloytools.alloy with Apache License 2.0 5 votes vote down vote up
/** {@inheritDoc} */
@Override
public Object visit(ExprITE x) throws Err {
    Formula c = cform(x.cond);
    Object l = visitThis(x.left);
    if (l instanceof Formula) {
        Formula c1 = c.implies((Formula) l);
        Formula c2 = c.not().implies(cform(x.right));
        return k2pos(c1.and(c2), x);
    }
    if (l instanceof Expression) {
        return c.thenElse((Expression) l, cset(x.right));
    }
    return c.thenElse((IntExpression) l, cint(x.right));
}
 
Example #18
Source File: Simplifier.java    From quetzal with Eclipse Public License 2.0 5 votes vote down vote up
/** @return a simplification of left op right, if possible, or null otherwise. */
final Formula simplify(FormulaOperator op, Formula left, Formula right) { 
	switch(op) { 
	case AND : 
		if (left==right)					{ return left; }
		else if (isTrue(left))				{ return right; }
		else if (isTrue(right))				{ return left; } 	
		else if (isFalse(left) || 
				 isFalse(right) || 
				 areInverses(left, right)) 	{ return Formula.FALSE; }
		break;
	case OR : 
		if (left==right)					{ return left; }
		else if (isFalse(left))				{ return right; }
		else if (isFalse(right))			{ return left; } 
		else if (isTrue(left) || 
				 isTrue(right) || 
				 areInverses(left, right)) 	{ return Formula.TRUE; }
		break;
	case IMPLIES : // !left or right
		if (left==right)					{ return Formula.TRUE; }
		else if (isTrue(left))				{ return right; }
		else if (isFalse(right)) 			{ return left; }
		else if (isFalse(left) || 
				 isTrue(right))				{ return Formula.TRUE; }
		break;
	case IFF : // (left and right) or (!left and !right)
		if (left==right)					{ return Formula.TRUE; }
		else if (isTrue(left))				{ return right; }
		else if (isFalse(left))				{ return right.not().accept(this); } 
		else if (isTrue(right))				{ return left; }
		else if (isFalse(right))			{ return left.not().accept(this); }
		else if (areInverses(left, right))	{ return Formula.FALSE; }
		break;
	default :
		Assertions.UNREACHABLE();
	}
	return null;
}
 
Example #19
Source File: DNACuts.java    From org.alloytools.alloy with Apache License 2.0 5 votes vote down vote up
/**
 * Returns the cutLinkUniqueness constraint.
 *
 * @return the cutLinkUniqueness constraint.
 */
public Formula cutLinkUniqueness() {
    final Variable c1 = Variable.unary("c1");
    final Variable c2 = Variable.unary("c2");
    final Formula f0 = c1.eq(c2).not().and(next.join(c1).in(JoinLink)).and(next.join(c2).in(JoinLink));
    Formula f = c1.join(base).in(c2.join(base).union(c2.join(base).join(partner))).not();
    for (int i = 0; i < neighbor.length; i++) {
        Expression c1n = c1.join(neighbor[i]), c2n = c2.join(neighbor[i]);
        f = f.or(c1n.in(JoinLink)).or(c2n.in(JoinLink));
        f = f.or(c1n.join(base).in(c2n.join(base).union(c2n.join(base).join(partner))).not());
    }
    return f0.implies(f).forAll(c1.oneOf(CutLink).and(c2.oneOf(CutLink)));
}
 
Example #20
Source File: Nodes.java    From org.alloytools.alloy with Apache License 2.0 5 votes vote down vote up
/**
 * Returns a minimal subset of {@linkplain #roots(Formula) roots} of the given
 * formula such that all nodes in the given collection are reachable from those
 * roots. The returned subset is a local minimum in that none of its members can
 * be removed without leaving some node in the descendants set unreachable from
 * the remaining roots.
 *
 * @requires descendants in formula.*components
 * @return { s: Set<Formula> | s.elements in roots(formula) and descendants in
 *         s.elements.*components and no s': Set<Formula> | s.containsAll(s')
 *         and s'.size()<s.size() and descendants in s.elements.*components }
 * @throws IllegalArgumentException descendants !in formula.*components
 */
public static Set<Formula> minRoots(Formula formula, Collection< ? extends Node> descendants) {

    final Set<Node> desc = new IdentityHashSet<Node>(descendants);
    final VoidVisitor visitor = new AbstractVoidVisitor() {

        final Set<Node> visited = new IdentityHashSet<Node>();

        @Override
        protected boolean visited(Node n) {
            if (visited.add(n)) {
                desc.remove(n);
                return false;
            }
            return true;
        }
    };

    final Set<Formula> roots = new LinkedHashSet<Formula>();
    for (Formula root : roots(formula)) {
        final int size = desc.size();
        root.accept(visitor);
        if (desc.size() < size) {
            roots.add(root);
        }
        if (desc.isEmpty()) {
            break;
        }
    }

    if (!desc.isEmpty())
        throw new IllegalArgumentException("descendants !in formula.*components: formula=" + formula + " ; descendants=" + descendants);

    return roots;
}
 
Example #21
Source File: MED001.java    From kodkod with MIT License 5 votes vote down vote up
/**
 * Returns the normo axiom.
 * @return normo
 */
public final Formula normo() {
	final Variable x0 = Variable.unary("X0");
	final Expression x1 = UNIV.difference(x0.join(gt));
	final Formula f0 = x1.in(bsecretioni).and(x0.in(bcapacitysn)).
		and(x0.in(qilt27)).and(x0.join(gt).in(conditionhyper));
	final Formula f1 = x1.in(releaselg).not().and(x0.in(bcapacitysn)).
		and(x0.in(qilt27).not()).and(x0.join(gt).in(conditionhyper));
	final Formula f2 = x1.in(releaselg).not().or(x1.in(uptakelg)).and(x0.in(bcapacitysn)).
		and(x1.in(bsecretioni)).and(x0.join(gt).in(conditionhyper));
	final Formula f3 = x1.in(uptakelg).and(x1.in(uptakepg)).
		and(x0.in(bcapacityex)).and(x0.join(gt).in(conditionhyper));
	return x1.in(conditionnormo).implies(f0.or(f1).or(f2).or(f3)).forAll(x0.oneOf(UNIV));
}
 
Example #22
Source File: Simplifier.java    From quetzal with Eclipse Public License 2.0 5 votes vote down vote up
public Formula visit(IntComparisonFormula formula) { 
	Formula ret = lookup(formula);
	if (ret!=null) return ret;
	
	final IntCompOperator op = formula.op();
	final IntExpression left = formula.left().accept(this);
	final IntExpression right = formula.right().accept(this);
	
	if (left==right) return cache(formula,Formula.TRUE);
	
	ret = left==formula.left()&&right==formula.right() ? formula : left.compare(op, right);
	return cache(formula,ret);
}
 
Example #23
Source File: Toughnut.java    From org.alloytools.alloy with Apache License 2.0 5 votes vote down vote up
/**
 * Returns the covering predicate. Note that we don't need to specify the first
 * two lines of the predicate, since they can be expressed as bounds
 * constraints.
 *
 * @return the covering predicate
 */
public Formula checkBelowTooDoublePrime() {
    final Variable x = Variable.unary("x");
    final Variable y = Variable.unary("y");
    final Decls d = x.oneOf(Cell).and(y.oneOf(Cell));
    final Expression xy = y.join(x.join(covered));
    // covering relation is symmetric
    Formula symm = xy.product(x.product(y)).in(covered).forAll(d);
    // each pair of cells on the board should be covered
    // by a domino, which also covers ONE of its neighbors
    Expression xNeighbors = (prev(x).union(next(x))).product(y);
    Expression yNeighbors = x.product(prev(y).union(next(y)));
    Formula covering = (xy.one().and(xy.in(xNeighbors.union(yNeighbors)))).forAll(d);
    return symm.and(covering);
}
 
Example #24
Source File: NUM374.java    From kodkod with MIT License 5 votes vote down vote up
/**
 * Returns the sum_product_distribution axiom.
 * @return sum_product_distribution
 */
public final Formula sumProductDistribution() {
	// ! [X,Y,Z] : product(X,sum(Y,Z)) = sum(product(X,Y),product(X,Z)) )).
	final Variable x = Variable.unary("X");
	final Variable y = Variable.unary("Y");
	final Variable z = Variable.unary("Z");
	return product(x, sum(y, z)).eq(sum(product(x,y),product(x,z))).
		forAll(x.oneOf(UNIV).and(y.oneOf(UNIV)).and(z.oneOf(UNIV)));	
}
 
Example #25
Source File: MED007.java    From org.alloytools.alloy with Apache License 2.0 5 votes vote down vote up
/**
 * Returns transsls2_qilt27 conjecture.
 *
 * @return transsls2_qilt27
 */
public final Formula transsls2_qilt27() {
    final Variable x0 = Variable.unary("X0");
    final Formula f0 = n0.in(s1).and(n0.join(gt).in(conditionhyper)).and(n0.in(bcapacitysn).not()).and(n0.in(qilt27));
    final Formula f1 = n0.product(x0).in(gt).not().and(x0.in(s2)).and(x0.join(gt).in(conditionhyper)).and(x0.in(bcapacityne.union(bcapacityex))).forSome(x0.oneOf(UNIV));
    return f0.implies(f1);
}
 
Example #26
Source File: GEO092.java    From org.alloytools.alloy with Apache License 2.0 5 votes vote down vote up
/**
 * Returns the conjecture proposition_2_14_1.
 *
 * @return proposition_2_14_1
 */
public final Formula proposition2141() {
    // all c1, c2: curve, p: point |
    // p->c1->c2 in meet && c1->c2 in sum.open =>
    // all q: point - p | c1 + c2 !in q.incident
    final Variable c1 = Variable.unary("C1");
    final Variable c2 = Variable.unary("C2");
    final Variable p = Variable.unary("P");
    final Variable q = Variable.unary("Q");
    final Expression e0 = c1.product(c2);
    final Formula f0 = p.product(e0).in(meet).and(e0.in(sum.join(open)));
    final Formula f1 = c1.union(c2).in(q.join(incident)).not().forAll(q.oneOf(point.difference(p)));
    return f0.implies(f1).forAll(c1.oneOf(curve).and(c2.oneOf(curve)).and(p.oneOf(point)));
}
 
Example #27
Source File: SET943.java    From kodkod with MIT License 5 votes vote down vote up
/**
 * Returns t8_xboole_1 axiom.
 * @return t8_xboole_1
 */
public final Formula t8_xboole_1() {
	final Variable a = Variable.unary("A");
	final Variable b = Variable.unary("B");
	final Variable c = Variable.unary("C");
	return subset(a,b).and(subset(c,b)).implies(subset(set_union2(a, c),b)).
			forAll(a.oneOf(UNIV).and(b.oneOf(UNIV)).and(c.oneOf(UNIV)));
}
 
Example #28
Source File: AbstractWorldDefinitions.java    From kodkod with MIT License 5 votes vote down vote up
/**
 * Returns the application of the AbWorldSecureOp predicate.
 * @return application of the AbWorldSecureOp predicate.
 */
public Formula AbWorldSecureOp(Expression s, Expression sprime, Expression a_in, Expression a_out) {
	final Formula f0 = AbOp(a_out);
	final Formula f1 = a_in.in(TransferDetails);

	final Expression e0 = a_in.join(from);
	final Expression e1 = a_in.join(to);
	final Expression e2 = s.join(abAuthPurse).difference(e0).difference(e1);
	final Expression e3 = sprime.join(abAuthPurse).difference(e0).difference(e1);
	final Formula f2 = e2.eq(e3);
	
	final Formula f3 = XiAbPurse(s, sprime, e2);
	
	return Formula.and(f0, f1, f2, f3);
}
 
Example #29
Source File: AbstractWorldDefinitions.java    From kodkod with MIT License 5 votes vote down vote up
/**
 * Applies the XiTransfer predicate to the arguments.
 * @return application of the XiTransfer predicate to the arguments.
 */
public final Formula XiTransfer(Expression p, Expression pprime) {
	final Formula f0 = p.join(from).eq(pprime.join(from));
	final Formula f1 = p.join(to).eq(pprime.join(to));
	final Formula f2 = p.join(value).eq(pprime.join(value));
	return Formula.and(f0, f1, f2);
}
 
Example #30
Source File: SET943.java    From kodkod with MIT License 5 votes vote down vote up
/**
 * Returns d2_xboole_0 axiom.
 * @return d2_xboole_0
 */
public final Formula d2_xboole_0() {
	final Variable a = Variable.unary("A");
	final Variable b = Variable.unary("B");
	final Variable c = Variable.unary("C");
	return c.eq(set_union2(a, b)).iff(in.join(c).eq(in.join(a).union(in.join(b)))).
		forAll(a.oneOf(UNIV).and(b.oneOf(UNIV)).and(c.oneOf(UNIV)));
}