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

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


   /** Add an ASSERT declaration. */
   String addAssertion(Pos pos, String name, Expr value) throws Err {
      status=3;
      if (name==null || name.length()==0) name="assert$"+(1+asserts.size());
      dup(pos, name, false);
      Expr old = asserts.put(name, ExprUnary.Op.NOOP.make(value.span().merge(pos), value));
      if (old!=null) {
         asserts.put(name, old);
         throw new ErrorSyntax(pos, "\""+name+"\" is already the name of an assertion in this module.");
      }
      return name;
View Full Code Here


   /** Each assertion name now points to a typechecked Expr rather than an untypechecked Exp. */
   private JoinableList<Err> resolveAssertions(A4Reporter rep, JoinableList<Err> errors, List<ErrorWarning> warns) throws Err {
      Context cx = new Context(this, warns);
      for(Map.Entry<String,Expr> e: asserts.entrySet()) {
         Expr expr = e.getValue();
         expr = cx.check(expr).resolve_as_formula(warns);
         if (expr.errors.isEmpty()) {
            e.setValue(expr);
            rep.typecheck("Assertion " + e.getKey() + ": " + expr.type()+"\n");
         } else errors = errors.make(expr.errors);
      }
      return errors;
   }
View Full Code Here

   /** Each fact name now points to a typechecked Expr rather than an untypechecked Exp; we'll also add the sig appended facts. */
   private JoinableList<Err> resolveFacts(CompModule res, A4Reporter rep, JoinableList<Err> errors, List<ErrorWarning> warns) throws Err {
      Context cx = new Context(this, warns);
      for(int i=0; i<facts.size(); i++) {
         String name = facts.get(i).a;
         Expr expr = facts.get(i).b;
         expr = cx.check(expr).resolve_as_formula(warns);
         if (expr.errors.isEmpty()) {
            facts.set(i, new Pair<String,Expr>(name, expr));
            rep.typecheck("Fact " + name + ": " + expr.type()+"\n");
         } else errors = errors.make(expr.errors);
      }
      for(Sig s: sigs.values()) {
         Expr f = res.old2appendedfacts.get(res.new2old.get(s));
         if (f == null) continue;
         if (f instanceof ExprConstant && ((ExprConstant)f).op==ExprConstant.Op.TRUE) continue;
         Expr formula;
         cx.rootsig = s;
         if (s.isOne==null) {
            cx.put("this", s.decl.get());
            formula = cx.check(f).resolve_as_formula(warns);
         } else {
            cx.put("this", s);
            formula = cx.check(f).resolve_as_formula(warns);
         }
         cx.remove("this");
         if (formula.errors.size()>0) errors = errors.make(formula.errors); else { s.addFact(formula);  rep.typecheck("Fact "+s+"$fact: " + formula.type()+"\n")}
      }
      return errors;
   }
View Full Code Here

   /** Resolve a particular command. */
   private Command resolveCommand(Command cmd, ConstList<Sig> exactSigs, Expr globalFacts) throws Err {
      Command parent = cmd.parent==null ? null : resolveCommand(cmd.parent, exactSigs, globalFacts);
      String cname = ((ExprVar)(cmd.formula)).label;
      Expr e;
      if (cmd.check) {
         List<Object> m = getRawQS(2, cname); // We prefer assertion in the topmost module
         if (m.size()==0 && cname.indexOf('/')<0) m=getRawNQS(this, 2, cname);
         if (m.size()>1) unique(cmd.pos, cname, m);
         if (m.size()<1) throw new ErrorSyntax(cmd.pos, "The assertion \""+cname+"\" cannot be found.");
         e = ((Expr)(m.get(0))).not();
      } 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());
      for(CommandScope et: cmd.scope) {
View Full Code Here

         if (d.expr.mult()!=ExprUnary.Op.EXACTLYOF) {if (defined) continue;} else {if (!defined) continue;}
         // The name "this" does matter, since the parser and the typechecker both refer to it as "this"
         cx.rootfield = d;
         cx.rootsig = s;
         cx.put("this", s.decl.get());
         Expr bound = cx.check(d.expr).resolve_as_set(warns);
         cx.remove("this");
         String[] names = new String[d.names.size()]for(int i=0; i<names.length; i++) names[i] = d.names.get(i).label;
         Field[] fields = s.addTrickyField(d.span(), d.isPrivate, d.disjoint, d.disjoint2, null, names, bound);
         for(Field f: fields) {
            rep.typecheck("Sig "+s+", Field "+f.label+": "+f.type()+"\n");
View Full Code Here

         sig2meta.put(s, ka);
         ka.addDefinedField(Pos.UNKNOWN, null, Pos.UNKNOWN, "value", s);
         m.new2old.put(ka, ka);
         m.sigs.put(base(ka), ka);
         hasMetaSig = true;
         Expr allfields = ExprConstant.EMPTYNESS;
         for(Field field: s.getFields()) {
            Pos priv = field.isPrivate; if (priv==null) priv = s.isPrivate;
            PrimSig kb = new PrimSig(s.label+"$"+field.label, root.metaField, Attr.ONE, PRIVATE.makenull(priv), Attr.META);
            field2meta.put(field, kb);
            m.new2old.put(kb, kb);
            m.sigs.put(base(kb), kb);
            hasMetaField = true;
            kb.addDefinedField(Pos.UNKNOWN, null, Pos.UNKNOWN, "value", field);
            if (allfields==ExprConstant.EMPTYNESS) allfields = kb; else allfields = allfields.plus(kb);
         }
         ka.addDefinedField(Pos.UNKNOWN, null, Pos.UNKNOWN, "fields", allfields);
      }
      for(Map.Entry<Sig,PrimSig> e: sig2meta.entrySet()) {
         Expr expr = null;
         if ((e.getKey()) instanceof PrimSig) {
            PrimSig a = (PrimSig)(e.getKey());
            if (a.parent!=null && a.parent!=UNIV) expr = sig2meta.get(a.parent);
         }
         e.getValue().addDefinedField(Pos.UNKNOWN, null, Pos.UNKNOWN, "parent", (expr==null ? ExprConstant.EMPTYNESS : expr));
      }
      for(Map.Entry<Sig,PrimSig> e: sig2meta.entrySet()) {
         Sig s = e.getKey();
         PrimSig s2 = e.getValue();
         Expr allfields = ExprConstant.EMPTYNESS;
         for(Field f: s.getFields()) {
            PrimSig metaF = field2meta.get(f);
            if (allfields==ExprConstant.EMPTYNESS) allfields = metaF; else allfields = allfields.plus(metaF);
         }
         if (s instanceof PrimSig) for(Sig c: (((PrimSig)s).descendents())) for(Field f: c.getFields()) {
            PrimSig metaF = field2meta.get(f);
            if (allfields==ExprConstant.EMPTYNESS) allfields = metaF; else allfields = allfields.plus(metaF);
         }
         s2.addDefinedField(Pos.UNKNOWN, null, Pos.UNKNOWN, "subfields", allfields);
      }
      if (hasMetaSig==false) root.facts.add(new Pair<String,Expr>("sig$fact", root.metaSig.no().and(root.metaField.no())));
      else if (hasMetaField==false) root.facts.add(new Pair<String,Expr>("sig$fact", root.metaField.no()));
View Full Code Here

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

      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);
               // Given the above, we can be sure that every column is well-bounded (except possibly the first column).
               // Thus, we need to add a bound that the first column is a 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(Relation.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);
View Full Code Here

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

    /* Evaluates an ExprBinary node. */
    /*===============================*/

    /** {@inheritDoc} */
    @Override public Object visit(ExprBinary x) throws Err {
        Expr a=x.left, b=x.right;
        Expression s, s2; IntExpression i; Formula f; Object obj;
        switch(x.op) {
            case IMPLIES: f=cform(a).not().or(cform(b)); return k2pos(f,x);
            case IN:      return k2pos(isIn(cset(a),b), x);
            case NOT_IN:  return k2pos(isIn(cset(a),b).not(), x);
            case LT:  i=cint(a);  f=i.lt(cint(b));   return k2pos(f,x);
            case LTE: i=cint(a);  f=i.lte(cint(b))return k2pos(f,x);
            case GT:  i=cint(a);  f=i.gt(cint(b));   return k2pos(f,x);
            case GTE: i=cint(a);  f=i.gte(cint(b))return k2pos(f,x);
            case NOT_LT:  i=cint(a);  f=i.lt(cint(b)).not();   return k2pos(f,x);
            case NOT_LTE: i=cint(a);  f=i.lte(cint(b)).not()return k2pos(f,x);
            case NOT_GT:  i=cint(a);  f=i.gt(cint(b)).not();   return k2pos(f,x);
            case NOT_GTE: i=cint(a);  f=i.gte(cint(b)).not()return k2pos(f,x);
            case AND: f=cform(a); f=f.and(cform(b)); return k2pos(f,x);
            case OR:  f=cform(a); f=f.or(cform(b))return k2pos(f,x);
            case IFF: f=cform(a); f=f.iff(cform(b)); return k2pos(f,x);
            case PLUSPLUS: s=cset(a); return s.override(cset(b));
            case MUL: i=cint(a); return i.multiply(cint(b));
            case DIV: i=cint(a); return i.divide(cint(b));
            case REM: i=cint(a); return i.modulo(cint(b));
            case SHL: i=cint(a); return i.shl(cint(b));
            case SHR: i=cint(a); return i.shr(cint(b));
            case SHA: i=cint(a); return i.sha(cint(b));
            case PLUS:
                obj = visitThis(a);
                if (obj instanceof IntExpression) { i=(IntExpression)obj; return i.plus(cint(b)); }
                s = (Expression)obj; return s.union(cset(b));
            case MINUS:
                // Special exception to allow "0-8" to not throw an exception, where 7 is the maximum allowed integer (when bitwidth==4)
                // (likewise, when bitwidth==5, then +15 is the maximum allowed integer, and we want to allow 0-16 without throwing an exception)
                if (a instanceof ExprConstant && ((ExprConstant)a).op==ExprConstant.Op.NUMBER && ((ExprConstant)a).num()==0)
                   if (b instanceof ExprConstant && ((ExprConstant)b).op==ExprConstant.Op.NUMBER && ((ExprConstant)b).num()==max+1)
                      return IntConstant.constant(min);
                obj=visitThis(a);
                if (obj instanceof IntExpression) { i=(IntExpression)obj; return i.minus(cint(b));}
                s=(Expression)obj; return s.difference(cset(b));
            case INTERSECT:
                s=cset(a); return s.intersection(cset(b));
            case ANY_ARROW_SOME: case ANY_ARROW_ONE: case ANY_ARROW_LONE:
            case SOME_ARROW_ANY: case SOME_ARROW_SOME: case SOME_ARROW_ONE: case SOME_ARROW_LONE:
            case ONE_ARROW_ANY: case ONE_ARROW_SOME: case ONE_ARROW_ONE: case ONE_ARROW_LONE:
            case LONE_ARROW_ANY: case LONE_ARROW_SOME: case LONE_ARROW_ONE: case LONE_ARROW_LONE:
            case ISSEQ_ARROW_LONE:
            case ARROW:
                s=cset(a); return s.product(cset(b));
            case JOIN:
                a=a.deNOP(); s=cset(a); s2=cset(b);
                if (a instanceof Sig && ((Sig)a).isOne!=null && s2 instanceof BinaryExpression) {
                    BinaryExpression bin = (BinaryExpression)s2;
                    if (bin.op()==ExprOperator.PRODUCT && bin.left()==s) return bin.right();
                }
                return s.join(s2);
View Full Code Here

TOP

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

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.