Esempio n. 1
0
        public VCVarFunTranslator(IEnumerable <Variable> vars,
                                  IDictionary <Function, Function> origToErasedFun,
                                  Boogie2VCExprTranslator translator,
                                  TypeAxiomBuilderPremisses axiomBuilder)
        {
            this.origToErasedFun = origToErasedFun;
            erasedToOrigFun      = origToErasedFun.InverseDict();

            boogieToVc = new Dictionary <Variable, VCExprVar>();
            vcToBoogie = new Dictionary <VCExprVar, Variable>();
            foreach (var v in vars)
            {
                var result = translator.TryLookupVariable(v);
                if (result != null)
                {
                    if (axiomBuilder != null)
                    {
                        result = axiomBuilder.TryTyped2Untyped(result);
                        if (result == null)
                        {
                            continue;
                        }
                    }

                    vcToBoogie.Add(result, v);
                    boogieToVc.Add(v, result);
                }
            }
        }
        public TypePremiseEraserProvider(
            VCExpressionGenerator vcExprGen,
            Boogie2VCExprTranslator vcTranslator,
            bool programIsPolymorphic,
            bool extractTypeArgs = true)
        {
            _vcExprGen           = vcExprGen;
            ProgramIsPolymorphic = programIsPolymorphic;
            if (programIsPolymorphic)
            {
                AxiomBuilder = new TypeAxiomBuilderPremisses(vcExprGen);
                AxiomBuilder.Setup();
            }
            else
            {
                AxiomBuilder = null;
            }

            Eraser        = new TypeEraserPremisses(AxiomBuilder, vcExprGen, extractTypeArgs);
            _vcTranslator = vcTranslator;
        }
Esempio n. 3
0
        public TPTPProcessTheoremProver(ProverOptions options, VCExpressionGenerator gen,
                                        DeclFreeProverContext ctx)
            : base(options, "", "", "", "", gen)
        {
            Contract.Requires(options != null);
            Contract.Requires(gen != null);
            Contract.Requires(ctx != null);

            // No bg predicate at the moment
            // InitializeGlobalInformation("UnivBackPred.tptp");

            this.ctx = ctx;
            this.Gen = gen;

            TypeAxiomBuilder axBuilder;

            switch (CommandLineOptions.Clo.TypeEncodingMethod)
            {
            case CommandLineOptions.TypeEncoding.Arguments:
                axBuilder = new TypeAxiomBuilderArguments(gen);
                axBuilder.Setup();
                break;

            case CommandLineOptions.TypeEncoding.Monomorphic:
                axBuilder = new TypeAxiomBuilderPremisses(gen);
                break;

            default:
                axBuilder = new TypeAxiomBuilderPremisses(gen);
                axBuilder.Setup();
                break;
            }
            AxBuilder = axBuilder;
            UniqueNamer namer = new UniqueNamer();

            Namer              = namer;
            Namer.Spacer       = "__";
            this.DeclCollector = new TypeDeclCollector(namer);
        }
