From cd25a8d2231231680ef4564325093f870d63e214 Mon Sep 17 00:00:00 2001 From: AD1024 Date: Wed, 13 Aug 2025 22:49:49 +0000 Subject: [PATCH 1/3] [fix] process verification failure message at base case --- .../CompilerCore/Backend/PVerifier/Uclid5CodeGenerator.cs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Src/PCompiler/CompilerCore/Backend/PVerifier/Uclid5CodeGenerator.cs b/Src/PCompiler/CompilerCore/Backend/PVerifier/Uclid5CodeGenerator.cs index 4d618365d..756cf2a22 100644 --- a/Src/PCompiler/CompilerCore/Backend/PVerifier/Uclid5CodeGenerator.cs +++ b/Src/PCompiler/CompilerCore/Backend/PVerifier/Uclid5CodeGenerator.cs @@ -256,13 +256,12 @@ private void ProcessFailureMessages(List collection, string[] query, stri foreach (var feedback in match.Groups[1].Captures.Zip(match.Groups[2].Captures)) { var line = query[int.Parse(feedback.Second.ToString()) - 1]; - var step = feedback.First.ToString().Contains("[Step #0]") ? "(base case)" : ""; var matchName = Regex.Match(line, @"// Failed to verify invariant (.*) at (.*)"); if (matchName.Success) { var invName = matchName.Groups[1].Value.Replace("_PGROUP_", ": "); failedInv.Add(invName); - failMessages.Add($"{reason} {line.Split("// ").Last()} {step}"); + failMessages.Add($"{reason} {line.Split("// ").Last()}"); } var matchDefault = Regex.Match(line, @@ -1212,7 +1211,7 @@ private void GenerateMain(Machine machine, State state, Event @event, ProofComma foreach (var inv in cmd.Premises) { - EmitLine($"invariant _{InvariantPrefix}{inv.Name}: {InvariantPrefix}{inv.Name}();"); + EmitLine($"invariant _{InvariantPrefix}{inv.Name}: {InvariantPrefix}{inv.Name}(); // Failed to verify invariant {inv.Name.Replace("_PGROUP_", ": ")} at base case"); } EmitLine(""); From 9acca8a44206be79154f8a931578d35a91b02271 Mon Sep 17 00:00:00 2001 From: AD1024 Date: Wed, 13 Aug 2025 22:53:00 +0000 Subject: [PATCH 2/3] [fix] RLE proof --- .../3_RingLeaderVerification/PSrc/System.p | 75 +++++++++++++++---- 1 file changed, 61 insertions(+), 14 deletions(-) diff --git a/Tutorial/Advanced/3_RingLeaderVerification/PSrc/System.p b/Tutorial/Advanced/3_RingLeaderVerification/PSrc/System.p index 9779f8100..dce72d083 100644 --- a/Tutorial/Advanced/3_RingLeaderVerification/PSrc/System.p +++ b/Tutorial/Advanced/3_RingLeaderVerification/PSrc/System.p @@ -3,22 +3,55 @@ type tNominate = (voteFor: machine); event eNominate : tNominate; pure le(x: machine, y: machine): bool; -axiom forall (x: machine) :: le(x, x); -axiom forall (x: machine, y: machine) :: le(x, y) || le(y, x); -axiom forall (x: machine, y: machine, z: machine) :: (le(x, y) && le(y, z)) ==> le(x, z); -axiom forall (x: machine, y: machine) :: (le(x, y) && le(y, x)) ==> (x == y); +init-condition forall (x: machine) :: le(x, x); +init-condition forall (x: machine, y: machine) :: le(x, y) || le(y, x); +init-condition forall (x: machine, y: machine, z: machine) :: (le(x, y) && le(y, z)) ==> le(x, z); +init-condition forall (x: machine, y: machine) :: (le(x, y) && le(y, x)) ==> (x == y); + +Lemma less_than { + invariant le_refl: forall (x: machine) :: le(x, x); + invariant le_symm: forall (x: machine, y: machine) :: le(x, y) || le(y, x); + invariant le_trans: forall (x: machine, y: machine, z: machine) :: (le(x, y) && le(y, z)) ==> le(x, z); + invariant le_antisymm: forall (x: machine, y: machine) :: (le(x, y) && le(y, x)) ==> (x == y); +} +Proof { + prove less_than; +} pure btw(x: machine, y: machine, z: machine): bool; -axiom forall (w: machine, x: machine, y: machine, z: machine) :: (btw(w, x, y) && btw(w, y, z)) ==> btw(w, x, z); -axiom forall (x: machine, y: machine, z: machine) :: btw(x, y, z) ==> !btw(x, z, y); -axiom forall (x: machine, y: machine, z: machine) :: btw(x, y, z) || btw(x, z, y) || (x == y) || (x == z) || (y == z); -axiom forall (x: machine, y: machine, z: machine) :: btw(x, y, z) ==> btw(y, z, x); +init-condition forall (w: machine, x: machine, y: machine, z: machine) :: (btw(w, x, y) && btw(w, y, z)) ==> btw(w, x, z); +init-condition forall (x: machine, y: machine, z: machine) :: btw(x, y, z) ==> !btw(x, z, y); +init-condition forall (x: machine, y: machine, z: machine) :: btw(x, y, z) || btw(x, z, y) || (x == y) || (x == z) || (y == z); +init-condition forall (x: machine, y: machine, z: machine) :: btw(x, y, z) ==> btw(y, z, x); + +Lemma between_rel { + invariant btw_1: forall (w: machine, x: machine, y: machine, z: machine) :: (btw(w, x, y) && btw(w, y, z)) ==> btw(w, x, z); + invariant btw_2: forall (x: machine, y: machine, z: machine) :: btw(x, y, z) ==> !btw(x, z, y); + invariant btw_3: forall (x: machine, y: machine, z: machine) :: btw(x, y, z) || btw(x, z, y) || (x == y) || (x == z) || (y == z); + invariant btw_4: forall (x: machine, y: machine, z: machine) :: btw(x, y, z) ==> btw(y, z, x); +} +Proof { + prove between_rel; +} pure right(x: machine): machine; -axiom forall (x: machine) :: x != right(x); -axiom forall (x: machine, y: machine) :: (x != y && y != right(x)) ==> btw(x, right(x), y); +init-condition forall (x: machine) :: x != right(x); +init-condition forall (x: machine, y: machine) :: (x != y && y != right(x)) ==> btw(x, right(x), y); +init-condition forall (x: machine, y: machine) :: !btw(x, y, right(x)); +init-condition forall (x: machine, n: machine, m: machine) :: m == right(n) ==> (btw(n, m, x) || x == m || x == n); + +Lemma right_rel { + invariant right_neq_self: forall (x: machine) :: x != right(x); + invariant btw_right: forall (x: machine, y: machine) :: (x != y && y != right(x)) ==> btw(x, right(x), y); + invariant Aux1: forall (x: machine, y: machine) :: !btw(x, y, right(x)); + invariant right_btw: forall (x: machine, n: machine, m: machine) :: m == right(n) ==> (btw(n, m, x) || x == m || x == n); +} +Proof { + prove right_rel; +} machine Server { + var aux: set[machine]; start state Proposing { entry { send right(this), eNominate, (voteFor=this,); @@ -38,10 +71,24 @@ machine Server { } } + + // voteFor is the running max -invariant NoBypass: forall (n: machine, m: machine, e: eNominate) :: (inflight e && e targets m && n is Server && btw(e.voteFor, n, m)) ==> le(n, e.voteFor); -invariant SelfPendingMax: forall (n: machine, m: machine, e: eNominate) :: (inflight e && e targets m && e.voteFor == m) ==> le(n, m); +Lemma lemmas { + invariant LeaderMax: forall (x: machine, y: machine) :: x is Won ==> le(y, x); + invariant Aux: forall (x: machine, y: machine) :: (le(x, y) && le(y, x)) ==> x == y; + invariant NoBypass: forall (n: machine, m: machine, e: eNominate) :: (inflight e && e targets m && btw(e.voteFor, n, m)) ==> le(n, e.voteFor); + invariant SelfPendingMax: forall (n: machine, m: machine, e: eNominate) :: (inflight e && e targets m && e.voteFor == m) ==> le(n, m); +} +Proof { + prove lemmas using less_than, between_rel, right_rel; +} // Main theorems -invariant LeaderMax: forall (x: machine, y: machine) :: x is Won ==> le(y, x); -invariant UniqueLeader: forall (x: machine, y: machine) :: (x is Won && y is Won) ==> (le(x, y) && le(y, x)); \ No newline at end of file +Theorem Safety { + invariant UniqueLeader: forall (x: machine, y: machine) :: (x is Won && y is Won) ==> x == y; +} +Proof { + prove Safety using lemmas_LeaderMax, lemmas_Aux; + prove default; +} \ No newline at end of file From 355a888a54cd8315f09380ad15961fc7fb816407 Mon Sep 17 00:00:00 2001 From: Mike He Date: Thu, 14 Aug 2025 15:38:05 -0700 Subject: [PATCH 3/3] save Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- Tutorial/Advanced/3_RingLeaderVerification/PSrc/System.p | 1 - 1 file changed, 1 deletion(-) diff --git a/Tutorial/Advanced/3_RingLeaderVerification/PSrc/System.p b/Tutorial/Advanced/3_RingLeaderVerification/PSrc/System.p index dce72d083..7d6d54b5e 100644 --- a/Tutorial/Advanced/3_RingLeaderVerification/PSrc/System.p +++ b/Tutorial/Advanced/3_RingLeaderVerification/PSrc/System.p @@ -51,7 +51,6 @@ Proof { } machine Server { - var aux: set[machine]; start state Proposing { entry { send right(this), eNominate, (voteFor=this,);