Пример #1
0
    public void GenerateVC()
    {
      if (initialized) return;
      if (CommandLineOptions.Clo.SIBoolControlVC)
      {
        GenerateVCBoolControl();
        initialized = true;
        return;
      }

      List<Variable> outputVariables = new List<Variable>();
      List<Expr> assertConjuncts = new List<Expr>();
      foreach (Variable v in impl.OutParams)
      {
        Constant c = new Constant(Token.NoToken,
          new TypedIdent(Token.NoToken, impl.Name + "_" + v.Name, v.TypedIdent.Type));
        outputVariables.Add(c);
        Expr eqExpr = Expr.Eq(new IdentifierExpr(Token.NoToken, c), new IdentifierExpr(Token.NoToken, v));
        assertConjuncts.Add(eqExpr);
      }

      foreach (IdentifierExpr e in impl.Proc.Modifies)
      {
        if (e.Decl == null) continue;
        Variable v = e.Decl;
        Constant c = new Constant(Token.NoToken,
          new TypedIdent(Token.NoToken, impl.Name + "_" + v.Name, v.TypedIdent.Type));
        outputVariables.Add(c);
        Expr eqExpr = Expr.Eq(new IdentifierExpr(Token.NoToken, c), new IdentifierExpr(Token.NoToken, v));
        assertConjuncts.Add(eqExpr);
      }

      exitAssertCmd = new AssertCmd(Token.NoToken, Expr.Not(Expr.BinaryTreeAnd(assertConjuncts)));

      Program program = vcgen.program;
      ProverInterface proverInterface = vcgen.prover;
      vcgen.ConvertCFG2DAG(impl);
      vcgen.PassifyImpl(impl, out mvInfo);

      VCExpressionGenerator gen = proverInterface.VCExprGen;
      var exprGen = proverInterface.Context.ExprGen;
      var translator = proverInterface.Context.BoogieExprTranslator;

      controlFlowVariable =
        new LocalVariable(Token.NoToken, new TypedIdent(Token.NoToken, "@cfc", Microsoft.Boogie.Type.Int));
      VCExpr controlFlowVariableExpr = translator.LookupVariable(controlFlowVariable);

      vcgen.InstrumentCallSites(impl);

      if (PassiveImplInstrumentation != null)
        PassiveImplInstrumentation(impl);

      label2absy = new Dictionary<int, Absy>();
      VCGen.CodeExprConversionClosure cc = new VCGen.CodeExprConversionClosure(label2absy, proverInterface.Context);
      translator.SetCodeExprConverter(cc.CodeExprToVerificationCondition);
      vcexpr = gen.Not(vcgen.GenerateVCAux(impl, controlFlowVariableExpr, label2absy, proverInterface.Context));

      if (controlFlowVariableExpr != null)
      {
        VCExpr controlFlowFunctionAppl =
          exprGen.ControlFlowFunctionApplication(controlFlowVariableExpr, exprGen.Integer(BigNum.ZERO));
        VCExpr eqExpr = exprGen.Eq(controlFlowFunctionAppl, exprGen.Integer(BigNum.FromInt(impl.Blocks[0].UniqueId)));
        vcexpr = exprGen.And(eqExpr, vcexpr);
      }

      callSites = vcgen.CollectCallSites(impl);
      recordProcCallSites = vcgen.CollectRecordProcedureCallSites(impl);

      privateExprVars = new List<VCExprVar>();
      foreach (Variable v in impl.LocVars)
      {
        privateExprVars.Add(translator.LookupVariable(v));
      }

      foreach (Variable v in impl.OutParams)
      {
        privateExprVars.Add(translator.LookupVariable(v));
      }

      interfaceExprVars = new List<VCExprVar>();
      foreach (Variable v in program.GlobalVariables)
      {
        interfaceExprVars.Add(translator.LookupVariable(v));
      }

      foreach (Variable v in impl.InParams)
      {
        interfaceExprVars.Add(translator.LookupVariable(v));
      }

      foreach (Variable v in outputVariables)
      {
        interfaceExprVars.Add(translator.LookupVariable(v));
      }

      initialized = true;
    }
