Beispiel #1
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);
        }
        public VcAxiomLemmaManager(
            VCInstantiation <VCExpr> vcAxiomInst,
            BoogieMethodData methodData,
            IEnumerable <Function> vcFunctions,
            VcRewriteLemmaGen vcRewriteLemmaGen,
            IVariableTranslationFactory variableFactory)
        {
            this.vcAxiomInst       = vcAxiomInst;
            this.methodData        = methodData;
            this.vcRewriteLemmaGen = vcRewriteLemmaGen;
            this.variableFactory   = variableFactory;
            basicCmdIsaVisitor     = new BasicCmdIsaVisitor(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(methodData.Constants), 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, methodData.Constants, variableFactory);
        }
Beispiel #3
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));
        }
        /// <summary>The returned list in-sync with <see cref="AllAssumptionLabels" />.</summary>
        public IList <Term> AllAssumptions(
            IDictionary <Function, TermIdent> funInterpMapping,
            IDictionary <NamedDeclaration, Term> declToVCMapping,
            Term state,
            BoogieContextIsa boogieContext,
            IVariableTranslation <Variable> varTranslation
            )
        {
            var assumptions = new List <Term>();

            foreach (var obj in _assumptionLabelMap.Keys)
            {
                if (obj is Function f)
                {
                    assumptions.Add(LemmaHelper.FunctionCtxtWfAssm(f, funInterpMapping, boogieContext));
                    assumptions.Add(LemmaHelper.FunctionVcCorresAssm(f, funInterpMapping, declToVCMapping,
                                                                     boogieContext));
                }
                else if (obj is Variable v)
                {
                    assumptions.Add(LemmaHelper.LocalStateVariableAssumption(v, boogieContext.varContext, state,
                                                                             declToVCMapping, varTranslation));
                    if (!TypeUtil.IsPrimitive(v.TypedIdent.Type))
                    {
                        assumptions.Add(LemmaHelper.VariableTypeAssumption(
                                            v,
                                            declToVCMapping[v],
                                            new TypeIsaVisitor(_factory.CreateEmptyTranslation().TypeVarTranslation),
                                            boogieContext.absValTyMap));
                    }
                }
                else if (obj is SpecialAssumptionsKind kind)
                {
                    switch (kind)
                    {
                    case SpecialAssumptionsKind.TypeValClosed:
                        assumptions.Add(EndToEndAssumptions.ClosednessAssumption(boogieContext.absValTyMap));
                        break;

                    default:
                        throw new ArgumentOutOfRangeException();
                    }
                }
            }

            return(assumptions);
        }
Beispiel #5
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));
        }
Beispiel #6
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));
        }
Beispiel #7
0
        public static IList <Tuple <TermIdent, TypeIsa> > GlobalFixedVariables(
            BoogieContextIsa boogieContext,
            IEnumerable <Function> functions,
            IEnumerable <Variable> variables,
            TermIdent normalInitState,
            IDictionary <Function, TermIdent> funToInterpMapping,
            IsaUniqueNamer uniqueNamer)
        {
            var absValType           = new VarType("a");
            var pureTyIsaTransformer = LemmaHelper.ConretePureTyIsaTransformer(absValType);

            var result = new List <Tuple <TermIdent, TypeIsa> >
            {
                Tuple.Create((TermIdent)boogieContext.absValTyMap, IsaBoogieType.AbstractValueTyFunType(absValType)),
                Tuple.Create((TermIdent)boogieContext.varContext, IsaBoogieType.VarContextType()),
                Tuple.Create((TermIdent)boogieContext.funContext, IsaBoogieType.FunInterpType(absValType)),
                Tuple.Create(normalInitState, IsaBoogieType.NormalStateType(absValType))
            };

            foreach (var kv in funToInterpMapping)
            {
                result.Add(Tuple.Create(kv.Value, IsaBoogieType.BoogieFuncInterpType(absValType)));

                var boogieFun = kv.Key;
                //get untyped version, maybe should precompute this somewhere and re-use or get the data from the VC
                TypeUtil.SplitTypeParams(boogieFun.TypeParameters, boogieFun.InParams.Select(v => v.TypedIdent.Type),
                                         out var explicitTypeVars, out _);

                var typeIsa = pureTyIsaTransformer.Translate(new Function(null, boogieFun.Name,
                                                                          explicitTypeVars, boogieFun.InParams, boogieFun.OutParams[0]));
                result.Add(Tuple.Create(
                               IsaCommonTerms.TermIdentFromName(uniqueNamer.GetName(boogieFun, boogieFun.Name)), typeIsa));
            }

            foreach (var v in variables)
            {
                var typeIsa = pureTyIsaTransformer.Translate(v);
                result.Add(Tuple.Create(IsaCommonTerms.TermIdentFromName(uniqueNamer.GetName(v, v.Name)), typeIsa));
            }

            return(result);
        }
        private static HashSet <Block> ReachableBlocks(CFGRepr cfg)
        {
            var reachableBlocks = new HashSet <Block>();
            var queue           = new Queue <Block>();

            reachableBlocks.Add(cfg.entry);
            queue.Enqueue(cfg.entry);

            while (queue.TryDequeue(out var b))
            {
                if (!LemmaHelper.FinalStateIsMagic(b))
                {
                    //b's successors are not trivially unreachable
                    var successors = cfg.GetSuccessorBlocks(b);
                    foreach (var suc in successors)
                    {
                        reachableBlocks.Add(suc);
                        queue.Enqueue(suc);
                    }
                }
            }

            return(reachableBlocks);
        }
Beispiel #9
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)));
        }