Example #1
0
 /// <summary>
 /// Creates a fresh local var of the given Type and adds it to the
 /// Bpl Implementation
 /// </summary>
 /// <param name="typeReference"> The type of the new variable </param>
 /// <returns> A fresh Variable with automatic generated name and location </returns>
 public Bpl.Variable CreateFreshLocal(ITypeReference typeReference) {
   Bpl.IToken loc = Bpl.Token.NoToken; // Helper Variables do not have a location
   Bpl.Type t = TranslationHelper.CciTypeToBoogie(typeReference);
   Bpl.LocalVariable v = new Bpl.LocalVariable(loc, new Bpl.TypedIdent(loc, TranslationHelper.GenerateTempVarName(), t));
   ILocalDefinition dummy = new LocalDefinition(); // Creates a dummy entry for the Dict, since only locals in the dict are translated to boogie
   localVarMap.Add(dummy, v);
   return v;
 }
Example #2
0
        static Bpl.LocalVariable BplLocalVar(string name, Bpl.Type ty, out Bpl.Expr e)
        {
            Contract.Requires(ty != null);
            var v = new Bpl.LocalVariable(ty.tok, new Bpl.TypedIdent(ty.tok, name, ty));

            e = new Bpl.IdentifierExpr(ty.tok, name, ty);
            return(v);
        }
Example #3
0
 /// <summary>
 /// 
 /// </summary>
 /// <param name="local"></param>
 /// <returns></returns>
 public Bpl.Variable FindOrCreateLocalVariable(ILocalDefinition local) {
   Bpl.LocalVariable v;
   Bpl.IToken tok = local.Token();
   Bpl.Type t = TranslationHelper.CciTypeToBoogie(local.Type.ResolvedType);
   if (!localVarMap.TryGetValue(local, out v)) {
     v = new Bpl.LocalVariable(tok, new Bpl.TypedIdent(tok, local.Name.Value, t));
     localVarMap.Add(local, v);
   }
   return v;
 }
Example #4
0
        void PredicateCmd(List<Cmd> cmdSeq, Cmd cmd)
        {
            if (cmd is AssignCmd) {
              var aCmd = (AssignCmd)cmd;
              cmdSeq.Add(new AssignCmd(Token.NoToken, aCmd.Lhss,
                   new List<Expr>(aCmd.Lhss.Zip(aCmd.Rhss, (lhs, rhs) =>
                     new NAryExpr(Token.NoToken,
                       new IfThenElse(Token.NoToken),
                       new List<Expr> { p, rhs, lhs.AsExpr })))));
            } else if (cmd is AssertCmd) {
              var aCmd = (AssertCmd)cmd;
              if (cmdSeq.Last() is AssignCmd &&
              cmdSeq.Cast<Cmd>().SkipEnd(1).All(c => c is AssertCmd)) {
            // This may be a loop invariant.  Make sure it continues to appear as
            // the first statement in the block.
            var assign = cmdSeq.Last();
            cmdSeq.RemoveAt(cmdSeq.Count-1);
            Expr newExpr = new EnabledReplacementVisitor(pExpr).VisitExpr(aCmd.Expr);
            aCmd.Expr = QKeyValue.FindBoolAttribute(aCmd.Attributes, "do_not_predicate") ? newExpr : Expr.Imp(pExpr, newExpr);
            cmdSeq.Add(aCmd);
            // cmdSeq.Add(new AssertCmd(aCmd.tok, Expr.Imp(pExpr, aCmd.Expr)));
            cmdSeq.Add(assign);
              } else {
            aCmd.Expr = Expr.Imp(p, aCmd.Expr);
            cmdSeq.Add(aCmd);
            // cmdSeq.Add(new AssertCmd(aCmd.tok, Expr.Imp(p, aCmd.Expr)));
              }
            } else if (cmd is AssumeCmd) {
              var aCmd = (AssumeCmd)cmd;
              cmdSeq.Add(new AssumeCmd(Token.NoToken, Expr.Imp(p, aCmd.Expr)));
            } else if (cmd is HavocCmd) {
              var hCmd = (HavocCmd)cmd;
              foreach (IdentifierExpr v in hCmd.Vars) {
            Microsoft.Boogie.Type type = v.Decl.TypedIdent.Type;
            Contract.Assert(type != null);

            IdentifierExpr havocTempExpr;
            if (havocVars.ContainsKey(type)) {
              havocTempExpr = havocVars[type];
            } else {
              var havocVar = new LocalVariable(Token.NoToken,
                             new TypedIdent(Token.NoToken,
                                            "_HAVOC_" + type.ToString(), type));
              impl.LocVars.Add(havocVar);
              havocVars[type] = havocTempExpr =
            new IdentifierExpr(Token.NoToken, havocVar);
            }
            cmdSeq.Add(new HavocCmd(Token.NoToken,
                                new List<IdentifierExpr> { havocTempExpr }));
            cmdSeq.Add(Cmd.SimpleAssign(Token.NoToken, v,
                                    new NAryExpr(Token.NoToken,
                                      new IfThenElse(Token.NoToken),
                                      new List<Expr> { p, havocTempExpr, v })));
              }
            } else if (cmd is CallCmd) {
              Debug.Assert(useProcedurePredicates);
              var cCmd = (CallCmd)cmd;
              cCmd.Ins.Insert(0, p);
              cmdSeq.Add(cCmd);
            }
            else if (cmd is CommentCmd) {
              // skip
            }
            else if (cmd is StateCmd) {
              var sCmd = (StateCmd)cmd;
              var newCmdSeq = new List<Cmd>();
              foreach (Cmd c in sCmd.Cmds)
            PredicateCmd(newCmdSeq, c);
              sCmd.Cmds = newCmdSeq;
              cmdSeq.Add(sCmd);
            }
            else {
              Console.WriteLine("Unsupported cmd: " + cmd.GetType().ToString());
            }
        }
Example #5
0
 public override LocalVariable VisitLocalVariable(LocalVariable node)
 {
     Contract.Ensures(Contract.Result<LocalVariable>() == node);
     return node;
 }
Example #6
0
 public override LocalVariable VisitLocalVariable(LocalVariable node) {
   //Contract.Requires(node != null);
   Contract.Ensures(Contract.Result<LocalVariable>() != null);
   return base.VisitLocalVariable((LocalVariable)node.Clone());
 }
Example #7
0
 private void ProcessLoopHeaders(Implementation impl, Graph<Block> graph, HashSet<Block> yieldingHeaders, 
     Dictionary<string, Variable> domainNameToInputVar, Dictionary<string, Variable> domainNameToLocalVar, Dictionary<Variable, Variable> ogOldGlobalMap,
     out List<Variable> oldPcs, out List<Variable> oldOks)
 {
     oldPcs = new List<Variable>();
     oldOks = new List<Variable>();
     foreach (Block header in yieldingHeaders)
     {
         LocalVariable oldPc = null;
         LocalVariable oldOk = null;
         if (pc != null)
         {
             oldPc = new LocalVariable(Token.NoToken, new TypedIdent(Token.NoToken, string.Format("{0}_{1}", pc.Name, header.Label), Type.Bool));
             oldPcs.Add(oldPc);
             oldOk = new LocalVariable(Token.NoToken, new TypedIdent(Token.NoToken, string.Format("{0}_{1}", ok.Name, header.Label), Type.Bool));
             oldOks.Add(oldOk);
         }
         Dictionary<string, Expr> domainNameToExpr = ComputeAvailableExprs(AvailableLinearVars(header), domainNameToInputVar);
         foreach (Block pred in header.Predecessors)
         {
             AddCallToYieldProc(header.tok, pred.Cmds, ogOldGlobalMap, domainNameToLocalVar);
             if (pc != null && !graph.BackEdgeNodes(header).Contains(pred))
             {
                 pred.Cmds.Add(new AssignCmd(Token.NoToken, new List<AssignLhs>(
                     new AssignLhs[] { new SimpleAssignLhs(Token.NoToken, Expr.Ident(oldPc)), new SimpleAssignLhs(Token.NoToken, Expr.Ident(oldOk)) }),
                     new List<Expr>(new Expr[] { Expr.Ident(pc), Expr.Ident(ok) })));
             }
             AddUpdatesToOldGlobalVars(pred.Cmds, ogOldGlobalMap, domainNameToLocalVar, domainNameToExpr);
         }
         List<Cmd> newCmds = new List<Cmd>();
         if (pc != null)
         {
             AssertCmd assertCmd;
             assertCmd = new AssertCmd(header.tok, Expr.Eq(Expr.Ident(oldPc), Expr.Ident(pc)));
             assertCmd.ErrorData = "Specification state must not change for transitions ending in loop headers";
             newCmds.Add(assertCmd);
             assertCmd = new AssertCmd(header.tok, Expr.Imp(Expr.Ident(oldOk), Expr.Ident(ok)));
             assertCmd.ErrorData = "Specification state must not change for transitions ending in loop headers";
             newCmds.Add(assertCmd);
         }
         foreach (string domainName in linearTypeChecker.linearDomains.Keys)
         {
             newCmds.Add(new AssumeCmd(Token.NoToken, Expr.Eq(Expr.Ident(domainNameToLocalVar[domainName]), domainNameToExpr[domainName])));
         }
         foreach (Variable v in ogOldGlobalMap.Keys)
         {
             newCmds.Add(new AssumeCmd(Token.NoToken, Expr.Eq(Expr.Ident(v), Expr.Ident(ogOldGlobalMap[v]))));
         }
         newCmds.AddRange(header.Cmds);
         header.Cmds = newCmds;
     }
 }
