use of edu.mit.csail.sdg.ast.ExprBinary 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.ExprBinary 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();
}
}
use of edu.mit.csail.sdg.ast.ExprBinary in project org.alloytools.alloy by AlloyTools.
the class BoundsComputer method sim.
// ==============================================================================================================//
/**
* If ex is a simple combination of Relations, then return that combination,
* else return null.
*/
private Expression sim(Expr ex) {
while (ex instanceof ExprUnary) {
ExprUnary u = (ExprUnary) ex;
if (u.op != ExprUnary.Op.NOOP && u.op != ExprUnary.Op.EXACTLYOF)
break;
ex = u.sub;
}
if (ex instanceof ExprBinary) {
ExprBinary b = (ExprBinary) ex;
if (b.op == ExprBinary.Op.ARROW || b.op == ExprBinary.Op.PLUS || b.op == ExprBinary.Op.JOIN) {
Expression left = sim(b.left);
if (left == null)
return null;
Expression right = sim(b.right);
if (right == null)
return null;
if (b.op == ExprBinary.Op.ARROW)
return left.product(right);
if (b.op == ExprBinary.Op.PLUS)
return left.union(right);
else
return left.join(right);
}
}
if (ex instanceof ExprConstant) {
switch(((ExprConstant) ex).op) {
case EMPTYNESS:
return Expression.NONE;
}
}
if (ex == Sig.NONE)
return Expression.NONE;
if (ex == Sig.SIGINT)
return Expression.INTS;
if (ex instanceof Sig)
return sol.a2k((Sig) ex);
if (ex instanceof Field)
return sol.a2k((Field) ex);
return null;
}
use of edu.mit.csail.sdg.ast.ExprBinary in project org.alloytools.alloy by AlloyTools.
the class ConvToConjunction method visit.
/**
* {@inheritDoc}
*/
@Override
public Expr visit(ExprUnary x) throws Err {
if (x.op == ExprUnary.Op.NOOP) {
return visitThis(x.sub);
}
if (x.op == ExprUnary.Op.NOT) {
Expr s = x.sub.deNOP();
if (s instanceof ExprBinary && ((ExprBinary) s).op == ExprBinary.Op.OR) {
Expr a = visitThis(((ExprBinary) s).left.not());
Expr b = visitThis(((ExprBinary) s).right.not());
return a.and(b);
}
}
return x;
}
use of edu.mit.csail.sdg.ast.ExprBinary in project org.alloytools.alloy by AlloyTools.
the class ConvToConjunction method visit.
/**
* {@inheritDoc}
*/
@Override
public Expr visit(ExprQt x) throws Err {
if (x.op == ExprQt.Op.ALL) {
Expr s = x.sub.deNOP();
if (s instanceof ExprBinary && ((ExprBinary) s).op == ExprBinary.Op.AND) {
Expr a = visitThis(x.op.make(Pos.UNKNOWN, Pos.UNKNOWN, x.decls, ((ExprBinary) s).left));
Expr b = visitThis(x.op.make(Pos.UNKNOWN, Pos.UNKNOWN, x.decls, ((ExprBinary) s).right));
return a.and(b);
}
}
return x;
}
Aggregations