Beispiel #1
0
	void LabelOrCmd(out Cmd c, out IToken label) {
		IToken/*!*/ x; Expr/*!*/ e;
		List<IToken>/*!*/ xs;
		List<IdentifierExpr> ids;
		c = dummyCmd;  label = null;
		Cmd/*!*/ cn;
		QKeyValue kv = null;
		
		switch (la.kind) {
		case 1: {
			LabelOrAssign(out c, out label);
			break;
		}
		case 47: {
			Get();
			x = t; 
			while (la.kind == 28) {
				Attribute(ref kv);
			}
			Proposition(out e);
			c = new AssertCmd(x, e, kv); 
			Expect(9);
			break;
		}
		case 48: {
			Get();
			x = t; 
			while (la.kind == 28) {
				Attribute(ref kv);
			}
			Proposition(out e);
			c = new AssumeCmd(x, e, kv); 
			Expect(9);
			break;
		}
		case 49: {
			Get();
			x = t; 
			Idents(out xs);
			Expect(9);
			ids = new List<IdentifierExpr>();
			foreach(IToken/*!*/ y in xs){
			 Contract.Assert(y != null);
			 ids.Add(new IdentifierExpr(y, y.val));
			}
			c = new HavocCmd(x,ids);
			
			break;
		}
		case 36: case 52: case 53: {
			CallCmd(out cn);
			Expect(9);
			c = cn; 
			break;
		}
		case 54: {
			ParCallCmd(out cn);
			c = cn; 
			break;
		}
		case 50: {
			Get();
			x = t; 
			Expect(9);
			c = new YieldCmd(x); 
			break;
		}
		default: SynErr(106); break;
		}
	}
Beispiel #2
0
        private void GenerateHelperBlocks(Implementation impl)
        {
            Contract.Requires(impl != null);
              Dictionary<TransferCmd, ReturnCmd> gotoCmdOrigins = new Dictionary<TransferCmd, ReturnCmd>();
              exitBlock = GenerateUnifiedExit(impl, gotoCmdOrigins);
              Contract.Assert(exitBlock != null);

              AddBlocksBetween(impl.Blocks);

              #region Insert pre- and post-conditions and where clauses as assume and assert statements
              {
            List<Cmd> cc = new List<Cmd>();
            // where clauses of global variables
            foreach (Declaration d in program.TopLevelDeclarations) {
              GlobalVariable gvar = d as GlobalVariable;
              if (gvar != null && gvar.TypedIdent.WhereExpr != null) {
            Cmd c = new AssumeCmd(gvar.tok, gvar.TypedIdent.WhereExpr);
            cc.Add(c);
              }
            }
            // where clauses of in- and out-parameters
            cc.AddRange(GetParamWhereClauses(impl));
            // where clauses of local variables
            foreach (Variable lvar in impl.LocVars) {
              Contract.Assert(lvar != null);
              if (lvar.TypedIdent.WhereExpr != null) {
            Cmd c = new AssumeCmd(lvar.tok, lvar.TypedIdent.WhereExpr);
            cc.Add(c);
              }
            }

            // add cc and the preconditions to new blocks preceding impl.Blocks[0]
            InjectPreconditions(impl, cc);

            // append postconditions, starting in exitBlock and continuing into other blocks, if needed
            exitBlock = InjectPostConditions(impl, exitBlock, gotoCmdOrigins);
              }
              #endregion
        }
    /// <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);
            }
          }
        }
      }
    }
Beispiel #4
0
        static void Instrument(Implementation impl, NativeLattice.Element[] pre, NativeLattice.Element[] post)
        {
            Contract.Requires(impl != null);
              Contract.Requires(pre != null);

              foreach (var b in impl.Blocks) {
            var element = pre[b.aiId];
            if (element != null && (b.widenBlock || CommandLineOptions.Clo.InstrumentInfer == CommandLineOptions.InstrumentationPlaces.Everywhere)) {
              List<Cmd> newCommands = new List<Cmd>();
              Expr inv = element.ToExpr();
              PredicateCmd cmd;
              var kv = new QKeyValue(Token.NoToken, "inferred", new List<object>(), null);
              if (CommandLineOptions.Clo.InstrumentWithAsserts) {
            cmd = new AssertCmd(Token.NoToken, inv, kv);
              } else {
            cmd = new AssumeCmd(Token.NoToken, inv, kv);
              }
              newCommands.Add(cmd);
              newCommands.AddRange(b.Cmds);
              if (post != null && post[b.aiId] != null) {
            inv = post[b.aiId].ToExpr();
            kv = new QKeyValue(Token.NoToken, "inferred", new List<object>(), null);
            if (CommandLineOptions.Clo.InstrumentWithAsserts) {
              cmd = new AssertCmd(Token.NoToken, inv, kv);
            } else {
              cmd = new AssumeCmd(Token.NoToken, inv, kv);
            }
            newCommands.Add(cmd);
              }
              b.Cmds = newCommands;  // destructively replace the commands of the block
            }
              }
        }
