use of kodkod.engine.fol2sat.Translation in project org.alloytools.alloy by AlloyTools.
the class Solver method solve.
/**
* Attempts to satisfy the given {@code formula} and {@code bounds} with respect
* to {@code this.options} or, optionally, prove the problem's unsatisfiability.
* If the method completes normally, the result is a {@linkplain Solution
* solution} containing either an {@linkplain Instance instance} of the given
* problem or, optionally, a {@linkplain Proof proof} of its unsatisfiability.
* An unsatisfiability proof will be constructed iff {@code this.options.solver}
* specifies a {@linkplain SATProver} and
* {@code this.options.logTranslation > 0}.
*
* @return some sol: {@link Solution} | some sol.instance() => sol.instance() in
* MODELS(formula, bounds, this.options) else UNSAT(formula, bound,
* this.options)
* @throws NullPointerException formula = null || bounds = null
* @throws UnboundLeafException the formula contains an undeclared variable or a
* relation not mapped by the given bounds
* @throws HigherOrderDeclException the formula contains a higher order
* declaration that cannot be skolemized, or it can be skolemized
* but {@code this.options.skolemDepth} is insufficiently large
* @throws AbortedException this solving task was aborted
* @see Options
* @see Solution
* @see Instance
* @see Proof
*/
@Override
public Solution solve(Formula formula, Bounds bounds) throws HigherOrderDeclException, UnboundLeafException, AbortedException {
final long startTransl = System.currentTimeMillis();
try {
final Translation.Whole translation = Translator.translate(formula, bounds, options);
final long endTransl = System.currentTimeMillis();
if (translation.trivial())
return trivial(translation, endTransl - startTransl);
final SATSolver cnf = translation.cnf();
options.reporter().solvingCNF(translation.numPrimaryVariables(), cnf.numberOfVariables(), cnf.numberOfClauses());
final long startSolve = System.currentTimeMillis();
final boolean isSat = cnf.solve();
final long endSolve = System.currentTimeMillis();
final Statistics stats = new Statistics(translation, endTransl - startTransl, endSolve - startSolve);
return isSat ? sat(translation, stats) : unsat(translation, stats);
} catch (SATAbortedException sae) {
throw new AbortedException(sae);
}
}
use of kodkod.engine.fol2sat.Translation in project org.alloytools.alloy by AlloyTools.
the class SolutionIterator method nextNonTrivialSolution.
/**
* Solves {@code translation.cnf} and adds the negation of the found model to
* the set of clauses. The latter has the effect of forcing the solver to come
* up with the next solution or return UNSAT. If
* {@code this.translation.cnf.solve()} is false, sets {@code this.translation}
* to null.
*
* @requires this.translation != null
* @ensures this.translation.cnf is modified to eliminate the current solution
* from the set of possible solutions
* @return current solution
*/
private Solution nextNonTrivialSolution() {
final Translation.Whole transl = translation;
final SATSolver cnf = transl.cnf();
final int primaryVars = transl.numPrimaryVariables();
transl.options().reporter().solvingCNF(primaryVars, cnf.numberOfVariables(), cnf.numberOfClauses());
final long startSolve = System.currentTimeMillis();
final boolean isSat = cnf.solve();
final long endSolve = System.currentTimeMillis();
final Statistics stats = new Statistics(transl, translTime, endSolve - startSolve);
final Solution sol;
if (isSat) {
// extract the current solution; can't use the sat(..) method
// because it frees the sat solver
sol = Solution.satisfiable(stats, transl.interpret());
// add the negation of the current model to the solver
final int[] notModel = new int[primaryVars];
for (int i = 1; i <= primaryVars; i++) {
notModel[i - 1] = cnf.valueOf(i) ? -i : i;
}
cnf.addClause(notModel);
} else {
// this also frees up solver
sol = Solver.unsat(transl, stats);
// resources, if any
// unsat, no more solutions
translation = null;
}
return sol;
}
use of kodkod.engine.fol2sat.Translation in project org.alloytools.alloy by AlloyTools.
the class SolutionIterator method nextTrivialSolution.
/**
* Returns the trivial solution corresponding to the trivial translation stored
* in {@code this.translation}, and if {@code this.translation.cnf.solve()} is
* true, sets {@code this.translation} to a new translation that eliminates the
* current trivial solution from the set of possible solutions. The latter has
* the effect of forcing either the translator or the solver to come up with the
* next solution or return UNSAT. If {@code this.translation.cnf.solve()} is
* false, sets {@code this.translation} to null.
*
* @requires this.translation != null
* @ensures this.translation is modified to eliminate the current trivial
* solution from the set of possible solutions
* @return current solution
*/
private Solution nextTrivialSolution() {
final Translation.Whole transl = this.translation;
// this also
final Solution sol = Solver.trivial(transl, translTime);
if (sol.instance() == null) {
// unsat, no more solutions
translation = null;
} else {
trivial++;
final Bounds bounds = transl.bounds();
final Bounds newBounds = bounds.clone();
final List<Formula> changes = new ArrayList<Formula>();
for (Relation r : bounds.relations()) {
final TupleSet lower = bounds.lowerBound(r);
if (lower != bounds.upperBound(r)) {
// r may change
if (lower.isEmpty()) {
changes.add(r.some());
} else {
final Relation rmodel = Relation.nary(r.name() + "_" + trivial, r.arity());
newBounds.boundExactly(rmodel, lower);
changes.add(r.eq(rmodel).not());
}
}
}
// nothing can change => there can be no more solutions (besides the
// current trivial one).
// note that transl.formula simplifies to the constant true with
// respect to
// transl.bounds, and that newBounds is a superset of transl.bounds.
// as a result, finding the next instance, if any, for
// transl.formula.and(Formula.or(changes))
// with respect to newBounds is equivalent to finding the next
// instance of Formula.or(changes) alone.
final Formula formula = changes.isEmpty() ? Formula.FALSE : Formula.or(changes);
final long startTransl = System.currentTimeMillis();
translation = Translator.translate(formula, newBounds, transl.options());
translTime += System.currentTimeMillis() - startTransl;
}
return sol;
}
Aggregations