Example #1
0
 public virtual ExistsExpr VisitExistsExpr(ExistsExpr node)
 {
     Contract.Requires(node != null);
     Contract.Ensures(Contract.Result <ExistsExpr>() != null);
     node = (ExistsExpr)this.VisitQuantifierExpr(node);
     return(node);
 }
Example #2
0
        public Expr DisjointnessExpr(string domainName, HashSet <Variable> scope)
        {
            LinearDomain  domain    = linearDomains[domainName];
            BoundVariable partition = new BoundVariable(Token.NoToken, new TypedIdent(Token.NoToken, string.Format("partition_{0}", domainName), new MapType(Token.NoToken, new List <TypeVariable>(), new List <Type> {
                domain.elementType
            }, Microsoft.Boogie.Type.Int)));
            Expr disjointExpr = Expr.True;
            int  count        = 0;

            foreach (Variable v in scope)
            {
                IdentifierExpr ie = new IdentifierExpr(Token.NoToken, v);
                Expr           e  = new NAryExpr(Token.NoToken, new FunctionCall(domain.mapConstInt), new List <Expr> {
                    new LiteralExpr(Token.NoToken, Microsoft.Basetypes.BigNum.FromInt(count++))
                });
                e = new NAryExpr(Token.NoToken, new FunctionCall(domain.mapEqInt), new List <Expr> {
                    new IdentifierExpr(Token.NoToken, partition), e
                });
                e = new NAryExpr(Token.NoToken, new FunctionCall(domain.mapImpBool), new List <Expr> {
                    v.TypedIdent.Type is MapType ? ie : Singleton(ie, domainName), e
                });
                e = Expr.Binary(BinaryOperator.Opcode.Eq, e, new NAryExpr(Token.NoToken, new FunctionCall(domain.mapConstBool), new List <Expr> {
                    Expr.True
                }));
                disjointExpr = Expr.Binary(BinaryOperator.Opcode.And, e, disjointExpr);
            }
            var expr = new ExistsExpr(Token.NoToken, new List <Variable> {
                partition
            }, disjointExpr);

            expr.Resolve(new ResolutionContext(null));
            expr.Typecheck(new TypecheckingContext(null));
            return(expr);
        }
Example #3
0
            private Expr CalculatePathCondition(PathInfo path)
            {
                Expr returnExpr = Expr.True;

                HashSet <Variable>          existsVars = path.existsVars;
                Dictionary <Variable, Expr> existsMap  = new Dictionary <Variable, Expr>();

                Dictionary <Variable, Expr> varToExpr = path.varToExpr;

                foreach (Variable v in varToExpr.Keys)
                {
                    if (postExistVars.Contains(v))
                    {
                        continue;
                    }
                    IdentifierExpr ie = varToExpr[v] as IdentifierExpr;
                    if (ie != null && !existsMap.ContainsKey(ie.Decl) && existsVars.Contains(ie.Decl))
                    {
                        existsMap[ie.Decl] = Expr.Ident(v);
                        existsVars.Remove(ie.Decl);
                    }
                    else
                    {
                        returnExpr      = Expr.And(returnExpr, Expr.Eq(Expr.Ident(v), (new MyDuplicator()).VisitExpr(varToExpr[v])));
                        returnExpr.Type = Type.Bool;
                    }
                }

                List <Expr> pathExprs = new List <Expr>();

                path.pathExprs.ForEach(x => pathExprs.Add((new MyDuplicator()).VisitExpr(x)));
                foreach (Expr x in pathExprs)
                {
                    Variable boundVar;
                    Expr     boundVarExpr;
                    if (InferSubstitution(x, out boundVar, out boundVarExpr) && existsVars.Contains(boundVar))
                    {
                        existsMap[boundVar] = boundVarExpr;
                        existsVars.Remove(boundVar);
                    }
                    else
                    {
                        returnExpr      = Expr.And(returnExpr, x);
                        returnExpr.Type = Type.Bool;
                    }
                }

                returnExpr = Substituter.Apply(Substituter.SubstitutionFromHashtable(existsMap), returnExpr);
                if (existsVars.Count > 0)
                {
                    returnExpr = new ExistsExpr(Token.NoToken, new List <Variable>(existsVars), returnExpr);
                }
                return(returnExpr);
            }
Example #4
0
    public Expr DisjointnessExprForPermissions(string domainName, IEnumerable<Expr> permissionsExprs)
    {
      Expr expr = Expr.True;
      if (permissionsExprs.Count() > 1)
      {
        int count = 0;
        List<Expr> subsetExprs = new List<Expr>();
        LinearDomain domain = linearDomains[domainName];
        BoundVariable partition = new BoundVariable(Token.NoToken,
          new TypedIdent(Token.NoToken, $"partition_{domainName}", domain.mapTypeInt));
        foreach (Expr e in permissionsExprs)
        {
          subsetExprs.Add(SubsetExpr(domain, e, partition, count));
          count++;
        }

        expr = new ExistsExpr(Token.NoToken, new List<Variable> {partition}, Expr.And(subsetExprs));
      }

      expr.Resolve(new ResolutionContext(null));
      expr.Typecheck(new TypecheckingContext(null));
      return expr;
    }
Example #5
0
 void PrintExistentialGuard(ExistsExpr guard) {
   Contract.Requires(guard != null);
   Contract.Requires(guard.Range == null);
   PrintQuantifierDomain(guard.BoundVars, guard.Attributes, null);
   wr.Write(" :| ");
   PrintExpression(guard.Term, false);
 }
Example #6
0
            public override QuantifierExpr VisitQuantifierExpr(QuantifierExpr node)
            {
                var oldE = existentialExpr;

                if (node is ExistsExpr)
                    existentialExpr = (node as ExistsExpr);

                node = base.VisitQuantifierExpr(node);

                existentialExpr = oldE;
                return node;
            }
Example #7
0
 public FunctionCollector()
 {
     functionsUsed = new List<Tuple<Function, ExistsExpr>>();
     existentialExpr = null;
 }
Example #8
0
 public override ExistsExpr VisitExistsExpr(ExistsExpr node)
 {
     //Contract.Requires(node != null);
     Contract.Ensures(Contract.Result <ExistsExpr>() != null);
     return(base.VisitExistsExpr((ExistsExpr)node.Clone()));
 }
Example #9
0
    public void SimpleExists() {
      var boundVar = new BoundVariable(Token.NoToken, new TypedIdent(Token.NoToken,"foo",Microsoft.Boogie.Type.Bool));
      var id = new IdentifierExpr(Token.NoToken, boundVar);
      var exists = new ExistsExpr(Token.NoToken, new List<Variable>() { boundVar }, id);

      var id2 = new IdentifierExpr(Token.NoToken, boundVar);
      var exists2 = new ExistsExpr(Token.NoToken, new List<Variable>() { boundVar }, id2);

      Assert.AreNotSame(exists, exists2); // These are different references

      Assert.IsTrue(exists.Equals(exists2)); // These are "structurally equal"
      Assert.AreEqual(exists.GetHashCode(), exists2.GetHashCode()); // If the .Equals() is true then hash codes must be the same
    }
