public void GenerateAtomicTauLeavesPCUnchangedLemma() { var pr = new PathPrinter(this); string str = $@" lemma lemma_{prefix}_AtomicTauLeavesPCUnchanged() ensures AtomicTauLeavesPCUnchanged({prefix}_GetSpecFunctions()) {{ var asf := {prefix}_GetSpecFunctions(); forall s, path, tid | asf.path_valid(s, path, tid) && asf.path_type(path).AtomicPathType_Tau? ensures var s' := asf.path_next(s, path, tid); asf.get_thread_pc(s', tid) == asf.get_thread_pc(s, tid) {{ { pr.GetOpenValidPathInvocation(TauPath) } }} }} "; pgp.AddLemma(str, auxName); }
public void GeneratePerAtomicPathLemma(string fileName, string lemmaName, PathToBoolDelegate pathFilter, PathToStringDelegate postconditionDelegate, PathToStringDelegate proofBodyDelegate) { string str; var pr = new PathPrinter(this); foreach (var atomicPath in atomicPaths.Where(ap => pathFilter(ap))) { str = $@" lemma lemma_{prefix}_{lemmaName}_{atomicPath.Name}( asf: AtomicSpecFunctions<{typeState}, {prefix}_Path, {moduleName}.Armada_PC>, s: {typeState}, path: {prefix}_Path, tid: Armada_ThreadHandle ) requires asf == {prefix}_GetSpecFunctions() requires path.{prefix}_Path_{atomicPath.Name}? requires asf.path_valid(s, path, tid) ensures {postconditionDelegate(atomicPath)} {{ { pr.GetOpenValidPathInvocation(atomicPath) } { proofBodyDelegate(atomicPath) } ProofCustomizationGoesHere(); }} "; if (fileName == null) { pgp.AddLemma(str); } else { pgp.AddLemma(str, fileName); } } }
/////////////////////////////////////////////////////////////////////// // LEMMAS /////////////////////////////////////////////////////////////////////// public void GeneratePCEffectLemmas() { string str; var pr = new PathPrinter(this); foreach (var atomicPath in atomicPaths) { str = $@" lemma lemma_{prefix}_PathHasPCEffect_{atomicPath.Name}( s: {typeState}, path: {prefix}_Path, tid: Armada_ThreadHandle ) requires path.{prefix}_Path_{atomicPath.Name}? requires var asf := {prefix}_GetSpecFunctions(); asf.path_valid(s, path, tid) ensures var asf := {prefix}_GetSpecFunctions(); var pc := asf.get_thread_pc(s, tid); var s' := asf.path_next(s, path, tid); var pc' := asf.get_thread_pc(s', tid); "; if (atomicPath.Tau) { str += $"asf.state_ok(s) && pc.Some? && asf.state_ok(s') && pc'.Some? && pc'.v == pc.v"; } else { str += $"asf.state_ok(s) && pc.Some? && pc.v.{atomicPath.StartPC}?"; if (atomicPath.Stopping) { str += " && !asf.state_ok(s')"; } else if (atomicPath.EndPC == null) { str += " && asf.state_ok(s') && pc'.None?"; } else { str += $" && asf.state_ok(s') && pc'.Some? && pc'.v.{atomicPath.EndPC}?"; } } str += "{\n"; str += pr.GetOpenValidPathInvocation(atomicPath); str += "}\n"; pgp.AddLemma(str, auxName); } str = $@" lemma lemma_{prefix}_PathImpliesThreadRunning( s: {typeState}, path: {prefix}_Path, tid: Armada_ThreadHandle ) ensures var asf := {prefix}_GetSpecFunctions(); asf.path_valid(s, path, tid) ==> asf.state_ok(s) && asf.get_thread_pc(s, tid).Some? {{ var asf := {prefix}_GetSpecFunctions(); if asf.path_valid(s, path, tid) {{ match path {{ "; foreach (var atomicPath in atomicPaths) { str += $@" case {prefix}_Path_{atomicPath.Name}(_) => lemma_{prefix}_PathHasPCEffect_{atomicPath.Name}(s, path, tid); "; } str += "} } }\n"; pgp.AddLemma(str, auxName); }