Search in sources :

Example 1 with Expr

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

the class CompModule method parseOneExpressionFromString.

/**
 * Parse one expression by starting fromt this module as the root module.
 */
@Override
public Expr parseOneExpressionFromString(String input) throws Err, FileNotFoundException, IOException {
    Map<String, String> fc = new LinkedHashMap<String, String>();
    // We prepend the line "run{"
    fc.put("", "run {\n" + input + "}");
    CompModule m = CompUtil.parse(new ArrayList<Object>(), null, fc, null, -1, "", "", 1);
    if (m.funcs.size() == 0)
        throw new ErrorSyntax("The input does not correspond to an Alloy expression.");
    Expr body = m.funcs.values().iterator().next().get(0).getBody();
    Context cx = new Context(this, null);
    body = cx.check(body);
    body = body.resolve(body.type(), null);
    if (body.errors.size() > 0)
        throw body.errors.pick();
    else
        return body;
}
Also used : ErrorSyntax(edu.mit.csail.sdg.alloy4.ErrorSyntax) Expr(edu.mit.csail.sdg.ast.Expr) LinkedHashMap(java.util.LinkedHashMap)

Example 2 with Expr

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

the class CompModule method resolveCommand.

/**
 * Resolve a particular command.
 */
private Command resolveCommand(Command cmd, ConstList<Sig> exactSigs, Expr globalFacts) throws Err {
    Command parent = cmd.parent == null ? null : resolveCommand(cmd.parent, exactSigs, globalFacts);
    String cname = ((ExprVar) (cmd.formula)).label;
    Expr e;
    Clause declaringClause = null;
    if (cmd.check) {
        // We prefer assertion in the
        List<Object> m = getRawQS(2, cname);
        // topmost module
        if (m.size() == 0 && cname.indexOf('/') < 0)
            m = getRawNQS(this, 2, cname);
        if (m.size() > 1)
            unique(cmd.pos, cname, m);
        if (m.size() < 1)
            throw new ErrorSyntax(cmd.pos, "The assertion \"" + cname + "\" cannot be found.");
        Expr expr = (Expr) (m.get(0));
        e = expr.not();
    } else {
        // We prefer fun/pred in the
        List<Object> m = getRawQS(4, cname);
        // topmost module
        if (m.size() == 0 && cname.indexOf('/') < 0)
            m = getRawNQS(this, 4, cname);
        if (m.size() > 1)
            unique(cmd.pos, cname, m);
        if (m.size() < 1)
            throw new ErrorSyntax(cmd.pos, "The predicate/function \"" + cname + "\" cannot be found.");
        Func f = (Func) (m.get(0));
        declaringClause = f;
        e = f.getBody();
        if (!f.isPred)
            e = e.in(f.returnDecl);
        if (f.decls.size() > 0)
            e = ExprQt.Op.SOME.make(null, null, f.decls, e);
    }
    if (e == null)
        e = ExprConstant.TRUE;
    TempList<CommandScope> sc = new TempList<CommandScope>(cmd.scope.size());
    for (CommandScope et : cmd.scope) {
        Sig s = getRawSIG(et.sig.pos, et.sig.label);
        if (s == null)
            throw new ErrorSyntax(et.sig.pos, "The sig \"" + et.sig.label + "\" cannot be found.");
        sc.add(new CommandScope(null, s, et.isExact, et.startingScope, et.endingScope, et.increment));
    }
    if (cmd.nameExpr != null) {
        cmd.nameExpr.setReferenced(declaringClause);
    }
    return new Command(cmd.pos, cmd.nameExpr, cmd.label, cmd.check, cmd.overall, cmd.bitwidth, cmd.maxseq, cmd.expects, sc.makeConst(), exactSigs, globalFacts.and(e), parent);
}
Also used : ExprVar(edu.mit.csail.sdg.ast.ExprVar) Func(edu.mit.csail.sdg.ast.Func) PrimSig(edu.mit.csail.sdg.ast.Sig.PrimSig) Sig(edu.mit.csail.sdg.ast.Sig) SubsetSig(edu.mit.csail.sdg.ast.Sig.SubsetSig) ErrorSyntax(edu.mit.csail.sdg.alloy4.ErrorSyntax) Expr(edu.mit.csail.sdg.ast.Expr) TempList(edu.mit.csail.sdg.alloy4.ConstList.TempList) Command(edu.mit.csail.sdg.ast.Command) Clause(edu.mit.csail.sdg.ast.Clause) CommandScope(edu.mit.csail.sdg.ast.CommandScope)

