Library zoo_std.semaphore
From stdpp Require Import
finite.
From zoo Require Import
prelude.
From zoo.common Require Import
countable.
From zoo.iris.bi Require Import
big_op.
From zoo.iris.base_logic Require Import
lib.excl.
From zoo.language Require Import
notations.
From zoo.diaframe Require Import
diaframe.
From zoo_std Require Export
base
semaphore__code.
From zoo_std Require Import
semaphore__types
condition.
From zoo Require Import
options.
Implicit Types b : bool.
Implicit Types cnt : nat.
Implicit Types l : location.
Implicit Types t : val.
Class SemaphoreG Σ `{zoo_G : !ZooG Σ} :=
{ #[local] semaphore_G_mutex_G :: MutexG Σ
; #[local] semaphore_G_tokens_G :: ExclG Σ unitO
}.
Definition semaphore_Σ :=
#[mutex_Σ
; excl_Σ unitO
].
#[global] Instance subG_semaphore_Σ Σ `{zoo_G : !ZooG Σ} :
subG semaphore_Σ Σ →
SemaphoreG Σ.
Section semaphore_G.
Context `{semaphore_G : SemaphoreG Σ}.
Implicit Types P : iProp Σ.
Record metadata :=
{ metadata_mutex : val
; metadata_condition : val
; metadata_tokens : list gname
}.
Implicit Types γ : metadata.
Implicit Types γ_tokens : list gname.
#[local] Instance metadata_eq_dec : EqDecision metadata :=
ltac:(solve_decision).
#[local] Instance metadata_countable :
Countable metadata.
#[local] Definition tokens_auth' γ_tokens cap : iProp Σ :=
⌜length γ_tokens = cap⌝.
#[local] Definition tokens_auth γ :=
tokens_auth' γ.(metadata_tokens).
#[local] Instance : CustomIpat "tokens_auth" :=
" %Htokens ".
#[local] Definition tokens_frag' γ_tokens : iProp Σ :=
∃ i η,
⌜γ_tokens !! i = Some η⌝ ∗
excl η ().
#[local] Definition tokens_frag γ :=
tokens_frag' γ.(metadata_tokens).
#[local] Instance : CustomIpat "tokens_frag" :=
" ( %i & %η & %Htokens_lookup & Hexcl ) ".
#[local] Definition inv_inner l γ P : iProp Σ :=
∃ cnt,
l.[count] ↦ #cnt ∗
[∗ list] _ ∈ seq 0 (S cnt),
tokens_frag γ ∗
P.
#[local] Instance : CustomIpat "inv_inner" :=
" ( %cnt & Hl_count & H ) ".
Definition semaphore_inv t cap P : iProp Σ :=
∃ l γ,
⌜t = #l⌝ ∗
meta l nroot γ ∗
l.[mutex] ↦□ γ.(metadata_mutex) ∗
mutex_inv γ.(metadata_mutex) (inv_inner l γ P) ∗
l.[condition] ↦□ γ.(metadata_condition) ∗
condition_inv γ.(metadata_condition) ∗
tokens_auth γ cap.
#[local] Instance : CustomIpat "inv" :=
" ( %l & %γ & -> & #Hmeta & #Hl_mutex & #Hmutex_inv & #Hl_condition & #Hcondition_inv & #Htokens_auth ) ".
Definition semaphore_locked t : iProp Σ :=
∃ l γ,
⌜t = #l⌝ ∗
meta l nroot γ ∗
tokens_frag γ.
#[local] Instance : CustomIpat "locked" :=
" ( %l_ & %γ_ & %Heq & #Hmeta_ & Htokens_frag ) ".
#[global] Instance semaphore_inv_contractive t cap :
Contractive (semaphore_inv t cap).
#[global] Instance semaphore_inv_ne t cap :
NonExpansive (semaphore_inv t cap).
#[global] Instance semaphore_inv_proper t cap :
Proper ((≡) ==> (≡)) (semaphore_inv t cap).
#[global] Instance semaphore_locked_timeless t :
Timeless (semaphore_locked t).
#[local] Instance tokens_auth_persistent γ cap :
Persistent (tokens_auth γ cap).
#[global] Instance semaphore_inv_persistent t cap P :
Persistent (semaphore_inv t cap P).
#[local] Lemma tokens_alloc cap :
⊢ |==>
∃ γ_tokens,
tokens_auth' γ_tokens cap ∗
[∗ list] _ ∈ seq 0 cap, tokens_frag' γ_tokens.
#[local] Lemma tokens_frags_valid γ cap n :
tokens_auth γ cap -∗
([∗ list] _ ∈ seq 0 n, tokens_frag γ) -∗
⌜n ≤ cap⌝.
Opaque tokens_auth.
Opaque tokens_frag.
Lemma semaphore٠create𑁒spec {cap} P :
(0 < cap)%Z →
{{{
[∗ list] _ ∈ seq 0 ₊cap, P
}}}
semaphore٠create #cap
{{{
t
, RET t;
semaphore_inv t ₊cap P
}}}.
Lemma semaphore٠try_lock𑁒spec t cap P :
{{{
semaphore_inv t cap P
}}}
semaphore٠try_lock t
{{{
b
, RET #b;
if b then
semaphore_locked t ∗
P
else
True
}}}.
Lemma semaphore٠lock𑁒spec t cap P :
{{{
semaphore_inv t cap P
}}}
semaphore٠lock t
{{{
RET ();
semaphore_locked t ∗
P
}}}.
Lemma semaphore٠unlock𑁒spec t cap P :
{{{
semaphore_inv t cap P ∗
semaphore_locked t ∗
P
}}}
semaphore٠unlock t
{{{
RET ();
True
}}}.
End semaphore_G.
From zoo_std Require
semaphore__opaque.
#[global] Opaque semaphore_inv.
#[global] Opaque semaphore_locked.
finite.
From zoo Require Import
prelude.
From zoo.common Require Import
countable.
From zoo.iris.bi Require Import
big_op.
From zoo.iris.base_logic Require Import
lib.excl.
From zoo.language Require Import
notations.
From zoo.diaframe Require Import
diaframe.
From zoo_std Require Export
base
semaphore__code.
From zoo_std Require Import
semaphore__types
condition.
From zoo Require Import
options.
Implicit Types b : bool.
Implicit Types cnt : nat.
Implicit Types l : location.
Implicit Types t : val.
Class SemaphoreG Σ `{zoo_G : !ZooG Σ} :=
{ #[local] semaphore_G_mutex_G :: MutexG Σ
; #[local] semaphore_G_tokens_G :: ExclG Σ unitO
}.
Definition semaphore_Σ :=
#[mutex_Σ
; excl_Σ unitO
].
#[global] Instance subG_semaphore_Σ Σ `{zoo_G : !ZooG Σ} :
subG semaphore_Σ Σ →
SemaphoreG Σ.
Section semaphore_G.
Context `{semaphore_G : SemaphoreG Σ}.
Implicit Types P : iProp Σ.
Record metadata :=
{ metadata_mutex : val
; metadata_condition : val
; metadata_tokens : list gname
}.
Implicit Types γ : metadata.
Implicit Types γ_tokens : list gname.
#[local] Instance metadata_eq_dec : EqDecision metadata :=
ltac:(solve_decision).
#[local] Instance metadata_countable :
Countable metadata.
#[local] Definition tokens_auth' γ_tokens cap : iProp Σ :=
⌜length γ_tokens = cap⌝.
#[local] Definition tokens_auth γ :=
tokens_auth' γ.(metadata_tokens).
#[local] Instance : CustomIpat "tokens_auth" :=
" %Htokens ".
#[local] Definition tokens_frag' γ_tokens : iProp Σ :=
∃ i η,
⌜γ_tokens !! i = Some η⌝ ∗
excl η ().
#[local] Definition tokens_frag γ :=
tokens_frag' γ.(metadata_tokens).
#[local] Instance : CustomIpat "tokens_frag" :=
" ( %i & %η & %Htokens_lookup & Hexcl ) ".
#[local] Definition inv_inner l γ P : iProp Σ :=
∃ cnt,
l.[count] ↦ #cnt ∗
[∗ list] _ ∈ seq 0 (S cnt),
tokens_frag γ ∗
P.
#[local] Instance : CustomIpat "inv_inner" :=
" ( %cnt & Hl_count & H ) ".
Definition semaphore_inv t cap P : iProp Σ :=
∃ l γ,
⌜t = #l⌝ ∗
meta l nroot γ ∗
l.[mutex] ↦□ γ.(metadata_mutex) ∗
mutex_inv γ.(metadata_mutex) (inv_inner l γ P) ∗
l.[condition] ↦□ γ.(metadata_condition) ∗
condition_inv γ.(metadata_condition) ∗
tokens_auth γ cap.
#[local] Instance : CustomIpat "inv" :=
" ( %l & %γ & -> & #Hmeta & #Hl_mutex & #Hmutex_inv & #Hl_condition & #Hcondition_inv & #Htokens_auth ) ".
Definition semaphore_locked t : iProp Σ :=
∃ l γ,
⌜t = #l⌝ ∗
meta l nroot γ ∗
tokens_frag γ.
#[local] Instance : CustomIpat "locked" :=
" ( %l_ & %γ_ & %Heq & #Hmeta_ & Htokens_frag ) ".
#[global] Instance semaphore_inv_contractive t cap :
Contractive (semaphore_inv t cap).
#[global] Instance semaphore_inv_ne t cap :
NonExpansive (semaphore_inv t cap).
#[global] Instance semaphore_inv_proper t cap :
Proper ((≡) ==> (≡)) (semaphore_inv t cap).
#[global] Instance semaphore_locked_timeless t :
Timeless (semaphore_locked t).
#[local] Instance tokens_auth_persistent γ cap :
Persistent (tokens_auth γ cap).
#[global] Instance semaphore_inv_persistent t cap P :
Persistent (semaphore_inv t cap P).
#[local] Lemma tokens_alloc cap :
⊢ |==>
∃ γ_tokens,
tokens_auth' γ_tokens cap ∗
[∗ list] _ ∈ seq 0 cap, tokens_frag' γ_tokens.
#[local] Lemma tokens_frags_valid γ cap n :
tokens_auth γ cap -∗
([∗ list] _ ∈ seq 0 n, tokens_frag γ) -∗
⌜n ≤ cap⌝.
Opaque tokens_auth.
Opaque tokens_frag.
Lemma semaphore٠create𑁒spec {cap} P :
(0 < cap)%Z →
{{{
[∗ list] _ ∈ seq 0 ₊cap, P
}}}
semaphore٠create #cap
{{{
t
, RET t;
semaphore_inv t ₊cap P
}}}.
Lemma semaphore٠try_lock𑁒spec t cap P :
{{{
semaphore_inv t cap P
}}}
semaphore٠try_lock t
{{{
b
, RET #b;
if b then
semaphore_locked t ∗
P
else
True
}}}.
Lemma semaphore٠lock𑁒spec t cap P :
{{{
semaphore_inv t cap P
}}}
semaphore٠lock t
{{{
RET ();
semaphore_locked t ∗
P
}}}.
Lemma semaphore٠unlock𑁒spec t cap P :
{{{
semaphore_inv t cap P ∗
semaphore_locked t ∗
P
}}}
semaphore٠unlock t
{{{
RET ();
True
}}}.
End semaphore_G.
From zoo_std Require
semaphore__opaque.
#[global] Opaque semaphore_inv.
#[global] Opaque semaphore_locked.