Example #10
0
        protected override Cmd ComputeDesugaring()
        {
            Contract.Ensures(Contract.Result<Cmd>() != null);
              List<Cmd> newBlockBody = new List<Cmd>();
              Dictionary<Variable, Expr> substMap = new Dictionary<Variable, Expr>();
              Dictionary<Variable, Expr> substMapOld = new Dictionary<Variable, Expr>();
              Dictionary<Variable, Expr> substMapBound = new Dictionary<Variable, Expr>();
              List<Variable>/*!*/ tempVars = new List<Variable>();

              // proc P(ins) returns (outs)
              //   requires Pre
              //   //modifies frame
              //   ensures Post
              //
              // call aouts := P(ains)

              // ins    : formal in parameters of procedure
              // frame  : a list of global variables from the modifies clause
              // outs   : formal out parameters of procedure
              // ains   : actual in arguments passed to call
              // aouts  : actual variables assigned to from call
              // cins   : new variables created just for this call, one per ains
              // cframe : new variables created just for this call, to keep track of OLD values
              // couts  : new variables created just for this call, one per aouts
              // WildcardVars : new variables created just for this call, one per null in ains

              #region Create cins; each one is an incarnation of the corresponding in parameter
              List<Variable>/*!*/ cins = new List<Variable>();
              List<Variable> wildcardVars = new List<Variable>();
              Contract.Assume(this.Proc != null);
              for (int i = 0; i < this.Proc.InParams.Count; ++i) {
            Variable/*!*/ param = cce.NonNull(this.Proc.InParams[i]);
            bool isWildcard = this.Ins[i] == null;

            Type/*!*/ actualType;
            if (isWildcard)
              actualType = param.TypedIdent.Type.Substitute(TypeParamSubstitution());
            else
              // during type checking, we have ensured that the type of the actual
              // parameter Ins[i] is correct, so we can use it here
              actualType = cce.NonNull(cce.NonNull(Ins[i]).Type);

            Variable cin = CreateTemporaryVariable(tempVars, param, actualType,
                                               TempVarKind.Formal);
            cins.Add(cin);
            IdentifierExpr ie = new IdentifierExpr(cin.tok, cin);
            substMap.Add(param, ie);
            if (isWildcard) {
              cin = CreateTemporaryVariable(tempVars, param,
                                        actualType, TempVarKind.Bound);
              wildcardVars.Add(cin);
              ie = new IdentifierExpr(cin.tok, cin);
            }
            substMapBound.Add(param, ie);
              }
              #endregion
              #region call aouts := P(ains) becomes: (open outlining one level to see)
              #region cins := ains (or havoc cin when ain is null)
              for (int i = 0, n = this.Ins.Count; i < n; i++) {
            IdentifierExpr/*!*/ cin_exp = new IdentifierExpr(cce.NonNull(cins[i]).tok, cce.NonNull(cins[i]));
            Contract.Assert(cin_exp != null);
            if (this.Ins[i] != null) {
              AssignCmd assign = Cmd.SimpleAssign(Token.NoToken, cin_exp, cce.NonNull(this.Ins[i]));
              newBlockBody.Add(assign);
            } else {
              List<IdentifierExpr>/*!*/ ies = new List<IdentifierExpr>();
              ies.Add(cin_exp);
              HavocCmd havoc = new HavocCmd(Token.NoToken, ies);
              newBlockBody.Add(havoc);
            }
              }
              #endregion

              #region assert (exists wildcardVars :: Pre[ins := cins])
              Substitution s = Substituter.SubstitutionFromHashtable(substMapBound);
              bool hasWildcard = (wildcardVars.Count != 0);
              Expr preConjunction = null;
              for (int i = 0; i < this.Proc.Requires.Count; i++) {
            Requires/*!*/ req = cce.NonNull(this.Proc.Requires[i]);
            if (!req.Free && !IsFree) {
              if (hasWildcard) {
            Expr pre = Substituter.Apply(s, req.Condition);
            if (preConjunction == null) {
              preConjunction = pre;
            } else {
              preConjunction = Expr.And(preConjunction, pre);
            }
              } else {
            Requires/*!*/ reqCopy = (Requires/*!*/)cce.NonNull(req.Clone());
            reqCopy.Condition = Substituter.Apply(s, req.Condition);
            AssertCmd/*!*/ a = new AssertRequiresCmd(this, reqCopy);
            Contract.Assert(a != null);
            a.ErrorDataEnhanced = reqCopy.ErrorDataEnhanced;
            newBlockBody.Add(a);
              }
            }
            else if (CommandLineOptions.Clo.StratifiedInlining > 0)
            {
            // inject free requires as assume statements at the call site
            AssumeCmd/*!*/ a = new AssumeCmd(req.tok, Substituter.Apply(s, req.Condition));
            Contract.Assert(a != null);
            newBlockBody.Add(a);
            }
              }
              if (hasWildcard) {
            if (preConjunction == null) {
              preConjunction = Expr.True;
            }
            Expr/*!*/ expr = new ExistsExpr(tok, wildcardVars, preConjunction);
            Contract.Assert(expr != null);
            AssertCmd/*!*/ a = new AssertCmd(tok, expr);
            Contract.Assert(a != null);
            a.ErrorDataEnhanced = AssertCmd.GenerateBoundVarMiningStrategy(expr);
            newBlockBody.Add(a);
              }
              #endregion

              #region assume Pre[ins := cins] with formal paramters
              if (hasWildcard) {
            s = Substituter.SubstitutionFromHashtable(substMap);
            for (int i = 0; i < this.Proc.Requires.Count; i++) {
              Requires/*!*/ req = cce.NonNull(this.Proc.Requires[i]);
              if (!req.Free) {
            Requires/*!*/ reqCopy = (Requires/*!*/)cce.NonNull(req.Clone());
            reqCopy.Condition = Substituter.Apply(s, req.Condition);
            AssumeCmd/*!*/ a = new AssumeCmd(tok, reqCopy.Condition);
            Contract.Assert(a != null);
            newBlockBody.Add(a);
              }
            }
              }
              #endregion

              #region cframe := frame (to hold onto frame values in case they are referred to in the postcondition)
              List<IdentifierExpr> havocVarExprs = new List<IdentifierExpr>();

              foreach (IdentifierExpr/*!*/ f in this.Proc.Modifies) {
            Contract.Assert(f != null);
            Contract.Assume(f.Decl != null);
            Contract.Assert(f.Type != null);
            Variable v = CreateTemporaryVariable(tempVars, f.Decl, f.Type, TempVarKind.Old);
            IdentifierExpr v_exp = new IdentifierExpr(v.tok, v);
            substMapOld.Add(f.Decl, v_exp);  // this assumes no duplicates in this.Proc.Modifies
            AssignCmd assign = Cmd.SimpleAssign(f.tok, v_exp, f);
            newBlockBody.Add(assign);

            // fra
            if (!havocVarExprs.Contains(f))
              havocVarExprs.Add(f);
              }
              #endregion
              #region Create couts
              List<Variable>/*!*/ couts = new List<Variable>();
              for (int i = 0; i < this.Proc.OutParams.Count; ++i) {
            Variable/*!*/ param = cce.NonNull(this.Proc.OutParams[i]);
            bool isWildcard = this.Outs[i] == null;

            Type/*!*/ actualType;
            if (isWildcard)
              actualType = param.TypedIdent.Type.Substitute(TypeParamSubstitution());
            else
              // during type checking, we have ensured that the type of the actual
              // out parameter Outs[i] is correct, so we can use it here
              actualType = cce.NonNull(cce.NonNull(Outs[i]).Type);

            Variable cout = CreateTemporaryVariable(tempVars, param, actualType,
                                                TempVarKind.Formal);
            couts.Add(cout);
            IdentifierExpr ie = new IdentifierExpr(cout.tok, cout);
            substMap.Add(param, ie);

            if (!havocVarExprs.Contains(ie))
              havocVarExprs.Add(ie);
              }
              // add the where clauses, now that we have the entire substitution map
              foreach (Variable/*!*/ param in this.Proc.OutParams) {
            Contract.Assert(param != null);
            Expr w = param.TypedIdent.WhereExpr;
            if (w != null) {
              IdentifierExpr ie = (IdentifierExpr/*!*/)cce.NonNull(substMap[param]);
              Contract.Assert(ie.Decl != null);
              ie.Decl.TypedIdent.WhereExpr = Substituter.Apply(Substituter.SubstitutionFromHashtable(substMap), w);
            }
              }
              #endregion

              #region havoc frame, couts
              // pass on this's token
              HavocCmd hc = new HavocCmd(this.tok, havocVarExprs);
              newBlockBody.Add(hc);
              #endregion

              #region assume Post[ins, outs, old(frame) := cins, couts, cframe]
              Substitution s2 = Substituter.SubstitutionFromHashtable(substMap);
              Substitution s2old = Substituter.SubstitutionFromHashtable(substMapOld);
              foreach (Ensures/*!*/ e in this.Proc.Ensures) {
            Contract.Assert(e != null);
            Expr copy = Substituter.ApplyReplacingOldExprs(s2, s2old, e.Condition);
            AssumeCmd assume = new AssumeCmd(this.tok, copy);
            #region stratified inlining support
            if (QKeyValue.FindBoolAttribute(e.Attributes, "si_fcall"))
            {
            assume.Attributes = Attributes;
            }
            if (QKeyValue.FindBoolAttribute(e.Attributes, "candidate"))
            {
            assume.Attributes = new QKeyValue(Token.NoToken, "candidate", new List<object>(), assume.Attributes);
            assume.Attributes.Params.Add(this.callee);
            }
            #endregion
            newBlockBody.Add(assume);
              }
              #endregion

              #region aouts := couts
              for (int i = 0, n = this.Outs.Count; i < n; i++) {
            if (this.Outs[i] != null) {
              Variable/*!*/ param_i = cce.NonNull(this.Proc.OutParams[i]);
              Expr/*!*/ cout_exp = new IdentifierExpr(cce.NonNull(couts[i]).tok, cce.NonNull(couts[i]));
              Contract.Assert(cout_exp != null);
              AssignCmd assign = Cmd.SimpleAssign(param_i.tok, cce.NonNull(this.Outs[i]), cout_exp);
              newBlockBody.Add(assign);
            }
              }
              #endregion
              #endregion

              return new StateCmd(this.tok, tempVars, newBlockBody);
        }
