Search in sources :

Example 16 with Expression

use of kodkod.ast.Expression 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;
}
Also used : QuantifiedFormula(kodkod.ast.QuantifiedFormula) Formula(kodkod.ast.Formula) Variable(kodkod.ast.Variable) Decls(kodkod.ast.Decls) Expression(kodkod.ast.Expression) BinaryExpression(kodkod.ast.BinaryExpression) IntExpression(kodkod.ast.IntExpression)

Example 17 with Expression

use of kodkod.ast.Expression 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));
}
Also used : QuantifiedFormula(kodkod.ast.QuantifiedFormula) Formula(kodkod.ast.Formula) Expression(kodkod.ast.Expression) BinaryExpression(kodkod.ast.BinaryExpression) IntExpression(kodkod.ast.IntExpression)

Example 18 with Expression

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

the class Skolemizer method visit.

/**
 * Skolemizes the given formula, if possible, otherwise returns the result of
 * replacing its free variables according to the current replacement
 * environment.
 *
 * @see kodkod.ast.visitor.AbstractReplacer#visit(kodkod.ast.QuantifiedFormula)
 */
@Override
public final Formula visit(QuantifiedFormula qf) {
    Formula ret = lookup(qf);
    if (ret != null)
        return ret;
    final Environment<Expression, Expression> oldRepEnv = repEnv;
    final Quantifier quant = qf.quantifier();
    final Decls decls = qf.decls();
    if (skolemDepth >= 0 && (negated && quant == ALL || !negated && quant == SOME)) {
        // skolemizable
        // formula
        final List<Formula> rangeConstraints = new LinkedList<Formula>();
        final List<Formula> domConstraints = new LinkedList<Formula>();
        for (Decl decl : decls) {
            final Decl skolemDecl = visit(decl);
            Variable skVar = skolemDecl.variable();
            final Relation skolem = Relation.skolem("$" + skVar.name(), nonSkolems.size() + skVar.arity(), skVar, skolemDecl, quant);
            reporter.skolemizing(decl, skolem, nonSkolemsView);
            final Expression skolemExpr = skolemExpr(skolemDecl, skolem);
            final Multiplicity mult = decl.multiplicity();
            rangeConstraints.add(source(skolemExpr.in(skolemDecl.expression()), decl));
            if (mult != Multiplicity.SET) {
                rangeConstraints.add(source(skolemExpr.apply(mult), decl));
            }
            if (!nonSkolems.isEmpty())
                domConstraints.add(source(domainConstraint(skolemDecl, skolem), decl));
            repEnv = repEnv.extend(decl.variable(), decl.expression(), skolemExpr);
        }
        ret = source(Formula.and(rangeConstraints), decls).compose(negated ? IMPLIES : AND, qf.formula().accept(this));
        if (!domConstraints.isEmpty())
            topSkolemConstraints.add(source(Formula.and(domConstraints), decls));
    } else {
        // non-skolemizable formula
        final Decls newDecls = visit(qf.decls());
        if (skolemDepth >= nonSkolems.size() + newDecls.size()) {
            // below
            for (Decl d : newDecls) {
                nonSkolems.add(new DeclInfo(d));
            }
            final Formula domain = qf.domain().accept(this);
            final Formula body = qf.body().accept(this);
            ret = ((newDecls == decls && domain == qf.domain() && body == qf.body()) ? qf : body.quantify(quant, newDecls, domain));
            for (int i = newDecls.size(); i > 0; i--) {
                nonSkolems.remove(nonSkolems.size() - 1);
            }
        } else {
            // can't skolemize below
            final int oldDepth = skolemDepth;
            skolemDepth = -1;
            final Formula domain = qf.domain().accept(this);
            final Formula body = qf.body().accept(this);
            ret = ((newDecls == decls && domain == qf.domain() && body == qf.body()) ? qf : body.quantify(quant, newDecls, domain));
            skolemDepth = oldDepth;
        }
    }
    repEnv = oldRepEnv;
    if (repEnv.isEmpty() && !topSkolemConstraints.isEmpty()) {
        ret = source(Formula.and(topSkolemConstraints), qf).compose(negated ? IMPLIES : AND, ret);
    }
    return source(cache(qf, ret), qf);
}
Also used : Variable(kodkod.ast.Variable) Decls(kodkod.ast.Decls) Decl(kodkod.ast.Decl) LinkedList(java.util.LinkedList) BinaryFormula(kodkod.ast.BinaryFormula) MultiplicityFormula(kodkod.ast.MultiplicityFormula) QuantifiedFormula(kodkod.ast.QuantifiedFormula) NotFormula(kodkod.ast.NotFormula) ComparisonFormula(kodkod.ast.ComparisonFormula) NaryFormula(kodkod.ast.NaryFormula) Formula(kodkod.ast.Formula) IntComparisonFormula(kodkod.ast.IntComparisonFormula) Relation(kodkod.ast.Relation) SumExpression(kodkod.ast.SumExpression) IntExpression(kodkod.ast.IntExpression) Expression(kodkod.ast.Expression) Multiplicity(kodkod.ast.operator.Multiplicity) Quantifier(kodkod.ast.operator.Quantifier)

