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); }
public VcAxiomLemmaManager( VCInstantiation <VCExpr> vcAxiomInst, BoogieMethodData methodData, IEnumerable <Function> vcFunctions, VcRewriteLemmaGen vcRewriteLemmaGen, IVariableTranslationFactory variableFactory) { this.vcAxiomInst = vcAxiomInst; this.methodData = methodData; this.vcRewriteLemmaGen = vcRewriteLemmaGen; this.variableFactory = variableFactory; basicCmdIsaVisitor = new BasicCmdIsaVisitor(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(methodData.Constants), 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, methodData.Constants, variableFactory); }
public LemmaDecl GenerateEmptyBlockLemma(Block block, IEnumerable <Block> finalCfgSuccessors, string lemmaName) { //Term cmds = new TermList(cmdIsaVisitor.Translate(block.Cmds)); var blockDefName = isaBlockInfo.CmdsQualifiedName(block); Term blockDefTerm = IsaCommonTerms.TermIdentFromName(blockDefName); var cmdsReduce = IsaBoogieTerm.RedCmdList(boogieContext, blockDefTerm, initState, finalState); var assumptions = new List <Term> { cmdsReduce }; if (finalCfgSuccessors.Any()) { assumptions.Add(LemmaHelper.ConjunctionOfSuccessorBlocks(finalCfgSuccessors, declToVCMapping, vcinst)); } var conclusion = ConclusionBlock(finalCfgSuccessors, normalInitState, finalState, declToVCMapping, vcinst); var proof = new Proof( new List <string> { "using assms", "unfolding " + blockDefName + "_def", "apply cases", "by auto" } ); return(new LemmaDecl(lemmaName, ContextElem.CreateWithAssumptions(assumptions), conclusion, proof)); }
/// <summary>The returned list in-sync with <see cref="AllAssumptionLabels" />.</summary> public IList <Term> AllAssumptions( IDictionary <Function, TermIdent> funInterpMapping, IDictionary <NamedDeclaration, Term> declToVCMapping, Term state, BoogieContextIsa boogieContext, IVariableTranslation <Variable> varTranslation ) { var assumptions = new List <Term>(); foreach (var obj in _assumptionLabelMap.Keys) { if (obj is Function f) { assumptions.Add(LemmaHelper.FunctionCtxtWfAssm(f, funInterpMapping, boogieContext)); assumptions.Add(LemmaHelper.FunctionVcCorresAssm(f, funInterpMapping, declToVCMapping, boogieContext)); } else if (obj is Variable v) { assumptions.Add(LemmaHelper.LocalStateVariableAssumption(v, boogieContext.varContext, state, declToVCMapping, varTranslation)); if (!TypeUtil.IsPrimitive(v.TypedIdent.Type)) { assumptions.Add(LemmaHelper.VariableTypeAssumption( v, declToVCMapping[v], new TypeIsaVisitor(_factory.CreateEmptyTranslation().TypeVarTranslation), boogieContext.absValTyMap)); } } else if (obj is SpecialAssumptionsKind kind) { switch (kind) { case SpecialAssumptionsKind.TypeValClosed: assumptions.Add(EndToEndAssumptions.ClosednessAssumption(boogieContext.absValTyMap)); break; default: throw new ArgumentOutOfRangeException(); } } } return(assumptions); }
private static Term ConclusionBlock( IEnumerable <Block> b_successors, Term normalInitState, Term finalState, IDictionary <NamedDeclaration, Term> declToVCMapping, VCInstantiation <Block> vcinst, bool useMagicFinalState = false) { if (useMagicFinalState) { return(new TermBinary(finalState, IsaBoogieTerm.Magic(), TermBinary.BinaryOpCode.Eq)); } Term nonFailureConclusion = new TermBinary(finalState, IsaBoogieTerm.Failure(), TermBinary.BinaryOpCode.Neq); var normalFinalState = IsaCommonTerms.TermIdentFromName("n_s'"); Term ifNormalConclusionLhs = new TermBinary(finalState, IsaBoogieTerm.Normal(normalFinalState), TermBinary.BinaryOpCode.Eq); Term ifNormalConclusionRhs1 = new TermBinary(normalFinalState, normalInitState, TermBinary.BinaryOpCode.Eq); var ifNormalConclusionRhs = !b_successors.Any() ? ifNormalConclusionRhs1 : new TermBinary( ifNormalConclusionRhs1, LemmaHelper.ConjunctionOfSuccessorBlocks(b_successors, declToVCMapping, vcinst), TermBinary.BinaryOpCode.And); Term ifNormalConclusion = new TermQuantifier( TermQuantifier.QuantifierKind.ALL, new List <Identifier> { normalFinalState.Id }, new TermBinary( ifNormalConclusionLhs, ifNormalConclusionRhs, TermBinary.BinaryOpCode.Implies) ); return(new TermBinary(nonFailureConclusion, ifNormalConclusion, TermBinary.BinaryOpCode.And)); }
public LemmaDecl GenerateBlockLemma(Block block, Block finalCfgBlock, IEnumerable <Block> finalCfgSuccessors, string lemmaName, string vcHintsName) { var cmdsReduce = IsaBoogieTerm.RedCmdList(boogieContext, IsaCommonTerms.TermIdentFromName(isaBlockInfo.CmdsQualifiedName(block)), initState, finalState); var vcAssm = vcinst.GetVCObjInstantiation(finalCfgBlock, declToVCMapping); //do not use separate assumption, leads to issues var conclusion = ConclusionBlock(finalCfgSuccessors, normalInitState, finalState, declToVCMapping, vcinst, LemmaHelper.FinalStateIsMagic(block)); Term statement = TermBinary.MetaImplies(cmdsReduce, TermBinary.MetaImplies(vcAssm, conclusion)); var proof = BlockCorrectProof(block, finalCfgBlock, vcHintsName); return(new LemmaDecl(lemmaName, ContextElem.CreateEmptyContext(), statement, proof)); }
public static IList <Tuple <TermIdent, TypeIsa> > GlobalFixedVariables( BoogieContextIsa boogieContext, IEnumerable <Function> functions, IEnumerable <Variable> variables, TermIdent normalInitState, IDictionary <Function, TermIdent> funToInterpMapping, IsaUniqueNamer uniqueNamer) { var absValType = new VarType("a"); var pureTyIsaTransformer = LemmaHelper.ConretePureTyIsaTransformer(absValType); var result = new List <Tuple <TermIdent, TypeIsa> > { Tuple.Create((TermIdent)boogieContext.absValTyMap, IsaBoogieType.AbstractValueTyFunType(absValType)), Tuple.Create((TermIdent)boogieContext.varContext, IsaBoogieType.VarContextType()), Tuple.Create((TermIdent)boogieContext.funContext, IsaBoogieType.FunInterpType(absValType)), Tuple.Create(normalInitState, IsaBoogieType.NormalStateType(absValType)) }; foreach (var kv in funToInterpMapping) { result.Add(Tuple.Create(kv.Value, IsaBoogieType.BoogieFuncInterpType(absValType))); var boogieFun = kv.Key; //get untyped version, maybe should precompute this somewhere and re-use or get the data from the VC TypeUtil.SplitTypeParams(boogieFun.TypeParameters, boogieFun.InParams.Select(v => v.TypedIdent.Type), out var explicitTypeVars, out _); var typeIsa = pureTyIsaTransformer.Translate(new Function(null, boogieFun.Name, explicitTypeVars, boogieFun.InParams, boogieFun.OutParams[0])); result.Add(Tuple.Create( IsaCommonTerms.TermIdentFromName(uniqueNamer.GetName(boogieFun, boogieFun.Name)), typeIsa)); } foreach (var v in variables) { var typeIsa = pureTyIsaTransformer.Translate(v); result.Add(Tuple.Create(IsaCommonTerms.TermIdentFromName(uniqueNamer.GetName(v, v.Name)), typeIsa)); } return(result); }
private static HashSet <Block> ReachableBlocks(CFGRepr cfg) { var reachableBlocks = new HashSet <Block>(); var queue = new Queue <Block>(); reachableBlocks.Add(cfg.entry); queue.Enqueue(cfg.entry); while (queue.TryDequeue(out var b)) { if (!LemmaHelper.FinalStateIsMagic(b)) { //b's successors are not trivially unreachable var successors = cfg.GetSuccessorBlocks(b); foreach (var suc in successors) { reachableBlocks.Add(suc); queue.Enqueue(suc); } } } return(reachableBlocks); }
public LemmaDecl GenerateCfgLemma( Block block, Block finalCfgBlock, bool isContainedInFinalCfg, IEnumerable <Block> successors, IEnumerable <Block> finalCfgSuccessors, Term cfg, Func <Block, string> cfgLemmaName, LemmaDecl BlockLemma) { var red = IsaBoogieTerm.RedCFGMulti( boogieContext, cfg, IsaBoogieTerm.CFGConfigNode(new NatConst(isaBlockInfo.BlockIds[block]), IsaBoogieTerm.Normal(normalInitState)), IsaBoogieTerm.CFGConfig(finalNode, finalState)); var assumption = new List <Term> { red }; var hasVcAssm = false; if (isContainedInFinalCfg) { assumption.Add(vcinst.GetVCObjInstantiation(finalCfgBlock, declToVCMapping)); hasVcAssm = true; } else { //vc assumption is conjunction of reachable successors in final cfg if (finalCfgSuccessors.Any()) { assumption.Add( LemmaHelper.ConjunctionOfSuccessorBlocks(finalCfgSuccessors, declToVCMapping, vcinst)); hasVcAssm = true; } } Term conclusion = new TermBinary(finalState, IsaBoogieTerm.Failure(), TermBinary.BinaryOpCode.Neq); var nodeLemma = isaBlockInfo.BlockCmdsMembershipLemma(block); var outEdgesLemma = isaBlockInfo.OutEdgesMembershipLemma(block); var proofMethods = new List <string>(); var eruleLocalBlock = "erule " + (hasVcAssm ? ProofUtil.OF(BlockLemma.Name, "_", "assms(2)") : BlockLemma.Name); if (isContainedInFinalCfg && LemmaHelper.FinalStateIsMagic(block)) { proofMethods.Add("apply (rule converse_rtranclpE2[OF assms(1)], fastforce)"); proofMethods.Add(ProofUtil.Apply("rule " + ProofUtil.OF("red_cfg_multi_backwards_step_magic", "assms(1)", nodeLemma))); proofMethods.Add(ProofUtil.By(eruleLocalBlock)); return(new LemmaDecl(cfgLemmaName(block), ContextElem.CreateWithAssumptions(assumption), conclusion, new Proof(proofMethods))); } if (successors.Any()) { proofMethods.Add("apply (rule converse_rtranclpE2[OF assms(1)], fastforce)"); var cfg_lemma = finalCfgSuccessors.Any() ? "red_cfg_multi_backwards_step" : "red_cfg_multi_backwards_step_2"; proofMethods.Add(ProofUtil.Apply("rule " + ProofUtil.OF(cfg_lemma, "assms(1)", nodeLemma))); proofMethods.Add(ProofUtil.Apply(eruleLocalBlock)); proofMethods.Add("apply (" + ProofUtil.Simp(outEdgesLemma) + ")"); foreach (var bSuc in successors) { proofMethods.Add("apply (erule member_elim, simp)"); proofMethods.Add("apply (erule " + cfgLemmaName(bSuc) + ", simp?" + ")"); } proofMethods.Add("by (simp add: member_rec(2))"); } else { proofMethods.Add("apply (rule converse_rtranclpE2[OF assms(1)], fastforce)"); proofMethods.Add("apply (rule " + ProofUtil.OF("red_cfg_multi_backwards_step_no_succ", "assms(1)", nodeLemma, outEdgesLemma) + ")"); if (isContainedInFinalCfg) { proofMethods.Add("using " + ProofUtil.OF(BlockLemma.Name, "_", "assms(2)") + " by blast"); } else { proofMethods.Add("using " + BlockLemma.Name + " by blast"); } } return(new LemmaDecl(cfgLemmaName(block), ContextElem.CreateWithAssumptions(assumption), conclusion, new Proof(proofMethods))); }