public PassificationLemmaManager(
            CFGRepr cfg,
            IDictionary <Block, Block> origToPassiveBlock,
            IProgramAccessor programAccessor,
            IProgramAccessor passiveProgramAccessor,
            Tuple <string, string> varContextNonPassivePassive,
            StateRelationData oldStateRelationData,
            PassiveRelationGen relationGen,
            IVariableTranslationFactory varTranslationFactory,
            IVariableTranslationFactory passiveTranslationFactory)
        {
            this.cfg = cfg;
            this.origToPassiveBlock     = origToPassiveBlock;
            this.programAccessor        = programAccessor;
            this.passiveProgramAccessor = passiveProgramAccessor;
            _oldStateRelationData       = oldStateRelationData;
            _relationGen          = relationGen;
            initState             = IsaBoogieTerm.Normal(normalInitState);
            varTranslation        = varTranslationFactory.CreateTranslation().VarTranslation;
            passiveVarTranslation = passiveTranslationFactory.CreateTranslation().VarTranslation;
            //separate unique namer for function interpretations (since they already have a name in uniqueNamer): possible clashes

            boogieContext = new BoogieContextIsa(
                IsaCommonTerms.TermIdentFromName("A"),
                IsaCommonTerms.TermIdentFromName("M"),
                IsaCommonTerms.TermIdentFromName(varContextNonPassivePassive.Item1),
                IsaCommonTerms.TermIdentFromName("\\<Gamma>"),
                IsaCommonTerms.TermIdentFromName("\\<Omega>")
                );
            passiveVarContext = IsaCommonTerms.TermIdentFromName(varContextNonPassivePassive.Item2);
        }
        public override Type VisitBasicType(BasicType node)
        {
            if (node.IsBool)
            {
                if (constructVal)
                {
                    ReturnResult(IsaBoogieTerm.BoolVal(arg));
                }
                else
                {
                    ReturnResult(IsaBoogieTerm.ConvertValToBool(arg));
                }
            }
            else if (node.IsInt)
            {
                if (constructVal)
                {
                    ReturnResult(IsaBoogieTerm.IntVal(arg));
                }
                else
                {
                    ReturnResult(IsaBoogieTerm.ConvertValToInt(arg));
                }
            }
            else
            {
                throw new NotImplementedException();
            }

            return(node);
        }
示例#3
0
        public VcPhaseLemmaManager(VCInstantiation <Block> vcinst,
                                   BoogieMethodData methodData,
                                   IEnumerable <Function> vcFunctions,
                                   IsaBlockInfo isaBlockInfo,
                                   IVariableTranslationFactory variableFactory)
        {
            this.vcinst          = vcinst;
            this.methodData      = methodData;
            programVariables     = methodData.AllVariables();
            initState            = IsaBoogieTerm.Normal(normalInitState);
            this.isaBlockInfo    = isaBlockInfo;
            this.variableFactory = variableFactory;
            boogieContext        = new BoogieContextIsa(
                IsaCommonTerms.TermIdentFromName("A"),
                IsaCommonTerms.TermIdentFromName("M"),
                IsaCommonTerms.TermIdentFromName("\\<Lambda>"),
                IsaCommonTerms.TermIdentFromName("\\<Gamma>"),
                IsaCommonTerms.TermIdentFromName("\\<Omega>")
                );
            var typeDeclTranslation = new ConcreteTypeDeclTranslation(boogieContext);

            declToVCMapping = LemmaHelper.DeclToTerm(
                ((IEnumerable <NamedDeclaration>)methodData.Functions).Union(programVariables),
                vcFunctions,
                typeDeclTranslation,
                uniqueNamer);
            //separate unique namer for function interpretations (since they already have a name in uniqueNamer): possible clashes
            funToInterpMapping = LemmaHelper.FunToTerm(methodData.Functions, new IsaUniqueNamer());

            assmManager = new AssumptionManager(methodData.Functions, programVariables, variableFactory);
        }
示例#4
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));
        }
示例#5
0
 public static Term BinderStateEmpty(Term normalState)
 {
     return(TermBinary.Eq(
                IsaBoogieTerm.BinderState(normalState),
                IsaCommonTerms.EmptyMap
                ));
 }
