//if blockToNewVars is non-null, then the mapped variables are universally quantified for the corresponding block definition public IDictionary <Block, DefDecl> IsaDefsFromVC(IDictionary <Block, VCExpr> blockToVC, IDictionary <Block, IList <VCExprVar> > blockToActiveVars, CFGRepr cfg, IDictionary <Block, IList <VCExprVar> > blockToNewVars = null) { Contract.Ensures(Contract.Result <IDictionary <Block, DefDecl> >().Count == cfg.NumOfBlocks()); IDictionary <Block, DefDecl> blockToDefVC = new Dictionary <Block, DefDecl>(); var vcExprIsaVisitor = new VCExprToIsaTranslator(uniqueNamer, blockToDefVC, blockToActiveVars); foreach (var block in cfg.GetBlocksBackwards()) { // might be more efficient to hand over this: // IEnumerable<Tuple<Block, DefDecl>> successorDefs = cfg.outgoingBlocks[block].Select(b => new Tuple<Block, DefDecl>(b, blockToDefVC[b])); var term = vcExprIsaVisitor.Translate(blockToVC[block]); if (blockToNewVars != null && blockToNewVars.TryGetValue(block, out var newVars) && newVars != null && newVars.Any()) { IList <Identifier> boundVars = newVars .Select(v => (Identifier) new SimpleIdentifier(uniqueNamer.GetName(v, v.Name))).ToList(); IList <TypeIsa> boundVarsTypes = newVars.Select(v => pureTyIsaTransformer.Translate(v.Type)).ToList(); term = new TermQuantifier(TermQuantifier.QuantifierKind.ALL, boundVars, boundVarsTypes, term); } IList <Term> args = blockToActiveVars[block].Select(v => vcExprIsaVisitor.Translate(v)).ToList(); var def = new DefDecl(GetVCDefName(block), new Tuple <IList <Term>, Term>(args, term)); Contract.Assert(!blockToDefVC.ContainsKey(block)); blockToDefVC.Add(block, def); } return(blockToDefVC); }
public VcRewriteLemmaGen(TypePremiseEraserFactory factory, VCExprToIsaTranslator vcToIsaTranslator) { _typeEraserFactory = factory; _vcToIsaTranslator = vcToIsaTranslator; }
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)); }