Example 3 with Expr

use of edu.mit.csail.sdg.ast.Expr 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 4 with Expr

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

the class SimInstance method enumerate.

/**
 * Helper method for enumerating all possibilties for a
 * quantification-expression.
 */
private int enumerate(final TempList<SimTuple> store, int sum, final ExprQt x, final Expr body, final int i) throws Err {
    // if op is ALL NO SOME ONE LONE then it always returns
    // 0 1 2
    final int n = x.count();
    final ExprVar v = x.get(i);
    final Expr bound = x.getBound(i);
    final SimTupleset e = cset(bound);
    final Iterator<SimTupleset> it;
    switch(bound.mult()) {
        case LONEOF:
            it = e.loneOf();
            break;
        case ONEOF:
            it = e.oneOf();
            break;
        case SOMEOF:
            it = e.someOf();
            break;
        default:
            it = e.setOf();
    }
    while (it.hasNext()) {
        final SimTupleset binding = it.next();
        if (bound.mult == 2 && !isIn(binding, bound))
            continue;
        env.put(v, binding);
        if (i < n - 1)
            sum = enumerate(store, sum, x, body, i + 1);
        else if (x.op == ExprQt.Op.SUM)
            sum += cint(body);
        else if (x.op != ExprQt.Op.COMPREHENSION)
            sum += cform(body) ? 1 : 0;
        else if (cform(body)) {
            SimTuple a = null, b;
            for (int j = 0; j < n; j++) {
                b = ((SimTupleset) (env.get(x.get(j)))).getTuple();
                if (a == null)
                    a = b;
                else
                    a = a.product(b);
            }
            store.add(a);
        }
        env.remove(v);
        if (sum >= 2 && x.op != ExprQt.Op.COMPREHENSION && x.op != ExprQt.Op.SUM)
            // no need to enumerate further
            return 2;
    }
    return sum;
}
Also used : ExprVar(edu.mit.csail.sdg.ast.ExprVar) Expr(edu.mit.csail.sdg.ast.Expr)

Example 5 with Expr

use of edu.mit.csail.sdg.ast.Expr 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)

Aggregations

Expr (edu.mit.csail.sdg.ast.Expr)46 PrimSig (edu.mit.csail.sdg.ast.Sig.PrimSig)17 Sig (edu.mit.csail.sdg.ast.Sig)15 Func (edu.mit.csail.sdg.ast.Func)12 ExprVar (edu.mit.csail.sdg.ast.ExprVar)11 SubsetSig (edu.mit.csail.sdg.ast.Sig.SubsetSig)11 ErrorSyntax (edu.mit.csail.sdg.alloy4.ErrorSyntax)9 Decl (edu.mit.csail.sdg.ast.Decl)8 Field (edu.mit.csail.sdg.ast.Sig.Field)8 ExprHasName (edu.mit.csail.sdg.ast.ExprHasName)7 ArrayList (java.util.ArrayList)7 LinkedHashMap (java.util.LinkedHashMap)7 ErrorFatal (edu.mit.csail.sdg.alloy4.ErrorFatal)6 Pos (edu.mit.csail.sdg.alloy4.Pos)6 XMLNode (edu.mit.csail.sdg.alloy4.XMLNode)6 Command (edu.mit.csail.sdg.ast.Command)5 IOException (java.io.IOException)5 HashMap (java.util.HashMap)5 Map (java.util.Map)5 BinaryExpression (kodkod.ast.BinaryExpression)5