Search in sources :

Example 1 with ExprHasName

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

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

the class CompModule method resolveFieldDecl.

// ============================================================================================================================//
private static void resolveFieldDecl(CompModule res, final A4Reporter rep, final Sig s, final List<ErrorWarning> warns, boolean defined) throws Err {
    // When typechecking each field:
    // * it is allowed to refer to earlier fields in the same SIG or in any
    // visible ancestor sig
    // * it is allowed to refer to visible sigs
    // * it is NOT allowed to refer to any predicate or function
    // For example, if A.als opens B.als, and B/SIGX extends A/SIGY,
    // then B/SIGX's fields cannot refer to A/SIGY, nor any fields in
    // A/SIGY)
    final List<Decl> oldDecls = res.old2fields.get(res.new2old.get(s));
    if (oldDecls == null)
        return;
    final CompModule m = res.sig2module.get(s);
    final Context cx = new Context(m, warns);
    final ExprHasName dup = Decl.findDuplicateName(oldDecls);
    if (dup != null)
        throw new ErrorSyntax(dup.span(), "sig \"" + s + "\" cannot have 2 fields named \"" + dup.label + "\"");
    for (final Decl d : oldDecls) {
        if (d.expr.mult() != ExprUnary.Op.EXACTLYOF) {
            if (defined)
                continue;
        } else {
            if (!defined)
                continue;
        }
        // The name "this" does matter, since the parser and the typechecker
        // both refer to it as "this"
        cx.rootfield = d;
        cx.rootsig = s;
        cx.put("this", s.decl.get());
        Expr bound = cx.check(d.expr).resolve_as_set(warns);
        cx.remove("this");
        String[] names = new String[d.names.size()];
        for (int i = 0; i < names.length; i++) names[i] = d.names.get(i).label;
        Field[] fields = s.addTrickyField(d.span(), d.isPrivate, d.disjoint, d.disjoint2, null, names, bound);
        for (Field f : fields) {
            rep.typecheck("Sig " + s + ", Field " + f.label + ": " + f.type() + "\n");
        }
    }
}
Also used : Field(edu.mit.csail.sdg.ast.Sig.Field) ErrorSyntax(edu.mit.csail.sdg.alloy4.ErrorSyntax) Expr(edu.mit.csail.sdg.ast.Expr) ExprHasName(edu.mit.csail.sdg.ast.ExprHasName) Decl(edu.mit.csail.sdg.ast.Decl)

Example 3 with ExprHasName

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

the class CompModule method resolveFuncBody.

/**
 * Each Func's body will now be typechecked Expr object.
 */
private JoinableList<Err> resolveFuncBody(A4Reporter rep, JoinableList<Err> errors, List<ErrorWarning> warns) throws Err {
    for (ArrayList<Func> entry : funcs.values()) for (Func ff : entry) {
        Context cx = new Context(this, warns);
        cx.rootfunbody = ff;
        for (Decl d : ff.decls) for (ExprHasName n : d.names) cx.put(n.label, n);
        Expr newBody = cx.check(ff.getBody());
        if (ff.isPred)
            newBody = newBody.resolve_as_formula(warns);
        else
            newBody = newBody.resolve_as_set(warns);
        errors = errors.make(newBody.errors);
        if (!newBody.errors.isEmpty())
            continue;
        try {
            ff.setBody(newBody);
        } catch (Err er) {
            errors = errors.make(er);
            continue;
        }
        if (warns != null && ff.returnDecl.type().hasTuple() && newBody.type().hasTuple() && !newBody.type().intersects(ff.returnDecl.type()))
            warns.add(new ErrorWarning(newBody.span(), "Function return value is disjoint from its return type.\n" + "Function body has type " + newBody.type() + "\n" + "but the return type is " + ff.returnDecl.type()));
        // else if (warns!=null && Version.experimental &&
        // !newBody.type.isSubtypeOf(ff.returnDecl.type))
        // warns.add(new ErrorWarning(newBody.span(),
        // "Function may return a tuple not in its declared return
        // type.\n"
        // +"The Alloy Analyzer's analysis may be unsound\n"
        // +"if it returns a tuple outside its declared return type.\n"
        // +"Function body has type "+newBody.type+"\nbut the return
        // type is "+ff.returnDecl.type));
        rep.typecheck(ff.toString() + ", BODY:" + newBody.type() + "\n");
    }
    return errors;
}
Also used : Expr(edu.mit.csail.sdg.ast.Expr) Err(edu.mit.csail.sdg.alloy4.Err) Func(edu.mit.csail.sdg.ast.Func) ExprHasName(edu.mit.csail.sdg.ast.ExprHasName) ErrorWarning(edu.mit.csail.sdg.alloy4.ErrorWarning) Decl(edu.mit.csail.sdg.ast.Decl)

