예제 #1
0
 public BigLiteralAbstracter(VCExpressionGenerator gen)
     : base(gen)
 {
     Contract.Requires(gen != null);
     DummyVar  = gen.Variable("x", Type.Int);
     IncAxioms = new List <VCExpr>();
     Literals  = new List <KeyValuePair <BigNum, VCExprVar> >();
 }
예제 #2
0
            private VCExpr create_let(Term t, VCExpr u)
            {
                var name = "$x" + let_ctr.ToString();

                let_ctr++;
                var sym = gen.Variable(name, u.Type);

                memo.Remove(t);
                memo.Add(t, sym);
                lets.Add(gen.LetBinding(sym, u));
                return(sym);
            }
예제 #3
0
    ////////////////////////////////////////////////////////////////////////////

    private VCExprVar AbstractWithVariable(VCExpr s, VCExpr t)
    {
      Contract.Requires(t != null);
      Contract.Requires(s != null);
      Contract.Requires((s.Type.Equals(t.Type)));
      Contract.Ensures(Contract.Result<VCExprVar>() != null);

      ExprPair pair = new ExprPair(s, t);
      if (!Representation.TryGetValue(pair, out var repr))
      {
        repr = Gen.Variable("abs" + Representation.Count, s.Type);
        Representation.Add(pair, repr);
      }

      return cce.NonNull(repr);
    }
예제 #4
0
파일: Wlp.cs 프로젝트: wrwg/boogie
        /// <summary>
        /// Computes the wlp for an assert or assume command "cmd".
        /// </summary>
        internal static VCExpr Cmd(Block b, Cmd cmd, VCExpr N, VCContext ctxt)
        {
            Contract.Requires(cmd != null);
            Contract.Requires(N != null);
            Contract.Requires(ctxt != null);
            Contract.Ensures(Contract.Result <VCExpr>() != null);

            VCExpressionGenerator gen = ctxt.Ctxt.ExprGen;

            Contract.Assert(gen != null);
            if (cmd is AssertCmd)
            {
                AssertCmd ac = (AssertCmd)cmd;

                var isFullyVerified = false;
                if (ac.VerifiedUnder != null)
                {
                    var litExpr = ac.VerifiedUnder as LiteralExpr;
                    isFullyVerified = litExpr != null && litExpr.IsTrue;
                }

                if (!isFullyVerified)
                {
                    ctxt.Ctxt.BoogieExprTranslator.isPositiveContext = !ctxt.Ctxt.BoogieExprTranslator.isPositiveContext;
                }

                VCExpr C = ctxt.Ctxt.BoogieExprTranslator.Translate(ac.Expr);

                VCExpr VU = null;
                if (!isFullyVerified)
                {
                    if (ac.VerifiedUnder != null)
                    {
                        VU = ctxt.Ctxt.BoogieExprTranslator.Translate(ac.VerifiedUnder);

                        if (CommandLineOptions.Clo.RunDiagnosticsOnTimeout)
                        {
                            ctxt.Ctxt.TimeoutDiagnosticIDToAssertion[ctxt.Ctxt.TimeoutDiagnosticsCount] =
                                new Tuple <AssertCmd, TransferCmd>(ac, b.TransferCmd);
                            VU = gen.Or(VU,
                                        gen.Function(VCExpressionGenerator.TimeoutDiagnosticsOp,
                                                     gen.Integer(BigNum.FromInt(ctxt.Ctxt.TimeoutDiagnosticsCount++))));
                        }
                    }
                    else if (CommandLineOptions.Clo.RunDiagnosticsOnTimeout)
                    {
                        ctxt.Ctxt.TimeoutDiagnosticIDToAssertion[ctxt.Ctxt.TimeoutDiagnosticsCount] =
                            new Tuple <AssertCmd, TransferCmd>(ac, b.TransferCmd);
                        VU = gen.Function(VCExpressionGenerator.TimeoutDiagnosticsOp,
                                          gen.Integer(BigNum.FromInt(ctxt.Ctxt.TimeoutDiagnosticsCount++)));
                    }

                    ctxt.Ctxt.BoogieExprTranslator.isPositiveContext = !ctxt.Ctxt.BoogieExprTranslator.isPositiveContext;
                }

                {
                    var subsumption = Subsumption(ac);
                    if (subsumption == CommandLineOptions.SubsumptionOption.Always ||
                        (subsumption == CommandLineOptions.SubsumptionOption.NotForQuantifiers && !(C is VCExprQuantifier)))
                    {
                        N = gen.ImpliesSimp(C, N, false);
                    }

                    if (isFullyVerified)
                    {
                        return(N);
                    }
                    else if (VU != null)
                    {
                        C = gen.OrSimp(VU, C);
                    }

                    int id = ac.UniqueId;
                    if (ctxt.Label2absy != null)
                    {
                        ctxt.Label2absy[id] = ac;
                    }

                    ctxt.AssertionCount++;

                    if (ctxt.ControlFlowVariableExpr == null)
                    {
                        Contract.Assert(ctxt.Label2absy != null);
                        return(gen.AndSimp(C, N));
                    }
                    else
                    {
                        VCExpr controlFlowFunctionAppl = gen.ControlFlowFunctionApplication(ctxt.ControlFlowVariableExpr,
                                                                                            gen.Integer(BigNum.FromInt(b.UniqueId)));
                        Contract.Assert(controlFlowFunctionAppl != null);
                        VCExpr assertFailure = gen.Eq(controlFlowFunctionAppl, gen.Integer(BigNum.FromInt(-ac.UniqueId)));
                        return(gen.AndSimp(gen.Implies(assertFailure, C), N));
                    }
                }
            }
            else if (cmd is AssumeCmd)
            {
                AssumeCmd ac = (AssumeCmd)cmd;

                if (CommandLineOptions.Clo.StratifiedInlining > 0)
                {
                    // Label the assume if it is a procedure call
                    NAryExpr naryExpr = ac.Expr as NAryExpr;
                    if (naryExpr != null)
                    {
                        if (naryExpr.Fun is FunctionCall)
                        {
                            int id = ac.UniqueId;
                            ctxt.Label2absy[id] = ac;
                            return(MaybeWrapWithOptimization(ctxt, gen, ac.Attributes,
                                                             gen.ImpliesSimp(ctxt.Ctxt.BoogieExprTranslator.Translate(ac.Expr), N)));
                        }
                    }
                }

                var expr = ctxt.Ctxt.BoogieExprTranslator.Translate(ac.Expr);

                var aid = QKeyValue.FindStringAttribute(ac.Attributes, "id");
                if (aid != null)
                {
                    var isTry = QKeyValue.FindBoolAttribute(ac.Attributes, "try");
                    var v     = gen.Variable((isTry ? "try$$" : "assume$$") + aid, Microsoft.Boogie.Type.Bool);
                    expr = gen.Function(VCExpressionGenerator.NamedAssumeOp, v, gen.ImpliesSimp(v, expr));
                }

                var soft       = QKeyValue.FindBoolAttribute(ac.Attributes, "soft");
                var softWeight = QKeyValue.FindIntAttribute(ac.Attributes, "soft", 0);
                if ((soft || 0 < softWeight) && aid != null)
                {
                    var v = gen.Variable("soft$$" + aid, Microsoft.Boogie.Type.Bool);
                    expr = gen.Function(new VCExprSoftOp(Math.Max(softWeight, 1)), v, gen.ImpliesSimp(v, expr));
                }

                return(MaybeWrapWithOptimization(ctxt, gen, ac.Attributes, gen.ImpliesSimp(expr, N)));
            }
            else
            {
                Console.WriteLine(cmd.ToString());
                Contract.Assert(false);
                throw new cce.UnreachableException(); // unexpected command
            }
        }