Пример #2
0
    public void GenerateVCBoolControl()
    {
      Debug.Assert(!initialized);
      Debug.Assert(CommandLineOptions.Clo.SIBoolControlVC);

      // fix names for exit variables
      var outputVariables = new List<Variable>();
      var assertConjuncts = new List<Expr>();
      foreach (Variable v in impl.OutParams)
      {
        Constant c = new Constant(Token.NoToken,
          new TypedIdent(Token.NoToken, impl.Name + "_" + v.Name, v.TypedIdent.Type));
        outputVariables.Add(c);
        Expr eqExpr = Expr.Eq(new IdentifierExpr(Token.NoToken, c), new IdentifierExpr(Token.NoToken, v));
        assertConjuncts.Add(eqExpr);
      }

      foreach (IdentifierExpr e in impl.Proc.Modifies)
      {
        if (e.Decl == null) continue;
        Variable v = e.Decl;
        Constant c = new Constant(Token.NoToken,
          new TypedIdent(Token.NoToken, impl.Name + "_" + v.Name, v.TypedIdent.Type));
        outputVariables.Add(c);
        Expr eqExpr = Expr.Eq(new IdentifierExpr(Token.NoToken, c), new IdentifierExpr(Token.NoToken, v));
        assertConjuncts.Add(eqExpr);
      }

      exitAssertCmd = new AssumeCmd(Token.NoToken, Expr.BinaryTreeAnd(assertConjuncts));
      (exitAssertCmd as AssumeCmd).Attributes = new QKeyValue(Token.NoToken, "exitAssert", new List<object>(), null);

      // no need for label2absy
      label2absy = new Dictionary<int, Absy>();

      // Passify
      Program program = vcgen.program;
      ProverInterface proverInterface = vcgen.prover;
      vcgen.ConvertCFG2DAG(impl);
      vcgen.PassifyImpl(impl, out mvInfo);

      VCExpressionGenerator gen = proverInterface.VCExprGen;
      var exprGen = proverInterface.Context.ExprGen;
      var translator = proverInterface.Context.BoogieExprTranslator;

      // add a boolean variable at each call site
      vcgen.InstrumentCallSites(impl);

      // typecheck
      var tc = new TypecheckingContext(null);
      impl.Typecheck(tc);

      ///////////////////
      // Generate the VC
      ///////////////////

      // block -> bool variable
      blockToControlVar = new Dictionary<Block, VCExprVar>();
      foreach (var b in impl.Blocks)
        blockToControlVar.Add(b, gen.Variable(b.Label + "_holds", Bpl.Type.Bool));

      vcexpr = VCExpressionGenerator.True;
      foreach (var b in impl.Blocks)
      {
        // conjoin all assume cmds
        VCExpr c = VCExpressionGenerator.True;
        foreach (var cmd in b.Cmds)
        {
          var acmd = cmd as AssumeCmd;
          if (acmd == null)
          {
            Debug.Assert(cmd is AssertCmd && (cmd as AssertCmd).Expr is LiteralExpr &&
                         ((cmd as AssertCmd).Expr as LiteralExpr).IsTrue);
            continue;
          }

          var expr = translator.Translate(acmd.Expr);
          c = gen.AndSimp(c, expr);
        }

        // block implies a disjunction of successors
        Debug.Assert(!(b.TransferCmd is ReturnExprCmd), "Not supported");
        var gc = b.TransferCmd as GotoCmd;
        if (gc != null)
        {
          VCExpr succ = VCExpressionGenerator.False;
          foreach (var sb in gc.labelTargets)
            succ = gen.OrSimp(succ, blockToControlVar[sb]);
          c = gen.AndSimp(c, succ);
        }
        else
        {
          // nothing to do
        }

        vcexpr = gen.AndSimp(vcexpr, gen.Eq(blockToControlVar[b], c));
      }

      // assert start block
      vcexpr = gen.AndSimp(vcexpr, blockToControlVar[impl.Blocks[0]]);

      //Console.WriteLine("VC of {0}: {1}", impl.Name, vcexpr);
      // Collect other information
      callSites = vcgen.CollectCallSites(impl);
      recordProcCallSites = vcgen.CollectRecordProcedureCallSites(impl);

      // record interface variables
      privateExprVars = new List<VCExprVar>();
      foreach (Variable v in impl.LocVars)
      {
        privateExprVars.Add(translator.LookupVariable(v));
      }

      foreach (Variable v in impl.OutParams)
      {
        privateExprVars.Add(translator.LookupVariable(v));
      }

      privateExprVars.AddRange(blockToControlVar.Values);

      interfaceExprVars = new List<VCExprVar>();
      foreach (Variable v in program.GlobalVariables)
      {
        interfaceExprVars.Add(translator.LookupVariable(v));
      }

      foreach (Variable v in impl.InParams)
      {
        interfaceExprVars.Add(translator.LookupVariable(v));
      }

      foreach (Variable v in outputVariables)
      {
        interfaceExprVars.Add(translator.LookupVariable(v));
      }
    }