Search in sources :

Example 1 with JoinableList

use of edu.mit.csail.sdg.alloy4.JoinableList in project org.alloytools.alloy by AlloyTools.

the class CompModule method resolveAll.

// ============================================================================================================================//
/**
 * This method resolves the entire world; NOTE: if it throws an exception, it
 * may leave the world in an inconsistent state!
 */
static CompModule resolveAll(final A4Reporter rep, final CompModule root) throws Err {
    final List<ErrorWarning> warns = new ArrayList<ErrorWarning>();
    for (CompModule m : root.getAllReachableModules()) root.allModules.add(m);
    resolveParams(rep, root.allModules);
    resolveModules(rep, root.allModules);
    for (CompModule m : root.allModules) for (Sig s : m.sigs.values()) root.sig2module.put(s, m);
    // Resolves SigAST -> Sig, and topologically sort the sigs into the
    // "sorted" array
    root.new2old.put(UNIV, UNIV);
    root.new2old.put(SIGINT, SIGINT);
    root.new2old.put(SEQIDX, SEQIDX);
    root.new2old.put(STRING, STRING);
    root.new2old.put(NONE, NONE);
    HashSet<Object> topo = new HashSet<Object>();
    for (CompModule m : root.allModules) for (Sig s : m.sigs.values()) resolveSig(root, topo, s);
    // (since fields in subsigs are allowed to refer to parent's fields)
    for (Sig oldS : root.new2old.keySet()) resolveFieldDecl(root, rep, oldS, warns, false);
    // Typecheck the function declarations
    JoinableList<Err> errors = new JoinableList<Err>();
    for (CompModule x : root.allModules) errors = x.resolveFuncDecls(rep, errors, warns);
    if (!errors.isEmpty())
        throw errors.pick();
    // Typecheck the defined fields
    for (Sig oldS : root.new2old.keySet()) resolveFieldDecl(root, rep, oldS, warns, true);
    if (Version.experimental && root.seenDollar)
        resolveMeta(root);
    // Reject name clash
    rejectNameClash(root.allModules);
    // to function declarations)
    for (CompModule x : root.allModules) {
        errors = x.resolveFuncBody(rep, errors, warns);
        errors = x.resolveAssertions(rep, errors, warns);
        errors = x.resolveFacts(root, rep, errors, warns);
        // root module's list of exact sigs
        for (String n : x.exactParams) {
            Sig sig = x.params.get(n);
            if (sig != null)
                root.exactSigs.add(sig);
        }
    }
    if (!errors.isEmpty())
        throw errors.pick();
    // Typecheck the run/check commands (which can refer to function bodies
    // and assertions)
    root.resolveCommands(root.getAllReachableFacts());
    if (!errors.isEmpty())
        throw errors.pick();
    for (ErrorWarning w : warns) rep.warning(w);
    for (Sig s : root.exactSigs) rep.debug("Forced to be exact: " + s + "\n");
    return root;
}
Also used : PrimSig(edu.mit.csail.sdg.ast.Sig.PrimSig) Sig(edu.mit.csail.sdg.ast.Sig) SubsetSig(edu.mit.csail.sdg.ast.Sig.SubsetSig) Err(edu.mit.csail.sdg.alloy4.Err) ArrayList(java.util.ArrayList) ErrorWarning(edu.mit.csail.sdg.alloy4.ErrorWarning) HashSet(java.util.HashSet) LinkedHashSet(java.util.LinkedHashSet) JoinableList(edu.mit.csail.sdg.alloy4.JoinableList)

Example 2 with JoinableList

use of edu.mit.csail.sdg.alloy4.JoinableList 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 3 with JoinableList

use of edu.mit.csail.sdg.alloy4.JoinableList in project org.alloytools.alloy by AlloyTools.

the class ExprCall method make.

// ============================================================================================================//
/**
 * Constructs an ExprCall node with the given predicate/function "fun" and the
 * list of arguments "args".
 */
