Search in sources :

Example 1 with SafeList

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

the class ScopeComputer method derive_abstract_scope.

// ===========================================================================================================================//
/**
 * If A is abstract, unscoped, and all children are scoped, then set A's scope
 * to be the sum; if A is abstract, scoped, and every child except one is
 * scoped, then set that child's scope to be the difference.
 */
private boolean derive_abstract_scope(Iterable<Sig> sigs) throws Err {
    boolean changed = false;
    again: for (Sig s : sigs) if (!s.builtin && (s instanceof PrimSig) && s.isAbstract != null) {
        SafeList<PrimSig> subs = ((PrimSig) s).children();
        if (subs.size() == 0)
            continue;
        Sig missing = null;
        int sum = 0;
        for (Sig c : subs) {
            int cn = sig2scope(c);
            if (cn < 0) {
                if (missing == null) {
                    missing = c;
                    continue;
                } else {
                    continue again;
                }
            }
            sum = sum + cn;
            if (sum < 0)
                throw new ErrorSyntax(cmd.pos, "The number of atoms exceeds the internal limit of " + Integer.MAX_VALUE);
        }
        int sn = sig2scope(s);
        if (sn < 0) {
            if (missing != null)
                continue;
            sig2scope(s, sum);
            changed = true;
        } else if (missing != null) {
            sig2scope(missing, (sn < sum) ? 0 : sn - sum);
            changed = true;
        }
    }
    return changed;
}
Also used : PrimSig(edu.mit.csail.sdg.ast.Sig.PrimSig) Sig(edu.mit.csail.sdg.ast.Sig) ErrorSyntax(edu.mit.csail.sdg.alloy4.ErrorSyntax) PrimSig(edu.mit.csail.sdg.ast.Sig.PrimSig)

Example 2 with SafeList

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

the class CompModule method populate.

/**
 * Resolve the name based on the current context and this module.
 */
