示例#1
0
        public IDictionary <Block, ISet <NamedDeclaration> > GetActiveDeclsPerBlock(IDictionary <Block, VCExpr> blockToVC,
                                                                                    IVCVarFunTranslator translator, CFGRepr cfg, out IDictionary <Block, ISet <Variable> > blockToNewVars)
        {
            var blockToDecls = new Dictionary <Block, ISet <NamedDeclaration> >();

            var declCollector = new VCExprDeclCollector();

            foreach (var b in cfg.GetBlocksBackwards())
            {
                var bDecls = declCollector.CollectNamedDeclarations(blockToVC[b], translator);
                foreach (var b_succ in cfg.GetSuccessorBlocks(b))
                {
                    //flattening
                    foreach (var sucDecl in blockToDecls[b_succ])
                    {
                        bDecls.Add(sucDecl);
                    }
                }

                blockToDecls[b] = bDecls;
            }

            blockToNewVars = null;

            return(blockToDecls);
        }
        //length of vcAxioms is at least length n of axioms (direct correspondence between the first n elements of the
        //two lists)
        private static IDictionary <VCExpr, ISet <NamedDeclaration> > VCInstAxioms(
            IEnumerable <VCExpr> vcAxioms,
            IVCVarFunTranslator translator)
        {
            var result = new Dictionary <VCExpr, ISet <NamedDeclaration> >();

            var collector = new VCExprDeclCollector();

            foreach (var ax in vcAxioms)
            {
                var activeDecls = collector.CollectNamedDeclarations(ax, translator);
                result.Add(ax, activeDecls);
            }

            return(result);
        }
        public IDictionary <Block, ISet <NamedDeclaration> > GetActiveDeclsPerBlock(IDictionary <Block, VCExpr> blockToVC,
                                                                                    IVCVarFunTranslator translator, CFGRepr cfg, out IDictionary <Block, ISet <Variable> > blockToNewVars)
        {
            var blockToDefinedDecls = new Dictionary <Block, ISet <NamedDeclaration> >();

            foreach (var b in cfg.GetBlocksForwards())
            {
                blockToDefinedDecls.Add(b, new HashSet <NamedDeclaration>());
            }

            var declCollector = new VCExprDeclCollector();

            var blockToNamedDecls = new Dictionary <Block, ISet <NamedDeclaration> >();

            //compute all named declarations in the VC for each block b which have been used before b is reached
            foreach (var b in cfg.GetBlocksForwards())
            {
                var bDecls = declCollector.CollectNamedDeclarations(blockToVC[b], translator);
                blockToNamedDecls.Add(b, bDecls);

                foreach (var bSucc in cfg.GetSuccessorBlocks(b))
                {
                    blockToDefinedDecls[bSucc].UnionWith(bDecls);
                    blockToDefinedDecls[bSucc].UnionWith(blockToDefinedDecls[b]);
                }
            }

            //compute all named declarations in the VC for each block b that are in any path reached from b and which were defined in any path reaching b
            //named declarations which are not variables are trivially defined at the beginning of the CFG
            var blockToActiveDecls = new Dictionary <Block, ISet <NamedDeclaration> >();

            blockToNewVars = new Dictionary <Block, ISet <Variable> >();
            foreach (var b in cfg.GetBlocksBackwards())
            {
                var bDecls = blockToNamedDecls[b];

                ISet <NamedDeclaration> oldActiveDecls = new HashSet <NamedDeclaration>();
                ISet <Variable>         newDecls       = new HashSet <Variable>();

                foreach (var d in bDecls)
                {
                    if (d is Variable v && !blockToDefinedDecls[b].Contains(d))
                    {
                        newDecls.Add(v);
                    }
        public static LocaleDecl ConvertVC(
            string localeName,
            VCExpr vc,
            IEnumerable <VCExpr> vcAxioms,
            IActiveDeclGenerator activeDeclGenerator,
            Boogie2VCExprTranslator translator,
            TypeAxiomBuilderPremisses axiomBuilder,
            BoogieMethodData methodData,
            CFGRepr cfg,
            out VCInstantiation <Block> vcinst,
            out VCInstantiation <VCExpr> vcinstAxiom,
            out IVCVarFunTranslator vcTranslator,
            out IEnumerable <Function> vcTypeFunctions)
        {
            var vcLet = vc as VCExprLet;

            Contract.Assert(vcLet != null);

            var uniqueNamer = new IsaUniqueNamer();
            var blockToVC   = VCBlockExtractor.BlockToVCMapping(vcLet, cfg);

            var declCollector = new VCFunDeclCollector();
            var funToVCfun    =
                declCollector.CollectFunDeclarations(new List <VCExpr> {
                vc
            }.Concat(vcAxioms), methodData.Functions);
            IVCVarFunTranslator varTranslator =
                new VCVarFunTranslator(methodData.AllVariables(), funToVCfun, translator, axiomBuilder);

            var activeDeclsPerBlock =
                activeDeclGenerator.GetActiveDeclsPerBlock(blockToVC, varTranslator, cfg, out var blockToNewVars);

            #region temporary: extend vc instantiation to support vc functions

            IList <Function> otherFunctions    = new List <Function>();
            ISet <Function>  otherFunctionsSet = new HashSet <Function>();

            foreach (var decl in activeDeclsPerBlock[cfg.entry])
            {
                if (decl is Function fun && !varTranslator.TranslateBoogieFunction(fun, out _))
                {
                    otherFunctions.Add(fun);
                    otherFunctionsSet.Add(fun);
                }
            }

            //also record functions that are used elswhere (type axiom related functions)
            var collector = new VCExprDeclCollector();
            var vcExprs   = vcAxioms.ToList();
            foreach (var ax in vcExprs)
            {
                var decls = collector.CollectNamedDeclarations(ax, varTranslator);
                foreach (var d in decls)
                {
                    if (d is Function fun && !varTranslator.TranslateBoogieFunction(fun, out _) &&
                        !otherFunctions.Contains(d))
                    {
                        otherFunctions.Add(fun);
                    }
                }
            }

            #endregion

            IDictionary <Block, IList <NamedDeclaration> > activeDeclsPerBlockSorted =
                SortActiveDecls(activeDeclsPerBlock, methodData.Functions.Union(otherFunctions), varTranslator,
                                out var activeVarsPerBlock);

            var blockToNewVCVars = ConvertVariableToVCExpr(blockToNewVars, varTranslator);

            var blockToIsaTranslator = new VCBlockToIsaTranslator(uniqueNamer);
            var blockToVCExpr        =
                blockToIsaTranslator.IsaDefsFromVC(blockToVC, activeVarsPerBlock, cfg, blockToNewVCVars);

            //add vc definitions of blocks in correct order
            IList <OuterDecl> vcOuterDecls = new List <OuterDecl>();

            foreach (var block in cfg.GetBlocksBackwards())
            {
                vcOuterDecls.Add(blockToVCExpr[block]);
            }

            vcinst = new VCInstantiation <Block>(blockToVCExpr, activeDeclsPerBlockSorted, localeName);

            /*
             *
             * //reason for using second reference: cannot use out parameters in lambda expressions
             * var vcinstInternal = vcinst;
             *
             * LemmaDecl vcCorrectLemma = new LemmaDecl("vc_correct",
             *  new TermApp(vcinstInternal.GetVCObjRef(cfg.entry, false),
             *             activeVarsPerBlock[cfg.entry].Select(v => (Term) IsaCommonTerms.TermIdentFromName(uniqueNamer.GetName(v, v.Name))).ToList()),
             *  new Proof(
             *    new List<string>() {
             *        "apply (simp only: " +
             *        cfg.GetBlocksForwards().Select(b => vcinstInternal.GetVCObjNameRef(b, false) + "_def").Concat(" ")
             + ")",
             +        "oops"
             +    }
             +  ));
             +
             + vcOuterDecls.Add(vcCorrectLemma);
             */

            //axioms
            var activeDeclsPerAxiom = VCInstAxioms(vcExprs, varTranslator);
            IDictionary <VCExpr, IList <NamedDeclaration> > activeDeclsPerAxiomSorted =
                SortActiveDecls(activeDeclsPerAxiom, methodData.Functions.Union(otherFunctions), varTranslator,
                                out var activeVarsPerAxiom);
            var axiomToDef          = new Dictionary <VCExpr, DefDecl>();
            var vcExprIsaTranslator = new VCExprToIsaTranslator(uniqueNamer);

            if (activeDeclsPerAxiomSorted.Count != vcExprs.Count())
            {
                throw new ProofGenUnexpectedStateException(typeof(VCToIsaInterface), "count not in-sync");
            }

            var axId = 0;
            foreach (var vcAx in activeDeclsPerAxiomSorted.Keys)
            {
                IList <Term> args = activeVarsPerAxiom[vcAx].Select(v => vcExprIsaTranslator.Translate(v)).ToList();
                var          rhs  = vcExprIsaTranslator.Translate(vcAx);

                var def = new DefDecl("vcax_" + axId, new Tuple <IList <Term>, Term>(args, rhs));
                axiomToDef.Add(vcAx, def);
                axId++;
            }

            vcinstAxiom = new VCInstantiation <VCExpr>(axiomToDef, activeDeclsPerAxiomSorted, localeName);

            vcOuterDecls.AddRange(axiomToDef.Values);

            var vcFunctions = methodData.Functions.Where(f => varTranslator.TranslateBoogieFunction(f, out var result))
                              .Select(f =>
            {
                if (varTranslator.TranslateBoogieFunction(f, out var result))
                {
                    return(result);
                }
                throw new InvalidOperationException();
            }).Union(otherFunctions);

            vcTranslator    = varTranslator;
            vcTypeFunctions = otherFunctions;

            return(new LocaleDecl(localeName, ContextElem.CreateWithFixedVars(GetVarsInVC(vcFunctions, uniqueNamer)),
                                  vcOuterDecls));
        }