public static Expr make(Pos pos, Pos closingBracket, Func fun, List<Expr> args, long extraPenalty) {
    if (extraPenalty < 0)
        extraPenalty = 0;
    if (args == null)
        args = ConstList.make();
    long weight = extraPenalty;
    boolean ambiguous = false;
    JoinableList<Err> errs = emptyListOfErrors;
    TempList<Expr> newargs = new TempList<Expr>(args.size());
    if (args.size() != fun.count()) {
        errs = errs.make(new ErrorSyntax(pos, "" + fun + " has " + fun.count() + " parameters but is called with " + args.size() + " arguments."));
    }
    for (int i = 0; i < args.size(); i++) {
        final int a = (i < fun.count()) ? fun.get(i).type.arity() : 0;
        final Expr x = args.get(i).typecheck_as_set();
        ambiguous = ambiguous || x.ambiguous;
        errs = errs.make(x.errors);
        weight = weight + x.weight;
        if (x.mult != 0)
            errs = errs.make(new ErrorSyntax(x.span(), "Multiplicity expression not allowed here."));
        if (a > 0 && x.errors.isEmpty() && !x.type.hasArity(a))
            errs = errs.make(new ErrorType(x.span(), "This should have arity " + a + " but instead its possible type(s) are " + x.type));
        newargs.add(x);
    }
    Type t = Type.FORMULA;
    if (!fun.isPred && errs.size() == 0) {
        final Type tt = fun.returnDecl.type;
        try {
            // This provides a limited form of polymorphic function,
            // by using actual arguments at each call site to derive a
            // tighter bound on the return value.
            DeduceType d = new DeduceType();
            for (int i = 0; i < args.size(); i++) {
                ExprVar param = fun.get(i);
                d.env.put(param, newargs.get(i).type.extract(param.type.arity()));
            }
            t = fun.returnDecl.accept(d);
            if (t == null || t.is_int() || t.is_bool || t.arity() != tt.arity())
                // Just in case an error occurred...
                t = tt;
        } catch (Throwable ex) {
            // Just in case an error occurred...
            t = tt;
        }
    }
    return new ExprCall(pos, closingBracket, ambiguous, t, fun, newargs.makeConst(), extraPenalty, weight, errs);
}
Also used : Err(edu.mit.csail.sdg.alloy4.Err) ErrorSyntax(edu.mit.csail.sdg.alloy4.ErrorSyntax) ErrorType(edu.mit.csail.sdg.alloy4.ErrorType) TempList(edu.mit.csail.sdg.alloy4.ConstList.TempList) ErrorType(edu.mit.csail.sdg.alloy4.ErrorType)

Example 4 with JoinableList

use of edu.mit.csail.sdg.alloy4.JoinableList in project org.alloytools.alloy by AlloyTools.

the class ExprList method make.

/**
 * Generates a call to a builtin predicate
 */
public static ExprList make(Pos pos, Pos closingBracket, Op op, List<? extends Expr> args) {
    boolean ambiguous = false;
    JoinableList<Err> errs = emptyListOfErrors;
    TempList<Expr> newargs = new TempList<Expr>(args.size());
    long weight = 0;
    Type commonArity = null;
    for (int i = 0; i < args.size(); i++) {
        Expr a = (op == Op.AND || op == Op.OR) ? args.get(i).typecheck_as_formula() : args.get(i).typecheck_as_set();
        ambiguous = ambiguous || a.ambiguous;
        weight = weight + a.weight;
        if (a.mult != 0)
            errs = errs.make(new ErrorSyntax(a.span(), "Multiplicity expression not allowed here."));
        if (!a.errors.isEmpty())
            errs = errs.make(a.errors);
        else if (commonArity == null)
            commonArity = a.type;
        else
            commonArity = commonArity.pickCommonArity(a.type);
        if (op == Op.AND)
            addAND(newargs, a);
        else if (op == Op.OR)
            addOR(newargs, a);
        else
            newargs.add(a);
    }
    if (op == Op.TOTALORDER) {
        if (newargs.size() != 3) {
            errs = errs.make(new ErrorSyntax(pos, "The builtin pred/totalOrder[] predicate must be called with exactly three arguments."));
        } else if (errs.isEmpty()) {
            if (!newargs.get(0).type.hasArity(1))
                errs = errs.make(new ErrorType(pos, "The first argument to pred/totalOrder must be unary."));
            if (!newargs.get(1).type.hasArity(1))
                errs = errs.make(new ErrorType(pos, "The second argument to pred/totalOrder must be unary."));
            if (!newargs.get(2).type.hasArity(2))
                errs = errs.make(new ErrorType(pos, "The third argument to pred/totalOrder must be binary."));
        }
    }
    if (op == Op.DISJOINT) {
        if (newargs.size() < 2)
            errs = errs.make(new ErrorSyntax(pos, "The builtin disjoint[] predicate must be called with at least two arguments."));
        if (commonArity == EMPTY)
            errs = errs.make(new ErrorType(pos, "The builtin predicate disjoint[] cannot be used among expressions of different arities."));
    }
    return new ExprList(pos, closingBracket, op, ambiguous, newargs.makeConst(), weight, errs);
}
Also used : ErrorType(edu.mit.csail.sdg.alloy4.ErrorType) ErrorSyntax(edu.mit.csail.sdg.alloy4.ErrorSyntax) Err(edu.mit.csail.sdg.alloy4.Err) TempList(edu.mit.csail.sdg.alloy4.ConstList.TempList) ErrorType(edu.mit.csail.sdg.alloy4.ErrorType)

