use of edu.mit.csail.sdg.alloy4.Err in project org.alloytools.alloy by AlloyTools.
the class A4SolutionReader method parseSkolem.
/**
* Parse skolem.
*/
private ExprVar parseSkolem(String id) throws IOException, Err {
final XMLNode node = nmap.get(id);
if (node == null)
throw new IOException("Unknown ID " + id + " encountered.");
if (!node.is("skolem"))
throw new IOException("ID " + id + " is not a skolem.");
String label = label(node);
Expr type = null;
for (XMLNode sub : node) if (sub.is("types")) {
Expr t = parseType(sub);
if (type == null)
type = t;
else
type = type.plus(t);
}
int arity;
if (type == null || (arity = type.type().arity()) < 1)
throw new IOException("Skolem " + label + " is maltyped.");
ExprVar var = ExprVar.make(Pos.UNKNOWN, label, type.type());
TupleSet ts = parseTuples(node, arity);
expr2ts.put(var, ts);
return var;
}
use of edu.mit.csail.sdg.alloy4.Err in project org.alloytools.alloy by AlloyTools.
the class A4SolutionReader method parseTuple.
/**
* Parse tuple.
*/
private Tuple parseTuple(XMLNode tuple, int arity) throws Err {
Tuple ans = null;
try {
for (XMLNode sub : tuple) if (sub.is("atom")) {
Tuple x = factory.tuple(sub.getAttribute("label"));
if (ans == null)
ans = x;
else
ans = ans.product(x);
}
if (ans == null)
throw new ErrorFatal("Expecting: <tuple> <atom label=\"..\"/> .. </tuple>");
if (ans.arity() != arity)
throw new ErrorFatal("Expecting: tuple of arity " + arity + " but got tuple of arity " + ans.arity());
return ans;
} catch (Throwable ex) {
throw new ErrorFatal("Expecting: <tuple> <atom label=\"..\"/> .. </tuple>", ex);
}
}
use of edu.mit.csail.sdg.alloy4.Err in project org.alloytools.alloy by AlloyTools.
the class A4SolutionReader method parseField.
/**
* Parse field.
*/
private Field parseField(String id) throws IOException, Err {
final XMLNode node = nmap.get(id);
if (node == null)
throw new IOException("Unknown FieldID " + id + " encountered.");
if (!node.is("field"))
throw new IOException("ID " + id + " is not a field.");
String label = label(node);
Pos isPrivate = yes(node, "private") ? Pos.UNKNOWN : null;
Pos isMeta = yes(node, "meta") ? Pos.UNKNOWN : null;
Expr type = null;
for (XMLNode sub : node) if (sub.is("types")) {
Expr t = parseType(sub);
if (type == null)
type = t;
else
type = type.plus(t);
}
int arity;
if (type == null || (arity = type.type().arity()) < 2)
throw new IOException("Field " + label + " is maltyped.");
String parentID = node.getAttribute("parentID");
Sig parent = id2sig.get(parentID);
if (parent == null)
throw new IOException("ID " + parentID + " is not a sig.");
Field field = null;
for (Field f : parent.getFields()) if (f.label.equals(label) && f.type().arity() == arity && choices.contains(f)) {
field = f;
choices.remove(f);
break;
}
if (field == null)
field = parent.addTrickyField(Pos.UNKNOWN, isPrivate, null, null, isMeta, new String[] { label }, UNIV.join(type))[0];
TupleSet ts = parseTuples(node, arity);
expr2ts.put(field, ts);
return field;
}
use of edu.mit.csail.sdg.alloy4.Err 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.Err 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);
}
Aggregations