Search in sources :

Example 26 with PrimSig

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

the class BoundsComputer method allocatePrimSig.

// ==============================================================================================================//
/**
 * Allocate relations for nonbuiltin PrimSigs bottom-up.
 */
private Expression allocatePrimSig(PrimSig sig) throws Err {
    // Recursively allocate all children expressions, and form the union of
    // them
    Expression sum = null;
    for (PrimSig child : sig.children()) {
        Expression childexpr = allocatePrimSig(child);
        if (sum == null) {
            sum = childexpr;
            continue;
        }
        // subsigs are disjoint
        sol.addFormula(sum.intersection(childexpr).no(), child.isSubsig);
        sum = sum.union(childexpr);
    }
    TupleSet lower = lb.get(sig).clone(), upper = ub.get(sig).clone();
    if (sum == null) {
        // If sig doesn't have children, then sig should make a fresh
        // relation for itself
        sum = sol.addRel(sig.label, lower, upper);
    } else if (sig.isAbstract == null) {
        // relation to act as the remainder.
        for (PrimSig child : sig.children()) {
            // Remove atoms that are KNOWN to be in a subsig;
            // it's okay to mistakenly leave some atoms in, since we will
            // never solve for the "remainder" relation directly;
            // instead, we union the remainder with the children, then solve
            // for the combined solution.
            // (Thus, the more we can remove, the more efficient it gets,
            // but it is not crucial for correctness)
            TupleSet childTS = sol.query(false, sol.a2k(child), false);
            lower.removeAll(childTS);
            upper.removeAll(childTS);
        }
        sum = sum.union(sol.addRel(sig.label + " remainder", lower, upper));
    }
    sol.addSig(sig, sum);
    return sum;
}
Also used : TupleSet(kodkod.instance.TupleSet) Expression(kodkod.ast.Expression) PrimSig(edu.mit.csail.sdg.ast.Sig.PrimSig)

Example 27 with PrimSig

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

the class ScopeComputer method sig2scope.

/**
 * Sets the scope for a sig; returns true iff the sig's scope is changed by this
 * call.
 */
private void sig2scope(Sig sig, int newValue) throws Err {
    if (sig.builtin)
        throw new ErrorSyntax(cmd.pos, "Cannot specify a scope for the builtin signature \"" + sig + "\"");
    if (!(sig instanceof PrimSig))
        throw new ErrorSyntax(cmd.pos, "Cannot specify a scope for a subset signature \"" + sig + "\"");
    if (newValue < 0)
        throw new ErrorSyntax(cmd.pos, "Cannot specify a negative scope for sig \"" + sig + "\"");
    int old = sig2scope(sig);
    if (old == newValue)
        return;
    if (old >= 0)
        throw new ErrorSyntax(cmd.pos, "Sig \"" + sig + "\" already has a scope of " + old + ", so we cannot set it to be " + newValue);
    sig2scope.put((PrimSig) sig, newValue);
    rep.scope("Sig " + sig + " scope <= " + newValue + "\n");
}
Also used : ErrorSyntax(edu.mit.csail.sdg.alloy4.ErrorSyntax) PrimSig(edu.mit.csail.sdg.ast.Sig.PrimSig)

Example 28 with PrimSig

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

the class ScopeComputer method derive_scope_from_parent.

// ===========================================================================================================================//
/**
 * If A is not toplevel, and we haven't been able to derive its scope yet, then
 * give it its parent's scope.
 */
private boolean derive_scope_from_parent(Iterable<Sig> sigs) throws Err {
    boolean changed = false;
    Sig trouble = null;
    for (Sig s : sigs) if (!s.builtin && !s.isTopLevel() && sig2scope(s) < 0 && (s instanceof PrimSig)) {
        PrimSig p = ((PrimSig) s).parent;
        int pb = sig2scope(p);
        if (pb >= 0) {
            sig2scope(s, pb);
            changed = true;
        } else {
            trouble = s;
        }
    }
    if (changed)
        return true;
    if (trouble == null)
        return false;
    throw new ErrorSyntax(cmd.pos, "You must specify a scope for sig \"" + trouble + "\"");
}
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 29 with PrimSig

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