示例#6
0
 // TODO: adjust clients so don't require paramsAndLocals
 public static Term LocalStateAssumption(BoogieContextIsa boogieContext, Term paramsAndLocals, Term normalState)
 {
     return
         (IsaBoogieTerm.StateWf(
              boogieContext.absValTyMap,
              boogieContext.rtypeEnv,
              paramsAndLocals,
              IsaBoogieTerm.LocalState(normalState)));
 }
示例#7
0
 // TODO: adjust clients so don't require constsAndGlobals
 public static Term GlobalStateAssumption(BoogieContextIsa boogieContext, Term constsAndGlobals,
                                          Term normalState)
 {
     return
         (IsaBoogieTerm.StateWf(
              boogieContext.absValTyMap,
              boogieContext.rtypeEnv,
              constsAndGlobals,
              IsaBoogieTerm.GlobalState(normalState)));
 }
 public void AddFunctionMembershipLemmas(IEnumerable <Function> functions)
 {
     AddNamedDeclsMembershipLemmas(functions,
                                   IsaCommonTerms.TermIdentFromName(isaProgramRepr.GlobalProgramRepr.funcsDeclDef),
                                   new[] { isaProgramRepr.GlobalProgramRepr.funcsDeclDef + "_def" },
                                   d => new StringConst(d.Name),
                                   d => IsaBoogieTerm.FunDecl((Function)d, factory, false),
                                   false
                                   );
 }
示例#9
0
        public static Term ClosednessAssumption(Term absValTyMap)
        {
            Identifier boundVar = new SimpleIdentifier("v");

            return(TermQuantifier.MetaAll(new List <Identifier> {
                boundVar
            },
                                          null,
                                          IsaBoogieTerm.IsClosedType(IsaBoogieTerm.TypeToVal(absValTyMap, new TermIdent(boundVar)))
                                          ));
        }
示例#10
0
        public static Term VariableTypeAssumption(
            Variable v,
            Term vcVar,
            TypeIsaVisitor typeIsaVisitor,
            Term absValTyMap)
        {
            var left  = IsaBoogieTerm.TypeToVal(absValTyMap, vcVar);
            var right = typeIsaVisitor.Translate(v.TypedIdent.Type);

            return(TermBinary.Eq(left, right));
        }
示例#11
0
 public static Term AxiomAssumption(BoogieContextIsa boogieContext, IProgramAccessor programAccessor,
                                    Term normalState)
 {
     return
         (IsaBoogieTerm.AxiomAssm(
              boogieContext.absValTyMap,
              boogieContext.funContext,
              IsaCommonTerms.TermIdentFromName(programAccessor.ConstsDecl()),
              normalState,
              programAccessor.AxiomsDecl()
              ));
 }
示例#12
0
        //desugar into single havoc commands
        private IList <Term> TranslateHavocCmd(HavocCmd node)
        {
            var varResults = node.Vars.Select(var => TranslateIdentifierExpr(var));

            IList <Term> results = new List <Term>();

            foreach (var v in varResults)
            {
                results.Add(IsaBoogieTerm.Havoc(v));
            }

            return(results);
        }
示例#13
0
        public static Term LocalStateVariableAssumption(Variable v, Term varContext, Term normalState, Term vcVar,
                                                        IVariableTranslation <Variable> varTranslation)
        {
            if (varTranslation.TryTranslateVariableId(v, out var varId, out var isBoundVar) && !isBoundVar)
            {
                var left  = IsaBoogieTerm.LookupVar(varContext, normalState, varId);
                var right =
                    IsaCommonTerms.SomeOption(pureToBoogieValConverter.ConvertToBoogieVal(v.TypedIdent.Type, vcVar));
                return(new TermBinary(left, right, TermBinary.BinaryOpCode.Eq));
            }

            throw new ProofGenUnexpectedStateException(typeof(LemmaHelper), "Can't retrieve variable id");
        }
        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 override Type VisitBasicType(BasicType node)
        {
            if (node.IsBool)
            {
                ReturnResult(v => IsaBoogieTerm.BoolVal(v));
            }
            else if (node.IsInt)
            {
                ReturnResult(v => IsaBoogieTerm.IntVal(v));
            }
            else
            {
                throw new NotImplementedException();
            }

            return(node);
        }