Example #8
0
  void PredicateCmd(Expr p, Expr pDom, List<Cmd> cmdSeq, Cmd cmd) {
    if (cmd is CallCmd) {
      var cCmd = (CallCmd)cmd;
      Debug.Assert(useProcedurePredicates(cCmd.Proc));
      cCmd.Ins.Insert(0, p != null ? p : Expr.True);
      cmdSeq.Add(cCmd);
    } else if (p == null) {
      new EnabledReplacementVisitor(Expr.True, pDom).Visit(cmd);
      cmdSeq.Add(cmd);
    } else if (cmd is AssignCmd) {
      var aCmd = (AssignCmd)cmd;
      cmdSeq.Add(new AssignCmd(Token.NoToken, aCmd.Lhss,
                   new List<Expr>(aCmd.Lhss.Zip(aCmd.Rhss, (lhs, rhs) =>
                     new NAryExpr(Token.NoToken,
                       new IfThenElse(Token.NoToken),
                       new List<Expr> { p, rhs, lhs.AsExpr })))));
    } else if (cmd is AssertCmd) {
      var aCmd = (AssertCmd)cmd;
      Expr newExpr = new EnabledReplacementVisitor(p, pDom).VisitExpr(aCmd.Expr);
      aCmd.Expr = QKeyValue.FindBoolAttribute(aCmd.Attributes, "do_not_predicate") ? newExpr : Expr.Imp(p, newExpr);
      cmdSeq.Add(aCmd);
    } else if (cmd is AssumeCmd) {
      var aCmd = (AssumeCmd)cmd;
      Expr newExpr = new EnabledReplacementVisitor(p, pDom).VisitExpr(aCmd.Expr);
      aCmd.Expr = QKeyValue.FindBoolAttribute(aCmd.Attributes, "do_not_predicate") ? newExpr : Expr.Imp(p, newExpr);
      cmdSeq.Add(aCmd);
    } else if (cmd is HavocCmd) {
      var hCmd = (HavocCmd)cmd;
      foreach (IdentifierExpr v in hCmd.Vars) {
        Microsoft.Boogie.Type type = v.Decl.TypedIdent.Type;
        Contract.Assert(type != null);

        IdentifierExpr havocTempExpr;
        if (havocVars.ContainsKey(type)) {
          havocTempExpr = havocVars[type];
        } else {
          var havocVar = new LocalVariable(Token.NoToken,
                             new TypedIdent(Token.NoToken,
                                            "_HAVOC_" + type.ToString(), type));
          impl.LocVars.Add(havocVar);
          havocVars[type] = havocTempExpr =
            new IdentifierExpr(Token.NoToken, havocVar);
        }
        cmdSeq.Add(new HavocCmd(Token.NoToken,
                                new List<IdentifierExpr> { havocTempExpr }));
        cmdSeq.Add(Cmd.SimpleAssign(Token.NoToken, v,
                                    new NAryExpr(Token.NoToken,
                                      new IfThenElse(Token.NoToken),
                                      new List<Expr> { p, havocTempExpr, v })));
      }
    } else if (cmd is CommentCmd) {
      // skip
    } else if (cmd is StateCmd) {
      var sCmd = (StateCmd)cmd;
      var newCmdSeq = new List<Cmd>();
      foreach (Cmd c in sCmd.Cmds)
        PredicateCmd(p, pDom, newCmdSeq, c);
      sCmd.Cmds = newCmdSeq;
      cmdSeq.Add(sCmd);
    } else {
      Console.WriteLine("Unsupported cmd: " + cmd.GetType().ToString());
    }
  }
    public Implementation Inject(Implementation implementation, Program programInCachedSnapshot)
    {
      Contract.Requires(implementation != null && programInCachedSnapshot != null);

      this.programInCachedSnapshot = programInCachedSnapshot;
      assumptionVariableCount = 0;
      temporaryVariableCount = 0;
      currentImplementation = implementation;

      #region Introduce explict assumption about the precondition.

      var oldProc = programInCachedSnapshot.FindProcedure(currentImplementation.Proc.Name);
      if (oldProc != null
          && oldProc.DependencyChecksum != currentImplementation.Proc.DependencyChecksum
          && currentImplementation.ExplicitAssumptionAboutCachedPrecondition == null)
      {
        var axioms = new List<Axiom>();
        var after = new List<Cmd>();
        Expr assumedExpr = new LiteralExpr(Token.NoToken, false);
        var canUseSpecs = DependencyCollector.CanExpressOldSpecs(oldProc, Program, true);
        if (canUseSpecs && oldProc.SignatureEquals(currentImplementation.Proc))
        {
          var always = Substituter.SubstitutionFromHashtable(currentImplementation.GetImplFormalMap(), true, currentImplementation.Proc);
          var forOld = Substituter.SubstitutionFromHashtable(new Dictionary<Variable, Expr>());
          var clauses = oldProc.Requires.Select(r => Substituter.FunctionCallReresolvingApply(always, forOld, r.Condition, Program));
          var conj = Expr.And(clauses, true);
          assumedExpr = conj != null ? FunctionExtractor.Extract(conj, Program, axioms) : new LiteralExpr(Token.NoToken, true);
        }

        if (assumedExpr != null)
        {
          var lv = new LocalVariable(Token.NoToken,
            new TypedIdent(Token.NoToken, string.Format("a##cached##{0}", FreshAssumptionVariableName), Type.Bool),
            new QKeyValue(Token.NoToken, "assumption", new List<object>(), null));
          currentImplementation.InjectAssumptionVariable(lv, !canUseSpecs);
          var lhs = new SimpleAssignLhs(Token.NoToken, new IdentifierExpr(Token.NoToken, lv));
          var rhs = LiteralExpr.And(new IdentifierExpr(Token.NoToken, lv), assumedExpr);
          var assumed = new AssignCmd(currentImplementation.tok, new List<AssignLhs> { lhs }, new List<Expr> { rhs });
          assumed.IrrelevantForChecksumComputation = true;
          currentImplementation.ExplicitAssumptionAboutCachedPrecondition = assumed;
          after.Add(assumed);
        }

        if (CommandLineOptions.Clo.TraceCachingForTesting || CommandLineOptions.Clo.TraceCachingForBenchmarking)
        {
          using (var tokTxtWr = new TokenTextWriter("<console>", Console.Out, false, false))
          {
            var loc = currentImplementation.tok != null && currentImplementation.tok != Token.NoToken ? string.Format("{0}({1},{2})", currentImplementation.tok.filename, currentImplementation.tok.line, currentImplementation.tok.col) : "<unknown location>";
            Console.Out.WriteLine("Processing implementation {0} (at {1}):", currentImplementation.Name, loc);
            foreach (var a in axioms)
            {
              Console.Out.Write("  >>> added axiom: ");
              a.Expr.Emit(tokTxtWr);
              Console.Out.WriteLine();
            }
            foreach (var b in after)
            {
              Console.Out.Write("  >>> added after assuming the current precondition: ");
              b.Emit(tokTxtWr, 0);
            }
          }
        }
      }

      #endregion

      var result = VisitImplementation(currentImplementation);
      currentImplementation = null;
      this.programInCachedSnapshot = null;
      return result;
    }
        public Bpl.Procedure addHandlerStubCaller(Sink sink, IMethodDefinition def)
        {
            MethodBody       callerBody = new MethodBody();
            MethodDefinition callerDef  = new MethodDefinition()
            {
                InternFactory            = (def as MethodDefinition).InternFactory,
                ContainingTypeDefinition = def.ContainingTypeDefinition,
                IsStatic = true,
                Name     = sink.host.NameTable.GetNameFor("BOOGIE_STUB_CALLER_" + def.Name.Value),
                Type     = sink.host.PlatformType.SystemVoid,
                Body     = callerBody,
            };

            callerBody.MethodDefinition = callerDef;
            Sink.ProcedureInfo procInfo   = sink.FindOrCreateProcedure(def);
            Sink.ProcedureInfo callerInfo = sink.FindOrCreateProcedure(callerDef);

            Bpl.LocalVariable[]  localVars = new Bpl.LocalVariable[procInfo.Decl.InParams.Count];
            Bpl.IdentifierExpr[] varExpr   = new Bpl.IdentifierExpr[procInfo.Decl.InParams.Count];
            for (int i = 0; i < procInfo.Decl.InParams.Count; i++)
            {
                Bpl.LocalVariable loc = new Bpl.LocalVariable(Bpl.Token.NoToken,
                                                              new Bpl.TypedIdent(Bpl.Token.NoToken, TranslationHelper.GenerateTempVarName(),
                                                                                 procInfo.Decl.InParams[i].TypedIdent.Type));
                localVars[i] = loc;
                varExpr[i]   = new Bpl.IdentifierExpr(Bpl.Token.NoToken, loc);
            }

            Bpl.StmtListBuilder builder = new Bpl.StmtListBuilder();
            builder.Add(getResetNavigationCheck(sink));

            string pageXaml = PhoneCodeHelper.instance().PhonePlugin.getXAMLForPage(def.ContainingTypeDefinition.ToString());

            Bpl.Variable boogieCurrentURI = sink.FindOrCreateFieldVariable(PhoneCodeHelper.CurrentURIFieldDefinition);
            Bpl.Constant boogieXamlConstant;
            if (pageXaml != null)
            {
                boogieXamlConstant = sink.FindOrCreateConstant(pageXaml);
            }
            else
            {
                boogieXamlConstant = null;
            }
            // NAVIGATION TODO: For now just assume we are in this page to be able to call the handler, this is NOT true for any handler
            // NAVIGATION TODO: ie, a network event handler
            if (boogieXamlConstant != null)
            {
                Bpl.AssumeCmd assumeCurrentPage =
                    new Bpl.AssumeCmd(Bpl.Token.NoToken,
                                      Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Eq, new Bpl.IdentifierExpr(Bpl.Token.NoToken, boogieCurrentURI),
                                                      new Bpl.IdentifierExpr(Bpl.Token.NoToken, boogieXamlConstant)));
                builder.Add(assumeCurrentPage);
            }

            // NAVIGATION TODO: have to do the pair generation all in one go instead of having different files that need to be sed'ed
            boogieXamlConstant = sink.FindOrCreateConstant(BOOGIE_STARTING_URI_PLACEHOLDER);
            Bpl.AssumeCmd assumeStartPage = new Bpl.AssumeCmd(Bpl.Token.NoToken,
                                                              Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Eq, new Bpl.IdentifierExpr(Bpl.Token.NoToken, boogieCurrentURI),
                                                                              new Bpl.IdentifierExpr(Bpl.Token.NoToken, boogieXamlConstant)));
            builder.Add(assumeStartPage);
            builder.Add(new Bpl.CallCmd(Bpl.Token.NoToken, procInfo.Decl.Name, new List <Bpl.Expr>(varExpr), new List <Bpl.IdentifierExpr>()));
            boogieXamlConstant = sink.FindOrCreateConstant(BOOGIE_ENDING_URI_PLACEHOLDER);
            Bpl.AssertCmd assertEndPage = new Bpl.AssertCmd(Bpl.Token.NoToken,
                                                            Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Neq, new Bpl.IdentifierExpr(Bpl.Token.NoToken, boogieCurrentURI),
                                                                            new Bpl.IdentifierExpr(Bpl.Token.NoToken, boogieXamlConstant)));

            Bpl.Expr            guard       = new Bpl.IdentifierExpr(Bpl.Token.NoToken, sink.FindOrCreateGlobalVariable(PhoneCodeHelper.BOOGIE_NAVIGATION_CHECK_VARIABLE, Bpl.Type.Bool));
            Bpl.StmtListBuilder thenBuilder = new Bpl.StmtListBuilder();
            thenBuilder.Add(assertEndPage);
            Bpl.IfCmd ifNavigated = new Bpl.IfCmd(Bpl.Token.NoToken, guard, thenBuilder.Collect(Bpl.Token.NoToken), null, new Bpl.StmtListBuilder().Collect(Bpl.Token.NoToken));

            builder.Add(ifNavigated);
            Bpl.Implementation impl =
                new Bpl.Implementation(Bpl.Token.NoToken, callerInfo.Decl.Name, new List <Bpl.TypeVariable>(), new List <Bpl.Variable>(),
                                       new List <Bpl.Variable>(), new List <Bpl.Variable>(localVars), builder.Collect(Bpl.Token.NoToken), null, new Bpl.Errors());

            sink.TranslatedProgram.AddTopLevelDeclaration(impl);
            return(impl.Proc);
        }
