use of kodkod.engine.bool.BooleanMatrix in project org.alloytools.alloy by AlloyTools.
the class LeafInterpreter method interpret.
/**
* Returns a {@link kodkod.engine.bool.BooleanMatrix matrix} m of
* {@link kodkod.engine.bool.BooleanValue boolean formulas} representing the
* specified relation.
*
* @requires r in this.relations
* @return { m: BooleanMatrix | let lset =
* (this.rBounds[r].TupleSet).tuples.index, hset =
* (this.rBounds[r][TupleSet]).tuples.index, dset =
* [0..this.universe.size()^r.arity) | m.dimensions.dimensions =
* [0..r.arity) ->one this.universe.size() && m.elements[lset] = TRUE &&
* m.elements[dset-hset] = FALSE && all disj i, j: hset-lset |
* m.elements[i]+m.elements[j] in this.vars[r] && m.elements[i].label <
* m.elements[j].label <=> i < j }
* @throws UnboundLeafException r !in this.relations
*/
public final BooleanMatrix interpret(Relation r) {
if (!lowers.containsKey(r))
throw new UnboundLeafException("Unbound relation: ", r);
final IntSet lowerBound = lowers.get(r).indexView();
final IntSet upperBound = uppers.get(r).indexView();
final BooleanMatrix m = factory.matrix(Dimensions.square(universe().size(), r.arity()), upperBound, lowerBound);
if (upperBound.size() > lowerBound.size()) {
int varId = vars.get(r).min();
for (IntIterator indeces = upperBound.iterator(); indeces.hasNext(); ) {
int tupleIndex = indeces.next();
if (!lowerBound.contains(tupleIndex))
m.set(tupleIndex, factory.variable(varId++));
}
}
return m;
}
use of kodkod.engine.bool.BooleanMatrix in project org.alloytools.alloy by AlloyTools.
the class FOL2BoolTranslator method comprehension.
/**
* Translates the given comprehension as follows (where A_0...A_|A| stand for
* boolean variables that represent the tuples of the expression A, etc.): let
* comprehension = "{ a: A, b: B, ..., x: X | F(a, b, ..., x) }" | { a: A, b: B,
* ..., x: X | a in A && b in B && ... && x in X && F(a, b, ..., x) }.
*
* @param decls the declarations comprehension
* @param param formula the body of the comprehension
* @param currentDecl currently processed declaration; should be 0 initially
* @param declConstraints the constraints implied by the declarations; should be
* Boolean.TRUE intially
* @param partialIndex partial index into the provided matrix; should be 0
* initially
* @param matrix boolean matrix that will retain the final results; should be an
* empty matrix of dimensions universe.size^decls.length initially
* @ensures the given matrix contains the translation of the comprehension "{
* decls | formula }"
*/
private final void comprehension(Decls decls, Formula formula, int currentDecl, BooleanValue declConstraints, int partialIndex, BooleanMatrix matrix) {
final BooleanFactory factory = interpreter.factory();
if (currentDecl == decls.size()) {
// TODO: what about this and overflow???
matrix.set(partialIndex, factory.and(declConstraints, formula.accept(this)));
return;
}
final Decl decl = decls.get(currentDecl);
final BooleanMatrix declTransl = visit(decl);
final int position = (int) StrictMath.pow(interpreter.universe().size(), decls.size() - currentDecl - 1);
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);
comprehension(decls, formula, currentDecl + 1, factory.and(entry.value(), declConstraints), partialIndex + entry.index() * position, matrix);
groundValue.set(entry.index(), BooleanConstant.FALSE);
}
env = env.parent();
}
use of kodkod.engine.bool.BooleanMatrix in project org.alloytools.alloy by AlloyTools.
the class FOL2BoolTranslator method visit.
/**
* Calls lookup(compFormula) 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(compFormula) | some t => t, let op =
* (binExpr.op).(SUBSET->subset + EQUALS->eq) | cache(compFormula,
* op(compFormula.left.accept(this), compFormula.right.accept(this)))
*/
@Override
public final BooleanValue visit(ComparisonFormula compFormula) {
BooleanValue ret = lookup(compFormula);
if (ret != null)
return ret;
final BooleanMatrix left = compFormula.left().accept(this);
final BooleanMatrix right = compFormula.right().accept(this);
final ExprCompOperator op = compFormula.op();
switch(op) {
case SUBSET:
ret = left.subset(right, env);
break;
case EQUALS:
ret = left.eq(right, env);
break;
default:
throw new IllegalArgumentException("Unknown operator: " + compFormula.op());
}
return cache(compFormula, ret);
}
use of kodkod.engine.bool.BooleanMatrix in project org.alloytools.alloy by AlloyTools.
the class FOL2BoolTranslator method visit.
/**
* Returns this.interpreter.interpret(relation).
*
* @return this.interpreter.interpret(relation)
*/
@Override
public final BooleanMatrix visit(Relation relation) {
BooleanMatrix ret = leafCache.get(relation);
if (relation.isSkolem())
vars.add(relation.getSkolemVar());
if (ret == null) {
ret = interpreter.interpret(relation);
leafCache.put(relation, ret);
}
return ret;
}
use of kodkod.engine.bool.BooleanMatrix in project org.alloytools.alloy by AlloyTools.
the class FOL2BoolTranslator method approximate.
/**
* Translates the given annotated expression into a boolean matrix that is a
* least sound upper bound on the expression's value, given the leaf and
* variable bindings in the the provided interpreter and environment.
*
* @requires interpreter.relations = AnnotatedNode.relations(annotated)
* @return a boolean matrix that is a least sound upper bound on the
* expression's value
* @throws HigherOrderDeclException annotated.node contains a higher order
* declaration
* @throws UnboundLeafException annotated.node refers to a variable that neither
* declared nor bound in env
*/
static final BooleanMatrix approximate(AnnotatedNode<Expression> annotated, LeafInterpreter interpreter, Environment<BooleanMatrix, Expression> env) {
final FOL2BoolTranslator approximator = new FOL2BoolTranslator(new FOL2BoolCache(annotated), interpreter, env) {
@Override
public final BooleanMatrix visit(BinaryExpression binExpr) {
final BooleanMatrix ret = lookup(binExpr);
if (ret != null)
return ret;
switch(binExpr.op()) {
case DIFFERENCE:
return cache(binExpr, binExpr.left().accept(this));
case OVERRIDE:
return cache(binExpr, binExpr.left().accept(this).or(binExpr.right().accept(this)));
default:
return super.visit(binExpr);
}
}
@Override
public final BooleanMatrix visit(Comprehension cexpr) {
final BooleanMatrix ret = lookup(cexpr);
return ret != null ? ret : cache(cexpr, super.visit((Comprehension) Formula.TRUE.comprehension(cexpr.decls())));
}
@Override
public BooleanMatrix visit(IfExpression ifExpr) {
final BooleanMatrix ret = lookup(ifExpr);
return ret != null ? ret : cache(ifExpr, ifExpr.thenExpr().accept(this).or(ifExpr.elseExpr().accept(this)));
}
@Override
public BooleanMatrix visit(IntToExprCast castExpr) {
BooleanMatrix ret = lookup(castExpr);
if (ret != null)
return ret;
switch(castExpr.op()) {
case INTCAST:
return cache(castExpr, Expression.INTS.accept(this));
case BITSETCAST:
final BooleanFactory factory = super.interpreter.factory();
ret = factory.matrix(Dimensions.square(super.interpreter.universe().size(), 1));
final IntSet ints = super.interpreter.ints();
final int msb = factory.bitwidth() - 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(super.interpreter.interpret(pow2), BooleanConstant.TRUE);
}
}
// handle the sign bit
if (ints.contains(-1 << msb)) {
ret.set(super.interpreter.interpret(-1 << msb), BooleanConstant.TRUE);
}
return cache(castExpr, ret);
default:
throw new IllegalArgumentException("Unknown operator: " + castExpr.op());
}
}
};
return annotated.node().accept(approximator);
}
Aggregations