use of edu.mit.csail.sdg.ast.Expr in project org.alloytools.alloy by AlloyTools.
the class CompModule method parseOneExpressionFromString.
/**
* Parse one expression by starting fromt this module as the root module.
*/
@Override
public Expr parseOneExpressionFromString(String input) throws Err, FileNotFoundException, IOException {
Map<String, String> fc = new LinkedHashMap<String, String>();
// We prepend the line "run{"
fc.put("", "run {\n" + input + "}");
CompModule m = CompUtil.parse(new ArrayList<Object>(), null, fc, null, -1, "", "", 1);
if (m.funcs.size() == 0)
throw new ErrorSyntax("The input does not correspond to an Alloy expression.");
Expr body = m.funcs.values().iterator().next().get(0).getBody();
Context cx = new Context(this, null);
body = cx.check(body);
body = body.resolve(body.type(), null);
if (body.errors.size() > 0)
throw body.errors.pick();
else
return body;
}
use of edu.mit.csail.sdg.ast.Expr in project org.alloytools.alloy by AlloyTools.
the class CompModule method resolveCommand.
/**
* Resolve a particular command.
*/
private Command resolveCommand(Command cmd, ConstList<Sig> exactSigs, Expr globalFacts) throws Err {
Command parent = cmd.parent == null ? null : resolveCommand(cmd.parent, exactSigs, globalFacts);
String cname = ((ExprVar) (cmd.formula)).label;
Expr e;
Clause declaringClause = null;
if (cmd.check) {
// We prefer assertion in the
List<Object> m = getRawQS(2, cname);
// topmost module
if (m.size() == 0 && cname.indexOf('/') < 0)
m = getRawNQS(this, 2, cname);
if (m.size() > 1)
unique(cmd.pos, cname, m);
if (m.size() < 1)
throw new ErrorSyntax(cmd.pos, "The assertion \"" + cname + "\" cannot be found.");
Expr expr = (Expr) (m.get(0));
e = expr.not();
} else {
// We prefer fun/pred in the
List<Object> m = getRawQS(4, cname);
// topmost module
if (m.size() == 0 && cname.indexOf('/') < 0)
m = getRawNQS(this, 4, cname);
if (m.size() > 1)
unique(cmd.pos, cname, m);
if (m.size() < 1)
throw new ErrorSyntax(cmd.pos, "The predicate/function \"" + cname + "\" cannot be found.");
Func f = (Func) (m.get(0));
declaringClause = f;
e = f.getBody();
if (!f.isPred)
e = e.in(f.returnDecl);
if (f.decls.size() > 0)
e = ExprQt.Op.SOME.make(null, null, f.decls, e);
}
if (e == null)
e = ExprConstant.TRUE;
TempList<CommandScope> sc = new TempList<CommandScope>(cmd.scope.size());
for (CommandScope et : cmd.scope) {
Sig s = getRawSIG(et.sig.pos, et.sig.label);
if (s == null)
throw new ErrorSyntax(et.sig.pos, "The sig \"" + et.sig.label + "\" cannot be found.");
sc.add(new CommandScope(null, s, et.isExact, et.startingScope, et.endingScope, et.increment));
}
if (cmd.nameExpr != null) {
cmd.nameExpr.setReferenced(declaringClause);
}
return new Command(cmd.pos, cmd.nameExpr, cmd.label, cmd.check, cmd.overall, cmd.bitwidth, cmd.maxseq, cmd.expects, sc.makeConst(), exactSigs, globalFacts.and(e), parent);
}
use of edu.mit.csail.sdg.ast.Expr in project org.alloytools.alloy by AlloyTools.
the class SimInstance method isIn.
/**
* Helper method that evaluates the formula "a in b" where b.mult==0
*/
public boolean isIn(SimTuple a, Expr b) throws Err {
b = b.deNOP();
if (b instanceof PrimSig && ((PrimSig) b).builtin) {
if (a.arity() != 1)
return false;
if (b.isSame(Sig.UNIV))
return true;
if (b.isSame(Sig.NONE))
return false;
if (b.isSame(Sig.SEQIDX)) {
Integer i = a.get(0).toInt(null);
return i != null && i >= 0 && i < maxseq;
}
if (b.isSame(Sig.SIGINT)) {
Integer i = a.get(0).toInt(null);
return i != null;
}
if (b.isSame(Sig.STRING)) {
String at = a.get(0).toString();
return at.length() > 0 && (at.charAt(0) == '\"');
}
}
if (b instanceof ExprBinary && ((ExprBinary) b).op == ExprBinary.Op.ARROW) {
Expr left = ((ExprBinary) b).left, right = ((ExprBinary) b).right;
int ll = left.type().arity(), rr = right.type().arity();
if (ll <= rr)
return isIn(a.head(ll), left) && isIn(a.tail(rr), right);
return isIn(a.tail(rr), right) && isIn(a.head(ll), left);
}
if (b instanceof ExprBinary && ((ExprBinary) b).op == ExprBinary.Op.PLUS) {
return isIn(a, ((ExprBinary) b).left) || isIn(a, ((ExprBinary) b).right);
}
if (b instanceof ExprBinary && ((ExprBinary) b).op == ExprBinary.Op.MINUS) {
return isIn(a, ((ExprBinary) b).left) && !isIn(a, ((ExprBinary) b).right);
}
return cset(b).has(a);
}
use of edu.mit.csail.sdg.ast.Expr in project org.alloytools.alloy by AlloyTools.
the class SimInstance method enumerate.
/**
* Helper method for enumerating all possibilties for a
* quantification-expression.
*/
private int enumerate(final TempList<SimTuple> store, int sum, final ExprQt x, final Expr body, final int i) throws Err {
// if op is ALL NO SOME ONE LONE then it always returns
// 0 1 2
final int n = x.count();
final ExprVar v = x.get(i);
final Expr bound = x.getBound(i);
final SimTupleset e = cset(bound);
final Iterator<SimTupleset> it;
switch(bound.mult()) {
case LONEOF:
it = e.loneOf();
break;
case ONEOF:
it = e.oneOf();
break;
case SOMEOF:
it = e.someOf();
break;
default:
it = e.setOf();
}
while (it.hasNext()) {
final SimTupleset binding = it.next();
if (bound.mult == 2 && !isIn(binding, bound))
continue;
env.put(v, binding);
if (i < n - 1)
sum = enumerate(store, sum, x, body, i + 1);
else if (x.op == ExprQt.Op.SUM)
sum += cint(body);
else if (x.op != ExprQt.Op.COMPREHENSION)
sum += cform(body) ? 1 : 0;
else if (cform(body)) {
SimTuple a = null, b;
for (int j = 0; j < n; j++) {
b = ((SimTupleset) (env.get(x.get(j)))).getTuple();
if (a == null)
a = b;
else
a = a.product(b);
}
store.add(a);
}
env.remove(v);
if (sum >= 2 && x.op != ExprQt.Op.COMPREHENSION && x.op != ExprQt.Op.SUM)
// no need to enumerate further
return 2;
}
return sum;
}
use of edu.mit.csail.sdg.ast.Expr in project org.alloytools.alloy by AlloyTools.
the class SimInstance method validate.
/**
* Checks whether this instance satisfies every fact defined in the given model.
*
* @param world - this must be the root of the Alloy model
* @return an empty String if yes, nonempty String if no
*/
public String validate(Module world) {
try {
for (Sig s : world.getAllReachableSigs()) if (!s.builtin) {
if (s.isLone != null && !(visit(s).longsize() <= 1))
return "There can be at most one " + s;
if (s.isOne != null && !(visit(s).longsize() == 1))
return "There must be exactly one " + s;
if (s.isSome != null && !(visit(s).longsize() >= 1))
return "There must be at least one " + s;
if (s instanceof SubsetSig) {
SubsetSig p = (SubsetSig) s;
Expr sum = null;
for (Sig par : p.parents) sum = par.plus(sum);
if (p.exact) {
if (!equal(s, sum))
return "Sig " + s + " must be equal to the union of its parents " + p.parents;
} else {
if (!isIn(s, sum))
return "Sig " + s + " must be equal or subset of its parents " + p.parents;
}
} else if (s != Sig.UNIV && s != Sig.NONE) {
PrimSig p = (PrimSig) s;
if (!isIn(s, p.parent))
return "Sig " + s + " must be equal or subset of its parent " + p.parent;
}
if (s.isAbstract != null) {
Expr sum = null;
for (Sig x : ((PrimSig) s).children()) sum = x.plus(sum);
if (sum != null && !equal(s, sum))
return "Abstract sig " + s + " must be equal to the union of its subsigs";
}
for (Decl d : s.getFieldDecls()) for (ExprHasName f : d.names) if (!((Field) f).defined) {
if (!cform(s.decl.get().join(f).in(d.expr).forAll(s.decl))) {
return "Field " + f + " violated its bound: " + visit((Field) f) + "\n" + d.expr;
}
SimTupleset setS = visit(s);
SimTupleset setF = visit((Field) f);
for (SimAtom x : setF.getAllAtoms(0)) if (!setS.has(x))
return "Field " + f + " first column has extra atom: " + setF + " not in " + setS;
}
for (Decl d : s.getFieldDecls()) {
if (d.disjoint != null && d.names.size() > 0) {
if (!cform(ExprList.makeDISJOINT(null, null, d.names)))
return "Fields must be disjoint.";
}
if (d.disjoint2 != null)
for (ExprHasName f : d.names) {
Decl that = s.oneOf("that");
Expr formula = s.decl.get().equal(that.get()).not().implies(s.decl.get().join(f).intersect(that.get().join(f)).no());
if (!cform(formula.forAll(that).forAll(s.decl)))
return "Fields must be disjoint.";
}
}
for (Expr f : s.getFacts()) {
if (!cform(f.forAll(s.decl))) {
f = f.deNOP();
if (f instanceof ExprUnary) {
ExprUnary u = (ExprUnary) f;
f = u.sub.deNOP();
if (f instanceof ExprBinary) {
ExprBinary b = (ExprBinary) f;
if (b.op == ExprBinary.Op.JOIN && b.left.isSame(s.decl.get()) && b.right.deNOP() instanceof Field) {
String n = ((Field) (b.right.deNOP())).label;
if (u.op == ExprUnary.Op.SOME)
return "The " + n + " cannot be empty.";
if (u.op == ExprUnary.Op.LONE)
return "The " + n + " cannot have more than one value.";
if (u.op == ExprUnary.Op.ONE)
return "The " + n + " must have exactly one value.";
if (u.op == ExprUnary.Op.NO)
return "The " + n + " must be empty.";
}
}
}
return "Cannot violate a consistency constraint";
}
}
}
for (Module m : world.getAllReachableModules()) for (Pair<String, Expr> f : m.getAllFacts()) if (!cform(f.b)) {
String err = f.a;
if (err.matches("^fact\\$[0-9][0-9]*"))
err = f.b.toString();
if (err.length() >= 2 && err.startsWith("\"") && err.endsWith("\""))
err = err.substring(1, err.length() - 1);
return "Violation: " + err;
}
return "";
} catch (Err ex) {
return "An internal error has occured:\n" + ex.dump();
}
}
Aggregations