use of kodkod.engine.bool.BooleanAccumulator in project org.alloytools.alloy by AlloyTools.
the class SymmetryBreaker method leq.
/**
* Returns a BooleanValue that is true iff the string of bits represented by l0
* is lexicographically less than or equal to the string of bits reprented by
* l1.
*
* @requires l0.size()==l1.size()
* @return a circuit that compares l0 and l1
*/
private static final BooleanValue leq(BooleanFactory f, List<BooleanValue> l0, List<BooleanValue> l1) {
final BooleanAccumulator cmp = BooleanAccumulator.treeGate(Operator.AND);
BooleanValue prevEquals = BooleanConstant.TRUE;
for (int i = 0; i < l0.size(); i++) {
cmp.add(f.implies(prevEquals, f.implies(l0.get(i), l1.get(i))));
prevEquals = f.and(prevEquals, f.iff(l0.get(i), l1.get(i)));
}
return f.accumulate(cmp);
}
use of kodkod.engine.bool.BooleanAccumulator 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.BooleanAccumulator in project org.alloytools.alloy by AlloyTools.
the class FOL2BoolTranslator method visit.
/**
* Calls lookup(formula) and returns the cached value, if any. If a translation
* has not been cached, translates the formula, calls cache(...) on it and
* returns it.
*
* @return let t = lookup(formula) | some t => t, cache(formula,
* formula.op(formula.left.accept(this), formula.right.accept(this))
*/
@Override
public final BooleanValue visit(NaryFormula formula) {
final BooleanValue ret = lookup(formula);
if (ret != null)
return ret;
final FormulaOperator op = formula.op();
final Operator.Nary boolOp;
switch(op) {
case AND:
boolOp = Operator.AND;
break;
case OR:
boolOp = Operator.OR;
break;
default:
throw new IllegalArgumentException("Unknown nary operator: " + op);
}
final BooleanAccumulator acc = BooleanAccumulator.treeGate(boolOp);
final BooleanValue shortCircuit = boolOp.shortCircuit();
for (Formula child : formula) {
if (acc.add(child.accept(this)) == shortCircuit)
break;
}
return cache(formula, interpreter.factory().accumulate(acc));
}
use of kodkod.engine.bool.BooleanAccumulator in project org.alloytools.alloy by AlloyTools.
the class FOL2BoolTranslator method visit.
/**
* Calls lookup(quantFormula) and returns the cached value, if any. If a
* translation has not been cached, translates the formula, calls cache(...) on
* it and returns it.
*
* @return let t = lookup(quantFormula) | some t => t, cache(quantFormula,
* translate(quantFormula))
*/
@Override
public final BooleanValue visit(QuantifiedFormula quantFormula) {
BooleanValue ret = lookup(quantFormula);
if (ret != null)
return ret;
final Quantifier quantifier = quantFormula.quantifier();
switch(quantifier) {
case ALL:
final BooleanAccumulator and = BooleanAccumulator.treeGate(Operator.AND);
all(quantFormula.decls(), quantFormula.formula(), 0, BooleanConstant.FALSE, and);
ret = interpreter.factory().accumulate(and);
break;
case SOME:
final BooleanAccumulator or = BooleanAccumulator.treeGate(Operator.OR);
some(quantFormula.decls(), quantFormula.formula(), 0, BooleanConstant.TRUE, or);
ret = interpreter.factory().accumulate(or);
break;
default:
throw new IllegalArgumentException("Unknown quantifier: " + quantifier);
}
return cache(quantFormula, ret);
}
use of kodkod.engine.bool.BooleanAccumulator in project org.alloytools.alloy by AlloyTools.
the class FOL2BoolTranslator method translate.
/**
* Translates the given annotated formula into a boolean accumulator with
* respect to the given interpreter and logs the translation events to the given
* logger.
*
* @requires interpreter.relations = AnnotatedNode.relations(annotated)
* @requires annotated.source[annotated.sourceSensitiveRoots()] =
* Nodes.roots(annotated.source[annotated.node])
* @return BooleanAccumulator that is the meaning of the given annotated formula
* with respect to the given interpreter
* @ensures log.records' contains the translation events that occurred while
* generating the returned value
* @throws HigherOrderDeclException annotated.node contains a higher order
* declaration
* @throws UnboundLeafException annotated.node refers to an undeclared variable
*/
static final BooleanAccumulator translate(final AnnotatedNode<Formula> annotated, LeafInterpreter interpreter, final TranslationLogger logger) {
final FOL2BoolCache cache = new FOL2BoolCache(annotated);
final FOL2BoolTranslator translator = new FOL2BoolTranslator(cache, interpreter) {
@Override
BooleanValue cache(Formula formula, BooleanValue translation) {
logger.log(formula, translation, super.env);
return super.cache(formula, translation);
}
};
translator.addSkolems(annotated.skolemRelations());
final BooleanAccumulator acc = BooleanAccumulator.treeGate(Operator.AND);
for (Formula root : Nodes.conjuncts(annotated.node())) {
acc.add(root.accept(translator));
}
logger.close();
return acc;
}
Aggregations