the class ScopeComputer method computeLowerBound.

// ===========================================================================================================================//
/**
 * Computes the number of atoms needed for each sig (and add these atoms to
 * this.atoms)
 */
private int computeLowerBound(final PrimSig sig) throws Err {
    if (sig.builtin)
        return 0;
    int n = sig2scope(sig), lower = 0;
    boolean isExact = isExact(sig);
    // First, figure out what atoms *MUST* be in this sig
    for (PrimSig c : sig.children()) lower = lower + computeLowerBound(c);
    // sig
    if (n < lower) {
        if (isExact)
            rep.scope("Sig " + sig + " scope raised from ==" + n + " to be ==" + lower + "\n");
        else
            rep.scope("Sig " + sig + " scope raised from <=" + n + " to be <=" + lower + "\n");
        n = lower;
        sig2scope.put(sig, n);
    }
    // Add special overrides for "exactly" sigs
    if (!isExact && cmd.additionalExactScopes.contains(sig)) {
        isExact = true;
        rep.scope("Sig " + sig + " forced to have exactly " + n + " atoms.\n");
        makeExact(Pos.UNKNOWN, sig);
    }
    // Create atoms
    if (n > lower && (isExact || sig.isTopLevel())) {
        // Figure out how many new atoms to make
        n = n - lower;
        // Pick a name for them
        String name = sig.label;
        if (name.startsWith("this/"))
            name = name.substring(5);
        name = un.make(name);
        // Now, generate each atom using the format "SIGNAME$INDEX"
        // By prepending the index with 0 so that they're the same width, we
        // ensure they sort lexicographically.
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < n; i++) {
            String x = sb.delete(0, sb.length()).append(name).append('$').append(i).toString();
            atoms.add(x);
            lower++;
        }
    }
    return lower;
}
Also used : PrimSig(edu.mit.csail.sdg.ast.Sig.PrimSig)

Example 30 with PrimSig

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

the class A4SolutionReader method parseSig.

/**
 * Parse sig/set.
 */
