Search in sources :

Example 6 with ExprVar

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

the class A4Solution method rename.

/**
 * Helper method that chooses a name for each atom based on its most specific
 * sig; (external caller should call this method with s==null and nexts==null)
 */
private static void rename(A4Solution frame, PrimSig s, Map<Sig, List<Tuple>> nexts, UniqueNameGenerator un) throws Err {
    if (s == null) {
        for (ExprVar sk : frame.skolems) un.seen(sk.label);
        // Store up the skolems
        List<Object> skolems = new ArrayList<Object>();
        for (Map.Entry<Relation, Type> e : frame.rel2type.entrySet()) {
            Relation r = e.getKey();
            if (!frame.eval.instance().contains(r))
                continue;
            Type t = e.getValue();
            if (t.arity() > r.arity())
                // Something is wrong; let's skip it
                continue;
            while (t.arity() < r.arity()) t = UNIV.type().product(t);
            String n = Util.tail(r.name());
            while (n.length() > 0 && n.charAt(0) == '$') n = n.substring(1);
            skolems.add(n);
            skolems.add(t);
            skolems.add(r);
        }
        // Find all suitable "next" or "prev" relations
        nexts = new LinkedHashMap<Sig, List<Tuple>>();
        for (Sig sig : frame.sigs) for (Field f : sig.getFields()) if (f.label.compareToIgnoreCase("next") == 0) {
            List<List<PrimSig>> fold = f.type().fold();
            if (fold.size() == 1) {
                List<PrimSig> t = fold.get(0);
                if (t.size() == 3 && t.get(0).isOne != null && t.get(1) == t.get(2) && !nexts.containsKey(t.get(1))) {
                    TupleSet set = frame.eval.evaluate(frame.a2k(t.get(1)));
                    if (set.size() <= 1)
                        continue;
                    TupleSet next = frame.eval.evaluate(frame.a2k(t.get(0)).join(frame.a2k(f)));
                    List<Tuple> test = isOrder(next, set);
                    if (test != null)
                        nexts.put(t.get(1), test);
                } else if (t.size() == 2 && t.get(0) == t.get(1) && !nexts.containsKey(t.get(0))) {
                    TupleSet set = frame.eval.evaluate(frame.a2k(t.get(0)));
                    if (set.size() <= 1)
                        continue;
                    TupleSet next = frame.eval.evaluate(frame.a2k(f));
                    List<Tuple> test = isOrder(next, set);
                    if (test != null)
                        nexts.put(t.get(1), test);
                }
            }
        }
        for (Sig sig : frame.sigs) for (Field f : sig.getFields()) if (f.label.compareToIgnoreCase("prev") == 0) {
            List<List<PrimSig>> fold = f.type().fold();
            if (fold.size() == 1) {
                List<PrimSig> t = fold.get(0);
                if (t.size() == 3 && t.get(0).isOne != null && t.get(1) == t.get(2) && !nexts.containsKey(t.get(1))) {
                    TupleSet set = frame.eval.evaluate(frame.a2k(t.get(1)));
                    if (set.size() <= 1)
                        continue;
                    TupleSet next = frame.eval.evaluate(frame.a2k(t.get(0)).join(frame.a2k(f)).transpose());
                    List<Tuple> test = isOrder(next, set);
                    if (test != null)
                        nexts.put(t.get(1), test);
                } else if (t.size() == 2 && t.get(0) == t.get(1) && !nexts.containsKey(t.get(0))) {
                    TupleSet set = frame.eval.evaluate(frame.a2k(t.get(0)));
                    if (set.size() <= 1)
                        continue;
                    TupleSet next = frame.eval.evaluate(frame.a2k(f).transpose());
                    List<Tuple> test = isOrder(next, set);
                    if (test != null)
                        nexts.put(t.get(1), test);
                }
            }
        }
        // Assign atom->name and atom->MostSignificantSig
        for (Tuple t : frame.eval.evaluate(Expression.INTS)) {
            frame.atom2sig.put(t.atom(0), SIGINT);
        }
        for (Tuple t : frame.eval.evaluate(KK_SEQIDX)) {
            frame.atom2sig.put(t.atom(0), SEQIDX);
        }
        for (Tuple t : frame.eval.evaluate(KK_STRING)) {
            frame.atom2sig.put(t.atom(0), STRING);
        }
        for (Sig sig : frame.sigs) if (sig instanceof PrimSig && !sig.builtin && ((PrimSig) sig).isTopLevel())
            rename(frame, (PrimSig) sig, nexts, un);
        // These are redundant atoms that were not chosen to be in the final
        // instance
        int unused = 0;
        for (Tuple tuple : frame.eval.evaluate(Expression.UNIV)) {
            Object atom = tuple.atom(0);
            if (!frame.atom2sig.containsKey(atom)) {
                frame.atom2name.put(atom, "unused" + unused);
                unused++;
            }
        }
        // Add the skolems
        for (int num = skolems.size(), i = 0; i < num - 2; i = i + 3) {
            String n = (String) skolems.get(i);
            while (n.length() > 0 && n.charAt(0) == '$') n = n.substring(1);
            Type t = (Type) skolems.get(i + 1);
            Relation r = (Relation) skolems.get(i + 2);
            frame.addSkolem(un.make("$" + n), t, r);
        }
        return;
    }
    for (PrimSig c : s.children()) rename(frame, c, nexts, un);
    String signame = un.make(s.label.startsWith("this/") ? s.label.substring(5) : s.label);
    List<Tuple> list = new ArrayList<Tuple>();
    for (Tuple t : frame.eval.evaluate(frame.a2k(s))) list.add(t);
    List<Tuple> order = nexts.get(s);
    if (order != null && order.size() == list.size() && order.containsAll(list)) {
        list = order;
    }
    int i = 0;
    for (Tuple t : list) {
        if (frame.atom2sig.containsKey(t.atom(0)))
            // This means one of the subsig has already claimed
            continue;
        // this atom.
        String x = signame + "$" + i;
        i++;
        frame.atom2sig.put(t.atom(0), s);
        frame.atom2name.put(t.atom(0), x);
        ExprVar v = ExprVar.make(null, x, s.type());
        TupleSet ts = t.universe().factory().range(t, t);
        Relation r = Relation.unary(x);
        frame.eval.instance().add(r, ts);
        frame.a2k.put(v, r);
        frame.atoms.add(v);
    }
}
Also used : ExprVar(edu.mit.csail.sdg.ast.ExprVar) TupleSet(kodkod.instance.TupleSet) ArrayList(java.util.ArrayList) PrimSig(edu.mit.csail.sdg.ast.Sig.PrimSig) Sig(edu.mit.csail.sdg.ast.Sig) Field(edu.mit.csail.sdg.ast.Sig.Field) Relation(kodkod.ast.Relation) Type(edu.mit.csail.sdg.ast.Type) SafeList(edu.mit.csail.sdg.alloy4.SafeList) List(java.util.List) ArrayList(java.util.ArrayList) ConstList(edu.mit.csail.sdg.alloy4.ConstList) ConstMap(edu.mit.csail.sdg.alloy4.ConstMap) Map(java.util.Map) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) PrimSig(edu.mit.csail.sdg.ast.Sig.PrimSig) Tuple(kodkod.instance.Tuple)

