Example #1
0
        /// <summary>
        /// Provide program for the next procedure (for the global declarations).
        /// </summary>
        public static void Program(Program p)
        {
            if (boogieGlobalData == null)
            {
                boogieGlobalData = new BoogieGlobalData(p.Functions, p.Axioms, p.GlobalVariables, p.Constants);

                var methodData            = BoogieMethodData.CreateOnlyGlobal(boogieGlobalData);
                var fixedVarTranslation   = new DeBruijnFixedVarTranslation(methodData);
                var fixedTyVarTranslation = new DeBruijnFixedTVarTranslation(methodData);
                var factory =
                    new DeBruijnVarFactory(fixedVarTranslation, fixedTyVarTranslation, boogieGlobalData);
                var globalDataTheoryName = "global_data";
                var globalDataConfig     = new IsaProgramGeneratorConfig(null, true, true, true, false, SpecsConfig.None, false);
                globalDataProgAccess = new IsaProgramGenerator().GetIsaProgram(
                    globalDataTheoryName,
                    "proc",
                    methodData, globalDataConfig, factory,
                    null,
                    out var declsGlobalData,
                    !CommandLineOptions.Clo.GenerateIsaProgNoProofs,
                    true
                    );

                var globalDataTheory = new Theory(globalDataTheoryName,
                                                  new List <string> {
                    "Boogie_Lang.Semantics", "Boogie_Lang.TypeSafety", "Boogie_Lang.Util"
                },
                                                  declsGlobalData);
                ProofGenerationOutput.StoreTheoriesTopLevel(new List <Theory> {
                    globalDataTheory
                });
            }
        }
