/** * */ package kodkod.examples.tptp; import static kodkod.ast.Expression.UNIV; import java.util.ArrayList; import java.util.List; 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.Universe; /** * A KK encoding of ALG212+1.p from http://www.cs.miami.edu/~tptp/ * @author Emina Torlak */ public final class ALG212 { private final Relation f; /** * Constucts a new instance of ALG212. */ public ALG212() { f = Relation.nary("f", 4); } /** * Returns the declarations. * @return declarations. */ public final Formula decls() { // all x,y,z: univ | one f[x][y][z] final Variable x = Variable.unary("x"); final Variable y = Variable.unary("y"); final Variable z = Variable.unary("z"); final Formula f0 = z.join(y.join(x.join(f))).one(); return f0.forAll(x.oneOf(UNIV).and(y.oneOf(UNIV)).and(z.oneOf(UNIV))); } /** * Returns the majority axiom. * @return majority */ public final Formula majority() { // all x, y: A | f[x][x][y] = x final Variable x = Variable.unary("x"); final Variable y = Variable.unary("y"); return y.join(x.join(x.join(f))).eq(x).forAll(x.oneOf(UNIV).and(y.oneOf(UNIV))); } /** * Returns the permute1 axiom. * @return permute1 */ public final Formula permute1() { // all x, y, z: A | f[x][y][z] = f[z][x][y] final Variable x = Variable.unary("x"); final Variable y = Variable.unary("y"); final Variable z = Variable.unary("z"); final Formula f0 = z.join(y.join(x.join(f))).eq(y.join(x.join(z.join(f)))); return f0.forAll(x.oneOf(UNIV).and(y.oneOf(UNIV)).and(z.oneOf(UNIV))); } /** * Returns the permute2 axiom. * @return permute2 */ public final Formula permute2() { // all x, y, z: A | f[x][y][z] = f[x][z][y] final Variable x = Variable.unary("x"); final Variable y = Variable.unary("y"); final Variable z = Variable.unary("z"); final Formula f0 = z.join(y.join(x.join(f))).eq(y.join(z.join(x.join(f)))); return f0.forAll(x.oneOf(UNIV).and(y.oneOf(UNIV)).and(z.oneOf(UNIV))); } /** * Returns the associativity axiom. * @return associativity */ public final Formula associativity() { // all w, x, y, z: A | f[f[x][w][y]][w][z] = f[x][w][f[y][w][z]] final Variable w = Variable.unary("w"); final Variable x = Variable.unary("x"); final Variable y = Variable.unary("y"); final Variable z = Variable.unary("z"); final Expression e0 = y.join(w.join(x.join(f))); final Expression e1 = z.join(w.join(e0.join(f))); final Expression e2 = z.join(w.join(y.join(f))); final Expression e3 = e2.join(w.join(x.join(f))); return e1.eq(e3).forAll(w.oneOf(UNIV).and(x.oneOf(UNIV)).and(y.oneOf(UNIV)).and(z.oneOf(UNIV))); } /** * Returns the conjuction of all axioms. * @return axioms */ public final Formula axioms() { return decls().and(majority()).and(permute1()).and(permute2()).and(associativity()); } /** * Returns the dist_long conjecture. * @return dist_long */ public final Formula distLong() { // all u, w, x, y, z: A | f[f[x][y][z]][u][w] = f[f[x][u][w]][f[y][u][w]][f[z][u][w]] final Variable u = Variable.unary("u"); final Variable w = Variable.unary("w"); final Variable x = Variable.unary("x"); final Variable y = Variable.unary("y"); final Variable z = Variable.unary("z"); final Expression e0 = z.join(y.join(x.join(f))); final Expression e1 = w.join(u.join(e0.join(f))); final Expression e2 = w.join(u.join(x.join(f))); final Expression e3 = w.join(u.join(y.join(f))); final Expression e4 = w.join(u.join(z.join(f))); final Expression e5 = e4.join(e3.join(e2.join(f))); return e1.eq(e5). forAll(u.oneOf(UNIV).and(w.oneOf(UNIV)).and(x.oneOf(UNIV)).and(y.oneOf(UNIV)).and(z.oneOf(UNIV))); } /** * Returns the conjunction of the axioms and the negation of the hypothesis. * @return axioms() && !distLong() */ public final Formula checkDistLong() { return axioms().and(distLong().not()); } /** * Returns the bounds for the given scope. * @return bounds for the given scope */ public final Bounds bounds(int n) { assert n > 0; final List<String> atoms = new ArrayList<String>(n); for(int i = 0; i < n; i++) atoms.add("a"+i); final Universe u = new Universe(atoms); final Bounds b = new Bounds(u); b.bound(f, u.factory().allOf(4)); return b; } private static void usage() { System.out.println("java examples.tptp.ALG212 [univ size]"); System.exit(1); } /** * Usage: java examples.tptp.ALG212 [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 ALG212 model = new ALG212(); final Solver solver = new Solver(); solver.options().setSolver(SATFactory.MiniSat); // solver.options().setSymmetryBreaking(n*n); // solver.options().setFlatten(false); final Formula f = model.checkDistLong(); final Bounds b = model.bounds(n); System.out.println(f); final Solution sol = solver.solve(f, b); System.out.println(sol); } catch (NumberFormatException nfe) { usage(); } } }