/**
*
*/
package kodkod.examples.tptp;
import static kodkod.ast.Expression.IDEN;
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.TupleFactory;
import kodkod.instance.Universe;
/**
* A KK encoding of TOP020+1.p from http://www.cs.miami.edu/~tptp/
* @author Emina Torlak
*/
public final class TOP020 {
private final Relation hausdorff;
private final Relation member, open, disjoint, closed;
private final Relation coerce, diagonal;
private final Relation product, tsproduct, ordered;
/**
* Constructs a new instance of TOP020.
*/
public TOP020() {
hausdorff = Relation.unary("a_hausdorff_top_space");
member = Relation.binary("a_member_of");
open = Relation.binary("open_in");
disjoint = Relation.binary("disjoint");
closed = Relation.binary("closed_in");
coerce = Relation.binary("coerce_to_class");
diagonal = Relation.binary("the_diagonal_top");
product = Relation.ternary("the_product_of");
tsproduct = Relation.ternary("the_product_top_space_of");
ordered = Relation.ternary("ordered_pair");
}
/**
* Returns the_product_top_space_of[A][B].
* @return the_product_top_space_of[A][B]
*/
final Expression the_product_top_space_of(Expression a, Expression b) {
return b.join(a.join(tsproduct));
}
/**
* Returns the_product_of[A][B].
* @return the_product_of[A][B]
*/
final Expression the_product_of(Expression a, Expression b) {
return b.join(a.join(product));
}
/**
* Returns the_ordered_pair[A][B].
* @return the_ordered_pair[A][B]
*/
final Expression the_ordered_pair(Expression a, Expression b) {
return b.join(a.join(ordered));
}
/**
* Returns coerce_to_class[A].
* @return coerce_to_class[A]
*/
final Expression coerce_to_class(Expression a) {
return a.join(coerce);
}
/**
* Returns the_diagonal_top[A].
* @return the_diagonal_top[A]
*/
final Expression the_diagonal_top(Expression a) {
return a.join(diagonal);
}
/**
* Returns a->b in a_member_of.
* @return a->b in a_member_of
*/
final Formula a_member_of(Expression a, Expression b) {
return a.product(b).in(member);
}
/**
* Returns a->b in open_in.
* @return a->b in open_in
*/
final Formula open_in(Expression a, Expression b) {
return a.product(b).in(open);
}
/**
* Returns a->b in closed_in.
* @return a->b in closed_in
*/
final Formula closed_in(Expression a, Expression b) {
return a.product(b).in(closed);
}
/**
* Returns a->b in disjoint.
* @return a->b in disjoint
*/
final Formula disjoint(Expression a, Expression b) {
return a.product(b).in(disjoint);
}
/**
* Returns the declarations.
* @return declarations
*/
public final Formula decls() {
final Variable a = Variable.unary("A");
final Variable b = Variable.unary("B");
final List<Formula> decls = new ArrayList<Formula>();
decls.add( coerce.function(UNIV, UNIV) );
decls.add( diagonal.function(UNIV, UNIV) );
decls.add( the_product_top_space_of(a, b).one().forAll(a.oneOf(UNIV).and(b.oneOf(UNIV))) );
decls.add( the_product_of(a, b).one().forAll(a.oneOf(UNIV).and(b.oneOf(UNIV))) );
decls.add( the_ordered_pair(a, b).one().forAll(a.oneOf(UNIV).and(b.oneOf(UNIV))) );
return Formula.and(decls);
}
/**
* Returns closed_subset_thm axiom.
* @return closed_subset_thm
*/
public final Formula closed_subset_thm() {
final Variable x = Variable.unary("X");
final Variable a = Variable.unary("A");
final Variable y = Variable.unary("Y");
final Formula f0 = a_member_of(y, coerce_to_class(x)).and(a_member_of(y, a).not());
final Formula f1 = y.join(member).intersection(open.join(x)).intersection(disjoint.join(a)).some();
final Formula f2 = f0.implies(f1).forAll(y.oneOf(UNIV));
return f2.implies(closed_in(a, x)).forAll(x.oneOf(UNIV).and(a.oneOf(UNIV)));
}
/**
* Returns hausdorff axiom.
* @return hausdorff
*/
public final Formula hausdorff() {
final Variable x = Variable.unary("X");
final Variable a = Variable.unary("A");
final Variable b = Variable.unary("B");
final Expression g1 = open.join(x).intersection(a.join(member));
final Expression g2 = open.join(x).intersection(b.join(member));
final Expression abrange = member.join(coerce_to_class(x));
return a.eq(b).not().implies(g1.product(g2).intersection(disjoint).some()).
forAll(a.oneOf(abrange).and(b.oneOf(abrange))).forAll(x.oneOf(hausdorff));
}
/**
* Returns product_of_open_sets axiom.
* @return product_of_open_sets
*/
public final Formula product_of_open_sets() {
final Variable a = Variable.unary("A");
final Variable x = Variable.unary("X");
final Variable b = Variable.unary("B");
final Variable y = Variable.unary("Y");
final Formula f0 = open_in(a, x).and(open_in(b, y));
final Formula f1 = open_in(the_product_of(a, b), the_product_top_space_of(x, y));
return f0.implies(f1).forAll(a.oneOf(UNIV).and(x.oneOf(UNIV)).and(b.oneOf(UNIV)).and(y.oneOf(UNIV)));
}
/**
* Returns product_top axiom.
* @return product_top
*/
public final Formula product_top() {
final Variable s = Variable.unary("S");
final Variable t = Variable.unary("T");
final Variable x = Variable.unary("X");
final Formula f0 = a_member_of(x, coerce_to_class(the_product_top_space_of(s, t)));
final Expression e0 = member.join(coerce_to_class(s));
final Expression e1 = member.join(coerce_to_class(t));
final Formula f1 = ordered.intersection(e0.product(e1).product(x)).some();
return f0.implies(f1).forAll(s.oneOf(UNIV).and(t.oneOf(UNIV)).and(x.oneOf(UNIV)));
}
/**
* Returns product axiom.
* @return product
*/
public final Formula product() {
final Variable x = Variable.unary("X");
final Variable s = Variable.unary("S");
final Variable t = Variable.unary("T");
final Formula f0 = a_member_of(x, the_product_of(s, t));
final Expression e0 = member.join(s);
final Expression e1 = member.join(t);
final Formula f1 = ordered.intersection(e0.product(e1).product(x)).some();
return f0.iff(f1).forAll(x.oneOf(UNIV).and(s.oneOf(UNIV)).and(t.oneOf(UNIV)));
}
/**
* Returns disjoint_defn axiom.
* @return disjoint_defn
*/
public final Formula disjoint_defn() {
final Variable a = Variable.unary("A");
final Variable b = Variable.unary("B");
return disjoint(a, b).iff(member.join(a).intersection(member.join(b)).no()).
forAll(a.oneOf(UNIV).and(b.oneOf(UNIV)));
}
/**
* Returns ordered_pair axiom.
* @return ordered_pair
*/
public final Formula ordered_pair() {
final Variable a = Variable.unary("A");
final Variable b = Variable.unary("B");
final Variable c = Variable.unary("C");
final Variable d = Variable.unary("D");
final Formula f0 = the_ordered_pair(a, b).eq(the_ordered_pair(c, d));
final Formula f1 = a.eq(c).and(b.eq(d));
return f0.implies(f1).forAll(a.oneOf(UNIV).and(b.oneOf(UNIV)).and(c.oneOf(UNIV)).and(d.oneOf(UNIV)));
}
/**
* Returns diagonal_top axiom.
* @return diagonal_top
*/
public final Formula diagonal_top() {
final Variable x = Variable.unary("X");
final Variable s = Variable.unary("S");
final Formula f0 = a_member_of(x, coerce_to_class(the_diagonal_top(s)));
final Expression a = member.join(coerce_to_class(s));
final Formula f1 = ordered.intersection((a.product(a).intersection(IDEN)).product(x)).some();
return f0.iff(f1).forAll(x.oneOf(UNIV).and(s.oneOf(UNIV)));
}
/**
* Returns the conjunction of all axioms.
* @return conjunction of all axioms.
*/
public final Formula axioms() {
return decls().and(closed_subset_thm()).and(hausdorff()).
and(product_of_open_sets()).and(product_top()).and(product()).
and(disjoint_defn()).and(ordered_pair()).and(diagonal_top());
}
/**
* Returns challenge_AMR_1_4_4 conjecture.
* @return challenge_AMR_1_4_4
*/
public final Formula challenge_AMR_1_4_4() {
final Variable s = Variable.unary("S");
return closed_in(coerce_to_class(the_diagonal_top(s)),the_product_top_space_of(s,s)).
forAll(s.oneOf(hausdorff));
}
/**
* Returns the conjunction of the axioms and the negation of the hypothesis.
* @return axioms() && !challenge_AMR_1_4_4()
*/
public final Formula checkChallenge_AMR_1_4_4() {
return axioms().and(challenge_AMR_1_4_4().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);
for(int i = 0; i < n; i++)
atoms.add("a"+i);
final Universe u = new Universe(atoms);
final Bounds b = new Bounds(u);
final TupleFactory f = u.factory();
b.bound(hausdorff, f.allOf(1));
b.bound(member, f.allOf(2));
b.bound(open, f.allOf(2));
b.bound(disjoint, f.allOf(2));
b.bound(closed, f.allOf(2));
b.bound(coerce, f.allOf(2));
b.bound(diagonal, f.allOf(2));
b.bound(product, f.allOf(3));
b.bound(tsproduct, f.allOf(3));
b.bound(ordered, f.allOf(3));
return b;
}
private static void usage() {
System.out.println("java examples.tptp.TOP020 [univ size]");
System.exit(1);
}
/**
* 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();
}
}
}