Example 4 with ExprHasName

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

the class TranslateAlloyToKodkod method makeFacts.

/**
 * Conjoin the constraints for "field declarations" and "fact" paragraphs
 */
private void makeFacts(Expr facts) throws Err {
    rep.debug("Generating facts...\n");
    // convert into a form that hopefully gives better unsat core
    facts = (new ConvToConjunction()).visitThis(facts);
    // add the field facts and appended facts
    for (Sig s : frame.getAllReachableSigs()) {
        for (Decl d : s.getFieldDecls()) {
            k2pos_enabled = false;
            for (ExprHasName n : d.names) {
                Field f = (Field) n;
                Expr form = s.decl.get().join(f).in(d.expr);
                form = s.isOne == null ? form.forAll(s.decl) : ExprLet.make(null, (ExprVar) (s.decl.get()), s, form);
                frame.addFormula(cform(form), f);
                // subset of s.
                if (s.isOne == null) {
                    Expression sr = a2k(s), fr = a2k(f);
                    for (int i = f.type().arity(); i > 1; i--) fr = fr.join(Expression.UNIV);
                    frame.addFormula(fr.in(sr), f);
                }
            }
            if (s.isOne == null && 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());
                    frame.addFormula(cform(formula.forAll(that).forAll(s.decl)), d.disjoint2);
                }
            if (d.names.size() > 1 && d.disjoint != null) {
                frame.addFormula(cform(ExprList.makeDISJOINT(d.disjoint, null, d.names)), d.disjoint);
            }
        }
        k2pos_enabled = true;
        for (Expr f : s.getFacts()) {
            Expr form = s.isOne == null ? f.forAll(s.decl) : ExprLet.make(null, (ExprVar) (s.decl.get()), s, f);
            frame.addFormula(cform(form), f);
        }
    }
    k2pos_enabled = true;
    recursiveAddFormula(facts);
}
Also used : Sig(edu.mit.csail.sdg.ast.Sig) ExprVar(edu.mit.csail.sdg.ast.ExprVar) Field(edu.mit.csail.sdg.ast.Sig.Field) 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) Decl(edu.mit.csail.sdg.ast.Decl)

Example 5 with ExprHasName

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

the class SimpleCLI method main.