Example #11
0
        private static void CreateDispatchMethod(Sink sink, ITypeDefinition type, HashSet <IMethodDefinition> delegates)
        {
            Contract.Assert(type.IsDelegate);
            IMethodDefinition invokeMethod = null;

            foreach (IMethodDefinition m in type.Methods)
            {
                if (m.Name.Value == "Invoke")
                {
                    invokeMethod = m;
                    break;
                }
            }

            try {
                IMethodDefinition  unspecializedInvokeMethod = Sink.Unspecialize(invokeMethod).ResolvedMethod;
                Sink.ProcedureInfo invokeProcedureInfo       = sink.FindOrCreateProcedure(unspecializedInvokeMethod);
                Bpl.Procedure      invokeProcedure           = (Bpl.Procedure)invokeProcedureInfo.Decl;
                invokeProcedure.AddAttribute("inline", Bpl.Expr.Literal(1));
                Bpl.Formal delegateVariable = invokeProcedureInfo.ThisVariable;
                Bpl.IToken token            = invokeMethod.Token();

                List <Bpl.Variable> dispatchProcInExprs = new List <Bpl.Variable>();
                for (int i = 1; i < invokeProcedure.InParams.Count; i++)
                {
                    Bpl.Variable v = invokeProcedure.InParams[i];
                    dispatchProcInExprs.Add(v);
                }
                List <Bpl.Variable> dispatchProcOutExprs = new List <Bpl.Variable>();
                foreach (Bpl.Variable v in invokeProcedure.OutParams)
                {
                    dispatchProcOutExprs.Add(v);
                }

                List <Bpl.Variable> localVariables = new List <Bpl.Variable>();
                Bpl.StmtListBuilder stmtBuilder    = new Bpl.StmtListBuilder();
                int localCounter = 0;
                foreach (IMethodDefinition defn in delegates)
                {
                    Bpl.Constant       c = sink.FindOrCreateDelegateMethodConstant(defn);
                    Sink.ProcedureInfo delegateProcedureInfo = sink.FindOrCreateProcedure(defn);
                    Bpl.Procedure      delegateProcedure     = (Bpl.Procedure)delegateProcedureInfo.Decl;
                    Bpl.Formal         thisVariable          = delegateProcedureInfo.ThisVariable;
                    int numArguments = defn.ParameterCount;

                    List <Bpl.Variable> tempInputs  = new List <Bpl.Variable>();
                    List <Bpl.Variable> tempOutputs = new List <Bpl.Variable>();

                    for (int i = 0; i < defn.ParameterCount; i++)
                    {
                        Bpl.Variable      v             = delegateProcedure.InParams[(thisVariable == null ? 0 : 1) + i];
                        Bpl.LocalVariable localVariable = new Bpl.LocalVariable(Bpl.Token.NoToken,
                                                                                new Bpl.TypedIdent(Bpl.Token.NoToken, "local" + localCounter++, v.TypedIdent.Type));
                        localVariables.Add(localVariable);
                        tempInputs.Add(localVariable);
                    }

                    for (int i = 0; i < delegateProcedure.OutParams.Count; i++)
                    {
                        Bpl.Variable      v             = delegateProcedure.OutParams[i];
                        Bpl.LocalVariable localVariable = new Bpl.LocalVariable(Bpl.Token.NoToken,
                                                                                new Bpl.TypedIdent(Bpl.Token.NoToken, "local" + localCounter++, v.TypedIdent.Type));
                        localVariables.Add(localVariable);
                        tempOutputs.Add(localVariable);
                    }

                    List <Bpl.Expr>           ins  = new List <Bpl.Expr>();
                    List <Bpl.IdentifierExpr> outs = new List <Bpl.IdentifierExpr>();
                    if (!defn.IsStatic)
                    {
                        ins.Add(sink.ReadReceiver(Bpl.Expr.Ident(c), Bpl.Expr.Ident(delegateVariable)));
                    }
                    for (int i = 0; i < tempInputs.Count; i++)
                    {
                        ins.Add(Bpl.Expr.Ident(tempInputs[i]));
                    }
                    if (defn.IsGeneric)
                    {
                        for (int i = 0; i < defn.GenericParameterCount; i++)
                        {
                            ins.Add(new Bpl.NAryExpr(Bpl.Token.NoToken,
                                                     new Bpl.FunctionCall(sink.FindOrCreateTypeParameterFunction(i)),
                                                     new List <Bpl.Expr>(new Bpl.Expr[] { sink.ReadTypeParameters(Bpl.Expr.Ident(c), Bpl.Expr.Ident(delegateVariable)) })));
                        }
                    }
                    if (defn.IsStatic)
                    {
                        int numTypeParameters = Sink.ConsolidatedGenericParameterCount(defn.ContainingType);
                        for (int i = 0; i < numTypeParameters; i++)
                        {
                            ins.Add(new Bpl.NAryExpr(Bpl.Token.NoToken,
                                                     new Bpl.FunctionCall(sink.FindOrCreateTypeParameterFunction(i)),
                                                     new List <Bpl.Expr>(new Bpl.Expr[] { sink.ReadTypeParameters(Bpl.Expr.Ident(c), Bpl.Expr.Ident(delegateVariable)) })));
                        }
                    }
                    for (int i = 0; i < tempOutputs.Count; i++)
                    {
                        outs.Add(Bpl.Expr.Ident(tempOutputs[i]));
                    }

                    Bpl.Expr            bexpr         = sink.ReadMethod(Bpl.Expr.Ident(c), Bpl.Expr.Ident(delegateVariable));
                    Bpl.StmtListBuilder ifStmtBuilder = new Bpl.StmtListBuilder();
                    System.Diagnostics.Debug.Assert(tempInputs.Count == dispatchProcInExprs.Count);
                    if (tempInputs.Count > 0)
                    {
                        BuildAssignment(sink, ifStmtBuilder, tempInputs, dispatchProcInExprs);
                    }
                    ifStmtBuilder.Add(EmitDummySourceContext());
                    ifStmtBuilder.Add(new Bpl.CallCmd(token, delegateProcedure.Name, ins, outs));
                    System.Diagnostics.Debug.Assert(tempOutputs.Count == dispatchProcOutExprs.Count);
                    if (tempOutputs.Count > 0)
                    {
                        BuildAssignment(sink, ifStmtBuilder, dispatchProcOutExprs, tempOutputs);
                    }
                    stmtBuilder.Add(new Bpl.IfCmd(bexpr.tok, bexpr, ifStmtBuilder.Collect(bexpr.tok), null, null));
                }

                Bpl.Implementation dispatchImpl =
                    new Bpl.Implementation(token,
                                           invokeProcedure.Name,
                                           new List <Bpl.TypeVariable>(),
                                           invokeProcedure.InParams,
                                           invokeProcedure.OutParams,
                                           localVariables,
                                           stmtBuilder.Collect(token)
                                           );
                dispatchImpl.Proc = invokeProcedure;
                dispatchImpl.AddAttribute("inline", Bpl.Expr.Literal(1));
                sink.TranslatedProgram.AddTopLevelDeclaration(dispatchImpl);
            } catch (TranslationException te) {
                throw new NotImplementedException(te.ToString());
            } catch {
                throw;
            } finally {
                // Maybe this is a good place to add the procedure to the toplevel declarations
            }
        }
Example #12
0
 // We have to give the type explicitly, because the type of the formal "likeThisOne" can contain type variables
 protected Variable CreateTemporaryVariable(List<Variable> tempVars, Variable likeThisOne, Type ty, TempVarKind kind)
 {
     Contract.Requires(ty != null);
       Contract.Requires(likeThisOne != null);
       Contract.Requires(tempVars != null);
       Contract.Ensures(Contract.Result<Variable>() != null);
       string/*!*/ tempNamePrefix;
       switch (kind) {
     case TempVarKind.Formal:
       tempNamePrefix = "formal@";
       break;
     case TempVarKind.Old:
       tempNamePrefix = "old@";
       break;
     case TempVarKind.Bound:
       tempNamePrefix = "forall@";
       break;
     default: {
     Contract.Assert(false);
     throw new cce.UnreachableException();
       }  // unexpected kind
       }
       TypedIdent ti = likeThisOne.TypedIdent;
       TypedIdent newTi = new TypedIdent(ti.tok, "call" + UniqueId + tempNamePrefix + ti.Name, ty);
       Variable/*!*/ v;
       if (kind == TempVarKind.Bound) {
     v = new BoundVariable(likeThisOne.tok, newTi);
       } else {
     v = new LocalVariable(likeThisOne.tok, newTi);
     tempVars.Add(v);
       }
       return v;
 }
