Example #1
0
        public LemmaDecl GenerateEmptyBlockLemma(Block block, IEnumerable <Block> finalCfgSuccessors, string lemmaName)
        {
            //Term cmds = new TermList(cmdIsaVisitor.Translate(block.Cmds));
            var  blockDefName = isaBlockInfo.CmdsQualifiedName(block);
            Term blockDefTerm = IsaCommonTerms.TermIdentFromName(blockDefName);
            var  cmdsReduce   = IsaBoogieTerm.RedCmdList(boogieContext, blockDefTerm, initState, finalState);
            var  assumptions  = new List <Term> {
                cmdsReduce
            };

            if (finalCfgSuccessors.Any())
            {
                assumptions.Add(LemmaHelper.ConjunctionOfSuccessorBlocks(finalCfgSuccessors, declToVCMapping, vcinst));
            }

            var conclusion = ConclusionBlock(finalCfgSuccessors, normalInitState, finalState, declToVCMapping, vcinst);

            var proof = new Proof(
                new List <string>
            {
                "using assms",
                "unfolding " + blockDefName + "_def",
                "apply cases",
                "by auto"
            }
                );

            return(new LemmaDecl(lemmaName, ContextElem.CreateWithAssumptions(assumptions), conclusion, proof));
        }
        private ContextElem LemmaContext(
            CFGRepr cfg,
            Term vcAssm
            )
        {
            var multiRed = IsaBoogieTerm.RedCFGMulti(
                BoogieContextIsa.CreateWithNewVarContext(
                    boogieContext,
                    new TermTuple(programAccessor.ConstsAndGlobalsDecl(), programAccessor.ParamsAndLocalsDecl())
                    ),
                programAccessor.CfgDecl(),
                IsaBoogieTerm.CFGConfigNode(new NatConst(cfg.GetUniqueIntLabel(cfg.entry)),
                                            IsaBoogieTerm.Normal(normalInitState)),
                IsaBoogieTerm.CFGConfig(finalNodeOrReturn, finalState)
                );
            var closedAssm        = EndToEndAssumptions.ClosednessAssumption(boogieContext.absValTyMap);
            var nonEmptyTypesAssm = EndToEndAssumptions.NonEmptyTypesAssumption(boogieContext.absValTyMap);
            var finterpAssm       = IsaBoogieTerm.FunInterpWf(boogieContext.absValTyMap, programAccessor.FunctionsDecl(),
                                                              boogieContext.funContext);
            var absValType = new VarType("a");
            //need to explicitly give type for normal state, otherwise Isabelle won't know that the abstract value type is the same as used in the VC
            var axiomAssm = EndToEndAssumptions.AxiomAssumption(boogieContext, programAccessor,
                                                                new TermWithExplicitType(normalInitState, IsaBoogieType.NormalStateType(absValType)));
            var presAssm =
                IsaBoogieTerm.ExprAllSat(boogieContext, normalInitState, programAccessor.PreconditionsDecl());
            var localsAssm = EndToEndAssumptions.LocalStateAssumption(boogieContext,
                                                                      IsaCommonTerms.Snd(boogieContext.varContext), normalInitState);
            var globalsAssm = EndToEndAssumptions.GlobalStateAssumption(boogieContext,
                                                                        IsaCommonTerms.Fst(boogieContext.varContext), normalInitState);
            var oldGlobalStateAssm = EndToEndAssumptions.OldGlobalStateAssumption(normalInitState);
            var binderEmptyAssm    = EndToEndAssumptions.BinderStateEmpty(normalInitState);

            return
                (ContextElem.CreateWithAssumptions(
                     new List <Term>
            {
                multiRed, vcAssm, closedAssm, nonEmptyTypesAssm, finterpAssm, axiomAssm,
                presAssm, localsAssm, globalsAssm, oldGlobalStateAssm, binderEmptyAssm
            },
                     new List <string>
            {
                redAssmName, vcAssmName, closedAssmName, nonEmptyTypesAssmName, finterpAssmName, axiomAssmName,
                preconditionsAssmName, paramsLocalsAssmName, constsGlobalsAssmName, oldGlobalAssmName,
                binderEmptyAssmName
            }
                     ));
        }
        public LemmaDecl AxiomVcLemma(string lemmaName, Axiom axiom, VCExpr vcAxiom, out IList <OuterDecl> requiredDecls)
        {
            var vc        = vcAxiomInst.GetVCObjInstantiation(vcAxiom, declToVCMapping);
            var axiomTerm = basicCmdIsaVisitor.Translate(axiom.Expr);

            requiredDecls = new List <OuterDecl>();

            vcRewriteLemmaGen.RequiredVcRewrite(axiom.Expr, true, out var vcRewriteLemmas);

            VCExprHint exprHint;

            if (vcRewriteLemmas != null && vcRewriteLemmas.Any())
            {
                exprHint = new VCExprHint(vcRewriteLemmas);
                requiredDecls.AddRange(vcRewriteLemmas);
            }
            else
            {
                exprHint = VCExprHint.EmptyExprHint();
            }

            var assumption =
                IsaBoogieTerm.RedExpr(boogieContext, axiomTerm, normalInitState, IsaBoogieTerm.BoolVal(true));
            var statement = vc;

            return
                (new LemmaDecl(lemmaName,
                               ContextElem.CreateWithAssumptions(assumption),
                               statement,
                               new Proof(new List <string>
            {
                "unfolding " + vcAxiomInst.GetVCObjNameRef(vcAxiom) + "_def",
                ProofUtil.By(
                    ProofUtil.MLTactic(
                        "prove_axiom_vc_tac @{context} (" + exprHint.GetMLString() + ") " +
                        MLUtil.IsaToMLThm("assms(1)") + " " + MLUtil.IsaToMLThms(globalAssmsName) +
                        " (@{thm forall_poly_thm}, @{thm exists_poly_thm}) []", 1)
                    )
            })
                               ));
        }
        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);
        }
Example #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)));
        }