Search in sources :

Example 1 with BooleanFactory

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);
}
Also used : IntIterator(kodkod.util.ints.IntIterator) IntSet(kodkod.util.ints.IntSet) ArrayList(java.util.ArrayList) BooleanAccumulator(kodkod.engine.bool.BooleanAccumulator) BooleanMatrix(kodkod.engine.bool.BooleanMatrix) BooleanFactory(kodkod.engine.bool.BooleanFactory) Relation(kodkod.ast.Relation) BooleanValue(kodkod.engine.bool.BooleanValue)

Example 2 with BooleanFactory

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);
}
Also used : IntIterator(kodkod.util.ints.IntIterator) IntSet(kodkod.util.ints.IntSet) BooleanValue(kodkod.engine.bool.BooleanValue) BooleanMatrix(kodkod.engine.bool.BooleanMatrix) Int(kodkod.engine.bool.Int) BooleanFactory(kodkod.engine.bool.BooleanFactory)

Example 3 with BooleanFactory

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

Example 4 with BooleanFactory

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

Example 5 with BooleanFactory

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);
    }
}
Also used : BooleanValue(kodkod.engine.bool.BooleanValue) BooleanAccumulator(kodkod.engine.bool.BooleanAccumulator) 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