Example #13
0
    private static void CreateDispatchMethod(Sink sink, ITypeDefinition type, HashSet<IMethodDefinition> delegates) {
      Contract.Assert(type.IsDelegate);
      IMethodDefinition invokeMethod = null;
      foreach (IMethodDefinition m in type.Methods) {
        if (m.Name.Value == "Invoke") {
          invokeMethod = m;
          break;
        }
      }

      try {
        IMethodDefinition unspecializedInvokeMethod = Sink.Unspecialize(invokeMethod).ResolvedMethod;
        Sink.ProcedureInfo invokeProcedureInfo = sink.FindOrCreateProcedure(unspecializedInvokeMethod);
        Bpl.Procedure invokeProcedure = (Bpl.Procedure) invokeProcedureInfo.Decl;
        invokeProcedure.AddAttribute("inline", Bpl.Expr.Literal(1));
        Bpl.Formal delegateVariable = invokeProcedureInfo.ThisVariable;
        Bpl.IToken token = invokeMethod.Token();
  
        List<Bpl.Variable> dispatchProcInExprs = new List<Bpl.Variable>();
        for (int i = 1; i < invokeProcedure.InParams.Count; i++) {
          Bpl.Variable v = invokeProcedure.InParams[i];
          dispatchProcInExprs.Add(v);
        }
        List<Bpl.Variable> dispatchProcOutExprs = new List<Bpl.Variable>();
        foreach (Bpl.Variable v in invokeProcedure.OutParams) {
          dispatchProcOutExprs.Add(v);
        }
          
        List<Bpl.Variable> localVariables = new List<Bpl.Variable>();
        Bpl.StmtListBuilder stmtBuilder = new Bpl.StmtListBuilder();
        int localCounter = 0;
        foreach (IMethodDefinition defn in delegates) {
          Bpl.Constant c = sink.FindOrCreateDelegateMethodConstant(defn);
          Sink.ProcedureInfo delegateProcedureInfo = sink.FindOrCreateProcedure(defn);
          Bpl.Procedure delegateProcedure = (Bpl.Procedure)delegateProcedureInfo.Decl;
          Bpl.Formal thisVariable = delegateProcedureInfo.ThisVariable;
          int numArguments = defn.ParameterCount;

          List<Bpl.Variable> tempInputs = new List<Bpl.Variable>();
          List<Bpl.Variable> tempOutputs = new List<Bpl.Variable>();

          for (int i = 0; i < defn.ParameterCount; i++) {
            Bpl.Variable v = delegateProcedure.InParams[(thisVariable == null ? 0 : 1) + i];
            Bpl.LocalVariable localVariable = new Bpl.LocalVariable(Bpl.Token.NoToken,
              new Bpl.TypedIdent(Bpl.Token.NoToken, "local" + localCounter++, v.TypedIdent.Type));
            localVariables.Add(localVariable);
            tempInputs.Add(localVariable);
          }

          for (int i = 0; i < delegateProcedure.OutParams.Count; i++) {
            Bpl.Variable v = delegateProcedure.OutParams[i];
            Bpl.LocalVariable localVariable = new Bpl.LocalVariable(Bpl.Token.NoToken,
              new Bpl.TypedIdent(Bpl.Token.NoToken, "local" + localCounter++, v.TypedIdent.Type));
            localVariables.Add(localVariable);
            tempOutputs.Add(localVariable);
          }

          List<Bpl.Expr> ins = new List<Bpl.Expr>();
          List<Bpl.IdentifierExpr> outs = new List<Bpl.IdentifierExpr>();
          if (!defn.IsStatic)
              ins.Add(sink.ReadReceiver(Bpl.Expr.Ident(c), Bpl.Expr.Ident(delegateVariable)));
          for (int i = 0; i < tempInputs.Count; i++) {
            ins.Add(Bpl.Expr.Ident(tempInputs[i]));
          }
          if (defn.IsGeneric) {
            for (int i = 0; i < defn.GenericParameterCount; i++) {
              ins.Add(new Bpl.NAryExpr(Bpl.Token.NoToken,
                                       new Bpl.FunctionCall(sink.FindOrCreateTypeParameterFunction(i)),
                                       new List<Bpl.Expr>(new Bpl.Expr[] {sink.ReadTypeParameters(Bpl.Expr.Ident(c), Bpl.Expr.Ident(delegateVariable))})));
            }
          }
          if (defn.IsStatic) {
            int numTypeParameters = Sink.ConsolidatedGenericParameterCount(defn.ContainingType);
            for (int i = 0; i < numTypeParameters; i++) {
              ins.Add(new Bpl.NAryExpr(Bpl.Token.NoToken,
                                       new Bpl.FunctionCall(sink.FindOrCreateTypeParameterFunction(i)),
                                       new List<Bpl.Expr>(new Bpl.Expr[] {sink.ReadTypeParameters(Bpl.Expr.Ident(c), Bpl.Expr.Ident(delegateVariable))})));
            }
          }
          for (int i = 0; i < tempOutputs.Count; i++) {
            outs.Add(Bpl.Expr.Ident(tempOutputs[i]));
          }

          Bpl.Expr bexpr = sink.ReadMethod(Bpl.Expr.Ident(c), Bpl.Expr.Ident(delegateVariable));
          Bpl.StmtListBuilder ifStmtBuilder = new Bpl.StmtListBuilder();
          System.Diagnostics.Debug.Assert(tempInputs.Count == dispatchProcInExprs.Count);
          if (tempInputs.Count > 0) {
            BuildAssignment(sink, ifStmtBuilder, tempInputs, dispatchProcInExprs);
          }
          ifStmtBuilder.Add(EmitDummySourceContext());
          ifStmtBuilder.Add(new Bpl.CallCmd(token, delegateProcedure.Name, ins, outs));
          System.Diagnostics.Debug.Assert(tempOutputs.Count == dispatchProcOutExprs.Count);
          if (tempOutputs.Count > 0) {
            BuildAssignment(sink, ifStmtBuilder, dispatchProcOutExprs, tempOutputs);
          }
          stmtBuilder.Add(new Bpl.IfCmd(bexpr.tok, bexpr, ifStmtBuilder.Collect(bexpr.tok), null, null));
        }
        
        Bpl.Implementation dispatchImpl =
            new Bpl.Implementation(token,
                invokeProcedure.Name,
                new List<Bpl.TypeVariable>(),
                invokeProcedure.InParams,
                invokeProcedure.OutParams,
                localVariables,
                stmtBuilder.Collect(token)
                );
        dispatchImpl.Proc = invokeProcedure;
        dispatchImpl.AddAttribute("inline", Bpl.Expr.Literal(1));
        sink.TranslatedProgram.AddTopLevelDeclaration(dispatchImpl);
      } catch (TranslationException te) {
        throw new NotImplementedException(te.ToString());
      } catch {
        throw;
      } finally {
        // Maybe this is a good place to add the procedure to the toplevel declarations
      }
    }
