Search in sources :

Example 71 with Expression

use of kodkod.ast.Expression in project org.alloytools.alloy by AlloyTools.

the class TranslateAlloyToKodkod method visit_qt.

/**
 * Helper method that translates the quantification expression "op vars | sub"
 */
private Object visit_qt(final ExprQt.Op op, final ConstList<Decl> xvars, final Expr sub) throws Err {
    if (op == ExprQt.Op.NO) {
        return visit_qt(ExprQt.Op.ALL, xvars, sub.not());
    }
    if (op == ExprQt.Op.ONE || op == ExprQt.Op.LONE) {
        boolean ok = true;
        for (int i = 0; i < xvars.size(); i++) {
            Expr v = addOne(xvars.get(i).expr).deNOP();
            if (v.type().arity() != 1 || v.mult() != ExprUnary.Op.ONEOF) {
                ok = false;
                break;
            }
        }
        if (op == ExprQt.Op.ONE && ok)
            return ((Expression) visit_qt(ExprQt.Op.COMPREHENSION, xvars, sub)).one();
        if (op == ExprQt.Op.LONE && ok)
            return ((Expression) visit_qt(ExprQt.Op.COMPREHENSION, xvars, sub)).lone();
    }
    if (op == ExprQt.Op.ONE) {
        Formula f1 = (Formula) visit_qt(ExprQt.Op.LONE, xvars, sub);
        Formula f2 = (Formula) visit_qt(ExprQt.Op.SOME, xvars, sub);
        return f1.and(f2);
    }
    if (op == ExprQt.Op.LONE) {
        QuantifiedFormula p1 = (QuantifiedFormula) visit_qt(ExprQt.Op.ALL, xvars, sub);
        QuantifiedFormula p2 = (QuantifiedFormula) visit_qt(ExprQt.Op.ALL, xvars, sub);
        Decls s1 = p1.decls(), s2 = p2.decls(), decls = null;
        Formula f1 = p1.formula(), f2 = p2.formula();
        Formula[] conjuncts = new Formula[s1.size()];
        for (int i = 0; i < conjuncts.length; i++) {
            kodkod.ast.Decl d1 = s1.get(i), d2 = s2.get(i);
            conjuncts[i] = d1.variable().eq(d2.variable());
            if (decls == null)
                decls = d1.and(d2);
            else
                decls = decls.and(d1).and(d2);
        }
        return f1.and(f2).implies(Formula.and(conjuncts)).forAll(decls);
    }
    Decls dd = null;
    List<Formula> guards = new ArrayList<Formula>();
    for (Decl dep : xvars) {
        final Expr dexexpr = addOne(dep.expr);
        final Expression dv = cset(dexexpr);
        for (ExprHasName dex : dep.names) {
            final Variable v = Variable.nary(skolem(dex.label), dex.type().arity());
            final kodkod.ast.Decl newd;
            env.put((ExprVar) dex, v);
            if (dex.type().arity() != 1) {
                guards.add(isIn(v, dexexpr));
                newd = v.setOf(dv);
            } else
                switch(dexexpr.mult()) {
                    case SETOF:
                        newd = v.setOf(dv);
                        break;
                    case SOMEOF:
                        newd = v.someOf(dv);
                        break;
                    case LONEOF:
                        newd = v.loneOf(dv);
                        break;
                    default:
                        newd = v.oneOf(dv);
                }
            if (frame != null)
                frame.kv2typepos(v, dex.type(), dex.pos);
            if (dd == null)
                dd = newd;
            else
                dd = dd.and(newd);
        }
    }
    final Formula ans = (op == ExprQt.Op.SUM) ? null : cform(sub);
    final IntExpression ians = (op != ExprQt.Op.SUM) ? null : cint(sub);
    for (Decl d : xvars) for (ExprHasName v : d.names) env.remove((ExprVar) v);
    if (op == ExprQt.Op.COMPREHENSION)
        // guards.size()==0, since each var
        return ans.comprehension(dd);
    // has to be unary
    if (op == ExprQt.Op.SUM)
        // guards.size()==0, since each var has to be
        return ians.sum(dd);
    // unary
    if (op == ExprQt.Op.SOME) {
        if (guards.size() == 0)
            return ans.forSome(dd);
        guards.add(ans);
        return Formula.and(guards).forSome(dd);
    } else {
        if (guards.size() == 0)
            return ans.forAll(dd);
        return Formula.and(guards).implies(ans).forAll(dd);
    }
}
Also used : ExprToIntCast(kodkod.ast.ExprToIntCast) IntToExprCast(kodkod.ast.IntToExprCast) Variable(kodkod.ast.Variable) Decls(kodkod.ast.Decls) IntExpression(kodkod.ast.IntExpression) ArrayList(java.util.ArrayList) Decl(edu.mit.csail.sdg.ast.Decl) QuantifiedFormula(kodkod.ast.QuantifiedFormula) Formula(kodkod.ast.Formula) Expr(edu.mit.csail.sdg.ast.Expr) Expression(kodkod.ast.Expression) BinaryExpression(kodkod.ast.BinaryExpression) IntExpression(kodkod.ast.IntExpression) ExprHasName(edu.mit.csail.sdg.ast.ExprHasName) QuantifiedFormula(kodkod.ast.QuantifiedFormula)

