/** * */ 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.fol2sat.HigherOrderDeclException; import kodkod.engine.fol2sat.UnboundLeafException; 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 LAT258+1.p from http://www.cs.miami.edu/~tptp/ * @author Emina Torlak */ public final class LAT258 { private final Relation goal, p, t, u, v, w, x, y, z; private final Relation lessThan, meet, join; /** * Constructs a new instance of LAT258. */ public LAT258() { goal = Relation.unary("goal"); p = Relation.unary("p"); t = Relation.unary("t"); u = Relation.unary("u"); v = Relation.unary("v"); w = Relation.unary("w"); x = Relation.unary("x"); y = Relation.unary("y"); z = Relation.unary("z"); lessThan = Relation.binary("lessThan"); meet = Relation.ternary("meet"); join = Relation.ternary("join"); } /** * Returns function declarations. * @return function declarations */ public final Formula decls() { return p.one().and(t.one()).and(v.one()).and(w.one()). and(u.one()).and(x.one()).and(y.one()).and(z.one()); } /** * Returns the join_assumption axiom. * @return join_assumption axiom. */ public final Formula joinAssumption() { // x->y->t + x->z->u in join return x.product(y).product(t).union(x.product(z).product(u)).in(join); } /** * Returns the meet_assumption axiom. * @return the meet_assumption axiom. */ public final Formula meetAssumption() { // t->u->v in meet return t.product(u).product(v).in(meet); } /** * Returns the meet_join_assumption axiom. * @return the meet_join_assumption axiom. */ public final Formula meetJoinAssumption() { // y->z->w in meet && x->w->p in join return y.product(z).product(w).in(meet).and(x.product(w).product(p).in(join)); } /** * Returns the goal_ax axiom. * @return the goal_ax axiom. */ public final Formula goalAx() { // v->p in lessThan => some goal return v.product(p).in(lessThan).implies(goal.some()); } /** * Returns the less_than_reflexive axiom. * @return the less_than_reflexive axiom. */ public final Formula lessThanReflexive() { // iden in lessThan return Expression.IDEN.in(lessThan); } /** * Returns the less_than_transitive axiom. * @return the less_than_transitive axiom. */ public final Formula lessThanTransitive() { // lessThan.lessThan in lessThan return lessThan.join(lessThan).in(lessThan); } /** * Returns the lower_bound_meet axiom. * @return the lower_bound_meet axiom. */ public final Formula lowerBoundMeet() { final Variable c = Variable.unary("C"); final Expression e0 = c.join(lessThan); final Formula f0 = meet.join(c).in(e0.product(e0)); // all c: univ | meet.c in c.lessThan->c.lessThan return f0.forAll(c.oneOf(UNIV)); } /* * fof(greatest_lower_bound_meet,axiom,( ! [A,B,C,D] : ( ( meet(A,B,C) & less_than(D,A) & less_than(D,B) ) => less_than(D,C) ) )). */ /** * Returns the greatest_lower_bound_meet axiom. * @return the greatest_lower_bound_meet axiom. */ public final Formula greatestLowerBoundMeet() { final Variable a = Variable.unary("A"), b = Variable.unary("B"); final Expression e0 = b.join(a.join(meet)); final Formula f0 = e0.some().implies(lessThan.join(a).intersection(lessThan.join(b)).in(lessThan.join(e0))); return f0.forAll(a.oneOf(UNIV).and(b.oneOf(UNIV))); } /** * 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)); } /** * Returns the least_upper_bound_join axiom. * @return the least_upper_bound_join axiom. */ public final Formula leastUpperBoundJoin() { final Variable a = Variable.unary("A"), b = Variable.unary("B"); final Expression e0 = b.join(a.join(meet)); final Formula f0 = e0.some().implies(a.join(lessThan).intersection(b.join(lessThan)).in(e0.join(lessThan))); return f0.forAll(a.oneOf(UNIV).and(b.oneOf(UNIV))); } /** * Returns the less_than_meet_join axiom. * @return the less_than_meet_join axiom. */ public final Formula lessThanMeetJoin() { final Variable a = Variable.unary("A"); final Variable b = Variable.unary("B"); final Expression e0 = a.product(b); final Formula f0 = e0.product(a).in(meet); final Formula f1 = e0.product(b).in(join); // all a: univ, b: a.lessThan | a->b->a in meet && a->b->b in join return f0.and(f1).forAll(b.oneOf(a.join(lessThan))).forAll(a.oneOf(UNIV)); } /** * Assumes that e is a ternary relation. * @return e.univ~ in e.univ */ private final Formula commutative(Expression e) { final Expression first2 = e.join(UNIV); return first2.transpose().in(first2); } /** * Returns the commutitivity_meet axiom. * @return the commutitivity_meet axiom. */ public final Formula commutativityMeet() { return commutative(meet); } /** * Returns the commutitivity_join axiom. * @return the commutitivity_join axiom. */ public final Formula commutativityJoin() { return commutative(join); } /* * fof(associativity_meet,axiom,( ! [A,B,C,D,E,F] : ( ( meet(A,B,D) & meet(D,C,E) & meet(B,C,F) ) => meet(A,F,E) ) )). */ /** * Assumes that r is a ternary relation. * @return all a, b, c: univ | a->(c.(b.r))->(c.(d.r)) in r */ private final Formula associative(Expression r) { final Variable a = Variable.unary("A"), b = Variable.unary("B"), c = Variable.unary("C"); final Expression d = b.join(a.join(r)); final Expression e = c.join(d.join(r)); final Expression f = c.join(b.join(r)); final Formula f0 = a.product(f).product(e).in(r); // all a, b, c: univ | a->(c.(b.r))->(c.((b.(a.r)).r)) in r return f0.forAll(a.oneOf(UNIV).and(b.oneOf(UNIV)).and(c.oneOf(UNIV))); } /** * Returns the associativity_meet axiom. * @return the associativity_meet axiom. */ public final Formula associativityMeet() { return associative(meet); } /** * Returns the associativity_join axiom. * @return the associativity_ axiom. */ public final Formula associativityJoin() { return associative(join); } /** * Returns the lo_le_distr axiom. * @return the lo_le_distr axiom. */ public final Formula loLeDistr() { final Variable a = Variable.unary("A"), b = Variable.unary("B"), c = Variable.unary("C"); final Expression h = c.join(b.join(join)); final Expression d = h.join(a.join(meet)); final Expression e = b.join(a.join(meet)); final Expression f = c.join(a.join(meet)); final Expression g = f.join(e.join(join)); final Formula f0 = d.product(g).in(lessThan); // all a, b, c: univ | (c.(b.(meet))).(a.meet) -> (c.(a.meet)).((b.(a.meet)).join) in lessThan return f0.forAll(a.oneOf(UNIV).and(b.oneOf(UNIV)).and(c.oneOf(UNIV))); } /** * Returns the do_lattice axiom. * @return the do_lattice axiom. */ public final Formula doLattice() { return UNIV.product(UNIV).in(meet.join(UNIV)); } /** * Returns the goal_to_be_proved conjecture. * @return goal_to_be_proved conjecture. */ public final Formula goalToBeProved() { return goal.some(); } /** * Returns the conjunction of all decls and axioms. * @return the conjunction of all decls and axioms. */ public final Formula axioms() { return decls().and(joinAssumption()).and(meetAssumption()). and(meetJoinAssumption()).and(goalAx()).and(lessThanReflexive()). and(lessThanTransitive()).and(lowerBoundMeet()). and(greatestLowerBoundMeet()).and(upperBoundJoin()). and(leastUpperBoundJoin()).and(lessThanMeetJoin()). and(commutativityMeet()).and(commutativityJoin()). and(associativityMeet()).and(associativityJoin()). and(loLeDistr()).and(doLattice()); } /** * Returns the conjunction of the axioms and the negation of the hypothesis. * @return axioms() && !goalToBeProved() */ public final Formula checkGoalToBeProved() { return axioms().and(goalToBeProved().not()); } /** * Returns the bounds for the given scope. * @return the 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("n"+i); final Universe univ = new Universe(atoms); final TupleFactory f = univ.factory(); final Bounds b = new Bounds(univ); b.bound(goal, f.setOf("n0")); final TupleSet all1 = f.allOf(1); b.bound(p, all1); b.bound(t, all1); b.bound(v, all1); b.bound(w, all1); b.bound(u, all1); b.bound(x, all1); b.bound(y, all1); b.bound(z, all1); b.bound(lessThan, f.allOf(2)); final TupleSet all3 = f.allOf(3); b.bound(join, all3); b.bound(meet, all3); return b; } private static void usage() { System.out.println("java examples.tptp.LAT258 [scope]"); System.exit(1); } /** * Usage: java examples.tptp.LAT258 [scope] */ public static void main(String[] args) { if (args.length < 1) usage(); try { final int n = Integer.parseInt(args[0]); final LAT258 model = new LAT258(); final Bounds b = model.bounds(n); final Solver solver = new Solver(); solver.options().setSolver(SATFactory.MiniSat); final Formula f = model.checkGoalToBeProved(); System.out.println(f); // System.out.println(b); final Solution s = solver.solve(f, b); System.out.println(s); } catch (NumberFormatException nfe) { usage(); } catch (HigherOrderDeclException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (UnboundLeafException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }