예제 #1
0
 public BasicCmdIsaVisitor(IVariableTranslationFactory variableFactory)
 {
     this.variableFactory = variableFactory;
     boogieVarTranslation = variableFactory.CreateTranslation();
     //by sharing TypeVarTranslation, changes in the bound variables will be visible in the type visitor
     typeIsaVisitor = new TypeIsaVisitor(boogieVarTranslation.TypeVarTranslation);
 }
        public IProgramAccessor GetIsaProgram(
            string theoryName,
            string procName,
            BoogieMethodData methodData,
            IsaProgramGeneratorConfig config,
            IVariableTranslationFactory varTranslationFactory,
            CFGRepr cfg,
            out IList <OuterDecl> decls,
            bool generateMembershipLemmas = true,
            bool onlyGlobalData           = false
            )
        {
            this.varTranslationFactory = varTranslationFactory;
            varTranslation             = varTranslationFactory.CreateTranslation();
            cmdIsaVisitor = new MultiCmdIsaVisitor(varTranslationFactory);

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

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

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

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

            MembershipLemmaManager membershipLemmaManager;

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

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

                decls.AddRange(blockInfo.BlockCmdsDefs.Values);

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

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

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

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

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

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

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

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

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

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

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

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

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

            return(membershipLemmaManager);
        }