Search in sources :

Example 1 with BooleanFormula

use of kodkod.engine.bool.BooleanFormula in project org.alloytools.alloy by AlloyTools.

the class Translator method translateIncrementalNonTrivial.

/**
 * @requires checkIncrementalBounds(bounds, transl)
 * @requires checkIncrementalOptions(transl.options)
 * @requires !transl.trivial()
 * @return see {@link #translateIncremental(Formula, Bounds, Options)}
 */
private static Translation.Incremental translateIncrementalNonTrivial(Formula formula, Bounds bounds, Translation.Incremental transl) {
    final Options tOptions = transl.options();
    final Bounds tBounds = transl.bounds();
    // save the set of relations bound in the pre-state
    final Set<Relation> oldRelations = new LinkedHashSet<Relation>(tBounds.relations());
    // skolemization (below) may also cause extra relations to be added.
    for (Relation r : bounds.relations()) {
        tBounds.bound(r, bounds.lowerBound(r), bounds.upperBound(r));
    }
    final AnnotatedNode<Formula> annotated = (transl.options().skolemDepth() < 0) ? annotate(formula) : skolemize(annotate(formula), tBounds, tOptions);
    // extend the interpreter with variable allocations for new relations,
    // either from given bounds
    // or those introduced by skolemization
    final LeafInterpreter interpreter = transl.interpreter();
    interpreter.extend(setDifference(tBounds.relations(), oldRelations), tBounds.lowerBounds(), tBounds.upperBounds());
    final BooleanValue circuit = FOL2BoolTranslator.translate(annotated, interpreter);
    if (circuit == BooleanConstant.FALSE) {
        // release the old solver and state, and return a fresh trivially
        // false incremental translation.
        transl.incrementer().solver().free();
        return new Translation.Incremental(tBounds, tOptions, transl.symmetries(), LeafInterpreter.empty(tBounds.universe(), tOptions), Bool2CNFTranslator.translateIncremental(BooleanConstant.FALSE, tOptions.solver()));
    } else if (circuit == BooleanConstant.TRUE) {
        // must add any newly allocated primary variables to the solver for
        // interpretation to work correctly
        final int maxVar = interpreter.factory().maxVariable();
        final int cnfVar = transl.cnf().numberOfVariables();
        if (maxVar > cnfVar) {
            transl.cnf().addVariables(maxVar - cnfVar);
        }
    } else {
        // circuit is a formula; add its CNF representation to
        // transl.incrementer.solver()
        Bool2CNFTranslator.translateIncremental((BooleanFormula) circuit, interpreter.factory().maxVariable(), transl.incrementer());
    }
    return transl;
}
Also used : LinkedHashSet(java.util.LinkedHashSet) Options(kodkod.engine.config.Options) BooleanFormula(kodkod.engine.bool.BooleanFormula) Formula(kodkod.ast.Formula) Relation(kodkod.ast.Relation) Bounds(kodkod.instance.Bounds) BooleanValue(kodkod.engine.bool.BooleanValue) BooleanFormula(kodkod.engine.bool.BooleanFormula)

Example 2 with BooleanFormula

use of kodkod.engine.bool.BooleanFormula in project org.alloytools.alloy by AlloyTools.

the class Bool2CNFTranslator method visit.

/**
 * Adds translation clauses to the solver and returns an array containing the
 * gate's literal. The CNF clauses are generated according to the standard SAT
 * to CNF translation: o = AND(i1, i2, ... ik) ---> (i1 | !o) & (i2 | !o) & ...
 * & (ik | !o) & (!i1 | !i2 | ... | !ik | o), o = OR(i1, i2, ... ik) ---> (!i1 |
 * o) & (!i2 | o) & ... & (!ik | o) & (i1 | i2 | ... | ik | !o).
 *
 * @return o: int[] | o.length = 1 && o.[0] = multigate.literal
 * @ensures if the multigate has not yet been visited, its children are visited
 *          and the clauses are added to the solver connecting the multigate's
 *          literal to its input literal, as described above.
 */
@Override
public final int[] visit(MultiGate multigate, Object arg) {
    final int oLit = multigate.label();
    if (visited.add(oLit)) {
        final int sgn;
        final boolean p, n;
        if (multigate.op() == AND) {
            sgn = 1;
            p = positive(oLit);
            n = negative(oLit);
        } else {
            // multigate.op()==OR
            sgn = -1;
            n = positive(oLit);
            p = negative(oLit);
        }
        final int[] lastClause = n ? new int[multigate.size() + 1] : null;
        final int output = oLit * -sgn;
        int i = 0;
        for (BooleanFormula input : multigate) {
            int iLit = input.accept(this, arg)[0];
            if (p) {
                solver.addClause(clause(iLit * sgn, output));
            }
            if (n) {
                lastClause[i++] = iLit * -sgn;
            }
        }
        if (n) {
            lastClause[i] = oLit * sgn;
            solver.addClause(lastClause);
        }
    }
    return clause(oLit);
}
Also used : BooleanFormula(kodkod.engine.bool.BooleanFormula)

Example 3 with BooleanFormula

use of kodkod.engine.bool.BooleanFormula in project org.alloytools.alloy by AlloyTools.

the class Bool2CNFTranslator method translate.

/**
 * Applies this translator to the given circuit, adding the translation of the
 * circuit to this.solver, and returns the translator.
 *
 * @requires circuit in this.factory.components
 * @requires maxPrimaryVar = this.factory.maxPrimaryVariable()
 * @ensures this.solver.variables' = this.solver.variables + { i: int |
 *          solver.numberOfVariables() < i <= max(abs(circuit.label),
 *          maxPrimaryVar) }
 * @effects this.solver.clauses' = this.solver.clauses + CNF(circuit)
 * @return this
 */
private Bool2CNFTranslator translate(BooleanFormula circuit, int maxPrimaryVar) {
    final int newVars = Math.max(Math.abs(circuit.label()), maxPrimaryVar) - solver.numberOfVariables();
    // System.out.println("solver.vars=" + solver.numberOfVariables());
    if (newVars > 0)
        solver.addVariables(newVars);
    if (circuit.op() == Operator.AND) {
        for (BooleanFormula input : circuit) {
            input.accept(this, null);
        }
        for (BooleanFormula input : circuit) {
            unaryClause[0] = input.label();
            solver.addClause(unaryClause);
        }
    } else {
        solver.addClause(circuit.accept(this, null));
    }
    return this;
}
Also used : BooleanFormula(kodkod.engine.bool.BooleanFormula)

Aggregations

BooleanFormula (kodkod.engine.bool.BooleanFormula)3 LinkedHashSet (java.util.LinkedHashSet)1 Formula (kodkod.ast.Formula)1 Relation (kodkod.ast.Relation)1 BooleanValue (kodkod.engine.bool.BooleanValue)1 Options (kodkod.engine.config.Options)1 Bounds (kodkod.instance.Bounds)1