Search in sources :

Example 1 with Translation

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);
    }
}
Also used : SATSolver(kodkod.engine.satlab.SATSolver) Translation(kodkod.engine.fol2sat.Translation) SATAbortedException(kodkod.engine.satlab.SATAbortedException) SATAbortedException(kodkod.engine.satlab.SATAbortedException)

Example 2 with Translation

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;
}
Also used : SATSolver(kodkod.engine.satlab.SATSolver) Translation(kodkod.engine.fol2sat.Translation)

Example 3 with Translation

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;
}
Also used : Formula(kodkod.ast.Formula) TupleSet(kodkod.instance.TupleSet) Translation(kodkod.engine.fol2sat.Translation) Relation(kodkod.ast.Relation) Bounds(kodkod.instance.Bounds) ArrayList(java.util.ArrayList)

Aggregations

Translation (kodkod.engine.fol2sat.Translation)3 SATSolver (kodkod.engine.satlab.SATSolver)2 ArrayList (java.util.ArrayList)1 Formula (kodkod.ast.Formula)1 Relation (kodkod.ast.Relation)1 SATAbortedException (kodkod.engine.satlab.SATAbortedException)1 Bounds (kodkod.instance.Bounds)1 TupleSet (kodkod.instance.TupleSet)1