Example #11
0
        void QuantifierGuts(out Expression q, bool allowSemi, bool allowLambda)
        {
            Contract.Ensures(Contract.ValueAtReturn(out q) != null); IToken/*!*/ x = Token.NoToken;
            bool univ = false;
            List<BoundVar/*!*/> bvars;
            Attributes attrs;
            Expression range;
            Expression/*!*/ body;

            if (la.kind == 103 || la.kind == 123) {
            Forall();
            x = t;  univ = true;
            } else if (la.kind == 124 || la.kind == 125) {
            Exists();
            x = t;
            } else SynErr(238);
            QuantifierDomain(out bvars, out attrs, out range);
            QSep();
            Expression(out body, allowSemi, allowLambda);
            if (univ) {
             q = new ForallExpr(x, bvars, range, body, attrs);
            } else {
             q = new ExistsExpr(x, bvars, range, body, attrs);
            }
        }
Example #12
0
 public override Expr VisitExistsExpr(ExistsExpr node)
 {
     Contract.Ensures(Contract.Result<Expr>() == node);
     return (ExistsExpr)this.VisitQuantifierExpr(node);
 }
Example #13
0
            private Expr CalculatePathCondition()
            {
                Expr returnExpr = Expr.True;

                foreach (Variable v in program.GlobalVariables())
                {
                    var eqExpr = Expr.Eq(new IdentifierExpr(Token.NoToken, v), new OldExpr(Token.NoToken, new IdentifierExpr(Token.NoToken, v)));
                    returnExpr = Expr.And(eqExpr, returnExpr);
                }
                if (first != null)
                {
                    foreach (Variable v in first.thisOutParams)
                    {
                        var eqExpr = Expr.Eq(new IdentifierExpr(Token.NoToken, v), new OldExpr(Token.NoToken, new IdentifierExpr(Token.NoToken, v)));
                        returnExpr = Expr.And(eqExpr, returnExpr);
                    }
                }
                foreach (Variable v in second.thatOutParams)
                {
                    var eqExpr = Expr.Eq(new IdentifierExpr(Token.NoToken, v), new OldExpr(Token.NoToken, new IdentifierExpr(Token.NoToken, v)));
                    returnExpr = Expr.And(eqExpr, returnExpr);
                }
                Block[] dfsStackAsArray = dfsStack.Reverse().ToArray();
                for (int i = dfsStackAsArray.Length - 1; i >= 0; i--)
                {
                    Block b = dfsStackAsArray[i];
                    for (int j = b.Cmds.Count - 1; j >= 0; j--)
                    {
                        Cmd cmd = b.Cmds[j];
                        if (cmd is AssumeCmd)
                        {
                            AssumeCmd assumeCmd = cmd as AssumeCmd;
                            returnExpr = Expr.And(new OldExpr(Token.NoToken, assumeCmd.Expr), returnExpr);
                        }
                        else if (cmd is AssignCmd)
                        {
                            AssignCmd assignCmd             = (cmd as AssignCmd).AsSimpleAssignCmd;
                            Dictionary <Variable, Expr> map = new Dictionary <Variable, Expr>();
                            for (int k = 0; k < assignCmd.Lhss.Count; k++)
                            {
                                map[assignCmd.Lhss[k].DeepAssignedVariable] = assignCmd.Rhss[k];
                            }
                            Substitution subst    = Substituter.SubstitutionFromHashtable(new Dictionary <Variable, Expr>());
                            Substitution oldSubst = Substituter.SubstitutionFromHashtable(map);
                            returnExpr = (Expr) new MySubstituter(subst, oldSubst).Visit(returnExpr);
                        }
                        else if (cmd is HavocCmd)
                        {
                            HavocCmd                    havocCmd  = cmd as HavocCmd;
                            List <Variable>             existVars = new List <Variable>();
                            Dictionary <Variable, Expr> map       = new Dictionary <Variable, Expr>();
                            foreach (IdentifierExpr ie in havocCmd.Vars)
                            {
                                BoundVariable bv = GetBoundVariable(ie.Decl.TypedIdent.Type);
                                map[ie.Decl] = new IdentifierExpr(Token.NoToken, bv);
                                existVars.Add(bv);
                            }
                            Substitution subst    = Substituter.SubstitutionFromHashtable(new Dictionary <Variable, Expr>());
                            Substitution oldSubst = Substituter.SubstitutionFromHashtable(map);
                            returnExpr = new ExistsExpr(Token.NoToken, existVars, (Expr) new MySubstituter(subst, oldSubst).Visit(returnExpr));
                        }
                        else
                        {
                            Debug.Assert(false);
                        }
                    }
                }
                return(returnExpr);
            }
