From 9e8900afe97bd02d31441baa5974095cfe91f7e5 Mon Sep 17 00:00:00 2001
From: Ralf Jung <jung@mpi-sws.org>
Date: Thu, 13 Apr 2017 10:34:02 +0200
Subject: [PATCH] switch lock spec to be accessor-based

---
 _CoqProject                  |   1 +
 theories/lang/lib/lock.v     | 110 ++++++++++++++---------------------
 theories/lifetime/lifetime.v |   6 ++
 3 files changed, 51 insertions(+), 66 deletions(-)

diff --git a/_CoqProject b/_CoqProject
index 332e5c76..21c4898b 100644
--- a/_CoqProject
+++ b/_CoqProject
@@ -53,6 +53,7 @@ theories/typing/lib/fake_shared_box.v
 theories/typing/lib/cell.v
 theories/typing/lib/spawn.v
 theories/typing/lib/rc.v
+theories/typing/lib/mutex.v
 theories/typing/lib/refcell/refcell.v
 theories/typing/lib/refcell/ref.v
 theories/typing/lib/refcell/refmut.v
diff --git a/theories/lang/lib/lock.v b/theories/lang/lib/lock.v
index 848b58ce..001dbfb5 100644
--- a/theories/lang/lib/lock.v
+++ b/theories/lang/lib/lock.v
@@ -22,110 +22,88 @@ Proof. solve_inG. Qed.
 Section proof.
   Context `{!lrustG Σ, !lockG Σ} (N : namespace).
 
-  Definition lockname := (gname * gname)%type.
-
-  Definition lock_inv (γ : gname) (l : loc) (R : iProp Σ) : iProp Σ :=
+  Definition lock_proto (γ : gname) (l : loc) (R : iProp Σ) : iProp Σ :=
     (∃ b : bool, l ↦ #b ∗ if b then True else own γ (Excl ()) ∗ R)%I.
 
-  Definition is_lock (γ : lockname) (l : loc) (R : iProp Σ) : iProp Σ :=
-    cinv N (γ.1) (lock_inv (γ.2) l R).
-
-  Definition own_lock (γ : lockname) : frac → iProp Σ :=
-    cinv_own (γ.1).
+  Definition locked (γ : gname): iProp Σ := own γ (Excl ()).
 
-  Definition locked (γ : lockname): iProp Σ := own (γ.2) (Excl ()).
-
-  Global Instance lock_inv_ne γ l : NonExpansive (lock_inv γ l).
+  Global Instance lock_inv_ne γ l : NonExpansive (lock_proto γ l).
   Proof. solve_proper. Qed.
-  Global Instance is_lock_contractive γ l : Contractive (is_lock γ l).
-  Proof. solve_contractive. Qed.
-  Global Instance is_lock_ne γ l : NonExpansive (is_lock γ l).
-  Proof. exact: contractive_ne. Qed.
 
-  Global Instance is_lock_persistent γ l R : PersistentP (is_lock γ l R).
-  Proof. apply _. Qed.
   Global Instance locked_timeless γ : TimelessP (locked γ).
   Proof. apply _. Qed.
 
-  Lemma locked_exclusive (γ : lockname) : locked γ -∗ locked γ -∗ False.
+  Lemma locked_exclusive (γ : gname) : locked γ -∗ locked γ -∗ False.
   Proof. iIntros "H1 H2". by iDestruct (own_valid_2 with "H1 H2") as %?. Qed.
 
-  Lemma is_lock_iff γ l R R' :
-    □ ▷ (R ↔ R') -∗ is_lock γ l R -∗ is_lock γ l R'.
+  Lemma lock_proto_iff γ l R R' :
+    □ (R ↔ R') -∗ lock_proto γ l R -∗ lock_proto γ l R'.
   Proof.
-    iIntros "#HRR' Hlck". iApply cinv_iff; last done. iNext. iAlways.
-    iSplit; iIntros "Hinv"; iDestruct "Hinv" as (b) "[Hl HR]"; iExists b;
-      iFrame "Hl"; (destruct b; first done); iDestruct "HR" as "[$ HR]";
-      by iApply "HRR'".
+    iIntros "#HRR' Hlck". iDestruct "Hlck" as (b) "[Hl HR]". iExists b.
+    iFrame "Hl". destruct b; first done. iDestruct "HR" as "[$ HR]".
+    by iApply "HRR'".
   Qed.
 
   (** The main proofs. *)
-  Lemma newlock_inplace (E : coPset) (R : iProp Σ) l (b : bool) :
-    l ↦ #b -∗ (if b then True else ▷ R) ={E}=∗ ∃ γ, is_lock γ l R ∗ own_lock γ 1%Qp.
+  Lemma lock_proto_create (E : coPset) (R : iProp Σ) l (b : bool) :
+    l ↦ #b -∗ (if b then True else R) ={E}=∗ ∃ γ, lock_proto γ l R.
   Proof.
     iIntros "Hl HR".
     iMod (own_alloc (Excl ())) as (γ) "Hγ"; first done.
-    iMod (cinv_alloc _ N (lock_inv γ l R) with "[-]") as (γ') "Hlock".
-    { iExists b. destruct b; by iFrame. }
-    iModIntro. iExists (_, _). eauto.
-  Qed.
-
-  Lemma newlock_spec (R : iProp Σ) :
-    {{{ ▷ R }}} newlock [] {{{ l γ, RET #l; is_lock γ l R ∗ own_lock γ 1%Qp }}}.
-  Proof.
-    iIntros (Φ) "HR HΦ". iApply wp_fupd.
-    wp_seq. wp_alloc l vl as "Hl" "H†". inv_vec vl=>x.
-    rewrite heap_mapsto_vec_singleton. (* FIXME shouldn't this also compute now, like bigops do? *)
-    wp_let. wp_write. iMod (newlock_inplace with "Hl HR") as (γ) "?".
-    by iApply "HΦ".
+    iExists _, _. iFrame "Hl". destruct b; first done. by iFrame.
   Qed.
 
-  Lemma destroy_lock E γ l R :
+  Lemma lock_proto_destroy E γ l R :
     ↑N ⊆ E → 
-    is_lock γ l R -∗ own_lock γ 1%Qp ={E}=∗ ∃ (b : bool), l ↦ #b ∗ if b then True else ▷ R.
+    lock_proto γ l R ={E}=∗ ∃ (b : bool), l ↦ #b ∗ if b then True else R.
   Proof.
-    iIntros (?) "#Hinv Hown".
-    iMod (cinv_cancel with "Hinv Hown") as (b) "[>Hl HR]"; first done.
-    iExists b. destruct b; first by eauto.
+    iIntros (?) "Hlck". iDestruct "Hlck" as (b) "[Hl HR]".
+    iExists b. iFrame "Hl". destruct b; first done.
     iDestruct "HR" as "[_ $]". done.
   Qed.
 
-  Lemma try_acquire_spec γ l R q :
-    {{{ is_lock γ l R ∗ own_lock γ q }}} try_acquire [ #l ]
-    {{{ b, RET #b; (if b is true then locked γ ∗ R else True) ∗ own_lock γ q }}}.
+  (* At this point, it'd be really nice to have some sugar for symmetric
+     accessors. *)
+  Lemma try_acquire_spec E γ l R P :
+    □ (P ={E,∅}=∗ lock_proto γ l R ∗ (lock_proto γ l R ={∅,E}=∗ P)) -∗
+    {{{ P }}} try_acquire [ #l ] @ E
+    {{{ b, RET #b; (if b is true then locked γ ∗ R else True) ∗ P }}}.
   Proof.
-    iIntros (Φ) "[Hinv Hown] HΦ".
-    wp_rec. iMod (cinv_open with "Hinv Hown") as "(Hinv & Hown & Hclose)"; first done.
+    iIntros "#Hproto !# * HP HΦ".
+    wp_rec. iMod ("Hproto" with "HP") as "(Hinv & Hclose)".
     iDestruct "Hinv" as ([]) "[Hl HR]".
     - wp_apply (wp_cas_int_fail with "Hl"); [done..|]. iIntros "Hl".
-      iMod ("Hclose" with "[Hl]"); first (iNext; iExists true; eauto).
+      iMod ("Hclose" with "[Hl]"); first (iExists true; by eauto).
       iModIntro. iApply ("HΦ" $! false). auto.
     - wp_apply (wp_cas_int_suc with "Hl"); [done..|]. iIntros "Hl".
       iDestruct "HR" as "[Hγ HR]".
-      iMod ("Hclose" with "[Hl]"); first (iNext; iExists true; eauto).
-      iModIntro. rewrite /locked. iApply ("HΦ" $! true with "[$Hγ $HR $Hown]").
+      iMod ("Hclose" with "[Hl]") as "HP"; first (iExists true; by eauto).
+      iModIntro. rewrite /locked. iApply ("HΦ" $! true with "[$Hγ $HR $HP]").
   Qed.
 
-  Lemma acquire_spec γ l R q :
-    {{{ is_lock γ l R ∗ own_lock γ q }}} acquire [ #l ]
-    {{{ RET #(); locked γ ∗ R ∗ own_lock γ q }}}.
+  Lemma acquire_spec E γ l R P :
+    □ (P ={E,∅}=∗ lock_proto γ l R ∗ (lock_proto γ l R ={∅,E}=∗ P)) -∗
+    {{{ P }}} acquire [ #l ] @ E {{{ RET #(); locked γ ∗ R ∗ P }}}.
   Proof.
-    iIntros (Φ) "[#Hinv Hown] HΦ". iLöb as "IH". wp_rec.
-    wp_apply (try_acquire_spec with "[$Hinv $Hown]"). iIntros ([]).
+    iIntros "#Hproto !# * HP HΦ". iLöb as "IH". wp_rec.
+    iPoseProof (try_acquire_spec with "[Hproto] * HP") as "Hacq".
+    { iFrame "Hproto". (* FIXME: Just saying "Hproto" in the pattern above should work. *) }
+    wp_apply "Hacq". (* FIXME: Using `(try_acquire_spec with "[Hproto] * HP")` to avoid the
+                        iPoseProof should work. *)
+    iIntros ([]).
     - iIntros "[[Hlked HR] Hown]". wp_if. iApply "HΦ"; iFrame.
     - iIntros "[_ Hown]". wp_if. iApply ("IH" with "Hown [HΦ]"). auto.
   Qed.
 
-  Lemma release_spec γ l R q :
-    {{{ is_lock γ l R ∗ locked γ ∗ R ∗ own_lock γ q }}} release [ #l ]
-    {{{ RET #(); own_lock γ q }}}.
+  Lemma release_spec E γ l R P :
+    □ (P ={E,∅}=∗ lock_proto γ l R ∗ (lock_proto γ l R ={∅,E}=∗ P)) -∗
+    {{{ locked γ ∗ R ∗ P }}} release [ #l ] @ E {{{ RET #(); P }}}.
   Proof.
-    iIntros (Φ) "(Hinv & Hlocked & HR & Hown) HΦ".
-    rewrite /release /=. wp_let.
-    iMod (cinv_open with "Hinv Hown") as "(Hinv & Hown & Hclose)"; first done.
-    iDestruct "Hinv" as (b) "[? _]". wp_write. iApply "HΦ". iFrame "Hown".
-    iApply "Hclose". iNext. iExists false. by iFrame.
+    iIntros "#Hproto !# * (Hlocked & HR & HP) HΦ". wp_let.
+    iMod ("Hproto" with "HP") as "(Hinv & Hclose)".
+    iDestruct "Hinv" as (b) "[? _]". wp_write. iApply "HΦ".
+    iApply "Hclose". iExists false. by iFrame.
   Qed.
 End proof.
 
-Typeclasses Opaque is_lock locked.
+Typeclasses Opaque lock_proto locked.
diff --git a/theories/lifetime/lifetime.v b/theories/lifetime/lifetime.v
index 62d715c1..c832d46c 100644
--- a/theories/lifetime/lifetime.v
+++ b/theories/lifetime/lifetime.v
@@ -55,6 +55,12 @@ Proof.
   iMod (bor_exists (A:=bool) with "LFT H") as ([]) "H"; auto.
 Qed.
 
+Lemma bor_iff_proper κ P P': ▷ □ (P ↔ P') -∗ □ (&{κ}P ↔ &{κ}P').
+Proof.
+  iIntros "#HP !#". iSplit; iIntros "?"; iApply bor_iff; try done.
+  iNext. iAlways. iSplit; iIntros "?"; iApply "HP"; done.
+Qed.
+
 Lemma bor_later E κ P :
   ↑lftN ⊆ E →
   lft_ctx -∗ &{κ}(▷ P) ={E,E∖↑lftN}▷=∗ &{κ}P.
-- 
GitLab