Library zoo_std.lazy
Require Import zoo.prelude.
Require Import zoo.common.countable.
Require Import zoo.iris.base_logic.lib.oneshot.
Require Import zoo.iris.base_logic.lib.subpreds.
Require Import zoo.base.
Require Export zoo_std.lazy__code.
Require Import zoo_std.lazy__types.
Require Import zoo.options.
Implicit Type b : bool.
Implicit Type v fn mtx : val.
Class LazyG Σ `{zoo۰G : !ZooG Σ} :=
{ #[local] lazy۰G۰mutex۰G :: MutexG Σ
; #[local] lazy۰G۰lstate۰G :: OneshotG Σ unit val
; #[local] lazy۰G۰consumer۰G :: SubpredsG Σ val
}.
Definition lazy۰Σ :=
#[mutex۰Σ
; oneshot۰Σ unit val
; subpreds۰Σ val
].
#[global] Instance subGーlazy۰Σ Σ `{zoo۰G : !ZooG Σ} :
subG lazy۰Σ Σ →
LazyG Σ .
Module base.
Section lazy۰G.
Context `{lazy۰G : LazyG Σ}.
Implicit Type t : location.
Implicit Type Ψ Χ Ξ : val → iProp Σ.
Record lazy۰name :=
{ lazy۰name۰thunk : val
; lazy۰name۰lstate : gname
; lazy۰name۰consumer : gname
}.
Implicit Type γ : lazy۰name.
#[global] Instance lazy۰nameーeq_dec : EqDecision lazy۰name :=
ltac:(solve_decision).
#[global] Instance lazy۰nameーcountable :
Countable lazy۰name.
Variant state :=
| Unset
| Setting mtx
| Set_ v.
Implicit Type state : state.
#[local] Instance stateーinhabited : Inhabited state :=
populate Unset.
#[local] Definition state۰to_bool state :=
match state with
| Set_ _ ⇒
true
| _ ⇒
false
end.
#[local] Definition state۰to_option state :=
match state with
| Set_ v ⇒
Some v
| _ ⇒
None
end.
#[local] Definition state۰to_val γ state :=
match state with
| Unset ⇒
‘Unset( γ.(lazy۰name۰thunk) )
| Setting mtx ⇒
‘Setting( mtx )
| Set_ v ⇒
‘Set( v )
end%V.
#[local] Definition lstate۰unset₁' γ_lstate :=
oneshot۰pending γ_lstate (DfracOwn (1/3)) ().
#[local] Definition lstate۰unset₁ γ :=
lstate۰unset₁' γ.(lazy۰name۰lstate).
#[local] Definition lstate۰unset₂' γ_lstate :=
oneshot۰pending γ_lstate (DfracOwn (2/3)) ().
#[local] Definition lstate۰unset₂ γ :=
lstate۰unset₂' γ.(lazy۰name۰lstate).
#[local] Definition lstate۰set' γ_lstate :=
oneshot۰shot γ_lstate.
#[local] Definition lstate۰set γ :=
lstate۰set' γ.(lazy۰name۰lstate).
#[local] Definition consumer۰auth' :=
subpreds۰auth.
#[local] Definition consumer۰auth γ :=
consumer۰auth' γ.(lazy۰name۰consumer).
#[local] Definition consumer۰frag' :=
subpreds۰frag.
#[local] Definition consumer۰frag γ :=
consumer۰frag' γ.(lazy۰name۰consumer).
Definition lazy۰result :=
lstate۰set.
#[local] Instance : CustomIpat "result" :=
" #Hlstate_set{_{}} ".
Definition lazy۰resolved γ : iProp Σ :=
∃ v,
lazy۰result γ v.
#[local] Definition inv۰state۰unset γ Ψ Ξ : iProp Σ :=
lstate۰unset₁ γ ∗
lstate۰unset₂ γ ∗
WP γ.(lazy۰name۰thunk) () {{ v,
▷ Ψ v ∗
▷ □ Ξ v
}}.
#[local] Instance : CustomIpat "inv۰state۰unset" :=
" ( {>;}Hlstate_unset₁{_{}} & {>;}Hlstate_unset₂{_{}} & Hthunk ) ".
#[local] Definition inv۰state۰setting γ mtx : iProp Σ :=
lstate۰unset₁ γ ∗
mutex۰inv mtx (lazy۰resolved γ).
#[local] Instance : CustomIpat "inv۰state۰setting" :=
" ( {>;}Hlstate_unset₁{_{}} & #Hmtx_inv{_{}} ) ".
#[local] Definition inv۰state۰set γ Ξ v : iProp Σ :=
lstate۰set γ v ∗
□ Ξ v.
#[local] Instance : CustomIpat "inv۰state۰set" :=
" ( {>;}#Hlstate_set{_{}} & #HΞ{_{}} ) ".
#[local] Definition inv۰state γ Ψ Ξ state :=
match state with
| Unset ⇒
inv۰state۰unset γ Ψ Ξ
| Setting mtx ⇒
inv۰state۰setting γ mtx
| Set_ v ⇒
inv۰state۰set γ Ξ v
end.
#[local] Definition inv۰inner t γ Ψ Ξ : iProp Σ :=
∃ state,
t ↦ᵣ state۰to_val γ state ∗
consumer۰auth γ Ψ (state۰to_option state) ∗
inv۰state γ Ψ Ξ state.
#[local] Instance : CustomIpat "inv۰inner" :=
" ( %state & Ht & Hconsumer_auth & Hstate ) ".
Definition lazy۰inv t γ Ψ Ξ : iProp Σ :=
inv nroot (inv۰inner t γ Ψ Ξ).
#[local] Instance : CustomIpat "inv" :=
" #Hinv ".
Definition lazy۰consumer :=
consumer۰frag.
#[local] Instance : CustomIpat "consumer" :=
" Hconsumer{}_frag ".
#[global] Instance lazy۰invーcontractive t γ n :
Proper (
(pointwise_relation _ (dist_later n)) ==>
(pointwise_relation _ (dist_later n)) ==>
(≡{n}≡)
) (lazy۰inv t γ).
#[global] Instance lazy۰invーproper t γ :
Proper (
(pointwise_relation _ (≡)) ==>
(pointwise_relation _ (≡)) ==>
(≡)
) (lazy۰inv t γ).
#[global] Instance lazy۰consumerーcontractive γ n :
Proper (
(pointwise_relation _ (dist_later n)) ==>
(≡{n}≡)
) (lazy۰consumer γ).
#[global] Instance lazy۰consumerーproper γ :
Proper (
(pointwise_relation _ (≡)) ==>
(≡)
) (lazy۰consumer γ).
#[global] Instance lazy۰resultーtimeless γ v :
Timeless (lazy۰result γ v).
#[global] Instance lazy۰invーpersistent t γ Ψ Ξ :
Persistent (lazy۰inv t γ Ψ Ξ).
#[global] Instance lazy۰resultーpersistent γ v :
Persistent (lazy۰result γ v).
#[local] Lemma lstateーalloc :
⊢ |==>
∃ γ_lstate,
lstate۰unset₁' γ_lstate ∗
lstate۰unset₂' γ_lstate.
#[local] Lemma lstate۰unset₂ーexclusive γ :
lstate۰unset₂ γ -∗
lstate۰unset₂ γ -∗
False.
#[local] Lemma lstate۰setーagree γ v1 v2 :
lstate۰set γ v1 -∗
lstate۰set γ v2 -∗
⌜v1 = v2⌝.
#[local] Lemma lstateーunset₁ーset γ v :
lstate۰unset₁ γ -∗
lstate۰set γ v -∗
False.
#[local] Lemma lstateーunset₂ーset γ v :
lstate۰unset₂ γ -∗
lstate۰set γ v -∗
False.
#[local] Lemma lstateーupdate {γ} v :
lstate۰unset₁ γ -∗
lstate۰unset₂ γ ==∗
lstate۰set γ v.
#[local] Lemma consumerーalloc Ψ :
⊢ |==>
∃ γ_consumer,
consumer۰auth' γ_consumer Ψ None ∗
consumer۰frag' γ_consumer Ψ.
#[local] Lemma consumerーwand {γ Ψ} {state : option val} {Χ1} Χ2 E :
▷ consumer۰auth γ Ψ state -∗
consumer۰frag γ Χ1 -∗
(∀ v, Χ1 v -∗ Χ2 v) ={E}=∗
▷ consumer۰auth γ Ψ state ∗
consumer۰frag γ Χ2.
#[local] Lemma consumerーdivide {γ Ψ} {state : option val} Χs E :
▷ consumer۰auth γ Ψ state -∗
consumer۰frag γ (λ v, [∗ list] Χ ∈ Χs, Χ v) ={E}=∗
▷ consumer۰auth γ Ψ state ∗
[∗ list] Χ ∈ Χs, consumer۰frag γ Χ.
#[local] Lemma consumerーproduce {γ Ψ} v :
consumer۰auth γ Ψ None -∗
Ψ v -∗
consumer۰auth γ Ψ (Some v).
#[local] Lemma consumerーconsume γ Ψ v Χ E :
▷ consumer۰auth γ Ψ (Some v) -∗
consumer۰frag γ Χ ={E}=∗
▷ consumer۰auth γ Ψ (Some v) ∗
▷^2 Χ v.
#[local] Lemma inv۰stateーlstate۰set γ Ψ Ξ state v :
▷ inv۰state γ Ψ Ξ state -∗
lstate۰set γ v -∗
◇ (
⌜state = Set_ v⌝ ∗
▷ inv۰state۰set γ Ξ v
).
Lemma lazy۰consumerーwand {t γ Ψ Ξ Χ1} Χ2 :
lazy۰inv t γ Ψ Ξ -∗
lazy۰consumer γ Χ1 -∗
(∀ v, Χ1 v -∗ Χ2 v) ={⊤}=∗
lazy۰consumer γ Χ2.
Lemma lazy۰consumerーdivide {t γ Ψ Ξ} Χs :
lazy۰inv t γ Ψ Ξ -∗
lazy۰consumer γ (λ v, [∗ list] Χ ∈ Χs, Χ v) ={⊤}=∗
[∗ list] Χ ∈ Χs, lazy۰consumer γ Χ.
Lemma lazy۰resultーagree γ v1 v2 :
lazy۰result γ v1 -∗
lazy۰result γ v2 -∗
⌜v1 = v2⌝.
Lemma lazyーinvーresult t γ Ψ Ξ v :
lazy۰inv t γ Ψ Ξ -∗
lazy۰result γ v ={⊤}=∗
▷ □ Ξ v.
Lemma lazyーinvーresultーconsumer t γ Ψ Ξ v Χ :
lazy۰inv t γ Ψ Ξ -∗
lazy۰result γ v -∗
lazy۰consumer γ Χ ={⊤}=∗
▷^2 Χ v ∗
▷ □ Ξ v.
Lemma lazy٠makeーspec Ψ Ξ fn :
{{{
WP fn () {{ v,
▷ Ψ v ∗
▷ □ Ξ v
}}
}}}
lazy٠make fn
{{{
t γ
, RET #t;
meta_token t ⊤ ∗
lazy۰inv t γ Ψ Ξ ∗
lazy۰consumer γ Ψ
}}}.
Lemma lazy٠returnーspec Ψ Ξ v :
{{{
▷ Ψ v ∗
▷ □ Ξ v
}}}
lazy٠return v
{{{
t γ
, RET #t;
meta_token t ⊤ ∗
lazy۰inv t γ Ψ Ξ ∗
lazy۰result γ v ∗
lazy۰consumer γ Ψ
}}}.
Lemma lazy٠is_setーspec t γ Ψ Ξ :
{{{
lazy۰inv t γ Ψ Ξ
}}}
lazy٠is_set #t
{{{
b
, RET #b;
if b then
£ 2 ∗
lazy۰resolved γ
else
True
}}}.
Lemma lazy٠is_setーspecーresult t γ Ψ Ξ v :
{{{
lazy۰inv t γ Ψ Ξ ∗
lazy۰result γ v
}}}
lazy٠is_set #t
{{{
RET true;
£ 2
}}}.
Lemma lazy٠is_unsetーspec t γ Ψ Ξ :
{{{
lazy۰inv t γ Ψ Ξ
}}}
lazy٠is_unset #t
{{{
b
, RET #b;
if b then
True
else
£ 2 ∗
lazy۰resolved γ
}}}.
Lemma lazy٠is_unsetーspecーresult t γ Ψ Ξ v :
{{{
lazy۰inv t γ Ψ Ξ ∗
lazy۰result γ v
}}}
lazy٠is_unset #t
{{{
RET false;
£ 2
}}}.
Lemma lazy٠getーspec t γ Ψ Ξ :
{{{
lazy۰inv t γ Ψ Ξ
}}}
lazy٠get #t
{{{
v
, RET v;
£ 2 ∗
lazy۰result γ v
}}}.
Lemma lazy٠getーspecーresult t γ Ψ Ξ v :
{{{
lazy۰inv t γ Ψ Ξ ∗
lazy۰result γ v
}}}
lazy٠get #t
{{{
RET v;
£ 2
}}}.
End lazy۰G.
#[global] Opaque lazy۰inv.
#[global] Opaque lazy۰consumer.
#[global] Opaque lazy۰result.
End base.
Require zoo_std.lazy__opaque.
Section lazy۰G.
Context `{lazy۰G : LazyG Σ}.
Implicit Type 𝑡 : location.
Implicit Type t : val.
Implicit Type γ : base.lazy۰name.
Implicit Type Ψ Χ Ξ : val → iProp Σ.
Definition lazy۰inv t Ψ Ξ : iProp Σ :=
∃ 𝑡 γ,
⌜t = #𝑡⌝ ∗
𝑡 ↪ γ ∗
base.lazy۰inv 𝑡 γ Ψ Ξ.
#[local] Instance : CustomIpat "inv" :=
" ( %l{} & %γ{} & {%Heq{};->} & #Hmeta{_{}} & Hinv{_{}} ) ".
Definition lazy۰consumer t Χ : iProp Σ :=
∃ 𝑡 γ,
⌜t = #𝑡⌝ ∗
𝑡 ↪ γ ∗
base.lazy۰consumer γ Χ.
#[local] Instance : CustomIpat "consumer" :=
" ( %l{;_} & %γ{;_} & {%Heq{};->} & #Hmeta{_{}} & Hconsumer{_{}} ) ".
Definition lazy۰result t v : iProp Σ :=
∃ 𝑡 γ,
⌜t = #𝑡⌝ ∗
𝑡 ↪ γ ∗
base.lazy۰result γ v.
#[local] Instance : CustomIpat "result" :=
" ( %l{;_} & %γ{;_} & {%Heq{};->} & #Hmeta{_{}} & Hresult{_{}} ) ".
Definition lazy۰resolved t : iProp Σ :=
∃ v,
lazy۰result t v.
#[global] Instance lazy۰invーcontractive t n :
Proper (
(pointwise_relation _ (dist_later n)) ==>
(pointwise_relation _ (dist_later n)) ==>
(≡{n}≡)
) (lazy۰inv t).
#[global] Instance lazy۰invーproper t :
Proper (
(pointwise_relation _ (≡)) ==>
(pointwise_relation _ (≡)) ==>
(≡)
) (lazy۰inv t).
#[global] Instance lazy۰consumerーcontractive t n :
Proper (
(pointwise_relation _ (dist_later n)) ==>
(≡{n}≡)
) (lazy۰consumer t).
#[global] Instance lazy۰consumerーproper t :
Proper (
(pointwise_relation _ (≡)) ==>
(≡)
) (lazy۰consumer t).
#[global] Instance lazy۰resultーtimeless t v :
Timeless (lazy۰result t v).
#[global] Instance lazy۰invーpersistent t Ψ Ξ :
Persistent (lazy۰inv t Ψ Ξ).
#[global] Instance lazy۰resultーpersistent t v :
Persistent (lazy۰result t v).
Lemma lazy۰consumerーwand {t Ψ Ξ Χ1} Χ2 :
lazy۰inv t Ψ Ξ -∗
lazy۰consumer t Χ1 -∗
(∀ v, Χ1 v -∗ Χ2 v) ={⊤}=∗
lazy۰consumer t Χ2.
Lemma lazy۰consumerーdivide {t Ψ Ξ} Χs :
lazy۰inv t Ψ Ξ -∗
lazy۰consumer t (λ v, [∗ list] Χ ∈ Χs, Χ v) ={⊤}=∗
[∗ list] Χ ∈ Χs, lazy۰consumer t Χ.
Lemma lazy۰consumerーsplit {t Ψ Ξ} Χ1 Χ2 :
lazy۰inv t Ψ Ξ -∗
lazy۰consumer t (λ v, Χ1 v ∗ Χ2 v) ={⊤}=∗
lazy۰consumer t Χ1 ∗
lazy۰consumer t Χ2.
Lemma lazy۰resultーagree t v1 v2 :
lazy۰result t v1 -∗
lazy۰result t v2 -∗
⌜v1 = v2⌝.
Lemma lazyーinvーresult t Ψ Ξ v :
lazy۰inv t Ψ Ξ -∗
lazy۰result t v ={⊤}=∗
▷ □ Ξ v.
Lemma lazyーinv_result' t Ψ Ξ v :
£ 1 -∗
lazy۰inv t Ψ Ξ -∗
lazy۰result t v ={⊤}=∗
□ Ξ v.
Lemma lazyーinvーresultーconsumer t Ψ Ξ v Χ :
lazy۰inv t Ψ Ξ -∗
lazy۰result t v -∗
lazy۰consumer t Χ ={⊤}=∗
▷^2 Χ v ∗
▷ □ Ξ v.
Lemma lazyーinvーresultーconsumer' t Ψ Ξ v Χ :
£ 2 -∗
lazy۰inv t Ψ Ξ -∗
lazy۰result t v -∗
lazy۰consumer t Χ ={⊤}=∗
Χ v ∗
□ Ξ v.
Lemma lazy٠makeーspec Ψ Ξ fn :
{{{
WP fn () {{ v,
▷ Ψ v ∗
▷ □ Ξ v
}}
}}}
lazy٠make fn
{{{
t
, RET t;
lazy۰inv t Ψ Ξ ∗
lazy۰consumer t Ψ
}}}.
Lemma lazy٠returnーspec Ψ Ξ v :
{{{
▷ Ψ v ∗
▷ □ Ξ v
}}}
lazy٠return v
{{{
t
, RET t;
lazy۰inv t Ψ Ξ ∗
lazy۰result t v ∗
lazy۰consumer t Ψ
}}}.
Lemma lazy٠is_setーspec t Ψ Ξ :
{{{
lazy۰inv t Ψ Ξ
}}}
lazy٠is_set t
{{{
b
, RET #b;
if b then
£ 2 ∗
lazy۰resolved t
else
True
}}}.
Lemma lazy٠is_setーspecーresult t Ψ Ξ v :
{{{
lazy۰inv t Ψ Ξ ∗
lazy۰result t v
}}}
lazy٠is_set t
{{{
RET true;
£ 2
}}}.
Lemma lazy٠is_unsetーspec t Ψ Ξ :
{{{
lazy۰inv t Ψ Ξ
}}}
lazy٠is_unset t
{{{
b
, RET #b;
if b then
True
else
£ 2 ∗
lazy۰resolved t
}}}.
Lemma lazy٠is_unsetーspecーresult t Ψ Ξ v :
{{{
lazy۰inv t Ψ Ξ ∗
lazy۰result t v
}}}
lazy٠is_unset t
{{{
RET false;
£ 2
}}}.
Lemma lazy٠getーspec t Ψ Ξ :
{{{
lazy۰inv t Ψ Ξ
}}}
lazy٠get t
{{{
v
, RET v;
£ 2 ∗
lazy۰result t v
}}}.
Lemma lazy٠getーspecーresult t Ψ Ξ v :
{{{
lazy۰inv t Ψ Ξ ∗
lazy۰result t v
}}}
lazy٠get t
{{{
RET v;
£ 2
}}}.
End lazy۰G.
#[global] Opaque lazy۰inv.
#[global] Opaque lazy۰consumer.
#[global] Opaque lazy۰result.
Require Import zoo.common.countable.
Require Import zoo.iris.base_logic.lib.oneshot.
Require Import zoo.iris.base_logic.lib.subpreds.
Require Import zoo.base.
Require Export zoo_std.lazy__code.
Require Import zoo_std.lazy__types.
Require Import zoo.options.
Implicit Type b : bool.
Implicit Type v fn mtx : val.
Class LazyG Σ `{zoo۰G : !ZooG Σ} :=
{ #[local] lazy۰G۰mutex۰G :: MutexG Σ
; #[local] lazy۰G۰lstate۰G :: OneshotG Σ unit val
; #[local] lazy۰G۰consumer۰G :: SubpredsG Σ val
}.
Definition lazy۰Σ :=
#[mutex۰Σ
; oneshot۰Σ unit val
; subpreds۰Σ val
].
#[global] Instance subGーlazy۰Σ Σ `{zoo۰G : !ZooG Σ} :
subG lazy۰Σ Σ →
LazyG Σ .
Module base.
Section lazy۰G.
Context `{lazy۰G : LazyG Σ}.
Implicit Type t : location.
Implicit Type Ψ Χ Ξ : val → iProp Σ.
Record lazy۰name :=
{ lazy۰name۰thunk : val
; lazy۰name۰lstate : gname
; lazy۰name۰consumer : gname
}.
Implicit Type γ : lazy۰name.
#[global] Instance lazy۰nameーeq_dec : EqDecision lazy۰name :=
ltac:(solve_decision).
#[global] Instance lazy۰nameーcountable :
Countable lazy۰name.
Variant state :=
| Unset
| Setting mtx
| Set_ v.
Implicit Type state : state.
#[local] Instance stateーinhabited : Inhabited state :=
populate Unset.
#[local] Definition state۰to_bool state :=
match state with
| Set_ _ ⇒
true
| _ ⇒
false
end.
#[local] Definition state۰to_option state :=
match state with
| Set_ v ⇒
Some v
| _ ⇒
None
end.
#[local] Definition state۰to_val γ state :=
match state with
| Unset ⇒
‘Unset( γ.(lazy۰name۰thunk) )
| Setting mtx ⇒
‘Setting( mtx )
| Set_ v ⇒
‘Set( v )
end%V.
#[local] Definition lstate۰unset₁' γ_lstate :=
oneshot۰pending γ_lstate (DfracOwn (1/3)) ().
#[local] Definition lstate۰unset₁ γ :=
lstate۰unset₁' γ.(lazy۰name۰lstate).
#[local] Definition lstate۰unset₂' γ_lstate :=
oneshot۰pending γ_lstate (DfracOwn (2/3)) ().
#[local] Definition lstate۰unset₂ γ :=
lstate۰unset₂' γ.(lazy۰name۰lstate).
#[local] Definition lstate۰set' γ_lstate :=
oneshot۰shot γ_lstate.
#[local] Definition lstate۰set γ :=
lstate۰set' γ.(lazy۰name۰lstate).
#[local] Definition consumer۰auth' :=
subpreds۰auth.
#[local] Definition consumer۰auth γ :=
consumer۰auth' γ.(lazy۰name۰consumer).
#[local] Definition consumer۰frag' :=
subpreds۰frag.
#[local] Definition consumer۰frag γ :=
consumer۰frag' γ.(lazy۰name۰consumer).
Definition lazy۰result :=
lstate۰set.
#[local] Instance : CustomIpat "result" :=
" #Hlstate_set{_{}} ".
Definition lazy۰resolved γ : iProp Σ :=
∃ v,
lazy۰result γ v.
#[local] Definition inv۰state۰unset γ Ψ Ξ : iProp Σ :=
lstate۰unset₁ γ ∗
lstate۰unset₂ γ ∗
WP γ.(lazy۰name۰thunk) () {{ v,
▷ Ψ v ∗
▷ □ Ξ v
}}.
#[local] Instance : CustomIpat "inv۰state۰unset" :=
" ( {>;}Hlstate_unset₁{_{}} & {>;}Hlstate_unset₂{_{}} & Hthunk ) ".
#[local] Definition inv۰state۰setting γ mtx : iProp Σ :=
lstate۰unset₁ γ ∗
mutex۰inv mtx (lazy۰resolved γ).
#[local] Instance : CustomIpat "inv۰state۰setting" :=
" ( {>;}Hlstate_unset₁{_{}} & #Hmtx_inv{_{}} ) ".
#[local] Definition inv۰state۰set γ Ξ v : iProp Σ :=
lstate۰set γ v ∗
□ Ξ v.
#[local] Instance : CustomIpat "inv۰state۰set" :=
" ( {>;}#Hlstate_set{_{}} & #HΞ{_{}} ) ".
#[local] Definition inv۰state γ Ψ Ξ state :=
match state with
| Unset ⇒
inv۰state۰unset γ Ψ Ξ
| Setting mtx ⇒
inv۰state۰setting γ mtx
| Set_ v ⇒
inv۰state۰set γ Ξ v
end.
#[local] Definition inv۰inner t γ Ψ Ξ : iProp Σ :=
∃ state,
t ↦ᵣ state۰to_val γ state ∗
consumer۰auth γ Ψ (state۰to_option state) ∗
inv۰state γ Ψ Ξ state.
#[local] Instance : CustomIpat "inv۰inner" :=
" ( %state & Ht & Hconsumer_auth & Hstate ) ".
Definition lazy۰inv t γ Ψ Ξ : iProp Σ :=
inv nroot (inv۰inner t γ Ψ Ξ).
#[local] Instance : CustomIpat "inv" :=
" #Hinv ".
Definition lazy۰consumer :=
consumer۰frag.
#[local] Instance : CustomIpat "consumer" :=
" Hconsumer{}_frag ".
#[global] Instance lazy۰invーcontractive t γ n :
Proper (
(pointwise_relation _ (dist_later n)) ==>
(pointwise_relation _ (dist_later n)) ==>
(≡{n}≡)
) (lazy۰inv t γ).
#[global] Instance lazy۰invーproper t γ :
Proper (
(pointwise_relation _ (≡)) ==>
(pointwise_relation _ (≡)) ==>
(≡)
) (lazy۰inv t γ).
#[global] Instance lazy۰consumerーcontractive γ n :
Proper (
(pointwise_relation _ (dist_later n)) ==>
(≡{n}≡)
) (lazy۰consumer γ).
#[global] Instance lazy۰consumerーproper γ :
Proper (
(pointwise_relation _ (≡)) ==>
(≡)
) (lazy۰consumer γ).
#[global] Instance lazy۰resultーtimeless γ v :
Timeless (lazy۰result γ v).
#[global] Instance lazy۰invーpersistent t γ Ψ Ξ :
Persistent (lazy۰inv t γ Ψ Ξ).
#[global] Instance lazy۰resultーpersistent γ v :
Persistent (lazy۰result γ v).
#[local] Lemma lstateーalloc :
⊢ |==>
∃ γ_lstate,
lstate۰unset₁' γ_lstate ∗
lstate۰unset₂' γ_lstate.
#[local] Lemma lstate۰unset₂ーexclusive γ :
lstate۰unset₂ γ -∗
lstate۰unset₂ γ -∗
False.
#[local] Lemma lstate۰setーagree γ v1 v2 :
lstate۰set γ v1 -∗
lstate۰set γ v2 -∗
⌜v1 = v2⌝.
#[local] Lemma lstateーunset₁ーset γ v :
lstate۰unset₁ γ -∗
lstate۰set γ v -∗
False.
#[local] Lemma lstateーunset₂ーset γ v :
lstate۰unset₂ γ -∗
lstate۰set γ v -∗
False.
#[local] Lemma lstateーupdate {γ} v :
lstate۰unset₁ γ -∗
lstate۰unset₂ γ ==∗
lstate۰set γ v.
#[local] Lemma consumerーalloc Ψ :
⊢ |==>
∃ γ_consumer,
consumer۰auth' γ_consumer Ψ None ∗
consumer۰frag' γ_consumer Ψ.
#[local] Lemma consumerーwand {γ Ψ} {state : option val} {Χ1} Χ2 E :
▷ consumer۰auth γ Ψ state -∗
consumer۰frag γ Χ1 -∗
(∀ v, Χ1 v -∗ Χ2 v) ={E}=∗
▷ consumer۰auth γ Ψ state ∗
consumer۰frag γ Χ2.
#[local] Lemma consumerーdivide {γ Ψ} {state : option val} Χs E :
▷ consumer۰auth γ Ψ state -∗
consumer۰frag γ (λ v, [∗ list] Χ ∈ Χs, Χ v) ={E}=∗
▷ consumer۰auth γ Ψ state ∗
[∗ list] Χ ∈ Χs, consumer۰frag γ Χ.
#[local] Lemma consumerーproduce {γ Ψ} v :
consumer۰auth γ Ψ None -∗
Ψ v -∗
consumer۰auth γ Ψ (Some v).
#[local] Lemma consumerーconsume γ Ψ v Χ E :
▷ consumer۰auth γ Ψ (Some v) -∗
consumer۰frag γ Χ ={E}=∗
▷ consumer۰auth γ Ψ (Some v) ∗
▷^2 Χ v.
#[local] Lemma inv۰stateーlstate۰set γ Ψ Ξ state v :
▷ inv۰state γ Ψ Ξ state -∗
lstate۰set γ v -∗
◇ (
⌜state = Set_ v⌝ ∗
▷ inv۰state۰set γ Ξ v
).
Lemma lazy۰consumerーwand {t γ Ψ Ξ Χ1} Χ2 :
lazy۰inv t γ Ψ Ξ -∗
lazy۰consumer γ Χ1 -∗
(∀ v, Χ1 v -∗ Χ2 v) ={⊤}=∗
lazy۰consumer γ Χ2.
Lemma lazy۰consumerーdivide {t γ Ψ Ξ} Χs :
lazy۰inv t γ Ψ Ξ -∗
lazy۰consumer γ (λ v, [∗ list] Χ ∈ Χs, Χ v) ={⊤}=∗
[∗ list] Χ ∈ Χs, lazy۰consumer γ Χ.
Lemma lazy۰resultーagree γ v1 v2 :
lazy۰result γ v1 -∗
lazy۰result γ v2 -∗
⌜v1 = v2⌝.
Lemma lazyーinvーresult t γ Ψ Ξ v :
lazy۰inv t γ Ψ Ξ -∗
lazy۰result γ v ={⊤}=∗
▷ □ Ξ v.
Lemma lazyーinvーresultーconsumer t γ Ψ Ξ v Χ :
lazy۰inv t γ Ψ Ξ -∗
lazy۰result γ v -∗
lazy۰consumer γ Χ ={⊤}=∗
▷^2 Χ v ∗
▷ □ Ξ v.
Lemma lazy٠makeーspec Ψ Ξ fn :
{{{
WP fn () {{ v,
▷ Ψ v ∗
▷ □ Ξ v
}}
}}}
lazy٠make fn
{{{
t γ
, RET #t;
meta_token t ⊤ ∗
lazy۰inv t γ Ψ Ξ ∗
lazy۰consumer γ Ψ
}}}.
Lemma lazy٠returnーspec Ψ Ξ v :
{{{
▷ Ψ v ∗
▷ □ Ξ v
}}}
lazy٠return v
{{{
t γ
, RET #t;
meta_token t ⊤ ∗
lazy۰inv t γ Ψ Ξ ∗
lazy۰result γ v ∗
lazy۰consumer γ Ψ
}}}.
Lemma lazy٠is_setーspec t γ Ψ Ξ :
{{{
lazy۰inv t γ Ψ Ξ
}}}
lazy٠is_set #t
{{{
b
, RET #b;
if b then
£ 2 ∗
lazy۰resolved γ
else
True
}}}.
Lemma lazy٠is_setーspecーresult t γ Ψ Ξ v :
{{{
lazy۰inv t γ Ψ Ξ ∗
lazy۰result γ v
}}}
lazy٠is_set #t
{{{
RET true;
£ 2
}}}.
Lemma lazy٠is_unsetーspec t γ Ψ Ξ :
{{{
lazy۰inv t γ Ψ Ξ
}}}
lazy٠is_unset #t
{{{
b
, RET #b;
if b then
True
else
£ 2 ∗
lazy۰resolved γ
}}}.
Lemma lazy٠is_unsetーspecーresult t γ Ψ Ξ v :
{{{
lazy۰inv t γ Ψ Ξ ∗
lazy۰result γ v
}}}
lazy٠is_unset #t
{{{
RET false;
£ 2
}}}.
Lemma lazy٠getーspec t γ Ψ Ξ :
{{{
lazy۰inv t γ Ψ Ξ
}}}
lazy٠get #t
{{{
v
, RET v;
£ 2 ∗
lazy۰result γ v
}}}.
Lemma lazy٠getーspecーresult t γ Ψ Ξ v :
{{{
lazy۰inv t γ Ψ Ξ ∗
lazy۰result γ v
}}}
lazy٠get #t
{{{
RET v;
£ 2
}}}.
End lazy۰G.
#[global] Opaque lazy۰inv.
#[global] Opaque lazy۰consumer.
#[global] Opaque lazy۰result.
End base.
Require zoo_std.lazy__opaque.
Section lazy۰G.
Context `{lazy۰G : LazyG Σ}.
Implicit Type 𝑡 : location.
Implicit Type t : val.
Implicit Type γ : base.lazy۰name.
Implicit Type Ψ Χ Ξ : val → iProp Σ.
Definition lazy۰inv t Ψ Ξ : iProp Σ :=
∃ 𝑡 γ,
⌜t = #𝑡⌝ ∗
𝑡 ↪ γ ∗
base.lazy۰inv 𝑡 γ Ψ Ξ.
#[local] Instance : CustomIpat "inv" :=
" ( %l{} & %γ{} & {%Heq{};->} & #Hmeta{_{}} & Hinv{_{}} ) ".
Definition lazy۰consumer t Χ : iProp Σ :=
∃ 𝑡 γ,
⌜t = #𝑡⌝ ∗
𝑡 ↪ γ ∗
base.lazy۰consumer γ Χ.
#[local] Instance : CustomIpat "consumer" :=
" ( %l{;_} & %γ{;_} & {%Heq{};->} & #Hmeta{_{}} & Hconsumer{_{}} ) ".
Definition lazy۰result t v : iProp Σ :=
∃ 𝑡 γ,
⌜t = #𝑡⌝ ∗
𝑡 ↪ γ ∗
base.lazy۰result γ v.
#[local] Instance : CustomIpat "result" :=
" ( %l{;_} & %γ{;_} & {%Heq{};->} & #Hmeta{_{}} & Hresult{_{}} ) ".
Definition lazy۰resolved t : iProp Σ :=
∃ v,
lazy۰result t v.
#[global] Instance lazy۰invーcontractive t n :
Proper (
(pointwise_relation _ (dist_later n)) ==>
(pointwise_relation _ (dist_later n)) ==>
(≡{n}≡)
) (lazy۰inv t).
#[global] Instance lazy۰invーproper t :
Proper (
(pointwise_relation _ (≡)) ==>
(pointwise_relation _ (≡)) ==>
(≡)
) (lazy۰inv t).
#[global] Instance lazy۰consumerーcontractive t n :
Proper (
(pointwise_relation _ (dist_later n)) ==>
(≡{n}≡)
) (lazy۰consumer t).
#[global] Instance lazy۰consumerーproper t :
Proper (
(pointwise_relation _ (≡)) ==>
(≡)
) (lazy۰consumer t).
#[global] Instance lazy۰resultーtimeless t v :
Timeless (lazy۰result t v).
#[global] Instance lazy۰invーpersistent t Ψ Ξ :
Persistent (lazy۰inv t Ψ Ξ).
#[global] Instance lazy۰resultーpersistent t v :
Persistent (lazy۰result t v).
Lemma lazy۰consumerーwand {t Ψ Ξ Χ1} Χ2 :
lazy۰inv t Ψ Ξ -∗
lazy۰consumer t Χ1 -∗
(∀ v, Χ1 v -∗ Χ2 v) ={⊤}=∗
lazy۰consumer t Χ2.
Lemma lazy۰consumerーdivide {t Ψ Ξ} Χs :
lazy۰inv t Ψ Ξ -∗
lazy۰consumer t (λ v, [∗ list] Χ ∈ Χs, Χ v) ={⊤}=∗
[∗ list] Χ ∈ Χs, lazy۰consumer t Χ.
Lemma lazy۰consumerーsplit {t Ψ Ξ} Χ1 Χ2 :
lazy۰inv t Ψ Ξ -∗
lazy۰consumer t (λ v, Χ1 v ∗ Χ2 v) ={⊤}=∗
lazy۰consumer t Χ1 ∗
lazy۰consumer t Χ2.
Lemma lazy۰resultーagree t v1 v2 :
lazy۰result t v1 -∗
lazy۰result t v2 -∗
⌜v1 = v2⌝.
Lemma lazyーinvーresult t Ψ Ξ v :
lazy۰inv t Ψ Ξ -∗
lazy۰result t v ={⊤}=∗
▷ □ Ξ v.
Lemma lazyーinv_result' t Ψ Ξ v :
£ 1 -∗
lazy۰inv t Ψ Ξ -∗
lazy۰result t v ={⊤}=∗
□ Ξ v.
Lemma lazyーinvーresultーconsumer t Ψ Ξ v Χ :
lazy۰inv t Ψ Ξ -∗
lazy۰result t v -∗
lazy۰consumer t Χ ={⊤}=∗
▷^2 Χ v ∗
▷ □ Ξ v.
Lemma lazyーinvーresultーconsumer' t Ψ Ξ v Χ :
£ 2 -∗
lazy۰inv t Ψ Ξ -∗
lazy۰result t v -∗
lazy۰consumer t Χ ={⊤}=∗
Χ v ∗
□ Ξ v.
Lemma lazy٠makeーspec Ψ Ξ fn :
{{{
WP fn () {{ v,
▷ Ψ v ∗
▷ □ Ξ v
}}
}}}
lazy٠make fn
{{{
t
, RET t;
lazy۰inv t Ψ Ξ ∗
lazy۰consumer t Ψ
}}}.
Lemma lazy٠returnーspec Ψ Ξ v :
{{{
▷ Ψ v ∗
▷ □ Ξ v
}}}
lazy٠return v
{{{
t
, RET t;
lazy۰inv t Ψ Ξ ∗
lazy۰result t v ∗
lazy۰consumer t Ψ
}}}.
Lemma lazy٠is_setーspec t Ψ Ξ :
{{{
lazy۰inv t Ψ Ξ
}}}
lazy٠is_set t
{{{
b
, RET #b;
if b then
£ 2 ∗
lazy۰resolved t
else
True
}}}.
Lemma lazy٠is_setーspecーresult t Ψ Ξ v :
{{{
lazy۰inv t Ψ Ξ ∗
lazy۰result t v
}}}
lazy٠is_set t
{{{
RET true;
£ 2
}}}.
Lemma lazy٠is_unsetーspec t Ψ Ξ :
{{{
lazy۰inv t Ψ Ξ
}}}
lazy٠is_unset t
{{{
b
, RET #b;
if b then
True
else
£ 2 ∗
lazy۰resolved t
}}}.
Lemma lazy٠is_unsetーspecーresult t Ψ Ξ v :
{{{
lazy۰inv t Ψ Ξ ∗
lazy۰result t v
}}}
lazy٠is_unset t
{{{
RET false;
£ 2
}}}.
Lemma lazy٠getーspec t Ψ Ξ :
{{{
lazy۰inv t Ψ Ξ
}}}
lazy٠get t
{{{
v
, RET v;
£ 2 ∗
lazy۰result t v
}}}.
Lemma lazy٠getーspecーresult t Ψ Ξ v :
{{{
lazy۰inv t Ψ Ξ ∗
lazy۰result t v
}}}
lazy٠get t
{{{
RET v;
£ 2
}}}.
End lazy۰G.
#[global] Opaque lazy۰inv.
#[global] Opaque lazy۰consumer.
#[global] Opaque lazy۰result.