Skip to content
Snippets Groups Projects
Commit 9524aefb authored by Robbert Krebbers's avatar Robbert Krebbers
Browse files

Add an ordering to protocols and allow protocol ownership to be weakened.

This idea is taken from the paper "Towards a session logic for
communication protocols" by Cracium et al.
parent 0eb2c8f4
No related branches found
No related tags found
No related merge requests found
Pipeline #21203 passed
...@@ -196,7 +196,24 @@ Infix "<++>" := iProto_app (at level 60) : proto_scope. ...@@ -196,7 +196,24 @@ Infix "<++>" := iProto_app (at level 60) : proto_scope.
Definition proto_eq_next {Σ} (p : iProto Σ) : laterO (iProto Σ) -n> iPropO Σ := Definition proto_eq_next {Σ} (p : iProto Σ) : laterO (iProto Σ) -n> iPropO Σ :=
OfeMor (sbi_internal_eq (Next p)). OfeMor (sbi_internal_eq (Next p)).
Fixpoint proto_interp `{!proto_chanG Σ} (vs : list val) (p1 p2 : iProto Σ) : iProp Σ := Program Definition iProto_le_aux {Σ} (rec : iProto Σ -n> iProto Σ -n> iPropO Σ) :
iProto Σ -n> iProto Σ -n> iPropO Σ := λne p1 p2,
((p1 proto_end p2 proto_end)
( pc1 pc2,
p1 proto_message Send pc1 p2 proto_message Send pc2
v p2', pc2 v (proto_eq_next p2') -∗
p1', rec p1' p2' pc1 v (proto_eq_next p1'))
( pc1 pc2,
p1 proto_message Receive pc1 p2 proto_message Receive pc2
v p1', pc1 v (proto_eq_next p1') -∗
p2', rec p1' p2' pc2 v (proto_eq_next p2')))%I.
Solve Obligations with solve_proper.
Local Instance iProto_le_aux_contractive {Σ} : Contractive (@iProto_le_aux Σ).
Proof. solve_contractive. Qed.
Definition iProto_le {Σ} (p1 p2 : iProto Σ) : iPropO Σ :=
fixpoint iProto_le_aux p1 p2.
Fixpoint proto_interp {Σ} (vs : list val) (p1 p2 : iProto Σ) : iProp Σ :=
match vs with match vs with
| [] => iProto_dual p1 p2 | [] => iProto_dual p1 p2
| v :: vs => pc p2', | v :: vs => pc p2',
...@@ -204,7 +221,7 @@ Fixpoint proto_interp `{!proto_chanG Σ} (vs : list val) (p1 p2 : iProto Σ) : i ...@@ -204,7 +221,7 @@ Fixpoint proto_interp `{!proto_chanG Σ} (vs : list val) (p1 p2 : iProto Σ) : i
pc v (proto_eq_next p2') pc v (proto_eq_next p2')
proto_interp vs p1 p2' proto_interp vs p1 p2'
end%I. end%I.
Arguments proto_interp {_ _} _ _%proto _%proto : simpl nomatch. Arguments proto_interp {_} _ _%proto _%proto : simpl nomatch.
Record proto_name := ProtName { Record proto_name := ProtName {
proto_c_name : chan_name; proto_c_name : chan_name;
...@@ -212,7 +229,7 @@ Record proto_name := ProtName { ...@@ -212,7 +229,7 @@ Record proto_name := ProtName {
proto_r_name : gname proto_r_name : gname
}. }.
Definition to_proto_auth_excl `{!proto_chanG Σ} (p : iProto Σ) := Definition to_proto_auth_excl {Σ} (p : iProto Σ) :=
to_auth_excl (Next (proto_map id iProp_fold iProp_unfold p)). to_auth_excl (Next (proto_map id iProp_fold iProp_unfold p)).
Definition proto_own_frag `{!proto_chanG Σ} (γ : proto_name) (s : side) Definition proto_own_frag `{!proto_chanG Σ} (γ : proto_name) (s : side)
...@@ -237,9 +254,12 @@ Definition protoN := nroot .@ "proto". ...@@ -237,9 +254,12 @@ Definition protoN := nroot .@ "proto".
(** * The connective for ownership of channel ends *) (** * The connective for ownership of channel ends *)
Definition mapsto_proto_def `{!proto_chanG Σ, !heapG Σ} Definition mapsto_proto_def `{!proto_chanG Σ, !heapG Σ}
(c : val) (p : iProto Σ) : iProp Σ := (c : val) (p : iProto Σ) : iProp Σ :=
( s (c1 c2 : val) γ, ( s (c1 c2 : val) γ p',
c = side_elim s c1 c2 c = side_elim s c1 c2
proto_own_frag γ s p is_chan protoN (proto_c_name γ) c1 c2 inv protoN (proto_inv γ))%I. iProto_le p' p
proto_own_frag γ s p'
is_chan protoN (proto_c_name γ) c1 c2
inv protoN (proto_inv γ))%I.
Definition mapsto_proto_aux : seal (@mapsto_proto_def). by eexists. Qed. Definition mapsto_proto_aux : seal (@mapsto_proto_def). by eexists. Qed.
Definition mapsto_proto {Σ } := mapsto_proto_aux.(unseal) Σ . Definition mapsto_proto {Σ } := mapsto_proto_aux.(unseal) Σ .
Definition mapsto_proto_eq : @mapsto_proto = @mapsto_proto_def := mapsto_proto_aux.(seal_eq). Definition mapsto_proto_eq : @mapsto_proto = @mapsto_proto_def := mapsto_proto_aux.(seal_eq).
...@@ -379,13 +399,143 @@ Section proto. ...@@ -379,13 +399,143 @@ Section proto.
iProto_dual (p1 <++> p2) (iProto_dual p1 <++> iProto_dual p2)%proto. iProto_dual (p1 <++> p2) (iProto_dual p1 <++> iProto_dual p2)%proto.
Proof. by rewrite /iProto_dual /iProto_app proto_map_app. Qed. Proof. by rewrite /iProto_dual /iProto_app proto_map_app. Qed.
(** ** Protocol entailment **)
Global Instance iProto_le_ne : NonExpansive2 (@iProto_le Σ).
Proof. solve_proper. Qed.
Global Instance iProto_le_proper : Proper (() ==> () ==> (⊣⊢)) (@iProto_le Σ).
Proof. solve_proper. Qed.
Lemma iProto_le_unfold p1 p2 :
iProto_le p1 p2 iProto_le_aux (fixpoint iProto_le_aux) p1 p2.
Proof. apply: (fixpoint_unfold iProto_le_aux). Qed.
Lemma iProto_le_refl p : iProto_le p p.
Proof.
iLöb as "IH" forall (p). destruct (proto_case p) as [->|([]&pc&->)].
- rewrite iProto_le_unfold. iLeft; by auto.
- rewrite iProto_le_unfold. iRight; iLeft. iExists _, _; do 2 (iSplit; [done|]).
iIntros (v p') "Hpc". iExists p'. iFrame "Hpc". iNext. iApply "IH".
- rewrite iProto_le_unfold. iRight; iRight. iExists _, _; do 2 (iSplit; [done|]).
iIntros (v p') "Hpc". iExists p'. iFrame "Hpc". iNext. iApply "IH".
Qed.
Lemma iProto_le_end_inv p : iProto_le p proto_end -∗ p proto_end.
Proof.
rewrite iProto_le_unfold. iIntros "[[Hp _]|H] //".
iDestruct "H" as "[H|H]"; iDestruct "H" as (pc1 pc2) "(_ & Heq & _)";
by rewrite proto_end_message_equivI.
Qed.
Lemma iProto_le_send_inv p1 pc2 :
iProto_le p1 (proto_message Send pc2) -∗ pc1,
p1 proto_message Send pc1
v p2', pc2 v (proto_eq_next p2') -∗
p1', iProto_le p1' p2' pc1 v (proto_eq_next p1').
Proof.
rewrite iProto_le_unfold. iIntros "[[_ Heq]|[H|H]]".
- by rewrite proto_message_end_equivI.
- iDestruct "H" as (pc1 pc2') "(Hp1 & Heq & H)".
iDestruct (proto_message_equivI with "Heq") as "[_ #Heq]".
iExists pc1. iIntros "{$Hp1}" (v p2') "Hpc".
iSpecialize ("Heq" $! v). iDestruct (bi.ofe_morO_equivI with "Heq") as "Heq'".
iRewrite ("Heq'" $! (proto_eq_next p2')) in "Hpc". by iApply "H".
- iDestruct "H" as (pc1 pc2') "(_ & Heq & _)".
by iDestruct (proto_message_equivI with "Heq") as "[% ?]".
Qed.
Lemma iProto_le_recv_inv p1 pc2 :
iProto_le p1 (proto_message Receive pc2) -∗ pc1,
p1 proto_message Receive pc1
v p1', pc1 v (proto_eq_next p1') -∗
p2', iProto_le p1' p2' pc2 v (proto_eq_next p2').
Proof.
rewrite iProto_le_unfold. iIntros "[[_ Heq]|[H|H]]".
- by rewrite proto_message_end_equivI.
- iDestruct "H" as (pc1 pc2') "(_ & Heq & _)".
by iDestruct (proto_message_equivI with "Heq") as "[% ?]".
- iDestruct "H" as (pc1 pc2') "(Hp1 & Heq & H)".
iDestruct (proto_message_equivI with "Heq") as "[_ #Heq]".
iExists pc1. iIntros "{$Hp1}" (v p1') "Hpc".
iSpecialize ("Heq" $! v). iDestruct (bi.ofe_morO_equivI with "Heq") as "Heq'".
iDestruct ("H" with "Hpc") as (p2') "[Hle Hpc]".
iExists p2'. iFrame "Hle". by iRewrite ("Heq'" $! (proto_eq_next p2')).
Qed.
Lemma iProto_le_trans p1 p2 p3 :
iProto_le p1 p2 -∗ iProto_le p2 p3 -∗ iProto_le p1 p3.
Proof.
iIntros "H1 H2". iLöb as "IH" forall (p1 p2 p3).
destruct (proto_case p3) as [->|([]&pc3&->)].
- rewrite iProto_le_end_inv. by iRewrite "H2" in "H1".
- iDestruct (iProto_le_send_inv with "H2") as (pc2) "[Hp2 H3]".
iRewrite "Hp2" in "H1".
iDestruct (iProto_le_send_inv with "H1") as (pc1) "[Hp1 H2]".
iRewrite "Hp1". rewrite iProto_le_unfold; iRight; iLeft.
iExists _, _; do 2 (iSplit; [done|]).
iIntros (v p3') "Hpc".
iDestruct ("H3" with "Hpc") as (p2') "[Hle Hpc]".
iDestruct ("H2" with "Hpc") as (p1') "[Hle' Hpc]".
iExists p1'. iIntros "{$Hpc} !>". by iApply ("IH" with "Hle'").
- iDestruct (iProto_le_recv_inv with "H2") as (pc2) "[Hp2 H3]".
iRewrite "Hp2" in "H1".
iDestruct (iProto_le_recv_inv with "H1") as (pc1) "[Hp1 H2]".
iRewrite "Hp1". rewrite iProto_le_unfold; iRight; iRight.
iExists _, _; do 2 (iSplit; [done|]).
iIntros (v p1') "Hpc".
iDestruct ("H2" with "Hpc") as (p2') "[Hle Hpc]".
iDestruct ("H3" with "Hpc") as (p3') "[Hle' Hpc]".
iExists p3'. iIntros "{$Hpc} !>". by iApply ("IH" with "Hle").
Qed.
Lemma iProto_send_le {TT1 TT2} (pc1 : TT1 val * iProp Σ * iProto Σ)
(pc2 : TT2 val * iProp Σ * iProto Σ) :
(.. x2 : TT2, .. x1 : TT1,
(pc1 x1).1.1 = (pc2 x2).1.1
((pc2 x2).1.2 -∗ (pc1 x1).1.2)
iProto_le (pc1 x1).2 (pc2 x2).2) -∗
iProto_le (iProto_message Send pc1) (iProto_message Send pc2).
Proof.
iIntros "H". rewrite iProto_le_unfold iProto_message_eq. iRight; iLeft.
iExists _, _; do 2 (iSplit; [done|]).
iIntros (v p2') "/=". iDestruct 1 as (x2 ->) "[Hpc2 #Heq]".
iDestruct ("H" $! x2) as (x1 ?) "[Hpc Hle]". iExists (pc1 x1).2. iSplitL "Hle".
{ iNext. change (fixpoint iProto_le_aux ?p1 ?p2) with (iProto_le p1 p2).
by iRewrite "Heq". }
iExists x1. iSplit; [done|]. iSplit; [by iApply "Hpc"|done].
Qed.
Lemma iProto_recv_le {TT1 TT2} (pc1 : TT1 val * iProp Σ * iProto Σ)
(pc2 : TT2 val * iProp Σ * iProto Σ) :
(.. x1 : TT1, .. x2 : TT2,
(pc1 x1).1.1 = (pc2 x2).1.1
((pc1 x1).1.2 -∗ (pc2 x2).1.2)
iProto_le (pc1 x1).2 (pc2 x2).2) -∗
iProto_le (iProto_message Receive pc1) (iProto_message Receive pc2).
Proof.
iIntros "H". rewrite iProto_le_unfold iProto_message_eq. iRight; iRight.
iExists _, _; do 2 (iSplit; [done|]).
iIntros (v p1') "/=". iDestruct 1 as (x1 ->) "[Hpc1 #Heq]".
iDestruct ("H" $! x1) as (x2 ?) "[Hpc Hle]". iExists (pc2 x2).2. iSplitL "Hle".
{ iNext. change (fixpoint iProto_le_aux ?p1 ?p2) with (iProto_le p1 p2).
by iRewrite "Heq". }
iExists x2. iSplit; [done|]. iSplit; [by iApply "Hpc"|done].
Qed.
Lemma iProto_mapsto_le c p1 p2 : c p1 -∗ iProto_le p1 p2 -∗ c p2.
Proof.
rewrite mapsto_proto_eq. iDestruct 1 as (s c1 c2 γ p1' ->) "[Hle H]".
iIntros "Hle'". iExists s, c1, c2, γ, p1'. iSplit; first done. iFrame "H".
by iApply (iProto_le_trans with "Hle").
Qed.
(** ** Auxiliary definitions and invariants *) (** ** Auxiliary definitions and invariants *)
Global Instance proto_interp_ne : NonExpansive2 (proto_interp vs). Global Instance proto_interp_ne : NonExpansive2 (proto_interp (Σ:=Σ) vs).
Proof. induction vs; solve_proper. Qed. Proof. induction vs; solve_proper. Qed.
Global Instance proto_interp_proper vs : Proper (() ==> () ==> ()) (proto_interp vs). Global Instance proto_interp_proper vs :
Proper (() ==> () ==> ()) (proto_interp (Σ:=Σ) vs).
Proof. apply (ne_proper_2 _). Qed. Proof. apply (ne_proper_2 _). Qed.
Global Instance to_proto_auth_excl_ne : NonExpansive to_proto_auth_excl. Global Instance to_proto_auth_excl_ne : NonExpansive (to_proto_auth_excl (Σ:=Σ)).
Proof. solve_proper. Qed. Proof. solve_proper. Qed.
Global Instance proto_own_ne γ s : NonExpansive (proto_own_frag γ s). Global Instance proto_own_ne γ s : NonExpansive (proto_own_frag γ s).
Proof. solve_proper. Qed. Proof. solve_proper. Qed.
...@@ -484,8 +634,10 @@ Section proto. ...@@ -484,8 +634,10 @@ Section proto.
iMod (inv_alloc protoN _ (proto_inv ) with "[-Hlstf Hrstf Hcctx]") as "#Hinv". iMod (inv_alloc protoN _ (proto_inv ) with "[-Hlstf Hrstf Hcctx]") as "#Hinv".
{ iNext. rewrite /proto_inv. eauto 10 with iFrame. } { iNext. rewrite /proto_inv. eauto 10 with iFrame. }
iModIntro. rewrite mapsto_proto_eq. iSplitL "Hlstf". iModIntro. rewrite mapsto_proto_eq. iSplitL "Hlstf".
- iExists Left, c1, c2, ; iFrame; auto. - iExists Left, c1, c2, , p.
- iExists Right, c1, c2, ; iFrame; auto. iFrame "Hlstf Hinv Hcctx". iSplit; [done|]. iApply iProto_le_refl.
- iExists Right, c1, c2, , (iProto_dual p).
iFrame "Hrstf Hinv Hcctx". iSplit; [done|]. iApply iProto_le_refl.
Qed. Qed.
(** ** Accessor style lemmas *) (** ** Accessor style lemmas *)
...@@ -501,47 +653,49 @@ Section proto. ...@@ -501,47 +653,49 @@ Section proto.
c (pc x).2. c (pc x).2.
Proof. Proof.
iIntros (?). rewrite {1}mapsto_proto_eq iProto_message_eq. iIntros (?). rewrite {1}mapsto_proto_eq iProto_message_eq.
iDestruct 1 as (s c1 c2 γ ->) "[Hstf #[Hcctx Hinv]]". iDestruct 1 as (s c1 c2 γ p ->) "(Hle & Hst & #[Hcctx Hinv])".
iExists s, c1, c2, γ. iSplit; first done. iFrame "Hcctx". iExists s, c1, c2, γ. iSplit; first done. iFrame "Hcctx".
iInv protoN as (l r pl pr) "(>Hclf & >Hcrf & Hstla & Hstra & Hinv')" "Hclose". iInv protoN as (l r pl pr) "(>Hcl & >Hcr & Hstla & Hstra & Hinv')" "Hclose".
(* TODO: refactor to avoid twice nearly the same proof *) (* TODO: refactor to avoid twice nearly the same proof *)
iModIntro. destruct s. iModIntro. destruct s.
- iExists _. - iExists _.
iIntros "{$Hclf} !>" (x) "HP Hclf". iIntros "{$Hcl} !>" (x) "HP Hcl".
iRename "Hstf" into "Hstlf". iDestruct (iProto_le_send_inv with "Hle") as (pc') "[Hp H] /=".
iDestruct (proto_own_auth_agree with "Hstla Hstlf") as "#Heq". iRewrite "Hp" in "Hst"; clear p.
iMod (proto_own_auth_update _ _ _ _ (pc x).2 iDestruct ("H" with "[HP]") as (p1') "[Hle HP]".
with "Hstla Hstlf") as "[Hstla Hstlf]". { iExists _. iFrame "HP". by iSplit. }
iMod ("Hclose" with "[-Hstlf]") as "_". iDestruct (proto_own_auth_agree with "Hstla Hst") as "#Heq".
{ iNext. iExists _,_,_,_. iFrame "Hcrf Hstra Hstla Hclf". iLeft. iMod (proto_own_auth_update _ _ _ _ p1' with "Hstla Hst") as "[Hstla Hst]".
iMod ("Hclose" with "[-Hst Hle]") as "_".
{ iNext. iExists _,_,_,_. iFrame "Hcr Hstra Hstla Hcl". iLeft.
iRewrite "Heq" in "Hinv'". iRewrite "Heq" in "Hinv'".
iDestruct "Hinv'" as "[[-> Heval]|[-> Heval]]". iDestruct "Hinv'" as "[[-> Heval]|[-> Heval]]".
{ iSplit=> //. iApply (proto_interp_send with "Heval [HP]"); simpl. { iSplit=> //. by iApply (proto_interp_send with "Heval [HP]"). }
iExists x. by iFrame. }
destruct r as [|vr r]; last first. destruct r as [|vr r]; last first.
{ iDestruct (proto_interp_False with "Heval") as %[]. } { iDestruct (proto_interp_False with "Heval") as %[]. }
iSplit; first done; simpl. iRewrite (proto_interp_nil with "Heval"). iSplit; first done; simpl. iRewrite (proto_interp_nil with "Heval").
iApply (proto_interp_send _ [] with "[//] [HP]"). iApply (proto_interp_send _ [] with "[//] HP"). }
iExists x. by iFrame. } iModIntro. rewrite mapsto_proto_eq. iExists Left, c1, c2, γ, p1'.
iModIntro. rewrite mapsto_proto_eq. iExists Left, c1, c2, γ. iFrame; auto. by iFrame "Hcctx Hinv Hst Hle".
- iExists _. - iExists _.
iIntros "{$Hcrf} !>" (x) "HP Hcrf". iIntros "{$Hcr} !>" (x) "HP Hcr".
iRename "Hstf" into "Hstrf". iDestruct (iProto_le_send_inv with "Hle") as (pc') "[Hp H] /=".
iDestruct (proto_own_auth_agree with "Hstra Hstrf") as "#Heq". iRewrite "Hp" in "Hst"; clear p.
iMod (proto_own_auth_update _ _ _ _ (pc x).2 iDestruct ("H" with "[HP]") as (p1') "[Hle HP]".
with "Hstra Hstrf") as "[Hstra Hstrf]". { iExists _. iFrame "HP". by iSplit. }
iMod ("Hclose" with "[-Hstrf]") as "_". iDestruct (proto_own_auth_agree with "Hstra Hst") as "#Heq".
{ iNext. iExists _, _, _, _. iFrame "Hcrf Hstra Hstla Hclf". iRight. iMod (proto_own_auth_update _ _ _ _ p1' with "Hstra Hst") as "[Hstra Hst]".
iMod ("Hclose" with "[-Hst Hle]") as "_".
{ iNext. iExists _, _, _, _. iFrame "Hcl Hstra Hstla Hcr". iRight.
iRewrite "Heq" in "Hinv'". iRewrite "Heq" in "Hinv'".
iDestruct "Hinv'" as "[[-> Heval]|[-> Heval]]"; last first. iDestruct "Hinv'" as "[[-> Heval]|[-> Heval]]"; last first.
{ iSplit=> //. iApply (proto_interp_send with "Heval [HP]"); simpl. { iSplit=> //. by iApply (proto_interp_send with "Heval [HP]"). }
iExists x. by iFrame. }
destruct l as [|vl l]; last first. destruct l as [|vl l]; last first.
{ iDestruct (proto_interp_False with "Heval") as %[]. } { iDestruct (proto_interp_False with "Heval") as %[]. }
iSplit; first done; simpl. iRewrite (proto_interp_nil with "Heval"). iSplit; first done; simpl. iRewrite (proto_interp_nil with "Heval").
iApply (proto_interp_send _ [] with "[//] [HP]"). iApply (proto_interp_send _ [] with "[//] HP"). }
iExists x. by iFrame. } iModIntro. rewrite mapsto_proto_eq. iExists Right, c1, c2, γ, p1'.
iModIntro. rewrite mapsto_proto_eq. iExists Right, c1, c2, γ. iFrame; auto. by iFrame "Hcctx Hinv Hst Hle".
Qed. Qed.
Lemma proto_recv_acc {TT} E c (pc : TT val * iProp Σ * iProto Σ) : Lemma proto_recv_acc {TT} E c (pc : TT val * iProp Σ * iProto Σ) :
...@@ -558,60 +712,65 @@ Section proto. ...@@ -558,60 +712,65 @@ Section proto.
v = (pc x).1.1 c (pc x).2 (pc x).1.2)). v = (pc x).1.1 c (pc x).2 (pc x).1.2)).
Proof. Proof.
iIntros (?). rewrite {1}mapsto_proto_eq iProto_message_eq. iIntros (?). rewrite {1}mapsto_proto_eq iProto_message_eq.
iDestruct 1 as (s c1 c2 γ ->) "[Hstf #[Hcctx Hinv]]". iDestruct 1 as (s c1 c2 γ p ->) "(Hle & Hst & #[Hcctx Hinv])".
iDestruct (iProto_le_recv_inv with "Hle") as (pc') "[Hp Hle]".
iExists (side_elim s Right Left), c1, c2, γ. iSplit; first by destruct s. iExists (side_elim s Right Left), c1, c2, γ. iSplit; first by destruct s.
iFrame "Hcctx". iFrame "Hcctx".
iInv protoN as (l r pl pr) "(>Hclf & >Hcrf & Hstla & Hstra & Hinv')" "Hclose". iInv protoN as (l r pl pr) "(>Hcl & >Hcr & Hstla & Hstra & Hinv')" "Hclose".
iExists (side_elim s r l). iModIntro. iExists (side_elim s r l). iModIntro.
(* TODO: refactor to avoid twice nearly the same proof *) (* TODO: refactor to avoid twice nearly the same proof *)
destruct s; simpl. destruct s; simpl.
- iIntros "{$Hcrf} !>". - iIntros "{$Hcr} !>". iRewrite "Hp" in "Hst". clear p.
iRename "Hstf" into "Hstlf". iDestruct (proto_own_auth_agree with "Hstla Hst") as "#Heq".
iDestruct (proto_own_auth_agree with "Hstla Hstlf") as "#Heq".
iSplit. iSplit.
+ iIntros "Hown". + iIntros "Hcr".
iMod ("Hclose" with "[-Hstlf]") as "_". iMod ("Hclose" with "[-Hst Hle]") as "_".
{ iNext. iExists l, r, _, _. iFrame. } { iNext. iExists l, r, _, _. iFrame. }
iModIntro. rewrite mapsto_proto_eq. iModIntro. rewrite mapsto_proto_eq.
iExists Left, c1, c2, γ. by iFrame "Hcctx ∗ Hinv". iExists Left, c1, c2, γ, (proto_message Receive pc').
+ iIntros (v vs ->) "Hown". iFrame "Hcctx Hinv Hst". iSplit; first done.
rewrite iProto_le_unfold. iModIntro. iRight; auto 10.
+ iIntros (v vs ->) "Hcr".
iDestruct "Hinv'" as "[[>% _]|[> -> Heval]]"; first done. iDestruct "Hinv'" as "[[>% _]|[> -> Heval]]"; first done.
iAssert ( proto_interp (v :: vs) pr (iProto_message_def Receive pc))%I iAssert ( proto_interp (v :: vs) pr (proto_message Receive pc'))%I
with "[Heval]" as "Heval". with "[Heval]" as "Heval".
{ iNext. by iRewrite "Heq" in "Heval". } { iNext. by iRewrite "Heq" in "Heval". }
iDestruct (proto_interp_recv with "Heval") as (q) "[Hf Heval]". iDestruct (proto_interp_recv with "Heval") as (q) "[Hpc Heval]".
iMod (proto_own_auth_update _ _ _ _ q with "Hstla Hstlf") as "[Hstla Hstlf]". iMod (proto_own_auth_update _ _ _ _ q with "Hstla Hst") as "[Hstla Hst]".
iMod ("Hclose" with "[-Hstlf Hf]") as %_. iMod ("Hclose" with "[-Hst Hpc Hle]") as %_.
{ iExists _, _,_ ,_. eauto 10 with iFrame. } { iExists _, _,_ ,_; iFrame; eauto. }
iIntros "!> !> /=". iIntros "!> !> /=".
iDestruct "Hf" as (x) "(Hv & HP & #Hf) /=". iDestruct ("Hle" with "Hpc") as (q') "[Hle H]".
iDestruct "H" as (x) "(Hv & HP & #Hf) /=".
iNext. iExists x. iFrame "Hv HP". iRewrite -"Hf". iNext. iExists x. iFrame "Hv HP". iRewrite -"Hf".
rewrite mapsto_proto_eq. iExists Left, c1, c2, γ. iFrame; auto. rewrite mapsto_proto_eq. iExists Left, c1, c2, γ, q. iFrame; auto.
- iIntros "{$Hclf} !>". - iIntros "{$Hcl} !>". iRewrite "Hp" in "Hst". clear p.
iRename "Hstf" into "Hstrf". iDestruct (proto_own_auth_agree with "Hstra Hst") as "#Heq".
iDestruct (proto_own_auth_agree with "Hstra Hstrf") as "#Heq".
iSplit. iSplit.
+ iIntros "Hown". + iIntros "Hcl".
iMod ("Hclose" with "[-Hstrf]") as "_". iMod ("Hclose" with "[-Hst Hle]") as "_".
{ iNext. iExists l, r, _, _. iFrame. } { iNext. iExists l, r, _, _. iFrame. }
iModIntro. rewrite mapsto_proto_eq. iModIntro. rewrite mapsto_proto_eq.
iExists Right, c1, c2, γ. by iFrame "Hcctx ∗ Hinv". iExists Right, c1, c2, γ, (proto_message Receive pc').
+ iIntros (v vs ->) "Hown". iFrame "Hcctx Hinv Hst". iSplit; first done.
rewrite iProto_le_unfold. iModIntro. iRight; auto 10.
+ iIntros (v vs ->) "Hcl".
iDestruct "Hinv'" as "[[>-> Heval]|[>% _]]"; last done. iDestruct "Hinv'" as "[[>-> Heval]|[>% _]]"; last done.
iAssert ( proto_interp (v :: vs) pl (iProto_message_def Receive pc))%I iAssert ( proto_interp (v :: vs) pl (proto_message Receive pc'))%I
with "[Heval]" as "Heval". with "[Heval]" as "Heval".
{ iNext. by iRewrite "Heq" in "Heval". } { iNext. by iRewrite "Heq" in "Heval". }
iDestruct (proto_interp_recv with "Heval") as (q) "[Hf Heval]". iDestruct (proto_interp_recv with "Heval") as (q) "[Hpc Heval]".
iMod (proto_own_auth_update _ _ _ _ q with "Hstra Hstrf") as "[Hstra Hstrf]". iMod (proto_own_auth_update _ _ _ _ q with "Hstra Hst") as "[Hstra Hst]".
iMod ("Hclose" with "[-Hstrf Hf]") as %_. iMod ("Hclose" with "[-Hst Hpc Hle]") as %_.
{ iExists _, _, _, _. eauto 10 with iFrame. } { iExists _, _, _, _. eauto 10 with iFrame. }
iIntros "!> !>". iIntros "!> !> /=".
iDestruct "Hf" as (x) "(Hv & HP & Hf) /=". iDestruct ("Hle" with "Hpc") as (q') "[Hle H]".
iDestruct "H" as (x) "(Hv & HP & Hf) /=".
iNext. iExists x. iFrame "Hv HP". iRewrite -"Hf". iNext. iExists x. iFrame "Hv HP". iRewrite -"Hf".
rewrite mapsto_proto_eq. iExists Right, c1, c2, γ. iFrame; auto. rewrite mapsto_proto_eq. iExists Right, c1, c2, γ, q. iFrame; auto.
Qed. Qed.
(** ** Specifications of [send] and [receive] *) (** ** Specifications of [send] and [recv] *)
Lemma new_chan_proto_spec : Lemma new_chan_proto_spec :
{{{ True }}} {{{ True }}}
new_chan #() new_chan #()
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment