/**
*
*/
package kodkod.examples.tptp;
import java.util.ArrayList;
import java.util.List;
import kodkod.ast.Decls;
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.config.ConsoleReporter;
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;
import kodkod.util.nodes.PrettyPrinter;
/**
* A KK encoding of GRA019+1.p through GRA026+1.p from http://www.cs.miami.edu/~tptp/
* @author Emina Torlak
*/
public final class GRA013_026 {
private final Relation red, green, lessThan,goal,node;
private final int graphSize, cliqueSize;
/**
* Constructs a new instance of GRA013_026 with the given graph and clique size.
* @requires 0 < cliqueSize <= graphSize
*/
public GRA013_026(int graphSize, int cliqueSize) {
if (cliqueSize <= 0) throw new IllegalArgumentException("cliqueSize must be positive: " + cliqueSize);
if (cliqueSize > graphSize) throw new IllegalArgumentException("cliqueSize must be less than or equal to graph size: " + cliqueSize + ">" + graphSize);
node = Relation.unary("N");
red = Relation.binary("red");
green = Relation.binary("green");
lessThan = Relation.binary("lessThan");
goal = Relation.unary("goal");
this.graphSize = graphSize;
this.cliqueSize = cliqueSize;
}
private final Formula cliqueAxiom(Expression color) {
final Variable[] vars = new Variable[cliqueSize];
for(int i = 0; i < cliqueSize; i++) {
vars[i] = Variable.unary("V"+i);
}
final List<Expression> members = new ArrayList<Expression>(cliqueSize);
for(int i = 0, max = cliqueSize-1; i < max; i++) {
final List<Expression> tmp = new ArrayList<Expression>();
for(int j = i+1; j < cliqueSize; j++) {
tmp.add(vars[j]);
}
members.add(vars[i].product(Expression.union(tmp)));
}
Decls d = vars[0].oneOf(node);
for(int i = 1; i < cliqueSize; i++) {
d = d.and(vars[i].oneOf(vars[i-1].join(lessThan)));
}
return Expression.union(members).in(color).implies(goalToBeProved()).forAll(d);
}
/**
* Returns the red clique axiom.
* @return red clique axiom.
*/
public final Formula redCliqueAxiom() {
return cliqueAxiom(red);
}
/**
* Returns the green clique axiom.
* @return green clique axiom.
*/
public final Formula greenCliqueAxiom() {
return cliqueAxiom(green);
}
/**
* Returns the partition axiom.
* @return partition axiom
*/
public final Formula partition() {
return lessThan.in(red.union(green));
}
/**
* Returns the transitivity axiom.
* @return transitivity axiom
*/
public final Formula lessThanTransitive() {
return lessThan.join(lessThan).in(lessThan);
}
/**
* Returns the no overlap axiom.
* @return no overlap axiom.
*/
public final Formula noOverlap() {
return red.intersection(green).no();
}
/**
* Returns the conjunction of all axioms.
* @return conjunction of all axioms
*/
public final Formula axioms() {
return Formula.and(redCliqueAxiom(), greenCliqueAxiom(), partition(), lessThanTransitive(), noOverlap());
}
/**
* Returns the goal_to_be_proved conjecture.
* @return goal_to_be_proved conjecture.
*/
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 the bounds.
* @return the bounds
*/
public final Bounds bounds() {
final List<String> atoms = new ArrayList<String>(graphSize);
for(int i = 1; i <= graphSize; i++)
atoms.add("n"+i);
atoms.add("goal");
final Universe u = new Universe(atoms);
final TupleFactory f = u.factory();
final Bounds b = new Bounds(u);
b.bound(goal, f.setOf("goal"));
final TupleSet ns = f.range(f.tuple("n1"), f.tuple("n"+graphSize));
b.boundExactly(node, ns);
final TupleSet s = f.noneOf(2);
for(int i = 1; i < graphSize; i++) {
for(int j = i+1; j < graphSize; j++)
s.add(f.tuple("n"+i, "n"+j));
}
b.boundExactly(lessThan, s);
b.bound(red, s);
b.bound(green, s);
return b;
}
private static void usage() {
System.out.println("Usage: java examples.tptp.GRA013_026 <graph size> <clique size>");
System.exit(1);
}
/**
* Usage: java examples.tptp.GRA013_026 <graph size> <clique size>
*/
public static void main(String[] args) {
if (args.length < 2)
usage();
try {
final GRA013_026 model = new GRA013_026(Integer.parseInt(args[0]), Integer.parseInt(args[1]));
final Bounds b = model.bounds();
final Solver solver = new Solver();
solver.options().setSolver(SATFactory.MiniSat);
solver.options().setReporter(new ConsoleReporter());
final Formula f = model.checkGoalToBeProved();
System.out.println(PrettyPrinter.print(f, 2));
// System.out.println(b);
final Solution s = solver.solve(f, b);
System.out.println(s);
//System.out.println((new Evaluator(s.instance())).evaluate(f));
} catch (HigherOrderDeclException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (UnboundLeafException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NumberFormatException nfe) {
usage();
}
}
}