use of edu.mit.csail.sdg.ast.Sig.PrimSig in project org.alloytools.alloy by AlloyTools.
the class Helper method atom2sig.
/**
* Given an A4Solution, return a map that maps every atom to its most specific
* signature.
* <p>
* For example, suppose we have "sig Animal { }" and "sig Dog, Cat extends
* Animal { }". Suppose the solution says Animal={A$1, A$2, A$3, A$4} and
* Dog={A$1} and Cat={A$2, A$3}. This method will return a map that maps A$1 to
* Dog, A$2 to Cat, A$3 to Cat, and A$4 to Animal. (A$1 is both an Animal and a
* Dog, but Dog is a subtype of Animal, so Dog is A$1's most specific signature)
*/
public static Map<String, PrimSig> atom2sig(A4Solution solution) throws Err {
Map<String, PrimSig> map = new HashMap<String, PrimSig>();
for (Sig s : solution.getAllReachableSigs()) if (s instanceof PrimSig)
for (A4Tuple t : solution.eval(s)) {
// We skip over SubsetSig and only care about PrimSig
String atom = t.atom(0);
PrimSig old = map.get(atom);
if (old == null || ((PrimSig) s).isSameOrDescendentOf(old)) {
map.put(atom, (PrimSig) s);
}
}
return map;
}
use of edu.mit.csail.sdg.ast.Sig.PrimSig in project org.alloytools.alloy by AlloyTools.
the class DemoFileSystem method makeSig.
PrimSig makeSig(PrimSig parent, String name, boolean isAbstract, boolean isOne) throws Err {
PrimSig ans = new PrimSig(name, parent, (isAbstract ? Attr.ABSTRACT : null), (isOne ? Attr.ONE : null));
sigs.add(ans);
return ans;
}
use of edu.mit.csail.sdg.ast.Sig.PrimSig in project org.alloytools.alloy by AlloyTools.
the class DemoFileSystem method makeInstance2.
/* Here is instance number 2. */
void makeInstance2() throws Err {
// dir = Root, D1, D2
// D2.parent = D1
// D1.parent = D2
PrimSig dir1 = makeSig(dir, "D1", false, true);
PrimSig dir2 = makeSig(dir, "D2", false, true);
fact = dir2.join(parent).equal(dir1).and(fact);
fact = dir1.join(parent).equal(dir2).and(fact);
}
use of edu.mit.csail.sdg.ast.Sig.PrimSig in project org.alloytools.alloy by AlloyTools.
the class ExprUnary method resolveClosure.
// ============================================================================================================//
/**
* Helper method that computes the relevant type for a closure expression.
* <p>
* Return Value == { c1->c2 | c1->c2 in childType, AND exists p1->p2 in
* parentType where p1..c1..c2..p2 is a path in the closure graph }
* <p>
* We need to do this because of situations like this follow: Suppose e's type
* is "A->B + B->C". Therefore, ^e = A->B + B->C + A->C which makes sense. But
* as we compute the relevance type back down, we may have lost some entries,
* and possibly end up with only A->B + A->C so we need to rediscover the
* relevant edges.
*/
private static Type resolveClosure(Type parent, Type child) {
LinkedHashSet<PrimSig> nodes = new LinkedHashSet<PrimSig>();
DirectedGraph<PrimSig> graph = new DirectedGraph<PrimSig>();
// For each (v1->v2) in childType, add (v1->v2) into the graph.
for (ProductType c : child) if (c.arity() == 2) {
PrimSig a = c.get(0), b = c.get(1);
nodes.add(a);
nodes.add(b);
graph.addEdge(a, b);
}
// edges v1->v2 and v2->v1.
for (PrimSig a : nodes) for (PrimSig b : nodes) if (a != b && a.intersects(b))
graph.addEdge(a, b);
// them.
for (ProductType p : parent) if (p.arity() == 2) {
PrimSig a = p.get(0), b = p.get(1);
// Add edges between a and all its subtypes and supertypes
if (!nodes.contains(a)) {
for (PrimSig x : nodes) if (a.intersects(x)) {
graph.addEdge(a, x);
graph.addEdge(x, a);
}
nodes.add(a);
}
// Add edges between b and all its subtypes and supertypes
if (!nodes.contains(b)) {
for (PrimSig x : nodes) if (b.intersects(x)) {
graph.addEdge(b, x);
graph.addEdge(x, b);
}
nodes.add(b);
}
}
// For each c1->c2 in childType, add c1->c2 into the finalType if there
// exists p1->p2 in parentType
// such that p1->..->c1->c2->..->p2 is a path in the graph.
Type answer = Type.EMPTY;
for (ProductType c : child) if (c.arity() == 2) {
PrimSig c1 = c.get(0), c2 = c.get(1);
for (ProductType p : parent) if (p.arity() == 2) {
PrimSig p1 = p.get(0), p2 = p.get(1);
if (graph.hasPath(p1, c1) && graph.hasPath(c2, p2)) {
answer = answer.merge(c);
break;
}
}
}
return answer;
}
Aggregations