/**
*
*/
package kodkod.examples.tptp;
import static kodkod.ast.Expression.IDEN;
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.TupleFactory;
import kodkod.instance.TupleSet;
import kodkod.instance.Universe;
/**
* A KK encoding of COM008+1.p from http://www.cs.miami.edu/~tptp/
*
* @author Emina Torlak
*/
public final class COM008 {
private final Relation equalish, rewrite, trr;
private final Relation a, b, c, goal;
private final Relation Atom;
/**
* Constructs a new instance of COM008.
*/
public COM008() {
equalish = Relation.binary("equalish");
rewrite = Relation.binary("rewrite");
trr = Relation.binary("trr");
a = Relation.unary("a");
b = Relation.unary("b");
c = Relation.unary("c");
goal = Relation.unary("goal");
Atom = Relation.unary("Atom");
}
/**
* Returns the declarations.
* @return one a && one b && one c
*/
public final Formula decls() {
return a.one().and(b.one()).and(c.one());
}
/**
* Returns the found axiom.
* @return the found axiom.
*/
public final Formula found() {
final Variable A = Variable.unary("A");
return b.product(A).union(c.product(A)).in(trr).implies(goal.some()).forAll(A.oneOf(Atom));
}
/**
* Returns the assumption axiom.
* @return the assumption axiom.
*/
public final Formula assumption() {
return a.product(b).union(a.product(c)).in(trr);
}
/**
* Returns the reflexivity axiom.
* @return the reflexivity axiom.
*/
public final Formula reflexivity() {
final Expression eqdom = equalish.join(Atom);
return eqdom.product(eqdom).intersection(IDEN).in(equalish);
}
/**
* Returns the symmetry axiom.
* @return the symmetry axiom.
*/
public final Formula symmetry() {
return equalish.eq(equalish.transpose());
}
/**
* Returns the equalish_in_transitive_reflexive_rewrite axiom.
* @return the equalish_in_transitive_reflexive_rewrite axiom.
*/
public final Formula equalishInTrr() {
return equalish.in(trr);
}
/**
* Returns the rewrite_in_transitive_reflexive_rewrite axiom.
* @return the rewrite_in_transitive_reflexive_rewrite axiom.
*/
public final Formula rewriteInTrr() {
return rewrite.in(trr);
}
/**
* Returns the transitivity_of_transitive_reflexive_rewrite axiom.
* @return the transitivity_of_transitive_reflexive_rewrite axiom.
*/
public final Formula transitivityOfTrr() {
return trr.join(trr).in(trr);
}
/**
* Returns the lo_cfl axiom.
* @return the lo_cfl axiom.
*/
public final Formula loCfl() {
final Variable A = Variable.unary("A");
final Variable B = Variable.unary("B");
final Variable C = Variable.unary("C");
final Formula f0 = A.product(B).union(A.product(C)).in(rewrite);
final Formula f1 = B.join(trr).intersection(C.join(trr)).some();
return f0.implies(f1).forAll(A.oneOf(Atom).and(B.oneOf(Atom)).and(C.oneOf(Atom)));
}
/**
* Returns the ih_cfl axiom.
* @return the ih_cfl axiom.
*/
public final Formula ihCfl() {
final Variable A = Variable.unary("A");
final Variable B = Variable.unary("B");
final Variable C = Variable.unary("C");
final Formula f0 = a.product(A).in(rewrite).and(A.product(B).union(A.product(C)).in(trr));
final Formula f1 = B.join(trr).intersection(C.join(trr)).some();
return f0.implies(f1).forAll(A.oneOf(Atom).and(B.oneOf(Atom)).and(C.oneOf(Atom)));
}
/**
* Returns the equalish_or_rewrite axiom.
* @return the equalish_or_rewrite axiom.
*/
public final Formula equalishOrRewrite() {
final Variable A = Variable.unary("A");
final Variable B = Variable.unary("B");
final Formula f0 = A.product(B).in(trr);
final Formula f1 = A.product(B).in(equalish);
final Formula f2 = A.join(rewrite).intersection(trr.join(B)).some();
return f0.implies(f1.or(f2)).forAll(A.oneOf(Atom).and(B.oneOf(Atom)));
}
public final Formula axioms() {
return decls().and(equalishInTrr()).and(rewriteInTrr()).
and(found()).and(assumption()).and(reflexivity()).
and(symmetry()).
and(transitivityOfTrr()).and(loCfl()).and(ihCfl()).
and(equalishOrRewrite());
}
/**
* Returns the conjecture.
* @return some goal
*/
public final Formula goalToBeProved() {
return goal.some();
}
/**
* 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 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);
atoms.add("goal");
for(int i = 0; i < n; i++)
atoms.add("a"+i);
final Universe u = new Universe(atoms);
final Bounds bound = new Bounds(u);
final TupleFactory f = u.factory();
final TupleSet d1 = f.range(f.tuple("a0"), f.tuple("a"+(n-1)));
final TupleSet d2 = d1.product(d1);
bound.bound(rewrite, d2);
bound.bound(equalish, d2);
bound.bound(a, d1);
bound.bound(b, d1);
bound.bound(c, d1);
bound.boundExactly(Atom, d1);
bound.bound(trr, d2);
bound.bound(goal, f.setOf("goal"));
return bound;
}
private static void usage() {
System.out.println("java examples.tptp.COM008 [univ size]");
System.exit(1);
}
/**
* Usage: java examples.tptp.COM008 [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 COM008 model = new COM008();
final Solver solver = new Solver();
solver.options().setSolver(SATFactory.MiniSat);
// solver.options().setSymmetryBreaking(22);
// solver.options().setFlatten(false);
final Formula f = model.checkGoalToBeProved();
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();
}
}
}