From 16764081e3f24f903d82c1a5d5449a989e9afc14 Mon Sep 17 00:00:00 2001
From: Jonas Kastberg Hinrichsen <jihgfee@gmail.com>
Date: Tue, 6 Feb 2024 14:13:15 +0100
Subject: [PATCH] More refactoring

---
 multi_actris/channel/proofmode.v              | 134 +++++++++++++++---
 .../channel/proto_consistency_examples.v      | 118 ---------------
 2 files changed, 111 insertions(+), 141 deletions(-)

diff --git a/multi_actris/channel/proofmode.v b/multi_actris/channel/proofmode.v
index 33e7d5a..cc8cc20 100644
--- a/multi_actris/channel/proofmode.v
+++ b/multi_actris/channel/proofmode.v
@@ -7,11 +7,12 @@ standard pattern using type classes to perform the normalization.
 In addition to the tactics for symbolic execution, this file defines the tactic
 [solve_proto_contractive], which can be used to automatically prove that
 recursive protocols are contractive. *)
+From iris.algebra Require Import gmap.
 From iris.proofmode Require Import coq_tactics reduction spec_patterns.
 From iris.heap_lang Require Export proofmode notation.
 From multi_actris.channel Require Import proto_model.
 From multi_actris Require Export channel.
-Export action.
+Set Default Proof Using "Type".
 
 (** * Tactics for proving contractiveness of protocols *)
 Ltac f_dist_le :=
@@ -343,28 +344,115 @@ Tactic Notation "wp_send" "(" uconstr(x1) uconstr(x2) uconstr(x3) uconstr(x4) ")
   wp_send_core (eexists x1; eexists x2; eexists x3; eexists x4; eexists x5;
                 eexists x6; eexists x7; eexists x8) with pat.
 
