package kodkod.test.sys; import static kodkod.engine.Solution.Outcome.UNSATISFIABLE; import static org.junit.Assert.assertEquals; import java.util.ArrayList; import java.util.Collection; import java.util.Set; import kodkod.ast.Formula; import kodkod.ast.Relation; import kodkod.engine.IncrementalSolver; import kodkod.engine.Solution; import kodkod.engine.config.Options; import kodkod.engine.fol2sat.SymmetryDetector; import kodkod.engine.satlab.SATFactory; import kodkod.instance.Bounds; import kodkod.instance.TupleFactory; import kodkod.instance.TupleSet; import kodkod.util.ints.IndexedEntry; import kodkod.util.ints.IntSet; import kodkod.util.nodes.AnnotatedNode; import kodkod.util.nodes.Nodes; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; import org.junit.runners.Parameterized.Parameters; import kodkod.test.util.Solvers; import kodkod.examples.tptp.LAT258; @RunWith(Parameterized.class) public class ExamplesTestWithIncrementalSolver extends ExamplesTest { private final IncrementalSolver solver; public ExamplesTestWithIncrementalSolver(SATFactory solverOpt) { final Options opt = new Options(); opt.setSolver(solverOpt); this.solver = IncrementalSolver.solver(opt); } @Parameters public static Collection<Object[]> solversToTestWith() { final Collection<Object[]> ret = new ArrayList<Object[]>(); for(SATFactory factory : Solvers.allAvailableSolvers()) { if (factory.incremental()) { ret.add(new Object[]{factory}); //System.out.println(factory); } } return ret; } protected Solution solve(Formula formula, Bounds bounds) { final Set<IntSet> parts = SymmetryDetector.partition(bounds); final Bounds inc = new Bounds(bounds.universe()); final TupleFactory t = inc.universe().factory(); for(IndexedEntry<TupleSet> e : inc.intBounds()) { inc.boundExactly(e.index(), e.value()); } for(IntSet part : parts) { // dummy relations to set up initial symmetry classes inc.boundExactly(Relation.unary("r" + part.min()), t.setOf(1, part)); } Solution sol = solver.solve(Formula.TRUE, inc); assertEquals(Solution.Outcome.TRIVIALLY_SATISFIABLE, sol.outcome()); //System.out.println("FORMULAS: " + Nodes.roots(formula).size()); for(Formula f : Nodes.roots(formula)) { inc.relations().clear(); if (!bounds.relations().isEmpty()) { final Set<Relation> rels = AnnotatedNode.annotate(f).relations(); rels.retainAll(bounds.relations()); for(Relation r : rels) { inc.bound(r, bounds.lowerBound(r), bounds.upperBound(r)); } bounds.relations().removeAll(rels); } //System.out.println(f + ", " + inc.relations() + "\n"); sol = solver.solve(f, inc); if (sol.unsat()) { break; } } return sol; } /** * Runs LAT258.checkGoalToBeProved for 5. Running it for 6 takes about a minute. */ @Test public void testLAT258() { final LAT258 prob = new LAT258(); final Solution sol = solve(prob.checkGoalToBeProved(), prob.bounds(5)); check(prob.getClass().getSimpleName(), sol, UNSATISFIABLE); } }