use of kodkod.instance.TupleSet in project org.alloytools.alloy by AlloyTools.
the class Quasigroups7 method bounds.
/**
* Returns the partial bounds the problem (axioms 1, 4, 9-11).
*
* @return the partial bounds for the problem
*/
public Bounds bounds() {
final List<String> atoms = new ArrayList<String>(14);
for (int i = 0; i < 7; i++) atoms.add("e1" + i);
for (int i = 0; i < 7; i++) atoms.add("e2" + i);
final Universe u = new Universe(atoms);
final Bounds b = new Bounds(u);
final TupleFactory f = u.factory();
b.boundExactly(s1, f.range(f.tuple("e10"), f.tuple("e16")));
b.boundExactly(s2, f.range(f.tuple("e20"), f.tuple("e26")));
// axioms 9, 10, 11
for (int i = 0; i < 7; i++) {
b.boundExactly(e1[i], f.setOf("e1" + i));
b.boundExactly(e2[i], f.setOf("e2" + i));
}
// axom 1
final TupleSet op1h = f.area(f.tuple("e10", "e10", "e10"), f.tuple("e16", "e16", "e16"));
// axiom 4
final TupleSet op2h = f.area(f.tuple("e20", "e20", "e20"), f.tuple("e26", "e26", "e26"));
b.bound(op1, op1h);
b.bound(op2, op2h);
return b;
}
use of kodkod.instance.TupleSet in project org.alloytools.alloy by AlloyTools.
the class KK method main.
public static void main(String[] args) throws Exception {
Relation x6 = Relation.unary("R");
int[] ints = new int[] { 0, 1, 2 };
List<Object> atomlist = new LinkedList<Object>();
atomlist.add("R$0");
atomlist.add("R$1");
atomlist.add("R$2");
for (int i : ints) atomlist.add(i);
Universe universe = new Universe(atomlist);
TupleFactory factory = universe.factory();
Bounds bounds = new Bounds(universe);
TupleSet x6_upper = factory.noneOf(1);
x6_upper.add(factory.tuple("R$0"));
x6_upper.add(factory.tuple("R$1"));
x6_upper.add(factory.tuple("R$2"));
bounds.bound(x6, x6_upper);
for (int i : ints) {
bounds.boundExactly(i, factory.setOf(i));
}
Formula x11 = x6.some();
IntExpression x5 = x6.count();
Formula x9 = x11.implies(x5.gt(IntConstant.constant(0)));
Formula x7 = x9.not();
Solver solver = new Solver();
solver.options().setSolver(SATFactory.DefaultSAT4J);
solver.options().setBitwidth(2);
// solver.options().setFlatten(false);
solver.options().setIntEncoding(Options.IntEncoding.TWOSCOMPLEMENT);
solver.options().setSymmetryBreaking(20);
solver.options().setSkolemDepth(0);
System.out.println("Solving...");
System.out.println(PrettyPrinter.print(x7, 0));
System.out.println(bounds);
Solution sol = solver.solve(x7, bounds);
System.out.println(sol.toString());
Instance inst = sol.instance();
Evaluator ev = new Evaluator(inst);
System.out.println(ev.evaluate(x6.some()));
System.out.println(ev.evaluate(x5));
System.out.println(ev.evaluate(x5.gt(IntConstant.constant(0))));
System.out.println(ev.evaluate(x6.some().implies(x5.gt(IntConstant.constant(0))).not()));
System.out.println(ev.evaluate(x7));
}
use of kodkod.instance.TupleSet 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.instance.TupleSet in project org.alloytools.alloy by AlloyTools.
the class SymmetryDetector method sort.
/**
* Returns an array that contains unique non-empty tuplesets in the given
* bounds, sorted in the order of increasing size.
*
* @return unique non-empty tuplesets in the given bounds, sorted in the order
* of increasing size.
*/
private TupleSet[] sort(Bounds bounds) {
final List<TupleSet> sets = new ArrayList<TupleSet>(bounds.relations().size());
for (Relation r : bounds.relations()) {
if (r.isAtom() && ignoreAllAtomRelsExcept != null && !ignoreAllAtomRelsExcept.contains(r))
continue;
if (ignoreRels != null && ignoreRels.contains(r))
continue;
final TupleSet lower = bounds.lowerBound(r);
final TupleSet upper = bounds.upperBound(r);
if (!lower.isEmpty() && lower.size() < upper.size()) {
sets.add(lower);
}
if (!upper.isEmpty()) {
sets.add(upper);
}
}
final TupleSet[] sorted = sets.toArray(new TupleSet[sets.size()]);
Arrays.sort(sorted, new Comparator<TupleSet>() {
@Override
public int compare(TupleSet o1, TupleSet o2) {
return o1.size() - o2.size();
}
});
return sorted;
}
use of kodkod.instance.TupleSet in project org.alloytools.alloy by AlloyTools.
the class SolutionIterator method nextTrivialSolution.
/**
* Returns the trivial solution corresponding to the trivial translation stored
* in {@code this.translation}, and if {@code this.translation.cnf.solve()} is
* true, sets {@code this.translation} to a new translation that eliminates the
* current trivial solution from the set of possible solutions. The latter has
* the effect of forcing either the translator or the solver to come up with the
* next solution or return UNSAT. If {@code this.translation.cnf.solve()} is
* false, sets {@code this.translation} to null.
*
* @requires this.translation != null
* @ensures this.translation is modified to eliminate the current trivial
* solution from the set of possible solutions
* @return current solution
*/
private Solution nextTrivialSolution() {
final Translation.Whole transl = this.translation;
// this also
final Solution sol = Solver.trivial(transl, translTime);
if (sol.instance() == null) {
// unsat, no more solutions
translation = null;
} else {
trivial++;
final Bounds bounds = transl.bounds();
final Bounds newBounds = bounds.clone();
final List<Formula> changes = new ArrayList<Formula>();
for (Relation r : bounds.relations()) {
final TupleSet lower = bounds.lowerBound(r);
if (lower != bounds.upperBound(r)) {
// r may change
if (lower.isEmpty()) {
changes.add(r.some());
} else {
final Relation rmodel = Relation.nary(r.name() + "_" + trivial, r.arity());
newBounds.boundExactly(rmodel, lower);
changes.add(r.eq(rmodel).not());
}
}
}
// nothing can change => there can be no more solutions (besides the
// current trivial one).
// note that transl.formula simplifies to the constant true with
// respect to
// transl.bounds, and that newBounds is a superset of transl.bounds.
// as a result, finding the next instance, if any, for
// transl.formula.and(Formula.or(changes))
// with respect to newBounds is equivalent to finding the next
// instance of Formula.or(changes) alone.
final Formula formula = changes.isEmpty() ? Formula.FALSE : Formula.or(changes);
final long startTransl = System.currentTimeMillis();
translation = Translator.translate(formula, newBounds, transl.options());
translTime += System.currentTimeMillis() - startTransl;
}
return sol;
}
Aggregations