예제 #5
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));
      }
    }
예제 #6
0
파일: DoomCheck.cs 프로젝트: omaragb/tlp182
        VCExpr LetVC(Block block,
                     Dictionary <int, Absy> label2absy,
                     Hashtable /*<Block, VCExprVar!>*/ blockVariables,
                     List <VCExprLetBinding> bindings,
                     ProverContext proverCtxt,
                     out int assertionCount)
        {
            Contract.Requires(label2absy != null);
            Contract.Requires(blockVariables != null);
            Contract.Requires(proverCtxt != null);
            Contract.Requires(cce.NonNullElements(bindings));
            Contract.Ensures(Contract.Result <VCExpr>() != null);

            assertionCount = 0;
            VCExpressionGenerator gen = proverCtxt.ExprGen;

            Contract.Assert(gen != null);
            VCExprVar v = (VCExprVar)blockVariables[block];

            if (v == null)
            {
                /*
                 * For block A (= block), generate:
                 *   LET_binding A_correct = wp(A_body, (/\ S \in Successors(A) :: S_correct))
                 * with the side effect of adding the let bindings to "bindings" for any
                 * successor not yet visited.
                 */
                VCExpr  SuccCorrect;
                GotoCmd gotocmd = block.TransferCmd as GotoCmd;
                if (gotocmd == null)
                {
                    if (CommandLineOptions.Clo.vcVariety == CommandLineOptions.VCVariety.Doomed)
                    {
                        SuccCorrect = VCExpressionGenerator.False;
                    }
                    else
                    {
                        SuccCorrect = VCExpressionGenerator.True;
                    }
                }
                else
                {
                    Contract.Assert(gotocmd.labelTargets != null);
                    List <VCExpr> SuccCorrectVars = new List <VCExpr>(gotocmd.labelTargets.Count);
                    foreach (Block successor in gotocmd.labelTargets)
                    {
                        Contract.Assert(successor != null);
                        int    ac;
                        VCExpr s = LetVC(successor, label2absy, blockVariables, bindings, proverCtxt, out ac);
                        assertionCount += ac;
                        SuccCorrectVars.Add(s);
                    }
                    SuccCorrect = gen.NAry(VCExpressionGenerator.AndOp, SuccCorrectVars);
                }

                VCContext context = new VCContext(label2absy, proverCtxt);
                //        m_Context = context;

                VCExpr vc = Wlp.Block(block, SuccCorrect, context);
                assertionCount += context.AssertionCount;
                v = gen.Variable(block.Label + "_correct", Microsoft.Boogie.Type.Bool);

                bindings.Add(gen.LetBinding(v, vc));
                blockVariables.Add(block, v);
            }
            return(v);
        }