Example #14
0
        private void CreateFailurePreservationChecker(Program program, ActionInfo first, ActionInfo second)
        {
            Tuple <ActionInfo, ActionInfo> actionPair = new Tuple <ActionInfo, ActionInfo>(first, second);

            if (failurePreservationCheckerCache.Contains(actionPair))
            {
                return;
            }
            failurePreservationCheckerCache.Add(actionPair);

            List <Variable> inputs = new List <Variable>();

            inputs.AddRange(first.thisInParams);
            inputs.AddRange(second.thatInParams);

            Expr transitionRelation = (new TransitionRelationComputation(program, second)).Compute();
            Expr expr = Expr.True;

            foreach (AssertCmd assertCmd in first.thisGate)
            {
                expr = Expr.And(assertCmd.Expr, expr);
            }
            List <Requires> requires = DisjointnessRequires(program, first, second);

            requires.Add(new Requires(false, Expr.Not(expr)));
            foreach (AssertCmd assertCmd in second.thatGate)
            {
                requires.Add(new Requires(false, assertCmd.Expr));
            }

            Dictionary <Variable, Expr> map       = new Dictionary <Variable, Expr>();
            Dictionary <Variable, Expr> oldMap    = new Dictionary <Variable, Expr>();
            List <Variable>             boundVars = new List <Variable>();

            foreach (Variable v in program.GlobalVariables())
            {
                BoundVariable bv = new BoundVariable(Token.NoToken, new TypedIdent(Token.NoToken, "post_" + v.Name, v.TypedIdent.Type));
                boundVars.Add(bv);
                map[v] = new IdentifierExpr(Token.NoToken, bv);
            }
            foreach (Variable v in second.thatOutParams)
            {
                {
                    BoundVariable bv = new BoundVariable(Token.NoToken, new TypedIdent(Token.NoToken, "post_" + v.Name, v.TypedIdent.Type));
                    boundVars.Add(bv);
                    map[v] = new IdentifierExpr(Token.NoToken, bv);
                }
                {
                    BoundVariable bv = new BoundVariable(Token.NoToken, new TypedIdent(Token.NoToken, "pre_" + v.Name, v.TypedIdent.Type));
                    boundVars.Add(bv);
                    oldMap[v] = new IdentifierExpr(Token.NoToken, bv);
                }
            }
            foreach (Variable v in second.thatAction.LocVars)
            {
                BoundVariable bv = new BoundVariable(Token.NoToken, new TypedIdent(Token.NoToken, "pre_" + v.Name, v.TypedIdent.Type));
                boundVars.Add(bv);
                oldMap[v] = new IdentifierExpr(Token.NoToken, bv);
            }

            Expr ensuresExpr = Expr.And(transitionRelation, Expr.Not(expr));

            if (boundVars.Count > 0)
            {
                Substitution subst    = Substituter.SubstitutionFromHashtable(map);
                Substitution oldSubst = Substituter.SubstitutionFromHashtable(oldMap);
                ensuresExpr = new ExistsExpr(Token.NoToken, boundVars, (Expr) new MySubstituter(subst, oldSubst).Visit(ensuresExpr));
            }
            List <Ensures> ensures = new List <Ensures>();

            ensures.Add(new Ensures(false, ensuresExpr));
            List <Block> blocks = new List <Block>();

            blocks.Add(new Block(Token.NoToken, "L", new List <Cmd>(), new ReturnCmd(Token.NoToken)));
            string checkerName = string.Format("FailurePreservationChecker_{0}_{1}", first.proc.Name, second.proc.Name);
            List <IdentifierExpr> globalVars = new List <IdentifierExpr>();

            program.GlobalVariables().Iter(x => globalVars.Add(new IdentifierExpr(Token.NoToken, x)));
            Procedure      proc = new Procedure(Token.NoToken, checkerName, new List <TypeVariable>(), inputs, new List <Variable>(), requires, globalVars, ensures);
            Implementation impl = new Implementation(Token.NoToken, checkerName, new List <TypeVariable>(), inputs, new List <Variable>(), new List <Variable>(), blocks);

            impl.Proc = proc;
            this.decls.Add(impl);
            this.decls.Add(proc);
        }
        private Expr CalculatePathCondition(PathInfo path)
        {
            HashSet <Variable>          allExistsVars         = new HashSet <Variable>(firstExistsVars.Union(secondExistsVars));
            HashSet <Variable>          usedExistsVars        = new HashSet <Variable>();
            Dictionary <Variable, Expr> existsSubstitutionMap = new Dictionary <Variable, Expr>();
            List <Expr> inferredSelectEqualities = new List <Expr>();

            foreach (Variable v in path.varToExpr.Keys.Except(postExistVars))
            {
                var expr = path.varToExpr[v];
                usedExistsVars.UnionWith(VariableCollector.Collect(expr).Intersect(allExistsVars));
                IdentifierExpr ie = expr as IdentifierExpr;
                if (ie != null && IsExistsVar(ie.Decl) && !existsSubstitutionMap.ContainsKey(ie.Decl))
                {
                    existsSubstitutionMap[ie.Decl] = Expr.Ident(v);
                }
                else if (IsMapStoreExpr(expr))
                {
                    inferredSelectEqualities.Add(GenerateEqualityWithSelect(expr as NAryExpr, Expr.Ident(v)));
                }
            }

            foreach (Expr expr in path.pathExprs)
            {
                usedExistsVars.UnionWith(VariableCollector.Collect(expr).Intersect(allExistsVars));
            }
            InferSubstitution(allExistsVars, existsSubstitutionMap, path.pathExprs, inferredSelectEqualities);

            List <Expr>     triggerExprs   = new List <Expr>();
            List <Variable> quantifiedVars = new List <Variable>();

            foreach (var v in usedExistsVars.Except(existsSubstitutionMap.Keys))
            {
                var triggerFun    = TriggerFunction(v); // this call populates existsVars[v]
                var quantifiedVar = existsVars[v];
                triggerExprs.Add(
                    new NAryExpr(Token.NoToken,
                                 new FunctionCall(triggerFun),
                                 new Expr[] { Expr.Ident(quantifiedVar) }));
                quantifiedVars.Add(quantifiedVar);
                existsSubstitutionMap[v] = Expr.Ident(quantifiedVar);
            }

            Substitution subst       = Substituter.SubstitutionFromHashtable(existsSubstitutionMap);
            List <Expr>  returnExprs = new List <Expr>();

            foreach (Variable v in path.varToExpr.Keys.Except(postExistVars))
            {
                Expr withOldExpr = MyDuplicator.Duplicate(path.varToExpr[v]);
                var  substExpr   = Expr.Eq(Expr.Ident(v), Substituter.Apply(subst, withOldExpr));
                substExpr.Type = Type.Bool;
                returnExprs.Add(substExpr);
            }

            foreach (Expr x in path.pathExprs)
            {
                var withOldExpr = MyDuplicator.Duplicate(x);
                returnExprs.Add(Substituter.Apply(subst, withOldExpr));
            }

            var returnExpr = Expr.And(returnExprs);

            if (quantifiedVars.Count > 0)
            {
                if (first == null)
                {
                    returnExpr = new ExistsExpr(Token.NoToken, quantifiedVars, returnExpr);
                }
                else
                {
                    returnExpr = new ExistsExpr(Token.NoToken,
                                                quantifiedVars,
                                                new Trigger(Token.NoToken, true, triggerExprs),
                                                returnExpr);
                }
            }
            return(returnExpr);
        }