Beispiel #5
0
  void PredicateImplementation() {
    blockGraph = prog.ProcessLoops(impl);
    sortedBlocks = blockGraph.LoopyTopSort();

    AssignPredicates();
    partInfo = BuildPartitionInfo();

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

    var newBlocks = new List<Block>();
    Block prevBlock = null;
    foreach (var n in sortedBlocks) {
      if (predMap.ContainsKey(n.Item1)) {
        var p = predMap[n.Item1];
        var pExpr = Expr.Ident(p);

        if (n.Item2) {
          var dominator = FindImmediateDominator(n.Item1);
          if (dominator != null && predMap.ContainsKey(dominator)) {
            AssumeCmd aCmd = new AssumeCmd(Token.NoToken, Expr.True);
            aCmd.Attributes = new QKeyValue(Token.NoToken, "dominator_predicate", new List<object>() { predMap[dominator].ToString() }, aCmd.Attributes);
            aCmd.Attributes = new QKeyValue(Token.NoToken, "predicate", new List<object>() { predMap[n.Item1].ToString() }, aCmd.Attributes);
            n.Item1.Cmds.Insert(0, aCmd);
          }

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

          backedgeBlock.Label = n.Item1.Label + ".backedge";
          backedgeBlock.Cmds = new List<Cmd> { new AssumeCmd(Token.NoToken, pExpr,
            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.Not(pExpr)) };

          if (uni != null && !uni.IsUniform(impl.Name, n.Item1)) {
            uni.AddNonUniform(impl.Name, backedgeBlock);
            uni.AddNonUniform(impl.Name, tailBlock);
          }

          if (prevBlock != null)
            prevBlock.TransferCmd = new GotoCmd(Token.NoToken,
                                          new List<Block> { backedgeBlock, tailBlock });
          prevBlock = tailBlock;
        } else {
          PredicateBlock(pExpr, n.Item1, newBlocks, ref prevBlock);
        }
      } else {
        if (!n.Item2) {
          PredicateBlock(null, n.Item1, newBlocks, ref prevBlock);
        }
      }
    }

    if (prevBlock != null)
      prevBlock.TransferCmd = new ReturnCmd(Token.NoToken);

    impl.Blocks = newBlocks;
  }
Beispiel #6
0
 private void AddHoudiniConstant(AssumeCmd assumeCmd)
 {
     Variable houdiniConstant;
     if (houdini.MatchCandidate(assumeCmd.Expr, out houdiniConstant))
     houdiniAssumeConstants.Add(houdiniConstant);
 }
        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);
        }
Beispiel #8
0
 public virtual Cmd VisitAssumeCmd(AssumeCmd node) {
   Contract.Requires(node != null);
   Contract.Ensures(Contract.Result<Cmd>() != null);
   node.Expr = this.VisitExpr(node.Expr);
   return node;
 }