-(* Section channel. *)
-(*   Context `{!heapGS Σ, !chanG Σ}. *)
-(*   Implicit Types p : iProto Σ. *)
-(*   Implicit Types TT : tele. *)
+Lemma iProto_consistent_equiv_proof {Σ} (ps : gmap nat (iProto Σ)) :
+  (∀ i j, valid_target ps i j) ∗
+  (∀ i j m1 m2,
+     (ps !!! i ≡ (<(Send, j)> m1)%proto) -∗
+     (ps !!! j ≡ (<(Recv, i)> m2)%proto) -∗
+     ∃ m1' m2' (TT1:tele) (TT2:tele) tv1 tP1 tp1 tv2 tP2 tp2,
+       (<(Send, j)> m1')%proto ≡ (<(Send, j)> m1)%proto ∗
+       (<(Recv, i)> m2')%proto ≡ (<(Recv, i)> m2)%proto ∗
+       ⌜MsgTele (TT:=TT1) m1' tv1 tP1 tp1⌝ ∗
+       ⌜MsgTele (TT:=TT2) m2' tv2 tP2 tp2⌝ ∗
+   ∀.. (x : TT1), tele_app tP1 x -∗
+   ∃.. (y : TT2), ⌜tele_app tv1 x = tele_app tv2 y⌝ ∗
+                  tele_app tP2 y ∗
+                  â–· (iProto_consistent
+                       (<[i:=tele_app tp1 x]>(<[j:=tele_app tp2 y]>ps)))) -∗
+  iProto_consistent ps.
+Proof.
+  iIntros "[H' H]".
+  rewrite iProto_consistent_unfold.
+  iFrame.
+  iIntros (i j m1 m2) "Hm1 Hm2".
+  iDestruct ("H" with "Hm1 Hm2")
+    as (m1' m2' TT1 TT2 tv1 tP1 tp1 tv2 tP2 tp2)
+         "(Heq1 & Heq2& %Hm1' & %Hm2' & H)".
+  rewrite !iProto_message_equivI.
+  iDestruct "Heq1" as "[_ Heq1]".
+  iDestruct "Heq2" as "[_ Heq2]".
+  iIntros (v p1) "Hm1".
+  iSpecialize ("Heq1" $! v (Next p1)).
+  iRewrite -"Heq1" in "Hm1".
+  rewrite Hm1'.
+  rewrite iMsg_base_eq. rewrite iMsg_texist_exist.
+  iDestruct "Hm1" as (x Htv1) "[Hp1 HP1]".
+  iDestruct ("H" with "HP1") as (y Htv2) "[HP2 H]".
+  iExists (tele_app tp2 y).
+  iSpecialize ("Heq2" $! v (Next (tele_app tp2 y))).
+  iRewrite -"Heq2".
+  rewrite Hm2'. rewrite iMsg_base_eq. rewrite iMsg_texist_exist.
+  iSplitL "HP2".
+  { iExists y. iFrame.
+    iSplit; [|done].
+    iPureIntro. subst. done. }
+  iNext. iRewrite -"Hp1". done.
+Qed.
+
+(* TODO: Improve automation *)
+Tactic Notation "iProto_consistent_take_step_step" :=
+  let i := fresh in
+  let j := fresh in
+  let m1 := fresh in
+  let m2 := fresh in
+  iIntros (i j m1 m2) "#Hm1 #Hm2";
+  repeat (destruct i as [|i];
+          [repeat (rewrite lookup_total_insert_ne; [|lia]);
+           try (by rewrite lookup_total_empty iProto_end_message_equivI);
+           try (rewrite lookup_total_insert;
+                try (by rewrite iProto_end_message_equivI);
+                iDestruct (iProto_message_equivI with "Hm1")
+                  as "[%Heq1 Hm1']";simplify_eq)|
+            repeat (rewrite lookup_total_insert_ne; [|lia]);
+            try (by rewrite lookup_total_empty iProto_end_message_equivI)]);
+  repeat (rewrite lookup_total_insert_ne; [|lia]);
+  try rewrite lookup_total_empty;
+  try (by iProto_end_message_equivI);
+  rewrite lookup_total_insert;
+  iDestruct (iProto_message_equivI with "Hm2")
+    as "[%Heq2 Hm2']";simplify_eq;
+  try (iClear "Hm1' Hm2'";
+       iExists _,_,_,_,_,_,_,_,_,_;
+       iSplitL "Hm1"; [iFrame "#"|];
+       iSplitL "Hm2"; [iFrame "#"|];
+       iSplit; [iPureIntro; tc_solve|];
+       iSplit; [iPureIntro; tc_solve|];
+       simpl; iClear "Hm1 Hm2"; clear m1 m2);
+  try (repeat (rewrite (insert_commute _ _ i); [|done]);
+  rewrite insert_insert;
+  repeat (rewrite (insert_commute _ _ j); [|done]);
+  rewrite insert_insert).
 
-(*   (* TODO: Why do the tactics not strip laters? *) *)
-(*   Lemma recv_test c p : *)
-(*     {{{ c ↣ (<(Recv,0) @(x:Z)> MSG #x ; p) }}} *)
-(*       recv c #0 *)
-(*     {{{ x, RET #x; c ↣ p }}}. *)
-(*   Proof. *)
-(*     iIntros (Φ) "Hc HΦ". *)
-(*     wp_recv (x) as "_". *)
-(*   Admitted. *)
+Tactic Notation "iProto_consistent_take_step_target" :=
+  let i := fresh in
+  iIntros (i j a m); rewrite /valid_target;
+            iIntros "#Hm";
+  repeat (destruct i as [|i];
+          [repeat (rewrite lookup_total_insert_ne; [|lia]);
+           try (by rewrite lookup_total_empty iProto_end_message_equivI);
+           try (rewrite lookup_total_insert;
+                try (by rewrite iProto_end_message_equivI);
+                iDestruct (iProto_message_equivI with "Hm1")
+                  as "[%Heq1 Hm1']";simplify_eq)|
+            repeat (rewrite lookup_total_insert_ne; [|lia]);
+            try (by rewrite lookup_total_empty iProto_end_message_equivI)]);
+  repeat (rewrite lookup_total_insert_ne; [|lia]);
+  try rewrite lookup_total_empty;
+  try (by iProto_end_message_equivI);
+  rewrite lookup_total_insert;
+  iDestruct (iProto_message_equivI with "Hm")
+    as "[%Heq Hm']";simplify_eq;
+  repeat (try rewrite lookup_empty;
+          try rewrite lookup_insert;
+          rewrite lookup_insert_ne; [|lia]);
+    try rewrite lookup_insert; try done.
 
-(*   Lemma send_test c p : *)
-(*     {{{ c ↣ (<(Send,0) @(x:Z)> MSG #x ; p) }}} *)
-(*       send c #0 #42 *)
-(*     {{{ x, RET #x; c ↣ p }}}. *)
-(*   Proof. *)
-(*     iIntros (Φ) "Hc HΦ". *)
-(*     wp_send (42%Z) with "[//]". *)
-(*   Admitted. *)
+Tactic Notation "iProto_consistent_take_step" :=
+  try iNext;
+  iApply iProto_consistent_equiv_proof;
+  iSplitR; [iProto_consistent_take_step_target|
+             iProto_consistent_take_step_step].
 
-(* End channel. *)
+Tactic Notation "clean_map" constr(i) :=
+  iEval (repeat (rewrite (insert_commute _ _ i); [|done]));
+  rewrite (insert_insert _ i).
diff --git a/multi_actris/channel/proto_consistency_examples.v b/multi_actris/channel/proto_consistency_examples.v
index 14771d2..0583fb2 100644
--- a/multi_actris/channel/proto_consistency_examples.v
+++ b/multi_actris/channel/proto_consistency_examples.v
@@ -1,124 +1,6 @@
-From iris.algebra Require Import gmap excl_auth gmap_view.
-From iris.proofmode Require Import proofmode.
-From iris.base_logic Require Export lib.iprop.
-From iris.base_logic Require Import lib.own.
 From multi_actris.channel Require Import proofmode.
 Set Default Proof Using "Type".
 
-Lemma iProto_consistent_equiv_proof {Σ} (ps : gmap nat (iProto Σ)) :
-  (∀ i j, valid_target ps i j) ∗
-  (∀ i j m1 m2,
-     (ps !!! i ≡ (<(Send, j)> m1)%proto) -∗
-     (ps !!! j ≡ (<(Recv, i)> m2)%proto) -∗
-     ∃ m1' m2' (TT1:tele) (TT2:tele) tv1 tP1 tp1 tv2 tP2 tp2,
-       (<(Send, j)> m1')%proto ≡ (<(Send, j)> m1)%proto ∗
-       (<(Recv, i)> m2')%proto ≡ (<(Recv, i)> m2)%proto ∗
-       ⌜MsgTele (TT:=TT1) m1' tv1 tP1 tp1⌝ ∗
-       ⌜MsgTele (TT:=TT2) m2' tv2 tP2 tp2⌝ ∗
-   ∀.. (x : TT1), tele_app tP1 x -∗
-   ∃.. (y : TT2), ⌜tele_app tv1 x = tele_app tv2 y⌝ ∗
-                  tele_app tP2 y ∗
-                  â–· (iProto_consistent
-                       (<[i:=tele_app tp1 x]>(<[j:=tele_app tp2 y]>ps)))) -∗
-  iProto_consistent ps.
-Proof.
-  iIntros "[H' H]".
-  rewrite iProto_consistent_unfold.
-  iFrame.
-  iIntros (i j m1 m2) "Hm1 Hm2".
-  iDestruct ("H" with "Hm1 Hm2")
-    as (m1' m2' TT1 TT2 tv1 tP1 tp1 tv2 tP2 tp2)
-         "(Heq1 & Heq2& %Hm1' & %Hm2' & H)".
-  rewrite !iProto_message_equivI.
-  iDestruct "Heq1" as "[_ Heq1]".
-  iDestruct "Heq2" as "[_ Heq2]".
-  iIntros (v p1) "Hm1".
-  iSpecialize ("Heq1" $! v (Next p1)).
-  iRewrite -"Heq1" in "Hm1".
-  rewrite Hm1'.
-  rewrite iMsg_base_eq. rewrite iMsg_texist_exist.
-  iDestruct "Hm1" as (x Htv1) "[Hp1 HP1]".
-  iDestruct ("H" with "HP1") as (y Htv2) "[HP2 H]".
-  iExists (tele_app tp2 y).
-  iSpecialize ("Heq2" $! v (Next (tele_app tp2 y))).
-  iRewrite -"Heq2".
-  rewrite Hm2'. rewrite iMsg_base_eq. rewrite iMsg_texist_exist.
-  iSplitL "HP2".
-  { iExists y. iFrame.
-    iSplit; [|done].
-    iPureIntro. subst. done. }
-  iNext. iRewrite -"Hp1". done.
-Qed.
-
-(* TODO: Improve automation *)
-(* Could clean up repeated inserts to save traverses *)
-Tactic Notation "iProto_consistent_take_step_step" :=
-  let i := fresh in
-  let j := fresh in
-  let m1 := fresh in
-  let m2 := fresh in
-  iIntros (i j m1 m2) "#Hm1 #Hm2";
-  repeat (destruct i as [|i];
-          [repeat (rewrite lookup_total_insert_ne; [|lia]);
-           try (by rewrite lookup_total_empty iProto_end_message_equivI);
-           try (rewrite lookup_total_insert;
-                try (by rewrite iProto_end_message_equivI);
-                iDestruct (iProto_message_equivI with "Hm1")
-                  as "[%Heq1 Hm1']";simplify_eq)|
-            repeat (rewrite lookup_total_insert_ne; [|lia]);
-            try (by rewrite lookup_total_empty iProto_end_message_equivI)]);
-  repeat (rewrite lookup_total_insert_ne; [|lia]);
-  try rewrite lookup_total_empty;
-  try (by iProto_end_message_equivI);
-  rewrite lookup_total_insert;
-  iDestruct (iProto_message_equivI with "Hm2")
-    as "[%Heq2 Hm2']";simplify_eq;
-  try (iClear "Hm1' Hm2'";
-       iExists _,_,_,_,_,_,_,_,_,_;
-       iSplitL "Hm1"; [iFrame "#"|];
-       iSplitL "Hm2"; [iFrame "#"|];
-       iSplit; [iPureIntro; tc_solve|];
-       iSplit; [iPureIntro; tc_solve|];
-       simpl; iClear "Hm1 Hm2"; clear m1 m2);
-  try (repeat (rewrite (insert_commute _ _ i); [|done]);
-  rewrite insert_insert;
-  repeat (rewrite (insert_commute _ _ j); [|done]);
-  rewrite insert_insert).
-
-Tactic Notation "iProto_consistent_take_step_target" :=
-  let i := fresh in
-  iIntros (i j a m); rewrite /valid_target;
-            iIntros "#Hm";
-  repeat (destruct i as [|i];
-          [repeat (rewrite lookup_total_insert_ne; [|lia]);
-           try (by rewrite lookup_total_empty iProto_end_message_equivI);
-           try (rewrite lookup_total_insert;
-                try (by rewrite iProto_end_message_equivI);
-                iDestruct (iProto_message_equivI with "Hm1")
-                  as "[%Heq1 Hm1']";simplify_eq)|
-            repeat (rewrite lookup_total_insert_ne; [|lia]);
-            try (by rewrite lookup_total_empty iProto_end_message_equivI)]);
-  repeat (rewrite lookup_total_insert_ne; [|lia]);
-  try rewrite lookup_total_empty;
-  try (by iProto_end_message_equivI);
-  rewrite lookup_total_insert;
-  iDestruct (iProto_message_equivI with "Hm")
-    as "[%Heq Hm']";simplify_eq;
-  repeat (try rewrite lookup_empty;
-          try rewrite lookup_insert;
-          rewrite lookup_insert_ne; [|lia]);
-    try rewrite lookup_insert; try done.
-
-Tactic Notation "iProto_consistent_take_step" :=
-  try iNext;
-  iApply iProto_consistent_equiv_proof;
-  iSplitR; [iProto_consistent_take_step_target|
-             iProto_consistent_take_step_step].
-
-Tactic Notation "clean_map" constr(i) :=
-  iEval (repeat (rewrite (insert_commute _ _ i); [|done]));
-  rewrite (insert_insert _ i).
-
 Definition iProto_empty {Σ} : gmap nat (iProto Σ) := ∅.
 
 Lemma iProto_consistent_empty {Σ} :
-- 
GitLab