public static void main(String[] args) throws Exception {
    final boolean sat4j = "yes".equals(System.getProperty("sat4j"));
    final boolean minisat = "yes".equals(System.getProperty("minisat"));
    SatSolver solver = A4Options.SatSolver.make("mem", "mem", "/zweb/sat/mem");
    final SimpleReporter rep = new SimpleReporter();
    final StringBuilder sb = rep.sb;
    for (String filename : args) {
        try {
            // Parse+Typecheck
            rep.sb.append("\n\nMain file = " + filename + "\n");
            if (db)
                db("Parsing+Typechecking...");
            Module world = CompUtil.parseEverything_fromFile(rep, null, filename);
            if (db)
                db(" ok\n");
            List<Command> cmds = world.getAllCommands();
            for (ErrorWarning msg : rep.warnings) rep.sb.append("Relevance Warning:\n" + (msg.toString().trim()) + "\n\n");
            rep.warnings.clear();
            // Do a detailed dump if we will not be executing the commands
            if (args.length != 1) {
                for (Module m : world.getAllReachableModules()) {
                    for (Sig x : m.getAllSigs()) {
                        sb.append("\nSig ").append(x.label).append(" at position ").append(x.pos).append("\n");
                        for (Decl d : x.getFieldDecls()) for (ExprHasName f : d.names) {
                            sb.append("\nField ").append(f.label).append(" with type ").append(f.type()).append("\n");
                            d.expr.toString(sb, 2);
                        }
                        rep.flush();
                    }
                    for (Func x : m.getAllFunc()) {
                        sb.append("\nFun/pred ").append(x.label).append(" at position ").append(x.pos).append("\n");
                        for (Decl d : x.decls) for (ExprHasName v : d.names) {
                            v.toString(sb, 2);
                            d.expr.toString(sb, 4);
                        }
                        x.returnDecl.toString(sb, 2);
                        x.getBody().toString(sb, 4);
                        rep.flush();
                    }
                    for (Pair<String, Expr> x : m.getAllFacts()) {
                        sb.append("\nFact ").append(x.a).append("\n");
                        x.b.toString(sb, 4);
                        rep.flush();
                    }
                    for (Pair<String, Expr> x : m.getAllAssertions()) {
                        sb.append("\nAssertion ").append(x.a).append("\n");
                        x.b.toString(sb, 4);
                        rep.flush();
                    }
                    if (m == world)
                        for (Command x : m.getAllCommands()) {
                            sb.append("\nCommand ").append(x.label).append("\n");
                            x.formula.toString(sb, 4);
                            rep.flush();
                        }
                }
                continue;
            }
            // Validate the metamodel generation code
            StringWriter metasb = new StringWriter();
            PrintWriter meta = new PrintWriter(metasb);
            Util.encodeXMLs(meta, "\n<alloy builddate=\"", Version.buildDate(), "\">\n\n");
            A4SolutionWriter.writeMetamodel(world.getAllReachableSigs(), filename, meta);
            Util.encodeXMLs(meta, "\n</alloy>");
            meta.flush();
            metasb.flush();
            String metaxml = metasb.toString();
            A4SolutionReader.read(new ArrayList<Sig>(), new XMLNode(new StringReader(metaxml)));
            StaticInstanceReader.parseInstance(new StringReader(metaxml));
            // Okay, now solve the commands
            A4Options options = new A4Options();
            options.originalFilename = filename;
            options.solverDirectory = "/zweb/zweb/tmp/alloy4/x86-freebsd";
            options.solver = sat4j ? A4Options.SatSolver.SAT4J : (minisat ? A4Options.SatSolver.MiniSatJNI : solver);
            for (int i = 0; i < cmds.size(); i++) {
                Command c = cmds.get(i);
                if (db) {
                    String cc = c.toString();
                    if (cc.length() > 60)
                        cc = cc.substring(0, 55);
                    db("Executing " + cc + "...\n");
                }
                rep.sb.append("Executing \"" + c + "\"\n");
                options.skolemDepth = 0;
                A4Solution s = TranslateAlloyToKodkod.execute_commandFromBook(rep, world.getAllReachableSigs(), c, options);
                if (s.satisfiable()) {
                    validate(s);
                    if (s.isIncremental()) {
                        s = s.next();
                        if (s.satisfiable())
                            validate(s);
                    }
                }
                options.skolemDepth = 2;
                s = TranslateAlloyToKodkod.execute_commandFromBook(rep, world.getAllReachableSigs(), c, options);
                if (s.satisfiable()) {
                    validate(s);
                    if (s.isIncremental()) {
                        s = s.next();
                        if (s.satisfiable())
                            validate(s);
                    }
                }
            }
        } catch (Throwable ex) {
            rep.sb.append("\n\nException: " + ex);
        }
        if (db) {
            if (args.length != 1)
                db(" ERROR!\n");
            else
                db("\n\n");
        }
    }
    rep.close();
}
Also used : XMLNode(edu.mit.csail.sdg.alloy4.XMLNode) Func(edu.mit.csail.sdg.ast.Func) ErrorWarning(edu.mit.csail.sdg.alloy4.ErrorWarning) Decl(edu.mit.csail.sdg.ast.Decl) Sig(edu.mit.csail.sdg.ast.Sig) Expr(edu.mit.csail.sdg.ast.Expr) StringWriter(java.io.StringWriter) Command(edu.mit.csail.sdg.ast.Command) ExprHasName(edu.mit.csail.sdg.ast.ExprHasName) A4Options(edu.mit.csail.sdg.translator.A4Options) StringReader(java.io.StringReader) Module(edu.mit.csail.sdg.ast.Module) SatSolver(edu.mit.csail.sdg.translator.A4Options.SatSolver) PrintWriter(java.io.PrintWriter) A4Solution(edu.mit.csail.sdg.translator.A4Solution)

Aggregations

ExprHasName (edu.mit.csail.sdg.ast.ExprHasName)10 Decl (edu.mit.csail.sdg.ast.Decl)9 Expr (edu.mit.csail.sdg.ast.Expr)7 Func (edu.mit.csail.sdg.ast.Func)4 Sig (edu.mit.csail.sdg.ast.Sig)4 Err (edu.mit.csail.sdg.alloy4.Err)3 ExprVar (edu.mit.csail.sdg.ast.ExprVar)3 Field (edu.mit.csail.sdg.ast.Sig.Field)3 ErrorSyntax (edu.mit.csail.sdg.alloy4.ErrorSyntax)2 ErrorWarning (edu.mit.csail.sdg.alloy4.ErrorWarning)2 Pair (edu.mit.csail.sdg.alloy4.Pair)2 Module (edu.mit.csail.sdg.ast.Module)2 A4Solution (edu.mit.csail.sdg.translator.A4Solution)2 ArrayList (java.util.ArrayList)2 BinaryExpression (kodkod.ast.BinaryExpression)2 Expression (kodkod.ast.Expression)2 IntExpression (kodkod.ast.IntExpression)2 TempList (edu.mit.csail.sdg.alloy4.ConstList.TempList)1 XMLNode (edu.mit.csail.sdg.alloy4.XMLNode)1 Command (edu.mit.csail.sdg.ast.Command)1