Example 72 with Expression

use of kodkod.ast.Expression in project org.alloytools.alloy by AlloyTools.

the class TranslateAlloyToKodkod method visit.

/**
 * {@inheritDoc}
 */
@Override
public Object visit(ExprList x) throws Err {
    if (x.op == ExprList.Op.AND || x.op == ExprList.Op.OR) {
        if (x.args.size() == 0)
            return (x.op == ExprList.Op.AND) ? Formula.TRUE : Formula.FALSE;
        Formula answer = getSingleFormula(x.op == ExprList.Op.AND, 1, x.args);
        return k2pos(answer, x);
    }
    if (x.op == ExprList.Op.TOTALORDER) {
        Expression elem = cset(x.args.get(0)), first = cset(x.args.get(1)), next = cset(x.args.get(2));
        if (elem instanceof Relation && first instanceof Relation && next instanceof Relation) {
            Relation lst = frame.addRel("", null, frame.query(true, elem, false));
            totalOrderPredicates.add((Relation) elem);
            totalOrderPredicates.add((Relation) first);
            totalOrderPredicates.add(lst);
            totalOrderPredicates.add((Relation) next);
            return k2pos(((Relation) next).totalOrder((Relation) elem, (Relation) first, lst), x);
        }
        // every
        Formula f1 = elem.in(first.join(next.reflexiveClosure()));
        // element
        // is in
        // the
        // total
        // order
        // first element has no
        Formula f2 = next.join(first).no();
        // predecessor
        Variable e = Variable.unary("v" + Integer.toString(cnt++));
        // each element
        Formula f3 = e.eq(first).or(next.join(e).one());
        // (except the
        // first) has
        // one
        // predecessor
        // each
        Formula f4 = e.eq(elem.difference(next.join(elem))).or(e.join(next).one());
        // element
        // (except
        // the
        // last)
        // has
        // one
        // successor
        // there are no
        Formula f5 = e.in(e.join(next.closure())).not();
        // cycles
        return k2pos(f3.and(f4).and(f5).forAll(e.oneOf(elem)).and(f1).and(f2), x);
    }
    // This says no(a&b) and no((a+b)&c) and no((a+b+c)&d)...
    // Empirically this seems to be more efficient than "no(a&b) and no(a&c)
    // and no(b&c)"
    Formula answer = null;
    Expression a = null;
    for (Expr arg : x.args) {
        Expression b = cset(arg);
        if (a == null) {
            a = b;
            continue;
        }
        if (answer == null)
            answer = a.intersection(b).no();
        else
            answer = a.intersection(b).no().and(answer);
        a = a.union(b);
    }
    if (answer != null)
        return k2pos(answer, x);
    else
        return Formula.TRUE;
}
Also used : QuantifiedFormula(kodkod.ast.QuantifiedFormula) Formula(kodkod.ast.Formula) Relation(kodkod.ast.Relation) Variable(kodkod.ast.Variable) Expr(edu.mit.csail.sdg.ast.Expr) Expression(kodkod.ast.Expression) BinaryExpression(kodkod.ast.BinaryExpression) IntExpression(kodkod.ast.IntExpression)

