package kodkod.examples.tptp;
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;
/**
* The GEO158+1 problem from http://www.cs.miami.edu/~tptp/
*
* @author Emina Torlak
*/
public class GEO158 {
final Relation partOf, incident, sum, endPoint, innerPoint, meet, closed, open;
final Relation curve, point;
/*
* part_of : C -> C
* incident_c : P -> C
* sum : C -> C -> one C
* end_point : P -> C
* inner_point : P -> C
* meet : P -> C -> C
* closed : C
* open : C
*/
/**
* Constructs a new instance of GEO0040.
*/
public GEO158() {
super();
partOf = Relation.binary("partOf");
incident = Relation.binary("incident");
sum = Relation.ternary("sum");
endPoint = Relation.binary("endPoint");
closed = Relation.unary("Closed");
open = Relation.unary("Open");
curve = Relation.unary("Curve");
point = Relation.unary("Point");
meet = Relation.ternary("meet");
innerPoint = Relation.binary("innerPoint");
}
/**
* Returns all the 'type' declarations.
* @return the type declarations
*/
public Formula decls() {
final Expression cc = curve.product(curve);
final Expression pc = point.product(curve);
final Formula f0 = partOf.in(cc);
final Formula f1 = closed.in(curve).and(open.in(curve));
final Formula f2 = meet.in(point.product(cc)).and(sum.in(curve.product(cc)));
final Formula f3 = incident.in(pc).and(endPoint.in(pc)).and(innerPoint.in(pc));
// all C1, C2: Curve | one C2.(C1.sum)
final Variable c1 = Variable.unary("C1");
final Variable c2 = Variable.unary("C2");
final Formula f4 = c2.join(c1.join(sum)).one().forAll(c1.oneOf(curve).and(c2.oneOf(curve)));
return f0.and(f1).and(f2).and(f3).and(f4);
}
/**
* Returns the part_of_defn axiom.
* @return part_of_defn
*/
public final Formula partOfDefn() {
// all C, C1: Curve | C1->C in partOf iff incident.C1 in incident.C
final Variable c = Variable.unary("C"), c1 = Variable.unary("C1");
final Formula f = c1.product(c).in(partOf).iff(incident.join(c1).in(incident.join(c)));
return f.forAll(c.oneOf(curve).and(c1.oneOf(curve)));
}
/**
* Returns the sum_defn axiom.
* @return sum_defn
*/
public final Formula sumDefn() {
// all C, C1, C2: Curve | C1->C2->C in sum iff
// incident.C = incident.C1 + incident.C2
final Variable c1 = Variable.unary("C1");
final Variable c2 = Variable.unary("C2");
final Variable c = Variable.unary("C");
final Formula f0 = c1.product(c2).product(c).in(sum);
final Formula f1 = incident.join(c).eq(incident.join(c1).union(incident.join(c2)));
return f0.iff(f1).forAll(c.oneOf(curve).and(c1.oneOf(curve)).and(c2.oneOf(curve)));
}
/**
* Returns the end_point_defn axiom.
* @return end_point_defn
*/
public final Formula endPointDefn() {
/* all P: Point, C: Curve | P->C in endPoint iff
* (P->C in incident &&
* all C1, C2: partOf.C & P.incident |
* C1->C2 in partOf || C2->C1 in partOf)
*/
final Variable c = Variable.unary("C");
final Variable p = Variable.unary("P");
final Expression e0 = p.product(c);
final Formula f0 = e0.in(endPoint);
final Formula f1 = e0.in(incident);
final Variable c1 = Variable.unary("C1"), c2 = Variable.unary("C2");
final Formula f2 = c1.product(c2).in(partOf).or(c2.product(c1).in(partOf));
final Expression e1 = partOf.join(c).intersection(p.join(incident));
final Formula f3 = f2.forAll(c1.oneOf(e1).and(c2.oneOf(e1)));
return f0.iff(f1.and(f3)).forAll(p.oneOf(point).and(c.oneOf(curve)));
}
/**
* Returns the inner_point_defn axiom.
* @return inner_point_defn
*/
public final Formula innerPointDefn() {
// all P: Point, C: Curve | P->C in innerPoint iff
// (P->C in incident && no P->C & endPoint)
final Variable c = Variable.unary("C");
final Variable p = Variable.unary("P");
final Expression e0 = p.product(c);
final Formula f0 = e0.in(innerPoint);
final Formula f1 = e0.in(incident).and(e0.intersection(endPoint).no());
return f0.iff(f1).forAll(p.oneOf(point).and(c.oneOf(curve)));
}
/**
* Returns the meet_defn axiom.
* @return meet_defn
*/
public final Formula meetDefn() {
// all P: Point, C, C1: Curve | P->C->C1 in meet iff
// (P->C in incident && P->C1 in incident &&
// incident.C & incident.C1 in endPoint.C & endPoint.C1)
final Variable c = Variable.unary("C");
final Variable c1 = Variable.unary("C1");
final Variable p = Variable.unary("P");
final Formula f0 = p.product(c).product(c1).in(meet);
final Formula f1 = p.product(c).in(incident).and(p.product(c1).in(incident));
final Expression e0 = incident.join(c).intersection(incident.join(c1));
final Expression e1 = endPoint.join(c).intersection(endPoint.join(c1));
final Formula f2 = e0.in(e1);
final Formula f3 = f0.iff(f1.and(f2));
return f3.forAll(p.oneOf(point).and(c.oneOf(curve)).and(c1.oneOf(curve)));
}
/**
* Returns the closed_defn axiom.
* @return closed_defn
*/
public final Formula closedDefn() {
// all C: Curve | C in Closed iff no endPoint.C
final Variable c = Variable.unary("C");
return c.in(closed).iff(endPoint.join(c).no()).forAll(c.oneOf(curve));
}
/**
* Returns the open_defn axiom.
* @return open_defn
*/
public final Formula openDefn() {
// all C: Curve | C in Open iff some endPoint.C
final Variable c = Variable.unary("C");
return c.in(open).iff(endPoint.join(c).some()).forAll(c.oneOf(curve));
}
/**
* Returns the c1 axiom.
* @return c1
*/
public final Formula c1() {
// all C, C1: Curve | (C1->C in partOf && C1 != C) => C1 in Open
final Variable c = Variable.unary("C");
final Variable c1 = Variable.unary("C1");
final Formula f0 = c1.product(c).in(partOf).and(c1.eq(c).not());
final Formula f1 = c1.in(open);
return f0.implies(f1).forAll(c.oneOf(curve).and(c1.oneOf(curve)));
}
/**
* Returns the c2 axiom.
* @return c2
*/
public final Formula c2() {
// all C, C1, C2, C3: Curve | ((C1 + C2 + C3)->C in partOf &&
// some endPoint.C1 & endPoint.C2 & endPoint.C3) =>
// (C2->C3 in partOf || C3->C2 in partOf || C1->C2 in partOf ||
// C2->C1 in partOf || C1->C3 in partOf || C3->C1 in partOf)
final Variable c = Variable.unary("C");
final Variable c1 = Variable.unary("C1");
final Variable c2 = Variable.unary("C2");
final Variable c3 = Variable.unary("C3");
final Formula f0 = c1.union(c2).union(c3).product(c).in(partOf);
final Formula f1 = endPoint.join(c1).intersection(endPoint.join(c2)).intersection(endPoint.join(c3)).some();
final Formula f2 = c2.product(c3).in(partOf).or(c3.product(c2).in(partOf));
final Formula f3 = c1.product(c2).in(partOf).or(c2.product(c1).in(partOf));
final Formula f4 = c1.product(c3).in(partOf).or(c3.product(c1).in(partOf));
return f0.and(f1).implies(f2.or(f3).or(f4)).
forAll(c.oneOf(curve).and(c1.oneOf(curve)).and(c2.oneOf(curve)).and(c3.oneOf(curve)));
}
/**
* Returns the c3 axiom.
* @return c3
*/
public final Formula c3() {
// all C: Curve | some innerPoint.C
final Variable c = Variable.unary("C");
return innerPoint.join(c).some().forAll(c.oneOf(curve));
}
/**
* Returns the c4 axiom.
* @return c4
*/
public final Formula c4() {
// all C: Curve, P: Point | P->C in innerPoint => some P.meet & sum.C
final Variable c = Variable.unary("C");
final Variable p = Variable.unary("P");
final Formula f0 = p.product(c).in(innerPoint);
final Formula f1 = p.join(meet).intersection(sum.join(c)).some();
return f0.implies(f1).forAll(c.oneOf(curve).and(p.oneOf(point)));
}
/**
* Returns the c5 axiom.
* @return c5
*/
public final Formula c5() {
// all C: Curve, P, Q, R: endPoint.C |
// P = Q || P = R || Q = R
final Variable c = Variable.unary("C");
final Variable p = Variable.unary("P");
final Variable q = Variable.unary("Q");
final Variable r = Variable.unary("R");
final Expression e0 = endPoint.join(c);
final Formula f0 = p.eq(q).or(p.eq(r)).or(q.eq(r));
return f0.forAll(c.oneOf(curve).and(p.oneOf(e0)).and(q.oneOf(e0)).and(r.oneOf(e0)));
}
/**
* Returns the c6 axiom.
* @return c6
*/
public final Formula c6() {
// all C: Curve, P: endPoint.C | some endPoint.C - P
final Variable c = Variable.unary("C");
final Variable p = Variable.unary("P");
final Expression e0 = endPoint.join(c);
return e0.difference(p).some().forAll(c.oneOf(curve).and(p.oneOf(e0)));
}
/**
* Returns the c7 axiom.
* @return c7
*/
public final Formula c7() {
// all C, C1, C2: Curve, P: Point | (C in Closed &&
// P->C1->C2 in meet && sum[C1][C2] = C) =>
// ((endPoint.C1)->C1->C2 in meet)
final Variable c = Variable.unary("C");
final Variable c1 = Variable.unary("C1");
final Variable c2 = Variable.unary("C2");
final Variable p = Variable.unary("P");
final Formula f0 = c.in(closed).and(p.product(c1).product(c2).in(meet));
final Formula f1 = c2.join(c1.join(sum)).eq(c);
final Formula f2 = endPoint.join(c1).product(c1).product(c2).in(meet);
return f0.and(f1).implies(f2).
forAll(c.oneOf(curve).and(c1.oneOf(curve)).and(c2.oneOf(curve)).and(p.oneOf(point)));
}
/**
* Returns the c8 axiom.
* @return c8
*/
public final Formula c8() {
// all C1, C2: Curve | some meet.C2.C1 => some sum[C1][C2]
final Variable c1 = Variable.unary("C1");
final Variable c2 = Variable.unary("C2");
final Formula f0 = meet.join(c2).join(c1).some();
final Formula f1 = c2.join(c1.join(sum)).some();
return f0.implies(f1).forAll(c1.oneOf(curve).and(c2.oneOf(curve)));
}
/**
* Returns the c9 axiom.
* @return c9
*/
public final Formula c9() {
// all C, C1: Curve | incident.C = incident.C1 => C = C1
final Variable c = Variable.unary("C");
final Variable c1 = Variable.unary("C1");
return incident.join(c).eq(incident.join(c1)).implies(c.eq(c1)).
forAll(c.oneOf(curve).and(c1.oneOf(curve)));
}
/**
* Returns the conjunction of all axioms and decls
* @returns the conjunction of all axioms and decls
*/
public Formula axioms() {
return decls().and(partOfDefn()).and(sumDefn()).and(endPointDefn()).and(innerPointDefn()).
and(meetDefn()).and(openDefn()).and(closedDefn()).
and(c1()).and(c2()).and(c3()).and(c4()).and(c5()).and(c6()).and(c7()).and(c8()).and(c9());
}
/**
* Returns the formula "some Curve"
* @return some Curve
*/
public Formula someCurve() {
return curve.some();
}
/**
* Returns a bounds with the given number of maximum curves and points
* @return a bounds with the given number of maximum curves and points
*/
public Bounds bounds(int scope) {
assert scope > 0;
List<String> atoms = new ArrayList<String>(scope);
for(int i = 0; i < scope; i++)
atoms.add("c"+i);
for(int i = 0; i < scope; i++)
atoms.add("p"+i);
final Universe u = new Universe(atoms);
final TupleFactory f = u.factory();
final Bounds b = new Bounds(u);
final TupleSet c = f.range(f.tuple("c0"), f.tuple("c"+(scope-1)));
final TupleSet p = f.range(f.tuple("p0"), f.tuple("p"+(scope-1)));
final TupleSet cc = c.product(c), pc = p.product(c);
b.bound(curve, c);
b.bound(point, p);
b.bound(partOf, cc);
b.bound(incident, pc);
b.bound(sum, c.product(cc));
b.bound(endPoint, pc);
b.bound(innerPoint, pc);
b.bound(meet, pc.product(c));
b.bound(closed, c);
b.bound(open, c);
return b;
}
/**
* Returns the conjunction of the axioms and the hypothesis.
* @return axioms() && someCurve()
*/
public final Formula checkConsistent() {
return axioms().and(someCurve());
}
private static void usage() {
System.out.println("java examples.tptp.GEO158 [ univ size ]");
System.exit(1);
}
/**
* Usage: java examples.tptp.GEO158 [# univ size ]
*/
public static void main(String[] args) {
if (args.length < 1)
usage();
try {
final int n = Integer.parseInt(args[0]);
final Solver solver = new Solver();
solver.options().setSolver(SATFactory.MiniSat);
final GEO158 model = new GEO158();
final Formula f = model.checkConsistent();
// System.out.println(model.decls());
// System.out.println(model.partOfDefn());
// System.out.println(model.sumDefn());
//
// System.out.println(model.endPointDefn());
// System.out.println(model.innerPointDefn());
// System.out.println(model.meetDefn());
//
// System.out.println(model.openDefn());
// System.out.println(model.closedDefn());
// System.out.println(model.c1());
//
// System.out.println(model.c2());
// System.out.println(model.c3());
// System.out.println(model.c4());
//
// System.out.println(model.c6());
// System.out.println(model.c7());
// System.out.println(model.c8());
//
// System.out.println(model.c9());
final Bounds b = model.bounds(n);
final Solution sol = solver.solve(f,b);
System.out.println(sol);
} catch (NumberFormatException nfe) {
usage();
}
}
}