Search in sources :

Example 11 with Func

use of edu.mit.csail.sdg.ast.Func 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 12 with Func

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

the class CompModule method unique.

/**
 * Throw an exception if there are more than 1 match; return nonnull if only one
 * match; return null if no match.
 */
private Object unique(Pos pos, String name, List<Object> objs) throws Err {
    if (objs.size() == 0)
        return null;
    if (objs.size() == 1)
        return objs.get(0);
    StringBuilder msg = new StringBuilder("The name \"").append(name);
    msg.append("\" is ambiguous.\n" + "There are ").append(objs.size()).append(" choices:");
    for (int i = 0; i < objs.size(); i++) {
        msg.append("\n\n#").append(i + 1).append(": ");
        Object x = objs.get(i);
        if (x instanceof Sig) {
            Sig y = (Sig) x;
            msg.append("sig ").append(y.label).append("\n" + "at ").append(y.pos.toShortString());
        } else if (x instanceof Func) {
            Func y = (Func) x;
            msg.append(y.isPred ? "pred " : "fun ").append(y.label).append("\n" + "at ").append(y.pos.toShortString());
        } else if (x instanceof Expr) {
            Expr y = (Expr) x;
            msg.append("assertion at ").append(y.pos.toShortString());
        }
    }
    throw new ErrorSyntax(pos, msg.toString());
}
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) ErrorSyntax(edu.mit.csail.sdg.alloy4.ErrorSyntax) Expr(edu.mit.csail.sdg.ast.Expr) Func(edu.mit.csail.sdg.ast.Func)

Example 13 with Func

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

the class A4Solution method highLevelCore.

/**
 * If this solution is unsatisfiable and its unsat core is available, then
 * return the core; else return an empty set.
 */
public Pair<Set<Pos>, Set<Pos>> highLevelCore() {
    if (hCoreCache != null)
        return hCoreCache;
    Set<Pos> ans1 = new LinkedHashSet<Pos>(), ans2 = new LinkedHashSet<Pos>();
    if (hCore != null)
        for (Node f : hCore) {
            Object x = k2pos(f);
            if (x instanceof Pos) {
                // System.out.println("F: "+f+" at "+x+"\n");
                // System.out.flush();
                ans1.add((Pos) x);
            } else if (x instanceof Expr) {
                Expr expr = (Expr) x;
                Pos p = ((Expr) x).span();
                ans1.add(p);
                // System.out.flush();
                for (Func func : expr.findAllFunctions()) ans2.add(func.getBody().span());
            }
        }
    return hCoreCache = new Pair<Set<Pos>, Set<Pos>>(Collections.unmodifiableSet(ans1), Collections.unmodifiableSet(ans2));
}
Also used : LinkedHashSet(java.util.LinkedHashSet) Set(java.util.Set) LinkedHashSet(java.util.LinkedHashSet) TupleSet(kodkod.instance.TupleSet) Expr(edu.mit.csail.sdg.ast.Expr) Pos(edu.mit.csail.sdg.alloy4.Pos) Func(edu.mit.csail.sdg.ast.Func) Node(kodkod.ast.Node)

Example 14 with Func

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

the class TranslateAlloyToKodkod method skolem.

// ==============================================================================================================//
/**
 * Given a variable name "name", prepend the current function name to form a
 * meaningful "skolem name". (Note: this function does NOT, and need NOT
 * guarantee that the name it generates is unique)
 */
private String skolem(String name) {
    if (current_function.size() == 0) {
        if (cmd != null && cmd.label.length() > 0 && cmd.label.indexOf('$') < 0)
            return cmd.label + "_" + name;
        else
            return name;
    }
    Func last = current_function.get(current_function.size() - 1);
    String funcname = tail(last.label);
    if (funcname.indexOf('$') < 0)
        return funcname + "_" + name;
    else
        return name;
}
Also used : Func(edu.mit.csail.sdg.ast.Func)

Example 15 with Func

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

the class TranslateAlloyToKodkod method visit.