private Sig parseSig(String id, int depth) throws IOException, Err {
    Sig ans = id2sig.get(id);
    if (ans != null)
        return ans;
    XMLNode node = nmap.get(id);
    if (node == null)
        throw new IOException("Unknown SigID " + id + " encountered.");
    if (!node.is("sig"))
        throw new IOException("ID " + id + " is not a sig.");
    String label = label(node);
    Attr isAbstract = yes(node, "abstract") ? Attr.ABSTRACT : null;
    Attr isOne = yes(node, "one") ? Attr.ONE : null;
    Attr isLone = yes(node, "lone") ? Attr.LONE : null;
    Attr isSome = yes(node, "some") ? Attr.SOME : null;
    Attr isPrivate = yes(node, "private") ? Attr.PRIVATE : null;
    Attr isMeta = yes(node, "meta") ? Attr.META : null;
    Attr isEnum = yes(node, "enum") ? Attr.ENUM : null;
    Attr isExact = yes(node, "exact") ? Attr.EXACT : null;
    if (yes(node, "builtin")) {
        if (label.equals(UNIV.label)) {
            id2sig.put(id, UNIV);
            return UNIV;
        }
        if (label.equals(SIGINT.label)) {
            id2sig.put(id, SIGINT);
            return SIGINT;
        }
        if (label.equals(SEQIDX.label)) {
            id2sig.put(id, SEQIDX);
            return SEQIDX;
        }
        if (label.equals(STRING.label)) {
            id2sig.put(id, STRING);
            return STRING;
        }
        throw new IOException("Unknown builtin sig: " + label + " (id=" + id + ")");
    }
    if (depth > nmap.size())
        throw new IOException("Sig " + label + " (id=" + id + ") is in a cyclic inheritance relationship.");
    List<Sig> parents = null;
    TupleSet ts = factory.noneOf(1);
    for (XMLNode sub : node) {
        if (sub.is("atom")) {
            ts.add(factory.tuple(sub.getAttribute("label")));
            continue;
        }
        if (!sub.is("type"))
            continue;
        Sig parent = parseSig(sub.getAttribute("ID"), depth + 1);
        if (parents == null)
            parents = new ArrayList<Sig>();
        parents.add(parent);
    }
    if (parents == null) {
        String parentID = node.getAttribute("parentID");
        Sig parent = parseSig(parentID, depth + 1);
        if (!(parent instanceof PrimSig))
            throw new IOException("Parent of sig " + label + " (id=" + id + ") must not be a subset sig.");
        for (Expr choice : choices) if (choice instanceof PrimSig && parent == ((PrimSig) choice).parent && ((Sig) choice).label.equals(label)) {
            ans = (Sig) choice;
            choices.remove(choice);
            break;
        }
        if (ans == null) {
            ans = new PrimSig(label, (PrimSig) parent, isAbstract, isLone, isOne, isSome, isPrivate, isMeta, isEnum);
            allsigs.add(ans);
        }
    } else {
        for (Expr choice : choices) if (choice instanceof SubsetSig && ((Sig) choice).label.equals(label) && sameset(parents, ((SubsetSig) choice).parents)) {
            ans = (Sig) choice;
            choices.remove(choice);
            break;
        }
        if (ans == null) {
            ans = new SubsetSig(label, parents, isExact, isLone, isOne, isSome, isPrivate, isMeta);
            allsigs.add(ans);
        }
    }
    id2sig.put(id, ans);
    expr2ts.put(ans, ts);
    if (ans instanceof PrimSig) {
        // Add the atoms in this SIG into all parent sigs
        for (PrimSig ans2 = ((PrimSig) ans).parent; ans2 != null && !ans2.builtin; ans2 = ans2.parent) {
            TupleSet ts2 = expr2ts.get(ans2);
            if (ts2 == null)
                ts2 = ts.clone();
            else {
                ts2 = ts2.clone();
                ts2.addAll(ts);
            }
            expr2ts.put(ans2, ts2);
        }
    }
    return ans;
}
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) XMLNode(edu.mit.csail.sdg.alloy4.XMLNode) Expr(edu.mit.csail.sdg.ast.Expr) ArrayList(java.util.ArrayList) IOException(java.io.IOException) Attr(edu.mit.csail.sdg.ast.Attr) PrimSig(edu.mit.csail.sdg.ast.Sig.PrimSig)

Aggregations

PrimSig (edu.mit.csail.sdg.ast.Sig.PrimSig)34 Sig (edu.mit.csail.sdg.ast.Sig)14 Expr (edu.mit.csail.sdg.ast.Expr)10 SubsetSig (edu.mit.csail.sdg.ast.Sig.SubsetSig)9 ArrayList (java.util.ArrayList)8 Field (edu.mit.csail.sdg.ast.Sig.Field)6 ErrorFatal (edu.mit.csail.sdg.alloy4.ErrorFatal)5 HashMap (java.util.HashMap)5 TupleSet (kodkod.instance.TupleSet)5 ConstList (edu.mit.csail.sdg.alloy4.ConstList)4 ErrorSyntax (edu.mit.csail.sdg.alloy4.ErrorSyntax)4 LinkedHashMap (java.util.LinkedHashMap)4 List (java.util.List)4 Map (java.util.Map)4 Err (edu.mit.csail.sdg.alloy4.Err)3 ErrorType (edu.mit.csail.sdg.alloy4.ErrorType)3 Pos (edu.mit.csail.sdg.alloy4.Pos)3 SafeList (edu.mit.csail.sdg.alloy4.SafeList)3 ExprVar (edu.mit.csail.sdg.ast.ExprVar)3 A4Tuple (edu.mit.csail.sdg.translator.A4Tuple)3