Example #16
0
        private void CreateFailurePreservationChecker(Program program, ActionInfo first, ActionInfo second)
        {
            Tuple<ActionInfo, ActionInfo> actionPair = new Tuple<ActionInfo, ActionInfo>(first, second);
            if (failurePreservationCheckerCache.Contains(actionPair))
                return;
            failurePreservationCheckerCache.Add(actionPair);

            List<Variable> inputs = new List<Variable>();
            inputs.AddRange(first.thisInParams);
            inputs.AddRange(second.thatInParams);

            Expr transitionRelation = (new TransitionRelationComputation(program, second)).Compute();
            Expr expr = Expr.True;
            foreach (AssertCmd assertCmd in first.thisGate)
            {
                expr = Expr.And(assertCmd.Expr, expr);
            }
            List<Requires> requires = DisjointnessRequires(program, first, second);
            requires.Add(new Requires(false, Expr.Not(expr)));
            foreach (AssertCmd assertCmd in second.thatGate)
            {
                requires.Add(new Requires(false, assertCmd.Expr));
            }

            Dictionary<Variable, Expr> map = new Dictionary<Variable, Expr>();
            Dictionary<Variable, Expr> oldMap = new Dictionary<Variable, Expr>();
            List<Variable> boundVars = new List<Variable>();
            foreach (Variable v in program.GlobalVariables())
            {
                BoundVariable bv = new BoundVariable(Token.NoToken, new TypedIdent(Token.NoToken, "post_" + v.Name, v.TypedIdent.Type));
                boundVars.Add(bv);
                map[v] = new IdentifierExpr(Token.NoToken, bv);
            }
            foreach (Variable v in second.thatOutParams)
            {
                {
                    BoundVariable bv = new BoundVariable(Token.NoToken, new TypedIdent(Token.NoToken, "post_" + v.Name, v.TypedIdent.Type));
                    boundVars.Add(bv);
                    map[v] = new IdentifierExpr(Token.NoToken, bv);
                }
                {
                    BoundVariable bv = new BoundVariable(Token.NoToken, new TypedIdent(Token.NoToken, "pre_" + v.Name, v.TypedIdent.Type));
                    boundVars.Add(bv);
                    oldMap[v] = new IdentifierExpr(Token.NoToken, bv);
                }
            }
            foreach (Variable v in second.thatAction.LocVars)
            {
                BoundVariable bv = new BoundVariable(Token.NoToken, new TypedIdent(Token.NoToken, "pre_" + v.Name, v.TypedIdent.Type));
                boundVars.Add(bv);
                oldMap[v] = new IdentifierExpr(Token.NoToken, bv);
            }

            Expr ensuresExpr = Expr.And(transitionRelation, Expr.Not(expr));
            if (boundVars.Count > 0)
            {
                Substitution subst = Substituter.SubstitutionFromHashtable(map);
                Substitution oldSubst = Substituter.SubstitutionFromHashtable(oldMap);
                ensuresExpr = new ExistsExpr(Token.NoToken, boundVars, (Expr)new MySubstituter(subst, oldSubst).Visit(ensuresExpr));
            }
            List<Ensures> ensures = new List<Ensures>();
            ensures.Add(new Ensures(false, ensuresExpr));
            List<Block> blocks = new List<Block>();
            blocks.Add(new Block(Token.NoToken, "L", new List<Cmd>(), new ReturnCmd(Token.NoToken)));
            string checkerName = string.Format("FailurePreservationChecker_{0}_{1}", first.proc.Name, second.proc.Name);
            List<IdentifierExpr> globalVars = new List<IdentifierExpr>();
            program.GlobalVariables().Iter(x => globalVars.Add(new IdentifierExpr(Token.NoToken, x)));
            Procedure proc = new Procedure(Token.NoToken, checkerName, new List<TypeVariable>(), inputs, new List<Variable>(), requires, globalVars, ensures);
            Implementation impl = new Implementation(Token.NoToken, checkerName, new List<TypeVariable>(), inputs, new List<Variable>(), new List<Variable>(), blocks);
            impl.Proc = proc;
            this.decls.Add(impl);
            this.decls.Add(proc);
        }
        private Expr CalculatePathCondition(PathInfo path)
        {
            HashSet<Variable> allExistsVars = new HashSet<Variable>(firstExistsVars.Union(secondExistsVars));
            HashSet<Variable> usedExistsVars = new HashSet<Variable>();
            Dictionary<Variable, Expr> existsSubstitutionMap = new Dictionary<Variable, Expr>();
            List<Expr> inferredSelectEqualities = new List<Expr>();
            foreach (Variable v in path.varToExpr.Keys.Except(postExistVars))
            {
                var expr = path.varToExpr[v];
                usedExistsVars.UnionWith(VariableCollector.Collect(expr).Intersect(allExistsVars));
                IdentifierExpr ie = expr as IdentifierExpr;
                if (ie != null && IsExistsVar(ie.Decl) && !existsSubstitutionMap.ContainsKey(ie.Decl))
                {
                    existsSubstitutionMap[ie.Decl] = Expr.Ident(v);
                }
                else if (IsMapStoreExpr(expr))
                {
                    inferredSelectEqualities.Add(GenerateEqualityWithSelect(expr as NAryExpr, Expr.Ident(v)));
                }
            }

            foreach (Expr expr in path.pathExprs)
            {
                usedExistsVars.UnionWith(VariableCollector.Collect(expr).Intersect(allExistsVars));
            }
            InferSubstitution(allExistsVars, existsSubstitutionMap, path.pathExprs, inferredSelectEqualities);

            List<Expr> triggerExprs = new List<Expr>();
            List<Variable> quantifiedVars = new List<Variable>();
            foreach (var v in usedExistsVars.Except(existsSubstitutionMap.Keys))
            {
                var triggerFun = TriggerFunction(v); // this call populates existsVars[v]
                var quantifiedVar = existsVars[v];
                triggerExprs.Add(
                    new NAryExpr(Token.NoToken, 
                        new FunctionCall(triggerFun), 
                        new Expr[] { Expr.Ident(quantifiedVar) }));
                quantifiedVars.Add(quantifiedVar);
                existsSubstitutionMap[v] = Expr.Ident(quantifiedVar);
            }

            Substitution subst = Substituter.SubstitutionFromHashtable(existsSubstitutionMap);
            List<Expr> returnExprs = new List<Expr>();

            foreach (Variable v in path.varToExpr.Keys.Except(postExistVars))
            {
                Expr withOldExpr = MyDuplicator.Duplicate(path.varToExpr[v]);
                var substExpr = Expr.Eq(Expr.Ident(v), Substituter.Apply(subst, withOldExpr));
                substExpr.Type = Type.Bool;
                returnExprs.Add(substExpr);
            }

            foreach (Expr x in path.pathExprs)
            {
                var withOldExpr = MyDuplicator.Duplicate(x);
                returnExprs.Add(Substituter.Apply(subst, withOldExpr));
            }

            var returnExpr = Expr.And(returnExprs);
            if (quantifiedVars.Count > 0)
            {
                if (first == null)
                {
                    returnExpr = new ExistsExpr(Token.NoToken, quantifiedVars, returnExpr);
                }
                else
                {
                    returnExpr = new ExistsExpr(Token.NoToken, 
                                    quantifiedVars, 
                                    new Trigger(Token.NoToken, true, triggerExprs), 
                                    returnExpr);
                }
            }
            return returnExpr;
        }
Example #18
0
	void AtomExpression(out Expr/*!*/ e) {
		Contract.Ensures(Contract.ValueAtReturn(out e) != null); IToken/*!*/ x; int n; BigNum bn; BigDec bd; BigFloat bf;
		List<Expr>/*!*/ es;  List<Variable>/*!*/ ds;  Trigger trig;
		List<TypeVariable>/*!*/ typeParams;
		IdentifierExpr/*!*/ id;
		QKeyValue kv;
		e = dummyExpr;
		List<Variable>/*!*/ locals;
		List<Block/*!*/>/*!*/ blocks;
		
		switch (la.kind) {
		case 83: {
			Get();
			e = new LiteralExpr(t, false); 
			break;
		}
		case 84: {
			Get();
			e = new LiteralExpr(t, true); 
			break;
		}
		case 3: {
			Nat(out bn);
			e = new LiteralExpr(t, bn); 
			break;
		}
		case 5: case 6: {
			Dec(out bd);
			e = new LiteralExpr(t, bd); 
			break;
		}
		case 7: {
			Float(out bf);
			e = new LiteralExpr(t, bf); 
			break;
		}
		case 2: {
			BvLit(out bn, out n);
			e = new LiteralExpr(t, bn, n); 
			break;
		}
		case 1: {
			Ident(out x);
			id = new IdentifierExpr(x, x.val);  e = id; 
			if (la.kind == 10) {
				Get();
				if (StartOf(9)) {
					Expressions(out es);
					e = new NAryExpr(x, new FunctionCall(id), es); 
				} else if (la.kind == 11) {
					e = new NAryExpr(x, new FunctionCall(id), new List<Expr>()); 
				} else SynErr(124);
				Expect(11);
			}
			break;
		}
		case 85: {
			Get();
			x = t; 
			Expect(10);
			Expression(out e);
			Expect(11);
			e = new OldExpr(x, e); 
			break;
		}
		case 15: {
			Get();
			x = t; 
			Expect(10);
			Expression(out e);
			Expect(11);
			e = new NAryExpr(x, new ArithmeticCoercion(x, ArithmeticCoercion.CoercionType.ToInt), new List<Expr>{ e }); 
			break;
		}
		case 16: {
			Get();
			x = t; 
			Expect(10);
			Expression(out e);
			Expect(11);
			e = new NAryExpr(x, new ArithmeticCoercion(x, ArithmeticCoercion.CoercionType.ToReal), new List<Expr>{ e }); 
			break;
		}
		case 10: {
			Get();
			if (StartOf(9)) {
				Expression(out e);
				if (e is BvBounds)
				 this.SemErr("parentheses around bitvector bounds " +
				        "are not allowed"); 
			} else if (la.kind == 89 || la.kind == 90) {
				Forall();
				x = t; 
				QuantifierBody(x, out typeParams, out ds, out kv, out trig, out e);
				if (typeParams.Count + ds.Count > 0)
				 e = new ForallExpr(x, typeParams, ds, kv, trig, e); 
			} else if (la.kind == 91 || la.kind == 92) {
				Exists();
				x = t; 
				QuantifierBody(x, out typeParams, out ds, out kv, out trig, out e);
				if (typeParams.Count + ds.Count > 0)
				 e = new ExistsExpr(x, typeParams, ds, kv, trig, e); 
			} else if (la.kind == 93 || la.kind == 94) {
				Lambda();
				x = t; 
				QuantifierBody(x, out typeParams, out ds, out kv, out trig, out e);
				if (trig != null)
				 SemErr("triggers not allowed in lambda expressions");
				if (typeParams.Count + ds.Count > 0)
				 e = new LambdaExpr(x, typeParams, ds, kv, e); 
			} else SynErr(125);
			Expect(11);
			break;
		}
		case 41: {
			IfThenElseExpression(out e);
			break;
		}
		case 86: {
			CodeExpression(out locals, out blocks);
			e = new CodeExpr(locals, blocks); 
			break;
		}
		default: SynErr(126); break;
		}
	}
