use of kodkod.util.ints.IntIterator in project org.alloytools.alloy by AlloyTools.
the class SymmetryDetector method computePartitions.
/**
* Partitions this.bounds.universe into sets of equivalent atoms.
*
* @ensures 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()) && (all ts:
* this.bounds.lowerBound[Relation] + this.bounds.upperBound[Relation]
* | all s: this.parts'[int] | all a1, a2:
* this.bounds.universe.atoms[s.ints] | all t1, t2: ts.tuples |
* t1.atoms[0] = a1 && t2.atoms[0] = a2 => t1.atoms[1..ts.arity) =
* t1.atoms[1..ts.arity) || t1.atoms[1..ts.arity) = a1 &&
* t1.atoms[1..ts.arity) = a2)
*/
private final void computePartitions() {
if (usize == 1)
// nothing more to do
return;
final Map<IntSet, IntSet> range2domain = new HashMap<IntSet, IntSet>((usize * 2) / 3);
// refine the partitions based on the bounds for each integer
for (IntIterator iter = bounds.ints().iterator(); iter.hasNext(); ) {
TupleSet exact = bounds.exactBound(iter.next());
refinePartitions(exact.indexView(), 1, range2domain);
}
// relation
for (TupleSet s : sort(bounds)) {
if (parts.size() == usize)
return;
refinePartitions(s.indexView(), s.arity(), range2domain);
}
}
use of kodkod.util.ints.IntIterator in project org.alloytools.alloy by AlloyTools.
the class SymmetryBreaker method breakAcyclic.
/**
* If possible, breaks symmetry on the given acyclic predicate and returns a
* formula f such that the meaning of acyclic 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
* this.bounds.upperBound[acyclic.relation] is the cross product of some
* partition in this.symmetries with itself. Assuming that this is the case, we
* then break symmetry on acyclic.relation 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 acylic.relation is removed from this.symmetries.
* </p>
*
* @return null if symmetry cannot be broken on acyclic; otherwise returns a
* formula f such that the meaning of acyclic 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 described in
* {@linkplain #breakMatrixSymmetries(Map, boolean)} iff
* this.bounds.upperBound[acyclic.relation] is the cross product of
* some partition in this.symmetries with itself
* @see #breakMatrixSymmetries(Map,boolean)
*/
private final Formula breakAcyclic(RelationPredicate.Acyclic acyclic, boolean aggressive) {
final IntSet[] colParts = symmetricColumnPartitions(acyclic.relation());
if (colParts != null) {
final Relation relation = acyclic.relation();
final IntSet upper = bounds.upperBound(relation).indexView();
final IntSet reduced = Ints.bestSet(usize * usize);
for (IntIterator tuples = upper.iterator(); tuples.hasNext(); ) {
int tuple = tuples.next();
int mirror = (tuple / usize) + (tuple % usize) * usize;
if (tuple != mirror) {
if (!upper.contains(mirror))
return null;
if (!reduced.contains(mirror))
reduced.add(tuple);
}
}
// remove the partition from the set of symmetric partitions
removePartition(colParts[0].min());
if (aggressive) {
bounds.bound(relation, bounds.universe().factory().setOf(2, reduced));
return Formula.TRUE;
} else {
final Relation acyclicConst = Relation.binary("SYM_BREAK_CONST_" + acyclic.relation().name());
bounds.boundExactly(acyclicConst, bounds.universe().factory().setOf(2, reduced));
return relation.in(acyclicConst);
}
}
return null;
}
use of kodkod.util.ints.IntIterator in project org.alloytools.alloy by AlloyTools.
the class AdaptiveRCEStrategy 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 one root formula left
break;
// get all axioms and resolvents corresponding to the clauses
// that
// form the translations of formulas identified by relevant vars
final IntSet relevantClauses = clausesFor(trace, relevantVars);
assert !relevantClauses.isEmpty() && !relevantClauses.contains(trace.size() - 1);
if (DBG)
System.out.println("relevant clauses: " + relevantClauses.size() + ", removed " + var);
return relevantClauses;
}
}
varsToTry.clear();
return Ints.EMPTY_SET;
}
use of kodkod.util.ints.IntIterator in project org.alloytools.alloy by AlloyTools.
the class DynamicRCEStrategy method sortByRelevance.
/**
* Returns an array R of longs such that for each i, j in [0..R.length) i < j
* implies that the formula identified by (int)R[i] in this.hits contributes
* fewer clauses to the core of the given trace than the formula identified by
* (int)R[j].
*
* @return an array as described above
*/
private long[] sortByRelevance(ResolutionTrace trace, IntSet relevantVars) {
hits.indices().retainAll(relevantVars);
if (hits.get(hits.indices().min()) == null) {
// the hits
for (IntIterator varItr = relevantVars.iterator(); varItr.hasNext(); ) {
final int var = varItr.next();
final IntSet varReachable = new IntBitSet(var + 1);
varReachable.add(var);
hits.put(var, varReachable);
}
for (Iterator<Clause> clauseItr = trace.reverseIterator(trace.axioms()); clauseItr.hasNext(); ) {
final Clause clause = clauseItr.next();
final int maxVar = clause.maxVariable();
for (IntSet reachableVars : hits.values()) {
if (reachableVars.contains(maxVar)) {
for (IntIterator lits = clause.literals(); lits.hasNext(); ) {
reachableVars.add(StrictMath.abs(lits.next()));
}
}
}
}
}
final long[] counts = new long[hits.size()];
for (Iterator<Clause> clauseItr = trace.iterator(trace.core()); clauseItr.hasNext(); ) {
final Clause clause = clauseItr.next();
final int maxVar = clause.maxVariable();
int i = 0;
for (IntSet reachableVars : hits.values()) {
if (reachableVars.contains(maxVar)) {
counts[i]++;
}
i++;
}
}
int i = 0;
for (IntIterator varItr = hits.indices().iterator(); varItr.hasNext(); ) {
final int var = varItr.next();
counts[i] = (counts[i] << 32) | var;
i++;
}
Arrays.sort(counts);
return counts;
}
use of kodkod.util.ints.IntIterator in project org.alloytools.alloy by AlloyTools.
the class HybridStrategy method coreClausesWithMaxVar.
/**
* Returns the indices of the clauses in the unsatisfiable core of the given
* trace that have the specified maximum variable.
*
* @return { i: trace.core() | trace[i].maxVariable() = maxVariable }
*/
private static IntSet coreClausesWithMaxVar(ResolutionTrace trace, int maxVariable) {
final IntSet core = trace.core();
final IntSet restricted = new IntBitSet(core.max() + 1);
final Iterator<Clause> clauses = trace.iterator(core);
final IntIterator indices = core.iterator();
while (clauses.hasNext()) {
Clause clause = clauses.next();
int index = indices.next();
if (clause.maxVariable() == maxVariable)
restricted.add(index);
}
return restricted;
}
Aggregations