private VCExpr Execute(Implementation impl, VCExpr vcExpr)
        {
            impl.Blocks.ForEach(block => block.Cmds.OfType <PredicateCmd>().Iter(predicateCmd =>
            {
                AddDictionary(FindInstantiationSources(predicateCmd, "add_to_pool", exprTranslator), labelToInstances);
            }));
            vcExpr            = Skolemizer.Skolemize(this, Polarity.Negative, vcExpr);
            lambdaToInstances = LambdaInstanceCollector.CollectInstances(this, vcExpr);
            while (labelToInstances.Count > 0)
            {
                var currLabelToInstances = labelToInstances;
                labelToInstances = new Dictionary <string, HashSet <VCExpr> >();
                AddDictionary(currLabelToInstances, accLabelToInstances);

                var currLambdaToInstances = lambdaToInstances;
                lambdaToInstances = new Dictionary <Function, HashSet <List <VCExpr> > >();
                AddDictionary(currLambdaToInstances, accLambdaToInstances);

                var visitedQuantifierBindings = new HashSet <VCExprVar>();
                while (visitedQuantifierBindings.Count < quantifierBinding.Count)
                {
                    foreach (var v in quantifierBinding.Keys)
                    {
                        if (visitedQuantifierBindings.Contains(v))
                        {
                            continue;
                        }
                        visitedQuantifierBindings.Add(v);
                        var quantifierExpr = quantifierBinding[v];
                        var quantifierInfo = quantifierInstantiationInfo[quantifierExpr];
                        if (quantifierInfo.relevantLabels.Overlaps(currLabelToInstances.Keys))
                        {
                            InstantiateQuantifier(quantifierExpr);
                        }
                    }
                }

                var visitedLambdaFunctions = new HashSet <Function>();
                while (visitedLambdaFunctions.Count < lambdaDefinition.Count)
                {
                    foreach (var lambdaFunction in lambdaDefinition.Keys)
                    {
                        if (visitedLambdaFunctions.Contains(lambdaFunction))
                        {
                            continue;
                        }
                        visitedLambdaFunctions.Add(lambdaFunction);
                        var quantifierExpr = lambdaDefinition[lambdaFunction];
                        var quantifierInfo = quantifierInstantiationInfo[quantifierExpr];
                        if (quantifierInfo.relevantLabels.Overlaps(currLabelToInstances.Keys) ||
                            currLambdaToInstances[lambdaFunction].Count > 0)
                        {
                            InstantiateLambdaDefinition(lambdaFunction);
                        }
                    }
                }
            }

            var lambdaAxioms = vcExprGen.NAry(VCExpressionGenerator.AndOp, lambdaDefinition.Values
                                              .SelectMany(quantifierExpr =>
                                                          quantifierInstantiationInfo[quantifierExpr].instances.Values.ToList()).ToList());

            return(vcExprGen.Implies(lambdaAxioms, LetConvert(vcExpr)));
        }
Esempio n. 2
0
        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);
        }