Example 73 with Expression

use of kodkod.ast.Expression in project org.alloytools.alloy by AlloyTools.

the class TranslateAlloyToKodkod method alloy2kodkod.

/**
 * Translate the Alloy expression into an equivalent Kodkod Expression or
 * IntExpression or Formula object.
 *
 * @param sol - an existing satisfiable A4Solution object
 * @param expr - this is the Alloy expression we want to translate
 */
public static Object alloy2kodkod(A4Solution sol, Expr expr) throws Err {
    if (expr.ambiguous && !expr.errors.isEmpty())
        expr = expr.resolve(expr.type(), null);
    if (!expr.errors.isEmpty())
        throw expr.errors.pick();
    TranslateAlloyToKodkod tr = new TranslateAlloyToKodkod(sol.getBitwidth(), sol.unrolls(), sol.a2k(), sol.s2k());
    Object ans;
    try {
        ans = tr.visitThis(expr);
    } catch (UnsatisfiedLinkError ex) {
        throw new ErrorFatal("The required JNI library cannot be found: " + ex.toString().trim());
    } catch (CapacityExceededException ex) {
        throw rethrow(ex);
    } catch (HigherOrderDeclException ex) {
        throw new ErrorType("Analysis cannot be performed since it requires higher-order quantification that could not be skolemized.");
    } catch (Throwable ex) {
        if (ex instanceof Err)
            throw (Err) ex;
        throw new ErrorFatal("Unknown exception occurred: " + ex, ex);
    }
    if ((ans instanceof IntExpression) || (ans instanceof Formula) || (ans instanceof Expression))
        return ans;
    throw new ErrorFatal("Unknown internal error encountered in the evaluator.");
}
Also used : QuantifiedFormula(kodkod.ast.QuantifiedFormula) Formula(kodkod.ast.Formula) CapacityExceededException(kodkod.engine.CapacityExceededException) ErrorFatal(edu.mit.csail.sdg.alloy4.ErrorFatal) ErrorType(edu.mit.csail.sdg.alloy4.ErrorType) Err(edu.mit.csail.sdg.alloy4.Err) Expression(kodkod.ast.Expression) BinaryExpression(kodkod.ast.BinaryExpression) IntExpression(kodkod.ast.IntExpression) IntExpression(kodkod.ast.IntExpression) HigherOrderDeclException(kodkod.engine.fol2sat.HigherOrderDeclException)

Example 74 with Expression

use of kodkod.ast.Expression in project org.alloytools.alloy by AlloyTools.

the class TranslateAlloyToKodkod method visit.

/**
 * {@inheritDoc}
 */
@Override
public Object visit(ExprCall x) throws Err {
    final Func f = x.fun;
    final Object candidate = f.count() == 0 ? cacheForConstants.get(f) : null;
    if (candidate != null)
        return candidate;
    final Expr body = f.getBody();
    if (body.type().arity() < 0 || body.type().arity() != f.returnDecl.type().arity())
        throw new ErrorType(body.span(), "Function return value not fully resolved.");
    final int n = f.count();
    int maxRecursion = unrolls;
    for (Func ff : current_function) if (ff == f) {
        if (maxRecursion < 0) {
            throw new ErrorSyntax(x.span(), "" + f + " cannot call itself recursively!");
        }
        if (maxRecursion == 0) {
            Type t = f.returnDecl.type();
            if (t.is_bool)
                return Formula.FALSE;
            if (t.is_int())
                return IntConstant.constant(0);
            int i = t.arity();
            Expression ans = Expression.NONE;
            while (i > 1) {
                ans = ans.product(Expression.NONE);
                i--;
            }
            return ans;
        }
        maxRecursion--;
    }
    Env<ExprVar, Object> newenv = new Env<ExprVar, Object>();
    for (int i = 0; i < n; i++) newenv.put(f.get(i), cset(x.args.get(i)));
    Env<ExprVar, Object> oldenv = env;
    env = newenv;
    current_function.add(f);
    Object ans = visitThis(body);
    env = oldenv;
    current_function.remove(current_function.size() - 1);
    if (ans instanceof Formula)
        k2pos((Formula) ans, x);
    if (f.count() == 0)
        cacheForConstants.put(f, ans);
    return ans;
}
Also used : ExprVar(edu.mit.csail.sdg.ast.ExprVar) QuantifiedFormula(kodkod.ast.QuantifiedFormula) Formula(kodkod.ast.Formula) ErrorSyntax(edu.mit.csail.sdg.alloy4.ErrorSyntax) Type(edu.mit.csail.sdg.ast.Type) ErrorType(edu.mit.csail.sdg.alloy4.ErrorType) Expr(edu.mit.csail.sdg.ast.Expr) ErrorType(edu.mit.csail.sdg.alloy4.ErrorType) Func(edu.mit.csail.sdg.ast.Func) Expression(kodkod.ast.Expression) BinaryExpression(kodkod.ast.BinaryExpression) IntExpression(kodkod.ast.IntExpression) Env(edu.mit.csail.sdg.alloy4.Env)

