use of kodkod.ast.Relation in project org.alloytools.alloy by AlloyTools.
the class OverflowTheoremTest method setupBounds.
protected void setupBounds() {
Relation ret = Relation.unary("ret");
int min = min(bw);
int max = max(bw);
List<String> atoms = new ArrayList<String>(max - min + 1);
for (int i = min; i <= max; i++) {
atoms.add(String.valueOf(i));
}
final Universe universe = new Universe(atoms);
TupleFactory factory = universe.factory();
this.bounds = new Bounds(factory.universe());
for (int i = min; i <= max; i++) {
bounds.boundExactly(i, factory.setOf(String.valueOf(i)));
}
bounds.bound(ret, factory.noneOf(1), factory.allOf(1));
}
use of kodkod.ast.Relation in project org.alloytools.alloy by AlloyTools.
the class BenchmarkSymmStats method toNauty.
private static void toNauty(Bounds bounds, PrintStream stream) {
int size = bounds.universe().size() + bounds.ints().size();
for (Relation r : bounds.relations()) {
final int upsize = bounds.upperBound(r).size(), lowsize = bounds.lowerBound(r).size();
size += (upsize == lowsize ? upsize : upsize + lowsize) * r.arity();
}
stream.println("n=" + size + " $0 *=13 k = 0 " + size + " +d -a -m g");
int v = bounds.universe().size();
final IntVector vec = new ArrayIntVector();
vec.add(v);
for (Relation r : bounds.relations()) {
final int arity = r.arity();
final TupleSet up = bounds.upperBound(r), down = bounds.lowerBound(r);
final TupleSet[] sets = up.size() == down.size() || down.size() == 0 ? new TupleSet[] { up } : new TupleSet[] { down, up };
for (TupleSet s : sets) {
for (Tuple t : s) {
for (int i = 0, max = arity - 1; i < max; i++) {
stream.println(v + " : " + (v + 1) + " " + t.atomIndex(i) + ";");
v++;
}
stream.println(v + " : " + t.atomIndex(arity - 1) + ";");
v++;
}
vec.add(v);
}
}
for (TupleSet s : bounds.intBounds().values()) {
stream.println(v + " : " + s.iterator().next().atomIndex(0) + ";");
v++;
vec.add(v);
}
// stream.println(".");
stream.print("f = [ 0:" + (vec.get(0) - 1));
for (int i = 1; i < vec.size(); i++) {
stream.print(" | " + vec.get(i - 1) + ":" + (vec.get(i) - 1));
}
stream.println(" ]");
stream.println("x");
// stream.println("o");
stream.println("q");
}
use of kodkod.ast.Relation 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.ast.Relation 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.ast.Relation in project org.alloytools.alloy by AlloyTools.
the class SymmetryBreaker method relParts.
/**
* Returns a list of RelationParts that map each non-constant r in
* this.bounds.relations to the representatives of the sets from this.symmetries
* contained in the upper bound of r. The entries are sorted by relations'
* arities and names.
*
* @return a list of RelationParts that contains an entry for each non-constant
* r in this.bounds.relations and the representatives of sets from
* this.symmetries contained in the upper bound of r.
*/
private List<RelationParts> relParts() {
final List<RelationParts> relParts = new ArrayList<RelationParts>(bounds.relations().size());
for (Relation r : bounds.relations()) {
IntSet upper = bounds.upperBound(r).indexView();
if (upper.size() == bounds.lowerBound(r).size())
// skip constant relation
continue;
IntSet reps = Ints.bestSet(usize);
for (IntIterator tuples = upper.iterator(); tuples.hasNext(); ) {
for (int tIndex = tuples.next(), i = r.arity(); i > 0; i--, tIndex /= usize) {
for (IntSet symm : symmetries) {
if (symm.contains(tIndex % usize)) {
reps.add(symm.min());
break;
}
}
}
}
relParts.add(new RelationParts(r, reps));
}
final Comparator<RelationParts> cmp = new Comparator<RelationParts>() {
@Override
public int compare(RelationParts o1, RelationParts o2) {
final int acmp = o1.relation.arity() - o2.relation.arity();
return acmp != 0 ? acmp : String.valueOf(o1.relation.name()).compareTo(String.valueOf(o2.relation.name()));
}
};
Collections.sort(relParts, cmp);
return relParts;
}
Aggregations