use of kodkod.ast.BinaryExpression 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.BinaryExpression in project org.alloytools.alloy by AlloyTools.
the class Simplifier method condense.
/**
* Simplify (a.(a->b)) into b when semantically equivalent
*/
private final Expression condense(Expression x) {
while (x instanceof BinaryExpression) {
BinaryExpression b = (BinaryExpression) x;
if (b.op() == ExprOperator.JOIN && b.left() instanceof Relation && b.right() instanceof BinaryExpression) {
Relation r = (Relation) (b.left());
try {
if (sol.query(true, r, false).size() != 1)
return x;
if (sol.query(false, r, false).size() != 1)
return x;
} catch (Err er) {
return x;
}
b = (BinaryExpression) (b.right());
if (b.op() == ExprOperator.PRODUCT && b.left() == r) {
x = b.right();
continue;
}
}
break;
}
return x;
}
use of kodkod.ast.BinaryExpression in project org.alloytools.alloy by AlloyTools.
the class TranslateKodkodToJava method countHeight.
/**
* Count the height of the given Kodkod AST tree.
*/
public static int countHeight(Node node) {
ReturnVisitor<Integer, Integer, Integer, Integer> vis = new ReturnVisitor<Integer, Integer, Integer, Integer>() {
private int max(int a, int b) {
return (a >= b) ? a : b;
}
private int max(int a, int b, int c) {
return (a >= b) ? (a >= c ? a : c) : (b >= c ? b : c);
}
@Override
public Integer visit(Relation x) {
return 1;
}
@Override
public Integer visit(IntConstant x) {
return 1;
}
@Override
public Integer visit(ConstantFormula x) {
return 1;
}
@Override
public Integer visit(Variable x) {
return 1;
}
@Override
public Integer visit(ConstantExpression x) {
return 1;
}
@Override
public Integer visit(NotFormula x) {
return 1 + x.formula().accept(this);
}
@Override
public Integer visit(IntToExprCast x) {
return 1 + x.intExpr().accept(this);
}
@Override
public Integer visit(Decl x) {
return 1 + x.expression().accept(this);
}
@Override
public Integer visit(ExprToIntCast x) {
return 1 + x.expression().accept(this);
}
@Override
public Integer visit(UnaryExpression x) {
return 1 + x.expression().accept(this);
}
@Override
public Integer visit(UnaryIntExpression x) {
return 1 + x.intExpr().accept(this);
}
@Override
public Integer visit(MultiplicityFormula x) {
return 1 + x.expression().accept(this);
}
@Override
public Integer visit(BinaryExpression x) {
return 1 + max(x.left().accept(this), x.right().accept(this));
}
@Override
public Integer visit(ComparisonFormula x) {
return 1 + max(x.left().accept(this), x.right().accept(this));
}
@Override
public Integer visit(BinaryFormula x) {
return 1 + max(x.left().accept(this), x.right().accept(this));
}
@Override
public Integer visit(BinaryIntExpression x) {
return 1 + max(x.left().accept(this), x.right().accept(this));
}
@Override
public Integer visit(IntComparisonFormula x) {
return 1 + max(x.left().accept(this), x.right().accept(this));
}
@Override
public Integer visit(IfExpression x) {
return 1 + max(x.condition().accept(this), x.thenExpr().accept(this), x.elseExpr().accept(this));
}
@Override
public Integer visit(IfIntExpression x) {
return 1 + max(x.condition().accept(this), x.thenExpr().accept(this), x.elseExpr().accept(this));
}
@Override
public Integer visit(SumExpression x) {
return 1 + max(x.decls().accept(this), x.intExpr().accept(this));
}
@Override
public Integer visit(QuantifiedFormula x) {
return 1 + max(x.decls().accept(this), x.formula().accept(this));
}
@Override
public Integer visit(FixFormula x) {
return 1 + max(x.condition().accept(this), x.formula().accept(this));
}
@Override
public Integer visit(Comprehension x) {
return 1 + max(x.decls().accept(this), x.formula().accept(this));
}
@Override
public Integer visit(Decls x) {
int max = 0, n = x.size();
for (int i = 0; i < n; i++) max = max(max, x.get(i).accept(this));
return max;
}
@Override
public Integer visit(ProjectExpression x) {
int max = x.expression().accept(this);
for (Iterator<IntExpression> t = x.columns(); t.hasNext(); ) {
max = max(max, t.next().accept(this));
}
return max;
}
@Override
public Integer visit(RelationPredicate x) {
if (x instanceof Function) {
Function f = ((Function) x);
return max(f.domain().accept(this), f.range().accept(this));
}
return 1;
}
@Override
public Integer visit(NaryExpression x) {
int max = 0;
for (int m = 0, n = x.size(), i = 0; i < n; i++) {
m = x.child(i).accept(this);
if (i == 0 || max < m)
max = m;
}
return max + 1;
}
@Override
public Integer visit(NaryIntExpression x) {
int max = 0;
for (int m = 0, n = x.size(), i = 0; i < n; i++) {
m = x.child(i).accept(this);
if (i == 0 || max < m)
max = m;
}
return max + 1;
}
@Override
public Integer visit(NaryFormula x) {
int max = 0;
for (int m = 0, n = x.size(), i = 0; i < n; i++) {
m = x.child(i).accept(this);
if (i == 0 || max < m)
max = m;
}
return max + 1;
}
};
Object ans = node.accept(vis);
if (ans instanceof Integer)
return ((Integer) ans).intValue();
else
return 0;
}
use of kodkod.ast.BinaryExpression in project org.alloytools.alloy by AlloyTools.
the class A4Solution method query.
/**
* Query the Bounds object to find the lower/upper bound; throws ErrorFatal if
* expr is not Relation, nor a {union, product} of Relations.
*/
TupleSet query(boolean findUpper, Expression expr, boolean makeMutable) throws ErrorFatal {
if (expr == Expression.NONE)
return factory.noneOf(1);
if (expr == Expression.INTS)
return makeMutable ? sigintBounds.clone() : sigintBounds;
if (expr == KK_SEQIDX)
return makeMutable ? seqidxBounds.clone() : seqidxBounds;
if (expr == KK_STRING)
return makeMutable ? stringBounds.clone() : stringBounds;
if (expr instanceof Relation) {
TupleSet ans = findUpper ? bounds.upperBound((Relation) expr) : bounds.lowerBound((Relation) expr);
if (ans != null)
return makeMutable ? ans.clone() : ans;
} else if (expr instanceof BinaryExpression) {
BinaryExpression b = (BinaryExpression) expr;
if (b.op() == ExprOperator.UNION) {
TupleSet left = query(findUpper, b.left(), true);
TupleSet right = query(findUpper, b.right(), false);
left.addAll(right);
return left;
} else if (b.op() == ExprOperator.PRODUCT) {
TupleSet left = query(findUpper, b.left(), true);
TupleSet right = query(findUpper, b.right(), false);
return left.product(right);
}
}
throw new ErrorFatal("Unknown expression encountered during bounds computation: " + expr);
}
use of kodkod.ast.BinaryExpression in project org.alloytools.alloy by AlloyTools.
the class AbstractReplacer method visit.
/**
* Calls lookup(binExpr) and returns the cached value, if any. If a replacement
* has not been cached, visits the expression's children. If nothing changes,
* the argument is cached and returned, otherwise a replacement expression is
* cached and returned.
*
* @return { b: BinaryExpression | b.left = binExpr.left.accept(delegate) &&
* b.right = binExpr.right.accept(delegate) && b.op = binExpr.op }
*/
@Override
public Expression visit(BinaryExpression binExpr) {
Expression ret = lookup(binExpr);
if (ret != null)
return ret;
final Expression left = binExpr.left().accept(delegate);
final Expression right = binExpr.right().accept(delegate);
ret = (left == binExpr.left() && right == binExpr.right()) ? binExpr : left.compose(binExpr.op(), right);
return cache(binExpr, ret);
}
Aggregations