Example 7 with ExprVar

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

the class CompModule method addMacro.

// ============================================================================================================================//
/**
 * Add a MACRO declaration.
 */
void addMacro(Pos p, Pos isPrivate, String n, List<ExprVar> decls, Expr v) throws Err {
    if (!Version.experimental)
        throw new ErrorSyntax(p, "LET declaration is allowed only inside a toplevel paragraph.");
    ConstList<ExprVar> ds = ConstList.make(decls);
    status = 3;
    dup(p, n, false);
    for (int i = 0; i < ds.size(); i++) for (int j = i + 1; j < ds.size(); j++) if (ds.get(i).label.equals(ds.get(j).label))
        throw new ErrorSyntax(ds.get(j).span(), "The parameter name \"" + ds.get(j).label + "\" cannot appear more than once.");
    Macro ans = new Macro(p, isPrivate, this, n, ds, v);
    Macro old = macros.put(n, ans);
    if (old != null) {
        macros.put(n, old);
        throw new ErrorSyntax(p, "You cannot declare more than one macro with the same name \"" + n + "\" in the same file.");
    }
}
Also used : ExprVar(edu.mit.csail.sdg.ast.ExprVar) ErrorSyntax(edu.mit.csail.sdg.alloy4.ErrorSyntax)

Example 8 with ExprVar

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

the class CompModule method addEnum.

/**
 * Add an enumeration.
 */
void addEnum(Pos pos, Pos priv, ExprVar name, List<ExprVar> atoms, Pos closingBracket) throws Err {
    ExprVar EXTENDS = ExprVar.make(null, "extends");
    ExprVar THIS = ExprVar.make(null, "this/" + name);
    List<ExprVar> THESE = Arrays.asList(THIS);
    if (atoms == null || atoms.size() == 0)
        throw new ErrorSyntax(pos, "Enumeration must contain at least one name.");
    addSig(name.label, null, null, null, null, WHERE.make(name.pos), ABSTRACT.make(name.pos), PRIVATE.makenull(priv), Attr.ENUM);
    for (ExprVar a : atoms) addSig(a.label, EXTENDS, THESE, null, null, WHERE.make(a.pos), ONE.make(a.pos), PRIVATE.makenull(priv));
    int oldStatus = status;
    status = 0;
    try {
        addOpen(null, null, ExprVar.make(pos, "util/ordering"), Arrays.asList(THIS), null);
    } finally {
        status = oldStatus;
    }
}
Also used : ExprVar(edu.mit.csail.sdg.ast.ExprVar) ErrorSyntax(edu.mit.csail.sdg.alloy4.ErrorSyntax)