Example #14
0
        private void TransformImpl(Implementation impl)
        {
            if (!QKeyValue.FindBoolAttribute(impl.Proc.Attributes, "yields")) return;

            // Find the yielding loop headers
            impl.PruneUnreachableBlocks();
            impl.ComputePredecessorsForBlocks();
            GraphUtil.Graph<Block> graph = Program.GraphFromImpl(impl);
            graph.ComputeLoops();
            if (!graph.Reducible)
            {
                throw new Exception("Irreducible flow graphs are unsupported.");
            }
            HashSet<Block> yieldingHeaders = new HashSet<Block>();
            IEnumerable<Block> sortedHeaders = graph.SortHeadersByDominance();
            foreach (Block header in sortedHeaders)
            {
                if (yieldingHeaders.Any(x => graph.DominatorMap.DominatedBy(x, header)))
                {
                    yieldingHeaders.Add(header);
                }
                else if (IsYieldingHeader(graph, header))
                {
                    yieldingHeaders.Add(header);
                }
                else
                {
                    continue;
                }
            }

            Program program = linearTypeChecker.program;
            Dictionary<Variable, Expr> map = new Dictionary<Variable, Expr>();
            foreach (Variable local in impl.LocVars)
            {
                var copy = new LocalVariable(Token.NoToken, new TypedIdent(Token.NoToken, local.Name, local.TypedIdent.Type));
                map[local] = new IdentifierExpr(Token.NoToken, copy);
            }
            Dictionary<Variable, Variable> ogOldGlobalMap = new Dictionary<Variable, Variable>();
            foreach (IdentifierExpr ie in globalMods)
            {
                Variable g = ie.Decl;
                LocalVariable l = new LocalVariable(Token.NoToken, new TypedIdent(Token.NoToken, string.Format("og_global_old_{0}", g.Name), g.TypedIdent.Type));
                ogOldGlobalMap[g] = l;
                impl.LocVars.Add(l);
            }
            Dictionary<string, Variable> domainNameToInputVar = new Dictionary<string, Variable>();
            Dictionary<string, Variable> domainNameToLocalVar = new Dictionary<string, Variable>();
            {
                int i = impl.InParams.Count - linearTypeChecker.linearDomains.Count;
                foreach (string domainName in linearTypeChecker.linearDomains.Keys)
                {
                    Variable inParam = impl.InParams[i];
                    domainNameToInputVar[domainName] = inParam;
                    Variable l = new LocalVariable(Token.NoToken, new TypedIdent(Token.NoToken, inParam.Name + "_local", inParam.TypedIdent.Type));
                    domainNameToLocalVar[domainName] = l;
                    impl.LocVars.Add(l);
                    i++;
                }
            }

            // Collect the yield predicates and desugar yields
            List<List<Cmd>> yields = new List<List<Cmd>>();
            List<Cmd> cmds = new List<Cmd>();
            foreach (Block b in impl.Blocks)
            {
                YieldCmd yieldCmd = null;
                List<Cmd> newCmds = new List<Cmd>();
                for (int i = 0; i < b.Cmds.Count; i++)
                {
                    Cmd cmd = b.Cmds[i];
                    if (cmd is YieldCmd)
                    {
                        yieldCmd = (YieldCmd)cmd;
                        continue;
                    }
                    if (yieldCmd != null)
                    {
                        PredicateCmd pcmd = cmd as PredicateCmd;
                        if (pcmd == null)
                        {
                            DesugarYield(yieldCmd, cmds, newCmds, ogOldGlobalMap, domainNameToInputVar, domainNameToLocalVar);
                            if (cmds.Count > 0)
                            {
                                yields.Add(cmds);
                                cmds = new List<Cmd>();
                            }
                            yieldCmd = null;
                        }
                        else
                        {
                            cmds.Add(pcmd);
                        }
                    }

                    if (cmd is CallCmd)
                    {
                        CallCmd callCmd = cmd as CallCmd;
                        if (callCmd.IsAsync || QKeyValue.FindBoolAttribute(callCmd.Proc.Attributes, "yields"))
                        {
                            AddCallToYieldProc(newCmds, ogOldGlobalMap, domainNameToLocalVar);
                        }
                        if (callCmd.IsAsync)
                        {
                            if (!asyncAndParallelCallDesugarings.ContainsKey(callCmd.Proc.Name))
                            {
                                asyncAndParallelCallDesugarings[callCmd.Proc.Name] = new Procedure(Token.NoToken, string.Format("DummyAsyncTarget_{0}", callCmd.Proc.Name), callCmd.Proc.TypeParameters, callCmd.Proc.InParams, callCmd.Proc.OutParams, callCmd.Proc.Requires, new List<IdentifierExpr>(), new List<Ensures>());
                            }
                            var dummyAsyncTargetProc = asyncAndParallelCallDesugarings[callCmd.Proc.Name];
                            CallCmd dummyCallCmd = new CallCmd(Token.NoToken, dummyAsyncTargetProc.Name, callCmd.Ins, callCmd.Outs);
                            dummyCallCmd.Proc = dummyAsyncTargetProc;
                            newCmds.Add(dummyCallCmd);
                        }
                        else
                        {
                            newCmds.Add(callCmd);
                        }
                        if (callCmd.IsAsync || QKeyValue.FindBoolAttribute(callCmd.Proc.Attributes, "yields"))
                        {
                            HashSet<Variable> availableLinearVars = new HashSet<Variable>(AvailableLinearVars(callCmd));
                            foreach (IdentifierExpr ie in callCmd.Outs)
                            {
                                if (linearTypeChecker.FindDomainName(ie.Decl) == null) continue;
                                availableLinearVars.Add(ie.Decl);
                            }
                            Dictionary<string, Expr> domainNameToExpr = ComputeAvailableExprs(availableLinearVars, domainNameToInputVar);
                            AddUpdatesToOldGlobalVars(newCmds, ogOldGlobalMap, domainNameToLocalVar, domainNameToExpr);
                        }
                    }
                    else if (cmd is ParCallCmd)
                    {
                        ParCallCmd parCallCmd = cmd as ParCallCmd;
                        AddCallToYieldProc(newCmds, ogOldGlobalMap, domainNameToLocalVar);
                        DesugarParallelCallCmd(newCmds, parCallCmd);
                        HashSet<Variable> availableLinearVars = new HashSet<Variable>(AvailableLinearVars(parCallCmd));
                        foreach (CallCmd callCmd in parCallCmd.CallCmds)
                        {
                            foreach (IdentifierExpr ie in callCmd.Outs)
                            {
                                if (linearTypeChecker.FindDomainName(ie.Decl) == null) continue;
                                availableLinearVars.Add(ie.Decl);
                            }
                        }
                        Dictionary<string, Expr> domainNameToExpr = ComputeAvailableExprs(availableLinearVars, domainNameToInputVar);
                        AddUpdatesToOldGlobalVars(newCmds, ogOldGlobalMap, domainNameToLocalVar, domainNameToExpr);
                    }
                    else
                    {
                        newCmds.Add(cmd);
                    }
                }
                if (yieldCmd != null)
                {
                    DesugarYield(yieldCmd, cmds, newCmds, ogOldGlobalMap, domainNameToInputVar, domainNameToLocalVar);
                    if (cmds.Count > 0)
                    {
                        yields.Add(cmds);
                        cmds = new List<Cmd>();
                    }
                }
                if (b.TransferCmd is ReturnCmd && QKeyValue.FindBoolAttribute(impl.Proc.Attributes, "yields"))
                {
                    AddCallToYieldProc(newCmds, ogOldGlobalMap, domainNameToLocalVar);
                }
                b.Cmds = newCmds;
            }

            foreach (Block header in yieldingHeaders)
            {
                Dictionary<string, Expr> domainNameToExpr = ComputeAvailableExprs(AvailableLinearVars(header), domainNameToInputVar);
                foreach (Block pred in header.Predecessors)
                {
                    AddCallToYieldProc(pred.Cmds, ogOldGlobalMap, domainNameToLocalVar);
                    AddUpdatesToOldGlobalVars(pred.Cmds, ogOldGlobalMap, domainNameToLocalVar, domainNameToExpr);
                }
                List<Cmd> newCmds = new List<Cmd>();
                foreach (string domainName in linearTypeChecker.linearDomains.Keys)
                {
                    newCmds.Add(new AssumeCmd(Token.NoToken, Expr.Binary(BinaryOperator.Opcode.Eq, Expr.Ident(domainNameToLocalVar[domainName]), domainNameToExpr[domainName])));
                }
                foreach (Variable v in ogOldGlobalMap.Keys)
                {
                    newCmds.Add(new AssumeCmd(Token.NoToken, Expr.Binary(BinaryOperator.Opcode.Eq, new IdentifierExpr(Token.NoToken, v), Expr.Ident(ogOldGlobalMap[v]))));
                }
                newCmds.AddRange(header.Cmds);
                header.Cmds = newCmds;
            }

            {
                // Add initial block
                List<AssignLhs> lhss = new List<AssignLhs>();
                List<Expr> rhss = new List<Expr>();
                Dictionary<string, Expr> domainNameToExpr = new Dictionary<string, Expr>();
                foreach (var domainName in linearTypeChecker.linearDomains.Keys)
                {
                    domainNameToExpr[domainName] = new IdentifierExpr(Token.NoToken, domainNameToInputVar[domainName]);
                }
                for (int i = 0; i < impl.InParams.Count - linearTypeChecker.linearDomains.Count; i++)
                {
                    Variable v = impl.InParams[i];
                    var domainName = linearTypeChecker.FindDomainName(v);
                    if (domainName == null) continue;
                    var domain = linearTypeChecker.linearDomains[domainName];
                    IdentifierExpr ie = new IdentifierExpr(Token.NoToken, v);
                    domainNameToExpr[domainName] = new NAryExpr(Token.NoToken, new FunctionCall(domain.mapOrBool), new List<Expr> { v.TypedIdent.Type is MapType ? ie : linearTypeChecker.Singleton(ie, domainName), domainNameToExpr[domainName] });
                }
                foreach (string domainName in linearTypeChecker.linearDomains.Keys)
                {
                    lhss.Add(new SimpleAssignLhs(Token.NoToken, new IdentifierExpr(Token.NoToken, domainNameToLocalVar[domainName])));
                    rhss.Add(domainNameToExpr[domainName]);
                }
                foreach (Variable g in ogOldGlobalMap.Keys)
                {
                    lhss.Add(new SimpleAssignLhs(Token.NoToken, Expr.Ident(ogOldGlobalMap[g])));
                    rhss.Add(Expr.Ident(g));
                }
                if (lhss.Count > 0)
                {
                    Block initBlock = new Block(Token.NoToken, "og_init", new List<Cmd> { new AssignCmd(Token.NoToken, lhss, rhss) }, new GotoCmd(Token.NoToken, new List<String> { impl.Blocks[0].Label }, new List<Block> { impl.Blocks[0] }));
                    impl.Blocks.Insert(0, initBlock);
                }
            }

            CreateYieldCheckerImpl(impl, yields, map);
        }
Example #15
0
        void PredicateImplementation()
        {
            blockGraph = prog.ProcessLoops(impl);
            var sortedBlocks = blockGraph.LoopyTopSort();

            int blockId = 0;
            foreach (var block in impl.Blocks)
              blockIds[block] = Expr.Literal(blockId++);
            returnBlockId = Expr.Literal(blockId++);

            curVar = new LocalVariable(Token.NoToken,
                               new TypedIdent(Token.NoToken, "cur",
                                              Microsoft.Boogie.Type.Int));
            impl.LocVars.Add(curVar);
            cur = Expr.Ident(curVar);

            pVar = new LocalVariable(Token.NoToken,
                             new TypedIdent(Token.NoToken, "p",
                                            Microsoft.Boogie.Type.Bool));
            impl.LocVars.Add(pVar);
            p = Expr.Ident(pVar);

            if (useProcedurePredicates)
              fp = Expr.Ident(impl.InParams[0]);

            var newBlocks = new List<Block>();

            Block entryBlock = new Block();
            entryBlock.Label = "entry";
            entryBlock.Cmds = new List<Cmd> { Cmd.SimpleAssign(Token.NoToken, cur,
                        CreateIfFPThenElse(blockIds[sortedBlocks[0].Item1],
                                           returnBlockId)) };
            newBlocks.Add(entryBlock);

            var prevBlock = entryBlock;
            foreach (var n in sortedBlocks) {
              if (n.Item2) {
            var backedgeBlock = new Block();
            newBlocks.Add(backedgeBlock);

            backedgeBlock.Label = n.Item1.Label + ".backedge";
            backedgeBlock.Cmds = new List<Cmd> { new AssumeCmd(Token.NoToken,
              Expr.Eq(cur, blockIds[n.Item1]),
              new QKeyValue(Token.NoToken, "backedge", new List<object>(), null)) };
            backedgeBlock.TransferCmd = new GotoCmd(Token.NoToken,
                                                new List<Block> { n.Item1 });

            var tailBlock = new Block();
            newBlocks.Add(tailBlock);

            tailBlock.Label = n.Item1.Label + ".tail";
            tailBlock.Cmds = new List<Cmd> { new AssumeCmd(Token.NoToken,
                                             Expr.Neq(cur, blockIds[n.Item1])) };

            prevBlock.TransferCmd = new GotoCmd(Token.NoToken,
                                        new List<Block> { backedgeBlock, tailBlock });
            prevBlock = tailBlock;
              } else {
            var runBlock = n.Item1;
            var oldCmdSeq = runBlock.Cmds;
            runBlock.Cmds = new List<Cmd>();
            newBlocks.Add(runBlock);
            prevBlock.TransferCmd = new GotoCmd(Token.NoToken,
                                            new List<Block> { runBlock });

            pExpr = Expr.Eq(cur, blockIds[runBlock]);
            if (createCandidateInvariants && blockGraph.Headers.Contains(runBlock)) {
              AddUniformCandidateInvariant(runBlock.Cmds, runBlock);
              AddNonUniformCandidateInvariant(runBlock.Cmds, runBlock);
            }
            runBlock.Cmds.Add(Cmd.SimpleAssign(Token.NoToken, p, pExpr));
            var transferCmd = runBlock.TransferCmd;
            foreach (Cmd cmd in oldCmdSeq)
              PredicateCmd(newBlocks, runBlock, cmd, out runBlock);
            PredicateTransferCmd(runBlock.Cmds, transferCmd);

            prevBlock = runBlock;
            doneBlocks.Add(runBlock);
              }
            }

            prevBlock.TransferCmd = new ReturnCmd(Token.NoToken);
            impl.Blocks = newBlocks;
        }