Beispiel #9
0
        // If the enclosing context is a loop, then "runOffTheEndLabel" is the loop head label;
        // otherwise, it is null.
        void CreateBlocks(StmtList stmtList, string runOffTheEndLabel)
        {
            Contract.Requires(stmtList != null);
              Contract.Requires(blocks != null);
              List<Cmd> cmdPrefixToApply = stmtList.PrefixCommands;

              int n = stmtList.BigBlocks.Count;
              foreach (BigBlock b in stmtList.BigBlocks) {
            n--;
            Contract.Assert(b.LabelName != null);
            List<Cmd> theSimpleCmds;
            if (cmdPrefixToApply == null) {
              theSimpleCmds = b.simpleCmds;
            } else {
              theSimpleCmds = new List<Cmd>();
              theSimpleCmds.AddRange(cmdPrefixToApply);
              theSimpleCmds.AddRange(b.simpleCmds);
              cmdPrefixToApply = null;  // now, we've used 'em up
            }

            if (b.tc != null) {
              // this BigBlock has the very same components as a Block
              Contract.Assert(b.ec == null);
              Block block = new Block(b.tok, b.LabelName, theSimpleCmds, b.tc);
              blocks.Add(block);

            } else if (b.ec == null) {
              TransferCmd trCmd;
              if (n == 0 && runOffTheEndLabel != null) {
            // goto the given label instead of the textual successor block
            trCmd = new GotoCmd(stmtList.EndCurly, new List<String> { runOffTheEndLabel });
              } else {
            trCmd = GotoSuccessor(stmtList.EndCurly, b);
              }
              Block block = new Block(b.tok, b.LabelName, theSimpleCmds, trCmd);
              blocks.Add(block);

            } else if (b.ec is BreakCmd) {
              BreakCmd bcmd = (BreakCmd)b.ec;
              Contract.Assert(bcmd.BreakEnclosure != null);
              Block block = new Block(b.tok, b.LabelName, theSimpleCmds, GotoSuccessor(b.ec.tok, bcmd.BreakEnclosure));
              blocks.Add(block);

            } else if (b.ec is WhileCmd) {
              WhileCmd wcmd = (WhileCmd)b.ec;
              string loopHeadLabel = prefix + anon + "_LoopHead";
              string/*!*/ loopBodyLabel = prefix + anon + "_LoopBody";
              string loopDoneLabel = prefix + anon + "_LoopDone";
              anon++;

              List<Cmd> ssBody = new List<Cmd>();
              List<Cmd> ssDone = new List<Cmd>();
              if (wcmd.Guard != null) {
            var ac = new AssumeCmd(wcmd.tok, wcmd.Guard);
            ac.Attributes = new QKeyValue(wcmd.tok, "partition", new List<object>(), null);
            ssBody.Add(ac);

            ac = new AssumeCmd(wcmd.tok, Expr.Not(wcmd.Guard));
            ac.Attributes = new QKeyValue(wcmd.tok, "partition", new List<object>(), null);
            ssDone.Add(ac);
              }

              // Try to squeeze in ssBody into the first block of wcmd.Body
              bool bodyGuardTakenCareOf = wcmd.Body.PrefixFirstBlock(ssBody, ref loopBodyLabel);

              // ... goto LoopHead;
              Block block = new Block(b.tok, b.LabelName, theSimpleCmds, new GotoCmd(wcmd.tok, new List<String> { loopHeadLabel }));
              blocks.Add(block);

              // LoopHead: assert/assume loop_invariant; goto LoopDone, LoopBody;
              List<Cmd> ssHead = new List<Cmd>();
              foreach (PredicateCmd inv in wcmd.Invariants) {
            ssHead.Add(inv);
              }
              block = new Block(wcmd.tok, loopHeadLabel, ssHead, new GotoCmd(wcmd.tok, new List<String> { loopDoneLabel, loopBodyLabel }));
              blocks.Add(block);

              if (!bodyGuardTakenCareOf) {
            // LoopBody: assume guard; goto firstLoopBlock;
            block = new Block(wcmd.tok, loopBodyLabel, ssBody, new GotoCmd(wcmd.tok, new List<String> { wcmd.Body.BigBlocks[0].LabelName }));
            blocks.Add(block);
              }

              // recurse to create the blocks for the loop body
              CreateBlocks(wcmd.Body, loopHeadLabel);

              // LoopDone: assume !guard; goto loopSuccessor;
              TransferCmd trCmd;
              if (n == 0 && runOffTheEndLabel != null) {
            // goto the given label instead of the textual successor block
            trCmd = new GotoCmd(wcmd.tok, new List<String> { runOffTheEndLabel });
              } else {
            trCmd = GotoSuccessor(wcmd.tok, b);
              }
              block = new Block(wcmd.tok, loopDoneLabel, ssDone, trCmd);
              blocks.Add(block);

            } else {
              IfCmd ifcmd = (IfCmd)b.ec;
              string predLabel = b.LabelName;
              List<Cmd> predCmds = theSimpleCmds;

              for (; ifcmd != null; ifcmd = ifcmd.elseIf) {
            string thenLabel = prefix + anon + "_Then";
            Contract.Assert(thenLabel != null);
            string elseLabel = prefix + anon + "_Else";
            Contract.Assert(elseLabel != null);
            anon++;

            List<Cmd> ssThen = new List<Cmd>();
            List<Cmd> ssElse = new List<Cmd>();
            if (ifcmd.Guard != null) {
              var ac = new AssumeCmd(ifcmd.tok, ifcmd.Guard);
              ac.Attributes = new QKeyValue(ifcmd.tok, "partition", new List<object>(), null);
              ssThen.Add(ac);

              ac = new AssumeCmd(ifcmd.tok, Expr.Not(ifcmd.Guard));
              ac.Attributes = new QKeyValue(ifcmd.tok, "partition", new List<object>(), null);
              ssElse.Add(ac);
            }

            // Try to squeeze in ssThen/ssElse into the first block of ifcmd.thn/ifcmd.elseBlock
            bool thenGuardTakenCareOf = ifcmd.thn.PrefixFirstBlock(ssThen, ref thenLabel);
            bool elseGuardTakenCareOf = false;
            if (ifcmd.elseBlock != null) {
              elseGuardTakenCareOf = ifcmd.elseBlock.PrefixFirstBlock(ssElse, ref elseLabel);
            }

            // ... goto Then, Else;
            Block block = new Block(b.tok, predLabel, predCmds,
              new GotoCmd(ifcmd.tok, new List<String> { thenLabel, elseLabel }));
            blocks.Add(block);

            if (!thenGuardTakenCareOf) {
              // Then: assume guard; goto firstThenBlock;
              block = new Block(ifcmd.tok, thenLabel, ssThen, new GotoCmd(ifcmd.tok, new List<String> { ifcmd.thn.BigBlocks[0].LabelName }));
              blocks.Add(block);
            }

            // recurse to create the blocks for the then branch
            CreateBlocks(ifcmd.thn, n == 0 ? runOffTheEndLabel : null);

            if (ifcmd.elseBlock != null) {
              Contract.Assert(ifcmd.elseIf == null);
              if (!elseGuardTakenCareOf) {
                // Else: assume !guard; goto firstElseBlock;
                block = new Block(ifcmd.tok, elseLabel, ssElse, new GotoCmd(ifcmd.tok, new List<String> { ifcmd.elseBlock.BigBlocks[0].LabelName }));
                blocks.Add(block);
              }

              // recurse to create the blocks for the else branch
              CreateBlocks(ifcmd.elseBlock, n == 0 ? runOffTheEndLabel : null);

            } else if (ifcmd.elseIf != null) {
              // this is an "else if"
              predLabel = elseLabel;
              predCmds = new List<Cmd>();
              if (ifcmd.Guard != null) {
                var ac = new AssumeCmd(ifcmd.tok, Expr.Not(ifcmd.Guard));
                ac.Attributes = new QKeyValue(ifcmd.tok, "partition", new List<object>(), null);
                predCmds.Add(ac);
              }

            } else {
              // no else alternative is specified, so else branch is just "skip"
              // Else: assume !guard; goto ifSuccessor;
              TransferCmd trCmd;
              if (n == 0 && runOffTheEndLabel != null) {
                // goto the given label instead of the textual successor block
                trCmd = new GotoCmd(ifcmd.tok, new List<String> { runOffTheEndLabel });
              } else {
                trCmd = GotoSuccessor(ifcmd.tok, b);
              }
              block = new Block(ifcmd.tok, elseLabel, ssElse, trCmd);
              blocks.Add(block);
            }
              }
            }
              }
        }
