use of kodkod.ast.Expression in project org.alloytools.alloy by AlloyTools.
the class BoundsComputer method allocateSubsetSig.
// ==============================================================================================================//
/**
* Allocate relations for SubsetSig top-down.
*/
private Expression allocateSubsetSig(SubsetSig sig) throws Err {
// We must not visit the same SubsetSig more than once, so if we've been
// here already, then return the old value right away
Expression sum = sol.a2k(sig);
if (sum != null && sum != Expression.NONE)
return sum;
// Recursively form the union of all parent expressions
TupleSet ts = factory.noneOf(1);
for (Sig parent : sig.parents) {
Expression p = (parent instanceof PrimSig) ? sol.a2k(parent) : allocateSubsetSig((SubsetSig) parent);
ts.addAll(sol.query(true, p, false));
if (sum == null)
sum = p;
else
sum = sum.union(p);
}
// If subset is exact, then just use the "sum" as is
if (sig.exact) {
sol.addSig(sig, sum);
return sum;
}
// Allocate a relation for this subset sig, then bound it
rep.bound("Sig " + sig + " in " + ts + "\n");
Relation r = sol.addRel(sig.label, null, ts);
sol.addSig(sig, r);
// Add a constraint that it is INDEED a subset of the union of its
// parents
sol.addFormula(r.in(sum), sig.isSubset);
return r;
}
use of kodkod.ast.Expression in project org.alloytools.alloy by AlloyTools.
the class BoundsComputer method size.
// ==============================================================================================================//
/**
* Helper method that returns the constraint that the sig has exactly "n"
* elements, or at most "n" elements
*/
private Formula size(Sig sig, int n, boolean exact) {
Expression a = sol.a2k(sig);
if (n <= 0)
return a.no();
if (n == 1)
return exact ? a.one() : a.lone();
Formula f = exact ? Formula.TRUE : null;
Decls d = null;
Expression sum = null;
while (n > 0) {
n--;
Variable v = Variable.unary("v" + Integer.toString(TranslateAlloyToKodkod.cnt++));
kodkod.ast.Decl dd = v.oneOf(a);
if (d == null)
d = dd;
else
d = dd.and(d);
if (sum == null)
sum = v;
else {
if (f != null)
f = v.intersection(sum).no().and(f);
sum = v.union(sum);
}
}
if (f != null)
return sum.eq(a).and(f).forSome(d);
else
return a.no().or(sum.eq(a).forSome(d));
}
use of kodkod.ast.Expression 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 kodkod.ast.Expression in project org.alloytools.alloy by AlloyTools.
the class TranslateAlloyToKodkod method makeFacts.
/**
* Conjoin the constraints for "field declarations" and "fact" paragraphs
*/
private void makeFacts(Expr facts) throws Err {
rep.debug("Generating facts...\n");
// convert into a form that hopefully gives better unsat core
facts = (new ConvToConjunction()).visitThis(facts);
// add the field facts and appended facts
for (Sig s : frame.getAllReachableSigs()) {
for (Decl d : s.getFieldDecls()) {
k2pos_enabled = false;
for (ExprHasName n : d.names) {
Field f = (Field) n;
Expr form = s.decl.get().join(f).in(d.expr);
form = s.isOne == null ? form.forAll(s.decl) : ExprLet.make(null, (ExprVar) (s.decl.get()), s, form);
frame.addFormula(cform(form), f);
// subset of s.
if (s.isOne == null) {
Expression sr = a2k(s), fr = a2k(f);
for (int i = f.type().arity(); i > 1; i--) fr = fr.join(Expression.UNIV);
frame.addFormula(fr.in(sr), f);
}
}
if (s.isOne == null && 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());
frame.addFormula(cform(formula.forAll(that).forAll(s.decl)), d.disjoint2);
}
if (d.names.size() > 1 && d.disjoint != null) {
frame.addFormula(cform(ExprList.makeDISJOINT(d.disjoint, null, d.names)), d.disjoint);
}
}
k2pos_enabled = true;
for (Expr f : s.getFacts()) {
Expr form = s.isOne == null ? f.forAll(s.decl) : ExprLet.make(null, (ExprVar) (s.decl.get()), s, f);
frame.addFormula(cform(form), f);
}
}
k2pos_enabled = true;
recursiveAddFormula(facts);
}
use of kodkod.ast.Expression in project org.alloytools.alloy by AlloyTools.
the class TranslateAlloyToKodkod method visit.
/* =============================== */
/* Evaluates an ExprBinary node. */
/* =============================== */
/**
* {@inheritDoc}
*/
@Override
public Object visit(ExprBinary x) throws Err {
Expr a = x.left, b = x.right;
Expression s, s2, eL, eR;
IntExpression i;
Formula f;
Object objL, objR;
switch(x.op) {
case IMPLIES:
f = cform(a).not().or(cform(b));
return k2pos(f, x);
case IN:
return k2pos(isIn(cset(a), b), x);
case NOT_IN:
return k2pos(isIn(cset(a), b).not(), x);
case LT:
i = cint(a);
f = i.lt(cint(b));
return k2pos(f, x);
case LTE:
i = cint(a);
f = i.lte(cint(b));
return k2pos(f, x);
case GT:
i = cint(a);
f = i.gt(cint(b));
return k2pos(f, x);
case GTE:
i = cint(a);
f = i.gte(cint(b));
return k2pos(f, x);
case NOT_LT:
i = cint(a);
f = i.lt(cint(b)).not();
return k2pos(f, x);
case NOT_LTE:
i = cint(a);
f = i.lte(cint(b)).not();
return k2pos(f, x);
case NOT_GT:
i = cint(a);
f = i.gt(cint(b)).not();
return k2pos(f, x);
case NOT_GTE:
i = cint(a);
f = i.gte(cint(b)).not();
return k2pos(f, x);
case AND:
f = cform(a);
f = f.and(cform(b));
return k2pos(f, x);
case OR:
f = cform(a);
f = f.or(cform(b));
return k2pos(f, x);
case IFF:
f = cform(a);
f = f.iff(cform(b));
return k2pos(f, x);
case PLUSPLUS:
s = cset(a);
return s.override(cset(b));
case MUL:
i = cint(a);
return i.multiply(cint(b));
case DIV:
i = cint(a);
return i.divide(cint(b));
case REM:
i = cint(a);
return i.modulo(cint(b));
case SHL:
i = cint(a);
return i.shl(cint(b));
case SHR:
i = cint(a);
return i.shr(cint(b));
case SHA:
i = cint(a);
return i.sha(cint(b));
case PLUS:
return cset(a).union(cset(b));
// s = (Expression)obj; return s.union(cset(b));
case IPLUS:
return cint(a).plus(cint(b));
case MINUS:
// exception)
if (a instanceof ExprConstant && ((ExprConstant) a).op == ExprConstant.Op.NUMBER && ((ExprConstant) a).num() == 0)
if (b instanceof ExprConstant && ((ExprConstant) b).op == ExprConstant.Op.NUMBER && ((ExprConstant) b).num() == max + 1)
return IntConstant.constant(min);
return cset(a).difference(cset(b));
// s=(Expression)obj; return s.difference(cset(b));
case IMINUS:
return cint(a).minus(cint(b));
case INTERSECT:
s = cset(a);
return s.intersection(cset(b));
case ANY_ARROW_SOME:
case ANY_ARROW_ONE:
case ANY_ARROW_LONE:
case SOME_ARROW_ANY:
case SOME_ARROW_SOME:
case SOME_ARROW_ONE:
case SOME_ARROW_LONE:
case ONE_ARROW_ANY:
case ONE_ARROW_SOME:
case ONE_ARROW_ONE:
case ONE_ARROW_LONE:
case LONE_ARROW_ANY:
case LONE_ARROW_SOME:
case LONE_ARROW_ONE:
case LONE_ARROW_LONE:
case ISSEQ_ARROW_LONE:
case ARROW:
s = cset(a);
return s.product(cset(b));
case JOIN:
a = a.deNOP();
s = cset(a);
s2 = cset(b);
if (a instanceof Sig && ((Sig) a).isOne != null && s2 instanceof BinaryExpression) {
BinaryExpression bin = (BinaryExpression) s2;
if (bin.op() == ExprOperator.PRODUCT && bin.left() == s)
return bin.right();
}
return s.join(s2);
case EQUALS:
objL = visitThis(a);
objR = visitThis(b);
eL = toSet(a, objL);
eR = toSet(b, objR);
if (eL instanceof IntToExprCast && eR instanceof IntToExprCast)
f = ((IntToExprCast) eL).intExpr().eq(((IntToExprCast) eR).intExpr());
else
f = eL.eq(eR);
return k2pos(f, x);
case NOT_EQUALS:
objL = visitThis(a);
objR = visitThis(b);
eL = toSet(a, objL);
eR = toSet(b, objR);
if (eL instanceof IntToExprCast && eR instanceof IntToExprCast)
f = ((IntToExprCast) eL).intExpr().eq(((IntToExprCast) eR).intExpr()).not();
else
f = eL.eq(eR).not();
return k2pos(f, x);
case DOMAIN:
s = cset(a);
s2 = cset(b);
for (int j = s2.arity(); j > 1; j--) s = s.product(Expression.UNIV);
return s.intersection(s2);
case RANGE:
s = cset(a);
s2 = cset(b);
for (int j = s.arity(); j > 1; j--) s2 = Expression.UNIV.product(s2);
return s.intersection(s2);
}
throw new ErrorFatal(x.pos, "Unsupported operator (" + x.op + ") encountered during ExprBinary.accept()");
}
Aggregations