private Expr populate(TempList<Expr> ch, TempList<String> re, Decl rootfield, Sig rootsig, boolean rootfunparam, Func rootfunbody, Pos pos, String fullname, Expr THIS) {
    // Return object can be Func(with > 0 arguments) or Expr
    final String name = (fullname.charAt(0) == '@') ? fullname.substring(1) : fullname;
    boolean fun = (rootsig != null && (rootfield == null || rootfield.expr.mult() == ExprUnary.Op.EXACTLYOF)) || (rootsig == null && !rootfunparam);
    if (name.equals("univ"))
        return ExprUnary.Op.NOOP.make(pos, UNIV);
    if (name.equals("Int"))
        return ExprUnary.Op.NOOP.make(pos, SIGINT);
    if (name.equals("seq/Int"))
        return ExprUnary.Op.NOOP.make(pos, SEQIDX);
    if (name.equals("String"))
        return ExprUnary.Op.NOOP.make(pos, STRING);
    if (name.equals("none"))
        return ExprUnary.Op.NOOP.make(pos, NONE);
    if (name.equals("iden"))
        return ExprConstant.Op.IDEN.make(pos, 0);
    if (name.equals("sig$") || name.equals("field$"))
        if (world != null) {
            Sig s = world.sigs.get(name);
            if (s != null)
                return ExprUnary.Op.NOOP.make(pos, s);
        }
    final List<Object> ans = name.indexOf('/') >= 0 ? getRawQS(fun ? 5 : 1, name) : getRawNQS(this, fun ? 5 : 1, name);
    final Sig param = params.get(name);
    if (param != null && !ans.contains(param))
        ans.add(param);
    for (Object x : ans) {
        if (x instanceof Sig) {
            Sig y = (Sig) x;
            ch.add(ExprUnary.Op.NOOP.make(pos, y, null, 0));
            re.add("sig " + y.label);
        } else if (x instanceof Func) {
            Func f = (Func) x;
            int fn = f.count();
            int penalty = 0;
            if (resolution == 1 && fn > 0 && rootsig != null && THIS != null && THIS.type().hasArity(1) && f.get(0).type().intersects(THIS.type())) {
                // If we're inside a sig, and there is a unary variable
                // bound to "this",
                // we should consider it as a possible FIRST ARGUMENT of a
                // fun/pred call
                ConstList<Expr> t = Util.asList(THIS);
                // penalty
                ch.add(fn == 1 ? ExprCall.make(pos, null, f, t, 1 + penalty) : ExprBadCall.make(pos, null, f, t, 1 + penalty));
                // of
                // 1
                re.add((f.isPred ? "pred this." : "fun this.") + f.label);
            }
            if (resolution == 1) {
                ch.add(fn == 0 ? ExprCall.make(pos, null, f, null, penalty) : ExprBadCall.make(pos, null, f, null, penalty));
                re.add((f.isPred ? "pred " : "fun ") + f.label);
            }
            if (resolution == 2 && f != rootfunbody && THIS != null && fullname.charAt(0) != '@' && fn > 0 && f.get(0).type().intersects(THIS.type())) {
                // If there is some value bound to "this", we should
                // consider it as a possible FIRST ARGUMENT of a fun/pred
                // call
                ConstList<Expr> t = Util.asList(THIS);
                ch.add(fn == 1 ? ExprCall.make(pos, null, f, t, 0) : ExprBadCall.make(pos, null, f, t, 0));
                re.add((f.isPred ? "pred this." : "fun this.") + f.label);
            }
            if (resolution != 1) {
                ch.add(fn == 0 ? ExprCall.make(pos, null, f, null, 0) : ExprBadCall.make(pos, null, f, null, 0));
                re.add((f.isPred ? "pred " : "fun ") + f.label);
            }
        }
    }
    // All else: we can call, and can refer to anything visible.
    for (CompModule m : getAllNameableModules()) for (Sig s : m.sigs.values()) if (m == this || s.isPrivate == null)
        for (Field f : s.getFields()) if (f.isMeta == null && (m == this || f.isPrivate == null) && f.label.equals(name))
            if (resolution == 1) {
                Expr x = null;
                if (rootsig == null) {
                    x = ExprUnary.Op.NOOP.make(pos, f, null, 0);
                } else if (rootsig.isSameOrDescendentOf(f.sig)) {
                    x = ExprUnary.Op.NOOP.make(pos, f, null, 0);
                    if (fullname.charAt(0) != '@')
                        x = THIS.join(x);
                } else if (rootfield == null || rootfield.expr.mult() == ExprUnary.Op.EXACTLYOF) {
                    x = ExprUnary.Op.NOOP.make(pos, f, null, 1);
                }
                // penalty of 1
                if (x != null) {
                    ch.add(x);
                    re.add("field " + f.sig.label + " <: " + f.label);
                }
            } else if (rootfield == null || rootsig.isSameOrDescendentOf(f.sig)) {
                Expr x0 = ExprUnary.Op.NOOP.make(pos, f, null, 0);
                if (resolution == 2 && THIS != null && fullname.charAt(0) != '@' && f.type().firstColumnOverlaps(THIS.type())) {
                    ch.add(THIS.join(x0));
                    re.add("field " + f.sig.label + " <: this." + f.label);
                    if (rootsig != null)
                        continue;
                }
                ch.add(x0);
                re.add("field " + f.sig.label + " <: " + f.label);
            }
    if (metaSig() != null && (rootsig == null || rootfield == null)) {
        SafeList<PrimSig> children = null;
        try {
            children = metaSig().children();
        } catch (Err err) {
            return null;
        }
        // exception NOT possible
        for (PrimSig s : children) for (Field f : s.getFields()) if (f.label.equals(name)) {
            Expr x = ExprUnary.Op.NOOP.make(pos, f, null, 0);
            ch.add(x);
            re.add("field " + f.sig.label + " <: " + f.label);
        }
    }
    if (metaField() != null && (rootsig == null || rootfield == null)) {
        SafeList<PrimSig> children = null;
        try {
            children = metaField().children();
        } catch (Err err) {
            return null;
        }
        // exception NOT possible
        for (PrimSig s : children) for (Field f : s.getFields()) if (f.label.equals(name)) {
            Expr x = ExprUnary.Op.NOOP.make(pos, f, null, 0);
            ch.add(x);
            re.add("field " + f.sig.label + " <: " + f.label);
        }
    }
    return null;
}
Also used : Err(edu.mit.csail.sdg.alloy4.Err) 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) Field(edu.mit.csail.sdg.ast.Sig.Field) Expr(edu.mit.csail.sdg.ast.Expr) ConstList(edu.mit.csail.sdg.alloy4.ConstList) PrimSig(edu.mit.csail.sdg.ast.Sig.PrimSig)

Example 3 with SafeList

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

the class Type method fold.