/**
 * {@inheritDoc}
 */
@Override
public Object visit(ExprCall x) throws Err {
    final Func f = x.fun;
    final Object candidate = f.count() == 0 ? cacheForConstants.get(f) : null;
    if (candidate != null)
        return candidate;
    final Expr body = f.getBody();
    if (body.type().arity() < 0 || body.type().arity() != f.returnDecl.type().arity())
        throw new ErrorType(body.span(), "Function return value not fully resolved.");
    final int n = f.count();
    int maxRecursion = unrolls;
    for (Func ff : current_function) if (ff == f) {
        if (maxRecursion < 0) {
            throw new ErrorSyntax(x.span(), "" + f + " cannot call itself recursively!");
        }
        if (maxRecursion == 0) {
            Type t = f.returnDecl.type();
            if (t.is_bool)
                return Formula.FALSE;
            if (t.is_int())
                return IntConstant.constant(0);
            int i = t.arity();
            Expression ans = Expression.NONE;
            while (i > 1) {
                ans = ans.product(Expression.NONE);
                i--;
            }
            return ans;
        }
        maxRecursion--;
    }
    Env<ExprVar, Object> newenv = new Env<ExprVar, Object>();
    for (int i = 0; i < n; i++) newenv.put(f.get(i), cset(x.args.get(i)));
    Env<ExprVar, Object> oldenv = env;
    env = newenv;
    current_function.add(f);
    Object ans = visitThis(body);
    env = oldenv;
    current_function.remove(current_function.size() - 1);
    if (ans instanceof Formula)
        k2pos((Formula) ans, x);
    if (f.count() == 0)
        cacheForConstants.put(f, ans);
    return ans;
}
Also used : ExprVar(edu.mit.csail.sdg.ast.ExprVar) QuantifiedFormula(kodkod.ast.QuantifiedFormula) Formula(kodkod.ast.Formula) ErrorSyntax(edu.mit.csail.sdg.alloy4.ErrorSyntax) Type(edu.mit.csail.sdg.ast.Type) ErrorType(edu.mit.csail.sdg.alloy4.ErrorType) Expr(edu.mit.csail.sdg.ast.Expr) ErrorType(edu.mit.csail.sdg.alloy4.ErrorType) Func(edu.mit.csail.sdg.ast.Func) Expression(kodkod.ast.Expression) BinaryExpression(kodkod.ast.BinaryExpression) IntExpression(kodkod.ast.IntExpression) Env(edu.mit.csail.sdg.alloy4.Env)

Aggregations

Func (edu.mit.csail.sdg.ast.Func)15 Expr (edu.mit.csail.sdg.ast.Expr)12 Sig (edu.mit.csail.sdg.ast.Sig)7 PrimSig (edu.mit.csail.sdg.ast.Sig.PrimSig)6 ErrorSyntax (edu.mit.csail.sdg.alloy4.ErrorSyntax)5 Decl (edu.mit.csail.sdg.ast.Decl)5 SubsetSig (edu.mit.csail.sdg.ast.Sig.SubsetSig)5 Command (edu.mit.csail.sdg.ast.Command)4 ExprHasName (edu.mit.csail.sdg.ast.ExprHasName)4 ExprVar (edu.mit.csail.sdg.ast.ExprVar)4 ArrayList (java.util.ArrayList)4 Err (edu.mit.csail.sdg.alloy4.Err)3 TempList (edu.mit.csail.sdg.alloy4.ConstList.TempList)2 Env (edu.mit.csail.sdg.alloy4.Env)2 ErrorType (edu.mit.csail.sdg.alloy4.ErrorType)2 ErrorWarning (edu.mit.csail.sdg.alloy4.ErrorWarning)2 Pos (edu.mit.csail.sdg.alloy4.Pos)2 A4Options (edu.mit.csail.sdg.translator.A4Options)2 A4Solution (edu.mit.csail.sdg.translator.A4Solution)2 ConstList (edu.mit.csail.sdg.alloy4.ConstList)1