Example #16
0
    protected void BeginInline(Implementation impl) {
      Contract.Requires(impl != null);
      Contract.Requires(impl.Proc != null);
      Contract.Requires(newModifies != null);
      Contract.Requires(newLocalVars != null);
      
      Dictionary<Variable, Expr> substMap = new Dictionary<Variable, Expr>();
      Procedure proc = impl.Proc;

      foreach (Variable/*!*/ locVar in cce.NonNull(impl.OriginalLocVars)) {
        Contract.Assert(locVar != null);
        LocalVariable localVar = new LocalVariable(Token.NoToken, new TypedIdent(Token.NoToken, GetProcVarName(proc.Name, locVar.Name), locVar.TypedIdent.Type, locVar.TypedIdent.WhereExpr));
        localVar.Attributes = locVar.Attributes; // copy attributes
        newLocalVars.Add(localVar);
        IdentifierExpr ie = new IdentifierExpr(Token.NoToken, localVar);
        substMap.Add(locVar, ie);
      }

      for (int i = 0; i < impl.InParams.Count; i++) {
        Variable inVar = cce.NonNull(impl.InParams[i]);
        LocalVariable localVar = new LocalVariable(Token.NoToken, new TypedIdent(Token.NoToken, GetProcVarName(proc.Name, inVar.Name), inVar.TypedIdent.Type, inVar.TypedIdent.WhereExpr));
        newLocalVars.Add(localVar);
        if (impl.Proc != null) localVar.Attributes = impl.Proc.InParams[i].Attributes; // copy attributes
        IdentifierExpr ie = new IdentifierExpr(Token.NoToken, localVar);
        substMap.Add(inVar, ie);
        // also add a substitution from the corresponding formal occurring in the PROCEDURE declaration
        Variable procInVar = cce.NonNull(proc.InParams[i]);
        if (procInVar != inVar) {
          substMap.Add(procInVar, ie);
        }
      }

      for (int i = 0; i < impl.OutParams.Count; i++) {
        Variable outVar = cce.NonNull(impl.OutParams[i]);
        LocalVariable localVar = new LocalVariable(Token.NoToken, new TypedIdent(Token.NoToken, GetProcVarName(proc.Name, outVar.Name), outVar.TypedIdent.Type, outVar.TypedIdent.WhereExpr));
        if (impl.Proc != null) localVar.Attributes = impl.Proc.OutParams[i].Attributes; // copy attributes
        newLocalVars.Add(localVar);
        IdentifierExpr ie = new IdentifierExpr(Token.NoToken, localVar);
        substMap.Add(outVar, ie);
        // also add a substitution from the corresponding formal occurring in the PROCEDURE declaration
        Variable procOutVar = cce.NonNull(proc.OutParams[i]);
        if (procOutVar != outVar) {
          substMap.Add(procOutVar, ie);
        }
      }

      Dictionary<Variable, Expr> substMapOld = new Dictionary<Variable, Expr>();

      foreach (IdentifierExpr/*!*/ mie in proc.Modifies) {
        Contract.Assert(mie != null);
        Variable/*!*/ mVar = cce.NonNull(mie.Decl);
        LocalVariable localVar = new LocalVariable(Token.NoToken, new TypedIdent(Token.NoToken, GetProcVarName(proc.Name, mVar.Name), mVar.TypedIdent.Type));
        newLocalVars.Add(localVar);
        IdentifierExpr ie = new IdentifierExpr(Token.NoToken, localVar);
        substMapOld.Add(mVar, ie);
        // FIXME why are we doing this? the modifies list should already include them.
        // add the modified variable to the modifies list of the procedure
        if (!newModifies.Contains(mie)) {
          newModifies.Add(mie);
        }
      }

      codeCopier.Subst = Substituter.SubstitutionFromHashtable(substMap);
      codeCopier.OldSubst = Substituter.SubstitutionFromHashtable(substMapOld);
    }
Example #17
0
    public override Cmd VisitCallCmd(CallCmd node)
    {
      var result = base.VisitCallCmd(node);

      var oldProc = programInCachedSnapshot.FindProcedure(node.Proc.Name);
      if (oldProc != null
          && oldProc.DependencyChecksum != node.Proc.DependencyChecksum
          && node.AssignedAssumptionVariable == null)
      {
        var before = new List<Cmd>();
        var beforePrecondtionCheck = new List<Cmd>();
        var after = new List<Cmd>();
        var axioms = new List<Axiom>();
        Expr assumedExpr = new LiteralExpr(Token.NoToken, false);
        // TODO(wuestholz): Try out two alternatives: only do this for low priority implementations or not at all.
        var canUseSpecs = DependencyCollector.CanExpressOldSpecs(oldProc, Program);
        if (canUseSpecs && oldProc.SignatureEquals(node.Proc))
        {
          var desugaring = node.Desugaring;
          Contract.Assert(desugaring != null);
          var precond = node.CheckedPrecondition(oldProc, Program, e => FunctionExtractor.Extract(e, Program, axioms));
          if (precond != null)
          {
            var assume = new AssumeCmd(node.tok, precond, new QKeyValue(Token.NoToken, "precondition_previous_snapshot", new List<object>(), null));
            assume.IrrelevantForChecksumComputation = true;
            beforePrecondtionCheck.Add(assume);
          }

          var unmods = node.UnmodifiedBefore(oldProc);
          var eqs = new List<Expr>();
          foreach (var unmod in unmods)
          {
            var oldUnmod = new LocalVariable(Token.NoToken,
              new TypedIdent(Token.NoToken, string.Format("{0}##old##{1}", unmod.Name, FreshTemporaryVariableName), unmod.Type));
            var lhs = new SimpleAssignLhs(Token.NoToken, new IdentifierExpr(Token.NoToken, oldUnmod));
            var rhs = new IdentifierExpr(Token.NoToken, unmod.Decl);
            var cmd = new AssignCmd(Token.NoToken, new List<AssignLhs> { lhs }, new List<Expr> { rhs });
            cmd.IrrelevantForChecksumComputation = true;
            before.Add(cmd);
            var eq = LiteralExpr.Eq(new IdentifierExpr(Token.NoToken, oldUnmod), new IdentifierExpr(Token.NoToken, unmod.Decl));
            eq.Type = Type.Bool;
            eq.TypeParameters = SimpleTypeParamInstantiation.EMPTY;
            eqs.Add(eq);
          }

          var mods = node.ModifiedBefore(oldProc);
          var oldSubst = new Dictionary<Variable, Expr>();
          foreach (var mod in mods)
          {
            var oldMod = new LocalVariable(Token.NoToken,
              new TypedIdent(Token.NoToken, string.Format("{0}##old##{1}", mod.Name, FreshTemporaryVariableName), mod.Type));
            oldSubst[mod.Decl] = new IdentifierExpr(Token.NoToken, oldMod);
            var lhs = new SimpleAssignLhs(Token.NoToken, new IdentifierExpr(Token.NoToken, oldMod));
            var rhs = new IdentifierExpr(Token.NoToken, mod.Decl);
            var cmd = new AssignCmd(Token.NoToken, new List<AssignLhs> { lhs }, new List<Expr> { rhs });
            cmd.IrrelevantForChecksumComputation = true;
            before.Add(cmd);
          }
          
          assumedExpr = node.Postcondition(oldProc, eqs, oldSubst, Program, e => FunctionExtractor.Extract(e, Program, axioms));
          if (assumedExpr == null)
          {
            assumedExpr = new LiteralExpr(Token.NoToken, true);
          }
        }

        if (assumedExpr != null)
        {
          var lv = new LocalVariable(Token.NoToken,
            new TypedIdent(Token.NoToken, string.Format("a##cached##{0}", FreshAssumptionVariableName), Type.Bool),
            new QKeyValue(Token.NoToken, "assumption", new List<object>(), null));
          node.AssignedAssumptionVariable = lv;
          currentImplementation.InjectAssumptionVariable(lv, !canUseSpecs);
          var lhs = new SimpleAssignLhs(Token.NoToken, new IdentifierExpr(Token.NoToken, lv));
          var rhs = LiteralExpr.And(new IdentifierExpr(Token.NoToken, lv), assumedExpr);
          var assumed = new AssignCmd(node.tok, new List<AssignLhs> { lhs }, new List<Expr> { rhs });
          assumed.IrrelevantForChecksumComputation = true;
          after.Add(assumed);
        }

        node.ExtendDesugaring(before, beforePrecondtionCheck, after);
        if (CommandLineOptions.Clo.TraceCachingForTesting || CommandLineOptions.Clo.TraceCachingForBenchmarking)
        {
          using (var tokTxtWr = new TokenTextWriter("<console>", Console.Out, false, false))
          {
            var loc = node.tok != null && node.tok != Token.NoToken ? string.Format("{0}({1},{2})", node.tok.filename, node.tok.line, node.tok.col) : "<unknown location>";
            Console.Out.WriteLine("Processing call to procedure {0} in implementation {1} (at {2}):", node.Proc.Name, currentImplementation.Name, loc);
            foreach (var a in axioms)
            {
              Console.Out.Write("  >>> added axiom: ");
              a.Expr.Emit(tokTxtWr);
              Console.Out.WriteLine();
            }
            foreach (var b in before)
            {
              Console.Out.Write("  >>> added before: ");
              b.Emit(tokTxtWr, 0);
            }
            foreach (var b in beforePrecondtionCheck)
            {
              Console.Out.Write("  >>> added before precondition check: ");
              b.Emit(tokTxtWr, 0);
            }
            foreach (var a in after)
            {
              Console.Out.Write("  >>> added after: ");
              a.Emit(tokTxtWr, 0);
            }
          }
        }
      }

      return result;
    }
    /// <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 #19
0
 Variable FreshPredicate(ref int predCount) {
   var pVar = new LocalVariable(Token.NoToken,
                                new TypedIdent(Token.NoToken,
                                               "p" + predCount++,
                                               Microsoft.Boogie.Type.Bool));
   impl.LocVars.Add(pVar);
   return pVar;
 }
