Library zoo_std.inf_array
Require Import Stdlib.Logic.FunctionalExtensionality.
Require Import zoo.prelude.
Require Import zoo.common.countable.
Require Import zoo.common.function.
Require Import zoo.iris.base_logic.lib.twins.
Require Import zoo.base.
Require Export zoo_std.inf_array__code.
Require Import zoo_std.inf_array__types.
Require Import zoo.options.
Implicit Type b : bool.
Implicit Type l : location.
Implicit Type pid : prophet_id.
Implicit Type v v_resolve t fn : val.
Implicit Type us : list val.
Implicit Type vs : nat → val.
Class InfArrayG Σ `{zoo۰G : !ZooG Σ} :=
{ #[local] inf_array۰G۰mutex۰G :: MutexG Σ
; #[local] inf_array۰G۰model۰G :: TwinsG Σ (nat -d> val_O)
}.
Definition inf_array۰Σ :=
#[mutex۰Σ
; twins۰Σ (nat -d> val_O)
].
#[global] Instance subGーinf_array۰Σ Σ `{zoo۰G : !ZooG Σ} :
subG inf_array۰Σ Σ →
InfArrayG Σ .
Section inf_array۰G.
Context `{inf_array۰G : InfArrayG Σ}.
Record metadata :=
{ metadata۰default : val
; metadata۰model : gname
}.
Implicit Type γ : metadata.
#[local] Instance metadataーeq_dec : EqDecision metadata :=
ltac:(solve_decision).
#[local] Instance metadataーcountable :
Countable metadata.
#[local] Definition model₁' γ_model vs :=
twins۰twin₁ γ_model (DfracOwn 1) vs.
#[local] Definition model₁ γ vs :=
model₁' γ.(metadata۰model) vs.
#[local] Definition model₂' γ_model vs :=
twins۰twin₂ γ_model vs.
#[local] Definition model₂ γ vs :=
model₂' γ.(metadata۰model) vs.
#[local] Definition inv₂ l γ us : iProp Σ :=
∃ data vs,
l.[data] ↦ data ∗
array۰model data (DfracOwn 1) us ∗
model₂ γ vs ∗
⌜vs = λ i, if decide (i < length us) then us !!! i else γ.(metadata۰default)⌝.
#[local] Instance : CustomIpat "inv₂" :=
" ( %data & %vs & Hl_data & Hdata & Hmodel₂ & %Hvs ) ".
#[local] Definition inv₁ l γ : iProp Σ :=
∃ us,
inv₂ l γ us.
#[local] Instance : CustomIpat "inv₁" :=
" ( %us{} & {{lazy}Hinv;(:inv₂)} ) ".
Definition inf_array۰inv t : iProp Σ :=
∃ l γ mtx,
⌜t = #l⌝ ∗
l ↪ γ ∗
l.[default] ↦□ γ.(metadata۰default) ∗
l.[mutex] ↦□ mtx ∗
mutex۰inv mtx (inv₁ l γ).
#[local] Instance : CustomIpat "inv" :=
" ( %l & %γ & %mtx & -> & #Hmeta & #Hl_mtx & #Hl_default & #Hmtx_inv ) ".
Definition inf_array۰model t vs : iProp Σ :=
∃ l γ,
⌜t = #l⌝ ∗
l ↪ γ ∗
model₁ γ vs.
#[local] Instance : CustomIpat "model" :=
" ( %l_ & %γ_ & %Heq & #Hmeta_ & Hmodel₁ ) ".
Definition inf_array۰model' t vsₗ vsᵣ :=
inf_array۰model t (
λ i,
if decide (i < length vsₗ) then vsₗ !!! i else vsᵣ (i - length vsₗ)
).
#[global] Instance inf_array۰invーpersistent t :
Persistent (inf_array۰inv t).
#[global] Instance inf_array۰modelーne t n :
Proper (pointwise_relation nat (=) ==> (≡{n}≡)) (inf_array۰model t).
#[global] Instance inf_array۰modelーproper t :
Proper (pointwise_relation nat (=) ==> (≡)) (inf_array۰model t).
#[global] Instance inf_array۰modelーtimeless t vs :
Timeless (inf_array۰model t vs).
#[global] Instance inf_array۰model'ーne t n :
Proper ((=) ==> pointwise_relation nat (=) ==> (≡{n}≡)) (inf_array۰model' t).
#[global] Instance inf_array۰model'ーproper t :
Proper ((=) ==> pointwise_relation nat (=) ==> (≡)) (inf_array۰model' t).
#[global] Instance inf_array۰model'ーtimeless t vsₗ vsᵣ :
Timeless (inf_array۰model' t vsₗ vsᵣ).
#[local] Lemma modelーalloc default :
⊢ |==>
∃ γ_model,
model₁' γ_model (λ _, default) ∗
model₂' γ_model (λ _, default).
#[local] Lemma modelーagree γ vs1 vs2 :
model₁ γ vs1 -∗
model₂ γ vs2 -∗
⌜vs1 = vs2⌝.
#[local] Lemma modelーupdate {γ vs1 vs2} vs :
model₁ γ vs1 -∗
model₂ γ vs2 ==∗
model₁ γ vs ∗
model₂ γ vs.
Lemma inf_array۰modelーtoーmodel' {t vs} vsₗ :
(∀ i v, vsₗ !! i = Some v → vs i = v) →
inf_array۰model t vs ⊢
inf_array۰model' t vsₗ (λ i, vs (length vsₗ + i)).
Lemma inf_array۰modelーtoーmodel'ーreplicate {t vs} n v :
(∀ i, i < n → vs i = v) →
inf_array۰model t vs ⊢
inf_array۰model' t (replicate n v) (λ i, vs (n + i)).
Lemma inf_array۰modelーtoーmodel'ーconstant {t v} n :
inf_array۰model t (λ _, v) ⊢
inf_array۰model' t (replicate n v) (λ _, v).
Lemma inf_array۰model'ーshift t vsₗ v vsᵣ :
inf_array۰model' t (vsₗ ++ [v]) vsᵣ ⊣⊢
inf_array۰model' t vsₗ (v .: vsᵣ).
Lemma inf_array۰model'ーshiftーr t vsₗ v vsᵣ :
inf_array۰model' t (vsₗ ++ [v]) vsᵣ ⊢
inf_array۰model' t vsₗ (v .: vsᵣ).
Lemma inf_array۰model'ーshiftーl t vsₗ vsᵣ v vsᵣ' :
vsᵣ ≡ᶠ v .: vsᵣ' →
inf_array۰model' t vsₗ vsᵣ ⊢
inf_array۰model' t (vsₗ ++ [v]) vsᵣ'.
Lemma inf_array۰model'ーshiftーl' t vsₗ vsᵣ :
inf_array۰model' t vsₗ vsᵣ ⊢
inf_array۰model' t (vsₗ ++ [vsᵣ 0]) (vsᵣ ∘ S).
Lemma inf_array٠createーspec default :
{{{
True
}}}
inf_array٠create default
{{{
t
, RET t;
inf_array۰inv t ∗
inf_array۰model t (λ _, default)
}}}.
#[local] Lemma inf_array٠next_capacityーspec n :
(0 ≤ n)%Z →
{{{
True
}}}
inf_array٠next_capacity #n
{{{
m
, RET #m;
⌜n ≤ m⌝%Z
}}}.
#[local] Lemma inf_array٠reserveーspec l γ us n :
(0 ≤ n)%Z →
{{{
l.[default] ↦□ γ.(metadata۰default) ∗
inv₂ l γ us
}}}
inf_array٠reserve #l #n
{{{
us
, RET ();
inv₂ l γ us ∗
⌜₊n ≤ length us⌝
}}}.
Lemma inf_array٠getーspec t i :
(0 ≤ i)%Z →
<<<
inf_array۰inv t
| ∀∀ vs,
inf_array۰model t vs
>>>
inf_array٠get t #i
<<<
inf_array۰model t vs
| RET vs ₊i;
£ 1
>>>.
Lemma inf_array٠getーspec' t i :
(0 ≤ i)%Z →
<<<
inf_array۰inv t
| ∀∀ vsₗ vsᵣ,
inf_array۰model' t vsₗ vsᵣ
>>>
inf_array٠get t #i
<<<
inf_array۰model' t vsₗ vsᵣ
| RET
if decide (₊i < length vsₗ) then
vsₗ !!! ₊i
else
vsᵣ (₊i - length vsₗ);
£ 1
>>>.
Lemma inf_array٠updateーspec Ψ1 Ψ2 t i fn :
(0 ≤ i)%Z →
<<<
inf_array۰inv t ∗
(∀ v, Ψ1 v -∗ WP fn v {{ Ψ2 v }})
| ∀∀ vs,
inf_array۰model t vs ∗
□ Ψ1 (vs ₊i)
>>>
inf_array٠update t #i fn
<<<
∃∃ v,
inf_array۰model t (<[₊i := v]> vs) ∗
Ψ2 (vs ₊i) v
| RET vs ₊i;
£ 1
>>>.
Lemma inf_array٠xchgーspec t i v :
(0 ≤ i)%Z →
<<<
inf_array۰inv t
| ∀∀ vs,
inf_array۰model t vs
>>>
inf_array٠xchg t #i v
<<<
inf_array۰model t (<[₊i := v]> vs)
| RET vs ₊i;
£ 1
>>>.
Lemma inf_array٠xchg_resolveーspec t i v pid v_resolve Φ E :
(0 ≤ i)%Z →
inf_array۰inv t -∗
( |={⊤,E}=>
∃ vs,
inf_array۰model t vs ∗
( ∀ e,
⌜PureExec True 1 e ()⌝ -∗
⌜to_val e = None⌝ -∗
inf_array۰model t (<[₊i := v]> vs) -∗
WP Resolve e #pid v_resolve @ E {{ _,
|={E,⊤}=>
Φ (vs ₊i)
}}
)
) -∗
WP inf_array٠xchg_resolve t #i v #pid v_resolve {{ Φ }}.
Lemma inf_array٠setーspec t i v :
(0 ≤ i)%Z →
<<<
inf_array۰inv t
| ∀∀ vs,
inf_array۰model t vs
>>>
inf_array٠set t #i v
<<<
inf_array۰model t (<[₊i := v]> vs)
| RET ();
£ 1
>>>.
Lemma inf_array٠setーspec' t i v :
(0 ≤ i)%Z →
<<<
inf_array۰inv t
| ∀∀ vsₗ vsᵣ,
inf_array۰model' t vsₗ vsᵣ
>>>
inf_array٠set t #i v
<<<
if decide (₊i < length vsₗ) then
inf_array۰model' t (<[₊i := v]> vsₗ) vsᵣ
else
inf_array۰model' t vsₗ (<[₊i - length vsₗ := v]> vsᵣ)
| RET ();
£ 1
>>>.
Lemma inf_array٠casーspec t i v1 v2 :
(0 ≤ i)%Z →
<<<
inf_array۰inv t
| ∀∀ vs,
inf_array۰model t vs
>>>
inf_array٠cas t #i v1 v2
<<<
∃∃ b,
⌜(if b then (≈) else (≉)) (vs ₊i) v1⌝ ∗
inf_array۰model t (if b then <[₊i := v2]> vs else vs)
| RET #b;
£ 1
>>>.
Lemma inf_array٠cas_resolveーspec t i v1 v2 pid v_resolve Φ E :
(0 ≤ i)%Z →
inf_array۰inv t -∗
( |={⊤,E}=>
∃ vs,
inf_array۰model t vs ∗
( ∀ e b,
⌜PureExec True 1 e ()⌝ -∗
⌜to_val e = None⌝ -∗
⌜(if b then (≈) else (≉)) (vs ₊i) v1⌝ -∗
inf_array۰model t (if b then <[₊i := v2]> vs else vs) -∗
WP Resolve e #pid v_resolve @ E {{ _,
|={E,⊤}=>
Φ #b
}}
)
) -∗
WP inf_array٠cas_resolve t #i v1 v2 #pid v_resolve {{ Φ }}.
Lemma inf_array٠faaーspec t i (incr : Z) :
(0 ≤ i)%Z →
<<<
inf_array۰inv t
| ∀∀ vs (n : Z),
⌜vs ₊i = #n⌝ ∗
inf_array۰model t vs
>>>
inf_array٠faa t #i #incr
<<<
inf_array۰model t (<[₊i := #(n + incr)]> vs)
| RET vs ₊i;
£ 1
>>>.
End inf_array۰G.
Require zoo_std.inf_array__opaque.
#[global] Opaque inf_array۰inv.
#[global] Opaque inf_array۰model.
#[global] Opaque inf_array۰model'.
Require Import zoo.prelude.
Require Import zoo.common.countable.
Require Import zoo.common.function.
Require Import zoo.iris.base_logic.lib.twins.
Require Import zoo.base.
Require Export zoo_std.inf_array__code.
Require Import zoo_std.inf_array__types.
Require Import zoo.options.
Implicit Type b : bool.
Implicit Type l : location.
Implicit Type pid : prophet_id.
Implicit Type v v_resolve t fn : val.
Implicit Type us : list val.
Implicit Type vs : nat → val.
Class InfArrayG Σ `{zoo۰G : !ZooG Σ} :=
{ #[local] inf_array۰G۰mutex۰G :: MutexG Σ
; #[local] inf_array۰G۰model۰G :: TwinsG Σ (nat -d> val_O)
}.
Definition inf_array۰Σ :=
#[mutex۰Σ
; twins۰Σ (nat -d> val_O)
].
#[global] Instance subGーinf_array۰Σ Σ `{zoo۰G : !ZooG Σ} :
subG inf_array۰Σ Σ →
InfArrayG Σ .
Section inf_array۰G.
Context `{inf_array۰G : InfArrayG Σ}.
Record metadata :=
{ metadata۰default : val
; metadata۰model : gname
}.
Implicit Type γ : metadata.
#[local] Instance metadataーeq_dec : EqDecision metadata :=
ltac:(solve_decision).
#[local] Instance metadataーcountable :
Countable metadata.
#[local] Definition model₁' γ_model vs :=
twins۰twin₁ γ_model (DfracOwn 1) vs.
#[local] Definition model₁ γ vs :=
model₁' γ.(metadata۰model) vs.
#[local] Definition model₂' γ_model vs :=
twins۰twin₂ γ_model vs.
#[local] Definition model₂ γ vs :=
model₂' γ.(metadata۰model) vs.
#[local] Definition inv₂ l γ us : iProp Σ :=
∃ data vs,
l.[data] ↦ data ∗
array۰model data (DfracOwn 1) us ∗
model₂ γ vs ∗
⌜vs = λ i, if decide (i < length us) then us !!! i else γ.(metadata۰default)⌝.
#[local] Instance : CustomIpat "inv₂" :=
" ( %data & %vs & Hl_data & Hdata & Hmodel₂ & %Hvs ) ".
#[local] Definition inv₁ l γ : iProp Σ :=
∃ us,
inv₂ l γ us.
#[local] Instance : CustomIpat "inv₁" :=
" ( %us{} & {{lazy}Hinv;(:inv₂)} ) ".
Definition inf_array۰inv t : iProp Σ :=
∃ l γ mtx,
⌜t = #l⌝ ∗
l ↪ γ ∗
l.[default] ↦□ γ.(metadata۰default) ∗
l.[mutex] ↦□ mtx ∗
mutex۰inv mtx (inv₁ l γ).
#[local] Instance : CustomIpat "inv" :=
" ( %l & %γ & %mtx & -> & #Hmeta & #Hl_mtx & #Hl_default & #Hmtx_inv ) ".
Definition inf_array۰model t vs : iProp Σ :=
∃ l γ,
⌜t = #l⌝ ∗
l ↪ γ ∗
model₁ γ vs.
#[local] Instance : CustomIpat "model" :=
" ( %l_ & %γ_ & %Heq & #Hmeta_ & Hmodel₁ ) ".
Definition inf_array۰model' t vsₗ vsᵣ :=
inf_array۰model t (
λ i,
if decide (i < length vsₗ) then vsₗ !!! i else vsᵣ (i - length vsₗ)
).
#[global] Instance inf_array۰invーpersistent t :
Persistent (inf_array۰inv t).
#[global] Instance inf_array۰modelーne t n :
Proper (pointwise_relation nat (=) ==> (≡{n}≡)) (inf_array۰model t).
#[global] Instance inf_array۰modelーproper t :
Proper (pointwise_relation nat (=) ==> (≡)) (inf_array۰model t).
#[global] Instance inf_array۰modelーtimeless t vs :
Timeless (inf_array۰model t vs).
#[global] Instance inf_array۰model'ーne t n :
Proper ((=) ==> pointwise_relation nat (=) ==> (≡{n}≡)) (inf_array۰model' t).
#[global] Instance inf_array۰model'ーproper t :
Proper ((=) ==> pointwise_relation nat (=) ==> (≡)) (inf_array۰model' t).
#[global] Instance inf_array۰model'ーtimeless t vsₗ vsᵣ :
Timeless (inf_array۰model' t vsₗ vsᵣ).
#[local] Lemma modelーalloc default :
⊢ |==>
∃ γ_model,
model₁' γ_model (λ _, default) ∗
model₂' γ_model (λ _, default).
#[local] Lemma modelーagree γ vs1 vs2 :
model₁ γ vs1 -∗
model₂ γ vs2 -∗
⌜vs1 = vs2⌝.
#[local] Lemma modelーupdate {γ vs1 vs2} vs :
model₁ γ vs1 -∗
model₂ γ vs2 ==∗
model₁ γ vs ∗
model₂ γ vs.
Lemma inf_array۰modelーtoーmodel' {t vs} vsₗ :
(∀ i v, vsₗ !! i = Some v → vs i = v) →
inf_array۰model t vs ⊢
inf_array۰model' t vsₗ (λ i, vs (length vsₗ + i)).
Lemma inf_array۰modelーtoーmodel'ーreplicate {t vs} n v :
(∀ i, i < n → vs i = v) →
inf_array۰model t vs ⊢
inf_array۰model' t (replicate n v) (λ i, vs (n + i)).
Lemma inf_array۰modelーtoーmodel'ーconstant {t v} n :
inf_array۰model t (λ _, v) ⊢
inf_array۰model' t (replicate n v) (λ _, v).
Lemma inf_array۰model'ーshift t vsₗ v vsᵣ :
inf_array۰model' t (vsₗ ++ [v]) vsᵣ ⊣⊢
inf_array۰model' t vsₗ (v .: vsᵣ).
Lemma inf_array۰model'ーshiftーr t vsₗ v vsᵣ :
inf_array۰model' t (vsₗ ++ [v]) vsᵣ ⊢
inf_array۰model' t vsₗ (v .: vsᵣ).
Lemma inf_array۰model'ーshiftーl t vsₗ vsᵣ v vsᵣ' :
vsᵣ ≡ᶠ v .: vsᵣ' →
inf_array۰model' t vsₗ vsᵣ ⊢
inf_array۰model' t (vsₗ ++ [v]) vsᵣ'.
Lemma inf_array۰model'ーshiftーl' t vsₗ vsᵣ :
inf_array۰model' t vsₗ vsᵣ ⊢
inf_array۰model' t (vsₗ ++ [vsᵣ 0]) (vsᵣ ∘ S).
Lemma inf_array٠createーspec default :
{{{
True
}}}
inf_array٠create default
{{{
t
, RET t;
inf_array۰inv t ∗
inf_array۰model t (λ _, default)
}}}.
#[local] Lemma inf_array٠next_capacityーspec n :
(0 ≤ n)%Z →
{{{
True
}}}
inf_array٠next_capacity #n
{{{
m
, RET #m;
⌜n ≤ m⌝%Z
}}}.
#[local] Lemma inf_array٠reserveーspec l γ us n :
(0 ≤ n)%Z →
{{{
l.[default] ↦□ γ.(metadata۰default) ∗
inv₂ l γ us
}}}
inf_array٠reserve #l #n
{{{
us
, RET ();
inv₂ l γ us ∗
⌜₊n ≤ length us⌝
}}}.
Lemma inf_array٠getーspec t i :
(0 ≤ i)%Z →
<<<
inf_array۰inv t
| ∀∀ vs,
inf_array۰model t vs
>>>
inf_array٠get t #i
<<<
inf_array۰model t vs
| RET vs ₊i;
£ 1
>>>.
Lemma inf_array٠getーspec' t i :
(0 ≤ i)%Z →
<<<
inf_array۰inv t
| ∀∀ vsₗ vsᵣ,
inf_array۰model' t vsₗ vsᵣ
>>>
inf_array٠get t #i
<<<
inf_array۰model' t vsₗ vsᵣ
| RET
if decide (₊i < length vsₗ) then
vsₗ !!! ₊i
else
vsᵣ (₊i - length vsₗ);
£ 1
>>>.
Lemma inf_array٠updateーspec Ψ1 Ψ2 t i fn :
(0 ≤ i)%Z →
<<<
inf_array۰inv t ∗
(∀ v, Ψ1 v -∗ WP fn v {{ Ψ2 v }})
| ∀∀ vs,
inf_array۰model t vs ∗
□ Ψ1 (vs ₊i)
>>>
inf_array٠update t #i fn
<<<
∃∃ v,
inf_array۰model t (<[₊i := v]> vs) ∗
Ψ2 (vs ₊i) v
| RET vs ₊i;
£ 1
>>>.
Lemma inf_array٠xchgーspec t i v :
(0 ≤ i)%Z →
<<<
inf_array۰inv t
| ∀∀ vs,
inf_array۰model t vs
>>>
inf_array٠xchg t #i v
<<<
inf_array۰model t (<[₊i := v]> vs)
| RET vs ₊i;
£ 1
>>>.
Lemma inf_array٠xchg_resolveーspec t i v pid v_resolve Φ E :
(0 ≤ i)%Z →
inf_array۰inv t -∗
( |={⊤,E}=>
∃ vs,
inf_array۰model t vs ∗
( ∀ e,
⌜PureExec True 1 e ()⌝ -∗
⌜to_val e = None⌝ -∗
inf_array۰model t (<[₊i := v]> vs) -∗
WP Resolve e #pid v_resolve @ E {{ _,
|={E,⊤}=>
Φ (vs ₊i)
}}
)
) -∗
WP inf_array٠xchg_resolve t #i v #pid v_resolve {{ Φ }}.
Lemma inf_array٠setーspec t i v :
(0 ≤ i)%Z →
<<<
inf_array۰inv t
| ∀∀ vs,
inf_array۰model t vs
>>>
inf_array٠set t #i v
<<<
inf_array۰model t (<[₊i := v]> vs)
| RET ();
£ 1
>>>.
Lemma inf_array٠setーspec' t i v :
(0 ≤ i)%Z →
<<<
inf_array۰inv t
| ∀∀ vsₗ vsᵣ,
inf_array۰model' t vsₗ vsᵣ
>>>
inf_array٠set t #i v
<<<
if decide (₊i < length vsₗ) then
inf_array۰model' t (<[₊i := v]> vsₗ) vsᵣ
else
inf_array۰model' t vsₗ (<[₊i - length vsₗ := v]> vsᵣ)
| RET ();
£ 1
>>>.
Lemma inf_array٠casーspec t i v1 v2 :
(0 ≤ i)%Z →
<<<
inf_array۰inv t
| ∀∀ vs,
inf_array۰model t vs
>>>
inf_array٠cas t #i v1 v2
<<<
∃∃ b,
⌜(if b then (≈) else (≉)) (vs ₊i) v1⌝ ∗
inf_array۰model t (if b then <[₊i := v2]> vs else vs)
| RET #b;
£ 1
>>>.
Lemma inf_array٠cas_resolveーspec t i v1 v2 pid v_resolve Φ E :
(0 ≤ i)%Z →
inf_array۰inv t -∗
( |={⊤,E}=>
∃ vs,
inf_array۰model t vs ∗
( ∀ e b,
⌜PureExec True 1 e ()⌝ -∗
⌜to_val e = None⌝ -∗
⌜(if b then (≈) else (≉)) (vs ₊i) v1⌝ -∗
inf_array۰model t (if b then <[₊i := v2]> vs else vs) -∗
WP Resolve e #pid v_resolve @ E {{ _,
|={E,⊤}=>
Φ #b
}}
)
) -∗
WP inf_array٠cas_resolve t #i v1 v2 #pid v_resolve {{ Φ }}.
Lemma inf_array٠faaーspec t i (incr : Z) :
(0 ≤ i)%Z →
<<<
inf_array۰inv t
| ∀∀ vs (n : Z),
⌜vs ₊i = #n⌝ ∗
inf_array۰model t vs
>>>
inf_array٠faa t #i #incr
<<<
inf_array۰model t (<[₊i := #(n + incr)]> vs)
| RET vs ₊i;
£ 1
>>>.
End inf_array۰G.
Require zoo_std.inf_array__opaque.
#[global] Opaque inf_array۰inv.
#[global] Opaque inf_array۰model.
#[global] Opaque inf_array۰model'.