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;
}
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);
}
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;
}
Aggregations