/** * */ package kodkod.examples.tptp; import static kodkod.ast.Expression.UNIV; import java.util.ArrayList; import java.util.List; import kodkod.ast.Decls; import kodkod.ast.Expression; import kodkod.ast.Formula; import kodkod.ast.Relation; import kodkod.ast.Variable; import kodkod.engine.Solution; import kodkod.engine.Solver; import kodkod.engine.satlab.SATFactory; import kodkod.instance.Bounds; import kodkod.instance.TupleFactory; import kodkod.instance.TupleSet; import kodkod.instance.Universe; /** * A KK encoding of NUM378+1.020.015.p from http://www.cs.miami.edu/~tptp/ * * @author Emina Torlak */ public final class NUM378 { private final Relation succ, sum; /** * Constructs a new instance of NUM378. */ public NUM378() { succ = Relation.binary("succ"); sum = Relation.ternary("sum"); } /** * Returns the expression y.(x.sum) * @return y.(x.sum) */ final Expression sum(Expression x, Expression y) { return y.join(x.join(sum)); } /** * Returns the successor of x. * @return x.succ */ final Expression succ(Expression x) { return x.join(succ); } /** * Returns the predecessor of x. * @return succ.x */ final Expression pred(Expression x) { return succ.join(x); } /** * 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)))); } private final Variable[] vars(String name, int size) { final Variable[] vars = new Variable[size]; for(int i = 0; i < size; i++) { vars[i] = Variable.unary(name + i); } return vars; } private final Decls decls(Variable[] vars) { Decls d = vars[0].oneOf(UNIV); for(int i = 1; i < vars.length; i++) { d = d.and(vars[i].oneOf(UNIV)); } return d; } /** * Returns the try_satisfy_this axiom. * @return try_satisfy_this */ public final Formula inequalities() { final Variable[] x = vars("X",16); final Variable[] y = vars("Y",16); final Variable[] npx = vars("NPX",15); final Variable[] nsx = vars("NSX",15); final Variable[] npy = vars("NPY",15); final Variable[] nsy = vars("NSY",15); Expression s21 = succ; for(int i = 1; i < 21; i++) { s21 = s21.join(succ); } Formula f = Formula.TRUE; for(int i = 0; i < 15; i++) { Formula f0 = npx[i].eq(s21.join(x[i])); Formula f1 = nsx[i].eq(x[i].join(s21)); Formula f2 = npy[i].eq(s21.join(y[i])); Formula f3 = nsy[i].eq(y[i].join(s21)); f = f.and(f0).and(f1).and(f2).and(f3); } for(int i = 1; i < 16; i++) { Formula f0 = x[i].eq(sum(sum(pred(x[i-1]),succ(y[i-1])),sum(pred(y[i-1]),succ(x[i-1])))); Formula f1 = y[i].eq(sum(pred(nsx[i-1]),sum(succ(npx[i-1]),sum(pred(nsy[i-1]),succ(npy[i-1]))))); f = f.and(f0).and(f1); } Formula g = Formula.FALSE; for(int i = 12; i < 16; i++) { g = g.or(x[i].eq(y[i]).not()); } return f.and(g). forSome(decls(x).and(decls(y)).and(decls(npx)).and(decls(nsx)).and(decls(npy)).and(decls(nsy))); } /** * Returns the conjunction of the axioms and the hypothesis. * @return axioms() && inequalities() */ public final Formula checkInequalities() { return decls().and(inequalities()); } /** * Returns bounds for the problem. * @return bounds for the problem. */ public final Bounds bounds() { final int n = 21; final List<String> atoms = new ArrayList<String>(n); atoms.add("goal"); for(int i = 0; i < n; i++) atoms.add("n"+i); final Universe u = new Universe(atoms); final Bounds bound = new Bounds(u); final TupleFactory f = u.factory(); final TupleSet succBound = f.noneOf(2); for(int i = 0; i < n; i++) { succBound.add(f.tuple("n"+i,"n"+((i+1)%n))); } bound.boundExactly(succ, succBound); final TupleSet sumBound = f.noneOf(3); for(int i = 0; i < n; i++) { for(int j = 0; j < n; j++) { sumBound.add(f.tuple("n"+i, "n"+j, "n"+((i+j)%n))); } } bound.boundExactly(sum, sumBound); return bound; } private static void usage() { System.out.println("java examples.tptp.NUM378"); System.exit(1); } /** * Usage: java examples.tptp.NUM378 */ public static void main(String[] args) { try { final NUM378 model = new NUM378(); final Solver solver = new Solver(); solver.options().setSolver(SATFactory.MiniSat); final Formula f = model.decls().and(model.inequalities()); final Bounds b = model.bounds(); // System.out.println(f); // System.out.println(b); final Solution sol = solver.solve(f, b); System.out.println(sol.outcome()); System.out.println(sol.stats()); } catch (NumberFormatException nfe) { usage(); } } }