Package edu.mit.csail.sdg.alloy4compiler.ast

Examples of edu.mit.csail.sdg.alloy4compiler.ast.Func


        return true;
    }

    /** {@inheritDoc} */
    @Override public Object visit(ExprCall x) throws Err {
        final Func f = x.fun;
        final int n = f.count();
        final Object candidate = n==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.");
        for(Func ff:current_function) if (ff==f) throw new ErrorSyntax(x.span(), ""+f+" cannot call itself recursively!");
        Env<ExprVar,Object> newenv = new Env<ExprVar,Object>();
        List<SimTupleset> list = new ArrayList<SimTupleset>(x.args.size());
        for(int i=0; i<n; i++) { SimTupleset ts = cset(x.args.get(i)); newenv.put(f.get(i), ts);  list.add(ts); }
        final SimCallback cb = callbacks.get(f);
        if (cb!=null) {
           try {
              Object answer = cb.compute(f, list);
              if (answer!=null) {
                 if (x.args.size()==0) cacheForConstants.put(f, answer);
                 return answer;
              }
           } catch(Exception ex) {
              // if the callback failed, we can just continue with our original attempt to evaluate this call
           }
        }
        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 (f.count()==0) cacheForConstants.put(f, ans);
        return ans;
    }
View Full Code Here


        Expr g = A.addField("g", B);
        // The line above is the same as:   A.addField(null, "g", B.oneOf())  since B is unary.
        // If you want "setOf", you need:   A.addField(null, "g", B.setOf())

        // pred someG { some g }
        Func someG = new Func(null, "SomeG", null, null, g.some());

        // pred atMostThree[x:univ, y:univ] { #(x+y) >= 3 }
        Decl x = UNIV.oneOf("x");
        Decl y = UNIV.oneOf("y");
        Expr body = x.get().plus(y.get()).cardinality().lte(ExprConstant.makeNUMBER(3));
        Func atMost3 = new Func(null, "atMost3", Util.asList(x,y), null, body);

        List<Sig> sigs = Arrays.asList(new Sig[]{A, B, A1, A2});

        // run { some A && atMostThree[B,B] } for 3 but 3 int, 3 seq
        Expr expr1 = A.some().and(atMost3.call(B,B));
        Command cmd1 = new Command(false, 3, 3, 3, expr1);
        A4Solution sol1 = TranslateAlloyToKodkod.execute_command(NOP, sigs, cmd1, opt);
        System.out.println("[Solution1]:");
        System.out.println(sol1.toString());
View Full Code Here

     */
    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;
    }
View Full Code Here

    /** Caches parameter-less functions to a Kodkod Expression, Kodkod IntExpression, or Kodkod Formula. */
    private final Map<Func,Object> cacheForConstants = new IdentityHashMap<Func,Object>();

    /** {@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;
    }
View Full Code Here

         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;
View Full Code Here

      }
      status=3;
      dup(p, n, false);
      ExprHasName dup = Decl.findDuplicateName(decls);
      if (dup!=null) throw new ErrorSyntax(dup.span(), "The parameter name \""+dup.label+"\" cannot appear more than once.");
      Func ans = new Func(p, isPrivate, n, decls, t, v);
      ArrayList<Func> list = funcs.get(n);
      if (list==null) { list = new ArrayList<Func>(); funcs.put(n, list); }
      list.add(ans);
   }
View Full Code Here

   /** Each FunAST will now point to a bodyless Func object. */
   private JoinableList<Err> resolveFuncDecls(A4Reporter rep, JoinableList<Err> errors, List<ErrorWarning> warns) throws Err {
      for(ArrayList<Func> list: funcs.values()) {
         for(int listi=0; listi<list.size(); listi++) {
            Func f = list.get(listi);
            String fullname = (path.length()==0 ? "this/" : (path+"/")) + f.label;
            // Each PARAMETER can refer to earlier parameter in the same function, and any SIG or FIELD visible from here.
            // Each RETURNTYPE can refer to the parameters of the same function, and any SIG or FIELD visible from here.
            Context cx = new Context(this, warns);
            cx.rootfunparam = true;
            TempList<Decl> tmpdecls = new TempList<Decl>();
            boolean err = false;
            for(Decl d: f.decls) {
               TempList<ExprVar> tmpvars = new TempList<ExprVar>();
               Expr val = cx.check(d.expr).resolve_as_set(warns);
               if (!val.errors.isEmpty()) { err = true; errors = errors.make(val.errors); }
               for(ExprHasName n: d.names) {
                  ExprVar v = ExprVar.make(n.span(), n.label, val.type());
                  cx.put(n.label, v);
                  tmpvars.add(v);
                  rep.typecheck((f.isPred?"pred ":"fun ")+fullname+", Param "+n.label+": "+v.type()+"\n");
               }
               tmpdecls.add(new Decl(d.isPrivate, d.disjoint, d.disjoint2, tmpvars.makeConst(), val));
            }
            Expr ret = null;
            if (!f.isPred) {
               ret = cx.check(f.returnDecl).resolve_as_set(warns);
               if (!ret.errors.isEmpty()) { err = true; errors = errors.make(ret.errors); }
            }
            if (err) continue;
            try {
               f = new Func(f.pos, f.isPrivate, fullname, tmpdecls.makeConst(), ret, f.getBody());
               list.set(listi, f);
               rep.typecheck("" + f + ", RETURN: " + f.returnDecl.type() + "\n");
            } catch(Err ex) { errors = errors.make(ex); }
         }
      }
View Full Code Here

      } else {
         List<Object> m = getRawQS(4, cname); // We prefer fun/pred in the topmost module
         if (m.size()==0 && cname.indexOf('/')<0) m=getRawNQS(this, 4, cname);
         if (m.size()>1) unique(cmd.pos, cname, m);
         if (m.size()<1) throw new ErrorSyntax(cmd.pos, "The predicate/function \""+cname+"\" cannot be found.");
         Func f = (Func) (m.get(0));
         e = f.getBody();
         if (!f.isPred) e = e.in(f.returnDecl);
         if (f.decls.size()>0) e = ExprQt.Op.SOME.make(null, null, f.decls, e);
      }
      if (e==null) e = ExprConstant.TRUE;
      TempList<CommandScope> sc=new TempList<CommandScope>(cmd.scope.size());
View Full Code Here

            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);
               ch.add(fn==1 ? ExprCall.make(pos, null, f, t, 1+penalty) : ExprBadCall.make(pos, null, f, t, 1+penalty)); // 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);
            }
         }
      }
      // Within a field decl
      // (1) Can refer to any visible sig/param (but you cannot call any function or predicates)
      // (2) Can refer to field in this sig (defined earlier than you), and fields in any visible ancestor sig
      // Within an appended facts
      // (1) Can refer to any visible sig/param/func/predicate
      // (2) Can refer to any visible field
      // Within a function paramDecl/returnDecl
      // (1) Cannot call
      // (2) But can refer to anything else visible.
      // 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);
View Full Code Here

TOP

Related Classes of edu.mit.csail.sdg.alloy4compiler.ast.Func

Copyright © 2018 www.massapicom. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.