use of kodkod.ast.Relation in project org.alloytools.alloy by AlloyTools.
the class Translation method interpret.
public Instance interpret(Bounds bounds) {
final SATSolver solver = cnf();
final Instance instance = new Instance(bounds.universe());
final TupleFactory f = bounds.universe().factory();
for (IndexedEntry<TupleSet> entry : bounds.intBounds()) {
instance.add(entry.index(), entry.value());
}
for (Relation r : bounds.relations()) {
// if (bnds != bounds && bnds.findRelByName(r.name()) == null)
// continue;
TupleSet lower = bounds.lowerBound(r);
IntSet indices = Ints.bestSet(lower.capacity());
indices.addAll(lower.indexView());
IntSet vars = primaryVariables(r);
if (!vars.isEmpty()) {
// System.out.println(r + ": [" + vars.min() + ", " + vars.max()
// + "]");
int lit = vars.min();
for (IntIterator iter = bounds.upperBound(r).indexView().iterator(); iter.hasNext(); ) {
final int index = iter.next();
if (!indices.contains(index) && solver.valueOf(lit++))
indices.add(index);
}
}
instance.add(r, f.setOf(r.arity(), indices));
}
return instance;
}
use of kodkod.ast.Relation in project org.alloytools.alloy by AlloyTools.
the class Translator method completeBounds.
/**
* Completes {@code this.bounds} using the bindings from
* {@code this.originalBounds} so that the result satisfies the
* {@linkplain Translation} invariants. This involves updating
* {@code this.bounds} with bindings from {@code this.originalBounds}, if any,
* that had been discarded in the {@link #translate() first step} of the
* translation. The first step of a non-incremental translation is to discard
* bounds for relations that are not constrained by
* {@code this.originalFormula}, and to discard all integer bounds if
* {@code this.originalFormula} contains no integer expressions. This is sound
* since any instance of {@code this.originalFormula} with respect to
* {@code this.originalBounds} only needs to satisfy the lower bound constraint
* on each discarded relation/integer. By updating {@code this.bounds} with the
* bindings for discarded relations/integers for which no variables were
* allocated, we ensure that any instance returned by
* {@linkplain Translation#interpret()} will bind those relations/integers to
* their lower bound, therefore satisfying the original problem
* {@code (this.originalFormula, this.originalBounds, this.options)}.
*
* @requires no this.bounds.intBound or this.bounds.intBound =
* this.originalBounds.intBound
* @ensures this.bounds.relations' = this.bounds.relations +
* this.originalBounds.relations && this.bounds.intBound' =
* this.originalBounds.intBound && this.bounds.lowerBound' =
* this.bounds.lowerBound + (this.originalBounds.relations -
* this.bounds.relations)<:(this.originalBounds.lowerBound) &&
* this.bounds.upperBound' = bounds.upperBound +
* (this.originalBounds.relations -
* this.bounds.relations)<:(this.originalBounds.upperBound)
* @return this.bounds
*/
private Bounds completeBounds() {
final Bounds optimized = this.bounds;
final Bounds original = this.originalBounds;
if (optimized.ints().isEmpty()) {
for (IndexedEntry<TupleSet> entry : original.intBounds()) {
optimized.boundExactly(entry.index(), entry.value());
}
} else {
assert optimized.intBounds().equals(original.intBounds());
}
final Set<Relation> rels = optimized.relations();
for (Relation r : original.relations()) {
if (!rels.contains(r)) {
optimized.bound(r, original.lowerBound(r), original.upperBound(r));
}
}
return optimized;
}
use of kodkod.ast.Relation in project org.alloytools.alloy by AlloyTools.
the class Translator method translateIncrementalTrivial.
/**
* @requires checkIncrementalBounds(bounds, transl)
* @requires checkIncrementalOptions(transl.options)
* @requires transl.trivial()
* @requires transl.cnf.solve()
* @return see {@link #translateIncremental(Formula, Bounds, Options)}
*/
private static Translation.Incremental translateIncrementalTrivial(Formula formula, Bounds bounds, Translation.Incremental transl) {
if (!transl.cnf().solve())
throw new IllegalArgumentException("Expected a satisfiable translation, given " + transl);
// release the old empty solver since we are going
transl.cnf().free();
// to re-translate
final Options tOptions = transl.options();
final Bounds tBounds = transl.bounds();
// transl.originalFormula.
for (Relation r : bounds.relations()) {
tBounds.bound(r, bounds.lowerBound(r), bounds.upperBound(r));
}
// re-translate the given formula with respect to tBounds. note that we
// don't have to re-translate
// the conjunction of transl.formula and formula since transl.formula is
// guaranteed to evaluate to
// TRUE with respect to tBounds (since no bindings that were originally
// in tBounds were changed by the above loop).
final Translation.Incremental updated = translateIncremental(formula, tBounds, tOptions);
// due to symmetry breaking.
return new Translation.Incremental(updated.bounds(), tOptions, transl.symmetries(), updated.interpreter(), updated.incrementer());
}
use of kodkod.ast.Relation in project org.alloytools.alloy by AlloyTools.
the class HOLTranslator method noNewHOLSkolems.
private boolean noNewHOLSkolems(Collection<Relation> newSkolems, Collection<Relation> oldSkolems) {
Set<Relation> diff = new HashSet<Relation>(newSkolems);
diff.removeAll(oldSkolems);
for (Relation sk : diff) {
Decl d = sk.getSkolemVarDecl();
if (d != null && d.multiplicity() != Multiplicity.ONE)
return false;
}
return true;
}
use of kodkod.ast.Relation in project org.alloytools.alloy by AlloyTools.
the class Bounds method varRels.
public Collection<Relation> varRels() {
ArrayList<Relation> ans = new ArrayList<Relation>(relations.size());
TupleSet ub, lb;
for (Relation r : relations) {
ub = uppers.get(r);
lb = lowers.get(r);
if (ub.size() > lb.size())
ans.add(r);
}
return ans;
}
Aggregations