Search in sources :

Example 1 with ExprBinary

use of edu.mit.csail.sdg.ast.ExprBinary in project org.alloytools.alloy by AlloyTools.

the class SimInstance method isIn.

/**
 * Helper method that evaluates the formula "a in b" where b.mult==0
 */
public boolean isIn(SimTuple a, Expr b) throws Err {
    b = b.deNOP();
    if (b instanceof PrimSig && ((PrimSig) b).builtin) {
        if (a.arity() != 1)
            return false;
        if (b.isSame(Sig.UNIV))
            return true;
        if (b.isSame(Sig.NONE))
            return false;
        if (b.isSame(Sig.SEQIDX)) {
            Integer i = a.get(0).toInt(null);
            return i != null && i >= 0 && i < maxseq;
        }
        if (b.isSame(Sig.SIGINT)) {
            Integer i = a.get(0).toInt(null);
            return i != null;
        }
        if (b.isSame(Sig.STRING)) {
            String at = a.get(0).toString();
            return at.length() > 0 && (at.charAt(0) == '\"');
        }
    }
    if (b instanceof ExprBinary && ((ExprBinary) b).op == ExprBinary.Op.ARROW) {
        Expr left = ((ExprBinary) b).left, right = ((ExprBinary) b).right;
        int ll = left.type().arity(), rr = right.type().arity();
        if (ll <= rr)
            return isIn(a.head(ll), left) && isIn(a.tail(rr), right);
        return isIn(a.tail(rr), right) && isIn(a.head(ll), left);
    }
    if (b instanceof ExprBinary && ((ExprBinary) b).op == ExprBinary.Op.PLUS) {
        return isIn(a, ((ExprBinary) b).left) || isIn(a, ((ExprBinary) b).right);
    }
    if (b instanceof ExprBinary && ((ExprBinary) b).op == ExprBinary.Op.MINUS) {
        return isIn(a, ((ExprBinary) b).left) && !isIn(a, ((ExprBinary) b).right);
    }
    return cset(b).has(a);
}
Also used : ExprBinary(edu.mit.csail.sdg.ast.ExprBinary) Expr(edu.mit.csail.sdg.ast.Expr) PrimSig(edu.mit.csail.sdg.ast.Sig.PrimSig)

Example 2 with ExprBinary

use of edu.mit.csail.sdg.ast.ExprBinary in project org.alloytools.alloy by AlloyTools.

the class SimInstance method validate.

/**
 * Checks whether this instance satisfies every fact defined in the given model.
 *
 * @param world - this must be the root of the Alloy model
 * @return an empty String if yes, nonempty String if no
 */
public String validate(Module world) {
    try {
        for (Sig s : world.getAllReachableSigs()) if (!s.builtin) {
            if (s.isLone != null && !(visit(s).longsize() <= 1))
                return "There can be at most one " + s;
            if (s.isOne != null && !(visit(s).longsize() == 1))
                return "There must be exactly one " + s;
            if (s.isSome != null && !(visit(s).longsize() >= 1))
                return "There must be at least one " + s;
            if (s instanceof SubsetSig) {
                SubsetSig p = (SubsetSig) s;
                Expr sum = null;
                for (Sig par : p.parents) sum = par.plus(sum);
                if (p.exact) {
                    if (!equal(s, sum))
                        return "Sig " + s + " must be equal to the union of its parents " + p.parents;
                } else {
                    if (!isIn(s, sum))
                        return "Sig " + s + " must be equal or subset of its parents " + p.parents;
                }
            } else if (s != Sig.UNIV && s != Sig.NONE) {
                PrimSig p = (PrimSig) s;
                if (!isIn(s, p.parent))
                    return "Sig " + s + " must be equal or subset of its parent " + p.parent;
            }
            if (s.isAbstract != null) {
                Expr sum = null;
                for (Sig x : ((PrimSig) s).children()) sum = x.plus(sum);
                if (sum != null && !equal(s, sum))
                    return "Abstract sig " + s + " must be equal to the union of its subsigs";
            }
            for (Decl d : s.getFieldDecls()) for (ExprHasName f : d.names) if (!((Field) f).defined) {
                if (!cform(s.decl.get().join(f).in(d.expr).forAll(s.decl))) {
                    return "Field " + f + " violated its bound: " + visit((Field) f) + "\n" + d.expr;
                }
                SimTupleset setS = visit(s);
                SimTupleset setF = visit((Field) f);
                for (SimAtom x : setF.getAllAtoms(0)) if (!setS.has(x))
                    return "Field " + f + " first column has extra atom: " + setF + " not in " + setS;
            }
            for (Decl d : s.getFieldDecls()) {
                if (d.disjoint != null && d.names.size() > 0) {
                    if (!cform(ExprList.makeDISJOINT(null, null, d.names)))
                        return "Fields must be disjoint.";
                }
                if (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());
                        if (!cform(formula.forAll(that).forAll(s.decl)))
                            return "Fields must be disjoint.";
                    }
            }
            for (Expr f : s.getFacts()) {
                if (!cform(f.forAll(s.decl))) {
                    f = f.deNOP();
                    if (f instanceof ExprUnary) {
                        ExprUnary u = (ExprUnary) f;
                        f = u.sub.deNOP();
                        if (f instanceof ExprBinary) {
                            ExprBinary b = (ExprBinary) f;
                            if (b.op == ExprBinary.Op.JOIN && b.left.isSame(s.decl.get()) && b.right.deNOP() instanceof Field) {
                                String n = ((Field) (b.right.deNOP())).label;
                                if (u.op == ExprUnary.Op.SOME)
                                    return "The " + n + " cannot be empty.";
                                if (u.op == ExprUnary.Op.LONE)
                                    return "The " + n + " cannot have more than one value.";
                                if (u.op == ExprUnary.Op.ONE)
                                    return "The " + n + " must have exactly one value.";
                                if (u.op == ExprUnary.Op.NO)
                                    return "The " + n + " must be empty.";
                            }
                        }
                    }
                    return "Cannot violate a consistency constraint";
                }
            }
        }
        for (Module m : world.getAllReachableModules()) for (Pair<String, Expr> f : m.getAllFacts()) if (!cform(f.b)) {
            String err = f.a;
            if (err.matches("^fact\\$[0-9][0-9]*"))
                err = f.b.toString();
            if (err.length() >= 2 && err.startsWith("\"") && err.endsWith("\""))
                err = err.substring(1, err.length() - 1);
            return "Violation: " + err;
        }
        return "";
    } catch (Err ex) {
        return "An internal error has occured:\n" + ex.dump();
    }
}
Also used : Err(edu.mit.csail.sdg.alloy4.Err) Decl(edu.mit.csail.sdg.ast.Decl) PrimSig(edu.mit.csail.sdg.ast.Sig.PrimSig) SubsetSig(edu.mit.csail.sdg.ast.Sig.SubsetSig) Sig(edu.mit.csail.sdg.ast.Sig) SubsetSig(edu.mit.csail.sdg.ast.Sig.SubsetSig) Field(edu.mit.csail.sdg.ast.Sig.Field) ExprBinary(edu.mit.csail.sdg.ast.ExprBinary) Expr(edu.mit.csail.sdg.ast.Expr) ExprHasName(edu.mit.csail.sdg.ast.ExprHasName) ExprUnary(edu.mit.csail.sdg.ast.ExprUnary) Module(edu.mit.csail.sdg.ast.Module) PrimSig(edu.mit.csail.sdg.ast.Sig.PrimSig) Pair(edu.mit.csail.sdg.alloy4.Pair)

