예제 #1
0
        //if blockToNewVars is non-null, then the mapped variables are universally quantified for the corresponding block definition
        public IDictionary <Block, DefDecl> IsaDefsFromVC(IDictionary <Block, VCExpr> blockToVC,
                                                          IDictionary <Block, IList <VCExprVar> > blockToActiveVars,
                                                          CFGRepr cfg,
                                                          IDictionary <Block, IList <VCExprVar> > blockToNewVars = null)
        {
            Contract.Ensures(Contract.Result <IDictionary <Block, DefDecl> >().Count == cfg.NumOfBlocks());

            IDictionary <Block, DefDecl> blockToDefVC = new Dictionary <Block, DefDecl>();

            var vcExprIsaVisitor = new VCExprToIsaTranslator(uniqueNamer, blockToDefVC, blockToActiveVars);

            foreach (var block in cfg.GetBlocksBackwards())
            {
                // might be more efficient to hand over this:
                // IEnumerable<Tuple<Block, DefDecl>> successorDefs = cfg.outgoingBlocks[block].Select(b => new Tuple<Block, DefDecl>(b, blockToDefVC[b]));

                var term = vcExprIsaVisitor.Translate(blockToVC[block]);

                if (blockToNewVars != null && blockToNewVars.TryGetValue(block, out var newVars) && newVars != null &&
                    newVars.Any())
                {
                    IList <Identifier> boundVars = newVars
                                                   .Select(v => (Identifier) new SimpleIdentifier(uniqueNamer.GetName(v, v.Name))).ToList();
                    IList <TypeIsa> boundVarsTypes =
                        newVars.Select(v => pureTyIsaTransformer.Translate(v.Type)).ToList();

                    term = new TermQuantifier(TermQuantifier.QuantifierKind.ALL, boundVars, boundVarsTypes, term);
                }

                IList <Term> args = blockToActiveVars[block].Select(v => vcExprIsaVisitor.Translate(v)).ToList();

                var def = new DefDecl(GetVCDefName(block), new Tuple <IList <Term>, Term>(args, term));

                Contract.Assert(!blockToDefVC.ContainsKey(block));
                blockToDefVC.Add(block, def);
            }

            return(blockToDefVC);
        }
 public VcRewriteLemmaGen(TypePremiseEraserFactory factory, VCExprToIsaTranslator vcToIsaTranslator)
 {
     _typeEraserFactory = factory;
     _vcToIsaTranslator = vcToIsaTranslator;
 }
        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));
        }