Example #20
0
        /// <summary>
        /// Add additional variable to allow checking as described in the paper
        /// "It's doomed; we can prove it"
        /// </summary>
        private List<Cmd> GenerateReachabilityPredicates(Implementation impl)
        {
            Contract.Requires(impl != null);

            foreach (Block b in impl.Blocks)
            {
            Contract.Assert(b != null);
            //if (b.Predecessors.Length==0) continue;
            //if (b.Cmds.Length == 0 ) continue;

            Variable v_ = new LocalVariable(Token.NoToken,
                                    new TypedIdent(b.tok, b.Label + reachvarsuffix, new BasicType(SimpleType.Int )));

            impl.LocVars.Add(v_);

            m_BlockReachabilityMap[b] = v_;

            IdentifierExpr lhs = new IdentifierExpr(b.tok, v_);
            Contract.Assert(lhs != null);

            impl.Proc.Modifies.Add(lhs);

            List<AssignLhs> lhsl = new List<AssignLhs>();
            lhsl.Add(new SimpleAssignLhs(Token.NoToken, lhs));
            List<Expr> rhsl = new List<Expr>();
            rhsl.Add(Expr.Literal(1) );

            List<Cmd> cs = new List<Cmd> { new AssignCmd(Token.NoToken, lhsl, rhsl) };
            cs.AddRange(b.Cmds);
            b.Cmds = cs;

            //checkBlocks.Add(new CheckableBlock(v_,b));
            }

            List<Cmd> incReachVars = new List<Cmd>();
            foreach (KeyValuePair<Block, Variable> kvp in m_BlockReachabilityMap)
            {
            IdentifierExpr lhs = new IdentifierExpr(Token.NoToken, kvp.Value);
            impl.Proc.Modifies.Add(lhs);
            incReachVars.Add(new AssumeCmd(Token.NoToken, Expr.Le(lhs, Expr.Literal(1))));
            }

            return incReachVars;
        }
Example #21
0
        private void CreateYieldCheckerImpl(Implementation impl, List<List<Cmd>> yields)
        {
            if (yields.Count == 0) return;

            Dictionary<Variable, Expr> map = new Dictionary<Variable, Expr>();
            foreach (Variable local in impl.LocVars)
            {
                var copy = new LocalVariable(Token.NoToken, new TypedIdent(Token.NoToken, local.Name, local.TypedIdent.Type));
                map[local] = Expr.Ident(copy);
            }

            Program program = linearTypeChecker.program;
            List<Variable> locals = new List<Variable>();
            List<Variable> inputs = new List<Variable>();
            foreach (IdentifierExpr ie in map.Values)
            {
                locals.Add(ie.Decl);
            }
            for (int i = 0; i < impl.InParams.Count - linearTypeChecker.linearDomains.Count; i++)
            {
                Variable inParam = impl.InParams[i];
                Variable copy = new LocalVariable(Token.NoToken, new TypedIdent(Token.NoToken, inParam.Name, inParam.TypedIdent.Type));
                locals.Add(copy);
                map[impl.InParams[i]] = Expr.Ident(copy);
            }
            {
                int i = impl.InParams.Count - linearTypeChecker.linearDomains.Count;
                foreach (string domainName in linearTypeChecker.linearDomains.Keys)
                {
                    Variable inParam = impl.InParams[i];
                    Variable copy = new Formal(Token.NoToken, new TypedIdent(Token.NoToken, inParam.Name, inParam.TypedIdent.Type), true);
                    inputs.Add(copy);
                    map[impl.InParams[i]] = Expr.Ident(copy);
                    i++;
                }
            }
            for (int i = 0; i < impl.OutParams.Count; i++)
            {
                Variable outParam = impl.OutParams[i];
                var copy = new LocalVariable(Token.NoToken, new TypedIdent(Token.NoToken, outParam.Name, outParam.TypedIdent.Type));
                locals.Add(copy);
                map[impl.OutParams[i]] = Expr.Ident(copy);
            }
            Dictionary<Variable, Expr> ogOldLocalMap = new Dictionary<Variable, Expr>();
            Dictionary<Variable, Expr> assumeMap = new Dictionary<Variable, Expr>(map);
            foreach (IdentifierExpr ie in globalMods)
            {
                Variable g = ie.Decl;
                var copy = new LocalVariable(Token.NoToken, new TypedIdent(Token.NoToken, string.Format("og_local_old_{0}", g.Name), g.TypedIdent.Type));
                locals.Add(copy);
                ogOldLocalMap[g] = Expr.Ident(copy);
                Formal f = new Formal(Token.NoToken, new TypedIdent(Token.NoToken, string.Format("og_global_old_{0}", g.Name), g.TypedIdent.Type), true);
                inputs.Add(f);
                assumeMap[g] = Expr.Ident(f);
            }

            Substitution assumeSubst = Substituter.SubstitutionFromHashtable(assumeMap);
            Substitution oldSubst = Substituter.SubstitutionFromHashtable(ogOldLocalMap);
            Substitution subst = Substituter.SubstitutionFromHashtable(map);
            List<Block> yieldCheckerBlocks = new List<Block>();
            List<String> labels = new List<String>();
            List<Block> labelTargets = new List<Block>();
            Block yieldCheckerBlock = new Block(Token.NoToken, "exit", new List<Cmd>(), new ReturnCmd(Token.NoToken));
            labels.Add(yieldCheckerBlock.Label);
            labelTargets.Add(yieldCheckerBlock);
            yieldCheckerBlocks.Add(yieldCheckerBlock);
            int yieldCount = 0;
            foreach (List<Cmd> cs in yields)
            {
                List<Cmd> newCmds = new List<Cmd>();
                foreach (Cmd cmd in cs)
                {
                    PredicateCmd predCmd = (PredicateCmd)cmd;
                    newCmds.Add(new AssumeCmd(Token.NoToken, Substituter.ApplyReplacingOldExprs(assumeSubst, oldSubst, predCmd.Expr)));
                }
                foreach (Cmd cmd in cs)
                {
                    PredicateCmd predCmd = (PredicateCmd)cmd;
                    var newExpr = Substituter.ApplyReplacingOldExprs(subst, oldSubst, predCmd.Expr);
                    if (predCmd is AssertCmd)
                    {
                        AssertCmd assertCmd = new AssertCmd(predCmd.tok, newExpr, predCmd.Attributes);
                        assertCmd.ErrorData = "Non-interference check failed";
                        newCmds.Add(assertCmd);
                    }
                    else
                    {
                        newCmds.Add(new AssumeCmd(Token.NoToken, newExpr));
                    }
                }
                newCmds.Add(new AssumeCmd(Token.NoToken, Expr.False));
                yieldCheckerBlock = new Block(Token.NoToken, "L" + yieldCount++, newCmds, new ReturnCmd(Token.NoToken));
                labels.Add(yieldCheckerBlock.Label);
                labelTargets.Add(yieldCheckerBlock);
                yieldCheckerBlocks.Add(yieldCheckerBlock);
            }
            yieldCheckerBlocks.Insert(0, new Block(Token.NoToken, "enter", new List<Cmd>(), new GotoCmd(Token.NoToken, labels, labelTargets)));

            // Create the yield checker procedure
            var yieldCheckerName = string.Format("{0}_YieldChecker_{1}", "Impl", impl.Name);
            var yieldCheckerProc = new Procedure(Token.NoToken, yieldCheckerName, impl.TypeParameters, inputs, new List<Variable>(), new List<Requires>(), new List<IdentifierExpr>(), new List<Ensures>());
            yieldCheckerProc.AddAttribute("inline", new LiteralExpr(Token.NoToken, Microsoft.Basetypes.BigNum.FromInt(1)));
            yieldCheckerProcs.Add(yieldCheckerProc);

            // Create the yield checker implementation
            var yieldCheckerImpl = new Implementation(Token.NoToken, yieldCheckerName, impl.TypeParameters, inputs, new List<Variable>(), locals, yieldCheckerBlocks);
            yieldCheckerImpl.Proc = yieldCheckerProc;
            yieldCheckerImpl.AddAttribute("inline", new LiteralExpr(Token.NoToken, Microsoft.Basetypes.BigNum.FromInt(1)));
            yieldCheckerImpls.Add(yieldCheckerImpl);
        }
Example #22
0
        void LocalIdentTypeOptional(out LocalVariable var, bool isGhost)
        {
            IToken id;  Type ty;  Type optType = null;

            WildIdent(out id, true);
            if (la.kind == 21) {
            Get();
            Type(out ty);
            optType = ty;
            }
            var = new LocalVariable(id, id, id.val, optType == null ? new InferredTypeProxy() : optType, isGhost);
        }