示例#16
0
        private static Term ConclusionBlock(
            IEnumerable <Block> b_successors,
            Term normalInitState,
            Term finalState,
            IDictionary <NamedDeclaration, Term> declToVCMapping,
            VCInstantiation <Block> vcinst,
            bool useMagicFinalState = false)
        {
            if (useMagicFinalState)
            {
                return(new TermBinary(finalState, IsaBoogieTerm.Magic(), TermBinary.BinaryOpCode.Eq));
            }

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

            var normalFinalState = IsaCommonTerms.TermIdentFromName("n_s'");

            Term ifNormalConclusionLhs = new TermBinary(finalState, IsaBoogieTerm.Normal(normalFinalState),
                                                        TermBinary.BinaryOpCode.Eq);

            Term ifNormalConclusionRhs1 = new TermBinary(normalFinalState, normalInitState, TermBinary.BinaryOpCode.Eq);

            var ifNormalConclusionRhs =
                !b_successors.Any()
                    ? ifNormalConclusionRhs1
                    : new TermBinary(
                    ifNormalConclusionRhs1,
                    LemmaHelper.ConjunctionOfSuccessorBlocks(b_successors, declToVCMapping, vcinst),
                    TermBinary.BinaryOpCode.And);

            Term ifNormalConclusion =
                new TermQuantifier(
                    TermQuantifier.QuantifierKind.ALL,
                    new List <Identifier> {
                normalFinalState.Id
            },
                    new TermBinary(
                        ifNormalConclusionLhs,
                        ifNormalConclusionRhs,
                        TermBinary.BinaryOpCode.Implies)
                    );

            return(new TermBinary(nonFailureConclusion, ifNormalConclusion, TermBinary.BinaryOpCode.And));
        }
示例#17
0
        public static Term NonEmptyTypesAssumption(Term absValTyMap)
        {
            Identifier bvType      = new SimpleIdentifier("t");
            Term       bvTypeTerm  = new TermIdent(bvType);
            Identifier bvValue     = new SimpleIdentifier("v");
            Term       bvValueTerm = new TermIdent(bvValue);

            return(TermQuantifier.MetaAll(new List <Identifier> {
                bvType
            },
                                          null,
                                          TermBinary.MetaImplies(IsaBoogieTerm.IsClosedType(bvTypeTerm),
                                                                 TermQuantifier.Exists(new List <Identifier> {
                bvValue
            },
                                                                                       null,
                                                                                       TermBinary.Eq(IsaBoogieTerm.TypeToVal(absValTyMap, bvValueTerm), bvTypeTerm)
                                                                                       ))));
        }
示例#18
0
        public LemmaDecl GenerateBlockLemma(Block block, Block finalCfgBlock, IEnumerable <Block> finalCfgSuccessors,
                                            string lemmaName, string vcHintsName)
        {
            var cmdsReduce = IsaBoogieTerm.RedCmdList(boogieContext,
                                                      IsaCommonTerms.TermIdentFromName(isaBlockInfo.CmdsQualifiedName(block)),
                                                      initState, finalState);

            var vcAssm = vcinst.GetVCObjInstantiation(finalCfgBlock, declToVCMapping);

            //do not use separate assumption, leads to issues
            var conclusion = ConclusionBlock(finalCfgSuccessors, normalInitState, finalState, declToVCMapping, vcinst,
                                             LemmaHelper.FinalStateIsMagic(block));

            Term statement = TermBinary.MetaImplies(cmdsReduce, TermBinary.MetaImplies(vcAssm, conclusion));

            var proof = BlockCorrectProof(block, finalCfgBlock, vcHintsName);

            return(new LemmaDecl(lemmaName, ContextElem.CreateEmptyContext(), statement, proof));
        }
        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)
                    )
            })
                               ));
        }
