Search in sources :

Example 6 with BooleanFactory

use of kodkod.engine.bool.BooleanFactory 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();
}
Also used : BooleanValue(kodkod.engine.bool.BooleanValue) Decl(kodkod.ast.Decl) BooleanMatrix(kodkod.engine.bool.BooleanMatrix) BooleanFactory(kodkod.engine.bool.BooleanFactory)

Example 7 with BooleanFactory

use of kodkod.engine.bool.BooleanFactory in project org.alloytools.alloy by AlloyTools.

the class FOL2BoolTranslator method visit.

/**
 * Calls lookup(binFormula) 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(binFormula) | some t => t, cache(binFormula,
 *         binFormula.op(binFormula.left.accept(this),
 *         binFormula.right.accept(this))
 */
@Override
public final BooleanValue visit(BinaryFormula binFormula) {
    BooleanValue ret = lookup(binFormula);
    if (ret != null)
        return ret;
    final BooleanValue left = binFormula.left().accept(this);
    final BooleanValue right = binFormula.right().accept(this);
    final FormulaOperator op = binFormula.op();
    final BooleanFactory f = interpreter.factory();
    switch(op) {
        case AND:
            ret = f.and(left, right);
            break;
        case OR:
            ret = f.or(left, right);
            break;
        case IMPLIES:
            ret = f.implies(left, right);
            break;
        case IFF:
            ret = f.iff(left, right);
            break;
        default:
            throw new IllegalArgumentException("Unknown operator: " + op);
    }
    return cache(binFormula, ret);
}
Also used : FormulaOperator(kodkod.ast.operator.FormulaOperator) BooleanValue(kodkod.engine.bool.BooleanValue) BooleanFactory(kodkod.engine.bool.BooleanFactory)

Example 8 with BooleanFactory

use of kodkod.engine.bool.BooleanFactory 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);
}
Also used : IfExpression(kodkod.ast.IfExpression) BinaryExpression(kodkod.ast.BinaryExpression) IntToExprCast(kodkod.ast.IntToExprCast) IntSet(kodkod.util.ints.IntSet) BooleanMatrix(kodkod.engine.bool.BooleanMatrix) Comprehension(kodkod.ast.Comprehension) BooleanFactory(kodkod.engine.bool.BooleanFactory)

Example 9 with BooleanFactory

use of kodkod.engine.bool.BooleanFactory in project org.alloytools.alloy by AlloyTools.

the class FOL2BoolTranslator method all.

/**
 * Translates the given universally quantified formula as follows (where
 * A_0...A_|A| stand for boolean variables that represent the tuples of the
 * expression A, etc.): let quantFormula = "all 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 = "all 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.FALSE initially
 * @param acc the accumulator that contains the top level conjunction; should be
 *            an empty AND accumulator initially
 * @ensures the given accumulator contains the translation of the formula "all
 *          decls | formula"
 */
private void all(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.or(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.ALL);
    for (IndexedEntry<BooleanValue> entry : declTransl) {
        groundValue.set(entry.index(), BooleanConstant.TRUE);
        all(decls, formula, currentDecl + 1, factory.or(factory.not(entry.value()), declConstraints), acc);
        groundValue.set(entry.index(), BooleanConstant.FALSE);
    }
    env = env.parent();
}
Also used : BooleanValue(kodkod.engine.bool.BooleanValue) Decl(kodkod.ast.Decl) BooleanMatrix(kodkod.engine.bool.BooleanMatrix) BooleanFactory(kodkod.engine.bool.BooleanFactory)

Aggregations

BooleanFactory (kodkod.engine.bool.BooleanFactory)9 BooleanValue (kodkod.engine.bool.BooleanValue)8 BooleanMatrix (kodkod.engine.bool.BooleanMatrix)7 Decl (kodkod.ast.Decl)4 IntSet (kodkod.util.ints.IntSet)3 BooleanAccumulator (kodkod.engine.bool.BooleanAccumulator)2 Int (kodkod.engine.bool.Int)2 IntIterator (kodkod.util.ints.IntIterator)2 ArrayList (java.util.ArrayList)1 BinaryExpression (kodkod.ast.BinaryExpression)1 Comprehension (kodkod.ast.Comprehension)1 IfExpression (kodkod.ast.IfExpression)1 IntToExprCast (kodkod.ast.IntToExprCast)1 Relation (kodkod.ast.Relation)1 FormulaOperator (kodkod.ast.operator.FormulaOperator)1