Esempio n. 4
0
        /// <summary>
        /// Generate all proofs for the current procedure.
        /// </summary>
        /// <param name="vc">WP of the procedure body</param>
        /// <param name="vcAxioms">VC assumptions for the Boogie axioms</param>
        /// <param name="typeAxioms">VC assumptions for the Boogie type encoding</param>
        /// <param name="typeAxiomInfo">Hints about the type encoding</param>
        /// <param name="gen"></param>
        /// <param name="translator"></param>
        /// <param name="axiomBuilder"></param>
        /// <exception cref="ArgumentException">
        /// axiom builder must be null iff types are not erased (since no polymorphism in vc), otherwise exception is
        /// thrown
        /// </exception>
        public static void VCGenerateAllProofs(
            VCExpr vc,
            VCExpr vcAxioms,
            VCExpr typeAxioms,
            List <VCAxiomInfo> typeAxiomInfo,
            VCExpressionGenerator gen,
            Boogie2VCExprTranslator translator,
            TypeAxiomBuilderPremisses axiomBuilder)
        {
            var uniqueNamer = new IsaUniqueNamer();
            var theories    = new List <Theory>();

            if (axiomBuilder == null && typeAxioms != null)
            {
                throw new ArgumentException("type axioms can only be null if axiom builder is null");
            }

            /* Since in the proofs calls are desugared, there can be more variables in "beforePassiveData". If only
             * the progam should be generaed, then these variables should be ignored. */
            var mainData = CommandLineOptions.Clo.GenerateIsaProgNoProofs ? beforeDagData : beforePassiveData;

            var fixedVarTranslation2   = new DeBruijnFixedVarTranslation(mainData);
            var fixedTyVarTranslation2 = new DeBruijnFixedTVarTranslation(mainData);
            var varTranslationFactory2 =
                new DeBruijnVarFactory(fixedVarTranslation2, fixedTyVarTranslation2, boogieGlobalData);

            #region before cfg to dag program
            var beforeCfgToDagTheoryName = uniqueNamer.GetName(afterPassificationImpl.Name + "_before_cfg_to_dag_prog");
            //Hack: specs config used to distinguish between all (free + checks) (--> expression tuples) or just checked (no tuples)
            var specsConfig              = CommandLineOptions.Clo.GenerateIsaProgNoProofs ? SpecsConfig.All : SpecsConfig.AllPreCheckedPost;
            var beforeCfgToDagConfig     = new IsaProgramGeneratorConfig(globalDataProgAccess, false, false, false, true, specsConfig, true);
            var beforeCfgToDagProgAccess = new IsaProgramGenerator().GetIsaProgram(
                beforeCfgToDagTheoryName,
                afterPassificationImpl.Name,
                mainData, beforeCfgToDagConfig, varTranslationFactory2,
                beforeDagCfg,
                out var programDeclsBeforeCfgToDag,
                !CommandLineOptions.Clo.GenerateIsaProgNoProofs);
            procNameToTopLevelPrograms.Add(afterPassificationImpl.Proc.Name, beforeCfgToDagProgAccess);

            var beforeCfgToDagProgTheory = new Theory(beforeCfgToDagTheoryName,
                                                      new List <string> {
                "Boogie_Lang.Semantics", "Boogie_Lang.TypeSafety", "Boogie_Lang.Util", "\"../" + globalDataProgAccess.TheoryName() + "\""
            },
                                                      programDeclsBeforeCfgToDag);
            theories.Add(beforeCfgToDagProgTheory);
            #endregion

            if (CommandLineOptions.Clo.GenerateIsaProgNoProofs)
            {
                StoreResult("program_" + afterPassificationImpl.Proc.Name, theories);
                return;
            }

            #region before passive program

            var beforePassiveProgTheoryName = uniqueNamer.GetName(afterPassificationImpl.Name + "_before_passive_prog");
            var beforePassiveConfig         =
                new IsaProgramGeneratorConfig(beforeCfgToDagProgAccess, false, false, false, false, SpecsConfig.None, false);
            var beforePassiveProgAccess = new IsaProgramGenerator().GetIsaProgram(beforePassiveProgTheoryName,
                                                                                  afterPassificationImpl.Name,
                                                                                  mainData, beforePassiveConfig, varTranslationFactory2,
                                                                                  beforePassificationCfg,
                                                                                  out var programDeclsBeforePassive,
                                                                                  !CommandLineOptions.Clo.GenerateIsaProgNoProofs);

            #endregion

            var vcAllAxioms = AxiomHandler.AxiomInfo(
                axiomBuilder != null,
                boogieGlobalData.Axioms,
                vcAxioms,
                typeAxioms,
                typeAxiomInfo,
                out var allAxiomsInfo);

            var vcLocale = VCToIsaInterface.ConvertVC(
                "vc",
                vc,
                vcAllAxioms,
                new StandardActiveDecl(),
                translator,
                axiomBuilder,
                finalProgData,
                afterUnreachablePruningCfg,
                out var vcinst,
                out var vcinstAxiom,
                out var vcTranslator,
                out var vcFunctions);

            //use global version map for translation
            var fixedVarTranslation   = new SimpleFixedVarTranslation(globalVersionMap);
            var fixedTyVarTranslation = new DeBruijnFixedTVarTranslation(finalProgData);
            varTranslationFactory =
                new DeBruijnVarFactory(fixedVarTranslation, fixedTyVarTranslation, boogieGlobalData);

            var finalProgTheoryName = uniqueNamer.GetName(afterPassificationImpl.Name + "_passive_prog");
            var passiveProgConfig   =
                new IsaProgramGeneratorConfig(beforePassiveProgAccess, false, false, false, true, SpecsConfig.None, false);
            var passiveProgAccess = new IsaProgramGenerator().GetIsaProgram(finalProgTheoryName,
                                                                            afterPassificationImpl.Name,
                                                                            finalProgData, passiveProgConfig, varTranslationFactory,
                                                                            //we use the CFG before the peep-hole transformations, so that we can directly use the VC to program proof in the passification phase
                                                                            afterPassificationCfg,
                                                                            out var programDecls,
                                                                            !CommandLineOptions.Clo.GenerateIsaProgNoProofs);

            var finalProgTheory =
                new Theory(finalProgTheoryName,
                           new List <string>
            {
                "Boogie_Lang.Semantics", "Boogie_Lang.Util", beforePassiveProgAccess.TheoryName()
            },
                           programDecls);
            theories.Add(finalProgTheory);

            var vcBoogieInfo = new VcBoogieInfo(vcinst, vcinstAxiom, vcAllAxioms, allAxiomsInfo);

            var vcProofData = new ProgramVcProofData(
                vcFunctions,
                vcBoogieInfo,
                vcHintManager,
                vcLocale,
                vcTranslator
                );

            var phasesTheories = new PhasesTheories(afterPassificationImpl.Name);

            var theoryPassive = VcPhaseManager.ProgramToVcProof(
                phasesTheories.TheoryName(PhasesTheories.Phase.Vc),
                _proofGenConfig.GenerateVcE2E,
                afterUnreachablePruningCfg,
                afterPassificationCfg,
                afterPassificationToAfterUnreachableBlock,
                afterPassificationToOrigBlock,
                passiveProgAccess,
                beforePassiveProgAccess,
                finalProgData,
                vcProofData,
                varTranslationFactory,
                typePremiseEraserFactory,
                gen,
                out var vcAssm,
                out var endToEndLemma
                );
            theories.Add(theoryPassive);

            #region before passive

            var passificationProgTheory = new Theory(beforePassiveProgTheoryName,
                                                     new List <string> {
                "Boogie_Lang.Semantics", "Boogie_Lang.Util", beforeCfgToDagTheoryName
            },
                                                     programDeclsBeforePassive);
            theories.Add(passificationProgTheory);

            /*
             * Console.WriteLine("Passive prog mapping: " + fixedVarTranslation.OutputMapping());
             * Console.WriteLine("Before passive prog mapping: " + fixedVarTranslation2.OutputMapping());
             */

            var passificationProofTheory = PassificationManager.PassificationProof(
                phasesTheories.TheoryName(PhasesTheories.Phase.Passification),
                theoryPassive.TheoryName,
                _proofGenConfig.GeneratePassifE2E,
                endToEndLemma,
                vcAssm,
                beforePassificationCfg,
                beforePassiveToAfterPassiveBlock,
                passiveRelationGen,
                beforePassiveProgAccess,
                passiveProgAccess,
                mainData,
                varTranslationFactory2,
                varTranslationFactory
                );
            theories.Add(passificationProofTheory);

            #endregion

            #region cfg to dag

            var uniqueExitBlock =
                uniqueExitBlockOrig != null
                    ? beforePassiveOrigBlock.First(kv => kv.Value == uniqueExitBlockOrig).Key
                    : null;


            var cfgToDagProofTheory = CfgToDagManager.CfgToDagProof(
                phasesTheories,
                _proofGenConfig.GenerateCfgDagE2E,
                vcAssm,
                beforeDagCfg,
                beforePassificationCfg,
                uniqueExitBlock,
                beforeDagData,
                cfgToDagHintManager,
                beforeDagAfterDagBlock,
                beforeCfgToDagProgAccess,
                beforePassiveProgAccess,
                varTranslationFactory2);
            theories.Add(cfgToDagProofTheory);
            #endregion

            StoreResult(afterPassificationImpl.Proc.Name, theories);
        }
        public static LocaleDecl ConvertVC(
            string localeName,
            VCExpr vc,
            IEnumerable <VCExpr> vcAxioms,
            IActiveDeclGenerator activeDeclGenerator,
            Boogie2VCExprTranslator translator,
            TypeAxiomBuilderPremisses axiomBuilder,
            BoogieMethodData methodData,
            CFGRepr cfg,
            out VCInstantiation <Block> vcinst,
            out VCInstantiation <VCExpr> vcinstAxiom,
            out IVCVarFunTranslator vcTranslator,
            out IEnumerable <Function> vcTypeFunctions)
        {
            var vcLet = vc as VCExprLet;

            Contract.Assert(vcLet != null);

            var uniqueNamer = new IsaUniqueNamer();
            var blockToVC   = VCBlockExtractor.BlockToVCMapping(vcLet, cfg);

            var declCollector = new VCFunDeclCollector();
            var funToVCfun    =
                declCollector.CollectFunDeclarations(new List <VCExpr> {
                vc
            }.Concat(vcAxioms), methodData.Functions);
            IVCVarFunTranslator varTranslator =
                new VCVarFunTranslator(methodData.AllVariables(), funToVCfun, translator, axiomBuilder);

            var activeDeclsPerBlock =
                activeDeclGenerator.GetActiveDeclsPerBlock(blockToVC, varTranslator, cfg, out var blockToNewVars);

            #region temporary: extend vc instantiation to support vc functions

            IList <Function> otherFunctions    = new List <Function>();
            ISet <Function>  otherFunctionsSet = new HashSet <Function>();

            foreach (var decl in activeDeclsPerBlock[cfg.entry])
            {
                if (decl is Function fun && !varTranslator.TranslateBoogieFunction(fun, out _))
                {
                    otherFunctions.Add(fun);
                    otherFunctionsSet.Add(fun);
                }
            }

            //also record functions that are used elswhere (type axiom related functions)
            var collector = new VCExprDeclCollector();
            var vcExprs   = vcAxioms.ToList();
            foreach (var ax in vcExprs)
            {
                var decls = collector.CollectNamedDeclarations(ax, varTranslator);
                foreach (var d in decls)
                {
                    if (d is Function fun && !varTranslator.TranslateBoogieFunction(fun, out _) &&
                        !otherFunctions.Contains(d))
                    {
                        otherFunctions.Add(fun);
                    }
                }
            }

            #endregion

            IDictionary <Block, IList <NamedDeclaration> > activeDeclsPerBlockSorted =
                SortActiveDecls(activeDeclsPerBlock, methodData.Functions.Union(otherFunctions), varTranslator,
                                out var activeVarsPerBlock);

            var blockToNewVCVars = ConvertVariableToVCExpr(blockToNewVars, varTranslator);

            var blockToIsaTranslator = new VCBlockToIsaTranslator(uniqueNamer);
            var blockToVCExpr        =
                blockToIsaTranslator.IsaDefsFromVC(blockToVC, activeVarsPerBlock, cfg, blockToNewVCVars);

            //add vc definitions of blocks in correct order
            IList <OuterDecl> vcOuterDecls = new List <OuterDecl>();

            foreach (var block in cfg.GetBlocksBackwards())
            {
                vcOuterDecls.Add(blockToVCExpr[block]);
            }

            vcinst = new VCInstantiation <Block>(blockToVCExpr, activeDeclsPerBlockSorted, localeName);

            /*
             *
             * //reason for using second reference: cannot use out parameters in lambda expressions
             * var vcinstInternal = vcinst;
             *
             * LemmaDecl vcCorrectLemma = new LemmaDecl("vc_correct",
             *  new TermApp(vcinstInternal.GetVCObjRef(cfg.entry, false),
             *             activeVarsPerBlock[cfg.entry].Select(v => (Term) IsaCommonTerms.TermIdentFromName(uniqueNamer.GetName(v, v.Name))).ToList()),
             *  new Proof(
             *    new List<string>() {
             *        "apply (simp only: " +
             *        cfg.GetBlocksForwards().Select(b => vcinstInternal.GetVCObjNameRef(b, false) + "_def").Concat(" ")
             + ")",
             +        "oops"
             +    }
             +  ));
             +
             + vcOuterDecls.Add(vcCorrectLemma);
             */

            //axioms
            var activeDeclsPerAxiom = VCInstAxioms(vcExprs, varTranslator);
            IDictionary <VCExpr, IList <NamedDeclaration> > activeDeclsPerAxiomSorted =
                SortActiveDecls(activeDeclsPerAxiom, methodData.Functions.Union(otherFunctions), varTranslator,
                                out var activeVarsPerAxiom);
            var axiomToDef          = new Dictionary <VCExpr, DefDecl>();
            var vcExprIsaTranslator = new VCExprToIsaTranslator(uniqueNamer);

            if (activeDeclsPerAxiomSorted.Count != vcExprs.Count())
            {
                throw new ProofGenUnexpectedStateException(typeof(VCToIsaInterface), "count not in-sync");
            }

            var axId = 0;
            foreach (var vcAx in activeDeclsPerAxiomSorted.Keys)
            {
                IList <Term> args = activeVarsPerAxiom[vcAx].Select(v => vcExprIsaTranslator.Translate(v)).ToList();
                var          rhs  = vcExprIsaTranslator.Translate(vcAx);

                var def = new DefDecl("vcax_" + axId, new Tuple <IList <Term>, Term>(args, rhs));
                axiomToDef.Add(vcAx, def);
                axId++;
            }

            vcinstAxiom = new VCInstantiation <VCExpr>(axiomToDef, activeDeclsPerAxiomSorted, localeName);

            vcOuterDecls.AddRange(axiomToDef.Values);

            var vcFunctions = methodData.Functions.Where(f => varTranslator.TranslateBoogieFunction(f, out var result))
                              .Select(f =>
            {
                if (varTranslator.TranslateBoogieFunction(f, out var result))
                {
                    return(result);
                }
                throw new InvalidOperationException();
            }).Union(otherFunctions);

            vcTranslator    = varTranslator;
            vcTypeFunctions = otherFunctions;

            return(new LocaleDecl(localeName, ContextElem.CreateWithFixedVars(GetVarsInVC(vcFunctions, uniqueNamer)),
                                  vcOuterDecls));
        }