Example 19 with Expression

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

the class Skolemizer method visit.

/*-------declarations---------*/
/**
 * Visits the given decl's expression. Note that we must not visit variables in
 * case they are re-used. For example, consider the formula some x: X | all x: Y
 * | F(x). Since x bound by the existential quantifier is going to be
 * skolemized, if we visited the variable in the enclosed declaration, we would
 * get the skolem constant as a return value and a ClassCastException would be
 * thrown.
 *
 * @return { d: Declaration | d.variable = decl.variable && d.multiplicity =
 *         decl.multiplicity && d.expression = decl.expression.accept(this) }
 */
@Override
public final Decl visit(Decl decl) {
    Decl ret = lookup(decl);
    if (ret != null)
        return ret;
    final int oldDepth = skolemDepth;
    // can't skolemize inside a decl
    skolemDepth = -1;
    final Expression expression = decl.expression().accept(this);
    skolemDepth = oldDepth;
    ret = (expression == decl.expression()) ? decl : decl.variable().declare(decl.multiplicity(), expression);
    return cache(decl, ret);
}
Also used : SumExpression(kodkod.ast.SumExpression) IntExpression(kodkod.ast.IntExpression) Expression(kodkod.ast.Expression) Decl(kodkod.ast.Decl)

Example 20 with Expression

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

the class Skolemizer method skolemExpr.

/**
 * Adds a bound for the given skolem relation to this.bounds, and returns the
 * expression that should replace skolemDecl.variable in the final formula.
 *
 * @requires skolem !in this.bounds.relations
 * @requires skolem.arity = nonSkolems.size() + skolemDecl.variable().arity()
 * @ensures adds a sound upper bound for the given skolem relation to
 *          this.bounds
 * @return the expression that should replace skolemDecl.variable in the final
 *         formula
 */
private Expression skolemExpr(Decl skolemDecl, Relation skolem) {
    final int depth = nonSkolems.size();
    final int arity = depth + skolemDecl.variable().arity();
    Expression skolemExpr = skolem;
    Environment<BooleanMatrix, Expression> skolemEnv = Environment.empty();
    for (DeclInfo info : nonSkolems) {
        if (info.upperBound == null) {
            info.upperBound = upperBound(info.decl.expression(), skolemEnv);
        }
        skolemEnv = skolemEnv.extend(info.decl.variable(), info.decl.expression(), info.upperBound);
        skolemExpr = info.decl.variable().join(skolemExpr);
    }
    BooleanMatrix matrixBound = upperBound(skolemDecl.expression(), skolemEnv);
    for (int i = depth - 1; i >= 0; i--) {
        matrixBound = nonSkolems.get(i).upperBound.cross(matrixBound);
    }
    final TupleSet skolemBound = bounds.universe().factory().setOf(arity, matrixBound.denseIndices());
    bounds.bound(skolem, skolemBound);
    return skolemExpr;
}
Also used : TupleSet(kodkod.instance.TupleSet) SumExpression(kodkod.ast.SumExpression) IntExpression(kodkod.ast.IntExpression) Expression(kodkod.ast.Expression) BooleanMatrix(kodkod.engine.bool.BooleanMatrix)

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