Example 3 with ExprBinary

use of edu.mit.csail.sdg.ast.ExprBinary 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;
}
Also used : PrimSig(edu.mit.csail.sdg.ast.Sig.PrimSig) SubsetSig(edu.mit.csail.sdg.ast.Sig.SubsetSig) Sig(edu.mit.csail.sdg.ast.Sig) Field(edu.mit.csail.sdg.ast.Sig.Field) ExprBinary(edu.mit.csail.sdg.ast.ExprBinary) Expression(kodkod.ast.Expression) ExprUnary(edu.mit.csail.sdg.ast.ExprUnary) ExprConstant(edu.mit.csail.sdg.ast.ExprConstant)

Example 4 with ExprBinary

use of edu.mit.csail.sdg.ast.ExprBinary in project org.alloytools.alloy by AlloyTools.

the class ConvToConjunction method visit.

/**
 * {@inheritDoc}
 */
@Override
public Expr visit(ExprUnary x) throws Err {
    if (x.op == ExprUnary.Op.NOOP) {
        return visitThis(x.sub);
    }
    if (x.op == ExprUnary.Op.NOT) {
        Expr s = x.sub.deNOP();
        if (s instanceof ExprBinary && ((ExprBinary) s).op == ExprBinary.Op.OR) {
            Expr a = visitThis(((ExprBinary) s).left.not());
            Expr b = visitThis(((ExprBinary) s).right.not());
            return a.and(b);
        }
    }
    return x;
}
Also used : ExprBinary(edu.mit.csail.sdg.ast.ExprBinary) Expr(edu.mit.csail.sdg.ast.Expr)

Example 5 with ExprBinary

use of edu.mit.csail.sdg.ast.ExprBinary in project org.alloytools.alloy by AlloyTools.

the class ConvToConjunction method visit.

/**
 * {@inheritDoc}
 */
@Override
public Expr visit(ExprQt x) throws Err {
    if (x.op == ExprQt.Op.ALL) {
        Expr s = x.sub.deNOP();
        if (s instanceof ExprBinary && ((ExprBinary) s).op == ExprBinary.Op.AND) {
            Expr a = visitThis(x.op.make(Pos.UNKNOWN, Pos.UNKNOWN, x.decls, ((ExprBinary) s).left));
            Expr b = visitThis(x.op.make(Pos.UNKNOWN, Pos.UNKNOWN, x.decls, ((ExprBinary) s).right));
            return a.and(b);
        }
    }
    return x;
}
Also used : ExprBinary(edu.mit.csail.sdg.ast.ExprBinary) Expr(edu.mit.csail.sdg.ast.Expr)

Aggregations

ExprBinary (edu.mit.csail.sdg.ast.ExprBinary)5 Expr (edu.mit.csail.sdg.ast.Expr)4 PrimSig (edu.mit.csail.sdg.ast.Sig.PrimSig)3 ExprUnary (edu.mit.csail.sdg.ast.ExprUnary)2 Sig (edu.mit.csail.sdg.ast.Sig)2 Field (edu.mit.csail.sdg.ast.Sig.Field)2 SubsetSig (edu.mit.csail.sdg.ast.Sig.SubsetSig)2 Err (edu.mit.csail.sdg.alloy4.Err)1 Pair (edu.mit.csail.sdg.alloy4.Pair)1 Decl (edu.mit.csail.sdg.ast.Decl)1 ExprConstant (edu.mit.csail.sdg.ast.ExprConstant)1 ExprHasName (edu.mit.csail.sdg.ast.ExprHasName)1 Module (edu.mit.csail.sdg.ast.Module)1 Expression (kodkod.ast.Expression)1