Beispiel #10
0
        public AtomicActionInfo(Procedure proc, Ensures ensures, MoverType moverType, int layerNum, int availableUptoLayerNum)
            : base(proc, layerNum, availableUptoLayerNum)
        {
            CodeExpr codeExpr = ensures.Condition as CodeExpr;
            this.ensures = ensures;
            this.moverType = moverType;
            this.thisGate = new List<AssertCmd>();
            this.thisAction = codeExpr;
            this.thisInParams = new List<Variable>();
            this.thisOutParams = new List<Variable>();
            this.thatGate = new List<AssertCmd>();
            this.thatInParams = new List<Variable>();
            this.thatOutParams = new List<Variable>();
            this.hasAssumeCmd = false;
            
            foreach (Block block in codeExpr.Blocks)
            {
                block.Cmds.ForEach(x => this.hasAssumeCmd = this.hasAssumeCmd || x is AssumeCmd);
            }

            var cmds = thisAction.Blocks[0].Cmds;
            for (int i = 0; i < cmds.Count; i++)
            {
                AssertCmd assertCmd = cmds[i] as AssertCmd;
                if (assertCmd == null) break;
                thisGate.Add(assertCmd);
                cmds[i] = new AssumeCmd(assertCmd.tok, Expr.True);
            }

            Dictionary<Variable, Expr> map = new Dictionary<Variable, Expr>();
            foreach (Variable x in proc.InParams)
            {
                this.thisInParams.Add(x);
                Variable y = new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "that_" + x.Name, x.TypedIdent.Type), true, x.Attributes);
                this.thatInParams.Add(y);
                map[x] = Expr.Ident(y);
            }
            foreach (Variable x in proc.OutParams)
            {
                this.thisOutParams.Add(x);
                Variable y = new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "that_" + x.Name, x.TypedIdent.Type), false, x.Attributes);
                this.thatOutParams.Add(y);
                map[x] = Expr.Ident(y);
            }
            List<Variable> thatLocVars = new List<Variable>();
            foreach (Variable x in thisAction.LocVars)
            {
                Variable y = new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "that_" + x.Name, x.TypedIdent.Type), false);
                map[x] = Expr.Ident(y);
                thatLocVars.Add(y);
            }
            Contract.Assume(proc.TypeParameters.Count == 0);
            Substitution subst = Substituter.SubstitutionFromHashtable(map);
            foreach (AssertCmd assertCmd in thisGate)
            {
                thatGate.Add((AssertCmd)Substituter.Apply(subst, assertCmd));
            }
            Dictionary<Block, Block> blockMap = new Dictionary<Block, Block>();
            List<Block> thatBlocks = new List<Block>();
            foreach (Block block in thisAction.Blocks)
            {
                List<Cmd> otherCmds = new List<Cmd>();
                foreach (Cmd cmd in block.Cmds)
                {
                    otherCmds.Add(Substituter.Apply(subst, cmd));
                }
                Block thatBlock = new Block();
                thatBlock.Cmds = otherCmds;
                thatBlock.Label = "that_" + block.Label;
                block.Label = "this_" + block.Label;
                thatBlocks.Add(thatBlock);
                blockMap[block] = thatBlock;
                if (block.TransferCmd is GotoCmd)
                {
                    GotoCmd gotoCmd = block.TransferCmd as GotoCmd;
                    for (int i = 0; i < gotoCmd.labelNames.Count; i++)
                    {
                        gotoCmd.labelNames[i] = "this_" + gotoCmd.labelNames[i];
                    }
                }
            }
            foreach (Block block in thisAction.Blocks)
            {
                if (block.TransferCmd is ReturnExprCmd)
                {
                    block.TransferCmd = new ReturnCmd(block.TransferCmd.tok);
                    blockMap[block].TransferCmd = new ReturnCmd(block.TransferCmd.tok);
                    continue;
                }
                List<Block> thatGotoCmdLabelTargets = new List<Block>();
                List<string> thatGotoCmdLabelNames = new List<string>();
                GotoCmd gotoCmd = block.TransferCmd as GotoCmd;
                foreach (Block target in gotoCmd.labelTargets)
                {
                    thatGotoCmdLabelTargets.Add(blockMap[target]);
                    thatGotoCmdLabelNames.Add(blockMap[target].Label);
                }
                blockMap[block].TransferCmd = new GotoCmd(block.TransferCmd.tok, thatGotoCmdLabelNames, thatGotoCmdLabelTargets);
            }
            this.thatAction = new CodeExpr(thatLocVars, thatBlocks);

            {
                VariableCollector collector = new VariableCollector();
                collector.Visit(codeExpr);
                this.actionUsedGlobalVars = new HashSet<Variable>(collector.usedVars.Where(x => x is GlobalVariable));
            }

            List<Variable> modifiedVars = new List<Variable>();
            foreach (Block block in codeExpr.Blocks)
            {
                block.Cmds.ForEach(cmd => cmd.AddAssignedVariables(modifiedVars));
            }
            this.modifiedGlobalVars = new HashSet<Variable>(modifiedVars.Where(x => x is GlobalVariable));

            {
                VariableCollector collector = new VariableCollector();
                this.thisGate.ForEach(assertCmd => collector.Visit(assertCmd));
                this.gateUsedGlobalVars = new HashSet<Variable>(collector.usedVars.Where(x => x is GlobalVariable));
            }
        }
