use of edu.mit.csail.sdg.alloy4.JoinableList in project org.alloytools.alloy by AlloyTools.
the class CompModule method resolveAll.
// ============================================================================================================================//
/**
* This method resolves the entire world; NOTE: if it throws an exception, it
* may leave the world in an inconsistent state!
*/
static CompModule resolveAll(final A4Reporter rep, final CompModule root) throws Err {
final List<ErrorWarning> warns = new ArrayList<ErrorWarning>();
for (CompModule m : root.getAllReachableModules()) root.allModules.add(m);
resolveParams(rep, root.allModules);
resolveModules(rep, root.allModules);
for (CompModule m : root.allModules) for (Sig s : m.sigs.values()) root.sig2module.put(s, m);
// Resolves SigAST -> Sig, and topologically sort the sigs into the
// "sorted" array
root.new2old.put(UNIV, UNIV);
root.new2old.put(SIGINT, SIGINT);
root.new2old.put(SEQIDX, SEQIDX);
root.new2old.put(STRING, STRING);
root.new2old.put(NONE, NONE);
HashSet<Object> topo = new HashSet<Object>();
for (CompModule m : root.allModules) for (Sig s : m.sigs.values()) resolveSig(root, topo, s);
// (since fields in subsigs are allowed to refer to parent's fields)
for (Sig oldS : root.new2old.keySet()) resolveFieldDecl(root, rep, oldS, warns, false);
// Typecheck the function declarations
JoinableList<Err> errors = new JoinableList<Err>();
for (CompModule x : root.allModules) errors = x.resolveFuncDecls(rep, errors, warns);
if (!errors.isEmpty())
throw errors.pick();
// Typecheck the defined fields
for (Sig oldS : root.new2old.keySet()) resolveFieldDecl(root, rep, oldS, warns, true);
if (Version.experimental && root.seenDollar)
resolveMeta(root);
// Reject name clash
rejectNameClash(root.allModules);
// to function declarations)
for (CompModule x : root.allModules) {
errors = x.resolveFuncBody(rep, errors, warns);
errors = x.resolveAssertions(rep, errors, warns);
errors = x.resolveFacts(root, rep, errors, warns);
// root module's list of exact sigs
for (String n : x.exactParams) {
Sig sig = x.params.get(n);
if (sig != null)
root.exactSigs.add(sig);
}
}
if (!errors.isEmpty())
throw errors.pick();
// Typecheck the run/check commands (which can refer to function bodies
// and assertions)
root.resolveCommands(root.getAllReachableFacts());
if (!errors.isEmpty())
throw errors.pick();
for (ErrorWarning w : warns) rep.warning(w);
for (Sig s : root.exactSigs) rep.debug("Forced to be exact: " + s + "\n");
return root;
}
use of edu.mit.csail.sdg.alloy4.JoinableList in project org.alloytools.alloy by AlloyTools.
the class CompModule method resolveFuncBody.
/**
* Each Func's body will now be typechecked Expr object.
*/
private JoinableList<Err> resolveFuncBody(A4Reporter rep, JoinableList<Err> errors, List<ErrorWarning> warns) throws Err {
for (ArrayList<Func> entry : funcs.values()) for (Func ff : entry) {
Context cx = new Context(this, warns);
cx.rootfunbody = ff;
for (Decl d : ff.decls) for (ExprHasName n : d.names) cx.put(n.label, n);
Expr newBody = cx.check(ff.getBody());
if (ff.isPred)
newBody = newBody.resolve_as_formula(warns);
else
newBody = newBody.resolve_as_set(warns);
errors = errors.make(newBody.errors);
if (!newBody.errors.isEmpty())
continue;
try {
ff.setBody(newBody);
} catch (Err er) {
errors = errors.make(er);
continue;
}
if (warns != null && ff.returnDecl.type().hasTuple() && newBody.type().hasTuple() && !newBody.type().intersects(ff.returnDecl.type()))
warns.add(new ErrorWarning(newBody.span(), "Function return value is disjoint from its return type.\n" + "Function body has type " + newBody.type() + "\n" + "but the return type is " + ff.returnDecl.type()));
// else if (warns!=null && Version.experimental &&
// !newBody.type.isSubtypeOf(ff.returnDecl.type))
// warns.add(new ErrorWarning(newBody.span(),
// "Function may return a tuple not in its declared return
// type.\n"
// +"The Alloy Analyzer's analysis may be unsound\n"
// +"if it returns a tuple outside its declared return type.\n"
// +"Function body has type "+newBody.type+"\nbut the return
// type is "+ff.returnDecl.type));
rep.typecheck(ff.toString() + ", BODY:" + newBody.type() + "\n");
}
return errors;
}
use of edu.mit.csail.sdg.alloy4.JoinableList in project org.alloytools.alloy by AlloyTools.
the class ExprCall method make.
// ============================================================================================================//
/**
* Constructs an ExprCall node with the given predicate/function "fun" and the
* list of arguments "args".
*/
public static Expr make(Pos pos, Pos closingBracket, Func fun, List<Expr> args, long extraPenalty) {
if (extraPenalty < 0)
extraPenalty = 0;
if (args == null)
args = ConstList.make();
long weight = extraPenalty;
boolean ambiguous = false;
JoinableList<Err> errs = emptyListOfErrors;
TempList<Expr> newargs = new TempList<Expr>(args.size());
if (args.size() != fun.count()) {
errs = errs.make(new ErrorSyntax(pos, "" + fun + " has " + fun.count() + " parameters but is called with " + args.size() + " arguments."));
}
for (int i = 0; i < args.size(); i++) {
final int a = (i < fun.count()) ? fun.get(i).type.arity() : 0;
final Expr x = args.get(i).typecheck_as_set();
ambiguous = ambiguous || x.ambiguous;
errs = errs.make(x.errors);
weight = weight + x.weight;
if (x.mult != 0)
errs = errs.make(new ErrorSyntax(x.span(), "Multiplicity expression not allowed here."));
if (a > 0 && x.errors.isEmpty() && !x.type.hasArity(a))
errs = errs.make(new ErrorType(x.span(), "This should have arity " + a + " but instead its possible type(s) are " + x.type));
newargs.add(x);
}
Type t = Type.FORMULA;
if (!fun.isPred && errs.size() == 0) {
final Type tt = fun.returnDecl.type;
try {
// This provides a limited form of polymorphic function,
// by using actual arguments at each call site to derive a
// tighter bound on the return value.
DeduceType d = new DeduceType();
for (int i = 0; i < args.size(); i++) {
ExprVar param = fun.get(i);
d.env.put(param, newargs.get(i).type.extract(param.type.arity()));
}
t = fun.returnDecl.accept(d);
if (t == null || t.is_int() || t.is_bool || t.arity() != tt.arity())
// Just in case an error occurred...
t = tt;
} catch (Throwable ex) {
// Just in case an error occurred...
t = tt;
}
}
return new ExprCall(pos, closingBracket, ambiguous, t, fun, newargs.makeConst(), extraPenalty, weight, errs);
}
use of edu.mit.csail.sdg.alloy4.JoinableList in project org.alloytools.alloy by AlloyTools.
the class ExprList method make.
/**
* Generates a call to a builtin predicate
*/
public static ExprList make(Pos pos, Pos closingBracket, Op op, List<? extends Expr> args) {
boolean ambiguous = false;
JoinableList<Err> errs = emptyListOfErrors;
TempList<Expr> newargs = new TempList<Expr>(args.size());
long weight = 0;
Type commonArity = null;
for (int i = 0; i < args.size(); i++) {
Expr a = (op == Op.AND || op == Op.OR) ? args.get(i).typecheck_as_formula() : args.get(i).typecheck_as_set();
ambiguous = ambiguous || a.ambiguous;
weight = weight + a.weight;
if (a.mult != 0)
errs = errs.make(new ErrorSyntax(a.span(), "Multiplicity expression not allowed here."));
if (!a.errors.isEmpty())
errs = errs.make(a.errors);
else if (commonArity == null)
commonArity = a.type;
else
commonArity = commonArity.pickCommonArity(a.type);
if (op == Op.AND)
addAND(newargs, a);
else if (op == Op.OR)
addOR(newargs, a);
else
newargs.add(a);
}
if (op == Op.TOTALORDER) {
if (newargs.size() != 3) {
errs = errs.make(new ErrorSyntax(pos, "The builtin pred/totalOrder[] predicate must be called with exactly three arguments."));
} else if (errs.isEmpty()) {
if (!newargs.get(0).type.hasArity(1))
errs = errs.make(new ErrorType(pos, "The first argument to pred/totalOrder must be unary."));
if (!newargs.get(1).type.hasArity(1))
errs = errs.make(new ErrorType(pos, "The second argument to pred/totalOrder must be unary."));
if (!newargs.get(2).type.hasArity(2))
errs = errs.make(new ErrorType(pos, "The third argument to pred/totalOrder must be binary."));
}
}
if (op == Op.DISJOINT) {
if (newargs.size() < 2)
errs = errs.make(new ErrorSyntax(pos, "The builtin disjoint[] predicate must be called with at least two arguments."));
if (commonArity == EMPTY)
errs = errs.make(new ErrorType(pos, "The builtin predicate disjoint[] cannot be used among expressions of different arities."));
}
return new ExprList(pos, closingBracket, op, ambiguous, newargs.makeConst(), weight, errs);
}
use of edu.mit.csail.sdg.alloy4.JoinableList in project org.alloytools.alloy by AlloyTools.
the class CompModule method resolveFuncDecls.
/**
* Each FunAST will now point to a bodyless Func object.
*/
private JoinableList<Err> resolveFuncDecls(A4Reporter rep, JoinableList<Err> errors, List<ErrorWarning> warns) throws Err {
for (ArrayList<Func> list : funcs.values()) {
for (int listi = 0; listi < list.size(); listi++) {
Func f = list.get(listi);
String fullname = (path.length() == 0 ? "this/" : (path + "/")) + f.label;
// Each PARAMETER can refer to earlier parameter in the same
// function, and any SIG or FIELD visible from here.
// Each RETURNTYPE can refer to the parameters of the same
// function, and any SIG or FIELD visible from here.
Context cx = new Context(this, warns);
cx.rootfunparam = true;
TempList<Decl> tmpdecls = new TempList<Decl>();
boolean err = false;
for (Decl d : f.decls) {
TempList<ExprVar> tmpvars = new TempList<ExprVar>();
Expr val = cx.check(d.expr).resolve_as_set(warns);
if (!val.errors.isEmpty()) {
err = true;
errors = errors.make(val.errors);
}
for (ExprHasName n : d.names) {
ExprVar v = ExprVar.make(n.span(), n.label, val.type());
cx.put(n.label, v);
tmpvars.add(v);
rep.typecheck((f.isPred ? "pred " : "fun ") + fullname + ", Param " + n.label + ": " + v.type() + "\n");
}
tmpdecls.add(new Decl(d.isPrivate, d.disjoint, d.disjoint2, tmpvars.makeConst(), val));
}
Expr ret = null;
if (!f.isPred) {
ret = cx.check(f.returnDecl).resolve_as_set(warns);
if (!ret.errors.isEmpty()) {
err = true;
errors = errors.make(ret.errors);
}
}
if (err)
continue;
try {
f = new Func(f.pos, f.isPrivate, fullname, tmpdecls.makeConst(), ret, f.getBody());
list.set(listi, f);
rep.typecheck("" + f + ", RETURN: " + f.returnDecl.type() + "\n");
} catch (Err ex) {
errors = errors.make(ex);
}
}
}
return errors;
}
Aggregations