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 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); }
//cfg must be acyclic public static IDictionary <Block, IEnumerable <Variable> > ComputeLiveVariables(CFGRepr cfg, BoogieMethodData methodData) { var liveVarsBefore = new Dictionary <Block, IEnumerable <Variable> >(); var allVarsSet = new HashSet <Variable>(methodData.AllVariables()); foreach (var b in cfg.GetBlocksBackwards()) { var bCurLiveVars = new HashSet <Variable>(); foreach (var bSuc in cfg.GetSuccessorBlocks(b)) { bCurLiveVars.UnionWith(liveVarsBefore[bSuc]); } for (var idx = b.cmds.Count - 1; idx >= 0; idx--) { UpdateLiveSet(b.cmds[idx], bCurLiveVars); } //due to the VariableCollector's implementation bound variables may also have been included bCurLiveVars.RemoveWhere(v => !allVarsSet.Contains(v)); liveVarsBefore.Add(b, bCurLiveVars); } return(liveVarsBefore); }
/// <summary> /// Provide target CFG for passification phase, construct global version map. /// </summary> /// <param name="impl">source CFG after passification phase</param> /// <exception cref="ProofGenUnexpectedStateException">thrown if global version map is incorrect /// (should never happen). </exception> public static void AfterPassificationCheckGlobalMap(Implementation impl) { afterPassificationImpl = impl; if (CommandLineOptions.Clo.GenerateIsaProgNoProofs) { return; } finalProgData = MethodDataFromImpl(impl, boogieGlobalData); var config = new CFGReprConfigBuilder().SetIsAcyclic(true).SetBlockCopy(true).SetDesugarCalls(false) .SetDeepCopyPredCmd(TypeCheckBeforeVcMaybeRewritesCmd).Build(); afterPassificationCfg = CFGReprTransformer.GetCfgRepresentation(impl, config, out afterPassificationToOrigBlock, out _); var passiveBlocks = new List <Block>(afterPassificationCfg.GetBlocksBackwards()); var origToAfterPassificationBlock = afterPassificationToOrigBlock.InverseDict(); beforePassiveToAfterPassiveBlock = DictionaryComposition(beforePassiveOrigBlock, origToAfterPassificationBlock); var globalVersion = new GlobalVersion(); passiveRelationGen = new PassiveRelationGen( beforePassificationCfg, passificationHintManager, initialVarMapping, beforePassiveOrigBlock, beforePassiveToAfterPassiveBlock, ProofGenLiveVarAnalysis.ComputeLiveVariables(beforePassificationCfg, beforePassiveData) ); //all variables before passification are the initial versions and already constrained globalVersionMap = globalVersion.GlobalVersionMap( passiveRelationGen, beforePassiveData.AllVariables(), afterPassificationCfg.entry, passiveBlocks); //Console.WriteLine("Version map: " + string.Join(Environment.NewLine, globalVersionMap)); var versionMapCorrect = GlobalVersionChecker.CheckVersionMap(globalVersionMap, passiveRelationGen, beforePassificationCfg, beforePassiveToAfterPassiveBlock); if (!versionMapCorrect) { throw new ProofGenUnexpectedStateException(typeof(ProofGenerationLayer), "Incorrect version map"); } }
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)); }