Esempio n. 1
0
        /// <summary>
        ///     Return lookup lemmas for each element in the old relation as well as the definition of the old relation, which
        ///     is defined via an association list
        /// </summary>
        private static StateRelationData OldRelation(
            ISet <Variable> oldGlobalVars,
            IVariableTranslation <Variable> variableTranslation,
            out IList <OuterDecl> oldRelDecls)
        {
            //assume that passive version representing old variable of "g" is "g" itself
            var oldRelTuples     = new List <Term>();
            var varList          = new List <Variable>();
            var varToLookupLemma = new Dictionary <Variable, LemmaDecl>();
            var uniqueNamer      = new IsaUniqueNamer();

            foreach (var v in oldGlobalVars)
            {
                if (variableTranslation.TryTranslateVariableId(v, out var varTermId, out _))
                {
                    oldRelTuples.Add(new TermTuple(varTermId, IsaCommonTerms.Inl(varTermId)));
                    var lemma = new LemmaDecl(
                        "lookup_old_rel" + uniqueNamer.GetName(v, v.Name),
                        TermBinary.Eq(new TermApp(oldRel, varTermId),
                                      IsaCommonTerms.SomeOption(IsaCommonTerms.Inl(varTermId))),
                        new Proof(new List <string>
                    {
                        "unfolding " + oldRelListName + "_def " + oldRelName + "_def",
                        "by simp"
                    })
                        );
                    varToLookupLemma.Add(v, lemma);
                    varList.Add(v);
                }
Esempio n. 2
0
        public override int VisitLemmaDecl(LemmaDecl d)
        {
            _sb.Append("lemma ").Append(d.Name).Append(":");
            if (!d.ContextElem.IsEmpty())
            {
                _sb.AppendLine();
                PrintContextElem(d.ContextElem);
            }

            _sb.AppendLine();

            _sb.Append("shows ");
            bool first = true;

            foreach (var stmt in d.Statements)
            {
                if (first)
                {
                    first = false;
                }
                else
                {
                    _sb.Append(" and ");
                }
                AppendInner(_termPrinter.Visit(stmt));
            }

            _sb.AppendLine();
            PrintProof(d.Proof);

            return(0);
        }
        public IEnumerable <OuterDecl> EndToEndProof(
            string entryCfgLemma,
            string passificationEndToEndLemma,
            Term vcAssm,
            IProgramAccessor programAccessor,
            CFGRepr cfg)
        {
            this.programAccessor = programAccessor;
            boogieContext        = new BoogieContextIsa(
                IsaCommonTerms.TermIdentFromName("A"),
                IsaCommonTerms.TermIdentFromName("M"),
                IsaCommonTerms.TermIdentFromName(varContextName),
                IsaCommonTerms.TermIdentFromName("\\<Gamma>"),
                IsaCommonTerms.EmptyList
                );

            var abbrev = new AbbreviationDecl(
                varContextName,
                new Tuple <IList <Term>, Term>(new List <Term>(),
                                               new TermTuple(programAccessor.ConstsAndGlobalsDecl(), programAccessor.ParamsAndLocalsDecl()))
                );
            var result = new List <OuterDecl> {
                abbrev
            };

            var kStepRed = IsaBoogieTerm.RedCFGKStep(
                BoogieContextIsa.CreateWithNewVarContext(
                    boogieContext,
                    new TermTuple(programAccessor.ConstsAndGlobalsDecl(), programAccessor.ParamsAndLocalsDecl())
                    ),
                programAccessor.CfgDecl(),
                IsaBoogieTerm.CFGConfigNode(new NatConst(cfg.GetUniqueIntLabel(cfg.entry)),
                                            IsaBoogieTerm.Normal(normalInitState)),
                IsaCommonTerms.TermIdentFromName("j"),
                IsaBoogieTerm.CFGConfig(finalNodeOrReturn, finalState)
                );

            var proofSb = new StringBuilder();

            proofSb.AppendLine("proof -");
            proofSb.AppendLine("from " + redAssmName + " obtain j where Aux:" + "\"" + kStepRed + "\"");
            proofSb.AppendLine("by (meson rtranclp_imp_relpowp)");
            proofSb.AppendLine("show ?thesis");
            proofSb.AppendLine(ProofUtil.Apply("rule " + entryCfgLemma));
            //TODO: don't hardcode this
            proofSb.AppendLine("unfolding cfg_to_dag_lemmas_def");
            proofSb.AppendLine(ProofUtil.Apply("rule " + finterpAssmName));
            proofSb.AppendLine("apply (rule Aux)");
            proofSb.AppendLine("apply (rule dag_lemma_assms_same)");
            proofSb.AppendLine("unfolding state_well_typed_def");
            proofSb.AppendLine("apply (intro conjI)");
            proofSb.AppendLine("using " + paramsLocalsAssmName + " apply simp");
            proofSb.AppendLine("using " + constsGlobalsAssmName + " apply simp");
            proofSb.AppendLine("using " + constsGlobalsAssmName + " " + oldGlobalAssmName + " apply simp");
            proofSb.AppendLine("using " + binderEmptyAssmName + " apply simp");
            proofSb.AppendLine(ProofUtil.Apply("rule " + passificationEndToEndLemma));
            //TODO: don't hardcode this
            proofSb.AppendLine("unfolding glue_proof_def");
            proofSb.AppendLine("apply (intro conjI)");
            proofSb.AppendLine("apply assumption");
            proofSb.AppendLine("using " + vcAssmName + " apply simp");
            proofSb.AppendLine("using " + closedAssmName + " apply simp");
            proofSb.AppendLine("using " + nonEmptyTypesAssmName + " apply simp");
            proofSb.AppendLine(ProofUtil.Apply("rule " + finterpAssmName));
            proofSb.AppendLine("using " + axiomAssmName + " apply simp");
            proofSb.AppendLine("using " + paramsLocalsAssmName + " apply simp");
            proofSb.AppendLine("using " + constsGlobalsAssmName + " apply simp");
            proofSb.AppendLine("using " + binderEmptyAssmName + " apply simp");
            proofSb.AppendLine("using " + oldGlobalAssmName + " apply simp");
            proofSb.AppendLine("using " + preconditionsAssmName + " apply simp");
            proofSb.AppendLine("done");
            proofSb.AppendLine("qed");

            var helperLemmaName = "end_to_end_theorem_aux";

            var helperLemma =
                new LemmaDecl(
                    helperLemmaName,
                    LemmaContext(cfg, vcAssm),
                    CfgToDagLemmaManager.CfgLemmaConclusion(boogieContext, programAccessor.PostconditionsDecl(),
                                                            finalNodeOrReturn, finalState),
                    new Proof(new List <string> {
                proofSb.ToString()
            })
                    );

            result.Add(helperLemma);
            //transform end to end theorem to a compact representation

            var endToEndLemma =
                new LemmaDecl(
                    "end_to_end_theorem",
                    ContextElem.CreateWithAssumptions(new List <Term> {
                vcAssm
            }, new List <string> {
                "VC"
            }),
                    ProcedureIsCorrect(
                        programAccessor.FunctionsDecl(),
                        IsaCommonTerms.TermIdentFromName(programAccessor.ConstsDecl()),
                        IsaCommonTerms.TermIdentFromName(programAccessor.GlobalsDecl()),
                        programAccessor.AxiomsDecl(),
                        programAccessor.ProcDecl()),
                    new Proof(
                        new List <string>
            {
                ProofUtil.Apply(ProofUtil.Rule(ProofUtil.OF("end_to_end_util", helperLemmaName))),
                "apply assumption " + "using VC apply simp " + " apply assumption+",
                ProofUtil.By("simp_all add: exprs_to_only_checked_spec_1 exprs_to_only_checked_spec_2 " +
                             programAccessor.ProcDeclName() + "_def " + programAccessor.CfgDeclName() + "_def")
            }
                        ));

            result.Add(endToEndLemma);
            return(result);
        }
Esempio n. 4
0
        public static Theory PassificationProof(
            string theoryName,
            string boogieToVcTheoryName,
            bool generateEndToEndLemma,
            LemmaDecl boogieToVcLemma,
            Term vcAssm,
            CFGRepr beforePassificationCfg,
            IDictionary <Block, Block> nonPassiveToPassiveBlock,
            PassiveRelationGen relationGen,
            IProgramAccessor beforePassiveProgAccess,
            IProgramAccessor passiveProgAccess,
            BoogieMethodData beforePassiveData,
            IVariableTranslationFactory beforePassiveFactory,
            IVariableTranslationFactory passiveFactory)
        {
            var varContextName              = "\\<Lambda>1";
            var passiveVarContextName       = "\\<Lambda>2";
            var varContextNonPassivePassive = Tuple.Create(varContextName, passiveVarContextName);

            var oldGlobalVars   = GetOldGlobalVariables(beforePassificationCfg);
            var oldRelationData =
                OldRelation(
                    oldGlobalVars,
                    beforePassiveFactory.CreateTranslation().VarTranslation,
                    out var oldRelListDecl);

            var passificationProofDecls = new List <OuterDecl>();

            passificationProofDecls.AddRange(oldRelListDecl);
            passificationProofDecls.AddRange(oldRelationData.VarToLookupLemma.Values);
            if (oldRelationData.VarToLookupLemma.Any())
            {
                passificationProofDecls.Add(new LemmasDecl(allOldLookupLemmasName,
                                                           oldRelationData.VarToLookupLemma.Values.Select(lemma => lemma.Name).ToList()));
            }

            var beforePassiveLemmaManager = new PassificationLemmaManager(
                beforePassificationCfg,
                nonPassiveToPassiveBlock,
                beforePassiveProgAccess,
                passiveProgAccess,
                varContextNonPassivePassive,
                oldRelationData,
                relationGen,
                beforePassiveFactory,
                passiveFactory
                );

            var lemmaNamer = new IsaUniqueNamer();

            var varContextAbbrev = new AbbreviationDecl(
                varContextName,
                new Tuple <IList <Term>, Term>(new List <Term>(), beforePassiveProgAccess.VarContext())
                );

            var passiveVarContextAbbrev = new AbbreviationDecl(
                passiveVarContextName,
                new Tuple <IList <Term>, Term>(new List <Term>(), passiveProgAccess.VarContext())
                );

            passificationProofDecls.Add(varContextAbbrev);
            passificationProofDecls.Add(passiveVarContextAbbrev);

            passificationProofDecls.AddRange(beforePassiveLemmaManager.Prelude());

            var cfgLemmas = new List <OuterDecl>();

            foreach (var block in beforePassificationCfg.GetBlocksBackwards())
            {
                var localAndCfgLemma =
                    beforePassiveLemmaManager.GenerateBlockLemma(
                        block,
                        GetLemmaName(block, lemmaNamer),
                        b => GetCfgLemmaName(b, lemmaNamer));
                passificationProofDecls.Add(localAndCfgLemma.Item1);
                cfgLemmas.Add(localAndCfgLemma.Item2);
            }

            //add cfg lemmas at the end
            passificationProofDecls.AddRange(cfgLemmas);

            if (generateEndToEndLemma)
            {
                var endToEnd = new PassificationEndToEnd();

                passificationProofDecls.AddRange(endToEnd.EndToEndProof(
                                                     GetCfgLemmaName(beforePassificationCfg.entry, lemmaNamer),
                                                     boogieToVcTheoryName + "." + boogieToVcLemma.Name,
                                                     vcAssm,
                                                     beforePassiveProgAccess,
                                                     passiveProgAccess,
                                                     varContextNonPassivePassive,
                                                     oldRelationData,
                                                     beforePassificationCfg,
                                                     relationGen.LiveVarsBeforeBlock(beforePassificationCfg.entry),
                                                     passiveFactory.CreateTranslation().VarTranslation
                                                     ));
            }

            var imports = new List <string>
            {
                "Boogie_Lang.Semantics", "Boogie_Lang.Util", beforePassiveProgAccess.TheoryName(),
                passiveProgAccess.TheoryName(), "Boogie_Lang.PassificationML",
                boogieToVcTheoryName
            };

            if (generateEndToEndLemma)
            {
                imports.Add("Boogie_Lang.PassificationEndToEnd");
            }

            return(new Theory(theoryName, imports, passificationProofDecls));
        }
Esempio n. 5
0
        public LemmaDecl GenerateCfgLemma(
            Block block,
            Block finalCfgBlock,
            bool isContainedInFinalCfg,
            IEnumerable <Block> successors,
            IEnumerable <Block> finalCfgSuccessors,
            Term cfg,
            Func <Block, string> cfgLemmaName,
            LemmaDecl BlockLemma)
        {
            var red = IsaBoogieTerm.RedCFGMulti(
                boogieContext,
                cfg,
                IsaBoogieTerm.CFGConfigNode(new NatConst(isaBlockInfo.BlockIds[block]),
                                            IsaBoogieTerm.Normal(normalInitState)),
                IsaBoogieTerm.CFGConfig(finalNode, finalState));
            var assumption = new List <Term> {
                red
            };
            var hasVcAssm = false;

            if (isContainedInFinalCfg)
            {
                assumption.Add(vcinst.GetVCObjInstantiation(finalCfgBlock, declToVCMapping));
                hasVcAssm = true;
            }
            else
            {
                //vc assumption is conjunction of reachable successors in final cfg
                if (finalCfgSuccessors.Any())
                {
                    assumption.Add(
                        LemmaHelper.ConjunctionOfSuccessorBlocks(finalCfgSuccessors, declToVCMapping, vcinst));
                    hasVcAssm = true;
                }
            }

            Term conclusion = new TermBinary(finalState, IsaBoogieTerm.Failure(), TermBinary.BinaryOpCode.Neq);

            var nodeLemma     = isaBlockInfo.BlockCmdsMembershipLemma(block);
            var outEdgesLemma = isaBlockInfo.OutEdgesMembershipLemma(block);
            var proofMethods  = new List <string>();


            var eruleLocalBlock =
                "erule " + (hasVcAssm ? ProofUtil.OF(BlockLemma.Name, "_", "assms(2)") : BlockLemma.Name);

            if (isContainedInFinalCfg && LemmaHelper.FinalStateIsMagic(block))
            {
                proofMethods.Add("apply (rule converse_rtranclpE2[OF assms(1)], fastforce)");
                proofMethods.Add(ProofUtil.Apply("rule " +
                                                 ProofUtil.OF("red_cfg_multi_backwards_step_magic", "assms(1)",
                                                              nodeLemma)));
                proofMethods.Add(ProofUtil.By(eruleLocalBlock));
                return(new LemmaDecl(cfgLemmaName(block), ContextElem.CreateWithAssumptions(assumption), conclusion,
                                     new Proof(proofMethods)));
            }

            if (successors.Any())
            {
                proofMethods.Add("apply (rule converse_rtranclpE2[OF assms(1)], fastforce)");
                var cfg_lemma = finalCfgSuccessors.Any()
                    ? "red_cfg_multi_backwards_step"
                    : "red_cfg_multi_backwards_step_2";

                proofMethods.Add(ProofUtil.Apply("rule " +
                                                 ProofUtil.OF(cfg_lemma, "assms(1)", nodeLemma)));
                proofMethods.Add(ProofUtil.Apply(eruleLocalBlock));
                proofMethods.Add("apply (" + ProofUtil.Simp(outEdgesLemma) + ")");
                foreach (var bSuc in successors)
                {
                    proofMethods.Add("apply (erule member_elim, simp)");
                    proofMethods.Add("apply (erule " + cfgLemmaName(bSuc) + ", simp?" + ")");
                }

                proofMethods.Add("by (simp add: member_rec(2))");
            }
            else
            {
                proofMethods.Add("apply (rule converse_rtranclpE2[OF assms(1)], fastforce)");
                proofMethods.Add("apply (rule " + ProofUtil.OF("red_cfg_multi_backwards_step_no_succ", "assms(1)",
                                                               nodeLemma, outEdgesLemma) + ")");
                if (isContainedInFinalCfg)
                {
                    proofMethods.Add("using " + ProofUtil.OF(BlockLemma.Name, "_", "assms(2)") + " by blast");
                }
                else
                {
                    proofMethods.Add("using " + BlockLemma.Name + " by blast");
                }
            }

            return(new LemmaDecl(cfgLemmaName(block), ContextElem.CreateWithAssumptions(assumption), conclusion,
                                 new Proof(proofMethods)));
        }
        public static Theory ProgramToVcProof(
            string theoryName,
            bool generateEndToEndProof,
            CFGRepr finalCfg,
            CFGRepr afterPassificationCfg,
            IDictionary <Block, Block> afterPassiveToFinalBlock,
            IDictionary <Block, Block> afterPassiveToOrigBlock,
            IProgramAccessor passiveProgAccess,
            IProgramAccessor beforePassiveProgAccess,
            BoogieMethodData methodData,
            ProgramVcProofData vcProofData,
            IVariableTranslationFactory varFactory,
            TypePremiseEraserFactory eraserFactory,
            VCExpressionGenerator gen,
            out Term vcAssm,
            out LemmaDecl endToEndLemma)
        {
            var lemmaNamer          = new IsaUniqueNamer();
            var passiveLemmaManager = new VcPhaseLemmaManager(
                vcProofData.VcBoogieInfo.VcInst,
                methodData,
                vcProofData.VcFunctions,
                passiveProgAccess.BlockInfo(),
                varFactory);

            var afterPassiveReachableBlocks = ReachableBlocks(afterPassificationCfg);

            var finalProgramLemmas =
                GenerateVCLemmas(afterPassificationCfg, finalCfg, afterPassiveToFinalBlock, afterPassiveToOrigBlock,
                                 afterPassiveReachableBlocks, passiveLemmaManager, vcProofData.VcHintManager, lemmaNamer);
            var cfgProgramLemmas =
                GenerateCfgLemmas(afterPassificationCfg, finalCfg, afterPassiveToFinalBlock,
                                  afterPassiveReachableBlocks, finalProgramLemmas, passiveLemmaManager, passiveProgAccess.CfgDecl(),
                                  lemmaNamer);

            var afterPassificationDecls = new List <OuterDecl>();

            foreach (var v in finalProgramLemmas.Values)
            {
                afterPassificationDecls.AddRange(v);
            }
            afterPassificationDecls.AddRange(cfgProgramLemmas.Values);

            var afterPassificationLocale =
                GenerateLocale("passification", passiveLemmaManager, afterPassificationDecls);

            var passiveOuterDecls = new List <OuterDecl> {
                vcProofData.VcLocale
            };

            passiveOuterDecls.Add(afterPassificationLocale);

            //generate axiom
            var axiomUniqueNamer  = new IsaUniqueNamer();
            var axId              = 0;
            var axiomToLemma      = new Dictionary <Axiom, OuterDecl>();
            var vcRewriteLemmaGen =
                new VcRewriteLemmaGen(eraserFactory, VCExprToIsaTranslator.CreateNameBasedTranslator(new IsaUniqueNamer()));

            var vcAxiomLemmaManager = new VcAxiomLemmaManager(
                vcProofData.VcBoogieInfo.VcInstAxiom,
                methodData,
                vcProofData.VcFunctions,
                vcRewriteLemmaGen, varFactory);

            var axiomLocaleRequiredDecls = new List <OuterDecl>();

            foreach (var axiom in vcProofData.VcBoogieInfo.VcAxiomsInfo)
            {
                if (axiom is VcBoogieAxiomInfo vcBoogieAxiom)
                {
                    var axiomVcLemma =
                        vcAxiomLemmaManager.AxiomVcLemma(
                            axiomUniqueNamer.GetName(axiom, "axiom_vc_" + axId),
                            vcBoogieAxiom.Axiom,
                            vcBoogieAxiom.Expr,
                            out var requiredDecls);
                    axiomToLemma.Add(vcBoogieAxiom.Axiom, axiomVcLemma);
                    axiomLocaleRequiredDecls.AddRange(requiredDecls);
                }
            }

            /* we add the required declarations for the axiom locale to the outer theory, since the axiom locale fixes variables that could clash
             * with the declarations */
            passiveOuterDecls.AddRange(axiomLocaleRequiredDecls);
            var axiomLocale = GenerateLocale("axioms", vcAxiomLemmaManager, axiomToLemma.Values.ToList());

            passiveOuterDecls.Add(axiomLocale);

            if (generateEndToEndProof)
            {
                var endToEnd = new EndToEndVCProof(
                    methodData,
                    passiveProgAccess,
                    vcProofData.VcFunctions,
                    vcProofData.VcBoogieInfo,
                    afterPassificationCfg,
                    finalCfg,
                    afterPassificationLocale.Name + "." + cfgProgramLemmas[afterPassificationCfg.entry].Name,
                    axiomLocale.Name,
                    ax => axiomLocale.Name + "." + axiomToLemma[ax].Name,
                    varFactory,
                    vcProofData.VcTranslator,
                    eraserFactory,
                    gen);
                passiveOuterDecls.AddRange(endToEnd.GenerateProof(out vcAssm, out endToEndLemma));
            }
            else
            {
                vcAssm        = null;
                endToEndLemma = null;
            }

            return
                (new Theory(theoryName,
                            new List <string>
            {
                "Boogie_Lang.Semantics", "Boogie_Lang.Util", "Boogie_Lang.VCHints", "Boogie_Lang.VCPhaseML",
                passiveProgAccess.TheoryName(), beforePassiveProgAccess.TheoryName()
            },
                            passiveOuterDecls));
        }