Search in sources :

Example 1 with IntSet

use of kodkod.util.ints.IntSet in project org.alloytools.alloy by AlloyTools.

the class BenchmarkSymmStats2 method printGBP.

// <symm time (ms)> <# of symms> <state bits> <SAT|UNSAT> <SAT time (ms)>
private static void printGBP(Formula formula, Bounds bounds) {
    final class SymmReporter extends AbstractReporter {

        long gbpTime;

        BigInteger symms;

        @Override
        public void detectingSymmetries(Bounds bounds) {
            gbpTime = bean.getCurrentThreadUserTime();
        }

        @Override
        public void detectedSymmetries(Set<IntSet> parts) {
            final long end = bean.getCurrentThreadUserTime();
            gbpTime = (end - gbpTime) / 1000000;
            symms = new BigInteger("1");
            for (IntSet s : parts) {
                symms = symms.multiply(fact(s.size()));
            }
        // System.out.println(parts);
        }
    }
    ;
    final SymmReporter reporter = new SymmReporter();
    final Solver solver = new Solver();
    solver.options().setBitwidth(8);
    solver.options().setSolver(SATFactory.MiniSat);
    solver.options().setReporter(reporter);
    final Solution sol = solver.solve(formula, bounds);
    // <gbp (ms)> <gbp (symms)>
    System.out.print(reporter.gbpTime + "\t");
    System.out.print(reporter.symms + "\t");
    // <state bits> <SAT|UNSAT> <SAT time (ms)>
    System.out.print(sol.stats().primaryVariables() + "\t");
    System.out.print(sol.instance() == null ? "UNSAT\t" : "SAT\t");
    System.out.print(sol.stats().solvingTime() + "\t");
}
Also used : Solver(kodkod.engine.Solver) LinkedHashSet(java.util.LinkedHashSet) TupleSet(kodkod.instance.TupleSet) IntTreeSet(kodkod.util.ints.IntTreeSet) IntSet(kodkod.util.ints.IntSet) Set(java.util.Set) IntSet(kodkod.util.ints.IntSet) Bounds(kodkod.instance.Bounds) AbstractReporter(kodkod.engine.config.AbstractReporter) BigInteger(java.math.BigInteger) Solution(kodkod.engine.Solution)

Example 2 with IntSet

use of kodkod.util.ints.IntSet in project org.alloytools.alloy by AlloyTools.

the class BenchmarkSymmStats2 method printGAD.

// <symm time (ms)> <# of symms> <state bits> <SAT|UNSAT> <SAT time (ms)>
private static void printGAD(Formula formula, Bounds bounds) {
    final class SymmReporter extends AbstractReporter {

        String symms, time;

        Bounds bounds;

        @Override
        public void detectingSymmetries(Bounds bounds) {
            this.bounds = bounds.clone();
        }

        @Override
        public void detectedSymmetries(Set<IntSet> parts) {
            parts.clear();
            final SymmInfo allSymms = allSymms(bounds);
            parts.addAll(allSymms.parts);
            symms = allSymms.symms;
            time = allSymms.time;
        // System.out.println(parts);
        }
    }
    ;
    final SymmReporter reporter = new SymmReporter();
    final Solver solver = new Solver();
    solver.options().setBitwidth(8);
    solver.options().setSolver(SATFactory.MiniSat);
    solver.options().setReporter(reporter);
    final Solution sol = solver.solve(formula, bounds);
    // <gbp (ms)> <gbp (symms)>
    System.out.print(reporter.time + "\t");
    System.out.print(reporter.symms + "\t");
    // <state bits> <SAT|UNSAT> <SAT time (ms)>
    System.out.print(sol.stats().primaryVariables() + "\t");
    System.out.print(sol.instance() == null ? "UNSAT\t" : "SAT\t");
    System.out.print(sol.stats().solvingTime() + "\t");
}
Also used : Solver(kodkod.engine.Solver) LinkedHashSet(java.util.LinkedHashSet) TupleSet(kodkod.instance.TupleSet) IntTreeSet(kodkod.util.ints.IntTreeSet) IntSet(kodkod.util.ints.IntSet) Set(java.util.Set) Bounds(kodkod.instance.Bounds) AbstractReporter(kodkod.engine.config.AbstractReporter) Solution(kodkod.engine.Solution)

Example 3 with IntSet

use of kodkod.util.ints.IntSet in project org.alloytools.alloy by AlloyTools.

the class SymmetryBreaker method breakTotalOrder.

/**
 * If possible, breaks symmetry on the given total ordering predicate and
 * returns a formula f such that the meaning of total with respect to
 * this.bounds is equivalent to the meaning of f with respect to this.bounds'.
 * If symmetry cannot be broken on the given predicate, returns null.
 * <p>
 * We break symmetry on the relation constrained by the given predicate iff
 * total.first, total.last, and total.ordered have the same upper bound, which,
 * when cross-multiplied with itself gives the upper bound of total.relation.
 * Assuming that this is the case, we then break symmetry on total.relation,
 * total.first, total.last, and total.ordered using one of the methods described
 * in {@linkplain #breakMatrixSymmetries(Map, boolean)}; the method used depends
 * on the value of the "agressive" flag. The partition that formed the upper
 * bound of total.ordered is removed from this.symmetries.
 * </p>
 *
 * @return null if symmetry cannot be broken on total; otherwise returns a
 *         formula f such that the meaning of total with respect to this.bounds
 *         is equivalent to the meaning of f with respect to this.bounds'
 * @ensures this.symmetries and this.bounds are modified as desribed in
 *          {@linkplain #breakMatrixSymmetries(Map, boolean)} iff total.first,
 *          total.last, and total.ordered have the same upper bound, which, when
 *          cross-multiplied with itself gives the upper bound of total.relation
 * @see #breakMatrixSymmetries(Map,boolean)
 */
