use of kodkod.instance.TupleSet in project org.alloytools.alloy by AlloyTools.
the class A4Solution method eval.
/**
* Return the A4TupleSet for the given sig (if solution not yet solved, or
* unsatisfiable, or sig not found, then return an empty tupleset)
*/
public A4TupleSet eval(Sig sig) {
try {
if (!solved || eval == null)
return new A4TupleSet(factory.noneOf(1), this);
A4TupleSet ans = evalCache.get(sig);
if (ans != null)
return ans;
TupleSet ts = eval.evaluate((Expression) TranslateAlloyToKodkod.alloy2kodkod(this, sig));
ans = new A4TupleSet(ts, this);
evalCache.put(sig, ans);
return ans;
} catch (Err er) {
return new A4TupleSet(factory.noneOf(1), this);
}
}
use of kodkod.instance.TupleSet in project org.alloytools.alloy by AlloyTools.
the class A4TupleSet method minus.
/**
* Construct a new tupleset as the subtraction of this and that; this and that
* must be come from the same solution. Note: if that==null, then the method
* returns this A4TupleSet as-is.
*/
public A4TupleSet minus(A4TupleSet that) throws ErrorAPI {
if (that == null)
return this;
if (sol != that.sol)
throw new ErrorAPI("A4TupleSet.minus() requires 2 tuplesets from the same A4Solution.");
if (arity() != that.arity())
throw new ErrorAPI("A4TupleSet.minus() requires 2 tuplesets with the same arity.");
if (tuples.size() == 0 || that.tuples.size() == 0)
// special short cut
return this;
TupleSet ts = tuples.clone();
ts.removeAll(that.tuples);
if (tuples.size() != ts.size())
return new A4TupleSet(ts, sol);
else
return this;
}
use of kodkod.instance.TupleSet in project org.alloytools.alloy by AlloyTools.
the class A4TupleSet method intersect.
/**
* Construct a new tupleset as the intersection of this and that; this and that
* must be come from the same solution.
*/
public A4TupleSet intersect(A4TupleSet that) throws ErrorAPI {
if (sol != that.sol)
throw new ErrorAPI("A4TupleSet.intersect() requires 2 tuplesets from the same A4Solution.");
if (arity() != that.arity())
throw new ErrorAPI("A4TupleSet.intersect() requires 2 tuplesets with the same arity.");
if (this.tuples.size() == 0)
// special short cut
return this;
if (that.tuples.size() == 0)
// special short cut
return that;
TupleSet ts = tuples.clone();
ts.retainAll(that.tuples);
if (tuples.size() != ts.size())
return new A4TupleSet(ts, sol);
else
return this;
}
use of kodkod.instance.TupleSet in project org.alloytools.alloy by AlloyTools.
the class BoundsComputer method allocatePrimSig.
// ==============================================================================================================//
/**
* Allocate relations for nonbuiltin PrimSigs bottom-up.
*/
private Expression allocatePrimSig(PrimSig sig) throws Err {
// Recursively allocate all children expressions, and form the union of
// them
Expression sum = null;
for (PrimSig child : sig.children()) {
Expression childexpr = allocatePrimSig(child);
if (sum == null) {
sum = childexpr;
continue;
}
// subsigs are disjoint
sol.addFormula(sum.intersection(childexpr).no(), child.isSubsig);
sum = sum.union(childexpr);
}
TupleSet lower = lb.get(sig).clone(), upper = ub.get(sig).clone();
if (sum == null) {
// If sig doesn't have children, then sig should make a fresh
// relation for itself
sum = sol.addRel(sig.label, lower, upper);
} else if (sig.isAbstract == null) {
// relation to act as the remainder.
for (PrimSig child : sig.children()) {
// Remove atoms that are KNOWN to be in a subsig;
// it's okay to mistakenly leave some atoms in, since we will
// never solve for the "remainder" relation directly;
// instead, we union the remainder with the children, then solve
// for the combined solution.
// (Thus, the more we can remove, the more efficient it gets,
// but it is not crucial for correctness)
TupleSet childTS = sol.query(false, sol.a2k(child), false);
lower.removeAll(childTS);
upper.removeAll(childTS);
}
sum = sum.union(sol.addRel(sig.label + " remainder", lower, upper));
}
sol.addSig(sig, sum);
return sum;
}
use of kodkod.instance.TupleSet in project org.alloytools.alloy by AlloyTools.
the class A4SolutionReader method parseSig.
/**
* Parse sig/set.
*/
private Sig parseSig(String id, int depth) throws IOException, Err {
Sig ans = id2sig.get(id);
if (ans != null)
return ans;
XMLNode node = nmap.get(id);
if (node == null)
throw new IOException("Unknown SigID " + id + " encountered.");
if (!node.is("sig"))
throw new IOException("ID " + id + " is not a sig.");
String label = label(node);
Attr isAbstract = yes(node, "abstract") ? Attr.ABSTRACT : null;
Attr isOne = yes(node, "one") ? Attr.ONE : null;
Attr isLone = yes(node, "lone") ? Attr.LONE : null;
Attr isSome = yes(node, "some") ? Attr.SOME : null;
Attr isPrivate = yes(node, "private") ? Attr.PRIVATE : null;
Attr isMeta = yes(node, "meta") ? Attr.META : null;
Attr isEnum = yes(node, "enum") ? Attr.ENUM : null;
Attr isExact = yes(node, "exact") ? Attr.EXACT : null;
if (yes(node, "builtin")) {
if (label.equals(UNIV.label)) {
id2sig.put(id, UNIV);
return UNIV;
}
if (label.equals(SIGINT.label)) {
id2sig.put(id, SIGINT);
return SIGINT;
}
if (label.equals(SEQIDX.label)) {
id2sig.put(id, SEQIDX);
return SEQIDX;
}
if (label.equals(STRING.label)) {
id2sig.put(id, STRING);
return STRING;
}
throw new IOException("Unknown builtin sig: " + label + " (id=" + id + ")");
}
if (depth > nmap.size())
throw new IOException("Sig " + label + " (id=" + id + ") is in a cyclic inheritance relationship.");
List<Sig> parents = null;
TupleSet ts = factory.noneOf(1);
for (XMLNode sub : node) {
if (sub.is("atom")) {
ts.add(factory.tuple(sub.getAttribute("label")));
continue;
}
if (!sub.is("type"))
continue;
Sig parent = parseSig(sub.getAttribute("ID"), depth + 1);
if (parents == null)
parents = new ArrayList<Sig>();
parents.add(parent);
}
if (parents == null) {
String parentID = node.getAttribute("parentID");
Sig parent = parseSig(parentID, depth + 1);
if (!(parent instanceof PrimSig))
throw new IOException("Parent of sig " + label + " (id=" + id + ") must not be a subset sig.");
for (Expr choice : choices) if (choice instanceof PrimSig && parent == ((PrimSig) choice).parent && ((Sig) choice).label.equals(label)) {
ans = (Sig) choice;
choices.remove(choice);
break;
}
if (ans == null) {
ans = new PrimSig(label, (PrimSig) parent, isAbstract, isLone, isOne, isSome, isPrivate, isMeta, isEnum);
allsigs.add(ans);
}
} else {
for (Expr choice : choices) if (choice instanceof SubsetSig && ((Sig) choice).label.equals(label) && sameset(parents, ((SubsetSig) choice).parents)) {
ans = (Sig) choice;
choices.remove(choice);
break;
}
if (ans == null) {
ans = new SubsetSig(label, parents, isExact, isLone, isOne, isSome, isPrivate, isMeta);
allsigs.add(ans);
}
}
id2sig.put(id, ans);
expr2ts.put(ans, ts);
if (ans instanceof PrimSig) {
// Add the atoms in this SIG into all parent sigs
for (PrimSig ans2 = ((PrimSig) ans).parent; ans2 != null && !ans2.builtin; ans2 = ans2.parent) {
TupleSet ts2 = expr2ts.get(ans2);
if (ts2 == null)
ts2 = ts.clone();
else {
ts2 = ts2.clone();
ts2.addAll(ts);
}
expr2ts.put(ans2, ts2);
}
}
return ans;
}
Aggregations