Example 9 with ExprVar

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

the class CompModule method addOpen.

/**
 * Add an OPEN declaration.
 */
void addOpen(Pos pos, Pos isPrivate, ExprVar name, List<ExprVar> args, ExprVar alias) throws Err {
    if (status > 2)
        throw new ErrorSyntax(pos, "The \"open\" declaration must occur before any\n" + "sig/pred/fun/fact/assert/check/run command.");
    String as = (alias == null ? "" : alias.label);
    if (name.label.length() == 0)
        throw new ErrorSyntax(name.span(), "The filename cannot be empty.");
    if (as.indexOf('$') >= 0)
        throw new ErrorSyntax(alias == null ? null : alias.span(), "Alias must not contain the \'$\' character");
    if (as.indexOf('@') >= 0)
        throw new ErrorSyntax(alias == null ? null : alias.span(), "Alias must not contain the \'@\' character");
    if (as.indexOf('/') >= 0)
        throw new ErrorSyntax(alias == null ? null : alias.span(), "Alias must not contain the \'/\' character");
    if (as.length() == 0) {
        as = "open$" + (1 + opens.size());
        if (args == null || args.size() == 0) {
            for (int i = 0; ; i++) {
                if (i >= name.label.length()) {
                    as = name.label;
                    break;
                }
                char c = name.label.charAt(i);
                if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'))
                    continue;
                if (i == 0)
                    break;
                if (!(c >= '0' && c <= '9') && c != '_' && c != '\'' && c != '\"')
                    break;
            }
        }
    }
    final TempList<String> newlist = new TempList<String>(args == null ? 0 : args.size());
    if (args != null)
        for (int i = 0; i < args.size(); i++) {
            ExprVar arg = args.get(i);
            if (arg.label.length() == 0)
                throw new ErrorSyntax(arg.span(), "Argument cannot be empty.");
            if (arg.label.indexOf('@') >= 0)
                throw new ErrorSyntax(arg.span(), "Argument cannot contain the \'@\' chracter.");
            newlist.add(arg.label);
        }
    Open x = opens.get(as);
    if (x != null) {
        // we allow this, especially because of util/sequniv
        if (x.args.equals(newlist.makeConst()) && x.filename.equals(name.label))
            return;
        throw new ErrorSyntax(pos, "You cannot import two different modules\n" + "using the same alias.");
    }
    List<Expr> expressions = new ArrayList<>(args == null ? Collections.emptySet() : args);
    expressions.add(0, name);
    expressions.add(alias);
    x = new Open(pos, isPrivate != null, as, newlist.makeConst(), name.label, expressions);
    opens.put(as, x);
}
Also used : ExprVar(edu.mit.csail.sdg.ast.ExprVar) ErrorSyntax(edu.mit.csail.sdg.alloy4.ErrorSyntax) TempList(edu.mit.csail.sdg.alloy4.ConstList.TempList) Expr(edu.mit.csail.sdg.ast.Expr) ArrayList(java.util.ArrayList)

Example 10 with ExprVar

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

Aggregations

ExprVar (edu.mit.csail.sdg.ast.ExprVar)22 Expr (edu.mit.csail.sdg.ast.Expr)11 Sig (edu.mit.csail.sdg.ast.Sig)11 PrimSig (edu.mit.csail.sdg.ast.Sig.PrimSig)8 ErrorSyntax (edu.mit.csail.sdg.alloy4.ErrorSyntax)7 Field (edu.mit.csail.sdg.ast.Sig.Field)7 SubsetSig (edu.mit.csail.sdg.ast.Sig.SubsetSig)5 Func (edu.mit.csail.sdg.ast.Func)4 ArrayList (java.util.ArrayList)4 HashMap (java.util.HashMap)4 LinkedHashMap (java.util.LinkedHashMap)4 TempList (edu.mit.csail.sdg.alloy4.ConstList.TempList)3 ErrorFatal (edu.mit.csail.sdg.alloy4.ErrorFatal)3 SafeList (edu.mit.csail.sdg.alloy4.SafeList)3 XMLNode (edu.mit.csail.sdg.alloy4.XMLNode)3 ExprHasName (edu.mit.csail.sdg.ast.ExprHasName)3 A4Solution (edu.mit.csail.sdg.translator.A4Solution)3 IOException (java.io.IOException)3 IdentityHashMap (java.util.IdentityHashMap)3 Map (java.util.Map)3