示例#20
0
        public static Term FunctionVcCorresAssm(
            Function f,
            IDictionary <Function, TermIdent> funInterpMapping,
            IDictionary <NamedDeclaration, Term> declToVCMapping,
            BoogieContextIsa boogieContext
            )
        {
            var converter = new PureToBoogieValConverter();

            //TODO: unique naming scheme
            var boundParamVars = GetNames("farg", f.InParams.Count);

            TypeUtil.SplitTypeParams(f.TypeParameters, f.InParams.Select(v => v.TypedIdent.Type),
                                     out var explicitTypeVars, out var implicitTypeVars);


            var boundTypeVars = GetNames("targ", f.TypeParameters.Count);

            IDictionary <TypeVariable, Term> substitution = new Dictionary <TypeVariable, Term>();
            var i = 0;

            foreach (var tv in f.TypeParameters)
            {
                substitution.Add(tv, new TermIdent(boundTypeVars[i]));
                i++;
            }

            var varSubstitution = new SimpleVarSubstitution <TypeVariable>(substitution);
            var typeIsaVisitor  = new TypeIsaVisitor(varSubstitution);

            IEnumerable <Term> valueArgConstraints =
                f.InParams
                .Select((v, idx) =>
                        !TypeUtil.IsPrimitive(v.TypedIdent.Type)
                            ? TermBinary.Eq(
                            IsaBoogieTerm.TypeToVal(boogieContext.absValTyMap, new TermIdent(boundParamVars[idx])),
                            typeIsaVisitor.Translate(v.TypedIdent.Type))
                            : null)
                .Where(t => t != null);

            var boogieFunTyArgs = boundTypeVars.Select(id => (Term) new TermIdent(id)).ToList();
            var vcFunTyArgs     = new List <Term>();

            f.TypeParameters.ZipDo(boogieFunTyArgs, (tv, tvTerm) =>
            {
                if (explicitTypeVars.Contains(tv))
                {
                    vcFunTyArgs.Add(IsaBoogieVC.TyToClosed(tvTerm));
                }
            });

            var boogieFunValArgs =
                f.InParams.Select(
                    (v, idx) => converter.ConvertToBoogieVal(v.TypedIdent.Type, new TermIdent(boundParamVars[idx]))
                    ).ToList();

            Term left = new TermApp(funInterpMapping[f], new List <Term>
            {
                new TermList(boogieFunTyArgs),
                new TermList(boogieFunValArgs)
            });

            Term vcFunApp =
                new TermApp(declToVCMapping[f],
                            vcFunTyArgs.Union(
                                boundParamVars.Select(bv => (Term) new TermIdent(bv)).ToList()
                                ).ToList());

            var outputType = f.OutParams.First().TypedIdent.Type;

            var right = IsaCommonTerms.SomeOption(
                converter.ConvertToBoogieVal(outputType,
                                             vcFunApp)
                );

            Term equation = TermBinary.Eq(left, right);

            Term conclusion;

            if (!TypeUtil.IsPrimitive(outputType))
            {
                //if type is not primitive, then the type information is not yet included

                conclusion = TermBinary.And(equation,
                                            TermBinary.Eq(
                                                IsaBoogieTerm.TypeToVal(boogieContext.absValTyMap, vcFunApp),
                                                typeIsaVisitor.Translate(outputType)
                                                ));
            }
            else
            {
                conclusion = equation;
            }

            if (valueArgConstraints.Any())
            {
                conclusion = TermBinary.MetaImplies(valueArgConstraints.Aggregate((t1, t2) => TermBinary.And(t2, t1)), conclusion);
            }

            if (boogieFunTyArgs.Any())
            {
                var closednessAssms = boogieFunTyArgs.Select(t1 => IsaBoogieTerm.IsClosedType(t1))
                                      .Aggregate((t1, t2) => TermBinary.And(t2, t1));
                conclusion = TermBinary.MetaImplies(closednessAssms, conclusion);
            }

            if (boundParamVars.Any())
            {
                return(new TermQuantifier(TermQuantifier.QuantifierKind.META_ALL,
                                          boundParamVars.Union(boundTypeVars).ToList(), conclusion));
            }

            return(conclusion);
        }
        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);
        }
示例#22
0
 public override Term Bool2U(Function func)
 {
     return(IsaBoogieTerm.BoolValConstr());
 }