Beispiel #11
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);
        }
Beispiel #12
0
        public ActionInfo(Procedure proc, CodeExpr codeExpr, MoverType moverType, int phaseNum)
        {
            this.proc = proc;
            this.moverType = moverType;
            this.phaseNum = phaseNum;
            this.callerPhaseNums = new HashSet<int>();
            this.thisGate = new List<AssertCmd>();
            this.thisAction = codeExpr;
            this.thisInParams = new List<Variable>();
            this.thisOutParams = new List<Variable>();
            this.thatGate = new List<AssertCmd>();
            this.thatInParams = new List<Variable>();
            this.thatOutParams = new List<Variable>();

            var cmds = thisAction.Blocks[0].Cmds;
            for (int i = 0; i < cmds.Count; i++)
            {
                AssertCmd assertCmd = cmds[i] as AssertCmd;
                if (assertCmd == null) break;
                thisGate.Add(assertCmd);
                cmds[i] = new AssumeCmd(assertCmd.tok, assertCmd.Expr);
            }

            Dictionary<Variable, Expr> map = new Dictionary<Variable, Expr>();
            foreach (Variable x in proc.InParams)
            {
                this.thisInParams.Add(x);
                Variable y = new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "that_" + x.Name, x.TypedIdent.Type), true);
                this.thatInParams.Add(y);
                map[x] = new IdentifierExpr(Token.NoToken, y);
            }
            foreach (Variable x in proc.OutParams)
            {
                this.thisOutParams.Add(x);
                Variable y = new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "that_" + x.Name, x.TypedIdent.Type), false);
                this.thatOutParams.Add(y);
                map[x] = new IdentifierExpr(Token.NoToken, y);
            }
            List<Variable> otherLocVars = new List<Variable>();
            foreach (Variable x in thisAction.LocVars)
            {
                Variable y = new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "that_" + x.Name, x.TypedIdent.Type), false);
                map[x] = new IdentifierExpr(Token.NoToken, y);
                otherLocVars.Add(y);
            }
            Contract.Assume(proc.TypeParameters.Count == 0);
            Substitution subst = Substituter.SubstitutionFromHashtable(map);
            foreach (AssertCmd assertCmd in thisGate)
            {
                thatGate.Add((AssertCmd)Substituter.Apply(subst, assertCmd));
            }
            Dictionary<Block, Block> blockMap = new Dictionary<Block, Block>();
            List<Block> otherBlocks = new List<Block>();
            foreach (Block block in thisAction.Blocks)
            {
                List<Cmd> otherCmds = new List<Cmd>();
                foreach (Cmd cmd in block.Cmds)
                {
                    otherCmds.Add(Substituter.Apply(subst, cmd));
                }
                Block otherBlock = new Block();
                otherBlock.Cmds = otherCmds;
                otherBlock.Label = "that_" + block.Label;
                block.Label = "this_" + block.Label;
                otherBlocks.Add(otherBlock);
                blockMap[block] = otherBlock;
                if (block.TransferCmd is GotoCmd)
                {
                    GotoCmd gotoCmd = block.TransferCmd as GotoCmd;
                    for (int i = 0; i < gotoCmd.labelNames.Count; i++)
                    {
                        gotoCmd.labelNames[i] = "this_" + gotoCmd.labelNames[i];
                    }
                }
            }
            foreach (Block block in thisAction.Blocks)
            {
                if (block.TransferCmd is ReturnExprCmd)
                {
                    block.TransferCmd = new ReturnCmd(block.TransferCmd.tok);
                    blockMap[block].TransferCmd = new ReturnCmd(block.TransferCmd.tok);
                    continue;
                }
                List<Block> otherGotoCmdLabelTargets = new List<Block>();
                List<string> otherGotoCmdLabelNames = new List<string>();
                GotoCmd gotoCmd = block.TransferCmd as GotoCmd;
                foreach (Block target in gotoCmd.labelTargets)
                {
                    otherGotoCmdLabelTargets.Add(blockMap[target]);
                    otherGotoCmdLabelNames.Add(blockMap[target].Label);
                }
                blockMap[block].TransferCmd = new GotoCmd(block.TransferCmd.tok, otherGotoCmdLabelNames, otherGotoCmdLabelTargets);
            }
            this.thatAction = new CodeExpr(otherLocVars, otherBlocks);
        }