Example 75 with Expression

use of kodkod.ast.Expression in project org.alloytools.alloy by AlloyTools.

the class AbstractReplacer method visit.

/**
 * Calls lookup(intExpr) and returns the cached value, if any. If a replacement
 * has not been cached, visits the expression's child. If nothing changes, the
 * argument is cached and returned, otherwise a replacement expression is cached
 * and returned.
 *
 * @return { i: ExprToIntCast | i.expression =
 *         intExpr.expression.accept(delegate) && i.op = intExpr.op}
 */
@Override
public IntExpression visit(ExprToIntCast intExpr) {
    IntExpression ret = lookup(intExpr);
    if (ret != null)
        return ret;
    final Expression expr = intExpr.expression().accept(delegate);
    ret = expr == intExpr.expression() ? intExpr : expr.apply(intExpr.op());
    return cache(intExpr, ret);
}
Also used : ProjectExpression(kodkod.ast.ProjectExpression) BinaryIntExpression(kodkod.ast.BinaryIntExpression) SumExpression(kodkod.ast.SumExpression) IfIntExpression(kodkod.ast.IfIntExpression) BinaryExpression(kodkod.ast.BinaryExpression) ConstantExpression(kodkod.ast.ConstantExpression) UnaryIntExpression(kodkod.ast.UnaryIntExpression) NaryIntExpression(kodkod.ast.NaryIntExpression) IntExpression(kodkod.ast.IntExpression) Expression(kodkod.ast.Expression) UnaryExpression(kodkod.ast.UnaryExpression) NaryExpression(kodkod.ast.NaryExpression) IfExpression(kodkod.ast.IfExpression) BinaryIntExpression(kodkod.ast.BinaryIntExpression) IfIntExpression(kodkod.ast.IfIntExpression) UnaryIntExpression(kodkod.ast.UnaryIntExpression) NaryIntExpression(kodkod.ast.NaryIntExpression) IntExpression(kodkod.ast.IntExpression)

Aggregations

Expression (kodkod.ast.Expression)127 Formula (kodkod.ast.Formula)95 Variable (kodkod.ast.Variable)80 IntExpression (kodkod.ast.IntExpression)49 Relation (kodkod.ast.Relation)26 BinaryExpression (kodkod.ast.BinaryExpression)22 Decls (kodkod.ast.Decls)22 Bounds (kodkod.instance.Bounds)21 TupleSet (kodkod.instance.TupleSet)20 Universe (kodkod.instance.Universe)20 SumExpression (kodkod.ast.SumExpression)19 TupleFactory (kodkod.instance.TupleFactory)19 Solution (kodkod.engine.Solution)17 QuantifiedFormula (kodkod.ast.QuantifiedFormula)14 Solver (kodkod.engine.Solver)14 BinaryIntExpression (kodkod.ast.BinaryIntExpression)13 ConstantExpression (kodkod.ast.ConstantExpression)13 IfExpression (kodkod.ast.IfExpression)13 IfIntExpression (kodkod.ast.IfIntExpression)13 NaryExpression (kodkod.ast.NaryExpression)13