Search in sources :

Example 1 with SubsetSig

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

the class CompModule method resolveSig.

/**
 * The given Sig will now point to a nonnull Sig.
 */
private static Sig resolveSig(CompModule res, Set<Object> topo, Sig oldS) throws Err {
    if (res.new2old.containsKey(oldS))
        return oldS;
    Sig realSig;
    final Pos pos = oldS.pos;
    final CompModule u = res.sig2module.get(oldS);
    final String name = base(oldS);
    final String fullname = (u.path.length() == 0) ? ("this/" + name) : (u.path + "/" + name);
    if (!topo.add(oldS))
        throw new ErrorType(pos, "Sig " + oldS + " is involved in a cyclic inheritance.");
    if (oldS instanceof SubsetSig) {
        List<Sig> parents = new ArrayList<Sig>();
        for (Sig n : ((SubsetSig) oldS).parents) {
            Sig parentAST = u.getRawSIG(n.pos, n.label);
            if (parentAST == null)
                throw new ErrorSyntax(n.pos, "The sig \"" + n.label + "\" cannot be found.");
            parents.add(resolveSig(res, topo, parentAST));
        }
        realSig = new SubsetSig(fullname, parents, oldS.attributes.toArray(new Attr[0]));
    } else {
        Sig sup = ((PrimSig) oldS).parent;
        Sig parentAST = u.getRawSIG(sup.pos, sup.label);
        if (parentAST == null)
            throw new ErrorSyntax(sup.pos, "The sig \"" + sup.label + "\" cannot be found.");
        Sig parent = resolveSig(res, topo, parentAST);
        if (!(parent instanceof PrimSig))
            throw new ErrorSyntax(sup.pos, "Cannot extend the subset signature \"" + parent + "\".\n" + "A signature can only extend a toplevel signature or a subsignature.");
        PrimSig p = (PrimSig) parent;
        realSig = new PrimSig(fullname, p, oldS.attributes.toArray(new Attr[0]));
    }
    res.new2old.put(realSig, oldS);
    res.sig2module.put(realSig, u);
    for (CompModule m : res.allModules) {
        for (Map.Entry<String, Sig> e : m.sigs.entrySet()) if (e.getValue() == oldS)
            e.setValue(realSig);
        for (Map.Entry<String, Sig> e : m.params.entrySet()) if (e.getValue() == oldS)
            e.setValue(realSig);
    }
    if (res.exactSigs.remove(oldS))
        res.exactSigs.add(realSig);
    return realSig;
}
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) SubsetSig(edu.mit.csail.sdg.ast.Sig.SubsetSig) ErrorSyntax(edu.mit.csail.sdg.alloy4.ErrorSyntax) ErrorType(edu.mit.csail.sdg.alloy4.ErrorType) Pos(edu.mit.csail.sdg.alloy4.Pos) ArrayList(java.util.ArrayList) Map(java.util.Map) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) PrimSig(edu.mit.csail.sdg.ast.Sig.PrimSig)

Example 2 with SubsetSig

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

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

the class BoundsComputer method allocateSubsetSig.

// ==============================================================================================================//
/**
 * Allocate relations for SubsetSig top-down.
 */
private Expression allocateSubsetSig(SubsetSig sig) throws Err {
    // We must not visit the same SubsetSig more than once, so if we've been
    // here already, then return the old value right away
    Expression sum = sol.a2k(sig);
    if (sum != null && sum != Expression.NONE)
        return sum;
    // Recursively form the union of all parent expressions
    TupleSet ts = factory.noneOf(1);
    for (Sig parent : sig.parents) {
        Expression p = (parent instanceof PrimSig) ? sol.a2k(parent) : allocateSubsetSig((SubsetSig) parent);
        ts.addAll(sol.query(true, p, false));
        if (sum == null)
            sum = p;
        else
            sum = sum.union(p);
    }
    // If subset is exact, then just use the "sum" as is
    if (sig.exact) {
        sol.addSig(sig, sum);
        return sum;
    }
    // Allocate a relation for this subset sig, then bound it
    rep.bound("Sig " + sig + " in " + ts + "\n");
    Relation r = sol.addRel(sig.label, null, ts);
    sol.addSig(sig, r);
    // Add a constraint that it is INDEED a subset of the union of its
    // parents
    sol.addFormula(r.in(sum), sig.isSubset);
    return r;
}
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) TupleSet(kodkod.instance.TupleSet) SubsetSig(edu.mit.csail.sdg.ast.Sig.SubsetSig) Relation(kodkod.ast.Relation) Expression(kodkod.ast.Expression) PrimSig(edu.mit.csail.sdg.ast.Sig.PrimSig)

Example 4 with SubsetSig

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

the class StaticInstanceReader method sigMETA.

/**
 * Returns the AlloyType corresponding to the given sig; create an AlloyType for
 * it if none existed before.
 */
