use of edu.mit.csail.sdg.ast.Sig.PrimSig in project org.alloytools.alloy by AlloyTools.
the class A4SolutionWriter method writeExpr.
/**
* Write the given Expr and its Type.
*/
private boolean writeExpr(String prefix, Expr expr) throws Err {
Type type = expr.type();
if (!type.hasTuple())
return false;
if (sol != null) {
// Check to see if the tupleset is *really* fully contained inside
// "type".
// If not, then grow "type" until the tupleset is fully contained
// inside "type"
Expr sum = type.toExpr();
int lastSize = (-1);
while (true) {
A4TupleSet ts = (A4TupleSet) (sol.eval(expr.minus(sum)));
int n = ts.size();
if (n <= 0)
break;
if (lastSize > 0 && lastSize <= n)
throw new ErrorFatal("An internal error occurred in the evaluator.");
lastSize = n;
Type extra = ts.iterator().next().type();
type = type.merge(extra);
sum = sum.plus(extra.toExpr());
}
// Now, write out the tupleset
A4TupleSet ts = (A4TupleSet) (sol.eval(expr));
for (A4Tuple t : ts) {
if (prefix.length() > 0) {
out.print(prefix);
prefix = "";
}
out.print(" <tuple>");
for (int i = 0; i < t.arity(); i++) Util.encodeXMLs(out, " <atom label=\"", t.atom(i), "\"/>");
out.print(" </tuple>\n");
}
}
// Now, write out the type
if (prefix.length() > 0)
return false;
for (List<PrimSig> ps : type.fold()) {
out.print(" <types>");
for (PrimSig sig : ps) Util.encodeXMLs(out, " <type ID=\"", map(sig), "\"/>");
out.print(" </types>\n");
}
return true;
}
use of edu.mit.csail.sdg.ast.Sig.PrimSig in project org.alloytools.alloy by AlloyTools.
the class A4SolutionWriter method writesig.
/**
* Write the given Sig.
*/
private A4TupleSet writesig(final Sig x) throws Err {
A4TupleSet ts = null, ts2 = null;
if (x == Sig.NONE)
// should not happen, but we test for it anyway
return null;
if (sol == null && x.isMeta != null)
// When writing the metamodel, skip the metamodel sigs!
return null;
if (x instanceof PrimSig)
for (final PrimSig sub : children((PrimSig) x)) {
A4TupleSet ts3 = writesig(sub);
if (ts2 == null)
ts2 = ts3;
else
ts2 = ts2.plus(ts3);
}
if (rep != null)
rep.write(x);
Util.encodeXMLs(out, "\n<sig label=\"", x.label, "\" ID=\"", map(x));
if (x instanceof PrimSig && x != Sig.UNIV)
Util.encodeXMLs(out, "\" parentID=\"", map(((PrimSig) x).parent));
if (x.builtin)
out.print("\" builtin=\"yes");
if (x.isAbstract != null)
out.print("\" abstract=\"yes");
if (x.isOne != null)
out.print("\" one=\"yes");
if (x.isLone != null)
out.print("\" lone=\"yes");
if (x.isSome != null)
out.print("\" some=\"yes");
if (x.isPrivate != null)
out.print("\" private=\"yes");
if (x.isMeta != null)
out.print("\" meta=\"yes");
if (x instanceof SubsetSig && ((SubsetSig) x).exact)
out.print("\" exact=\"yes");
if (x.isEnum != null)
out.print("\" enum=\"yes");
out.print("\">\n");
try {
if (sol != null && x != Sig.UNIV && x != Sig.SIGINT && x != Sig.SEQIDX) {
ts = (sol.eval(x));
for (A4Tuple t : ts.minus(ts2)) Util.encodeXMLs(out, " <atom label=\"", t.atom(0), "\"/>\n");
}
} catch (Throwable ex) {
throw new ErrorFatal("Error evaluating sig " + x.label, ex);
}
if (x instanceof SubsetSig)
for (Sig p : ((SubsetSig) x).parents) Util.encodeXMLs(out, " <type ID=\"", map(p), "\"/>\n");
out.print("</sig>\n");
for (Field field : x.getFields()) writeField(field);
return ts;
}
use of edu.mit.csail.sdg.ast.Sig.PrimSig in project org.alloytools.alloy by AlloyTools.
the class Type method fold.
/**
* Merge "a" into the set of entries.
* <p>
* If {a}+this.entries contain a set of entries X1..Xn, such that <br>
* (1) For each X: X[j]==a[j] for i!=j, and X[i].super==a[i].super <br>
* (2) X1[i]..Xn[i] exhaust all the direct subsignatures of an abstract parent
* sig <br>
* THEN: <br>
* we remove X1..Xn, then return the merged result of X1..Xn <br>
* ELSE <br>
* we change nothing, and simply return null
* <p>
* <b>Precondition:</b> a[i] is not NONE, and a[i].parent is abstract, and
* a[i].parent!=UNIV
*/
private static List<PrimSig> fold(ArrayList<List<PrimSig>> entries, List<PrimSig> a, int i) {
PrimSig parent = a.get(i).parent;
SafeList<PrimSig> children;
try {
children = parent.children();
} catch (Err ex) {
return null;
}
// Exception only occurs if a[i].parent==UNIV
List<PrimSig> subs = children.makeCopy();
ArrayList<List<PrimSig>> toDelete = new ArrayList<List<PrimSig>>();
for (int bi = entries.size() - 1; bi >= 0; bi--) {
List<PrimSig> b = entries.get(bi);
if (b.size() == a.size()) {
for (int j = 0; ; j++) {
if (j >= b.size()) {
toDelete.add(b);
subs.remove(b.get(i));
break;
}
PrimSig bt1 = a.get(j), bt2 = b.get(j);
if (i == j && bt2.parent != parent)
break;
if (i != j && bt2 != bt1)
break;
}
}
}
subs.remove(a.get(i));
if (subs.size() != 0)
return null;
entries.removeAll(toDelete);
entries.remove(a);
a = new ArrayList<PrimSig>(a);
a.set(i, parent);
return a;
}
use of edu.mit.csail.sdg.ast.Sig.PrimSig in project org.alloytools.alloy by AlloyTools.
the class Type method fold.
/**
* Return the result of folding this Type (that is, whenever a subset of
* relations are identical except for 1 position, where together they comprise
* of all direct subsigs of an abstract sig, then we merge them)
* <p>
* Note: the result is only current with respect to the current existing sig
* objects
*/
public List<List<PrimSig>> fold() {
ArrayList<List<PrimSig>> e = new ArrayList<List<PrimSig>>();
for (ProductType xx : entries) {
List<PrimSig> x = Arrays.asList(xx.types);
while (true) {
int n = x.size();
boolean changed = false;
for (int i = 0; i < n; i++) {
PrimSig bt = x.get(i);
if (bt.parent != null && bt.parent != UNIV && bt.parent.isAbstract != null) {
List<PrimSig> folded = fold(e, x, i);
if (folded != null) {
x = folded;
changed = true;
i--;
}
}
}
if (changed == false)
break;
}
e.add(x);
}
return e;
}
use of edu.mit.csail.sdg.ast.Sig.PrimSig in project org.alloytools.alloy by AlloyTools.
the class CompModule method addSig.
Sig addSig(String name, ExprVar par, List<ExprVar> parents, List<Decl> fields, Expr fact, Attr... attributes) throws Err {
Sig obj;
Pos pos = Pos.UNKNOWN.merge(WHERE.find(attributes));
status = 3;
dup(pos, name, true);
String full = (path.length() == 0) ? "this/" + name : path + "/" + name;
Pos subset = null, subsig = null;
boolean exact = false;
if (par != null) {
if (par.label.equals("extends")) {
subsig = par.span().merge(parents.get(0).span());
} else {
exact = !par.label.equals("in");
subset = par.span();
for (ExprVar p : parents) subset = p.span().merge(subset);
}
}
attributes = Util.append(attributes, exact ? Attr.EXACT : null);
if (subset != null) {
attributes = Util.append(attributes, SUBSET.makenull(subset));
List<Sig> newParents = new ArrayList<Sig>(parents == null ? 0 : parents.size());
if (parents != null)
for (ExprVar p : parents) newParents.add(new PrimSig(p.label, WHERE.make(p.pos)));
obj = new SubsetSig(full, newParents, attributes);
} else {
attributes = Util.append(attributes, SUBSIG.makenull(subsig));
PrimSig newParent = (parents != null && parents.size() > 0) ? (new PrimSig(parents.get(0).label, WHERE.make(parents.get(0).pos))) : UNIV;
obj = new PrimSig(full, newParent, attributes);
}
sigs.put(name, obj);
old2fields.put(obj, fields);
old2appendedfacts.put(obj, fact);
return obj;
}
Aggregations