Example #19
0
 private void IntroduceAndAssignBoundVars(int indent, ExistsExpr exists, TextWriter wr) {
   Contract.Requires(0 <= indent);
   Contract.Requires(exists != null);
   Contract.Assume(exists.Bounds != null);  // follows from successful resolution
   Contract.Assert(exists.Range == null);  // follows from invariant of class IfStmt
   foreach (var bv in exists.BoundVars) {
     TrLocalVar(bv, false, indent, wr);
   }
   var ivars = exists.BoundVars.ConvertAll(bv => (IVariable)bv);
   TrAssignSuchThat(indent, ivars, exists.Term, exists.Bounds, exists.tok.line, wr, false);
 }
Example #20
0
        void ExistentialGuard(out Expression e, bool allowLambda)
        {
            var bvars = new List<BoundVar>();
            BoundVar bv;  IToken x;
            Attributes attrs = null;
            Expression body;

            IdentTypeOptional(out bv);
            bvars.Add(bv); x = bv.tok;
            while (la.kind == 22) {
            Get();
            IdentTypeOptional(out bv);
            bvars.Add(bv);
            }
            while (la.kind == 46) {
            Attribute(ref attrs);
            }
            Expect(25);
            Expression(out body, true, allowLambda);
            e = new ExistsExpr(x, bvars, null, body, attrs);
        }
Example #21
0
 public void CachedHashCodeExistsExpr()
 {
     var x = new BoundVariable(Token.NoToken, new TypedIdent(Token.NoToken, "x", BasicType.Int));
     var y = new BoundVariable(Token.NoToken, new TypedIdent(Token.NoToken, "x", BasicType.Int));
     var body = Expr.Gt (new IdentifierExpr (Token.NoToken, x, /*immutable=*/true),
         new IdentifierExpr(Token.NoToken, y, /*immutable=*/true));
     var exists = new ExistsExpr(Token.NoToken, new List<Variable> () {x, y }, body, /*immutable=*/ true);
     Assert.AreEqual(exists.ComputeHashCode(), exists.GetHashCode());
 }
Example #22
0
 public virtual Expr VisitExistsExpr(ExistsExpr node) {
   Contract.Requires(node != null);
   Contract.Ensures(Contract.Result<Expr>() != null);
   node = (ExistsExpr)this.VisitQuantifierExpr(node);
   return node;
 }
Example #23
0
 private Expr CalculatePathCondition()
 {
     Expr returnExpr = Expr.True;
     foreach (Variable v in program.GlobalVariables())
     {
         var eqExpr = Expr.Eq(new IdentifierExpr(Token.NoToken, v), new OldExpr(Token.NoToken, new IdentifierExpr(Token.NoToken, v)));
         returnExpr = Expr.And(eqExpr, returnExpr);
     }
     if (first != null)
     {
         foreach (Variable v in first.thisOutParams)
         {
             var eqExpr = Expr.Eq(new IdentifierExpr(Token.NoToken, v), new OldExpr(Token.NoToken, new IdentifierExpr(Token.NoToken, v)));
             returnExpr = Expr.And(eqExpr, returnExpr);
         }
     }
     foreach (Variable v in second.thatOutParams)
     {
         var eqExpr = Expr.Eq(new IdentifierExpr(Token.NoToken, v), new OldExpr(Token.NoToken, new IdentifierExpr(Token.NoToken, v)));
         returnExpr = Expr.And(eqExpr, returnExpr);
     }
     Block[] dfsStackAsArray = dfsStack.Reverse().ToArray();
     for (int i = dfsStackAsArray.Length - 1; i >= 0; i--)
     {
         Block b = dfsStackAsArray[i];
         for (int j = b.Cmds.Count - 1; j >= 0; j--)
         {
             Cmd cmd = b.Cmds[j];
             if (cmd is AssumeCmd)
             {
                 AssumeCmd assumeCmd = cmd as AssumeCmd;
                 returnExpr = Expr.And(new OldExpr(Token.NoToken, assumeCmd.Expr), returnExpr);
             }
             else if (cmd is AssignCmd)
             {
                 AssignCmd assignCmd = (cmd as AssignCmd).AsSimpleAssignCmd;
                 Dictionary<Variable, Expr> map = new Dictionary<Variable, Expr>();
                 for (int k = 0; k < assignCmd.Lhss.Count; k++)
                 {
                     map[assignCmd.Lhss[k].DeepAssignedVariable] = assignCmd.Rhss[k];
                 }
                 Substitution subst = Substituter.SubstitutionFromHashtable(new Dictionary<Variable, Expr>());
                 Substitution oldSubst = Substituter.SubstitutionFromHashtable(map);
                 returnExpr = (Expr) new MySubstituter(subst, oldSubst).Visit(returnExpr);
             }
             else if (cmd is HavocCmd)
             {
                 HavocCmd havocCmd = cmd as HavocCmd;
                 List<Variable> existVars = new List<Variable>();
                 Dictionary<Variable, Expr> map = new Dictionary<Variable, Expr>();
                 foreach (IdentifierExpr ie in havocCmd.Vars)
                 {
                     BoundVariable bv = GetBoundVariable(ie.Decl.TypedIdent.Type);
                     map[ie.Decl] = new IdentifierExpr(Token.NoToken, bv);
                     existVars.Add(bv);
                 }
                 Substitution subst = Substituter.SubstitutionFromHashtable(new Dictionary<Variable, Expr>());
                 Substitution oldSubst = Substituter.SubstitutionFromHashtable(map);
                 returnExpr = new ExistsExpr(Token.NoToken, existVars, (Expr) new MySubstituter(subst, oldSubst).Visit(returnExpr));
             }
             else
             {
                 Debug.Assert(false);
             }
         }
     }
     return returnExpr;
 }
Example #24
0
 private Expr SubsetExprs(LinearDomain domain, HashSet<Variable> scope, Variable partition, int count, Expr expr)
 {
     foreach (Variable v in scope)
     {
         if (!domain.collectors.ContainsKey(v.TypedIdent.Type)) continue;
         Expr ie = new NAryExpr(Token.NoToken, new FunctionCall(domain.collectors[v.TypedIdent.Type]), new List<Expr> { Expr.Ident(v) });
         expr = Expr.And(SubsetExpr(domain, ie, partition, count), expr);
         count++;
     }
     expr = new ExistsExpr(Token.NoToken, new List<Variable> { partition }, expr);
     expr.Resolve(new ResolutionContext(null));
     expr.Typecheck(new TypecheckingContext(null));
     return expr;
 }
Example #25
0
 public Expr DisjointnessExpr(string domainName, HashSet<Variable> scope)
 {
     LinearDomain domain = linearDomains[domainName];
     BoundVariable partition = new BoundVariable(Token.NoToken, new TypedIdent(Token.NoToken, string.Format("partition_{0}", domainName), new MapType(Token.NoToken, new List<TypeVariable>(), new List<Type> { domain.elementType }, Microsoft.Boogie.Type.Int)));
     Expr disjointExpr = Expr.True;
     int count = 0;
     foreach (Variable v in scope)
     {
         IdentifierExpr ie = new IdentifierExpr(Token.NoToken, v);
         Expr e = new NAryExpr(Token.NoToken, new FunctionCall(domain.mapConstInt), new List<Expr>{ new LiteralExpr(Token.NoToken, Microsoft.Basetypes.BigNum.FromInt(count++)) } );
         e = new NAryExpr(Token.NoToken, new FunctionCall(domain.mapEqInt), new List<Expr> { new IdentifierExpr(Token.NoToken, partition), e } );
         e = new NAryExpr(Token.NoToken, new FunctionCall(domain.mapImpBool), new List<Expr> { v.TypedIdent.Type is MapType ? ie : Singleton(ie, domainName), e } );
         e = Expr.Binary(BinaryOperator.Opcode.Eq, e, new NAryExpr(Token.NoToken, new FunctionCall(domain.mapConstBool), new List<Expr> { Expr.True }));
         disjointExpr = Expr.Binary(BinaryOperator.Opcode.And, e, disjointExpr);
     }
     var expr = new ExistsExpr(Token.NoToken, new List<Variable> { partition }, disjointExpr);
     expr.Resolve(new ResolutionContext(null));
     expr.Typecheck(new TypecheckingContext(null));
     return expr;
 }
