use of edu.mit.csail.sdg.ast.Sig 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 in project org.alloytools.alloy by AlloyTools.
the class CompModule method resolveCommands.
/**
* Each command now points to a typechecked Expr.
*/
private void resolveCommands(Expr globalFacts) throws Err {
ConstList<Sig> exactSigs = ConstList.make(world.exactSigs);
for (int i = 0; i < commands.size(); i++) {
Command cmd = commands.get(i);
cmd = resolveCommand(cmd, exactSigs, globalFacts);
commands.set(i, cmd);
}
}
use of edu.mit.csail.sdg.ast.Sig 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;
}
use of edu.mit.csail.sdg.ast.Sig in project org.alloytools.alloy by AlloyTools.
the class CompModule method rejectNameClash.
// ============================================================================================================================//
private static void rejectNameClash(final List<CompModule> modules) throws Err {
// The Alloy language forbids two overlapping sigs from having fields
// with the same name.
// In other words: if 2 fields have the same name, then their type's
// first column must not intersect.
final Map<String, List<Field>> fieldname2fields = new LinkedHashMap<String, List<Field>>();
for (CompModule m : modules) {
for (Sig sig : m.sigs.values()) {
for (Field field : sig.getFields()) {
List<Field> peers = fieldname2fields.get(field.label);
if (peers == null) {
peers = new ArrayList<Field>();
fieldname2fields.put(field.label, peers);
}
for (Field field2 : peers) if (field.type().firstColumnOverlaps(field2.type()))
throw new ErrorType(field.pos, "Two overlapping signatures cannot have\n" + "two fields with the same name \"" + field.label + "\":\n\n1) one is in sig \"" + field.sig + "\"\n" + field.pos + "\n\n2) the other is in sig \"" + field2.sig + "\"\n" + field2.pos);
peers.add(field);
}
}
}
}
use of edu.mit.csail.sdg.ast.Sig in project org.alloytools.alloy by AlloyTools.
the class CompModule method resolveFacts.
/**
* Each fact name now points to a typechecked Expr rather than an untypechecked
* Exp; we'll also add the sig appended facts.
*/
private JoinableList<Err> resolveFacts(CompModule res, A4Reporter rep, JoinableList<Err> errors, List<ErrorWarning> warns) throws Err {
Context cx = new Context(this, warns);
for (int i = 0; i < facts.size(); i++) {
String name = facts.get(i).a;
Expr expr = facts.get(i).b;
Expr checked = cx.check(expr);
expr = checked.resolve_as_formula(warns);
if (expr.errors.isEmpty()) {
facts.set(i, new Pair<String, Expr>(name, expr));
rep.typecheck("Fact " + name + ": " + expr.type() + "\n");
} else
errors = errors.make(expr.errors);
}
for (Sig s : sigs.values()) {
Expr f = res.old2appendedfacts.get(res.new2old.get(s));
if (f == null)
continue;
if (f instanceof ExprConstant && ((ExprConstant) f).op == ExprConstant.Op.TRUE)
continue;
Expr formula;
cx.rootsig = s;
if (s.isOne == null) {
cx.put("this", s.decl.get());
formula = cx.check(f).resolve_as_formula(warns);
} else {
cx.put("this", s);
formula = cx.check(f).resolve_as_formula(warns);
}
cx.remove("this");
if (formula.errors.size() > 0)
errors = errors.make(formula.errors);
else {
s.addFact(formula);
rep.typecheck("Fact " + s + "$fact: " + formula.type() + "\n");
}
}
return errors;
}
Aggregations