/**
 * Merge "a" into the set of entries.
 * <p>
 * If {a}+this.entries contain a set of entries X1..Xn, such that <br>
 * (1) For each X: X[j]==a[j] for i!=j, and X[i].super==a[i].super <br>
 * (2) X1[i]..Xn[i] exhaust all the direct subsignatures of an abstract parent
 * sig <br>
 * THEN: <br>
 * we remove X1..Xn, then return the merged result of X1..Xn <br>
 * ELSE <br>
 * we change nothing, and simply return null
 * <p>
 * <b>Precondition:</b> a[i] is not NONE, and a[i].parent is abstract, and
 * a[i].parent!=UNIV
 */
private static List<PrimSig> fold(ArrayList<List<PrimSig>> entries, List<PrimSig> a, int i) {
    PrimSig parent = a.get(i).parent;
    SafeList<PrimSig> children;
    try {
        children = parent.children();
    } catch (Err ex) {
        return null;
    }
    // Exception only occurs if a[i].parent==UNIV
    List<PrimSig> subs = children.makeCopy();
    ArrayList<List<PrimSig>> toDelete = new ArrayList<List<PrimSig>>();
    for (int bi = entries.size() - 1; bi >= 0; bi--) {
        List<PrimSig> b = entries.get(bi);
        if (b.size() == a.size()) {
            for (int j = 0; ; j++) {
                if (j >= b.size()) {
                    toDelete.add(b);
                    subs.remove(b.get(i));
                    break;
                }
                PrimSig bt1 = a.get(j), bt2 = b.get(j);
                if (i == j && bt2.parent != parent)
                    break;
                if (i != j && bt2 != bt1)
                    break;
            }
        }
    }
    subs.remove(a.get(i));
    if (subs.size() != 0)
        return null;
    entries.removeAll(toDelete);
    entries.remove(a);
    a = new ArrayList<PrimSig>(a);
    a.set(i, parent);
    return a;
}
Also used : Err(edu.mit.csail.sdg.alloy4.Err) ArrayList(java.util.ArrayList) SafeList(edu.mit.csail.sdg.alloy4.SafeList) TempList(edu.mit.csail.sdg.alloy4.ConstList.TempList) ConstList(edu.mit.csail.sdg.alloy4.ConstList) ArrayList(java.util.ArrayList) List(java.util.List) PrimSig(edu.mit.csail.sdg.ast.Sig.PrimSig)

Example 4 with SafeList

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

the class InternalTest method test1.

public void test1() throws Exception {
    XMLNode xml = new XMLNode(new StringReader("<alloy builddate='unknown'>" + "<instance bitwidth='2' maxseq='1' command='Run Deadlock' filename='dijkstra.als'>" + "<sig label='univ' ID='0' builtin='yes'> <atom label='-2'/> <atom label='-1'/> <atom label='0'/> <atom label='1'/> <atom label='State$0'/> <atom label='State$1'/> <atom label='State$2'/> </sig>" + "<sig label='Int' ID='1' parentID='0' builtin='yes'> <atom label='-2'/> <atom label='-1'/> <atom label='0'/> <atom label='1'/> </sig>" + "<sig label='seq/Int' ID='2' parentID='1' builtin='yes'> <atom label='0'/> </sig>" + "<sig label='State' ID='5' parentID='0'> <atom label='State$0'/> <atom label='State$1'/> <atom label='State$2'/> </sig>" + "<field label='len' parentID='5' ID='17'>" + "   <tuple> <atom label='State$1'/> <atom label='-2'/> </tuple>" + "   <tuple> <atom label='State$1'/> <atom label='-1'/> </tuple>" + "   <types> <type ID='5'/> <type ID='1'/> </types>" + "</field>" + "<skolem label='$Deadlock_s' ID='16'>" + "   <tuple> <atom label='State$0'/> </tuple>" + "   <types> <type ID='5'/> </types>" + "</skolem>" + "</instance>" + "</alloy>"));
    Sig state = new Sig.PrimSig("State");
    A4Solution sol = A4SolutionReader.read(Arrays.asList(state), xml);
    SafeList<ExprVar> skolems = new SafeList<ExprVar>(sol.getAllSkolems());
    check(skolems.size() == 1);
    check(skolems.get(0).label, "$Deadlock_s");
    check(skolems.get(0).type(), state.type());
    // 
    Sig state2 = new Sig.PrimSig("State");
    Field field2 = state2.addField("len", Sig.SIGINT);
    sol = A4SolutionReader.read(Arrays.asList(state2), xml);
    SafeList<ExprVar> skolems2 = new SafeList<ExprVar>(sol.getAllSkolems());
    check(skolems2.size() == 1);
    check(skolems2.get(0).label, "$Deadlock_s");
    check(skolems2.get(0).type(), state2.type());
    check("" + sol.eval(field2.cardinality()), "-2");
}
Also used : Sig(edu.mit.csail.sdg.ast.Sig) ExprVar(edu.mit.csail.sdg.ast.ExprVar) Field(edu.mit.csail.sdg.ast.Sig.Field) XMLNode(edu.mit.csail.sdg.alloy4.XMLNode) SafeList(edu.mit.csail.sdg.alloy4.SafeList) StringReader(java.io.StringReader) A4Solution(edu.mit.csail.sdg.translator.A4Solution)