Example #26
0
 public void ProtectedExistsExprBody()
 {
     var x = new BoundVariable(Token.NoToken, new TypedIdent(Token.NoToken, "x", BasicType.Int));
     var y = new BoundVariable(Token.NoToken, new TypedIdent(Token.NoToken, "x", BasicType.Int));
     var xId = new IdentifierExpr(Token.NoToken, x, /*immutable=*/true);
     var yId = new IdentifierExpr(Token.NoToken, y, /*immutable=*/true);
     var body = Expr.Gt(xId, yId);
     var exists = new ExistsExpr(Token.NoToken, new List<Variable> () { x, y }, body, /*immutable=*/true);
     exists.Body = Expr.Lt(xId, yId); // Changing the body of an immutable ExistsExpr should fail
 }
    /// <summary>
    /// 
    /// </summary>
    /// <param name="methodCall"></param>
    /// <remarks>Stub, This one really needs comments!</remarks>
    public override void TraverseChildren(IMethodCall methodCall) {
      var resolvedMethod = ResolveUnspecializedMethodOrThrow(methodCall.MethodToCall);

      Bpl.IToken methodCallToken = methodCall.Token();

      if (this.sink.Options.getMeHere) {
        // TODO: Get a method reference so this isn't a string comparison?
        var methodName = MemberHelper.GetMethodSignature(methodCall.MethodToCall, NameFormattingOptions.None);
        if (methodName.Equals("GetMeHere.GetMeHere.Assert")) {
          // for now, just translate it as "assert e"
          this.Traverse(methodCall.Arguments.First());
          Bpl.Expr e = this.TranslatedExpressions.Pop();
          this.StmtTraverser.StmtBuilder.Add(new Bpl.AssertCmd(methodCallToken, e));
          return;
        }
      }

      // Handle type equality specially when it is testing against a constant, i.e., o.GetType() == typeof(T)
      if (IsOperator(resolvedMethod) && !IsConversionOperator(resolvedMethod) && 
        TypeHelper.TypesAreEquivalent(resolvedMethod.ContainingType, this.sink.host.PlatformType.SystemType)) {
        // REVIEW: Assume the only operators on System.Type are == and !=
        var typeToTest = methodCall.Arguments.ElementAtOrDefault(0) as ITypeOf;
        IMethodCall callToGetType;
        if (typeToTest == null) {
          typeToTest = methodCall.Arguments.ElementAtOrDefault(1) as ITypeOf;
          callToGetType = methodCall.Arguments.ElementAtOrDefault(0) as IMethodCall;
        } else {
          callToGetType = methodCall.Arguments.ElementAtOrDefault(1) as IMethodCall;
        }
        if (typeToTest != null && callToGetType != null &&
          TypeHelper.TypesAreEquivalent(callToGetType.MethodToCall.ContainingType, this.sink.host.PlatformType.SystemObject) &&
          MemberHelper.GetMethodSignature(callToGetType.MethodToCall).Equals("System.Object.GetType")) {

          IExpression objectToTest = callToGetType.ThisArgument;

          // generate: $TypeConstructor($DynamicType(o)) == TypeConstructorId
          var typeConstructorId = this.sink.FindOrDefineType(typeToTest.TypeToGet.ResolvedType).ConstructorId;
          Contract.Assume(typeConstructorId != null);

          this.Traverse(objectToTest);
          var e = this.TranslatedExpressions.Pop();

          var exprs = new List<Bpl.Expr>(new Bpl.Expr[] {this.sink.Heap.DynamicType(e)});
          Bpl.Expr typeTestExpression = 
              Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Eq, 
                              new Bpl.NAryExpr(methodCallToken, new Bpl.FunctionCall(sink.Heap.TypeConstructorFunction), exprs),
                              Bpl.Expr.Ident(typeConstructorId));
          if (MemberHelper.GetMethodSignature(resolvedMethod).Equals("System.Type.op_Inequality"))
            typeTestExpression = Bpl.Expr.Unary( methodCallToken, Bpl.UnaryOperator.Opcode.Not, typeTestExpression);
          this.TranslatedExpressions.Push(typeTestExpression);
          return;
        }
      }

      // Handle calls to Contract.ForAll and Contract.Exists specially (if they are to the overloads that take two ints and a predicate on ints)
      if (resolvedMethod.ContainingTypeDefinition.InternedKey == this.sink.host.PlatformType.SystemDiagnosticsContractsContract.InternedKey)
      {
          var methodName = resolvedMethod.Name.Value;
          if (methodCall.Arguments.Count() == 3 && (methodName == "ForAll" || methodName == "Exists"))
          {
              var noToken = Bpl.Token.NoToken;

              this.Traverse(methodCall.Arguments.ElementAt(0));
              var lb = this.TranslatedExpressions.Pop();
              this.Traverse(methodCall.Arguments.ElementAt(1));
              var ub = this.TranslatedExpressions.Pop();
              var delegateArgument = methodCall.Arguments.ElementAt(2);
              this.Traverse(delegateArgument);
              var del = this.TranslatedExpressions.Pop();

              var boundVar = new Bpl.LocalVariable(noToken, new Bpl.TypedIdent(noToken, TranslationHelper.GenerateTempVarName(), Bpl.Type.Int));

              var resultVar = new Bpl.LocalVariable(noToken, new Bpl.TypedIdent(noToken, TranslationHelper.GenerateTempVarName(), Bpl.Type.Bool));

              var delegateType = delegateArgument.Type;
              var invokeMethod = delegateType.ResolvedType.GetMembersNamed(this.sink.host.NameTable.GetNameFor("Invoke"), false).First() as IMethodReference;
              var unspecializedInvokeMethod = Sink.Unspecialize(invokeMethod).ResolvedMethod;
              var invokeProcedureInfo = sink.FindOrCreateProcedure(unspecializedInvokeMethod);
              var ins = new List<Bpl.Expr>();
              ins.Add(del);
              var localStmtTraverser = this.StmtTraverser.factory.MakeStatementTraverser(this.sink, this.StmtTraverser.PdbReader, this.contractContext);

              var secondArg = new Bpl.NAryExpr(noToken, new Bpl.FunctionCall(this.sink.Heap.Int2Union), new List<Bpl.Expr>(new Bpl.Expr[] {Bpl.Expr.Ident(boundVar)}));
              ins.Add(secondArg);
              var outs = new List<Bpl.IdentifierExpr>();
              outs.Add(Bpl.Expr.Ident(resultVar));

              var callCmd = new Bpl.CallCmd(noToken, invokeProcedureInfo.Decl.Name, ins, outs);
              var blockCmds = new List<Bpl.Cmd>();
              blockCmds.Add(
                new Bpl.AssumeCmd(noToken,
                Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Eq,
                                new Bpl.NAryExpr(noToken, new Bpl.FunctionCall(this.sink.Heap.Union2Int), new List<Bpl.Expr>(new Bpl.Expr[] {secondArg})),
                                Bpl.Expr.Ident(boundVar))));
              blockCmds.Add(callCmd);
              Bpl.Block block = new Bpl.Block(noToken, "A", blockCmds, new Bpl.ReturnExprCmd(noToken, Bpl.Expr.Ident(resultVar)));
              Bpl.Expr body = new Bpl.CodeExpr(new List<Bpl.Variable>(new Bpl.Variable[] {resultVar}), new List<Bpl.Block>{block});


              Bpl.Expr antecedent = Bpl.Expr.And(Bpl.Expr.Le(lb, Bpl.Expr.Ident(boundVar)), Bpl.Expr.Lt(Bpl.Expr.Ident(boundVar), ub));

              Bpl.Expr quantifier;
              if (methodName == "ForAll")
              {
                  body = Bpl.Expr.Imp(antecedent, body);
                  quantifier = new Bpl.ForallExpr(methodCallToken, new List<Bpl.Variable>(new Bpl.Variable[] {boundVar}), body);
              }
              else
              {
                  body = Bpl.Expr.And(antecedent, body);
                  quantifier = new Bpl.ExistsExpr(methodCallToken, new List<Bpl.Variable>(new Bpl.Variable[] {boundVar}), body);
              }
              this.TranslatedExpressions.Push(quantifier);
              return;
          }
      }

      List<Bpl.Expr> inexpr;
      List<Bpl.IdentifierExpr> outvars;
      Bpl.IdentifierExpr thisExpr;
      Dictionary<Bpl.IdentifierExpr, Tuple<Bpl.IdentifierExpr,bool>> toBoxed;
      var proc = TranslateArgumentsAndReturnProcedure(methodCallToken, methodCall.MethodToCall, resolvedMethod, methodCall.IsStaticCall ? null : methodCall.ThisArgument, methodCall.Arguments, out inexpr, out outvars, out thisExpr, out toBoxed);
      string methodname = proc.Name;
      var translateAsFunctionCall = proc is Bpl.Function;
      bool isAsync = false;

      // this code structure is quite chaotic, and some code needs to be evaluated regardless, hence the try-finally
      try {
        if (!translateAsFunctionCall) {
          foreach (var a in resolvedMethod.Attributes) {
            if (TypeHelper.GetTypeName(a.Type).EndsWith("AsyncAttribute")) {
                isAsync = true;
            }
          }
        }

        var deferringCtorCall = resolvedMethod.IsConstructor && methodCall.ThisArgument is IThisReference;
        // REVIEW!! Ask Herman: is the above test enough? The following test is used in FindCtorCall.IsDeferringCtor,
        // but it doesn't work when the type is a struct S because then "this" has a type of "&S".
          //&& TypeHelper.TypesAreEquivalent(resolvedMethod.ContainingType, methodCall.ThisArgument.Type);

        if (resolvedMethod.IsConstructor && resolvedMethod.ContainingTypeDefinition.IsStruct && !deferringCtorCall) {
          handleStructConstructorCall(methodCall, methodCallToken, inexpr, outvars, thisExpr, proc);
          return;
        }

        Bpl.CallCmd call;
        bool isEventAdd = resolvedMethod.IsSpecialName && resolvedMethod.Name.Value.StartsWith("add_");
        bool isEventRemove = resolvedMethod.IsSpecialName && resolvedMethod.Name.Value.StartsWith("remove_");
        if (isEventAdd || isEventRemove) {
          call = translateAddRemoveCall(methodCall, resolvedMethod, methodCallToken, inexpr, outvars, thisExpr, isEventAdd);
        } else {
          if (translateAsFunctionCall) {
            var func = proc as Bpl.Function;
            var exprSeq = new List<Bpl.Expr>();
            foreach (var e in inexpr) {
              exprSeq.Add(e);
            }
            var callFunction = new Bpl.NAryExpr(methodCallToken, new Bpl.FunctionCall(func), exprSeq);
            this.TranslatedExpressions.Push(callFunction);
            return;
          } else {
            EmitLineDirective(methodCallToken);
            call = new Bpl.CallCmd(methodCallToken, methodname, inexpr, outvars);
            call.IsAsync = isAsync;
            this.StmtTraverser.StmtBuilder.Add(call);
          }
        }

        foreach (KeyValuePair<Bpl.IdentifierExpr, Tuple<Bpl.IdentifierExpr,bool>> kv in toBoxed) {
          var lhs = kv.Key;
          var tuple = kv.Value;
          var rhs = tuple.Item1;
          Bpl.Expr fromUnion = this.sink.Heap.FromUnion(Bpl.Token.NoToken, lhs.Type, rhs, tuple.Item2);
          this.StmtTraverser.StmtBuilder.Add(TranslationHelper.BuildAssignCmd(lhs, fromUnion));
        }

        if (this.sink.Options.modelExceptions == 2
          || (this.sink.Options.modelExceptions == 1 && this.sink.MethodThrowsExceptions(resolvedMethod))) {
          Bpl.Expr expr = Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Neq, Bpl.Expr.Ident(this.sink.Heap.ExceptionVariable), Bpl.Expr.Ident(this.sink.Heap.NullRef));
          this.StmtTraverser.RaiseException(expr);
        }
      } finally {
        // TODO move away phone related code from the translation, it would be better to have 2 or more translation phases
        if (PhoneCodeHelper.instance().PhonePlugin != null) {
          if (PhoneCodeHelper.instance().PhoneNavigationToggled) {
            if (PhoneCodeHelper.instance().isNavigationCall(methodCall)) {
              Bpl.AssignCmd assignCmd = PhoneCodeHelper.instance().createBoogieNavigationUpdateCmd(sink);
              this.StmtTraverser.StmtBuilder.Add(assignCmd);
            }
          }

          if (PhoneCodeHelper.instance().PhoneFeedbackToggled) {
            if (PhoneCodeHelper.instance().isMethodKnownUIChanger(methodCall)) {
              Bpl.AssumeCmd assumeFalse = new Bpl.AssumeCmd(Bpl.Token.NoToken, Bpl.LiteralExpr.False);
              this.StmtTraverser.StmtBuilder.Add(assumeFalse);
            }
          }
        }
      }
    }
