public static void SetTypeEraserFactory(TypePremiseEraserFactory factory) { if (CommandLineOptions.Clo.GenerateIsaProgNoProofs) { return; } typePremiseEraserFactory = factory; var uniqueNamer = new IsaUniqueNamer(); /* Hack: try to make sure unique namer uses names for Boogie functions and Boogie variables that are different * from the default name otherwise it clashes with the functions potentially fixed in the context of a locale */ foreach (var fun in boogieGlobalData.Functions) { uniqueNamer.GetName(fun.Name, "o123_" + fun.Name); } foreach (var variable in finalProgData.AllVariables()) { uniqueNamer.GetName(variable.Name, "o123_" + variable.Name); } //Hack: translate vc variable based on name, to ensure that applying erasure multiple times shares the same variables var translator = VCExprToIsaTranslator.CreateNameBasedTranslator(uniqueNamer); translator.SetFunctionNamer(uniqueNamer); translator.SetTryInstantiatingFunctions(true); vcHintManager = new VCHintManager(new VcRewriteLemmaGen(factory, translator)); }
public static Theory ProgramToVcProof( string theoryName, bool generateEndToEndProof, CFGRepr finalCfg, CFGRepr afterPassificationCfg, IDictionary <Block, Block> afterPassiveToFinalBlock, IDictionary <Block, Block> afterPassiveToOrigBlock, IProgramAccessor passiveProgAccess, IProgramAccessor beforePassiveProgAccess, BoogieMethodData methodData, ProgramVcProofData vcProofData, IVariableTranslationFactory varFactory, TypePremiseEraserFactory eraserFactory, VCExpressionGenerator gen, out Term vcAssm, out LemmaDecl endToEndLemma) { var lemmaNamer = new IsaUniqueNamer(); var passiveLemmaManager = new VcPhaseLemmaManager( vcProofData.VcBoogieInfo.VcInst, methodData, vcProofData.VcFunctions, passiveProgAccess.BlockInfo(), varFactory); var afterPassiveReachableBlocks = ReachableBlocks(afterPassificationCfg); var finalProgramLemmas = GenerateVCLemmas(afterPassificationCfg, finalCfg, afterPassiveToFinalBlock, afterPassiveToOrigBlock, afterPassiveReachableBlocks, passiveLemmaManager, vcProofData.VcHintManager, lemmaNamer); var cfgProgramLemmas = GenerateCfgLemmas(afterPassificationCfg, finalCfg, afterPassiveToFinalBlock, afterPassiveReachableBlocks, finalProgramLemmas, passiveLemmaManager, passiveProgAccess.CfgDecl(), lemmaNamer); var afterPassificationDecls = new List <OuterDecl>(); foreach (var v in finalProgramLemmas.Values) { afterPassificationDecls.AddRange(v); } afterPassificationDecls.AddRange(cfgProgramLemmas.Values); var afterPassificationLocale = GenerateLocale("passification", passiveLemmaManager, afterPassificationDecls); var passiveOuterDecls = new List <OuterDecl> { vcProofData.VcLocale }; passiveOuterDecls.Add(afterPassificationLocale); //generate axiom var axiomUniqueNamer = new IsaUniqueNamer(); var axId = 0; var axiomToLemma = new Dictionary <Axiom, OuterDecl>(); var vcRewriteLemmaGen = new VcRewriteLemmaGen(eraserFactory, VCExprToIsaTranslator.CreateNameBasedTranslator(new IsaUniqueNamer())); var vcAxiomLemmaManager = new VcAxiomLemmaManager( vcProofData.VcBoogieInfo.VcInstAxiom, methodData, vcProofData.VcFunctions, vcRewriteLemmaGen, varFactory); var axiomLocaleRequiredDecls = new List <OuterDecl>(); foreach (var axiom in vcProofData.VcBoogieInfo.VcAxiomsInfo) { if (axiom is VcBoogieAxiomInfo vcBoogieAxiom) { var axiomVcLemma = vcAxiomLemmaManager.AxiomVcLemma( axiomUniqueNamer.GetName(axiom, "axiom_vc_" + axId), vcBoogieAxiom.Axiom, vcBoogieAxiom.Expr, out var requiredDecls); axiomToLemma.Add(vcBoogieAxiom.Axiom, axiomVcLemma); axiomLocaleRequiredDecls.AddRange(requiredDecls); } } /* we add the required declarations for the axiom locale to the outer theory, since the axiom locale fixes variables that could clash * with the declarations */ passiveOuterDecls.AddRange(axiomLocaleRequiredDecls); var axiomLocale = GenerateLocale("axioms", vcAxiomLemmaManager, axiomToLemma.Values.ToList()); passiveOuterDecls.Add(axiomLocale); if (generateEndToEndProof) { var endToEnd = new EndToEndVCProof( methodData, passiveProgAccess, vcProofData.VcFunctions, vcProofData.VcBoogieInfo, afterPassificationCfg, finalCfg, afterPassificationLocale.Name + "." + cfgProgramLemmas[afterPassificationCfg.entry].Name, axiomLocale.Name, ax => axiomLocale.Name + "." + axiomToLemma[ax].Name, varFactory, vcProofData.VcTranslator, eraserFactory, gen); passiveOuterDecls.AddRange(endToEnd.GenerateProof(out vcAssm, out endToEndLemma)); } else { vcAssm = null; endToEndLemma = null; } return (new Theory(theoryName, new List <string> { "Boogie_Lang.Semantics", "Boogie_Lang.Util", "Boogie_Lang.VCHints", "Boogie_Lang.VCPhaseML", passiveProgAccess.TheoryName(), beforePassiveProgAccess.TheoryName() }, passiveOuterDecls)); }
/// <summary> /// As a side effect, updates "this.parent.CumulativeAssertionCount". /// </summary> public void BeginCheck(Checker checker, VerifierCallback callback, ModelViewInfo mvInfo, int no, int timeout, int rlimit) { Contract.Requires(checker != null); Contract.Requires(callback != null); splitNo = no; impl.Blocks = blocks; this.checker = checker; Dictionary <int, Absy> label2absy = new Dictionary <int, Absy>(); ProverContext ctx = checker.TheoremProver.Context; Boogie2VCExprTranslator bet = ctx.BoogieExprTranslator; var cc = new VCGen.CodeExprConversionClosure(label2absy, ctx); bet.SetCodeExprConverter(cc.CodeExprToVerificationCondition); var exprGen = ctx.ExprGen; VCExpr controlFlowVariableExpr = exprGen.Integer(BigNum.ZERO); #region proofgen TypePremiseEraserFactory typePremiseEraserFactory; switch (CommandLineOptions.Clo.TypeEncodingMethod) { case CommandLineOptions.TypeEncoding.Predicates: typePremiseEraserFactory = new TypePremiseEraserFactory(checker.VCExprGen, bet, true); break; case CommandLineOptions.TypeEncoding.Monomorphic: typePremiseEraserFactory = new TypePremiseEraserFactory(checker.VCExprGen, bet, false); break; default: throw new NotImplementedException(); } ProofGenerationLayer.SetTypeEraserFactory(typePremiseEraserFactory); #endregion /* PROOF GEN: we pass "null" as the control flow variable expression, such that labels are not produced as they are * not relevant for proof generation of programs that verify */ VCExpr vc = parent.GenerateVCAux(impl, null, label2absy, checker.TheoremProver.Context); Contract.Assert(vc != null); #region proofgen if (!(ctx is DeclFreeProverContext)) { throw new NotImplementedException("Proof Generation only supports DeclFreeProverContext as context."); } var declFreeProverContext = ctx as DeclFreeProverContext; var premiseEraserProvider = typePremiseEraserFactory?.NewEraser(); VCExpr eraseVC(VCExpr vc, int polarity) { return(!premiseEraserProvider.ProgramIsPolymorphic ? vc : premiseEraserProvider.EraseAndSortLet(vc, polarity)); } VCExpr erasedVC = eraseVC(vc, 1); VCExpr erasedAxioms = eraseVC(declFreeProverContext.Axioms, -1); VCExpr typeAxioms = null; List <VCAxiomInfo> vcAxiomsInfo = null; if (premiseEraserProvider.ProgramIsPolymorphic) { typeAxioms = premiseEraserProvider.AxiomBuilder.GetNewAxiomsAndInfo(out vcAxiomsInfo); } ProofGenerationLayer.VCGenerateAllProofs( erasedVC, erasedAxioms, typeAxioms, vcAxiomsInfo, checker.TheoremProver.VCExprGen, checker.TheoremProver.Context.BoogieExprTranslator, premiseEraserProvider?.AxiomBuilder); #endregion /* PROOF GEN: comment out label specific parts * VCExpr controlFlowFunctionAppl = * exprGen.ControlFlowFunctionApplication(exprGen.Integer(BigNum.ZERO), exprGen.Integer(BigNum.ZERO)); * VCExpr eqExpr = exprGen.Eq(controlFlowFunctionAppl, exprGen.Integer(BigNum.FromInt(impl.Blocks[0].UniqueId))); * vc = exprGen.Implies(eqExpr, vc); */ reporter = new VCGen.ErrorReporter(gotoCmdOrigins, label2absy, impl.Blocks, parent.debugInfos, callback, mvInfo, this.Checker.TheoremProver.Context, parent.program); if (CommandLineOptions.Clo.TraceVerify && no >= 0) { Console.WriteLine("-- after split #{0}", no); Print(); } string desc = cce.NonNull(impl.Name); if (no >= 0) { desc += "_split" + no; } checker.BeginCheck(desc, vc, reporter, timeout, rlimit, impl.RandomSeed); }