Example 5 with JoinableList

use of edu.mit.csail.sdg.alloy4.JoinableList in project org.alloytools.alloy by AlloyTools.

the class CompModule method resolveFuncDecls.

/**
 * Each FunAST will now point to a bodyless Func object.
 */
private JoinableList<Err> resolveFuncDecls(A4Reporter rep, JoinableList<Err> errors, List<ErrorWarning> warns) throws Err {
    for (ArrayList<Func> list : funcs.values()) {
        for (int listi = 0; listi < list.size(); listi++) {
            Func f = list.get(listi);
            String fullname = (path.length() == 0 ? "this/" : (path + "/")) + f.label;
            // Each PARAMETER can refer to earlier parameter in the same
            // function, and any SIG or FIELD visible from here.
            // Each RETURNTYPE can refer to the parameters of the same
            // function, and any SIG or FIELD visible from here.
            Context cx = new Context(this, warns);
            cx.rootfunparam = true;
            TempList<Decl> tmpdecls = new TempList<Decl>();
            boolean err = false;
            for (Decl d : f.decls) {
                TempList<ExprVar> tmpvars = new TempList<ExprVar>();
                Expr val = cx.check(d.expr).resolve_as_set(warns);
                if (!val.errors.isEmpty()) {
                    err = true;
                    errors = errors.make(val.errors);
                }
                for (ExprHasName n : d.names) {
                    ExprVar v = ExprVar.make(n.span(), n.label, val.type());
                    cx.put(n.label, v);
                    tmpvars.add(v);
                    rep.typecheck((f.isPred ? "pred " : "fun ") + fullname + ", Param " + n.label + ": " + v.type() + "\n");
                }
                tmpdecls.add(new Decl(d.isPrivate, d.disjoint, d.disjoint2, tmpvars.makeConst(), val));
            }
            Expr ret = null;
            if (!f.isPred) {
                ret = cx.check(f.returnDecl).resolve_as_set(warns);
                if (!ret.errors.isEmpty()) {
                    err = true;
                    errors = errors.make(ret.errors);
                }
            }
            if (err)
                continue;
            try {
                f = new Func(f.pos, f.isPrivate, fullname, tmpdecls.makeConst(), ret, f.getBody());
                list.set(listi, f);
                rep.typecheck("" + f + ", RETURN: " + f.returnDecl.type() + "\n");
            } catch (Err ex) {
                errors = errors.make(ex);
            }
        }
    }
    return errors;
}
Also used : ExprVar(edu.mit.csail.sdg.ast.ExprVar) Err(edu.mit.csail.sdg.alloy4.Err) Func(edu.mit.csail.sdg.ast.Func) Decl(edu.mit.csail.sdg.ast.Decl) TempList(edu.mit.csail.sdg.alloy4.ConstList.TempList) Expr(edu.mit.csail.sdg.ast.Expr) ExprHasName(edu.mit.csail.sdg.ast.ExprHasName)

Aggregations

Err (edu.mit.csail.sdg.alloy4.Err)6 TempList (edu.mit.csail.sdg.alloy4.ConstList.TempList)3 ErrorSyntax (edu.mit.csail.sdg.alloy4.ErrorSyntax)3 ErrorType (edu.mit.csail.sdg.alloy4.ErrorType)3 ErrorWarning (edu.mit.csail.sdg.alloy4.ErrorWarning)2 Decl (edu.mit.csail.sdg.ast.Decl)2 Expr (edu.mit.csail.sdg.ast.Expr)2 ExprHasName (edu.mit.csail.sdg.ast.ExprHasName)2 Func (edu.mit.csail.sdg.ast.Func)2 JoinableList (edu.mit.csail.sdg.alloy4.JoinableList)1 ExprVar (edu.mit.csail.sdg.ast.ExprVar)1 Sig (edu.mit.csail.sdg.ast.Sig)1 PrimSig (edu.mit.csail.sdg.ast.Sig.PrimSig)1 SubsetSig (edu.mit.csail.sdg.ast.Sig.SubsetSig)1 ArrayList (java.util.ArrayList)1 HashSet (java.util.HashSet)1 LinkedHashSet (java.util.LinkedHashSet)1