Beispiel #13
0
 public override Cmd VisitAssumeCmd(AssumeCmd node)
 {
     AddHoudiniConstant(node);
       return base.VisitAssumeCmd(node);
 }
Beispiel #14
0
        public AtomicActionInfo(Procedure proc, Ensures ensures, MoverType moverType, int layerNum, int availableUptoLayerNum)
            : base(proc, layerNum, availableUptoLayerNum)
        {
            this.ensures = ensures;
            this.moverType = moverType;
            this.gate = new List<AssertCmd>();
            this.action = ensures.Condition as CodeExpr;
            this.thisGate = new List<AssertCmd>();
            this.thisInParams = new List<Variable>();
            this.thisOutParams = new List<Variable>();
            this.thatGate = new List<AssertCmd>();
            this.thatInParams = new List<Variable>();
            this.thatOutParams = new List<Variable>();
            this.hasAssumeCmd = false;
            this.thisMap = new Dictionary<Variable, Expr>();
            this.thatMap = new Dictionary<Variable, Expr>();
            this.triggerFuns = new Dictionary<Variable, Function>();

            foreach (Block block in this.action.Blocks)
            {
                block.Cmds.ForEach(x => this.hasAssumeCmd = this.hasAssumeCmd || x is AssumeCmd);
            }

            foreach (Block block in this.action.Blocks)
            {
                if (block.TransferCmd is ReturnExprCmd)
                {
                    block.TransferCmd = new ReturnCmd(block.TransferCmd.tok);
                }
            }

            var cmds = this.action.Blocks[0].Cmds;
            for (int i = 0; i < cmds.Count; i++)
            {
                AssertCmd assertCmd = cmds[i] as AssertCmd;
                if (assertCmd == null) break;
                this.gate.Add(assertCmd);
                cmds[i] = new AssumeCmd(assertCmd.tok, Expr.True);
            }

            foreach (Variable x in proc.InParams)
            {
                Variable thisx = new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "this_" + x.Name, x.TypedIdent.Type), true, x.Attributes);
                this.thisInParams.Add(thisx);
                this.thisMap[x] = Expr.Ident(thisx);
                Variable thatx = new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "that_" + x.Name, x.TypedIdent.Type), true, x.Attributes);
                this.thatInParams.Add(thatx);
                this.thatMap[x] = Expr.Ident(thatx);
            }
            foreach (Variable x in proc.OutParams)
            {
                Variable thisx = new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "this_" + x.Name, x.TypedIdent.Type), false, x.Attributes);
                this.thisOutParams.Add(thisx);
                this.thisMap[x] = Expr.Ident(thisx);
                Variable thatx = new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "that_" + x.Name, x.TypedIdent.Type), false, x.Attributes);
                this.thatOutParams.Add(thatx);
                this.thatMap[x] = Expr.Ident(thatx);
            }
            List<Variable> thisLocVars = new List<Variable>();
            List<Variable> thatLocVars = new List<Variable>();
            foreach (Variable x in this.action.LocVars)
            {
                Variable thisx = new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "this_" + x.Name, x.TypedIdent.Type), false);
                thisMap[x] = Expr.Ident(thisx);
                thisLocVars.Add(thisx);
                Variable thatx = new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "that_" + x.Name, x.TypedIdent.Type), false);
                thatMap[x] = Expr.Ident(thatx);
                thatLocVars.Add(thatx);
            }
            Contract.Assume(proc.TypeParameters.Count == 0);
            Substitution thisSubst = Substituter.SubstitutionFromHashtable(this.thisMap);
            Substitution thatSubst = Substituter.SubstitutionFromHashtable(this.thatMap);
            foreach (AssertCmd assertCmd in this.gate)
            {
                this.thisGate.Add((AssertCmd)Substituter.Apply(thisSubst, assertCmd));
                this.thatGate.Add((AssertCmd)Substituter.Apply(thatSubst, assertCmd));
            }
            this.thisAction = new CodeExpr(thisLocVars, SubstituteBlocks(this.action.Blocks, thisSubst, "this_"));
            this.thatAction = new CodeExpr(thatLocVars, SubstituteBlocks(this.action.Blocks, thatSubst, "that_"));

            {
                VariableCollector collector = new VariableCollector();
                collector.Visit(this.action);
                this.actionUsedGlobalVars = new HashSet<Variable>(collector.usedVars.Where(x => x is GlobalVariable));
            }

            List<Variable> modifiedVars = new List<Variable>();
            foreach (Block block in this.action.Blocks)
            {
                block.Cmds.ForEach(cmd => cmd.AddAssignedVariables(modifiedVars));
            }
            this.modifiedGlobalVars = new HashSet<Variable>(modifiedVars.Where(x => x is GlobalVariable));

            {
                VariableCollector collector = new VariableCollector();
                this.gate.ForEach(assertCmd => collector.Visit(assertCmd));
                this.gateUsedGlobalVars = new HashSet<Variable>(collector.usedVars.Where(x => x is GlobalVariable));
            }
        }