private final Formula breakTotalOrder(RelationPredicate.TotalOrdering total, boolean aggressive) {
    final Relation first = total.first(), last = total.last(), ordered = total.ordered(), relation = total.relation();
    final IntSet domain = bounds.upperBound(ordered).indexView();
    if (symmetricColumnPartitions(ordered) != null && bounds.upperBound(first).indexView().contains(domain.min()) && bounds.upperBound(last).indexView().contains(domain.max())) {
        // construct the natural ordering that corresponds to the ordering
        // of the atoms in the universe
        final IntSet ordering = Ints.bestSet(usize * usize);
        int prev = domain.min();
        for (IntIterator atoms = domain.iterator(prev + 1, usize); atoms.hasNext(); ) {
            int next = atoms.next();
            ordering.add(prev * usize + next);
            prev = next;
        }
        if (ordering.containsAll(bounds.lowerBound(relation).indexView()) && bounds.upperBound(relation).indexView().containsAll(ordering)) {
            // remove the ordered partition from the set of symmetric
            // partitions
            removePartition(domain.min());
            final TupleFactory f = bounds.universe().factory();
            if (aggressive) {
                bounds.boundExactly(first, f.setOf(f.tuple(1, domain.min())));
                bounds.boundExactly(last, f.setOf(f.tuple(1, domain.max())));
                bounds.boundExactly(ordered, bounds.upperBound(total.ordered()));
                bounds.boundExactly(relation, f.setOf(2, ordering));
                return Formula.TRUE;
            } else {
                final Relation firstConst = Relation.unary("SYM_BREAK_CONST_" + first.name());
                final Relation lastConst = Relation.unary("SYM_BREAK_CONST_" + last.name());
                final Relation ordConst = Relation.unary("SYM_BREAK_CONST_" + ordered.name());
                final Relation relConst = Relation.binary("SYM_BREAK_CONST_" + relation.name());
                bounds.boundExactly(firstConst, f.setOf(f.tuple(1, domain.min())));
                bounds.boundExactly(lastConst, f.setOf(f.tuple(1, domain.max())));
                bounds.boundExactly(ordConst, bounds.upperBound(total.ordered()));
                bounds.boundExactly(relConst, f.setOf(2, ordering));
                return Formula.and(first.eq(firstConst), last.eq(lastConst), ordered.eq(ordConst), relation.eq(relConst));
            // return first.eq(firstConst).and(last.eq(lastConst)).and(
            // ordered.eq(ordConst)).and( relation.eq(relConst));
            }
        }
    }
    return null;
}
Also used : Relation(kodkod.ast.Relation) IntIterator(kodkod.util.ints.IntIterator) IntSet(kodkod.util.ints.IntSet) TupleFactory(kodkod.instance.TupleFactory)

Example 4 with IntSet

use of kodkod.util.ints.IntSet 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 5 with IntSet

use of kodkod.util.ints.IntSet in project org.alloytools.alloy by AlloyTools.

the class SymmetryBreaker method symmetricColumnPartitions.

/**
 * If all columns of the upper bound of r are symmetric partitions, those
 * partitions are returned. Otherwise null is returned.
 *
 * @return (all i: [0..r.arity) | some s: symmetries[int] |
 *         bounds.upperBound[r].project(i).indexView() = s) => {colParts:
 *         [0..r.arity)->IntSet | all i: [0..r.arity()) | colParts[i] =
 *         bounds.upperBound[r].project(i).indexView() }, null
 */
private final IntSet[] symmetricColumnPartitions(Relation r) {
    final IntSet upper = bounds.upperBound(r).indexView();
    if (upper.isEmpty())
        return null;
    final IntSet[] colParts = new IntSet[r.arity()];
    for (int i = r.arity() - 1, min = upper.min(); i >= 0; i--, min /= usize) {
        for (IntSet part : symmetries) {
            if (part.contains(min % usize)) {
                colParts[i] = part;
                break;
            }
        }
        if (colParts[i] == null)
            return null;
    }
    for (IntIterator tuples = upper.iterator(); tuples.hasNext(); ) {
        for (int i = r.arity() - 1, tuple = tuples.next(); i >= 0; i--, tuple /= usize) {
            if (!colParts[i].contains(tuple % usize))
                return null;
        }
    }
    return colParts;
}
Also used : IntIterator(kodkod.util.ints.IntIterator) IntSet(kodkod.util.ints.IntSet)

Aggregations

IntSet (kodkod.util.ints.IntSet)45 IntIterator (kodkod.util.ints.IntIterator)21 IntBitSet (kodkod.util.ints.IntBitSet)9 IntTreeSet (kodkod.util.ints.IntTreeSet)8 Relation (kodkod.ast.Relation)7 Clause (kodkod.engine.satlab.Clause)6 TupleSet (kodkod.instance.TupleSet)6 BooleanMatrix (kodkod.engine.bool.BooleanMatrix)5 Map (java.util.Map)4 Set (java.util.Set)4 LinkedHashMap (java.util.LinkedHashMap)3 LinkedHashSet (java.util.LinkedHashSet)3 Formula (kodkod.ast.Formula)3 Node (kodkod.ast.Node)3 BooleanFactory (kodkod.engine.bool.BooleanFactory)3 RecordFilter (kodkod.engine.fol2sat.RecordFilter)3 TranslationRecord (kodkod.engine.fol2sat.TranslationRecord)3 Bounds (kodkod.instance.Bounds)3 ArrayList (java.util.ArrayList)2 HashMap (java.util.HashMap)2