use of kodkod.ast.Formula in project org.alloytools.alloy by AlloyTools.
the class TranslateAlloyToKodkod method visit.
/**
* {@inheritDoc}
*/
@Override
public Object visit(ExprQt x) throws Err {
Expr xx = x.desugar();
if (xx instanceof ExprQt)
x = (ExprQt) xx;
else
return visitThis(xx);
Object ans = visit_qt(x.op, x.decls, x.sub);
if (ans instanceof Formula)
k2pos((Formula) ans, x);
return ans;
}
use of kodkod.ast.Formula 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()");
}
use of kodkod.ast.Formula in project org.alloytools.alloy by AlloyTools.
the class TranslateAlloyToKodkod method isInBinary.
/**
* Helper method that translates the formula "r in (a ?->? b)" into a Kodkod
* formula.
*/
private Formula isInBinary(Expression r, ExprBinary ab) throws Err {
final Expression a = cset(ab.left), b = cset(ab.right);
Decls d = null, d2 = null;
Formula ans1, ans2;
// "R in A ->op B" means for each tuple a in A, there are "op" tuples in
// r that begins with a.
Expression atuple = null, ar = r;
for (int i = a.arity(); i > 0; i--) {
Variable v = Variable.unary("v" + Integer.toString(cnt++));
if (!am) {
if (a.arity() == 1)
d = v.oneOf(a);
else if (d == null)
d = v.oneOf(Expression.UNIV);
else
d = v.oneOf(Expression.UNIV).and(d);
} else {
d = am(a, d, i, v);
}
ar = v.join(ar);
if (atuple == null)
atuple = v;
else
atuple = atuple.product(v);
}
ans1 = isIn(ar, ab.right);
switch(ab.op) {
case ISSEQ_ARROW_LONE:
case ANY_ARROW_LONE:
case SOME_ARROW_LONE:
case ONE_ARROW_LONE:
case LONE_ARROW_LONE:
ans1 = ar.lone().and(ans1);
break;
case ANY_ARROW_ONE:
case SOME_ARROW_ONE:
case ONE_ARROW_ONE:
case LONE_ARROW_ONE:
ans1 = ar.one().and(ans1);
break;
case ANY_ARROW_SOME:
case SOME_ARROW_SOME:
case ONE_ARROW_SOME:
case LONE_ARROW_SOME:
ans1 = ar.some().and(ans1);
break;
}
if (a.arity() > 1) {
Formula tmp = isIn(atuple, ab.left);
if (tmp != Formula.TRUE)
ans1 = tmp.implies(ans1);
}
ans1 = ans1.forAll(d);
// "R in A op-> B" means for each tuple b in B, there are "op" tuples in
// r that end with b.
Expression btuple = null, rb = r;
for (int i = b.arity(); i > 0; i--) {
Variable v = Variable.unary("v" + Integer.toString(cnt++));
if (!am) {
if (b.arity() == 1)
d2 = v.oneOf(b);
else if (d2 == null)
d2 = v.oneOf(Expression.UNIV);
else
d2 = v.oneOf(Expression.UNIV).and(d2);
} else {
d2 = am(b, d2, i, v);
}
rb = rb.join(v);
if (btuple == null)
btuple = v;
else
btuple = v.product(btuple);
}
ans2 = isIn(rb, ab.left);
switch(ab.op) {
case LONE_ARROW_ANY:
case LONE_ARROW_SOME:
case LONE_ARROW_ONE:
case LONE_ARROW_LONE:
ans2 = rb.lone().and(ans2);
break;
case ONE_ARROW_ANY:
case ONE_ARROW_SOME:
case ONE_ARROW_ONE:
case ONE_ARROW_LONE:
ans2 = rb.one().and(ans2);
break;
case SOME_ARROW_ANY:
case SOME_ARROW_SOME:
case SOME_ARROW_ONE:
case SOME_ARROW_LONE:
ans2 = rb.some().and(ans2);
break;
}
if (b.arity() > 1) {
Formula tmp = isIn(btuple, ab.right);
if (tmp != Formula.TRUE)
ans2 = tmp.implies(ans2);
}
ans2 = ans2.forAll(d2);
// Now, put everything together
Formula ans = r.in(a.product(b)).and(ans1).and(ans2);
if (ab.op == ExprBinary.Op.ISSEQ_ARROW_LONE) {
Expression rr = r;
while (rr.arity() > 1) rr = rr.join(Expression.UNIV);
ans = rr.difference(rr.join(A4Solution.KK_NEXT)).in(A4Solution.KK_ZERO).and(ans);
}
return ans;
}
use of kodkod.ast.Formula in project org.alloytools.alloy by AlloyTools.
the class TranslateAlloyToKodkod method visit.
// ==============================================================================================================//
/* ============================ */
/* Evaluates an ExprITE node. */
/* ============================ */
/**
* {@inheritDoc}
*/
@Override
public Object visit(ExprITE x) throws Err {
Formula c = cform(x.cond);
Object l = visitThis(x.left);
if (l instanceof Formula) {
Formula c1 = c.implies((Formula) l);
Formula c2 = c.not().implies(cform(x.right));
return k2pos(c1.and(c2), x);
}
if (l instanceof Expression) {
return c.thenElse((Expression) l, cset(x.right));
}
return c.thenElse((IntExpression) l, cint(x.right));
}
use of kodkod.ast.Formula in project org.alloytools.alloy by AlloyTools.
the class FOL2BoolTranslator method visit.
/**
* Calls lookup(formula) and returns the cached value, if any. If a translation
* has not been cached, translates the formula, calls cache(...) on it and
* returns it.
*
* @return let t = lookup(formula) | some t => t, cache(formula,
* formula.op(formula.left.accept(this), formula.right.accept(this))
*/
@Override
public final BooleanValue visit(NaryFormula formula) {
final BooleanValue ret = lookup(formula);
if (ret != null)
return ret;
final FormulaOperator op = formula.op();
final Operator.Nary boolOp;
switch(op) {
case AND:
boolOp = Operator.AND;
break;
case OR:
boolOp = Operator.OR;
break;
default:
throw new IllegalArgumentException("Unknown nary operator: " + op);
}
final BooleanAccumulator acc = BooleanAccumulator.treeGate(boolOp);
final BooleanValue shortCircuit = boolOp.shortCircuit();
for (Formula child : formula) {
if (acc.add(child.accept(this)) == shortCircuit)
break;
}
return cache(formula, interpreter.factory().accumulate(acc));
}
Aggregations