示例#23
0
 public static Term OldGlobalStateAssumption(Term normalState)
 {
     return(TermBinary.Eq(IsaBoogieTerm.GlobalState(normalState), IsaBoogieTerm.OldGlobalState(normalState)));
 }
        /**
         * cases:
         * 1) is loop head block
         * 2) is back edge block
         * 3) successor is loop head block
         *
         * any combination is possible
         */
        public static Theory CfgToDagProof(
            PhasesTheories phasesTheories,
            bool generateEndToEndLemma,
            Term vcAssm,
            CFGRepr beforeDagCfg,
            CFGRepr afterDagCfg,
            Block afterUniqueExit,
            BoogieMethodData beforeDagData,
            CfgToDagHintManager hintManager,
            IDictionary <Block, Block> beforeToAfter,
            IProgramAccessor beforeDagProgAccess,
            IProgramAccessor afterDagProgAccess,
            IVariableTranslationFactory varFactory)
        {
            var afterToBefore = beforeToAfter.InverseDict();

            //track mapping from blocks to loops that the block is contained in and for which it is not the loop head
            IDictionary <Block, IList <Block> > blocksToLoops = new Dictionary <Block, IList <Block> >();

            foreach (var afterBlock in afterDagCfg.GetBlocksBackwards())
            {
                if (afterToBefore.TryGetValue(afterBlock, out var beforeBlock))
                {
                    var loops = new HashSet <Block>();
                    foreach (var bSuc in beforeDagCfg.GetSuccessorBlocks(beforeBlock))
                    {
                        if (blocksToLoops.TryGetValue(bSuc, out var loopsSuc))
                        {
                            //if successor inside of a loop L and the block is not the loop head of L, then the block is also inside L
                            foreach (var loopSuc in loopsSuc)
                            {
                                if (!loopSuc.Equals(beforeBlock))
                                {
                                    loops.Add(loopSuc);
                                }
                            }
                        }
                    }

                    /* a node is inside all loops for which it has an out-going backedge
                     * if a node has a backedge to itself (i.e., it is also a loop head), then we do not add this loop
                     */
                    if (hintManager.TryIsBackedgeNode(beforeBlock, out var backedgeLoops))
                    {
                        foreach (var backedgeLoop in backedgeLoops)
                        {
                            if (beforeBlock != backedgeLoop)
                            {
                                loops.Add(backedgeLoop);
                            }
                        }
                    }

                    var loopsList = loops.ToList();
                    blocksToLoops.Add(beforeBlock, loopsList);
                }
            }

            var varContextName   = "\\<Lambda>1";
            var varContextAbbrev = new AbbreviationDecl(
                varContextName,
                new Tuple <IList <Term>, Term>(new List <Term>(), beforeDagProgAccess.VarContext())
                );

            var funContextWfName = "Wf_Fun";
            var boogieContext    = new BoogieContextIsa(
                IsaCommonTerms.TermIdentFromName("A"),
                IsaCommonTerms.TermIdentFromName("M"),
                IsaCommonTerms.TermIdentFromName(varContextName),
                IsaCommonTerms.TermIdentFromName("\\<Gamma>"),
                IsaCommonTerms.EmptyList);
            var lemmaManager = new CfgToDagLemmaManager(
                beforeDagProgAccess,
                afterDagProgAccess,
                boogieContext,
                afterDagCfg,
                funContextWfName,
                hintManager,
                blocksToLoops,
                beforeToAfter,
                beforeDagData,
                afterUniqueExit,
                varFactory);

            var lemmaNamer = new IsaUniqueNamer();
            var outerDecls = new List <OuterDecl>();

            outerDecls.Add(varContextAbbrev);
            outerDecls.Add(new DeclareDecl("Nat.One_nat_def[simp del]"));
            if (afterUniqueExit != null)
            {
                outerDecls.AddRange(lemmaManager.UnifiedExitLemma(GetCfgLemmaName(afterUniqueExit, lemmaNamer)));
            }

            foreach (var afterBlock in afterDagCfg.GetBlocksBackwards())
            {
                if (afterToBefore.TryGetValue(afterBlock, out var beforeBlock))
                {
                    //if the node's only edge is a backedge, then an "assume false" will be added
                    var singleCutEdge = hintManager.TryIsBackedgeNode(beforeBlock, out var _) &&
                                        beforeDagCfg.NumOfSuccessors(beforeBlock) == 1;

                    var(localLemmas, cfgLemma) =
                        lemmaManager.BlockLemma(
                            beforeBlock,
                            afterBlock,
                            beforeDagCfg.GetSuccessorBlocks(beforeBlock),
                            block => GetLemmaName(block, lemmaNamer),
                            block => GetCfgLemmaName(block, lemmaNamer),
                            singleCutEdge
                            );

                    outerDecls.AddRange(localLemmas);
                    outerDecls.Add(cfgLemma);
                }
                else
                {
                    //block was added as part of transformation
                    if (afterBlock == afterDagCfg.entry)
                    {
                        //entry lemma handled elsewhere
                        continue;
                    }

                    var afterBlockSuccessors     = afterDagCfg.GetSuccessorBlocks(afterBlock);
                    var afterBlockSuccessorsList = afterBlockSuccessors.ToList();
                    if (!afterBlockSuccessorsList.Any())
                    {
                        //this must be the unique node
                        if (afterUniqueExit == null)
                        {
                            throw new ProofGenUnexpectedStateException(
                                      "unique exit block added, but only exit block existed before cfg-to-dag");
                        }

                        continue;
                    }

                    if (afterBlockSuccessorsList.Count != 1)
                    {
                        throw new ProofGenUnexpectedStateException(
                                  "Block added in CFG-to-DAG phase does not have a unique successor");
                    }

                    var afterUniqueSuc = afterBlockSuccessorsList.First();
                    if (afterToBefore.TryGetValue(afterUniqueSuc, out var beforeUniqueSuc))
                    {
                        hintManager.IsLoopHead(beforeUniqueSuc, out var hint);
                        var lemma = lemmaManager.NewBlockLemma(
                            GetCfgLemmaName(afterBlock, lemmaNamer),
                            afterBlock,
                            afterUniqueSuc,
                            hint
                            );
                        outerDecls.Add(lemma);
                    }
                    else if (hintManager.IsNewBackedgeBlock(afterBlock, out var loopHeadHint))
                    {
                        if (afterDagCfg.GetSuccessorBlocks(afterUniqueSuc).Any())
                        {
                            throw new ProofGenUnexpectedStateException(
                                      "New backedge node has successor that is not the exit node.");
                        }

                        //afterUniqueSuc is a successor to a backedge node for which all edges were eliminated
                        var lemma = lemmaManager.NewBlockLemma(
                            GetCfgLemmaName(afterBlock, lemmaNamer),
                            afterBlock,
                            null,
                            loopHeadHint
                            );
                        outerDecls.Add(lemma);
                    }
                    else
                    {
                        throw new ProofGenUnexpectedStateException(
                                  "CFG-to-DAG: Unique successor of added block cannot be mapped to original block");
                    }
                }
            }

            var entryLemma = lemmaManager.EntryLemma("entry_lemma", beforeDagCfg.entry, afterDagCfg.entry,
                                                     b => GetCfgLemmaName(b, lemmaNamer));

            outerDecls.Add(entryLemma);

            var absValType           = new VarType("a");
            var cfgToDagLemmasLocale = new LocaleDecl(
                "cfg_to_dag_lemmas",
                new ContextElem(
                    new List <Tuple <TermIdent, TypeIsa> >
            {
                Tuple.Create((TermIdent)boogieContext.absValTyMap,
                             IsaBoogieType.AbstractValueTyFunType(absValType)),
                Tuple.Create((TermIdent)boogieContext.funContext, IsaBoogieType.FunInterpType(absValType))
            },
                    new List <Term>
            {
                IsaBoogieTerm.FunInterpWf(boogieContext.absValTyMap, beforeDagProgAccess.FunctionsDecl(),
                                          boogieContext.funContext)
            },
                    new List <string> {
                funContextWfName
            }
                    ),
                outerDecls
                );

            var theoryOuterDecls = new List <OuterDecl>();

            theoryOuterDecls.Add(cfgToDagLemmasLocale);

            if (generateEndToEndLemma)
            {
                var endToEndManager = new CfgToDagEndToEnd();
                var endToEndDecls   = endToEndManager.EndToEndProof(
                    cfgToDagLemmasLocale.Name + "." + entryLemma.Name,
                    phasesTheories.EndToEndLemmaName(PhasesTheories.Phase.Passification, true),
                    vcAssm,
                    beforeDagProgAccess,
                    beforeDagCfg
                    );
                theoryOuterDecls.AddRange(endToEndDecls);
            }

            return(new Theory(
                       phasesTheories.TheoryName(PhasesTheories.Phase.CfgToDag),
                       new List <string>
            {
                "Boogie_Lang.Semantics", "Boogie_Lang.Util", "Boogie_Lang.BackedgeElim", "Boogie_Lang.TypingML",
                beforeDagProgAccess.TheoryName(),
                afterDagProgAccess.TheoryName(), phasesTheories.TheoryName(PhasesTheories.Phase.Passification),
                phasesTheories.TheoryName(PhasesTheories.Phase.Vc)
            },
                       theoryOuterDecls
                       ));
        }
示例#25
0
 public override Term Int2U(Function func)
 {
     return(IsaBoogieTerm.IntValConstr());
 }
示例#26
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)));
        }