Example #28
0
 public override Expr VisitExistsExpr(ExistsExpr node) {
   //Contract.Requires(node != null);
   Contract.Ensures(Contract.Result<Expr>() != null);
   return base.VisitExistsExpr((ExistsExpr)node.Clone());
 }
Example #29
0
            private Expr CalculatePathCondition(PathInfo path)
            {
                Expr returnExpr = Expr.True;

                HashSet<Variable> existsVars = path.existsVars;
                Dictionary<Variable, Expr> existsMap = new Dictionary<Variable, Expr>();

                Dictionary<Variable, Expr> varToExpr = path.varToExpr;
                foreach (Variable v in varToExpr.Keys)
                {
                    if (postExistVars.Contains(v)) continue;
                    IdentifierExpr ie = varToExpr[v] as IdentifierExpr;
                    if (ie != null && !existsMap.ContainsKey(ie.Decl) && existsVars.Contains(ie.Decl))
                    {
                        existsMap[ie.Decl] = Expr.Ident(v);
                        existsVars.Remove(ie.Decl);
                    }
                    else
                    {
                        returnExpr = Expr.And(returnExpr, Expr.Eq(Expr.Ident(v), (new MyDuplicator()).VisitExpr(varToExpr[v])));
                        returnExpr.Type = Type.Bool;
                    }
                }

                List<Expr> pathExprs = new List<Expr>();
                path.pathExprs.ForEach(x => pathExprs.Add((new MyDuplicator()).VisitExpr(x)));
                foreach (Expr x in pathExprs)
                {
                    Variable boundVar;
                    Expr boundVarExpr;
                    if (InferSubstitution(x, out boundVar, out boundVarExpr) && existsVars.Contains(boundVar))
                    {
                        existsMap[boundVar] = boundVarExpr;
                        existsVars.Remove(boundVar);
                    }
                    else
                    {
                        returnExpr = Expr.And(returnExpr, x);
                        returnExpr.Type = Type.Bool;
                    }
                }
                
                returnExpr = Substituter.Apply(Substituter.SubstitutionFromHashtable(existsMap), returnExpr);
                if (existsVars.Count > 0)
                {
                    returnExpr = new ExistsExpr(Token.NoToken, new List<Variable>(existsVars), returnExpr);
                }
                return returnExpr;
            }