Example #2
0
        /// <summary>
        /// Generate all proofs for the current procedure.
        /// </summary>
        /// <param name="vc">WP of the procedure body</param>
        /// <param name="vcAxioms">VC assumptions for the Boogie axioms</param>
        /// <param name="typeAxioms">VC assumptions for the Boogie type encoding</param>
        /// <param name="typeAxiomInfo">Hints about the type encoding</param>
        /// <param name="gen"></param>
        /// <param name="translator"></param>
        /// <param name="axiomBuilder"></param>
        /// <exception cref="ArgumentException">
        /// axiom builder must be null iff types are not erased (since no polymorphism in vc), otherwise exception is
        /// thrown
        /// </exception>
        public static void VCGenerateAllProofs(
            VCExpr vc,
            VCExpr vcAxioms,
            VCExpr typeAxioms,
            List <VCAxiomInfo> typeAxiomInfo,
            VCExpressionGenerator gen,
            Boogie2VCExprTranslator translator,
            TypeAxiomBuilderPremisses axiomBuilder)
        {
            var uniqueNamer = new IsaUniqueNamer();
            var theories    = new List <Theory>();

            if (axiomBuilder == null && typeAxioms != null)
            {
                throw new ArgumentException("type axioms can only be null if axiom builder is null");
            }

            /* Since in the proofs calls are desugared, there can be more variables in "beforePassiveData". If only
             * the progam should be generaed, then these variables should be ignored. */
            var mainData = CommandLineOptions.Clo.GenerateIsaProgNoProofs ? beforeDagData : beforePassiveData;

            var fixedVarTranslation2   = new DeBruijnFixedVarTranslation(mainData);
            var fixedTyVarTranslation2 = new DeBruijnFixedTVarTranslation(mainData);
            var varTranslationFactory2 =
                new DeBruijnVarFactory(fixedVarTranslation2, fixedTyVarTranslation2, boogieGlobalData);

            #region before cfg to dag program
            var beforeCfgToDagTheoryName = uniqueNamer.GetName(afterPassificationImpl.Name + "_before_cfg_to_dag_prog");
            //Hack: specs config used to distinguish between all (free + checks) (--> expression tuples) or just checked (no tuples)
            var specsConfig              = CommandLineOptions.Clo.GenerateIsaProgNoProofs ? SpecsConfig.All : SpecsConfig.AllPreCheckedPost;
            var beforeCfgToDagConfig     = new IsaProgramGeneratorConfig(globalDataProgAccess, false, false, false, true, specsConfig, true);
            var beforeCfgToDagProgAccess = new IsaProgramGenerator().GetIsaProgram(
                beforeCfgToDagTheoryName,
                afterPassificationImpl.Name,
                mainData, beforeCfgToDagConfig, varTranslationFactory2,
                beforeDagCfg,
                out var programDeclsBeforeCfgToDag,
                !CommandLineOptions.Clo.GenerateIsaProgNoProofs);
            procNameToTopLevelPrograms.Add(afterPassificationImpl.Proc.Name, beforeCfgToDagProgAccess);

            var beforeCfgToDagProgTheory = new Theory(beforeCfgToDagTheoryName,
                                                      new List <string> {
                "Boogie_Lang.Semantics", "Boogie_Lang.TypeSafety", "Boogie_Lang.Util", "\"../" + globalDataProgAccess.TheoryName() + "\""
            },
                                                      programDeclsBeforeCfgToDag);
            theories.Add(beforeCfgToDagProgTheory);
            #endregion

            if (CommandLineOptions.Clo.GenerateIsaProgNoProofs)
            {
                StoreResult("program_" + afterPassificationImpl.Proc.Name, theories);
                return;
            }

            #region before passive program

            var beforePassiveProgTheoryName = uniqueNamer.GetName(afterPassificationImpl.Name + "_before_passive_prog");
            var beforePassiveConfig         =
                new IsaProgramGeneratorConfig(beforeCfgToDagProgAccess, false, false, false, false, SpecsConfig.None, false);
            var beforePassiveProgAccess = new IsaProgramGenerator().GetIsaProgram(beforePassiveProgTheoryName,
                                                                                  afterPassificationImpl.Name,
                                                                                  mainData, beforePassiveConfig, varTranslationFactory2,
                                                                                  beforePassificationCfg,
                                                                                  out var programDeclsBeforePassive,
                                                                                  !CommandLineOptions.Clo.GenerateIsaProgNoProofs);

            #endregion

            var vcAllAxioms = AxiomHandler.AxiomInfo(
                axiomBuilder != null,
                boogieGlobalData.Axioms,
                vcAxioms,
                typeAxioms,
                typeAxiomInfo,
                out var allAxiomsInfo);

            var vcLocale = VCToIsaInterface.ConvertVC(
                "vc",
                vc,
                vcAllAxioms,
                new StandardActiveDecl(),
                translator,
                axiomBuilder,
                finalProgData,
                afterUnreachablePruningCfg,
                out var vcinst,
                out var vcinstAxiom,
                out var vcTranslator,
                out var vcFunctions);

            //use global version map for translation
            var fixedVarTranslation   = new SimpleFixedVarTranslation(globalVersionMap);
            var fixedTyVarTranslation = new DeBruijnFixedTVarTranslation(finalProgData);
            varTranslationFactory =
                new DeBruijnVarFactory(fixedVarTranslation, fixedTyVarTranslation, boogieGlobalData);

            var finalProgTheoryName = uniqueNamer.GetName(afterPassificationImpl.Name + "_passive_prog");
            var passiveProgConfig   =
                new IsaProgramGeneratorConfig(beforePassiveProgAccess, false, false, false, true, SpecsConfig.None, false);
            var passiveProgAccess = new IsaProgramGenerator().GetIsaProgram(finalProgTheoryName,
                                                                            afterPassificationImpl.Name,
                                                                            finalProgData, passiveProgConfig, varTranslationFactory,
                                                                            //we use the CFG before the peep-hole transformations, so that we can directly use the VC to program proof in the passification phase
                                                                            afterPassificationCfg,
                                                                            out var programDecls,
                                                                            !CommandLineOptions.Clo.GenerateIsaProgNoProofs);

            var finalProgTheory =
                new Theory(finalProgTheoryName,
                           new List <string>
            {
                "Boogie_Lang.Semantics", "Boogie_Lang.Util", beforePassiveProgAccess.TheoryName()
            },
                           programDecls);
            theories.Add(finalProgTheory);

            var vcBoogieInfo = new VcBoogieInfo(vcinst, vcinstAxiom, vcAllAxioms, allAxiomsInfo);

            var vcProofData = new ProgramVcProofData(
                vcFunctions,
                vcBoogieInfo,
                vcHintManager,
                vcLocale,
                vcTranslator
                );

            var phasesTheories = new PhasesTheories(afterPassificationImpl.Name);

            var theoryPassive = VcPhaseManager.ProgramToVcProof(
                phasesTheories.TheoryName(PhasesTheories.Phase.Vc),
                _proofGenConfig.GenerateVcE2E,
                afterUnreachablePruningCfg,
                afterPassificationCfg,
                afterPassificationToAfterUnreachableBlock,
                afterPassificationToOrigBlock,
                passiveProgAccess,
                beforePassiveProgAccess,
                finalProgData,
                vcProofData,
                varTranslationFactory,
                typePremiseEraserFactory,
                gen,
                out var vcAssm,
                out var endToEndLemma
                );
            theories.Add(theoryPassive);

            #region before passive

            var passificationProgTheory = new Theory(beforePassiveProgTheoryName,
                                                     new List <string> {
                "Boogie_Lang.Semantics", "Boogie_Lang.Util", beforeCfgToDagTheoryName
            },
                                                     programDeclsBeforePassive);
            theories.Add(passificationProgTheory);

            /*
             * Console.WriteLine("Passive prog mapping: " + fixedVarTranslation.OutputMapping());
             * Console.WriteLine("Before passive prog mapping: " + fixedVarTranslation2.OutputMapping());
             */

            var passificationProofTheory = PassificationManager.PassificationProof(
                phasesTheories.TheoryName(PhasesTheories.Phase.Passification),
                theoryPassive.TheoryName,
                _proofGenConfig.GeneratePassifE2E,
                endToEndLemma,
                vcAssm,
                beforePassificationCfg,
                beforePassiveToAfterPassiveBlock,
                passiveRelationGen,
                beforePassiveProgAccess,
                passiveProgAccess,
                mainData,
                varTranslationFactory2,
                varTranslationFactory
                );
            theories.Add(passificationProofTheory);

            #endregion

            #region cfg to dag

            var uniqueExitBlock =
                uniqueExitBlockOrig != null
                    ? beforePassiveOrigBlock.First(kv => kv.Value == uniqueExitBlockOrig).Key
                    : null;


            var cfgToDagProofTheory = CfgToDagManager.CfgToDagProof(
                phasesTheories,
                _proofGenConfig.GenerateCfgDagE2E,
                vcAssm,
                beforeDagCfg,
                beforePassificationCfg,
                uniqueExitBlock,
                beforeDagData,
                cfgToDagHintManager,
                beforeDagAfterDagBlock,
                beforeCfgToDagProgAccess,
                beforePassiveProgAccess,
                varTranslationFactory2);
            theories.Add(cfgToDagProofTheory);
            #endregion

            StoreResult(afterPassificationImpl.Proc.Name, theories);
        }
        public IProgramAccessor GetIsaProgram(
            string theoryName,
            string procName,
            BoogieMethodData methodData,
            IsaProgramGeneratorConfig config,
            IVariableTranslationFactory varTranslationFactory,
            CFGRepr cfg,
            out IList <OuterDecl> decls,
            bool generateMembershipLemmas = true,
            bool onlyGlobalData           = false
            )
        {
            this.varTranslationFactory = varTranslationFactory;
            varTranslation             = varTranslationFactory.CreateTranslation();
            cmdIsaVisitor = new MultiCmdIsaVisitor(varTranslationFactory);

            /*
             * Term program = IsaBoogieTerm.Program(IsaCommonTerms.TermIdentFromName(funcs.name),
             *  new TermList(new List<Term>()),
             *  new TermList(new List<Term>()),
             *  IsaCommonTerms.TermIdentFromName(axiomsDecl.name),
             *  new List<Term>() { method });
             *
             * var list = new List<Tuple<IList<Term>, Term>>
             * {
             *  new Tuple<IList<Term>, Term>(new List<Term>(), program)
             * };
             */

            //OuterDecl programDefinition = new DefDecl("ProgramM", new Tuple<IList<Term>, Term>(new List<Term>(), program));

            decls = new List <OuterDecl>();
            var isaGlobalProgramRepr = new IsaGlobalProgramRepr(
                FunctionDeclarationsName(),
                AxiomDeclarationsName(),
                VariableDeclarationsName("globals"),
                VariableDeclarationsName("constants")
                );
            var globalsMax = methodData.Constants.Count() + methodData.GlobalVars.Count() - 1;
            // assume single versioning and order on constants, globals, params, locals
            var localsMin = globalsMax + 1;

            if (globalsMax < 0)
            {
                globalsMax = 0;
            }

            MembershipLemmaManager membershipLemmaManager;

            if (onlyGlobalData)
            {
                membershipLemmaManager = new MembershipLemmaManager(
                    isaGlobalProgramRepr, globalsMax, varTranslationFactory, theoryName);
            }
            else
            {
                var outEdges       = GetOutEdgesIsa(procName, cfg, out var edgeLemmas);
                var blockInfo      = BlockToInfo(theoryName, procName, cfg, edgeLemmas);
                var isaProgramRepr = new IsaProgramRepr(
                    isaGlobalProgramRepr,
                    PreconditionDeclarationName(),
                    PostconditionDeclarationName(),
                    VariableDeclarationsName("params"),
                    VariableDeclarationsName("locals"),
                    cfgName,
                    procDefName);
                membershipLemmaManager = new MembershipLemmaManager(config, isaProgramRepr, blockInfo,
                                                                    Tuple.Create(globalsMax, localsMin), varTranslationFactory, theoryName);

                var nodesToBlocks = GetNodeToBlocksIsa(cfg, blockInfo.BlockCmdsDefs);

                decls.AddRange(blockInfo.BlockCmdsDefs.Values);

                Term entry         = new IntConst(BigNum.FromInt(cfg.GetUniqueIntLabel(cfg.entry)));
                var  methodBodyCFG =
                    IsaBoogieTerm.MethodCFGBody(
                        entry, IsaCommonTerms.TermIdentFromName(outEdges.Name),
                        IsaCommonTerms.TermIdentFromName(nodesToBlocks.Name)
                        );

                var methodBodyDecl = GetMethodBodyCFGDecl(procName, methodBodyCFG);
                decls.AddRange(
                    new List <OuterDecl>
                {
                    outEdges, nodesToBlocks, methodBodyDecl
                });

                decls.AddRange(blockInfo.BlockCmdsLemmas.Values);
                decls.AddRange(blockInfo.BlockOutEdgesLemmas.Values);

                if (config.specsConfig != SpecsConfig.None)
                {
                    OuterDecl preconditions;
                    OuterDecl postconditions;

                    if (config.specsConfig == SpecsConfig.AllPreCheckedPost)
                    {
                        preconditions  = GetExprListIsa(PreconditionDeclarationName(), methodData.Preconditions.Select(pre => pre.Item1));
                        postconditions = GetExprListIsa(PostconditionDeclarationName(), methodData.Postconditions.Where(post => !post.Item2).Select(post => post.Item1));
                    }
                    else
                    {
                        preconditions  = GetExprListIsa(PreconditionDeclarationName(), methodData.Preconditions);
                        postconditions = GetExprListIsa(PostconditionDeclarationName(), methodData.Postconditions);
                    }

                    decls.Add(preconditions);
                    decls.Add(postconditions);
                }

                if (config.generateParamsAndLocals)
                {
                    decls.Add(GetVariableDeclarationsIsa("params", methodData.InParams));
                    decls.Add(GetVariableDeclarationsIsa("locals", methodData.Locals));
                }

                /* membership lemmas might still be added even if the parameter and local variable definitions are not generated
                 * at this point (since the variable context may still be different, which requires other lookup lemmas)
                 */
                if (generateMembershipLemmas)
                {
                    membershipLemmaManager.AddVariableMembershipLemmas(methodData.InParams, VarKind.ParamOrLocal);
                    membershipLemmaManager.AddVariableMembershipLemmas(methodData.Locals, VarKind.ParamOrLocal);
                }
            }

            if (config.generateAxioms)
            {
                decls.Add(GetAxioms(methodData.Axioms));
                if (generateMembershipLemmas)
                {
                    membershipLemmaManager.AddAxiomMembershipLemmas(methodData.Axioms);
                }
            }

            if (config.generateFunctions)
            {
                decls.Add(GetFunctionDeclarationsIsa(methodData.Functions));
                if (generateMembershipLemmas)
                {
                    membershipLemmaManager.AddFunctionMembershipLemmas(methodData.Functions);
                }
            }

            if (config.generateGlobalsAndConstants)
            {
                decls.Add(GetVariableDeclarationsIsa("globals", methodData.GlobalVars));
                decls.Add(GetVariableDeclarationsIsa("constants", methodData.Constants));
            }

            if (generateMembershipLemmas)
            {
                membershipLemmaManager.AddVariableMembershipLemmas(methodData.GlobalVars, VarKind.Global);
                membershipLemmaManager.AddVariableMembershipLemmas(methodData.Constants, VarKind.Constant);
                decls.AddRange(membershipLemmaManager.OuterDecls());
            }

            if (config.specsConfig != SpecsConfig.None)
            {
                DefDecl methodDef = MethodDefinition(membershipLemmaManager, methodData, config.specsConfig);
                decls.Add(methodDef);
            }

            return(membershipLemmaManager);
        }