Example #23
0
        private void SetupRefinementCheck(Implementation impl, 
            out List<Variable> newLocalVars,
            out Dictionary<string, Variable> domainNameToInputVar, out Dictionary<string, Variable> domainNameToLocalVar, out Dictionary<Variable, Variable> ogOldGlobalMap)
        {
            pc = null;
            ok = null;
            alpha = null;
            beta = null;
            frame = null;

            newLocalVars = new List<Variable>();
            Program program = linearTypeChecker.program;
            ogOldGlobalMap = new Dictionary<Variable, Variable>();
            foreach (IdentifierExpr ie in globalMods)
            {
                Variable g = ie.Decl;
                LocalVariable l = new LocalVariable(Token.NoToken, new TypedIdent(Token.NoToken, string.Format("og_global_old_{0}", g.Name), g.TypedIdent.Type));
                ogOldGlobalMap[g] = l;
                newLocalVars.Add(l);
            }

            Procedure originalProc = implMap[impl].Proc;
            ActionInfo actionInfo = civlTypeChecker.procToActionInfo[originalProc];
            if (actionInfo.createdAtLayerNum == this.layerNum)
            {
                pc = new LocalVariable(Token.NoToken, new TypedIdent(Token.NoToken, "og_pc", Type.Bool));
                newLocalVars.Add(pc);
                ok = new LocalVariable(Token.NoToken, new TypedIdent(Token.NoToken, "og_ok", Type.Bool));
                newLocalVars.Add(ok);
                Dictionary<Variable, Expr> alwaysMap = new Dictionary<Variable, Expr>();
                for (int i = 0; i < originalProc.InParams.Count; i++)
                {
                    alwaysMap[originalProc.InParams[i]] = Expr.Ident(impl.InParams[i]);
                }
                for (int i = 0; i < originalProc.OutParams.Count; i++)
                {
                    alwaysMap[originalProc.OutParams[i]] = Expr.Ident(impl.OutParams[i]);
                }
                Substitution always = Substituter.SubstitutionFromHashtable(alwaysMap);
                Dictionary<Variable, Expr> foroldMap = new Dictionary<Variable, Expr>();
                foreach (IdentifierExpr ie in globalMods)
                {
                    foroldMap[ie.Decl] = Expr.Ident(ogOldGlobalMap[ie.Decl]);
                }
                Substitution forold = Substituter.SubstitutionFromHashtable(foroldMap);
                frame = new HashSet<Variable>(civlTypeChecker.SharedVariables);
                foreach (Variable v in civlTypeChecker.SharedVariables)
                {
                    if (civlTypeChecker.globalVarToSharedVarInfo[v].hideLayerNum <= actionInfo.createdAtLayerNum ||
                        civlTypeChecker.globalVarToSharedVarInfo[v].introLayerNum > actionInfo.createdAtLayerNum)
                    {
                        frame.Remove(v);
                    }
                }
                AtomicActionInfo atomicActionInfo = actionInfo as AtomicActionInfo;
                if (atomicActionInfo == null)
                {
                    beta = Expr.True;
                    foreach (var v in frame)
                    {
                        beta = Expr.And(beta, Expr.Eq(Expr.Ident(v), foroldMap[v]));
                    }
                    alpha = Expr.True;
                }
                else
                {
                    Expr betaExpr = (new MoverCheck.TransitionRelationComputation(civlTypeChecker.program, atomicActionInfo, frame, new HashSet<Variable>())).TransitionRelationCompute(true);
                    beta = Substituter.ApplyReplacingOldExprs(always, forold, betaExpr);
                    Expr alphaExpr = Expr.True;
                    foreach (AssertCmd assertCmd in atomicActionInfo.gate)
                    {
                        alphaExpr = Expr.And(alphaExpr, assertCmd.Expr);
                        alphaExpr.Type = Type.Bool;
                    }
                    alpha = Substituter.Apply(always, alphaExpr);
                }
                foreach (Variable f in impl.OutParams)
                {
                    LocalVariable copy = new LocalVariable(Token.NoToken, new TypedIdent(Token.NoToken, string.Format("og_old_{0}", f.Name), f.TypedIdent.Type));
                    newLocalVars.Add(copy);
                    ogOldGlobalMap[f] = copy;
                }
            }

            domainNameToInputVar = new Dictionary<string, Variable>();
            domainNameToLocalVar = new Dictionary<string, Variable>();
            {
                int i = impl.InParams.Count - linearTypeChecker.linearDomains.Count;
                foreach (string domainName in linearTypeChecker.linearDomains.Keys)
                {
                    Variable inParam = impl.InParams[i];
                    domainNameToInputVar[domainName] = inParam;
                    Variable l = new LocalVariable(Token.NoToken, new TypedIdent(Token.NoToken, inParam.Name + "_local", inParam.TypedIdent.Type));
                    domainNameToLocalVar[domainName] = l;
                    newLocalVars.Add(l);
                    i++;
                }
            }
        }
Example #24
0
 public virtual LocalVariable VisitLocalVariable(LocalVariable node) {
   Contract.Requires(node != null);
   Contract.Ensures(Contract.Result<LocalVariable>() != null);
   return node;
 }
Example #25
0
        private List<Block> CreateAssertsBlocks(Implementation queryImplementation, Implementation targetImplementation, List<Tuple<Variable, Expr, Expr>> assumeVars)
        {
            var exprs = CreateAssertsExprs(queryImplementation, targetImplementation);
            var assertsCmds = CreateAsserts(exprs);

            queryImplementation.InParams.Iter(iq =>
            {
                targetImplementation.InParams.Iter(it =>
                {
                    if (Equals(iq.TypedIdent.Type, it.TypedIdent.Type))
                    {
                        var eqVar = new LocalVariable(Token.NoToken, new TypedIdent(Token.NoToken, AssumeVarPrefix + "_" + _eqVarsCounter++, BType.Bool));
                        assumeVars.Add(new Tuple<Variable, Expr, Expr>(eqVar, Expr.Ident(iq), Expr.Ident(it)));
                        queryImplementation.Blocks[0].Cmds.Insert(0, Utils.BoogieUtils.CreateAssignCmd(new List<IdentifierExpr>() { Expr.Ident(eqVar) }, new List<Expr>() { Expr.Eq(Expr.Ident(iq), Expr.Ident(it)) }));
                    }
                });
            });

            // The equality vars are grouped according to lhs. This means that expressions like eq_0 = `rax == v2.rcx` and eq_13 = `rax == v2.p0` will be
            // grouped together, to make the assumes choosing algorithm more efficient (we won't select eq_0 and eq_13 for the same section)
            var eqVarsGroups = new Dictionary<string, List<Tuple<Variable, Expr, Expr>>>();
            assumeVars.Iter(t =>
            {
                var lhs = t.Item2.ToString();
                if (!eqVarsGroups.ContainsKey(lhs))
                    eqVarsGroups[lhs] = new List<Tuple<Variable, Expr, Expr>>();
                eqVarsGroups[lhs].Add(t);
            });
            assumeVars.Iter(t => queryImplementation.LocVars.Add(t.Item1));
            return CreateAssertsWithAssumes(eqVarsGroups.Values.ToList(), assertsCmds);
        }
    public Bpl.Procedure addHandlerStubCaller(Sink sink, IMethodDefinition def) {
      MethodBody callerBody = new MethodBody();
      MethodDefinition callerDef = new MethodDefinition() {
        InternFactory = (def as MethodDefinition).InternFactory,
        ContainingTypeDefinition = def.ContainingTypeDefinition,
        IsStatic = true,
        Name = sink.host.NameTable.GetNameFor("BOOGIE_STUB_CALLER_" + def.Name.Value),
        Type = sink.host.PlatformType.SystemVoid,
        Body = callerBody,
      };
      callerBody.MethodDefinition = callerDef;
      Sink.ProcedureInfo procInfo = sink.FindOrCreateProcedure(def);
      Sink.ProcedureInfo callerInfo = sink.FindOrCreateProcedure(callerDef);

      Bpl.LocalVariable[] localVars = new Bpl.LocalVariable[procInfo.Decl.InParams.Count];
      Bpl.IdentifierExpr[] varExpr = new Bpl.IdentifierExpr[procInfo.Decl.InParams.Count];
      for (int i = 0; i < procInfo.Decl.InParams.Count; i++) {
        Bpl.LocalVariable loc = new Bpl.LocalVariable(Bpl.Token.NoToken,
                                                     new Bpl.TypedIdent(Bpl.Token.NoToken, TranslationHelper.GenerateTempVarName(),
                                                                        procInfo.Decl.InParams[i].TypedIdent.Type));
        localVars[i] = loc;
        varExpr[i] = new Bpl.IdentifierExpr(Bpl.Token.NoToken, loc);
      }

      Bpl.StmtListBuilder builder = new Bpl.StmtListBuilder();
      builder.Add(getResetNavigationCheck(sink));
      
      string pageXaml= PhoneCodeHelper.instance().PhonePlugin.getXAMLForPage(def.ContainingTypeDefinition.ToString());
      Bpl.Variable boogieCurrentURI = sink.FindOrCreateFieldVariable(PhoneCodeHelper.CurrentURIFieldDefinition);
      Bpl.Constant boogieXamlConstant;
      if (pageXaml != null)
        boogieXamlConstant = sink.FindOrCreateConstant(pageXaml);
      else
        boogieXamlConstant = null;
      // NAVIGATION TODO: For now just assume we are in this page to be able to call the handler, this is NOT true for any handler
      // NAVIGATION TODO: ie, a network event handler
      if (boogieXamlConstant != null) {
        Bpl.AssumeCmd assumeCurrentPage =
          new Bpl.AssumeCmd(Bpl.Token.NoToken,
                            Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Eq, new Bpl.IdentifierExpr(Bpl.Token.NoToken, boogieCurrentURI),
                                            new Bpl.IdentifierExpr(Bpl.Token.NoToken, boogieXamlConstant)));
        builder.Add(assumeCurrentPage);
      }

      // NAVIGATION TODO: have to do the pair generation all in one go instead of having different files that need to be sed'ed
      boogieXamlConstant = sink.FindOrCreateConstant(BOOGIE_STARTING_URI_PLACEHOLDER);
      Bpl.AssumeCmd assumeStartPage = new Bpl.AssumeCmd(Bpl.Token.NoToken,
                            Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Eq, new Bpl.IdentifierExpr(Bpl.Token.NoToken, boogieCurrentURI),
                                            new Bpl.IdentifierExpr(Bpl.Token.NoToken, boogieXamlConstant)));
      builder.Add(assumeStartPage);
      builder.Add(new Bpl.CallCmd(Bpl.Token.NoToken, procInfo.Decl.Name, new List<Bpl.Expr>(varExpr), new List<Bpl.IdentifierExpr>()));
      boogieXamlConstant = sink.FindOrCreateConstant(BOOGIE_ENDING_URI_PLACEHOLDER);
      Bpl.AssertCmd assertEndPage = new Bpl.AssertCmd(Bpl.Token.NoToken,
                            Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Neq, new Bpl.IdentifierExpr(Bpl.Token.NoToken, boogieCurrentURI),
                                            new Bpl.IdentifierExpr(Bpl.Token.NoToken, boogieXamlConstant)));

      Bpl.Expr guard= new Bpl.IdentifierExpr(Bpl.Token.NoToken, sink.FindOrCreateGlobalVariable(PhoneCodeHelper.BOOGIE_NAVIGATION_CHECK_VARIABLE, Bpl.Type.Bool));
      Bpl.StmtListBuilder thenBuilder = new Bpl.StmtListBuilder();
      thenBuilder.Add(assertEndPage);
      Bpl.IfCmd ifNavigated = new Bpl.IfCmd(Bpl.Token.NoToken, guard, thenBuilder.Collect(Bpl.Token.NoToken), null, new Bpl.StmtListBuilder().Collect(Bpl.Token.NoToken));

      builder.Add(ifNavigated);
      Bpl.Implementation impl =
        new Bpl.Implementation(Bpl.Token.NoToken, callerInfo.Decl.Name, new List<Bpl.TypeVariable>(), new List<Bpl.Variable>(),
                               new List<Bpl.Variable>(), new List<Bpl.Variable>(localVars), builder.Collect(Bpl.Token.NoToken), null, new Bpl.Errors());

      sink.TranslatedProgram.AddTopLevelDeclaration(impl);
      return impl.Proc;
    }