use of kodkod.engine.bool.BooleanFactory in project org.alloytools.alloy by AlloyTools.
the class SymmetryBreaker method generateSBP.
/**
* Generates a lex leader symmetry breaking predicate for this.symmetries (if
* any), using the specified leaf interpreter and options.symmetryBreaking. It
* also invokes options.reporter().generatingSBP() if a non-constant predicate
* is generated.
*
* @requires interpreter.relations in this.bounds.relations
* @ensures options.reporter().generatingSBP() if a non-constant predicate is
* generated.
* @return a symmetry breaking predicate for this.symmetries
*/
public final BooleanValue generateSBP(LeafInterpreter interpreter, Options options) {
final int predLength = options.symmetryBreaking();
if (symmetries.isEmpty() || predLength == 0)
return BooleanConstant.TRUE;
options.reporter().generatingSBP();
final List<RelationParts> relParts = relParts();
final BooleanFactory factory = interpreter.factory();
final BooleanAccumulator sbp = BooleanAccumulator.treeGate(Operator.AND);
final List<BooleanValue> original = new ArrayList<BooleanValue>(predLength);
final List<BooleanValue> permuted = new ArrayList<BooleanValue>(predLength);
for (IntSet sym : symmetries) {
IntIterator indeces = sym.iterator();
for (int prevIndex = indeces.next(); indeces.hasNext(); ) {
int curIndex = indeces.next();
for (Iterator<RelationParts> rIter = relParts.iterator(); rIter.hasNext() && original.size() < predLength; ) {
RelationParts rparts = rIter.next();
Relation r = rparts.relation;
if (!rparts.representatives.contains(sym.min()))
// r does not range over sym
continue;
BooleanMatrix m = interpreter.interpret(r);
for (IndexedEntry<BooleanValue> entry : m) {
int permIndex = permutation(r.arity(), entry.index(), prevIndex, curIndex);
BooleanValue permValue = m.get(permIndex);
if (permIndex == entry.index() || atSameIndex(original, permValue, permuted, entry.value()))
continue;
original.add(entry.value());
permuted.add(permValue);
}
}
sbp.add(leq(factory, original, permuted));
original.clear();
permuted.clear();
prevIndex = curIndex;
}
}
// no symmetries left to break (this is
symmetries.clear();
// conservative)
return factory.accumulate(sbp);
}
use of kodkod.engine.bool.BooleanFactory in project org.alloytools.alloy by AlloyTools.
the class FOL2BoolTranslator method visit.
/**
* Calls lookup(castExpr) and returns the cached value, if any. If a translation
* has not been cached, translates the expression, calls cache(...) on it and
* returns it.
*
* @return let t = lookup(castExpr) | some t => t, cache(castExpr,
* translate(castExpr))
*/
@Override
public BooleanMatrix visit(IntToExprCast castExpr) {
BooleanMatrix ret = lookup(castExpr);
if (ret != null)
return ret;
final Int child = castExpr.intExpr().accept(this);
final BooleanFactory factory = interpreter.factory();
final IntSet ints = interpreter.ints();
ret = factory.matrix(Dimensions.square(interpreter.universe().size(), 1));
switch(castExpr.op()) {
case INTCAST:
for (IntIterator iter = ints.iterator(); iter.hasNext(); ) {
int i = iter.next();
int atomIndex = interpreter.interpret(i);
ret.set(atomIndex, factory.or(ret.get(atomIndex), child.eq(factory.integer(i))));
}
ret.setDefCond(child.defCond());
break;
case BITSETCAST:
final List<BooleanValue> twosComplement = child.twosComplementBits();
final int msb = twosComplement.size() - 1;
// handle all bits but the sign bit
for (int i = 0; i < msb; i++) {
int pow2 = 1 << i;
if (ints.contains(pow2)) {
ret.set(interpreter.interpret(pow2), twosComplement.get(i));
}
}
// handle the sign bit
if (ints.contains(-1 << msb)) {
ret.set(interpreter.interpret(-1 << msb), twosComplement.get(msb));
}
break;
default:
throw new IllegalArgumentException("Unknown cast operator: " + castExpr.op());
}
return cache(castExpr, ret);
}
use of kodkod.engine.bool.BooleanFactory in project org.alloytools.alloy by AlloyTools.
the class FOL2BoolTranslator method some.
/**
* Translates the given existentially quantified formula as follows (where
* A_0...A_|A| stand for boolean variables that represent the tuples of the
* expression A, etc.): let quantFormula = "some a: A, b: B, ..., x: X | F(a, b,
* ..., x)" | (A_0 && B_0 && ... && X_0 && translate(F(A_0, B_0, ..., X_0))) ||
* ... || (A_|A| && B_|B| && ... && X_|X| && translate(F(A_|A|, B_|B|, ...,
* X_|X|)) If the noOverflow option is specified, then the translation looks
* like: let quantFormula = "some a: A, b: B, ..., x: X | F(a, b, ..., x)" |
* (A_0 && B_0 && ... && X_0 && !of(F(A_0, B_0, ..., X_0)) && translate(F(A_0,
* B_0, ..., X_0))) || ... || (A_|A| && B_|B| && ... && X_|X| && !of(F(A_|A|,
* B_|B|, ..., X_|X|)) && translate(F(A_|A|, B_|B|, ..., X_|X|)) where
* of(F(A_|a|, B_|b|, ..., X_|x|)) is the portion of the overflow circuit
* generated by the translation of F(A_|a|, B_|b|, ..., X_|x|) contributed by
* arithmetic operations over only the integer variables of this quantifier
*
* @param decls formula declarations
* @param formula the formula body
* @param currentDecl currently processed declaration; should be 0 initially
* @param declConstraints the constraints implied by the declarations; should be
* Boolean.TRUE intially
* @param acc the accumulator that contains the top level conjunction; should be
* an empty OR accumulator initially
* @ensures the given accumulator contains the translation of the formula "some
* decls | formula"
*/
private void some(Decls decls, Formula formula, int currentDecl, BooleanValue declConstraints, BooleanAccumulator acc) {
if (acc.isShortCircuited())
return;
final BooleanFactory factory = interpreter.factory();
if (decls.size() == currentDecl) {
BooleanValue formulaCircuit = formula.accept(this);
BooleanValue finalCircuit = factory.and(declConstraints, formulaCircuit);
acc.add(finalCircuit);
return;
}
final Decl decl = decls.get(currentDecl);
final BooleanMatrix declTransl = visit(decl);
final BooleanMatrix groundValue = factory.matrix(declTransl.dimensions());
env = env.extend(decl.variable(), decl.expression(), groundValue, Quantifier.SOME);
for (IndexedEntry<BooleanValue> entry : declTransl) {
groundValue.set(entry.index(), BooleanConstant.TRUE);
some(decls, formula, currentDecl + 1, factory.and(entry.value(), declConstraints), acc);
groundValue.set(entry.index(), BooleanConstant.FALSE);
}
env = env.parent();
}
use of kodkod.engine.bool.BooleanFactory in project org.alloytools.alloy by AlloyTools.
the class FOL2BoolTranslator method sum.
/**
* Translates the given sum expression as follows (where A_0...A_|A| stand for
* boolean variables that represent the tuples of the expression A, etc.): let
* sum = "sum a: A, b: B, ..., x: X | IE(a, b, ..., x) " | sum a: A, b: B, ...,
* x: X | if (a in A && b in B && ... && x in X) then IE(a, b, ..., x) else 0 }.
*
* @param decls intexpr declarations
* @param formula the formula body
* @param currentDecl currently processed declaration; should be 0 initially
* @param declConstraints the constraints implied by the declarations; should be
* Boolean.TRUE intially
* @param values integer values computed so far
*/
private final void sum(Decls decls, IntExpression expr, int currentDecl, BooleanValue declConstraints, List<Int> values) {
final BooleanFactory factory = interpreter.factory();
if (decls.size() == currentDecl) {
Int intExpr = expr.accept(this);
Int newInt = intExpr.choice(declConstraints, factory.integer(0));
values.add(newInt);
return;
}
final Decl decl = decls.get(currentDecl);
final BooleanMatrix declTransl = visit(decl);
final BooleanMatrix groundValue = factory.matrix(declTransl.dimensions());
env = env.extend(decl.variable(), decl.expression(), groundValue);
for (IndexedEntry<BooleanValue> entry : declTransl) {
groundValue.set(entry.index(), BooleanConstant.TRUE);
sum(decls, expr, currentDecl + 1, factory.and(entry.value(), declConstraints), values);
groundValue.set(entry.index(), BooleanConstant.FALSE);
}
env = env.parent();
}
use of kodkod.engine.bool.BooleanFactory in project org.alloytools.alloy by AlloyTools.
the class Translator method toBoolean.
// private HOLTranslation toHOLTransl(AnnotatedNode<Formula> annotated,
// SymmetryBreaker breaker) {
// checkHOLOptions(options);
//
// // AnnotatedNode<Formula> fl = FormulaFlattener.flatten(optimized, true);
// //TODO: need this?
// //AnnotatedNode<Formula> nnf1 = NNFConverter.toNNF(optimized,
// options.reporter());
// AnnotatedNode<Formula> nnf = FullNegationPropagator.toNNF(annotated,
// options.reporter());
// //AnnotatedNode<Formula> pnf = PrenexNFConverter.toPNF(nnf);
// AnnotatedNode<Formula> skl = Skolemizer.skolemize(nnf, bounds, options);
//
// return HOL2ProcTranslator.translate(skl, bounds, options);
// }
/**
* Translates the given annotated formula to a circuit, conjoins the circuit
* with an SBP generated by the given symmetry breaker, and returns its
* {@linkplain Translation} to CNF. The SBP breaks any symmetries that could not
* be broken during the
* {@linkplain #optimizeFormulaAndBounds(AnnotatedNode, SymmetryBreaker) formula
* and bounds optimization} step.
*
* @requires SAT(annotated.node, this.bounds, this.options) iff
* SAT(this.originalFormula, this.originalBounds, this.options)
* @requires breaker.bounds = this.bounds
* @ensures this.options.logTranslation => some this.log'
* @ensures this.options.reporter().translatingToBoolean(annotated.node(),
* this.bounds)
* @ensures this.options.reporter().generatingSBP()
* @return the translation of annotated.node with respect to this.bounds
*/
private Translation toBoolean(AnnotatedNode<Formula> annotated, SymmetryBreaker breaker) {
options.reporter().translatingToBoolean(annotated.node(), bounds);
final LeafInterpreter interpreter = LeafInterpreter.exact(bounds, options, incremental);
final BooleanFactory factory = interpreter.factory();
if (logging) {
assert !incremental;
final TranslationLogger logger = options.logTranslation() == 1 ? new MemoryLogger(annotated, bounds) : new FileLogger(annotated, bounds);
BooleanAccumulator circuit = FOL2BoolTranslator.translate(annotated, interpreter, logger);
final TranslationLog log = logger.log();
if (circuit.isShortCircuited()) {
return trivial(circuit.op().shortCircuit(), log);
} else if (circuit.size() == 0) {
return trivial(circuit.op().identity(), log);
}
circuit.add(breaker.generateSBP(interpreter, options));
return toCNF((BooleanFormula) factory.accumulate(circuit), interpreter, log);
} else {
BooleanValue circuit = (BooleanValue) FOL2BoolTranslator.translate(annotated, interpreter);
if (circuit.op() == Operator.CONST) {
return trivial((BooleanConstant) circuit, null);
}
return toCNF((BooleanFormula) factory.and(circuit, breaker.generateSBP(interpreter, options)), interpreter, null);
}
}
Aggregations