Beispiel #15
0
 public override Cmd VisitAssumeCmd(AssumeCmd node)
 {
     node.tok = Token.NoToken;
     TokenCount++; 
     return base.VisitAssumeCmd(node);
 }
Beispiel #16
0
 public override Cmd VisitAssumeCmd(AssumeCmd node)
 {
     Contract.Ensures(Contract.Result<Cmd>() == node);
     this.VisitExpr(node.Expr);
     return node;
 }
Beispiel #17
0
    // result[0] is the entry block
    protected List<Block/*!*/>/*!*/ CreateInlinedBlocks(CallCmd callCmd, Implementation impl, string nextBlockLabel) {
      Contract.Requires(nextBlockLabel != null);
      Contract.Requires(impl != null);
      Contract.Requires(impl.Proc != null);
      Contract.Requires(callCmd != null);
      Contract.Requires(codeCopier.Subst != null);

      Contract.Requires(codeCopier.OldSubst != null);
      Contract.Ensures(cce.NonNullElements(Contract.Result<List<Block>>()));
      List<Block/*!*/>/*!*/ implBlocks = cce.NonNull(impl.OriginalBlocks);
      Contract.Assert(implBlocks.Count > 0);

      Procedure proc = impl.Proc;
      string startLabel = implBlocks[0].Label;

      List<Block/*!*/>/*!*/ inlinedBlocks = new List<Block/*!*/>();

      // create in block
      List<Cmd> inCmds = new List<Cmd>();

      // assign in parameters
      for (int i = 0; i < impl.InParams.Count; ++i) {
        Cmd cmd = Cmd.SimpleAssign(impl.tok,
                                   (IdentifierExpr)cce.NonNull(codeCopier.Subst)(cce.NonNull(impl.InParams[i])),
                                   cce.NonNull(callCmd.Ins[i]));
        inCmds.Add(cmd);
      }

      // inject requires
      for (int i = 0; i < proc.Requires.Count; i++) {
        Requires/*!*/ req = cce.NonNull(proc.Requires[i]);
        inCmds.Add(InlinedRequires(callCmd, req));
      }

      List<Variable> locVars = cce.NonNull(impl.OriginalLocVars);

      // havoc locals and out parameters in case procedure is invoked in a loop
      List<IdentifierExpr> havocVars = new List<IdentifierExpr>();
      foreach (Variable v in locVars)
      {
          havocVars.Add((IdentifierExpr)codeCopier.Subst(v));
      }
      foreach (Variable v in impl.OutParams)
      {
          havocVars.Add((IdentifierExpr)codeCopier.Subst(v));
      }
      if (havocVars.Count > 0)
      {
          inCmds.Add(new HavocCmd(Token.NoToken, havocVars));
      }

      // add where clauses of local vars as assume
      for (int i = 0; i < locVars.Count; ++i) {
        Expr whereExpr = (cce.NonNull(locVars[i])).TypedIdent.WhereExpr;
        if (whereExpr != null) {
          whereExpr = Substituter.Apply(codeCopier.Subst, whereExpr);
          // FIXME we cannot overwrite it, can we?!
          (cce.NonNull(locVars[i])).TypedIdent.WhereExpr = whereExpr;
          AssumeCmd/*!*/ a = new AssumeCmd(Token.NoToken, whereExpr);
          Contract.Assert(a != null);
          inCmds.Add(a);
        }
      }

      // add where clauses of output params as assume
      for (int i = 0; i < impl.OutParams.Count; ++i) {
        Expr whereExpr = (cce.NonNull(impl.OutParams[i])).TypedIdent.WhereExpr;
        if (whereExpr != null) {
          whereExpr = Substituter.Apply(codeCopier.Subst, whereExpr);
          // FIXME likewise
          (cce.NonNull(impl.OutParams[i])).TypedIdent.WhereExpr = whereExpr;
          AssumeCmd/*!*/ a = new AssumeCmd(Token.NoToken, whereExpr);
          Contract.Assert(a != null);
          inCmds.Add(a);
        }
      }

      // assign modifies old values
      foreach (IdentifierExpr/*!*/ mie in proc.Modifies) {
        Contract.Assert(mie != null);
        Variable/*!*/ mvar = cce.NonNull(mie.Decl);
        AssignCmd assign = Cmd.SimpleAssign(impl.tok, (IdentifierExpr)cce.NonNull(codeCopier.OldSubst(mvar)), mie);
        inCmds.Add(assign);
      }

      GotoCmd inGotoCmd = new GotoCmd(callCmd.tok, new List<String> { GetInlinedProcLabel(proc.Name) + "$" + startLabel });
      Block inBlock = new Block(impl.tok, GetInlinedProcLabel(proc.Name) + "$Entry", inCmds, inGotoCmd);
      inlinedBlocks.Add(inBlock);

      // inject the blocks of the implementation
      Block intBlock;
      foreach (Block block in implBlocks) {
        List<Cmd> copyCmds = codeCopier.CopyCmdSeq(block.Cmds);
        if (0 <= inlineDepth) {
          copyCmds = RemoveAsserts(copyCmds);
        }
        TransferCmd transferCmd = CreateInlinedTransferCmd(cce.NonNull(block.TransferCmd), GetInlinedProcLabel(proc.Name));
        intBlock = new Block(block.tok, GetInlinedProcLabel(proc.Name) + "$" + block.Label, copyCmds, transferCmd);
        inlinedBlocks.Add(intBlock);
      }

      // create out block
      List<Cmd> outCmds = new List<Cmd>();

      // inject ensures
      for (int i = 0; i < proc.Ensures.Count; i++) {
        Ensures/*!*/ ens = cce.NonNull(proc.Ensures[i]);
        outCmds.Add(InlinedEnsures(callCmd, ens));
      }

      // assign out params
      for (int i = 0; i < impl.OutParams.Count; ++i) {
        Expr/*!*/ cout_exp = (IdentifierExpr)cce.NonNull(codeCopier.Subst(cce.NonNull(impl.OutParams[i])));
        Cmd cmd = Cmd.SimpleAssign(impl.tok, cce.NonNull(callCmd.Outs[i]), cout_exp);
        outCmds.Add(cmd);
      }

      // create out block
      GotoCmd outGotoCmd = new GotoCmd(Token.NoToken, new List<String> { nextBlockLabel });
      Block outBlock = new Block(impl.tok, GetInlinedProcLabel(proc.Name) + "$Return", outCmds, outGotoCmd);
      inlinedBlocks.Add(outBlock);

      return inlinedBlocks;
    }
    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;
    }
 private void AssertOrAssumeNonNull(Bpl.IToken token, Bpl.Expr instance) {
   if (this.sink.Options.dereference != Options.Dereference.None) {
     Bpl.Cmd c;
     var n = Bpl.Expr.Ident(this.sink.Heap.NullRef);
     var neq = Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Neq, instance, n);
     if (this.sink.Options.dereference == Options.Dereference.Assume) {
       c = new Bpl.AssumeCmd(token, neq);
     } else {
       c = new Bpl.AssertCmd(token, neq);
     }
     this.StmtTraverser.StmtBuilder.Add(c);
   }
 }
Beispiel #20
0
 public override Cmd VisitAssumeCmd(AssumeCmd node) {
   //Contract.Requires(node != null);
   Contract.Ensures(Contract.Result<Cmd>() != null);
   return base.VisitAssumeCmd((AssumeCmd)node.Clone());
 }
    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;
    }