use of kodkod.engine.bool.BooleanMatrix 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.BooleanMatrix in project org.alloytools.alloy by AlloyTools.
the class FOL2BoolTranslator method visit.
/**
* Calls lookup(decls) and returns the cached value, if any. If a translation
* has not been cached, translates decls into a list of translations of its
* children, calls cache(...) on it and returns it.
*
* @return let t = lookup(decls) | some t => t, cache(decl,
* decls.declarations.expression.accept(this))
*/
@Override
public final List<BooleanMatrix> visit(Decls decls) {
List<BooleanMatrix> ret = lookup(decls);
if (ret != null)
return ret;
ret = new ArrayList<BooleanMatrix>(decls.size());
for (Decl decl : decls) {
ret.add(visit(decl));
}
return cache(decls, ret);
}
use of kodkod.engine.bool.BooleanMatrix in project org.alloytools.alloy by AlloyTools.
the class Skolemizer method skolemExpr.
/**
* Adds a bound for the given skolem relation to this.bounds, and returns the
* expression that should replace skolemDecl.variable in the final formula.
*
* @requires skolem !in this.bounds.relations
* @requires skolem.arity = nonSkolems.size() + skolemDecl.variable().arity()
* @ensures adds a sound upper bound for the given skolem relation to
* this.bounds
* @return the expression that should replace skolemDecl.variable in the final
* formula
*/
private Expression skolemExpr(Decl skolemDecl, Relation skolem) {
final int depth = nonSkolems.size();
final int arity = depth + skolemDecl.variable().arity();
Expression skolemExpr = skolem;
Environment<BooleanMatrix, Expression> skolemEnv = Environment.empty();
for (DeclInfo info : nonSkolems) {
if (info.upperBound == null) {
info.upperBound = upperBound(info.decl.expression(), skolemEnv);
}
skolemEnv = skolemEnv.extend(info.decl.variable(), info.decl.expression(), info.upperBound);
skolemExpr = info.decl.variable().join(skolemExpr);
}
BooleanMatrix matrixBound = upperBound(skolemDecl.expression(), skolemEnv);
for (int i = depth - 1; i >= 0; i--) {
matrixBound = nonSkolems.get(i).upperBound.cross(matrixBound);
}
final TupleSet skolemBound = bounds.universe().factory().setOf(arity, matrixBound.denseIndices());
bounds.bound(skolem, skolemBound);
return skolemExpr;
}
use of kodkod.engine.bool.BooleanMatrix in project org.alloytools.alloy by AlloyTools.
the class FOL2BoolTranslator method visit.
/**
* Calls lookup(multFormula) 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(multFormula) | some t => t, let op =
* (multFormula.mult).(NO->none + SOME->some + ONE->one + LONE->lone) |
* cache(multFormula, op(multFormula.expression.accept(this)))
*/
@Override
public final BooleanValue visit(MultiplicityFormula multFormula) {
BooleanValue ret = lookup(multFormula);
if (ret != null)
return ret;
final BooleanMatrix child = multFormula.expression().accept(this);
final Multiplicity mult = multFormula.multiplicity();
switch(mult) {
case NO:
ret = child.none(env);
break;
case SOME:
ret = child.some(env);
break;
case ONE:
ret = child.one(env);
break;
case LONE:
ret = child.lone(env);
break;
default:
throw new IllegalArgumentException("Unknown multiplicity: " + mult);
}
return cache(multFormula, ret);
}
use of kodkod.engine.bool.BooleanMatrix in project org.alloytools.alloy by AlloyTools.
the class FOL2BoolTranslator method visit.
/**
* Calls lookup(project) 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(project) | some t => t, cache(project,
* project.expression.accept(this).project(translate(project.columns))
*/
@Override
public final BooleanMatrix visit(ProjectExpression project) {
BooleanMatrix ret = lookup(project);
if (ret != null)
return ret;
final Int[] cols = new Int[project.arity()];
for (int i = 0, arity = project.arity(); i < arity; i++) {
cols[i] = project.column(i).accept(this);
}
return cache(project, project.expression().accept(this).project(cols));
}
Aggregations