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");
}
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");
}
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;
}
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);
}
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;
}
Aggregations