use of kodkod.util.ints.IntSet in project org.alloytools.alloy by AlloyTools.
the class SCEStrategy method next.
/**
* {@inheritDoc}
*
* @see kodkod.engine.satlab.ReductionStrategy#next(kodkod.engine.satlab.ResolutionTrace)
*/
@Override
public IntSet next(ResolutionTrace trace) {
if (varsToTry.isEmpty())
// tried everything
return Ints.EMPTY_SET;
final IntSet relevantVars = StrategyUtils.coreTailUnits(trace);
for (IntIterator varItr = varsToTry.iterator(); varItr.hasNext(); ) {
final int var = varItr.next();
varItr.remove();
if (relevantVars.remove(var)) {
// relevant variables
if (relevantVars.isEmpty())
// there was only root formula left
break;
// get all axioms corresponding to the clauses that
// form the translations of formulas identified by relevant vars
final IntSet relevantClauses = StrategyUtils.clausesFor(trace, relevantVars);
assert !relevantClauses.isEmpty() && !relevantClauses.contains(trace.size() - 1);
return relevantClauses;
}
}
varsToTry.clear();
return Ints.EMPTY_SET;
}
use of kodkod.util.ints.IntSet in project org.alloytools.alloy by AlloyTools.
the class MiniSatProver method reduce.
/**
* {@inheritDoc}
*
* @see kodkod.engine.satlab.SATProver#reduce(kodkod.engine.satlab.ReductionStrategy)
*/
@Override
public void reduce(ReductionStrategy strategy) {
proof();
if (proof.resolvents().isEmpty()) {
// nothing to minimize; we had an empty axiom added to the
return;
// solver's database
}
for (IntSet next = strategy.next(proof); !next.isEmpty(); next = strategy.next(proof)) {
long prover = make();
addVariables(prover, numberOfVariables());
for (Iterator<Clause> itr = proof.iterator(next); itr.hasNext(); ) {
Clause c = itr.next();
if (!addClause(prover, c.toArray())) {
throw new AssertionError("could not add non-redundant clause: " + c);
}
}
if (!solve(prover)) {
adjustClauseCount(next.size());
int[][] trace = trace(prover, false);
free(prover);
proof = new LazyTrace(proof, next, format(trace));
} else {
free(prover);
}
}
}
use of kodkod.util.ints.IntSet in project org.alloytools.alloy by AlloyTools.
the class MiniSatProver method formatTrivial.
/**
* Returns a subset of the given trivial trace that consists only of axioms. A
* trace is trivial iff its last clause is an empty clause. This means that the
* empty axiom was added to the solver via {@linkplain #addClause(int[])}, so no
* resolution was necessary to reach the conflict. The empty axiom is always the
* last clause in the trace.
*
* @requires trace[trace.length].length = 0
* @return a subset of the given trivial trace that consists only of axioms
*/
private int[][] formatTrivial(int[][] trace) {
final int length = trace.length;
final int empty = length - 1;
final IntSet axioms = new IntBitSet(length);
axioms.add(empty);
final int numVars = numberOfVariables();
for (int i = 0; i < empty; i++) {
int[] clause = trace[i];
if (clause[0] <= numVars) {
axioms.add(i);
}
}
if (axioms.size() == length) {
return trace;
}
final int[][] axiomClauses = new int[axioms.size()][];
final IntIterator itr = axioms.iterator();
for (int i = 0; itr.hasNext(); i++) {
axiomClauses[i] = trace[itr.next()];
}
return axiomClauses;
}
use of kodkod.util.ints.IntSet in project org.alloytools.alloy by AlloyTools.
the class SymmetryDetector method oneOf.
/**
* Returns an IntSet that can store elements in the range [0..size), and that
* holds the given number.
*
* @requries 0 <= num < size
* @return {s: IntSet | s.ints = num }
*/
private static final IntSet oneOf(int size, int num) {
final IntSet set = Ints.bestSet(size);
set.add(num);
return set;
}
use of kodkod.util.ints.IntSet in project org.alloytools.alloy by AlloyTools.
the class SymmetryDetector method refinePartitions.
/**
* Refines the atomic partitions in this.parts based on the contents of the
* given tupleset, decomposed into its constituent IntSet and arity. The
* range2domain map is used for intermediate computations for efficiency (to
* avoid allocating it in each recursive call).
*
* @requires all disj s, q: this.parts[int] | some s.ints && some q.ints && (no
* s.ints & q.ints) && this.parts[int].ints =
* [0..this.bounds.universe.size())
* @ensures let usize = this.bounds.universe.size(), firstColFactor =
* usize^(arit-1) | all disj s, q: this.parts'[int] | some s.ints &&
* some q.ints && (no s.ints & q.ints) && this.parts'[int].ints =
* [0..usize) && all s: this.parts'[int] | all a1, a2:
* this.bounds.universe.atoms[s.ints] | all t1, t2: set.ints | t1 /
* firstColFactor = a1 && t2 / firstColFactor = a2 => t1 %
* firstColFactor = t2 % firstColFactor || t1 = a1*((1 -
* firstColFactor) / (1 - usize)) && t2 = a2*((1 - firstColFactor) / (1
* - usize)))
*/
private void refinePartitions(IntSet set, int arity, Map<IntSet, IntSet> range2domain) {
if (arity == 1) {
refinePartitions(set);
return;
}
final List<IntSet> otherColumns = new LinkedList<IntSet>();
int firstColFactor = (int) StrictMath.pow(usize, arity - 1);
IntSet firstCol = Ints.bestSet(usize);
for (IntIterator rbIter = set.iterator(); rbIter.hasNext(); ) {
firstCol.add(rbIter.next() / firstColFactor);
}
refinePartitions(firstCol);
int idenFactor = (1 - firstColFactor) / (1 - usize);
for (ListIterator<IntSet> partsIter = parts.listIterator(); partsIter.hasNext(); ) {
IntSet part = partsIter.next();
if (firstCol.contains(part.min())) {
// contains one, contains them
// all
range2domain.clear();
for (IntIterator atoms = part.iterator(); atoms.hasNext(); ) {
int atom = atoms.next();
IntSet atomRange = Ints.bestSet(firstColFactor);
for (IntIterator rbIter = set.iterator(atom * firstColFactor, (atom + 1) * firstColFactor - 1); rbIter.hasNext(); ) {
atomRange.add(rbIter.next() % firstColFactor);
}
IntSet atomDomain = range2domain.get(atomRange);
if (atomDomain != null)
atomDomain.add(atom);
else
range2domain.put(atomRange, oneOf(usize, atom));
}
partsIter.remove();
IntSet idenPartition = Ints.bestSet(usize);
for (Map.Entry<IntSet, IntSet> entry : range2domain.entrySet()) {
if (entry.getValue().size() == 1 && entry.getKey().size() == 1 && entry.getKey().min() == entry.getValue().min() * idenFactor) {
idenPartition.add(entry.getValue().min());
} else {
partsIter.add(entry.getValue());
otherColumns.add(entry.getKey());
}
}
if (!idenPartition.isEmpty())
partsIter.add(idenPartition);
}
}
// refine based on the remaining columns
for (IntSet otherCol : otherColumns) {
refinePartitions(otherCol, arity - 1, range2domain);
}
}
Aggregations