private void sigMETA(SubsetSig s) throws Err {
    AlloyAtom atom;
    AlloyType type = sig2type.get(s);
    if (type != null)
        return;
    type = makeType(s.label, s.isOne != null, s.isAbstract != null, false, s.isPrivate != null, s.isMeta != null, s.isEnum != null);
    atom = new AlloyAtom(type, Integer.MAX_VALUE, s.label);
    atom2sets.put(atom, new LinkedHashSet<AlloySet>());
    sig2atom.put(s, atom);
    sig2type.put(s, type);
    ts.put(type, AlloyType.SET);
    for (Sig p : s.parents) {
        if (p instanceof SubsetSig)
            sigMETA((SubsetSig) p);
        else
            sigMETA((PrimSig) p);
        ins.add(new AlloyTuple(atom, sig2atom.get(p)));
    }
}
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) SubsetSig(edu.mit.csail.sdg.ast.Sig.SubsetSig) PrimSig(edu.mit.csail.sdg.ast.Sig.PrimSig)

Example 5 with SubsetSig

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

the class A4SolutionWriter method writesig.

/**
 * Write the given Sig.
 */
private A4TupleSet writesig(final Sig x) throws Err {
    A4TupleSet ts = null, ts2 = null;
    if (x == Sig.NONE)
        // should not happen, but we test for it anyway
        return null;
    if (sol == null && x.isMeta != null)
        // When writing the metamodel, skip the metamodel sigs!
        return null;
    if (x instanceof PrimSig)
        for (final PrimSig sub : children((PrimSig) x)) {
            A4TupleSet ts3 = writesig(sub);
            if (ts2 == null)
                ts2 = ts3;
            else
                ts2 = ts2.plus(ts3);
        }
    if (rep != null)
        rep.write(x);
    Util.encodeXMLs(out, "\n<sig label=\"", x.label, "\" ID=\"", map(x));
    if (x instanceof PrimSig && x != Sig.UNIV)
        Util.encodeXMLs(out, "\" parentID=\"", map(((PrimSig) x).parent));
    if (x.builtin)
        out.print("\" builtin=\"yes");
    if (x.isAbstract != null)
        out.print("\" abstract=\"yes");
    if (x.isOne != null)
        out.print("\" one=\"yes");
    if (x.isLone != null)
        out.print("\" lone=\"yes");
    if (x.isSome != null)
        out.print("\" some=\"yes");
    if (x.isPrivate != null)
        out.print("\" private=\"yes");
    if (x.isMeta != null)
        out.print("\" meta=\"yes");
    if (x instanceof SubsetSig && ((SubsetSig) x).exact)
        out.print("\" exact=\"yes");
    if (x.isEnum != null)
        out.print("\" enum=\"yes");
    out.print("\">\n");
    try {
        if (sol != null && x != Sig.UNIV && x != Sig.SIGINT && x != Sig.SEQIDX) {
            ts = (sol.eval(x));
            for (A4Tuple t : ts.minus(ts2)) Util.encodeXMLs(out, "   <atom label=\"", t.atom(0), "\"/>\n");
        }
    } catch (Throwable ex) {
        throw new ErrorFatal("Error evaluating sig " + x.label, ex);
    }
    if (x instanceof SubsetSig)
        for (Sig p : ((SubsetSig) x).parents) Util.encodeXMLs(out, "   <type ID=\"", map(p), "\"/>\n");
    out.print("</sig>\n");
    for (Field field : x.getFields()) writeField(field);
    return ts;
}
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) SubsetSig(edu.mit.csail.sdg.ast.Sig.SubsetSig) Field(edu.mit.csail.sdg.ast.Sig.Field) ErrorFatal(edu.mit.csail.sdg.alloy4.ErrorFatal) PrimSig(edu.mit.csail.sdg.ast.Sig.PrimSig)

Aggregations

Sig (edu.mit.csail.sdg.ast.Sig)7 PrimSig (edu.mit.csail.sdg.ast.Sig.PrimSig)7 SubsetSig (edu.mit.csail.sdg.ast.Sig.SubsetSig)7 ArrayList (java.util.ArrayList)3 Pos (edu.mit.csail.sdg.alloy4.Pos)2 Expr (edu.mit.csail.sdg.ast.Expr)2 Field (edu.mit.csail.sdg.ast.Sig.Field)2 TupleSet (kodkod.instance.TupleSet)2 Err (edu.mit.csail.sdg.alloy4.Err)1 ErrorFatal (edu.mit.csail.sdg.alloy4.ErrorFatal)1 ErrorSyntax (edu.mit.csail.sdg.alloy4.ErrorSyntax)1 ErrorType (edu.mit.csail.sdg.alloy4.ErrorType)1 Pair (edu.mit.csail.sdg.alloy4.Pair)1 XMLNode (edu.mit.csail.sdg.alloy4.XMLNode)1 Attr (edu.mit.csail.sdg.ast.Attr)1 Decl (edu.mit.csail.sdg.ast.Decl)1 ExprBinary (edu.mit.csail.sdg.ast.ExprBinary)1 ExprHasName (edu.mit.csail.sdg.ast.ExprHasName)1 ExprUnary (edu.mit.csail.sdg.ast.ExprUnary)1 ExprVar (edu.mit.csail.sdg.ast.ExprVar)1