Example 5 with SafeList

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

the class InternalTest method test2.

public void test2() throws Exception {
    test1();
    XMLNode xml = new XMLNode(new StringReader("<alloy builddate='unknown'>" + "<instance bitwidth='2' maxseq='1' command='Run Deadlock' filename='dijkstra.als'>" + "<sig label='univ' ID='0' builtin='yes'> <atom label='-2'/> <atom label='-1'/> <atom label='0'/> <atom label='1'/> <atom label='State$0'/> <atom label='State$1'/> <atom label='State$2'/> </sig>" + "<sig label='Int' ID='1' parentID='0' builtin='yes'> <atom label='-2'/> <atom label='-1'/> <atom label='0'/> <atom label='1'/> </sig>" + "<sig label='seq/Int' ID='2' parentID='1' builtin='yes'> <atom label='0'/> </sig>" + "<sig label='Act' ID='5' parentID='0'> <atom label='Act$0'/> <atom label='Act$1'/> <atom label='Act$2'/> </sig>" + "<skolem label='$x' ID='16'>" + "   <tuple> <atom label='0'/> <atom label='Act$1'/> </tuple>" + "   <types> <type ID='2'/> <type ID='5'/> </types>" + "</skolem>" + "</instance>" + "</alloy>"));
    Sig activity = new Sig.PrimSig("Act");
    A4Solution sol = A4SolutionReader.read(Arrays.asList(activity), xml);
    SafeList<ExprVar> skolems = new SafeList<ExprVar>(sol.getAllSkolems());
    check(skolems.size() == 1);
    check(skolems.get(0).label, "$x");
    check(skolems.get(0).type(), Sig.SEQIDX.type().product(activity.type()));
}
Also used : Sig(edu.mit.csail.sdg.ast.Sig) ExprVar(edu.mit.csail.sdg.ast.ExprVar) XMLNode(edu.mit.csail.sdg.alloy4.XMLNode) SafeList(edu.mit.csail.sdg.alloy4.SafeList) StringReader(java.io.StringReader) A4Solution(edu.mit.csail.sdg.translator.A4Solution)

Aggregations

Sig (edu.mit.csail.sdg.ast.Sig)5 SafeList (edu.mit.csail.sdg.alloy4.SafeList)3 Field (edu.mit.csail.sdg.ast.Sig.Field)3 PrimSig (edu.mit.csail.sdg.ast.Sig.PrimSig)3 A4Solution (edu.mit.csail.sdg.translator.A4Solution)3 ConstList (edu.mit.csail.sdg.alloy4.ConstList)2 Err (edu.mit.csail.sdg.alloy4.Err)2 XMLNode (edu.mit.csail.sdg.alloy4.XMLNode)2 ExprVar (edu.mit.csail.sdg.ast.ExprVar)2 StringReader (java.io.StringReader)2 A4Reporter (edu.mit.csail.sdg.alloy4.A4Reporter)1 TempList (edu.mit.csail.sdg.alloy4.ConstList.TempList)1 ErrorAPI (edu.mit.csail.sdg.alloy4.ErrorAPI)1 ErrorSyntax (edu.mit.csail.sdg.alloy4.ErrorSyntax)1 Command (edu.mit.csail.sdg.ast.Command)1 Expr (edu.mit.csail.sdg.ast.Expr)1 Func (edu.mit.csail.sdg.ast.Func)1 SubsetSig (edu.mit.csail.sdg.ast.Sig.SubsetSig)1 CompModule (edu.mit.csail.sdg.parser.CompModule)1 A4Options (edu.mit.csail.sdg.translator.A4Options)1