Library zoo_std.array
Require Import Stdlib.micromega.ZifyNat.
Require Import zoo.prelude.
Require Import zoo.common.list.
Require Import zoo.common.math.
Require Import zoo.iris.bi.big_op.
Require Import zoo.base.
Require Import zoo_std.chunk.
Require Export zoo_std.array__code.
Require Import zoo_std.array__types.
Require Import zoo.options.
Implicit Type b : bool.
Implicit Type i j k n : nat.
Implicit Type l : location.
Implicit Type v t fn acc : val.
Implicit Type vs vs_left vs_right ws : list val.
Definition array٠unsafe_xchg : val :=
𝗳𝘂𝗻 "t" "i" "v" →
Xchg ("t", "i") "v".
Definition array٠unsafe_cas : val :=
𝗳𝘂𝗻 "t" "i" "v1" "v2" →
CAS ("t", "i") "v1" "v2".
Definition array٠unsafe_faa : val :=
𝗳𝘂𝗻 "t" "i" "incr" →
FAA ("t", "i") "incr".
Section zoo۰G.
Context `{zoo۰G : !ZooG Σ}.
Section array۰inv.
Definition array۰inv t (sz : nat) : iProp Σ :=
∃ l,
⌜t = #l⌝ ∗
l ↦ₕ Header 0 sz.
#[global] Instance array۰invーtimeless t sz :
Timeless (array۰inv t sz).
#[global] Instance array۰invーpersistent t sz :
Persistent (array۰inv t sz).
Lemma array۰invーagree t sz1 sz2 :
array۰inv t sz1 -∗
array۰inv t sz2 -∗
⌜sz1 = sz2⌝.
End array۰inv.
Section array۰slice.
Definition array۰slice t i dq vs : iProp Σ :=
∃ l,
⌜t = #l⌝ ∗
chunk۰model (l +ₗ i) dq vs.
#[global] Instance array۰sliceーtimeless t i dq vs :
Timeless (array۰slice t i dq vs).
#[global] Instance array۰sliceーpersistent t i vs :
Persistent (array۰slice t i DfracDiscarded vs).
#[global] Instance array۰sliceーfractional t i vs :
Fractional (λ q, array۰slice t i (DfracOwn q) vs).
#[global] Instance array۰sliceーas_fractional t i q vs :
AsFractional (array۰slice t i (DfracOwn q) vs) (λ q, array۰slice t i (DfracOwn q) vs) q.
Lemma array۰sliceーvalid t i dq vs :
0 < length vs →
array۰slice t i dq vs ⊢
⌜✓ dq⌝.
Lemma array۰sliceーcombine t i dq1 vs1 dq2 vs2 :
length vs1 = length vs2 →
array۰slice t i dq1 vs1 -∗
array۰slice t i dq2 vs2 -∗
⌜vs1 = vs2⌝ ∗
array۰slice t i (dq1 ⋅ dq2) vs1.
Lemma array۰sliceーvalidー2 t i dq1 vs1 dq2 vs2 :
0 < length vs1 →
length vs1 = length vs2 →
array۰slice t i dq1 vs1 -∗
array۰slice t i dq2 vs2 -∗
⌜✓ (dq1 ⋅ dq2)⌝ ∗
⌜vs1 = vs2⌝.
Lemma array۰sliceーagree t i dq1 vs1 dq2 vs2 :
length vs1 = length vs2 →
array۰slice t i dq1 vs1 -∗
array۰slice t i dq2 vs2 -∗
⌜vs1 = vs2⌝.
Lemma array۰sliceーdfracーne t1 i1 dq1 vs1 t2 i2 dq2 vs2 :
0 < length vs1 →
length vs1 = length vs2 →
¬ ✓ (dq1 ⋅ dq2) →
array۰slice t1 i1 dq1 vs1 -∗
array۰slice t2 i2 dq2 vs2 -∗
⌜t1 ≠ t2 ∨ i1 ≠ i2⌝.
Lemma array۰sliceーne t1 i1 vs1 t2 i2 dq2 vs2 :
0 < length vs1 →
length vs1 = length vs2 →
array۰slice t1 i1 (DfracOwn 1) vs1 -∗
array۰slice t2 i2 dq2 vs2 -∗
⌜t1 ≠ t2 ∨ i1 ≠ i2⌝.
Lemma array۰sliceーexclusive t i vs1 dq2 vs2 :
0 < length vs1 →
length vs1 = length vs2 →
array۰slice t i (DfracOwn 1) vs1 -∗
array۰slice t i dq2 vs2 -∗
False.
Lemma array۰sliceーpersist t i dq vs :
array۰slice t i dq vs ⊢ |==>
array۰slice t i DfracDiscarded vs.
Lemma array۰sliceーnil {t i1 dq1 vs1} i2 dq2 :
array۰slice t i1 dq1 vs1 ⊢
array۰slice t i2 dq2 [].
Lemma array۰sliceーapp t i dq vs1 vs2 :
array۰slice t i dq vs1 ∗
array۰slice t (i + length vs1) dq vs2 ⊣⊢
array۰slice t i dq (vs1 ++ vs2).
Lemma array۰sliceーapp₁ t i dq vs1 vs2 :
array۰slice t i dq vs1 -∗
array۰slice t (i + length vs1) dq vs2 -∗
array۰slice t i dq (vs1 ++ vs2).
Lemma array۰sliceーapp₁' {t dq i1 vs1} i2 vs2 :
i2 = i1 + length vs1 →
array۰slice t i1 dq vs1 -∗
array۰slice t i2 dq vs2 -∗
array۰slice t i1 dq (vs1 ++ vs2).
Lemma array۰sliceーapp₂ {t i dq vs} vs1 vs2 :
vs = vs1 ++ vs2 →
array۰slice t i dq vs ⊢
array۰slice t i dq vs1 ∗
array۰slice t (i + length vs1) dq vs2.
Lemma array۰sliceーappー3 {t i dq} vs1 vs2 vs3 :
array۰slice t i dq vs1 ∗
array۰slice t (i + length vs1) dq vs2 ∗
array۰slice t (i + length vs1 + length vs2) dq vs3 ⊣⊢
array۰slice t i dq (vs1 ++ vs2 ++ vs3).
Lemma array۰sliceーappー3₁ t dq i1 vs1 i2 vs2 i3 vs3 :
i2 = i1 + length vs1 →
i3 = i1 + length vs1 + length vs2 →
array۰slice t i1 dq vs1 -∗
array۰slice t i2 dq vs2 -∗
array۰slice t i3 dq vs3 -∗
array۰slice t i1 dq (vs1 ++ vs2 ++ vs3).
Lemma array۰sliceーappー3₂ {t i dq vs} vs1 vs2 vs3 :
vs = vs1 ++ vs2 ++ vs3 →
array۰slice t i dq vs ⊢
array۰slice t i dq vs1 ∗
array۰slice t (i + length vs1) dq vs2 ∗
array۰slice t (i + length vs1 + length vs2) dq vs3.
Lemma array۰sliceーcons t i dq v vs :
array۰slice t i dq (v :: vs) ⊣⊢
array۰slice t i dq [v] ∗
array۰slice t ˖i dq vs.
Lemma array۰sliceーcons₁ t i dq v vs :
array۰slice t i dq (v :: vs) ⊢
array۰slice t i dq [v] ∗
array۰slice t ˖i dq vs.
Lemma array۰sliceーcons₂ t i dq v vs :
array۰slice t i dq [v] -∗
array۰slice t ˖i dq vs -∗
array۰slice t i dq (v :: vs).
Lemma array۰sliceーcons₂' t i1 dq v i2 vs :
i2 = ˖i1 →
array۰slice t i1 dq [v] -∗
array۰slice t i2 dq vs -∗
array۰slice t i1 dq (v :: vs).
Lemma array۰sliceーatomize t i dq vs :
array۰slice t i dq vs ⊢
[∗ list] j ↦ v ∈ vs,
array۰slice t (i + j) dq [v].
Lemma array۰sliceーupdate {t i dq vs} j v :
vs !! j = Some v →
array۰slice t i dq vs ⊢
array۰slice t (i + j) dq [v] ∗
( ∀ w,
array۰slice t (i + j) dq [w] -∗
array۰slice t i dq (<[j := w]> vs)
).
Lemma array۰sliceーlookupーacc {t i dq vs} j v :
vs !! j = Some v →
array۰slice t i dq vs ⊢
array۰slice t (i + j) dq [v] ∗
( array۰slice t (i + j) dq [v] -∗
array۰slice t i dq vs
).
Lemma array۰sliceーlookup {t i dq vs} j v :
vs !! j = Some v →
array۰slice t i dq vs ⊢
array۰slice t (i + j) dq [v].
End array۰slice.
Section array۰model.
Definition array۰model t dq vs : iProp Σ :=
∃ l,
⌜t = #l⌝ ∗
l ↦ₕ Header 0 (length vs) ∗
chunk۰model l dq vs.
Lemma array۰modelーtoーinv t dq vs :
array۰model t dq vs ⊢
array۰inv t (length vs).
Lemma array۰sliceーtoーmodel t sz dq vs :
sz = length vs →
array۰inv t sz -∗
array۰slice t 0 dq vs -∗
array۰model t dq vs.
Lemma array۰modelーtoーslice t dq vs :
array۰model t dq vs ⊣⊢
array۰inv t (length vs) ∗
array۰slice t 0 dq vs.
Lemma array۰modelーtoーslice' t dq vs :
array۰model t dq vs ⊢
array۰slice t 0 dq vs ∗
□ (
∀ vs',
⌜length vs' = length vs⌝ -∗
array۰slice t 0 dq vs' -∗
array۰model t dq vs'
).
#[global] Instance array۰modelーtimeless t dq vs :
Timeless (array۰model t dq vs).
#[global] Instance array۰modelーpersistent t vs :
Persistent (array۰model t DfracDiscarded vs).
#[global] Instance array۰modelーfractional t vs :
Fractional (λ q, array۰model t (DfracOwn q) vs).
#[global] Instance array۰modelーas_fractional t q vs :
AsFractional (array۰model t (DfracOwn q) vs) (λ q, array۰model t (DfracOwn q) vs) q.
Lemma arrayーinvーmodelーagree t sz dq vs :
array۰inv t sz -∗
array۰model t dq vs -∗
⌜length vs = sz⌝.
Lemma array۰modelーvalid t dq vs :
0 < length vs →
array۰model t dq vs ⊢
⌜✓ dq⌝.
Lemma array۰modelーcombine t dq1 vs1 dq2 vs2 :
array۰model t dq1 vs1 -∗
array۰model t dq2 vs2 -∗
⌜vs1 = vs2⌝ ∗
array۰model t (dq1 ⋅ dq2) vs1.
Lemma array۰modelーvalidー2 t dq1 vs1 dq2 vs2 :
0 < length vs1 →
array۰model t dq1 vs1 -∗
array۰model t dq2 vs2 -∗
⌜✓ (dq1 ⋅ dq2)⌝ ∗
⌜vs1 = vs2⌝.
Lemma array۰modelーagree t dq1 vs1 dq2 vs2 :
array۰model t dq1 vs1 -∗
array۰model t dq2 vs2 -∗
⌜vs1 = vs2⌝.
Lemma array۰modelーdfracーne t1 dq1 vs1 t2 dq2 vs2 :
0 < length vs1 →
¬ ✓ (dq1 ⋅ dq2) →
array۰model t1 dq1 vs1 -∗
array۰model t2 dq2 vs2 -∗
⌜t1 ≠ t2⌝.
Lemma array۰modelーne t1 vs1 t2 dq2 vs2 :
0 < length vs1 →
array۰model t1 (DfracOwn 1) vs1 -∗
array۰model t2 dq2 vs2 -∗
⌜t1 ≠ t2⌝.
Lemma array۰modelーexclusive t vs1 dq2 vs2 :
0 < length vs1 →
array۰model t (DfracOwn 1) vs1 -∗
array۰model t dq2 vs2 -∗
False.
Lemma array۰modelーpersist t dq vs :
array۰model t dq vs ⊢ |==>
array۰model t DfracDiscarded vs.
Lemma array۰modelーatomize t dq vs :
array۰model t dq vs ⊢
array۰inv t (length vs) ∗
[∗ list] i ↦ v ∈ vs,
array۰slice t i dq [v].
#[local] Typeclasses Opaque array۰slice.
Lemma array۰modelーupdate {t dq vs} i v :
vs !! i = Some v →
array۰model t dq vs ⊢
array۰inv t (length vs) ∗
array۰slice t i dq [v] ∗
( ∀ w,
array۰slice t i dq [w] -∗
array۰model t dq (<[i := w]> vs)
).
Lemma array۰modelーlookupーacc {t dq vs} i v :
vs !! i = Some v →
array۰model t dq vs ⊢
array۰slice t i dq [v] ∗
( array۰slice t i dq [v] -∗
array۰model t dq vs
).
Lemma array۰modelーlookup {t dq vs} i v :
vs !! i = Some v →
array۰model t dq vs ⊢
array۰slice t i dq [v].
End array۰model.
Section array۰cslice.
Definition array۰cslice t (sz : nat) i dq vs : iProp Σ :=
∃ l,
⌜t = #l⌝ ∗
l ↦ₕ Header 0 sz ∗
chunk۰cslice l sz i dq vs.
Lemma array۰csliceーtoーinv t sz i dq vs :
array۰cslice t sz i dq vs ⊢
array۰inv t sz.
Lemma array۰modelーtoーcslice t dq vs :
array۰model t dq vs ⊢
array۰cslice t (length vs) 0 dq vs.
Lemma array۰csliceーtoーslice t sz i dq vs :
0 < sz →
length vs ≤ sz →
array۰cslice t sz i dq vs ⊣⊢
array۰inv t sz ∗
array۰slice t (i `mod` sz) dq (take (sz - i `mod` sz) vs) ∗
array۰slice t 0 dq (drop (sz - i `mod` sz) vs).
Lemma array۰csliceーtoーslice' t sz i dq vs :
0 < sz →
length vs ≤ sz →
array۰cslice t sz i dq vs ⊢
array۰slice t (i `mod` sz) dq (take (sz - i `mod` sz) vs) ∗
array۰slice t 0 dq (drop (sz - i `mod` sz) vs).
Lemma array۰csliceーtoーmodel t sz i dq vs :
0 < sz →
length vs = sz →
array۰cslice t sz i dq vs ⊣⊢
array۰model t dq (rotation (sz - i `mod` sz) vs).
Lemma array۰csliceーtoーsliceーcell t sz i dq v :
array۰cslice t sz i dq [v] ⊣⊢
array۰inv t sz ∗
array۰slice t (i `mod` sz) dq [v].
Lemma array۰csliceーtoーsliceーcell' t sz i dq v :
array۰cslice t sz i dq [v] ⊢
array۰slice t (i `mod` sz) dq [v].
Lemma array۰sliceーtoーcsliceーcell t sz i dq v :
array۰inv t sz -∗
array۰slice t (i `mod` sz) dq [v] -∗
array۰cslice t sz i dq [v].
#[global] Instance array۰csliceーtimeless t sz i dq vs :
Timeless (array۰cslice t sz i dq vs).
#[global] Instance array۰csliceーpersistent t sz i vs :
Persistent (array۰cslice t sz i DfracDiscarded vs).
#[global] Instance array۰csliceーfractional t sz i vs :
Fractional (λ q, array۰cslice t sz i (DfracOwn q) vs).
#[global] Instance array۰csliceーas_fractional t sz i q vs :
AsFractional (array۰cslice t sz i (DfracOwn q) vs) (λ q, array۰cslice t sz i (DfracOwn q) vs) q.
Lemma arrayーinvーcsliceーagree t sz1 sz2 i dq vs :
array۰inv t sz1 -∗
array۰cslice t sz2 i dq vs -∗
⌜sz1 = sz2⌝.
Lemma array۰csliceーnil t sz i dq :
array۰inv t sz ⊢
array۰cslice t sz i dq [].
Lemma array۰csliceーapp t sz i dq vs1 vs2 :
array۰cslice t sz i dq vs1 ∗
array۰cslice t sz (i + length vs1) dq vs2 ⊣⊢
array۰cslice t sz i dq (vs1 ++ vs2).
Lemma array۰csliceーapp₁ t sz dq i1 vs1 i2 vs2 :
i2 = i1 + length vs1 →
array۰cslice t sz i1 dq vs1 -∗
array۰cslice t sz i2 dq vs2 -∗
array۰cslice t sz i1 dq (vs1 ++ vs2).
Lemma array۰csliceーapp₂ {t sz i dq vs} vs1 vs2 :
vs = vs1 ++ vs2 →
array۰cslice t sz i dq vs ⊢
array۰cslice t sz i dq vs1 ∗
array۰cslice t sz (i + length vs1) dq vs2.
Lemma array۰csliceーappー3 t sz i dq vs1 vs2 vs3 :
array۰cslice t sz i dq vs1 ∗
array۰cslice t sz (i + length vs1) dq vs2 ∗
array۰cslice t sz (i + length vs1 + length vs2) dq vs3 ⊣⊢
array۰cslice t sz i dq (vs1 ++ vs2 ++ vs3).
Lemma array۰csliceーappー3₁ t sz dq i1 vs1 i2 vs2 i3 vs3 :
i2 = i1 + length vs1 →
i3 = i1 + length vs1 + length vs2 →
array۰cslice t sz i1 dq vs1 -∗
array۰cslice t sz i2 dq vs2 -∗
array۰cslice t sz i3 dq vs3 -∗
array۰cslice t sz i1 dq (vs1 ++ vs2 ++ vs3).
Lemma array۰csliceーappー3₂ {t sz i dq vs} vs1 vs2 vs3 :
vs = vs1 ++ vs2 ++ vs3 →
array۰cslice t sz i dq vs ⊢
array۰cslice t sz i dq vs1 ∗
array۰cslice t sz (i + length vs1) dq vs2 ∗
array۰cslice t sz (i + length vs1 + length vs2) dq vs3.
Lemma array۰csliceーcons t sz i dq v vs :
array۰cslice t sz i dq (v :: vs) ⊣⊢
array۰cslice t sz i dq [v] ∗
array۰cslice t sz ˖i dq vs.
Lemma array۰csliceーcons₁ t sz i dq v vs :
array۰cslice t sz i dq (v :: vs) ⊢
array۰cslice t sz i dq [v] ∗
array۰cslice t sz ˖i dq vs.
Lemma array۰csliceーcons₂ t sz i dq v vs :
array۰cslice t sz i dq [v] -∗
array۰cslice t sz ˖i dq vs -∗
array۰cslice t sz i dq (v :: vs).
Lemma array۰csliceーcons₂' t sz i1 dq v i2 vs :
i2 = ˖i1 →
array۰cslice t sz i1 dq [v] -∗
array۰cslice t sz i2 dq vs -∗
array۰cslice t sz i1 dq (v :: vs).
Lemma array۰csliceーatomize sz t i dq vs :
array۰cslice t sz i dq vs ⊢
[∗ list] j ↦ v ∈ vs,
array۰cslice t sz (i + j) dq [v].
Lemma array۰csliceーupdate {t sz i dq vs} j v :
vs !! j = Some v →
array۰cslice t sz i dq vs ⊢
array۰cslice t sz (i + j) dq [v] ∗
( ∀ w,
array۰cslice t sz (i + j) dq [w] -∗
array۰cslice t sz i dq (<[j := w]> vs)
).
Lemma array۰csliceーlookupーacc {t sz i dq vs} j v :
vs !! j = Some v →
array۰cslice t sz i dq vs ⊢
array۰cslice t sz (i + j) dq [v] ∗
( array۰cslice t sz (i + j) dq [v] -∗
array۰cslice t sz i dq vs
).
Lemma array۰csliceーlookup {t sz i dq vs} j v :
vs !! j = Some v →
array۰cslice t sz i dq vs ⊢
array۰cslice t sz (i + j) dq [v].
Lemma array۰csliceーshift t sz i dq vs :
array۰cslice t sz i dq vs ⊣⊢
array۰cslice t sz (i + sz) dq vs.
Lemma array۰csliceーshiftーright t sz i dq vs :
array۰cslice t sz i dq vs ⊢
array۰cslice t sz (i + sz) dq vs.
Lemma array۰csliceーshiftーright' {t sz i1 dq vs} i2 :
i2 = i1 + sz →
array۰cslice t sz i1 dq vs ⊢
array۰cslice t sz i2 dq vs.
Lemma array۰csliceーshiftーleft t sz i dq vs :
sz ≤ i →
array۰cslice t sz i dq vs ⊢
array۰cslice t sz (i - sz) dq vs.
Lemma array۰csliceーshiftーleft' {t sz i1 dq vs} i2 :
sz ≤ i1 →
i2 = i1 - sz →
array۰cslice t sz i1 dq vs ⊢
array۰cslice t sz i2 dq vs.
Lemma array۰csliceーrotationーright {t sz i dq vs} n :
0 < sz →
length vs = sz →
array۰cslice t sz i dq vs ⊣⊢
array۰cslice t sz (i + n) dq (rotation (n `mod` sz) vs).
Lemma array۰csliceーrotationーright₁ {t sz i dq vs} n :
0 < sz →
length vs = sz →
array۰cslice t sz i dq vs ⊢
array۰cslice t sz (i + n) dq (rotation (n `mod` sz) vs).
Lemma array۰csliceーrotationーrightー0 {t sz dq vs} i :
0 < sz →
length vs = sz →
array۰cslice t sz 0 dq vs ⊣⊢
array۰cslice t sz i dq (rotation (i `mod` sz) vs).
Lemma array۰csliceーrotationーright' {t sz i1 dq vs} i2 n :
0 < sz →
length vs = sz →
i2 = i1 + n →
array۰cslice t sz i1 dq vs ⊣⊢
array۰cslice t sz i2 dq (rotation (n `mod` sz) vs).
Lemma array۰csliceーrotationーright₁' {t sz i1 dq vs} i2 n :
0 < sz →
length vs = sz →
i2 = i1 + n →
array۰cslice t sz i1 dq vs ⊢
array۰cslice t sz i2 dq (rotation (n `mod` sz) vs).
Lemma array۰csliceーrotationーrightーsmall {t sz i dq vs} n :
0 < sz →
length vs = sz →
n < sz →
array۰cslice t sz i dq vs ⊣⊢
array۰cslice t sz (i + n) dq (rotation n vs).
Lemma array۰csliceーrotationーrightーsmall₁ {t sz i dq vs} n :
0 < sz →
length vs = sz →
n < sz →
array۰cslice t sz i dq vs ⊢
array۰cslice t sz (i + n) dq (rotation n vs).
Lemma array۰csliceーrotationーrightーsmall' {t sz i1 dq vs} i2 n :
0 < sz →
length vs = sz →
i2 = i1 + n →
n < sz →
array۰cslice t sz i1 dq vs ⊣⊢
array۰cslice t sz i2 dq (rotation n vs).
Lemma array۰csliceーrotationーrightーsmall₁' {t sz i1 dq vs} i2 n :
0 < sz →
length vs = sz →
i2 = i1 + n →
n < sz →
array۰cslice t sz i1 dq vs ⊢
array۰cslice t sz i2 dq (rotation n vs).
Lemma array۰csliceーrotationーleft t sz i n dq vs :
0 < sz →
length vs = sz →
array۰cslice t sz (i + n) dq vs ⊣⊢
array۰cslice t sz i dq (rotation (sz - n `mod` sz) vs).
Lemma array۰csliceーrotationーleft₁ t sz i n dq vs :
0 < sz →
length vs = sz →
array۰cslice t sz (i + n) dq vs ⊢
array۰cslice t sz i dq (rotation (sz - n `mod` sz) vs).
Lemma array۰csliceーrotationーleftー0 t sz i dq vs :
0 < sz →
length vs = sz →
array۰cslice t sz i dq vs ⊣⊢
array۰cslice t sz 0 dq (rotation (sz - i `mod` sz) vs).
Lemma array۰csliceーrotationーleft' {t sz i1 dq vs} i2 n :
0 < sz →
length vs = sz →
i1 = i2 + n →
array۰cslice t sz i1 dq vs ⊣⊢
array۰cslice t sz i2 dq (rotation (sz - n `mod` sz) vs).
Lemma array۰csliceーrotationーleft₁' {t sz i1 dq vs} i2 n :
0 < sz →
length vs = sz →
i1 = i2 + n →
array۰cslice t sz i1 dq vs ⊢
array۰cslice t sz i2 dq (rotation (sz - n `mod` sz) vs).
Lemma array۰csliceーrotationーleftーsmall t sz i n dq vs :
0 < sz →
length vs = sz →
n < sz →
array۰cslice t sz (i + n) dq vs ⊣⊢
array۰cslice t sz i dq (rotation (sz - n) vs).
Lemma array۰csliceーrotationーleftーsmall₁ t sz i n dq vs :
0 < sz →
length vs = sz →
n < sz →
array۰cslice t sz (i + n) dq vs ⊢
array۰cslice t sz i dq (rotation (sz - n) vs).
Lemma array۰csliceーrotationーleftーsmall' {t sz i1 dq vs} i2 n :
0 < sz →
length vs = sz →
i1 = i2 + n →
n < sz →
array۰cslice t sz i1 dq vs ⊣⊢
array۰cslice t sz i2 dq (rotation (sz - n) vs).
Lemma array۰csliceーrotationーleftーsmall₁' {t sz i1 dq vs} i2 n :
0 < sz →
length vs = sz →
i1 = i2 + n →
n < sz →
array۰cslice t sz i1 dq vs ⊢
array۰cslice t sz i2 dq (rotation (sz - n) vs).
Lemma array۰csliceーrebase {t sz i1 dq vs1} i2 :
0 < sz →
length vs1 = sz →
array۰cslice t sz i1 dq vs1 ⊢
∃ vs2 n,
⌜vs2 = rotation n vs1⌝ ∗
array۰cslice t sz i2 dq vs2 ∗
( array۰cslice t sz i2 dq vs2 -∗
array۰cslice t sz i1 dq vs1
).
Lemma array۰csliceーvalid t sz i dq vs :
0 < length vs →
array۰cslice t sz i dq vs ⊢
⌜✓ dq⌝.
Lemma array۰csliceーcombine t sz i dq1 vs1 dq2 vs2 :
length vs1 = length vs2 →
array۰cslice t sz i dq1 vs1 -∗
array۰cslice t sz i dq2 vs2 -∗
⌜vs1 = vs2⌝ ∗
array۰cslice t sz i (dq1 ⋅ dq2) vs1.
Lemma array۰csliceーvalidー2 t sz i dq1 vs1 dq2 vs2 :
0 < length vs1 →
length vs1 = length vs2 →
array۰cslice t sz i dq1 vs1 -∗
array۰cslice t sz i dq2 vs2 -∗
⌜✓ (dq1 ⋅ dq2)⌝ ∗
⌜vs1 = vs2⌝.
Lemma array۰csliceーagree t sz i dq1 vs1 dq2 vs2 :
length vs1 = length vs2 →
array۰cslice t sz i dq1 vs1 -∗
array۰cslice t sz i dq2 vs2 -∗
⌜vs1 = vs2⌝.
Lemma array۰csliceーdfracーne t sz i1 dq1 vs1 i2 dq2 vs2 :
0 < length vs1 →
length vs1 = length vs2 →
¬ ✓ (dq1 ⋅ dq2) →
array۰cslice t sz i1 dq1 vs1 -∗
array۰cslice t sz i2 dq2 vs2 -∗
⌜i1 ≠ i2⌝.
Lemma array۰csliceーne t sz i1 vs1 i2 dq2 vs2 :
0 < length vs1 →
length vs1 = length vs2 →
array۰cslice t sz i1 (DfracOwn 1) vs1 -∗
array۰cslice t sz i2 dq2 vs2 -∗
⌜i1 ≠ i2⌝.
Lemma array۰csliceーexclusive t sz i vs1 dq2 vs2 :
0 < length vs1 →
length vs1 = length vs2 →
array۰cslice t sz i (DfracOwn 1) vs1 -∗
array۰cslice t sz i dq2 vs2 -∗
False.
Lemma array۰csliceーpersist t sz i dq vs :
array۰cslice t sz i dq vs ⊢ |==>
array۰cslice t sz i DfracDiscarded vs.
Lemma array۰csliceーlength t sz i vs :
0 < sz →
array۰cslice t sz i (DfracOwn 1) vs ⊢
⌜length vs ≤ sz⌝.
End array۰cslice.
#[local] Typeclasses Opaque
array۰inv
array۰slice
array۰model
array۰cslice.
Notation au_load t i Φ := (
AU <{
∃∃ dq v,
array۰slice t i dq [v]
}> @ ⊤, ∅ <{
array۰slice t i dq [v],
COMM
Φ v
}>
)%I.
Notation au_store t i v P := (
AU <{
∃∃ w,
array۰slice t i (DfracOwn 1) [w]
}> @ ⊤, ∅ <{
array۰slice t i (DfracOwn 1) [v],
COMM
P
}>
)%I.
Lemma array٠unsafe_allocーspec sz :
(0 ≤ sz)%Z →
{{{
True
}}}
array٠unsafe_alloc #sz
{{{
t
, RET t;
array۰model t (DfracOwn 1) (replicate ₊sz ()%V)
}}}.
Lemma array٠allocーspec sz :
{{{
True
}}}
array٠alloc #sz
{{{
t
, RET t;
⌜0 ≤ sz⌝%Z ∗
array۰model t (DfracOwn 1) (replicate ₊sz ()%V)
}}}.
Lemma array٠createーspec :
{{{
True
}}}
array٠create ()
{{{
t
, RET t;
array۰model t (DfracOwn 1) []
}}}.
Lemma array٠sizeーspecーinv t sz :
{{{
array۰inv t sz
}}}
array٠size t
{{{
RET #sz;
True
}}}.
Lemma array٠sizeーspecーatomic t :
<<<
True
| ∀∀ dq vs,
array۰model t dq vs
>>>
array٠size t
<<<
array۰model t dq vs
| RET #(length vs);
£ 1 ∗
array۰inv t (length vs)
>>>.
Lemma array٠sizeーspecーatomicーcslice t :
<<<
True
| ∀∀ sz i dq vs,
array۰cslice t sz i dq vs
>>>
array٠size t
<<<
array۰cslice t sz i dq vs
| RET #sz;
£ 1 ∗
array۰inv t sz
>>>.
Lemma array٠sizeーspec t dq vs :
{{{
array۰model t dq vs
}}}
array٠size t
{{{
RET #(length vs);
array۰model t dq vs
}}}.
Lemma array٠sizeーspecーcslice t sz i dq vs :
{{{
array۰cslice t sz i dq vs
}}}
array٠size t
{{{
RET #sz;
array۰cslice t sz i dq vs
}}}.
Lemma array٠unsafe_getーspecーatomicーslice t (j : Z) :
<<<
True
| ∀∀ dq vs i v,
⌜(i ≤ j)%Z⌝ ∗
⌜vs !! (₊j - i) = Some v⌝ ∗
array۰slice t i dq vs
>>>
array٠unsafe_get t #j
<<<
array۰slice t i dq vs
| RET v;
£ 1
>>>.
Lemma array٠unsafe_getーspecーatomicーcell t (i : Z) :
<<<
True
| ∀∀ i_ dq v,
⌜i = ⁺i_⌝ ∗
array۰slice t i_ dq [v]
>>>
array٠unsafe_get t #i
<<<
array۰slice t ₊i dq [v]
| RET v;
£ 1
>>>.
Lemma array٠unsafe_getーspecーatomic t (i : Z) :
(0 ≤ i)%Z →
<<<
True
| ∀∀ dq vs v,
⌜vs !! ₊i = Some v⌝ ∗
array۰model t dq vs
>>>
array٠unsafe_get t #i
<<<
array۰model t dq vs
| RET v;
£ 1
>>>.
Lemma array٠unsafe_getーspecーatomicーinv t (sz : nat) (i : Z) :
(0 ≤ i < sz)%Z →
<<<
array۰inv t sz
| ∀∀ vs,
array۰model t (DfracOwn 1) vs
>>>
array٠unsafe_get t #i
<<<
∃∃ v,
⌜vs !! ₊i = Some v⌝ ∗
array۰model t (DfracOwn 1) vs
| RET v;
£ 1
>>>.
Lemma array٠unsafe_getーspecーslice k t i dq vs (j : Z) v :
(i ≤ j)%Z →
vs !! k = Some v →
k = ₊j - i →
{{{
array۰slice t i dq vs
}}}
array٠unsafe_get t #j
{{{
RET v;
array۰slice t i dq vs
}}}.
Lemma array٠unsafe_getーspecーcell t (i : Z) i_ dq v :
i = ₊i_ →
{{{
array۰slice t i_ dq [v]
}}}
array٠unsafe_get t #i
{{{
RET v;
array۰slice t i_ dq [v]
}}}.
Lemma array٠unsafe_getーspec i_ t (i : Z) dq vs v :
(0 ≤ i)%Z →
vs !! i_ = Some v →
i_ = ₊i →
{{{
array۰model t dq vs
}}}
array٠unsafe_get t #i
{{{
RET v;
array۰model t dq vs
}}}.
Lemma array٠getーspecーatomicーslice t sz (j : Z) :
<<<
array۰inv t sz
| ∀∀ dq vs i v,
⌜0 ≤ j < sz⌝%Z -∗
⌜i ≤ ₊j⌝ ∗
⌜vs !! (₊j - i) = Some v⌝ ∗
array۰slice t i dq vs
>>>
array٠get t #j
<<<
array۰slice t i dq vs
| RET v;
⌜0 ≤ j < sz⌝%Z ∗
£ 1
>>>.
Lemma array٠getーspecーatomicーcell t sz (i : Z) i_ :
i_ = ₊i →
<<<
array۰inv t sz
| ∀∀ dq v,
⌜0 ≤ i < sz⌝%Z -∗
array۰slice t i_ dq [v]
>>>
array٠get t #i
<<<
array۰slice t i_ dq [v]
| RET v;
⌜0 ≤ i < sz⌝%Z ∗
£ 1
>>>.
Lemma array٠getーspecーatomic t sz (i : Z) :
<<<
array۰inv t sz
| ∀∀ dq vs v,
⌜0 ≤ i < sz⌝%Z -∗
⌜vs !! ₊i = Some v⌝ ∗
array۰model t dq vs
>>>
array٠get t #i
<<<
array۰model t dq vs
| RET v;
⌜0 ≤ i < sz⌝%Z ∗
£ 1
>>>.
Lemma array٠getーspecーslice k t sz i dq vs (j : Z) v :
{{{
array۰inv t sz ∗
( ⌜0 ≤ j < sz⌝%Z -∗
⌜i ≤ ₊j⌝ ∗
⌜vs !! k = Some v⌝ ∗
⌜k = ₊j - i⌝ ∗
array۰slice t i dq vs
)
}}}
array٠get t #j
{{{
RET v;
⌜0 ≤ j < sz⌝%Z ∗
array۰slice t i dq vs
}}}.
Lemma array٠getーspecーcell t sz (i : Z) i_ dq v :
i_ = ₊i →
{{{
array۰inv t sz ∗
( ⌜0 ≤ i < sz⌝%Z -∗
array۰slice t i_ dq [v]
)
}}}
array٠get t #i
{{{
RET v;
⌜0 ≤ i < sz⌝%Z ∗
array۰slice t i_ dq [v]
}}}.
Lemma array٠getーspec t (i : Z) dq vs v :
{{{
array۰model t dq vs ∗
( ⌜0 ≤ i < length vs⌝%Z -∗
⌜vs !! ₊i = Some v⌝
)
}}}
array٠get t #i
{{{
RET v;
⌜0 ≤ i < length vs⌝%Z ∗
array۰model t dq vs
}}}.
Lemma array٠unsafe_setーspecーatomicーslice t (j : Z) v :
<<<
True
| ∀∀ vs i,
⌜i ≤ j < i + length vs⌝%Z ∗
array۰slice t i (DfracOwn 1) vs
>>>
array٠unsafe_set t #j v
<<<
∃∃ w,
⌜vs !! (₊j - i) = Some w⌝ ∗
array۰slice t i (DfracOwn 1) (<[₊j - i := v]> vs)
| RET ();
£ 1
>>>.
Lemma array٠unsafe_setーspecーatomicーcell t (i : Z) v :
<<<
True
| ∀∀ i_ w,
⌜i = ⁺i_⌝ ∗
array۰slice t i_ (DfracOwn 1) [w]
>>>
array٠unsafe_set t #i v
<<<
array۰slice t i_ (DfracOwn 1) [v]
| RET ();
£ 1
>>>.
Lemma array٠unsafe_setーspecーatomic t (i : Z) v :
(0 ≤ i)%Z →
<<<
True
| ∀∀ vs,
⌜i < length vs⌝%Z ∗
array۰model t (DfracOwn 1) vs
>>>
array٠unsafe_set t #i v
<<<
∃∃ w,
⌜vs !! ₊i = Some w⌝ ∗
array۰model t (DfracOwn 1) (<[₊i := v]> vs)
| RET ();
£ 1
>>>.
Lemma array٠unsafe_setーspecーatomicーinv t (sz : nat) (i : Z) v :
(0 ≤ i < sz)%Z →
<<<
array۰inv t sz
| ∀∀ vs,
array۰model t (DfracOwn 1) vs
>>>
array٠unsafe_set t #i v
<<<
∃∃ w,
⌜vs !! ₊i = Some w⌝ ∗
array۰model t (DfracOwn 1) (<[₊i := v]> vs)
| RET ();
£ 1
>>>.
Lemma array٠unsafe_setーspecーslice t i vs (j : Z) v :
(i ≤ j < i + length vs)%Z →
{{{
array۰slice t i (DfracOwn 1) vs
}}}
array٠unsafe_set t #j v
{{{
RET ();
array۰slice t i (DfracOwn 1) (<[₊j - i := v]> vs)
}}}.
Lemma array٠unsafe_setーspecーcell t (i : Z) i_ w v :
i = ⁺i_ →
{{{
array۰slice t i_ (DfracOwn 1) [w]
}}}
array٠unsafe_set t #i v
{{{
RET ();
array۰slice t i_ (DfracOwn 1) [v]
}}}.
Lemma array٠unsafe_setーspec t (i : Z) vs v :
(0 ≤ i < length vs)%Z →
{{{
array۰model t (DfracOwn 1) vs
}}}
array٠unsafe_set t #i v
{{{
RET ();
array۰model t (DfracOwn 1) (<[₊i := v]> vs)
}}}.
Lemma array٠setーspecーatomicーslice t sz (j : Z) v :
<<<
array۰inv t sz
| ∀∀ vs i,
⌜0 ≤ j < sz⌝%Z -∗
⌜i ≤ ₊j < i + length vs⌝ ∗
array۰slice t i (DfracOwn 1) vs
>>>
array٠set t #j v
<<<
array۰slice t i (DfracOwn 1) (<[₊j - i := v]> vs)
| RET ();
⌜0 ≤ j < sz⌝%Z ∗
£ 1
>>>.
Lemma array٠setーspecーatomicーcell t sz (i : Z) i_ v :
i_ = ₊i →
<<<
array۰inv t sz
| ∀∀ w,
⌜0 ≤ i < sz⌝%Z -∗
array۰slice t i_ (DfracOwn 1) [w]
>>>
array٠set t #i v
<<<
array۰slice t i_ (DfracOwn 1) [v]
| RET ();
⌜0 ≤ i < sz⌝%Z ∗
£ 1
>>>.
Lemma array٠setーspecーatomic t sz (i : Z) v :
<<<
array۰inv t sz
| ∀∀ vs,
⌜0 ≤ i < sz⌝%Z -∗
⌜(₊i < length vs)%Z⌝ ∗
array۰model t (DfracOwn 1) vs
>>>
array٠set t #i v
<<<
array۰model t (DfracOwn 1) (<[₊i := v]> vs)
| RET ();
⌜0 ≤ i < sz⌝%Z ∗
£ 1
>>>.
Lemma array٠setーspecーslice t sz i vs (j : Z) v :
{{{
array۰inv t sz ∗
( ⌜0 ≤ j < sz⌝%Z -∗
⌜i ≤ ₊j < i + length vs⌝ ∗
array۰slice t i (DfracOwn 1) vs
)
}}}
array٠set t #j v
{{{
RET ();
⌜0 ≤ j < sz⌝%Z ∗
array۰slice t i (DfracOwn 1) (<[₊j - i := v]> vs)
}}}.
Lemma array٠setーspecーcell t sz (i : Z) i_ w v :
i_ = ₊i →
{{{
array۰inv t sz ∗
( ⌜0 ≤ i < sz⌝%Z -∗
array۰slice t i_ (DfracOwn 1) [w]
)
}}}
array٠set t #i v
{{{
RET ();
⌜0 ≤ i < sz⌝%Z ∗
array۰slice t i_ (DfracOwn 1) [v]
}}}.
Lemma array٠setーspec t (i : Z) vs v :
{{{
array۰model t (DfracOwn 1) vs
}}}
array٠set t #i v
{{{
RET ();
array۰model t (DfracOwn 1) (<[₊i := v]> vs)
}}}.
Lemma array٠unsafe_xchgーspecーatomicーslice t (j : Z) v :
<<<
True
| ∀∀ vs i,
⌜i ≤ j < i + length vs⌝%Z ∗
array۰slice t i (DfracOwn 1) vs
>>>
array٠unsafe_xchg t #j v
<<<
∃∃ w,
⌜vs !! (₊j - i) = Some w⌝ ∗
array۰slice t i (DfracOwn 1) (<[₊j - i := v]> vs)
| RET w;
£ 1
>>>.
Lemma array٠unsafe_xchgーspecーatomicーcell t (i : Z) v :
<<<
True
| ∀∀ i_ w,
⌜i = ⁺i_⌝ ∗
array۰slice t i_ (DfracOwn 1) [w]
>>>
array٠unsafe_xchg t #i v
<<<
array۰slice t i_ (DfracOwn 1) [v]
| RET w;
£ 1
>>>.
Lemma array٠unsafe_xchgーspecーatomic t (i : Z) v :
(0 ≤ i)%Z →
<<<
True
| ∀∀ vs,
⌜i < length vs⌝%Z ∗
array۰model t (DfracOwn 1) vs
>>>
array٠unsafe_xchg t #i v
<<<
∃∃ w,
⌜vs !! ₊i = Some w⌝ ∗
array۰model t (DfracOwn 1) (<[₊i := v]> vs)
| RET w;
£ 1
>>>.
Lemma array٠unsafe_xchgーspecーatomicーinv t (sz : nat) (i : Z) v :
(0 ≤ i < sz)%Z →
<<<
array۰inv t sz
| ∀∀ vs,
array۰model t (DfracOwn 1) vs
>>>
array٠unsafe_xchg t #i v
<<<
∃∃ w,
⌜vs !! ₊i = Some w⌝ ∗
array۰model t (DfracOwn 1) (<[₊i := v]> vs)
| RET w;
£ 1
>>>.
Lemma array٠unsafe_xchgーspecーslice t i vs (j : Z) v :
(i ≤ j < i + length vs)%Z →
{{{
array۰slice t i (DfracOwn 1) vs
}}}
array٠unsafe_xchg t #j v
{{{
w
, RET w;
⌜vs !! (₊j - i) = Some w⌝ ∗
array۰slice t i (DfracOwn 1) (<[₊j - i := v]> vs)
}}}.
Lemma array٠unsafe_xchgーspecーcell t (i : Z) i_ w v :
i = ⁺i_ →
{{{
array۰slice t i_ (DfracOwn 1) [w]
}}}
array٠unsafe_xchg t #i v
{{{
RET w;
array۰slice t i_ (DfracOwn 1) [v]
}}}.
Lemma array٠unsafe_xchgーspec t (i : Z) vs v :
(0 ≤ i < length vs)%Z →
{{{
array۰model t (DfracOwn 1) vs
}}}
array٠unsafe_xchg t #i v
{{{
w
, RET w;
⌜vs !! ₊i = Some w⌝ ∗
array۰model t (DfracOwn 1) (<[₊i := v]> vs)
}}}.
Lemma array٠unsafe_casーspecーatomicーslice t (j : Z) v1 v2 :
<<<
True
| ∀∀ vs i,
⌜i ≤ j < i + length vs⌝%Z ∗
array۰slice t i (DfracOwn 1) vs
>>>
array٠unsafe_cas t #j v1 v2
<<<
∃∃ b v,
⌜vs !! (₊j - i) = Some v⌝ ∗
⌜(if b then (≈) else (≉)) v v1⌝ ∗
array۰slice t i (DfracOwn 1) (if b then <[₊j - i := v2]> vs else vs)
| RET #b;
£ 1
>>>.
Lemma array٠unsafe_casーspecーatomicーcell t (i : Z) v1 v2 :
<<<
True
| ∀∀ i_ v,
⌜i = ⁺i_⌝ ∗
array۰slice t i_ (DfracOwn 1) [v]
>>>
array٠unsafe_cas t #i v1 v2
<<<
∃∃ b,
⌜(if b then (≈) else (≉)) v v1⌝ ∗
array۰slice t i_ (DfracOwn 1) [if b then v2 else v]
| RET #b;
£ 1
>>>.
Lemma array٠unsafe_casーspecーatomic t (i : Z) v1 v2 :
(0 ≤ i)%Z →
<<<
True
| ∀∀ vs,
⌜i < length vs⌝%Z ∗
array۰model t (DfracOwn 1) vs
>>>
array٠unsafe_cas t #i v1 v2
<<<
∃∃ b v,
⌜vs !! ₊i = Some v⌝ ∗
⌜(if b then (≈) else (≉)) v v1⌝ ∗
array۰model t (DfracOwn 1) (if b then <[₊i := v2]> vs else vs)
| RET #b;
£ 1
>>>.
Lemma array٠unsafe_casーspecーatomicーinv t (sz : nat) (i : Z) v1 v2 :
(0 ≤ i < sz)%Z →
<<<
array۰inv t sz
| ∀∀ vs,
array۰model t (DfracOwn 1) vs
>>>
array٠unsafe_cas t #i v1 v2
<<<
∃∃ b v,
⌜vs !! ₊i = Some v⌝ ∗
⌜(if b then (≈) else (≉)) v v1⌝ ∗
array۰model t (DfracOwn 1) (if b then <[₊i := v2]> vs else vs)
| RET #b;
£ 1
>>>.
Lemma array٠unsafe_casーspecーslice t i vs (j : Z) v1 v2 :
(i ≤ j < i + length vs)%Z →
{{{
array۰slice t i (DfracOwn 1) vs
}}}
array٠unsafe_cas t #j v1 v2
{{{
b v
, RET #b;
⌜vs !! (₊j - i) = Some v⌝ ∗
⌜(if b then (≈) else (≉)) v v1⌝ ∗
array۰slice t i (DfracOwn 1) (if b then <[₊j - i := v2]> vs else vs)
}}}.
Lemma array٠unsafe_casーspecーcell t (i : Z) i_ v v1 v2 :
i = ⁺i_ →
{{{
array۰slice t i_ (DfracOwn 1) [v]
}}}
array٠unsafe_cas t #i v1 v2
{{{
b
, RET #b;
⌜(if b then (≈) else (≉)) v v1⌝ ∗
array۰slice t i_ (DfracOwn 1) [if b then v2 else v]
}}}.
Lemma array٠unsafe_casーspec t (i : Z) vs v1 v2 :
(0 ≤ i < length vs)%Z →
{{{
array۰model t (DfracOwn 1) vs
}}}
array٠unsafe_cas t #i v1 v2
{{{
b v
, RET #b;
⌜vs !! ₊i = Some v⌝ ∗
⌜(if b then (≈) else (≉)) v v1⌝ ∗
array۰model t (DfracOwn 1) (if b then <[₊i := v2]> vs else vs)
}}}.
Lemma array٠unsafe_swapーspecーslice {t i vs} {i1 : Z} k1 {v1} {i2 : Z} k2 v2 :
(i ≤ i1)%Z →
(i ≤ i2)%Z →
vs !! k1 = Some v1 →
k1 = ₊i1 - i →
vs !! k2 = Some v2 →
k2 = ₊i2 - i →
{{{
array۰slice t i (DfracOwn 1) vs
}}}
array٠unsafe_swap t #i1 #i2
{{{
RET ();
array۰slice t i (DfracOwn 1) (<[k2 := v1]> $ <[k1 := v2]> vs)
}}}.
Lemma array٠unsafe_swapーspecーsliceーid t i vs (i1 i2 : Z) :
i1 = i2 →
(i ≤ i1 < i + length vs)%Z →
{{{
array۰slice t i (DfracOwn 1) vs
}}}
array٠unsafe_swap t #i1 #i2
{{{
RET ();
array۰slice t i (DfracOwn 1) vs
}}}.
Lemma array٠unsafe_swapーspec {t vs} {i1 : Z} i1_ {v1} {i2 : Z} i2_ v2 :
(0 ≤ i1)%Z →
(0 ≤ i2)%Z →
vs !! i1_ = Some v1 →
i1_ = ₊i1 →
vs !! i2_ = Some v2 →
i2_ = ₊i2 →
{{{
array۰model t (DfracOwn 1) vs
}}}
array٠unsafe_swap t #i1 #i2
{{{
RET ();
array۰model t (DfracOwn 1) (<[i2_ := v1]> $ <[i1_ := v2]> vs)
}}}.
Lemma array٠unsafe_fill_sliceーspecーatomic Ψ t (i n : Z) v :
(0 ≤ i)%Z →
{{{
▷ Ψ 0 ∗
□ (
∀ j,
⌜j < ₊n⌝ -∗
Ψ j -∗
au_store t (₊i + j) v (
▷ Ψ ˖j
)
)
}}}
array٠unsafe_fill_slice t #i #n v
{{{
RET ();
Ψ ₊n
}}}.
Lemma array٠unsafe_fill_sliceーspecーsliceーfit t vs (i : Z) i_ (n : Z) v :
i = ⁺i_ →
₊n = length vs →
{{{
array۰slice t i_ (DfracOwn 1) vs
}}}
array٠unsafe_fill_slice t #i #n v
{{{
RET ();
array۰slice t i_ (DfracOwn 1) (replicate ₊n v)
}}}.
Lemma array٠unsafe_fill_sliceーspecーslice t vs (i : Z) j (n : Z) v :
(j ≤ i)%Z →
₊i + ₊n ≤ j + length vs →
{{{
array۰slice t j (DfracOwn 1) vs
}}}
array٠unsafe_fill_slice t #i #n v
{{{
RET ();
array۰slice t j (DfracOwn 1) (with_slice (₊i - j) ₊n vs (replicate ₊n v))
}}}.
Lemma array٠unsafe_fill_sliceーspec t vs (i : Z) (n : Z) v :
(0 ≤ i)%Z →
₊i + ₊n ≤ length vs →
{{{
array۰model t (DfracOwn 1) vs
}}}
array٠unsafe_fill_slice t #i #n v
{{{
RET ();
array۰model t (DfracOwn 1) (with_slice ₊i ₊n vs (replicate ₊n v))
}}}.
Lemma array٠fill_sliceーspec t sz vs (i : Z) i_ (n : Z) v :
i_ = ₊i →
₊n = length vs →
{{{
array۰inv t sz ∗
array۰slice t i_ (DfracOwn 1) vs
}}}
array٠fill_slice t #i #n v
{{{
RET ();
⌜0 ≤ i⌝%Z ∗
⌜0 ≤ n⌝%Z ∗
⌜i + n ≤ sz⌝%Z ∗
array۰slice t i_ (DfracOwn 1) (replicate ₊n v)
}}}.
Lemma array٠fillーspec t vs v :
{{{
array۰model t (DfracOwn 1) vs
}}}
array٠fill t v
{{{
RET ();
array۰model t (DfracOwn 1) (replicate (length vs) v)
}}}.
Lemma array٠unsafe_makeーspec sz v :
(0 ≤ sz)%Z →
{{{
True
}}}
array٠unsafe_make #sz v
{{{
t
, RET t;
array۰model t (DfracOwn 1) (replicate ₊sz v)
}}}.
Lemma array٠makeーspec sz v :
{{{
True
}}}
array٠make #sz v
{{{
t
, RET t;
⌜0 ≤ sz⌝%Z ∗
array۰model t (DfracOwn 1) (replicate ₊sz v)
}}}.
#[local] Lemma array٠foldli_auxーspec vs Ψ fn t sz i acc :
i ≤ sz →
i = length vs →
{{{
▷ Ψ i vs None acc ∗
□ (
∀ i vs (o : option val) acc,
⌜i < sz⌝ -∗
⌜i = length vs⌝ -∗
Ψ i vs o acc -∗
match o with
| None ⇒
au_load t i (λ v,
▷ Ψ i vs (Some v) acc
)
| Some v ⇒
WP fn #i acc v {{ acc,
▷ Ψ ˖i (vs ++ [v]) None acc
}}
end
)
}}}
array٠foldli_aux fn t #sz #i acc
{{{
vs' acc
, RET acc;
⌜(length vs + length vs')%nat = sz⌝ ∗
Ψ sz (vs ++ vs') None acc
}}}.
Lemma array٠foldliーspecーatomic Ψ fn acc t sz :
{{{
array۰inv t sz ∗
▷ Ψ 0 [] None acc ∗
□ (
∀ i vs (o : option val) acc,
⌜i < sz⌝ -∗
⌜i = length vs⌝ -∗
Ψ i vs o acc -∗
match o with
| None ⇒
au_load t i (λ v,
▷ Ψ i vs (Some v) acc
)
| Some v ⇒
WP fn #i acc v {{ acc,
▷ Ψ ˖i (vs ++ [v]) None acc
}}
end
)
}}}
array٠foldli fn acc t
{{{
vs acc
, RET acc;
⌜length vs = sz⌝ ∗
Ψ sz vs None acc
}}}.
Lemma array٠foldliーspec Ψ fn acc t dq vs :
{{{
▷ Ψ 0 [] acc ∗
array۰model t dq vs ∗
□ (
∀ i v acc,
⌜vs !! i = Some v⌝ -∗
Ψ i (take i vs) acc -∗
WP fn #i acc v {{ acc,
▷ Ψ ˖i (take i vs ++ [v]) acc
}}
)
}}}
array٠foldli fn acc t
{{{
acc
, RET acc;
array۰model t dq vs ∗
Ψ (length vs) vs acc
}}}.
Lemma array٠foldliーspec' Ψ fn acc t dq vs :
{{{
▷ Ψ 0 [] acc ∗
array۰model t dq vs ∗
( [∗ list] i ↦ v ∈ vs,
∀ acc,
Ψ i (take i vs) acc -∗
WP fn #i acc v {{ acc,
▷ Ψ ˖i (take i vs ++ [v]) acc
}}
)
}}}
array٠foldli fn acc t
{{{
acc
, RET acc;
array۰model t dq vs ∗
Ψ (length vs) vs acc
}}}.
Lemma array٠foldlーspecーatomic Ψ fn acc t sz :
{{{
array۰inv t sz ∗
▷ Ψ 0 [] None acc ∗
□ (
∀ i vs (o : option val) acc,
⌜i < sz⌝ -∗
⌜i = length vs⌝ -∗
Ψ i vs o acc -∗
match o with
| None ⇒
au_load t i (λ v,
▷ Ψ i vs (Some v) acc
)
| Some v ⇒
WP fn acc v {{ acc,
▷ Ψ ˖i (vs ++ [v]) None acc
}}
end
)
}}}
array٠foldl fn acc t
{{{
vs acc
, RET acc;
⌜length vs = sz⌝ ∗
Ψ sz vs None acc
}}}.
Lemma array٠foldlーspec Ψ fn acc t dq vs :
{{{
▷ Ψ 0 [] acc ∗
array۰model t dq vs ∗
□ (
∀ i v acc,
⌜vs !! i = Some v⌝ -∗
Ψ i (take i vs) acc -∗
WP fn acc v {{ acc,
▷ Ψ ˖i (take i vs ++ [v]) acc
}}
)
}}}
array٠foldl fn acc t
{{{
acc
, RET acc;
array۰model t dq vs ∗
Ψ (length vs) vs acc
}}}.
Lemma array٠foldlーspec' Ψ fn acc t dq vs :
{{{
▷ Ψ 0 [] acc ∗
array۰model t dq vs ∗
( [∗ list] i ↦ v ∈ vs,
∀ acc,
Ψ i (take i vs) acc -∗
WP fn acc v {{ acc,
▷ Ψ ˖i (take i vs ++ [v]) acc
}}
)
}}}
array٠foldl fn acc t
{{{
acc
, RET acc;
array۰model t dq vs ∗
Ψ (length vs) vs acc
}}}.
#[local] Lemma array٠foldri_auxーspec sz vs Ψ fn t (i : Z) acc :
₊i + length vs = sz →
{{{
▷ Ψ ₊i acc None vs ∗
□ (
∀ i acc (o : option val) vs,
⌜(˖i + length vs)%nat = sz⌝ -∗
Ψ ˖i acc o vs -∗
match o with
| None ⇒
au_load t i (λ v,
▷ Ψ ˖i acc (Some v) vs
)
| Some v ⇒
WP fn #i v acc {{ acc,
▷ Ψ i acc None (v :: vs)
}}
end
)
}}}
array٠foldri_aux fn t #i acc
{{{
acc vs'
, RET acc;
⌜(length vs' + length vs)%nat = sz⌝ ∗
Ψ 0 acc None (vs' ++ vs)
}}}.
Lemma array٠foldriーspecーatomic Ψ fn t sz acc :
{{{
array۰inv t sz ∗
▷ Ψ sz acc None [] ∗
□ (
∀ i acc (o : option val) vs,
⌜(˖i + length vs)%nat = sz⌝ -∗
Ψ ˖i acc o vs -∗
match o with
| None ⇒
au_load t i (λ v,
▷ Ψ ˖i acc (Some v) vs
)
| Some v ⇒
WP fn #i v acc {{ acc,
▷ Ψ i acc None (v :: vs)
}}
end
)
}}}
array٠foldri fn t acc
{{{
acc vs
, RET acc;
⌜length vs = sz⌝ ∗
Ψ 0 acc None vs
}}}.
Lemma array٠foldriーspec Ψ fn t dq vs acc :
{{{
array۰model t dq vs ∗
▷ Ψ (length vs) acc [] ∗
□ (
∀ i v acc,
⌜vs !! i = Some v⌝ -∗
Ψ ˖i acc (drop ˖i vs) -∗
WP fn #i v acc {{ acc,
▷ Ψ i acc (v :: drop ˖i vs)
}}
)
}}}
array٠foldri fn t acc
{{{
acc
, RET acc;
Ψ 0 acc vs ∗
array۰model t dq vs
}}}.
Lemma array٠foldriーspec' Ψ fn t dq vs acc :
{{{
array۰model t dq vs ∗
▷ Ψ (length vs) acc [] ∗
( [∗ list] i ↦ v ∈ vs,
∀ acc,
Ψ ˖i acc (drop ˖i vs) -∗
WP fn #i v acc {{ acc,
▷ Ψ i acc (v :: drop ˖i vs)
}}
)
}}}
array٠foldri fn t acc
{{{
acc
, RET acc;
Ψ 0 acc vs ∗
array۰model t dq vs
}}}.
Lemma array٠foldrーspecーatomic Ψ fn t sz acc :
{{{
array۰inv t sz ∗
▷ Ψ sz acc None [] ∗
□ (
∀ i acc (o : option val) vs,
⌜(˖i + length vs)%nat = sz⌝ -∗
Ψ ˖i acc o vs -∗
match o with
| None ⇒
au_load t i (λ v,
▷ Ψ ˖i acc (Some v) vs
)
| Some v ⇒
WP fn v acc {{ acc,
▷ Ψ i acc None (v :: vs)
}}
end
)
}}}
array٠foldr fn t acc
{{{
acc vs
, RET acc;
⌜length vs = sz⌝ ∗
Ψ 0 acc None vs
}}}.
Lemma array٠foldrーspec Ψ fn t dq vs acc :
{{{
array۰model t dq vs ∗
▷ Ψ (length vs) acc [] ∗
□ (
∀ i v acc,
⌜vs !! i = Some v⌝ -∗
Ψ ˖i acc (drop ˖i vs) -∗
WP fn v acc {{ acc,
▷ Ψ i acc (v :: drop ˖i vs)
}}
)
}}}
array٠foldr fn t acc
{{{
acc
, RET acc;
Ψ 0 acc vs ∗
array۰model t dq vs
}}}.
Lemma array٠foldrーspec' Ψ fn t dq vs acc :
{{{
array۰model t dq vs ∗
▷ Ψ (length vs) acc [] ∗
( [∗ list] i ↦ v ∈ vs,
∀ acc,
Ψ ˖i acc (drop ˖i vs) -∗
WP fn v acc {{ acc,
▷ Ψ i acc (v :: drop ˖i vs)
}}
)
}}}
array٠foldr fn t acc
{{{
acc
, RET acc;
Ψ 0 acc vs ∗
array۰model t dq vs
}}}.
Lemma array٠unsafe_iteri_sliceーspecーatomic Ψ fn t (sz : nat) (i n : Z) :
(0 ≤ i ≤ sz)%Z →
(0 ≤ n)%Z →
(i + n ≤ sz)%Z →
{{{
array۰inv t sz ∗
▷ Ψ 0 [] None ∗
□ (
∀ k vs (o : option val),
⌜k < ₊n⌝ -∗
⌜k = length vs⌝ -∗
Ψ k vs o -∗
match o with
| None ⇒
au_load t (₊i + k) (λ v,
▷ Ψ k vs (Some v)
)
| Some v ⇒
WP fn #k v {{ res,
⌜res = ()%V⌝ ∗
▷ Ψ ˖k (vs ++ [v]) None
}}
end
)
}}}
array٠unsafe_iteri_slice fn t #i #n
{{{
vs
, RET ();
⌜length vs = ₊n⌝ ∗
Ψ ₊n vs None
}}}.
Lemma array٠unsafe_iteri_sliceーspec Ψ fn t dq vs (i n : Z) :
(0 ≤ i ≤ length vs)%Z →
(0 ≤ n)%Z →
(i + n ≤ length vs)%Z →
{{{
▷ Ψ 0 [] ∗
array۰model t dq vs ∗
□ (
∀ k v,
⌜k < ₊n⌝ -∗
⌜vs !! (₊i + k)%nat = Some v⌝ -∗
Ψ k (slice ₊i k vs) -∗
WP fn #k v {{ res,
⌜res = ()%V⌝ ∗
▷ Ψ ˖k (slice ₊i k vs ++ [v])
}}
)
}}}
array٠unsafe_iteri_slice fn t #i #n
{{{
RET ();
array۰model t dq vs ∗
Ψ ₊n (slice ₊i ₊n vs)
}}}.
Lemma array٠unsafe_iteri_sliceーspec' Ψ fn t dq vs (i n : Z) :
(0 ≤ i ≤ length vs)%Z →
(0 ≤ n)%Z →
(i + n ≤ length vs)%Z →
{{{
▷ Ψ 0 [] ∗
array۰model t dq vs ∗
( [∗ list] k ↦ v ∈ slice ₊i ₊n vs,
Ψ k (slice ₊i k vs) -∗
WP fn #k v {{ res,
⌜res = ()%V⌝ ∗
▷ Ψ ˖k (slice ₊i k vs ++ [v])
}}
)
}}}
array٠unsafe_iteri_slice fn t #i #n
{{{
RET ();
array۰model t dq vs ∗
Ψ ₊n (slice ₊i ₊n vs)
}}}.
Lemma array٠unsafe_iteri_sliceーspecーdisentangled Ψ fn t dq vs (i n : Z) :
(0 ≤ i ≤ length vs)%Z →
(0 ≤ n)%Z →
(i + n ≤ length vs)%Z →
{{{
array۰model t dq vs ∗
□ (
∀ k v,
⌜k < ₊n⌝ -∗
⌜vs !! (₊i + k)%nat = Some v⌝ -∗
WP fn #k v {{ res,
⌜res = ()%V⌝ ∗
▷ Ψ k v
}}
)
}}}
array٠unsafe_iteri_slice fn t #i #n
{{{
RET ();
array۰model t dq vs ∗
( [∗ list] k ↦ v ∈ slice ₊i ₊n vs,
Ψ k v
)
}}}.
Lemma array٠unsafe_iteri_sliceーspecーdisentangled' Ψ fn t dq vs (i n : Z) :
(0 ≤ i ≤ length vs)%Z →
(0 ≤ n)%Z →
(i + n ≤ length vs)%Z →
{{{
array۰model t dq vs ∗
( [∗ list] k ↦ v ∈ slice ₊i ₊n vs,
WP fn #k v {{ res,
⌜res = ()%V⌝ ∗
▷ Ψ k v
}}
)
}}}
array٠unsafe_iteri_slice fn t #i #n
{{{
RET ();
array۰model t dq vs ∗
( [∗ list] k ↦ v ∈ slice ₊i ₊n vs,
Ψ k v
)
}}}.
Lemma array٠iteri_sliceーspecーatomic Ψ fn t (sz : nat) (i n : Z) :
{{{
array۰inv t sz ∗
▷ Ψ 0 [] None ∗
□ (
∀ k vs (o : option val),
⌜k < ₊n⌝ -∗
⌜k = length vs⌝ -∗
Ψ k vs o -∗
match o with
| None ⇒
au_load t (₊i + k) (λ v,
▷ Ψ k vs (Some v)
)
| Some v ⇒
WP fn #k v {{ res,
⌜res = ()%V⌝ ∗
▷ Ψ ˖k (vs ++ [v]) None
}}
end
)
}}}
array٠iteri_slice fn t #i #n
{{{
vs
, RET ();
⌜0 ≤ i ≤ sz⌝%Z ∗
⌜0 ≤ n⌝%Z ∗
⌜i + n ≤ sz⌝%Z ∗
⌜length vs = ₊n⌝ ∗
Ψ ₊n vs None
}}}.
Lemma array٠iteri_sliceーspec Ψ fn t dq vs (i n : Z) :
{{{
▷ Ψ 0 [] ∗
array۰model t dq vs ∗
□ (
∀ k v,
⌜k < ₊n⌝ -∗
⌜vs !! (₊i + k)%nat = Some v⌝ -∗
Ψ k (slice ₊i k vs) -∗
WP fn #k v {{ res,
⌜res = ()%V⌝ ∗
▷ Ψ ˖k (slice ₊i k vs ++ [v])
}}
)
}}}
array٠iteri_slice fn t #i #n
{{{
RET ();
⌜0 ≤ i ≤ length vs⌝%Z ∗
⌜0 ≤ n⌝%Z ∗
⌜i + n ≤ length vs⌝%Z ∗
array۰model t dq vs ∗
Ψ ₊n (slice ₊i ₊n vs)
}}}.
Lemma array٠iteri_sliceーspec' Ψ fn t dq vs (i n : Z) :
{{{
▷ Ψ 0 [] ∗
array۰model t dq vs ∗
( [∗ list] k ↦ v ∈ slice ₊i ₊n vs,
Ψ k (slice ₊i k vs) -∗
WP fn #k v {{ res,
⌜res = ()%V⌝ ∗
▷ Ψ ˖k (slice ₊i k vs ++ [v])
}}
)
}}}
array٠iteri_slice fn t #i #n
{{{
RET ();
⌜0 ≤ i ≤ length vs⌝%Z ∗
⌜0 ≤ n⌝%Z ∗
⌜i + n ≤ length vs⌝%Z ∗
array۰model t dq vs ∗
Ψ ₊n (slice ₊i ₊n vs)
}}}.
Lemma array٠iteri_sliceーspecーdisentangled Ψ fn t dq vs (i n : Z) :
{{{
array۰model t dq vs ∗
□ (
∀ k v,
⌜k < ₊n⌝ -∗
⌜vs !! (₊i + k)%nat = Some v⌝ -∗
WP fn #k v {{ res,
⌜res = ()%V⌝ ∗
▷ Ψ k v
}}
)
}}}
array٠iteri_slice fn t #i #n
{{{
RET ();
⌜0 ≤ i ≤ length vs⌝%Z ∗
⌜0 ≤ n⌝%Z ∗
⌜i + n ≤ length vs⌝%Z ∗
array۰model t dq vs ∗
( [∗ list] k ↦ v ∈ slice ₊i ₊n vs,
Ψ k v
)
}}}.
Lemma array٠iteri_sliceーspecーdisentangled' Ψ fn t dq vs (i n : Z) :
{{{
array۰model t dq vs ∗
( [∗ list] k ↦ v ∈ slice ₊i ₊n vs,
WP fn #k v {{ res,
⌜res = ()%V⌝ ∗
▷ Ψ k v
}}
)
}}}
array٠iteri_slice fn t #i #n
{{{
RET ();
⌜0 ≤ i ≤ length vs⌝%Z ∗
⌜0 ≤ n⌝%Z ∗
⌜i + n ≤ length vs⌝%Z ∗
array۰model t dq vs ∗
( [∗ list] k ↦ v ∈ slice ₊i ₊n vs,
Ψ k v
)
}}}.
Lemma array٠unsafe_iter_sliceーspecーatomic Ψ fn t (sz : nat) (i n : Z) :
(0 ≤ i ≤ sz)%Z →
(0 ≤ n)%Z →
(i + n ≤ sz)%Z →
{{{
array۰inv t sz ∗
▷ Ψ 0 [] None ∗
□ (
∀ k vs (o : option val),
⌜k < ₊n⌝ -∗
⌜k = length vs⌝ -∗
Ψ k vs o -∗
match o with
| None ⇒
au_load t (₊i + k) (λ v,
▷ Ψ k vs (Some v)
)
| Some v ⇒
WP fn v {{ res,
⌜res = ()%V⌝ ∗
▷ Ψ ˖k (vs ++ [v]) None
}}
end
)
}}}
array٠unsafe_iter_slice fn t #i #n
{{{
vs
, RET ();
⌜length vs = ₊n⌝ ∗
Ψ ₊n vs None
}}}.
Lemma array٠unsafe_iter_sliceーspec Ψ fn t dq vs (i n : Z) :
(0 ≤ i ≤ length vs)%Z →
(0 ≤ n)%Z →
(i + n ≤ length vs)%Z →
{{{
▷ Ψ 0 [] ∗
array۰model t dq vs ∗
□ (
∀ k v,
⌜k < ₊n⌝ -∗
⌜vs !! (₊i + k)%nat = Some v⌝ -∗
Ψ k (slice ₊i k vs) -∗
WP fn v {{ res,
⌜res = ()%V⌝ ∗
▷ Ψ ˖k (slice ₊i k vs ++ [v])
}}
)
}}}
array٠unsafe_iter_slice fn t #i #n
{{{
RET ();
array۰model t dq vs ∗
Ψ ₊n (slice ₊i ₊n vs)
}}}.
Lemma array٠unsafe_iter_sliceーspec' Ψ fn t dq vs (i n : Z) :
(0 ≤ i ≤ length vs)%Z →
(0 ≤ n)%Z →
(i + n ≤ length vs)%Z →
{{{
▷ Ψ 0 [] ∗
array۰model t dq vs ∗
( [∗ list] k ↦ v ∈ slice ₊i ₊n vs,
Ψ k (slice ₊i k vs) -∗
WP fn v {{ res,
⌜res = ()%V⌝ ∗
▷ Ψ ˖k (slice ₊i k vs ++ [v])
}}
)
}}}
array٠unsafe_iter_slice fn t #i #n
{{{
RET ();
array۰model t dq vs ∗
Ψ ₊n (slice ₊i ₊n vs)
}}}.
Lemma array٠unsafe_iter_sliceーspecーdisentangled Ψ fn t dq vs (i n : Z) :
(0 ≤ i ≤ length vs)%Z →
(0 ≤ n)%Z →
(i + n ≤ length vs)%Z →
{{{
array۰model t dq vs ∗
□ (
∀ k v,
⌜k < ₊n⌝ -∗
⌜vs !! (₊i + k)%nat = Some v⌝ -∗
WP fn v {{ res,
⌜res = ()%V⌝ ∗
▷ Ψ k v
}}
)
}}}
array٠unsafe_iter_slice fn t #i #n
{{{
RET ();
array۰model t dq vs ∗
( [∗ list] k ↦ v ∈ slice ₊i ₊n vs,
Ψ k v
)
}}}.
Lemma array٠unsafe_iter_sliceーspecーdisentangled' Ψ fn t dq vs (i n : Z) :
(0 ≤ i ≤ length vs)%Z →
(0 ≤ n)%Z →
(i + n ≤ length vs)%Z →
{{{
array۰model t dq vs ∗
( [∗ list] k ↦ v ∈ slice ₊i ₊n vs,
WP fn v {{ res,
⌜res = ()%V⌝ ∗
▷ Ψ k v
}}
)
}}}
array٠unsafe_iter_slice fn t #i #n
{{{
RET ();
array۰model t dq vs ∗
( [∗ list] k ↦ v ∈ slice ₊i ₊n vs,
Ψ k v
)
}}}.
Lemma array٠iter_sliceーspecーatomic Ψ fn t (sz : nat) (i n : Z) :
{{{
array۰inv t sz ∗
▷ Ψ 0 [] None ∗
□ (
∀ k vs (o : option val),
⌜k < ₊n⌝ -∗
⌜k = length vs⌝ -∗
Ψ k vs o -∗
match o with
| None ⇒
au_load t (₊i + k) (λ v,
▷ Ψ k vs (Some v)
)
| Some v ⇒
WP fn v {{ res,
⌜res = ()%V⌝ ∗
▷ Ψ ˖k (vs ++ [v]) None
}}
end
)
}}}
array٠iter_slice fn t #i #n
{{{
vs
, RET ();
⌜0 ≤ i ≤ sz⌝%Z ∗
⌜0 ≤ n⌝%Z ∗
⌜i + n ≤ sz⌝%Z ∗
⌜length vs = ₊n⌝ ∗
Ψ ₊n vs None
}}}.
Lemma array٠iter_sliceーspec Ψ fn t dq vs (i n : Z) :
{{{
▷ Ψ 0 [] ∗
array۰model t dq vs ∗
□ (
∀ k v,
⌜k < ₊n⌝ -∗
⌜vs !! (₊i + k)%nat = Some v⌝ -∗
Ψ k (slice ₊i k vs) -∗
WP fn v {{ res,
⌜res = ()%V⌝ ∗
▷ Ψ ˖k (slice ₊i k vs ++ [v])
}}
)
}}}
array٠iter_slice fn t #i #n
{{{
RET ();
⌜0 ≤ i ≤ length vs⌝%Z ∗
⌜0 ≤ n⌝%Z ∗
⌜i + n ≤ length vs⌝%Z ∗
array۰model t dq vs ∗
Ψ ₊n (slice ₊i ₊n vs)
}}}.
Lemma array٠iter_sliceーspec' Ψ fn t dq vs (i n : Z) :
{{{
▷ Ψ 0 [] ∗
array۰model t dq vs ∗
( [∗ list] k ↦ v ∈ slice ₊i ₊n vs,
Ψ k (slice ₊i k vs) -∗
WP fn v {{ res,
⌜res = ()%V⌝ ∗
▷ Ψ ˖k (slice ₊i k vs ++ [v])
}}
)
}}}
array٠iter_slice fn t #i #n
{{{
RET ();
⌜0 ≤ i ≤ length vs⌝%Z ∗
⌜0 ≤ n⌝%Z ∗
⌜i + n ≤ length vs⌝%Z ∗
array۰model t dq vs ∗
Ψ ₊n (slice ₊i ₊n vs)
}}}.
Lemma array٠iter_sliceーspecーdisentangled Ψ fn t dq vs (i n : Z) :
{{{
array۰model t dq vs ∗
□ (
∀ k v,
⌜k < ₊n⌝ -∗
⌜vs !! (₊i + k)%nat = Some v⌝ -∗
WP fn v {{ res,
⌜res = ()%V⌝ ∗
▷ Ψ k v
}}
)
}}}
array٠iter_slice fn t #i #n
{{{
RET ();
⌜0 ≤ i ≤ length vs⌝%Z ∗
⌜0 ≤ n⌝%Z ∗
⌜i + n ≤ length vs⌝%Z ∗
array۰model t dq vs ∗
( [∗ list] k ↦ v ∈ slice ₊i ₊n vs,
Ψ k v
)
}}}.
Lemma array٠iter_sliceーspecーdisentangled' Ψ fn t dq vs (i n : Z) :
{{{
array۰model t dq vs ∗
( [∗ list] k ↦ v ∈ slice ₊i ₊n vs,
WP fn v {{ res,
⌜res = ()%V⌝ ∗
▷ Ψ k v
}}
)
}}}
array٠iter_slice fn t #i #n
{{{
RET ();
⌜0 ≤ i ≤ length vs⌝%Z ∗
⌜0 ≤ n⌝%Z ∗
⌜i + n ≤ length vs⌝%Z ∗
array۰model t dq vs ∗
( [∗ list] k ↦ v ∈ slice ₊i ₊n vs,
Ψ k v
)
}}}.
Lemma array٠iteriーspecーatomic Ψ fn t sz :
{{{
array۰inv t sz ∗
▷ Ψ 0 [] None ∗
□ (
∀ i vs (o : option val),
⌜i < sz⌝ -∗
⌜i = length vs⌝ -∗
Ψ i vs o -∗
match o with
| None ⇒
au_load t i (λ v,
▷ Ψ i vs (Some v)
)
| Some v ⇒
WP fn #i v {{ res,
⌜res = ()%V⌝ ∗
▷ Ψ ˖i (vs ++ [v]) None
}}
end
)
}}}
array٠iteri fn t
{{{
vs
, RET ();
⌜length vs = sz⌝ ∗
Ψ sz vs None
}}}.
Lemma array٠iteriーspec Ψ fn t dq vs :
{{{
▷ Ψ 0 [] ∗
array۰model t dq vs ∗
□ (
∀ i v,
⌜vs !! i = Some v⌝ -∗
Ψ i (take i vs) -∗
WP fn #i v {{ res,
⌜res = ()%V⌝ ∗
▷ Ψ ˖i (take i vs ++ [v])
}}
)
}}}
array٠iteri fn t
{{{
RET ();
array۰model t dq vs ∗
Ψ (length vs) vs
}}}.
Lemma array٠iteriーspec' Ψ fn t dq vs :
{{{
▷ Ψ 0 [] ∗
array۰model t dq vs ∗
( [∗ list] i ↦ v ∈ vs,
Ψ i (take i vs) -∗
WP fn #i v {{ res,
⌜res = ()%V⌝ ∗
▷ Ψ ˖i (take i vs ++ [v])
}}
)
}}}
array٠iteri fn t
{{{
RET ();
array۰model t dq vs ∗
Ψ (length vs) vs
}}}.
Lemma array٠iteriーspecーdisentangled Ψ fn t dq vs :
{{{
array۰model t dq vs ∗
□ (
∀ i v,
⌜vs !! i = Some v⌝ -∗
WP fn #i v {{ res,
⌜res = ()%V⌝ ∗
▷ Ψ i v
}}
)
}}}
array٠iteri fn t
{{{
RET ();
array۰model t dq vs ∗
( [∗ list] i ↦ v ∈ vs,
Ψ i v
)
}}}.
Lemma array٠iteriーspecーdisentangled' Ψ fn t dq vs :
{{{
array۰model t dq vs ∗
( [∗ list] i ↦ v ∈ vs,
WP fn #i v {{ res,
⌜res = ()%V⌝ ∗
▷ Ψ i v
}}
)
}}}
array٠iteri fn t
{{{
RET ();
array۰model t dq vs ∗
( [∗ list] i ↦ v ∈ vs,
Ψ i v
)
}}}.
Lemma array٠iterーspecーatomic Ψ fn t sz :
{{{
array۰inv t sz ∗
▷ Ψ 0 [] None ∗
□ (
∀ i vs (o : option val),
⌜i < sz⌝ -∗
⌜i = length vs⌝ -∗
Ψ i vs o -∗
match o with
| None ⇒
au_load t i (λ v,
▷ Ψ i vs (Some v)
)
| Some v ⇒
WP fn v {{ res,
⌜res = ()%V⌝ ∗
▷ Ψ ˖i (vs ++ [v]) None
}}
end
)
}}}
array٠iter fn t
{{{
vs
, RET ();
⌜length vs = sz⌝ ∗
Ψ sz vs None
}}}.
Lemma array٠iterーspec Ψ fn t dq vs :
{{{
▷ Ψ 0 [] ∗
array۰model t dq vs ∗
□ (
∀ i v,
⌜vs !! i = Some v⌝ -∗
Ψ i (take i vs) -∗
WP fn v {{ res,
⌜res = ()%V⌝ ∗
▷ Ψ ˖i (take i vs ++ [v])
}}
)
}}}
array٠iter fn t
{{{
RET ();
array۰model t dq vs ∗
Ψ (length vs) vs
}}}.
Lemma array٠iterーspec' Ψ fn t dq vs :
{{{
▷ Ψ 0 [] ∗
array۰model t dq vs ∗
( [∗ list] i ↦ v ∈ vs,
Ψ i (take i vs) -∗
WP fn v {{ res,
⌜res = ()%V⌝ ∗
▷ Ψ ˖i (take i vs ++ [v])
}}
)
}}}
array٠iter fn t
{{{
RET ();
array۰model t dq vs ∗
Ψ (length vs) vs
}}}.
Lemma array٠iterーspecーdisentangled Ψ fn t dq vs :
{{{
array۰model t dq vs ∗
□ (
∀ i v,
⌜vs !! i = Some v⌝ -∗
WP fn v {{ res,
⌜res = ()%V⌝ ∗
▷ Ψ i v
}}
)
}}}
array٠iter fn t
{{{
RET ();
array۰model t dq vs ∗
( [∗ list] i ↦ v ∈ vs,
Ψ i v
)
}}}.
Lemma array٠iterーspecーdisentangled' Ψ fn t dq vs :
{{{
array۰model t dq vs ∗
( [∗ list] i ↦ v ∈ vs,
WP fn v {{ res,
⌜res = ()%V⌝ ∗
▷ Ψ i v
}}
)
}}}
array٠iter fn t
{{{
RET ();
array۰model t dq vs ∗
( [∗ list] i ↦ v ∈ vs,
Ψ i v
)
}}}.
Lemma array٠unsafe_applyi_sliceーspecーatomic Ψ fn t (sz : nat) (i n : Z) :
(0 ≤ i ≤ sz)%Z →
(0 ≤ n)%Z →
(i + n ≤ sz)%Z →
{{{
array۰inv t sz ∗
▷ Ψ 0 [] None [] ∗
□ (
∀ k vs (o : option (val + val × val)) ws,
⌜k < ₊n⌝ -∗
⌜k = length vs⌝ -∗
⌜length vs = length ws⌝ -∗
Ψ k vs o ws -∗
match o with
| None ⇒
au_load t (₊i + k) (λ v,
▷ Ψ k vs (Some $ inl v) ws
)
| Some (inl v) ⇒
WP fn #k v {{ w,
▷ Ψ k vs (Some $ inr (v, w)) ws
}}
| Some (inr (v, w)) ⇒
au_store t (₊i + k) w (
▷ Ψ ˖k (vs ++ [v]) None (ws ++ [w])
)
end
)
}}}
array٠unsafe_applyi_slice fn t #i #n
{{{
vs ws
, RET ();
⌜length vs = ₊n⌝ ∗
⌜length vs = length ws⌝ ∗
Ψ ₊n vs None ws
}}}.
Lemma array٠unsafe_applyi_sliceーspec Ψ fn t vs (i n : Z) :
(0 ≤ i ≤ length vs)%Z →
(0 ≤ n)%Z →
(i + n ≤ length vs)%Z →
{{{
▷ Ψ 0 [] [] ∗
array۰model t (DfracOwn 1) vs ∗
□ (
∀ k v ws,
⌜k = length ws⌝ -∗
⌜k < ₊n⌝ -∗
⌜vs !! (₊i + k)%nat = Some v⌝ -∗
Ψ k (slice ₊i k vs) ws -∗
WP fn #k v {{ w,
▷ Ψ ˖k (slice ₊i k vs ++ [v]) (ws ++ [w])
}}
)
}}}
array٠unsafe_applyi_slice fn t #i #n
{{{
ws
, RET ();
⌜length ws = ₊n⌝ ∗
array۰model t (DfracOwn 1) (with_slice ₊i ₊n vs ws) ∗
Ψ ₊n (slice ₊i ₊n vs) ws
}}}.
Lemma array٠unsafe_applyi_sliceーspec' Ψ fn t vs (i n : Z) :
(0 ≤ i ≤ length vs)%Z →
(0 ≤ n)%Z →
(i + n ≤ length vs)%Z →
{{{
▷ Ψ 0 [] [] ∗
array۰model t (DfracOwn 1) vs ∗
( [∗ list] k ↦ v ∈ slice ₊i ₊n vs,
∀ ws,
⌜k = length ws⌝ -∗
Ψ k (slice ₊i k vs) ws -∗
WP fn #k v {{ w,
▷ Ψ ˖k (slice ₊i k vs ++ [v]) (ws ++ [w])
}}
)
}}}
array٠unsafe_applyi_slice fn t #i #n
{{{
ws
, RET ();
⌜length ws = ₊n⌝ ∗
array۰model t (DfracOwn 1) (with_slice ₊i ₊n vs ws) ∗
Ψ ₊n (slice ₊i ₊n vs) ws
}}}.
Lemma array٠unsafe_applyi_sliceーspecーdisentangled Ψ fn t vs (i n : Z) :
(0 ≤ i ≤ length vs)%Z →
(0 ≤ n)%Z →
(i + n ≤ length vs)%Z →
{{{
array۰model t (DfracOwn 1) vs ∗
□ (
∀ k v,
⌜k < ₊n⌝ -∗
⌜vs !! (₊i + k)%nat = Some v⌝ -∗
WP fn #k v {{ w,
▷ Ψ k w
}}
)
}}}
array٠unsafe_applyi_slice fn t #i #n
{{{
ws
, RET ();
⌜length ws = ₊n⌝ ∗
array۰model t (DfracOwn 1) (with_slice ₊i ₊n vs ws) ∗
( [∗ list] i ↦ w ∈ ws,
Ψ i w
)
}}}.
Lemma array٠unsafe_applyi_sliceーspecーdisentangled' Ψ fn t vs (i n : Z) :
(0 ≤ i ≤ length vs)%Z →
(0 ≤ n)%Z →
(i + n ≤ length vs)%Z →
{{{
array۰model t (DfracOwn 1) vs ∗
( [∗ list] k ↦ v ∈ slice ₊i ₊n vs,
WP fn #k v {{ w,
▷ Ψ k w
}}
)
}}}
array٠unsafe_applyi_slice fn t #i #n
{{{
ws
, RET ();
array۰model t (DfracOwn 1) (with_slice ₊i ₊n vs ws) ∗
( [∗ list] i ↦ w ∈ ws,
Ψ i w
)
}}}.
Lemma array٠applyi_sliceーspecーatomic Ψ fn t (sz : nat) (i n : Z) :
{{{
array۰inv t sz ∗
▷ Ψ 0 [] None [] ∗
□ (
∀ k vs (o : option (val + val × val)) ws,
⌜k < ₊n⌝ -∗
⌜k = length vs⌝ -∗
⌜length vs = length ws⌝ -∗
Ψ k vs o ws -∗
match o with
| None ⇒
au_load t (₊i + k) (λ v,
▷ Ψ k vs (Some $ inl v) ws
)
| Some (inl v) ⇒
WP fn #k v {{ w,
▷ Ψ k vs (Some $ inr (v, w)) ws
}}
| Some (inr (v, w)) ⇒
au_store t (₊i + k) w (
▷ Ψ ˖k (vs ++ [v]) None (ws ++ [w])
)
end
)
}}}
array٠applyi_slice fn t #i #n
{{{
vs ws
, RET ();
⌜0 ≤ i ≤ sz⌝%Z ∗
⌜0 ≤ n⌝%Z ∗
⌜i + n ≤ sz⌝%Z ∗
⌜length vs = ₊n⌝ ∗
⌜length vs = length ws⌝ ∗
Ψ ₊n vs None ws
}}}.
Lemma array٠applyi_sliceーspec Ψ fn t vs (i n : Z) :
{{{
▷ Ψ 0 [] [] ∗
array۰model t (DfracOwn 1) vs ∗
□ (
∀ k v ws,
⌜k = length ws⌝ -∗
⌜k < ₊n⌝ -∗
⌜vs !! (₊i + k)%nat = Some v⌝ -∗
Ψ k (slice ₊i k vs) ws -∗
WP fn #k v {{ w,
▷ Ψ ˖k (slice ₊i k vs ++ [v]) (ws ++ [w])
}}
)
}}}
array٠applyi_slice fn t #i #n
{{{
ws
, RET ();
⌜0 ≤ i ≤ length vs⌝%Z ∗
⌜0 ≤ n⌝%Z ∗
⌜i + n ≤ length vs⌝%Z ∗
⌜length ws = ₊n⌝ ∗
array۰model t (DfracOwn 1) (with_slice ₊i ₊n vs ws) ∗
Ψ ₊n (slice ₊i ₊n vs) ws
}}}.
Lemma array٠applyi_sliceーspec' Ψ fn t vs (i n : Z) :
{{{
▷ Ψ 0 [] [] ∗
array۰model t (DfracOwn 1) vs ∗
( [∗ list] k ↦ v ∈ slice ₊i ₊n vs,
∀ ws,
⌜k = length ws⌝ -∗
Ψ k (slice ₊i k vs) ws -∗
WP fn #k v {{ w,
▷ Ψ ˖k (slice ₊i k vs ++ [v]) (ws ++ [w])
}}
)
}}}
array٠applyi_slice fn t #i #n
{{{
ws
, RET ();
⌜0 ≤ i ≤ length vs⌝%Z ∗
⌜0 ≤ n⌝%Z ∗
⌜i + n ≤ length vs⌝%Z ∗
⌜length ws = ₊n⌝ ∗
array۰model t (DfracOwn 1) (with_slice ₊i ₊n vs ws) ∗
Ψ ₊n (slice ₊i ₊n vs) ws
}}}.
Lemma array٠applyi_sliceーspecーdisentangled Ψ fn t vs (i n : Z) :
{{{
array۰model t (DfracOwn 1) vs ∗
□ (
∀ k v,
⌜k < ₊n⌝ -∗
⌜vs !! (₊i + k)%nat = Some v⌝ -∗
WP fn #k v {{ w,
▷ Ψ k w
}}
)
}}}
array٠applyi_slice fn t #i #n
{{{
ws
, RET ();
⌜0 ≤ i ≤ length vs⌝%Z ∗
⌜0 ≤ n⌝%Z ∗
⌜i + n ≤ length vs⌝%Z ∗
⌜length ws = ₊n⌝ ∗
array۰model t (DfracOwn 1) (with_slice ₊i ₊n vs ws) ∗
( [∗ list] i ↦ w ∈ ws,
Ψ i w
)
}}}.
Lemma array٠applyi_sliceーspecーdisentangled' Ψ fn t vs (i n : Z) :
{{{
array۰model t (DfracOwn 1) vs ∗
( [∗ list] k ↦ v ∈ slice ₊i ₊n vs,
WP fn #k v {{ w,
▷ Ψ k w
}}
)
}}}
array٠applyi_slice fn t #i #n
{{{
ws
, RET ();
⌜0 ≤ i ≤ length vs⌝%Z ∗
⌜0 ≤ n⌝%Z ∗
⌜i + n ≤ length vs⌝%Z ∗
array۰model t (DfracOwn 1) (with_slice ₊i ₊n vs ws) ∗
( [∗ list] i ↦ w ∈ ws,
Ψ i w
)
}}}.
Lemma array٠unsafe_apply_sliceーspecーatomic Ψ fn t (sz : nat) (i n : Z) :
(0 ≤ i ≤ sz)%Z →
(0 ≤ n)%Z →
(i + n ≤ sz)%Z →
{{{
array۰inv t sz ∗
▷ Ψ 0 [] None [] ∗
□ (
∀ k vs (o : option (val + val × val)) ws,
⌜k < ₊n⌝ -∗
⌜k = length vs⌝ -∗
⌜length vs = length ws⌝ -∗
Ψ k vs o ws -∗
match o with
| None ⇒
au_load t (₊i + k) (λ v,
▷ Ψ k vs (Some $ inl v) ws
)
| Some (inl v) ⇒
WP fn v {{ w,
▷ Ψ k vs (Some $ inr (v, w)) ws
}}
| Some (inr (v, w)) ⇒
au_store t (₊i + k) w (
▷ Ψ ˖k (vs ++ [v]) None (ws ++ [w])
)
end
)
}}}
array٠unsafe_apply_slice fn t #i #n
{{{
vs ws
, RET ();
⌜length vs = ₊n⌝ ∗
⌜length vs = length ws⌝ ∗
Ψ ₊n vs None ws
}}}.
Lemma array٠unsafe_apply_sliceーspec Ψ fn t vs (i n : Z) :
(0 ≤ i ≤ length vs)%Z →
(0 ≤ n)%Z →
(i + n ≤ length vs)%Z →
{{{
▷ Ψ 0 [] [] ∗
array۰model t (DfracOwn 1) vs ∗
□ (
∀ k v ws,
⌜k = length ws⌝ -∗
⌜k < ₊n⌝ -∗
⌜vs !! (₊i + k)%nat = Some v⌝ -∗
Ψ k (slice ₊i k vs) ws -∗
WP fn v {{ w,
▷ Ψ ˖k (slice ₊i k vs ++ [v]) (ws ++ [w])
}}
)
}}}
array٠unsafe_apply_slice fn t #i #n
{{{
ws
, RET ();
⌜length ws = ₊n⌝ ∗
array۰model t (DfracOwn 1) (with_slice ₊i ₊n vs ws) ∗
Ψ ₊n (slice ₊i ₊n vs) ws
}}}.
Lemma array٠unsafe_apply_sliceーspec' Ψ fn t vs (i n : Z) :
(0 ≤ i ≤ length vs)%Z →
(0 ≤ n)%Z →
(i + n ≤ length vs)%Z →
{{{
▷ Ψ 0 [] [] ∗
array۰model t (DfracOwn 1) vs ∗
( [∗ list] k ↦ v ∈ slice ₊i ₊n vs,
∀ ws,
⌜k = length ws⌝ -∗
Ψ k (slice ₊i k vs) ws -∗
WP fn v {{ w,
▷ Ψ ˖k (slice ₊i k vs ++ [v]) (ws ++ [w])
}}
)
}}}
array٠unsafe_apply_slice fn t #i #n
{{{
ws
, RET ();
⌜length ws = ₊n⌝ ∗
array۰model t (DfracOwn 1) (with_slice ₊i ₊n vs ws) ∗
Ψ ₊n (slice ₊i ₊n vs) ws
}}}.
Lemma array٠unsafe_apply_sliceーspecーdisentangled Ψ fn t vs (i n : Z) :
(0 ≤ i ≤ length vs)%Z →
(0 ≤ n)%Z →
(i + n ≤ length vs)%Z →
{{{
array۰model t (DfracOwn 1) vs ∗
□ (
∀ k v,
⌜k < ₊n⌝ -∗
⌜vs !! (₊i + k)%nat = Some v⌝ -∗
WP fn v {{ w,
▷ Ψ k w
}}
)
}}}
array٠unsafe_apply_slice fn t #i #n
{{{
ws
, RET ();
⌜length ws = ₊n⌝ ∗
array۰model t (DfracOwn 1) (with_slice ₊i ₊n vs ws) ∗
( [∗ list] i ↦ w ∈ ws,
Ψ i w
)
}}}.
Lemma array٠unsafe_apply_sliceーspecーdisentangled' Ψ fn t vs (i n : Z) :
(0 ≤ i ≤ length vs)%Z →
(0 ≤ n)%Z →
(i + n ≤ length vs)%Z →
{{{
array۰model t (DfracOwn 1) vs ∗
( [∗ list] k ↦ v ∈ slice ₊i ₊n vs,
WP fn v {{ w,
▷ Ψ k w
}}
)
}}}
array٠unsafe_apply_slice fn t #i #n
{{{
ws
, RET ();
array۰model t (DfracOwn 1) (with_slice ₊i ₊n vs ws) ∗
( [∗ list] i ↦ w ∈ ws,
Ψ i w
)
}}}.
Lemma array٠apply_sliceーspecーatomic Ψ fn t (sz : nat) (i n : Z) :
{{{
array۰inv t sz ∗
▷ Ψ 0 [] None [] ∗
□ (
∀ k vs (o : option (val + val × val)) ws,
⌜k < ₊n⌝ -∗
⌜k = length vs⌝ -∗
⌜length vs = length ws⌝ -∗
Ψ k vs o ws -∗
match o with
| None ⇒
au_load t (₊i + k) (λ v,
▷ Ψ k vs (Some $ inl v) ws
)
| Some (inl v) ⇒
WP fn v {{ w,
▷ Ψ k vs (Some $ inr (v, w)) ws
}}
| Some (inr (v, w)) ⇒
au_store t (₊i + k) w (
▷ Ψ ˖k (vs ++ [v]) None (ws ++ [w])
)
end
)
}}}
array٠apply_slice fn t #i #n
{{{
vs ws
, RET ();
⌜0 ≤ i ≤ sz⌝%Z ∗
⌜0 ≤ n⌝%Z ∗
⌜i + n ≤ sz⌝%Z ∗
⌜length vs = ₊n⌝ ∗
⌜length vs = length ws⌝ ∗
Ψ ₊n vs None ws
}}}.
Lemma array٠apply_sliceーspec Ψ fn t vs (i n : Z) :
{{{
▷ Ψ 0 [] [] ∗
array۰model t (DfracOwn 1) vs ∗
□ (
∀ k v ws,
⌜k = length ws⌝ -∗
⌜k < ₊n⌝ -∗
⌜vs !! (₊i + k)%nat = Some v⌝ -∗
Ψ k (slice ₊i k vs) ws -∗
WP fn v {{ w,
▷ Ψ ˖k (slice ₊i k vs ++ [v]) (ws ++ [w])
}}
)
}}}
array٠apply_slice fn t #i #n
{{{
ws
, RET ();
⌜0 ≤ i ≤ length vs⌝%Z ∗
⌜0 ≤ n⌝%Z ∗
⌜i + n ≤ length vs⌝%Z ∗
⌜length ws = ₊n⌝ ∗
array۰model t (DfracOwn 1) (with_slice ₊i ₊n vs ws) ∗
Ψ ₊n (slice ₊i ₊n vs) ws
}}}.
Lemma array٠apply_sliceーspec' Ψ fn t vs (i n : Z) :
{{{
▷ Ψ 0 [] [] ∗
array۰model t (DfracOwn 1) vs ∗
( [∗ list] k ↦ v ∈ slice ₊i ₊n vs,
∀ ws,
⌜k = length ws⌝ -∗
Ψ k (slice ₊i k vs) ws -∗
WP fn v {{ w,
▷ Ψ ˖k (slice ₊i k vs ++ [v]) (ws ++ [w])
}}
)
}}}
array٠apply_slice fn t #i #n
{{{
ws
, RET ();
⌜0 ≤ i ≤ length vs⌝%Z ∗
⌜0 ≤ n⌝%Z ∗
⌜i + n ≤ length vs⌝%Z ∗
⌜length ws = ₊n⌝ ∗
array۰model t (DfracOwn 1) (with_slice ₊i ₊n vs ws) ∗
Ψ ₊n (slice ₊i ₊n vs) ws
}}}.
Lemma array٠apply_sliceーspecーdisentangled Ψ fn t vs (i n : Z) :
{{{
array۰model t (DfracOwn 1) vs ∗
□ (
∀ k v,
⌜k < ₊n⌝ -∗
⌜vs !! (₊i + k)%nat = Some v⌝ -∗
WP fn v {{ w,
▷ Ψ k w
}}
)
}}}
array٠apply_slice fn t #i #n
{{{
ws
, RET ();
⌜0 ≤ i ≤ length vs⌝%Z ∗
⌜0 ≤ n⌝%Z ∗
⌜i + n ≤ length vs⌝%Z ∗
⌜length ws = ₊n⌝ ∗
array۰model t (DfracOwn 1) (with_slice ₊i ₊n vs ws) ∗
( [∗ list] i ↦ w ∈ ws,
Ψ i w
)
}}}.
Lemma array٠apply_sliceーspecーdisentangled' Ψ fn t vs (i n : Z) :
{{{
array۰model t (DfracOwn 1) vs ∗
( [∗ list] k ↦ v ∈ slice ₊i ₊n vs,
WP fn v {{ w,
▷ Ψ k w
}}
)
}}}
array٠apply_slice fn t #i #n
{{{
ws
, RET ();
⌜0 ≤ i ≤ length vs⌝%Z ∗
⌜0 ≤ n⌝%Z ∗
⌜i + n ≤ length vs⌝%Z ∗
array۰model t (DfracOwn 1) (with_slice ₊i ₊n vs ws) ∗
( [∗ list] i ↦ w ∈ ws,
Ψ i w
)
}}}.
Lemma array٠applyiーspecーatomic Ψ fn t sz :
{{{
array۰inv t sz ∗
▷ Ψ 0 [] None [] ∗
□ (
∀ i vs (o : option (val + val × val)) ws,
⌜i < sz⌝ -∗
⌜i = length vs⌝ -∗
⌜length vs = length ws⌝ -∗
Ψ i vs o ws -∗
match o with
| None ⇒
au_load t i (λ v,
▷ Ψ i vs (Some $ inl v) ws
)
| Some (inl v) ⇒
WP fn #i v {{ w,
▷ Ψ i vs (Some $ inr (v, w)) ws
}}
| Some (inr (v, w)) ⇒
au_store t i w (
▷ Ψ ˖i (vs ++ [v]) None (ws ++ [w])
)
end
)
}}}
array٠applyi fn t
{{{
vs ws
, RET ();
⌜length vs = sz⌝ ∗
⌜length vs = length ws⌝ ∗
Ψ sz vs None ws
}}}.
Lemma array٠applyiーspec Ψ fn t vs :
{{{
▷ Ψ 0 [] [] ∗
array۰model t (DfracOwn 1) vs ∗
□ (
∀ i v ws,
⌜i = length ws⌝ -∗
⌜vs !! i = Some v⌝ -∗
Ψ i (take i vs) ws -∗
WP fn #i v {{ w,
▷ Ψ ˖i (take i vs ++ [v]) (ws ++ [w])
}}
)
}}}
array٠applyi fn t
{{{
ws
, RET ();
⌜length vs = length ws⌝ ∗
array۰model t (DfracOwn 1) ws ∗
Ψ (length vs) vs ws
}}}.
Lemma array٠applyiーspec' Ψ fn t vs :
{{{
▷ Ψ 0 [] [] ∗
array۰model t (DfracOwn 1) vs ∗
( [∗ list] i ↦ v ∈ vs,
∀ ws,
⌜i = length ws⌝ -∗
Ψ i (take i vs) ws -∗
WP fn #i v {{ w,
▷ Ψ ˖i (take i vs ++ [v]) (ws ++ [w])
}}
)
}}}
array٠applyi fn t
{{{
ws
, RET ();
⌜length vs = length ws⌝ ∗
array۰model t (DfracOwn 1) ws ∗
Ψ (length vs) vs ws
}}}.
Lemma array٠applyiーspecーdisentangled Ψ fn t vs :
{{{
array۰model t (DfracOwn 1) vs ∗
□ (
∀ i v,
⌜vs !! i = Some v⌝ -∗
WP fn #i v {{ w,
▷ Ψ i w
}}
)
}}}
array٠applyi fn t
{{{
ws
, RET ();
⌜length vs = length ws⌝ ∗
array۰model t (DfracOwn 1) ws ∗
( [∗ list] i ↦ w ∈ ws,
Ψ i w
)
}}}.
Lemma array٠applyiーspecーdisentangled' Ψ fn t vs :
{{{
array۰model t (DfracOwn 1) vs ∗
( [∗ list] i ↦ v ∈ vs,
WP fn #i v {{ w,
▷ Ψ i w
}}
)
}}}
array٠applyi fn t
{{{
ws
, RET ();
array۰model t (DfracOwn 1) ws ∗
( [∗ list] i ↦ w ∈ ws,
Ψ i w
)
}}}.
Lemma array٠applyーspecーatomic Ψ fn t sz :
{{{
array۰inv t sz ∗
▷ Ψ 0 [] None [] ∗
□ (
∀ i vs (o : option (val + val × val)) ws,
⌜i < sz⌝ -∗
⌜i = length vs⌝ -∗
⌜length vs = length ws⌝ -∗
Ψ i vs o ws -∗
match o with
| None ⇒
au_load t i (λ v,
▷ Ψ i vs (Some $ inl v) ws
)
| Some (inl v) ⇒
WP fn v {{ w,
▷ Ψ i vs (Some $ inr (v, w)) ws
}}
| Some (inr (v, w)) ⇒
au_store t i w (
▷ Ψ ˖i (vs ++ [v]) None (ws ++ [w])
)
end
)
}}}
array٠apply fn t
{{{
vs ws
, RET ();
⌜length vs = sz⌝ ∗
⌜length vs = length ws⌝ ∗
Ψ sz vs None ws
}}}.
Lemma array٠applyーspec Ψ fn t vs :
{{{
▷ Ψ 0 [] [] ∗
array۰model t (DfracOwn 1) vs ∗
□ (
∀ i v ws,
⌜i = length ws⌝ -∗
⌜vs !! i = Some v⌝ -∗
Ψ i (take i vs) ws -∗
WP fn v {{ w,
▷ Ψ ˖i (take i vs ++ [v]) (ws ++ [w])
}}
)
}}}
array٠apply fn t
{{{
ws
, RET ();
⌜length vs = length ws⌝ ∗
array۰model t (DfracOwn 1) ws ∗
Ψ (length vs) vs ws
}}}.
Lemma array٠applyーspec' Ψ fn t vs :
{{{
▷ Ψ 0 [] [] ∗
array۰model t (DfracOwn 1) vs ∗
( [∗ list] i ↦ v ∈ vs,
∀ ws,
⌜i = length ws⌝ -∗
Ψ i (take i vs) ws -∗
WP fn v {{ w,
▷ Ψ ˖i (take i vs ++ [v]) (ws ++ [w])
}}
)
}}}
array٠apply fn t
{{{
ws
, RET ();
⌜length vs = length ws⌝ ∗
array۰model t (DfracOwn 1) ws ∗
Ψ (length vs) vs ws
}}}.
Lemma array٠applyーspecーdisentangled Ψ fn t vs :
{{{
array۰model t (DfracOwn 1) vs ∗
□ (
∀ i v,
⌜vs !! i = Some v⌝ -∗
WP fn v {{ w,
▷ Ψ i w
}}
)
}}}
array٠apply fn t
{{{
ws
, RET ();
⌜length vs = length ws⌝ ∗
array۰model t (DfracOwn 1) ws ∗
( [∗ list] i ↦ w ∈ ws,
Ψ i w
)
}}}.
Lemma array٠applyーspecーdisentangled' Ψ fn t vs :
{{{
array۰model t (DfracOwn 1) vs ∗
( [∗ list] i ↦ v ∈ vs,
WP fn v {{ w,
▷ Ψ i w
}}
)
}}}
array٠apply fn t
{{{
ws
, RET ();
array۰model t (DfracOwn 1) ws ∗
( [∗ list] i ↦ w ∈ ws,
Ψ i w
)
}}}.
Lemma array٠unsafe_initiーspec Ψ sz fn :
(0 ≤ sz)%Z →
{{{
▷ (
∀ t,
|={⊤}=> Ψ t 0 []
) ∗
□ (
∀ t i vs,
⌜i < ₊sz⌝ -∗
⌜i = length vs⌝ -∗
Ψ t i vs -∗
WP fn #i {{ v,
▷ Ψ t ˖i (vs ++ [v])
}}
)
}}}
array٠unsafe_initi #sz fn
{{{
t vs
, RET t;
⌜length vs = ₊sz⌝ ∗
array۰model t (DfracOwn 1) vs ∗
Ψ t ₊sz vs
}}}.
Lemma array٠unsafe_initiーspec' Ψ sz fn :
(0 ≤ sz)%Z →
{{{
▷ (
∀ t,
|={⊤}=> Ψ t 0 []
) ∗
( [∗ list] i ∈ seq 0 ₊sz,
∀ t vs,
⌜i = length vs⌝ -∗
Ψ t i vs -∗
WP fn #i {{ v,
▷ Ψ t ˖i (vs ++ [v])
}}
)
}}}
array٠unsafe_initi #sz fn
{{{
t vs
, RET t;
⌜length vs = ₊sz⌝ ∗
array۰model t (DfracOwn 1) vs ∗
Ψ t ₊sz vs
}}}.
Lemma array٠unsafe_initiーspecーdisentangledーstrong Χ Ψ sz fn :
(0 ≤ sz)%Z →
{{{
▷ (
∀ t,
|={⊤}=> Χ t
) ∗
□ (
∀ t i,
Χ t -∗
⌜i < ₊sz⌝ -∗
WP fn #i {{ v,
Χ t ∗
▷ Ψ t i v
}}
)
}}}
array٠unsafe_initi #sz fn
{{{
t vs
, RET t;
⌜length vs = ₊sz⌝ ∗
array۰model t (DfracOwn 1) vs ∗
Χ t ∗
( [∗ list] i ↦ v ∈ vs,
Ψ t i v
)
}}}.
Lemma array٠unsafe_initiーspecーdisentangled Ψ sz fn :
(0 ≤ sz)%Z →
{{{
□ (
∀ i,
⌜i < ₊sz⌝ -∗
WP fn #i {{ v,
▷ Ψ i v
}}
)
}}}
array٠unsafe_initi #sz fn
{{{
t vs
, RET t;
⌜length vs = ₊sz⌝ ∗
array۰model t (DfracOwn 1) vs ∗
( [∗ list] i ↦ v ∈ vs,
Ψ i v
)
}}}.
Lemma array٠unsafe_initiーspecーdisentangledーstrong' Χ Ψ sz fn :
(0 ≤ sz)%Z →
{{{
▷ (
∀ t,
|={⊤}=> Χ t
) ∗
( [∗ list] i ∈ seq 0 ₊sz,
∀ t,
Χ t -∗
WP fn #i {{ v,
Χ t ∗
▷ Ψ t i v
}}
)
}}}
array٠unsafe_initi #sz fn
{{{
t vs
, RET t;
⌜length vs = ₊sz⌝ ∗
array۰model t (DfracOwn 1) vs ∗
Χ t ∗
( [∗ list] i ↦ v ∈ vs,
Ψ t i v
)
}}}.
Lemma array٠unsafe_initiーspecーdisentangled' Ψ sz fn :
(0 ≤ sz)%Z →
{{{
( [∗ list] i ∈ seq 0 ₊sz,
WP fn #i {{ v,
▷ Ψ i v
}}
)
}}}
array٠unsafe_initi #sz fn
{{{
t vs
, RET t;
⌜length vs = ₊sz⌝ ∗
array۰model t (DfracOwn 1) vs ∗
( [∗ list] i ↦ v ∈ vs,
Ψ i v
)
}}}.
Lemma array٠initiーspec Ψ sz fn :
{{{
▷ (
∀ t,
|={⊤}=> Ψ t 0 []
) ∗
□ (
∀ t i vs,
⌜i < ₊sz⌝ -∗
⌜i = length vs⌝ -∗
Ψ t i vs -∗
WP fn #i {{ v,
▷ Ψ t ˖i (vs ++ [v])
}}
)
}}}
array٠initi #sz fn
{{{
t vs
, RET t;
⌜0 ≤ sz⌝%Z ∗
⌜length vs = ₊sz⌝ ∗
array۰model t (DfracOwn 1) vs ∗
Ψ t ₊sz vs
}}}.
Lemma array٠initiーspec' Ψ sz fn :
{{{
▷ (
∀ t,
|={⊤}=> Ψ t 0 []
) ∗
( [∗ list] i ∈ seq 0 ₊sz,
∀ t vs,
⌜i = length vs⌝ -∗
Ψ t i vs -∗
WP fn #i {{ v,
▷ Ψ t ˖i (vs ++ [v])
}}
)
}}}
array٠initi #sz fn
{{{
t vs
, RET t;
⌜0 ≤ sz⌝%Z ∗
⌜length vs = ₊sz⌝ ∗
array۰model t (DfracOwn 1) vs ∗
Ψ t ₊sz vs
}}}.
Lemma array٠initiーspecーdisentangled Ψ sz fn :
{{{
□ (
∀ i,
⌜i < ₊sz⌝ -∗
WP fn #i {{ v,
▷ Ψ i v
}}
)
}}}
array٠initi #sz fn
{{{
t vs
, RET t;
⌜0 ≤ sz⌝%Z ∗
⌜length vs = ₊sz⌝ ∗
array۰model t (DfracOwn 1) vs ∗
( [∗ list] i ↦ v ∈ vs,
Ψ i v
)
}}}.
Lemma array٠initiーspecーdisentangled' Ψ sz fn :
{{{
( [∗ list] i ∈ seq 0 ₊sz,
WP fn #i {{ v,
▷ Ψ i v
}}
)
}}}
array٠initi #sz fn
{{{
t vs
, RET t;
⌜0 ≤ sz⌝%Z ∗
⌜length vs = ₊sz⌝ ∗
array۰model t (DfracOwn 1) vs ∗
( [∗ list] i ↦ v ∈ vs,
Ψ i v
)
}}}.
Lemma array٠unsafe_initーspec Ψ sz fn :
(0 ≤ sz)%Z →
{{{
▷ (
∀ t,
|={⊤}=> Ψ t 0 []
) ∗
□ (
∀ t i vs,
⌜i < ₊sz⌝ -∗
⌜i = length vs⌝ -∗
Ψ t i vs -∗
WP fn () {{ v,
▷ Ψ t ˖i (vs ++ [v])
}}
)
}}}
array٠unsafe_init #sz fn
{{{
t vs
, RET t;
⌜length vs = ₊sz⌝ ∗
array۰model t (DfracOwn 1) vs ∗
Ψ t ₊sz vs
}}}.
Lemma array٠unsafe_initーspec' Ψ sz fn :
(0 ≤ sz)%Z →
{{{
▷ (
∀ t,
|={⊤}=> Ψ t 0 []
) ∗
( [∗ list] i ∈ seq 0 ₊sz,
∀ t vs,
⌜i = length vs⌝ -∗
Ψ t i vs -∗
WP fn () {{ v,
▷ Ψ t ˖i (vs ++ [v])
}}
)
}}}
array٠unsafe_init #sz fn
{{{
t vs
, RET t;
⌜length vs = ₊sz⌝ ∗
array۰model t (DfracOwn 1) vs ∗
Ψ t ₊sz vs
}}}.
Lemma array٠unsafe_initーspecーdisentangled Ψ sz fn :
(0 ≤ sz)%Z →
{{{
□ (
∀ i,
⌜i < ₊sz⌝ -∗
WP fn () {{ v,
▷ Ψ i v
}}
)
}}}
array٠unsafe_init #sz fn
{{{
t vs
, RET t;
⌜length vs = ₊sz⌝ ∗
array۰model t (DfracOwn 1) vs ∗
( [∗ list] i ↦ v ∈ vs,
Ψ i v
)
}}}.
Lemma array٠unsafe_initーspecーdisentangled' Ψ sz fn :
(0 ≤ sz)%Z →
{{{
( [∗ list] i ∈ seq 0 ₊sz,
WP fn () {{ v,
▷ Ψ i v
}}
)
}}}
array٠unsafe_init #sz fn
{{{
t vs
, RET t;
⌜length vs = ₊sz⌝ ∗
array۰model t (DfracOwn 1) vs ∗
( [∗ list] i ↦ v ∈ vs,
Ψ i v
)
}}}.
Lemma array٠initーspec Ψ sz fn :
{{{
▷ (
∀ t,
|={⊤}=> Ψ t 0 []
) ∗
□ (
∀ t i vs,
⌜i < ₊sz⌝ -∗
⌜i = length vs⌝ -∗
Ψ t i vs -∗
WP fn () {{ v,
▷ Ψ t ˖i (vs ++ [v])
}}
)
}}}
array٠init #sz fn
{{{
t vs
, RET t;
⌜0 ≤ sz⌝%Z ∗
⌜length vs = ₊sz⌝ ∗
array۰model t (DfracOwn 1) vs ∗
Ψ t ₊sz vs
}}}.
Lemma array٠initーspec' Ψ sz fn :
{{{
▷ (
∀ t,
|={⊤}=> Ψ t 0 []
) ∗
( [∗ list] i ∈ seq 0 ₊sz,
∀ t vs,
⌜i = length vs⌝ -∗
Ψ t i vs -∗
WP fn () {{ v,
▷ Ψ t ˖i (vs ++ [v])
}}
)
}}}
array٠init #sz fn
{{{
t vs
, RET t;
⌜0 ≤ sz⌝%Z ∗
⌜length vs = ₊sz⌝ ∗
array۰model t (DfracOwn 1) vs ∗
Ψ t ₊sz vs
}}}.
Lemma array٠initーspecーdisentangled Ψ sz fn :
{{{
□ (
∀ i,
⌜i < ₊sz⌝ -∗
WP fn () {{ v,
▷ Ψ i v
}}
)
}}}
array٠init #sz fn
{{{
t vs
, RET t;
⌜0 ≤ sz⌝%Z ∗
⌜length vs = ₊sz⌝ ∗
array۰model t (DfracOwn 1) vs ∗
( [∗ list] i ↦ v ∈ vs,
Ψ i v
)
}}}.
Lemma array٠initーspecーdisentangled' Ψ sz fn :
{{{
( [∗ list] i ∈ seq 0 ₊sz,
WP fn () {{ v,
▷ Ψ i v
}}
)
}}}
array٠init #sz fn
{{{
t vs
, RET t;
⌜0 ≤ sz⌝%Z ∗
⌜length vs = ₊sz⌝ ∗
array۰model t (DfracOwn 1) vs ∗
( [∗ list] i ↦ v ∈ vs,
Ψ i v
)
}}}.
Lemma array٠mapiーspecーatomic Ψ fn t sz :
{{{
array۰inv t sz ∗
▷ Ψ 0 [] None [] ∗
□ (
∀ i vs (o : option val) ws,
⌜i < sz⌝ -∗
⌜i = length vs⌝ -∗
⌜length vs = length ws⌝ -∗
Ψ i vs o ws -∗
match o with
| None ⇒
au_load t i (λ v,
▷ Ψ i vs (Some v) ws
)
| Some v ⇒
WP fn #i v {{ w,
▷ Ψ ˖i (vs ++ [v]) None (ws ++ [w])
}}
end
)
}}}
array٠mapi fn t
{{{
t' vs ws
, RET t';
⌜length vs = sz⌝ ∗
⌜length vs = length ws⌝ ∗
array۰model t' (DfracOwn 1) ws ∗
Ψ sz vs None ws
}}}.
Lemma array٠mapiーspec Ψ fn t dq vs :
{{{
▷ Ψ 0 [] [] ∗
array۰model t dq vs ∗
□ (
∀ i v ws,
⌜vs !! i = Some v⌝ -∗
⌜i = length ws⌝ -∗
Ψ i (take i vs) ws -∗
WP fn #i v {{ w,
▷ Ψ ˖i (take i vs ++ [v]) (ws ++ [w])
}}
)
}}}
array٠mapi fn t
{{{
t' ws
, RET t';
⌜length ws = length vs⌝ ∗
array۰model t dq vs ∗
array۰model t' (DfracOwn 1) ws ∗
Ψ (length vs) vs ws
}}}.
Lemma array٠mapiーspec' Ψ fn t dq vs :
{{{
▷ Ψ 0 [] [] ∗
array۰model t dq vs ∗
( [∗ list] i ↦ v ∈ vs,
∀ ws,
⌜i = length ws⌝ -∗
Ψ i (take i vs) ws -∗
WP fn #i v {{ w,
▷ Ψ ˖i (take i vs ++ [v]) (ws ++ [w])
}}
)
}}}
array٠mapi fn t
{{{
t' ws
, RET t';
⌜length ws = length vs⌝ ∗
array۰model t dq vs ∗
array۰model t' (DfracOwn 1) ws ∗
Ψ (length vs) vs ws
}}}.
Lemma array٠mapiーspecーdisentangled Ψ fn t dq vs :
{{{
array۰model t dq vs ∗
□ (
∀ i v,
⌜vs !! i = Some v⌝ -∗
WP fn #i v {{ w,
▷ Ψ i v w
}}
)
}}}
array٠mapi fn t
{{{
t' ws
, RET t';
⌜length ws = length vs⌝ ∗
array۰model t dq vs ∗
array۰model t' (DfracOwn 1) ws ∗
( [∗ list] i ↦ v; w ∈ vs; ws,
Ψ i v w
)
}}}.
Lemma array٠mapiーspecーdisentangled' Ψ fn t dq vs :
{{{
array۰model t dq vs ∗
( [∗ list] i ↦ v ∈ vs,
WP fn #i v {{ w,
▷ Ψ i v w
}}
)
}}}
array٠mapi fn t
{{{
t' ws
, RET t';
⌜length ws = length vs⌝ ∗
array۰model t dq vs ∗
array۰model t' (DfracOwn 1) ws ∗
( [∗ list] i ↦ v; w ∈ vs; ws,
Ψ i v w
)
}}}.
Lemma array٠mapーspecーatomic Ψ fn t sz :
{{{
array۰inv t sz ∗
▷ Ψ 0 [] None [] ∗
□ (
∀ i vs (o : option val) ws,
⌜i < ₊sz⌝ -∗
⌜i = length vs⌝ -∗
⌜length vs = length ws⌝ -∗
Ψ i vs o ws -∗
match o with
| None ⇒
au_load t i (λ v,
▷ Ψ i vs (Some v) ws
)
| Some v ⇒
WP fn v {{ w,
▷ Ψ ˖i (vs ++ [v]) None (ws ++ [w])
}}
end
)
}}}
array٠map fn t
{{{
t' vs ws
, RET t';
⌜length vs = sz⌝ ∗
⌜length vs = length ws⌝ ∗
array۰model t' (DfracOwn 1) ws ∗
Ψ sz vs None ws
}}}.
Lemma array٠mapーspec Ψ fn t dq vs :
{{{
▷ Ψ 0 [] [] ∗
array۰model t dq vs ∗
□ (
∀ i v ws,
⌜vs !! i = Some v⌝ -∗
⌜i = length ws⌝ -∗
Ψ i (take i vs) ws -∗
WP fn v {{ w,
▷ Ψ ˖i (take i vs ++ [v]) (ws ++ [w])
}}
)
}}}
array٠map fn t
{{{
t' ws
, RET t';
⌜length ws = length vs⌝ ∗
array۰model t dq vs ∗
array۰model t' (DfracOwn 1) ws ∗
Ψ (length vs) vs ws
}}}.
Lemma array٠mapーspec' Ψ fn t dq vs :
{{{
▷ Ψ 0 [] [] ∗
array۰model t dq vs ∗
( [∗ list] i ↦ v ∈ vs,
∀ ws,
⌜i = length ws⌝ -∗
Ψ i (take i vs) ws -∗
WP fn v {{ w,
▷ Ψ ˖i (take i vs ++ [v]) (ws ++ [w])
}}
)
}}}
array٠map fn t
{{{
t' ws
, RET t';
⌜length ws = length vs⌝ ∗
array۰model t dq vs ∗
array۰model t' (DfracOwn 1) ws ∗
Ψ (length vs) vs ws
}}}.
Lemma array٠mapーspecーdisentangled Ψ fn t dq vs :
{{{
array۰model t dq vs ∗
□ (
∀ i v,
⌜vs !! i = Some v⌝ -∗
WP fn v {{ w,
▷ Ψ i v w
}}
)
}}}
array٠map fn t
{{{
t' ws
, RET t';
⌜length ws = length vs⌝ ∗
array۰model t dq vs ∗
array۰model t' (DfracOwn 1) ws ∗
( [∗ list] i ↦ v; w ∈ vs; ws,
Ψ i v w
)
}}}.
Lemma array٠mapーspecーdisentangled' Ψ fn t dq vs :
{{{
array۰model t dq vs ∗
( [∗ list] i ↦ v ∈ vs,
WP fn v {{ w,
▷ Ψ i v w
}}
)
}}}
array٠map fn t
{{{
t' ws
, RET t';
⌜length ws = length vs⌝ ∗
array۰model t dq vs ∗
array۰model t' (DfracOwn 1) ws ∗
( [∗ list] i ↦ v; w ∈ vs; ws,
Ψ i v w
)
}}}.
Lemma array٠unsafe_copy_sliceーspecーatomic Ψ t1 (i1 : Z) t2 (i2 n : Z) :
(0 ≤ i1)%Z →
(0 ≤ i2)%Z →
(0 ≤ n)%Z →
{{{
▷ Ψ 0 [] None ∗
□ (
∀ k vs o,
⌜k < ₊n⌝ -∗
⌜k = length vs⌝ -∗
Ψ k vs o -∗
match o with
| None ⇒
au_load t1 (₊i1 + k) (λ v,
▷ Ψ k vs (Some v)
)
| Some v ⇒
au_store t2 (₊i2 + k) v (
▷ Ψ ˖k (vs ++ [v]) None
)
end
)
}}}
array٠unsafe_copy_slice t1 #i1 t2 #i2 #n
{{{
vs
, RET ();
⌜length vs = ₊n⌝ ∗
Ψ ₊n vs None
}}}.
Lemma array٠unsafe_copy_sliceーspecーsliceーfit t1 (i1 : Z) i1_ dq1 vs1 t2 (i2 : Z) i2_ vs2 (n : Z) :
i1 = ⁺i1_ →
i2 = ⁺i2_ →
n = length vs1 →
length vs1 = length vs2 →
{{{
array۰slice t1 i1_ dq1 vs1 ∗
array۰slice t2 i2_ (DfracOwn 1) vs2
}}}
array٠unsafe_copy_slice t1 #i1 t2 #i2 #n
{{{
RET ();
array۰slice t1 i1_ dq1 vs1 ∗
array۰slice t2 i2_ (DfracOwn 1) vs1
}}}.
Lemma array٠unsafe_copy_sliceーspecーsliceーfitーsrc t1 (i1 : Z) i1_ dq1 vs1 t2 i2 (j2 : Z) vs2 (n : Z) :
i1 = ⁺i1_ →
(i2 ≤ j2)%Z →
n = length vs1 →
(j2 + n ≤ i2 + length vs2)%Z →
{{{
array۰slice t1 i1_ dq1 vs1 ∗
array۰slice t2 i2 (DfracOwn 1) vs2
}}}
array٠unsafe_copy_slice t1 #i1 t2 #j2 #n
{{{
RET ();
array۰slice t1 i1_ dq1 vs1 ∗
array۰slice t2 i2 (DfracOwn 1) (with_slice (₊j2 - i2) ₊n vs2 vs1)
}}}.
Lemma array٠unsafe_copy_sliceーspecーsliceーfitーdst t1 i1 (j1 : Z) dq1 vs1 t2 (i2 : Z) i2_ vs2 (n : Z) :
(i1 ≤ j1)%Z →
i2 = ⁺i2_ →
n = length vs2 →
(j1 + n ≤ i1 + length vs1)%Z →
{{{
array۰slice t1 i1 dq1 vs1 ∗
array۰slice t2 i2_ (DfracOwn 1) vs2
}}}
array٠unsafe_copy_slice t1 #j1 t2 #i2 #n
{{{
RET ();
array۰slice t1 i1 dq1 vs1 ∗
array۰slice t2 i2_ (DfracOwn 1) (slice (₊j1 - i1) ₊n vs1)
}}}.
Lemma array٠unsafe_copy_sliceーspecーslice t1 i1 (j1 : Z) dq1 vs1 t2 i2 (j2 : Z) vs2 (n : Z) :
(i1 ≤ j1)%Z →
(i2 ≤ j2)%Z →
(0 ≤ n)%Z →
(j1 + n ≤ i1 + length vs1)%Z →
(j2 + n ≤ i2 + length vs2)%Z →
{{{
array۰slice t1 i1 dq1 vs1 ∗
array۰slice t2 i2 (DfracOwn 1) vs2
}}}
array٠unsafe_copy_slice t1 #j1 t2 #j2 #n
{{{
RET ();
array۰slice t1 i1 dq1 vs1 ∗
array۰slice t2 i2 (DfracOwn 1) (with_slice (₊j2 - i2) ₊n vs2 (take ₊n (drop (₊j1 - i1) vs1)))
}}}.
Lemma array٠unsafe_copy_sliceーspec t1 (i1 : Z) dq1 vs1 t2 (i2 : Z) vs2 (n : Z) :
(0 ≤ i1)%Z →
(0 ≤ i2)%Z →
(0 ≤ n)%Z →
(i1 + n ≤ length vs1)%Z →
(i2 + n ≤ length vs2)%Z →
{{{
array۰model t1 dq1 vs1 ∗
array۰model t2 (DfracOwn 1) vs2
}}}
array٠unsafe_copy_slice t1 #i1 t2 #i2 #n
{{{
RET ();
array۰model t1 dq1 vs1 ∗
array۰model t2 (DfracOwn 1) (with_slice ₊i2 ₊n vs2 (take ₊n (drop ₊i1 vs1)))
}}}.
Lemma array٠copy_sliceーspecーsliceーfit t1 sz1 (i1 : Z) i1_ dq1 vs1 t2 sz2 (i2 : Z) i2_ vs2 (n : Z) :
i1_ = ₊i1 →
i2_ = ₊i2 →
{{{
array۰inv t1 sz1 ∗
array۰inv t2 sz2 ∗
( ⌜0 ≤ i1⌝%Z -∗
⌜0 ≤ i2⌝%Z -∗
⌜0 ≤ n⌝%Z -∗
⌜i1 + n ≤ sz1⌝%Z -∗
⌜i2 + n ≤ sz2⌝%Z -∗
⌜₊n = length vs1⌝ ∗
⌜length vs1 = length vs2⌝ ∗
array۰slice t1 i1_ dq1 vs1 ∗
array۰slice t2 i2_ (DfracOwn 1) vs2
)
}}}
array٠copy_slice t1 #i1 t2 #i2 #n
{{{
RET ();
⌜0 ≤ i1⌝%Z ∗
⌜0 ≤ i2⌝%Z ∗
⌜0 ≤ n⌝%Z ∗
⌜i1 + n ≤ sz1⌝%Z ∗
⌜i2 + n ≤ sz2⌝%Z ∗
array۰slice t1 i1_ dq1 vs1 ∗
array۰slice t2 i2_ (DfracOwn 1) vs1
}}}.
Lemma array٠copy_sliceーspecーslice t1 sz1 i1 (j1 : Z) dq1 vs1 t2 sz2 i2 (j2 : Z) vs2 (n : Z) :
{{{
array۰inv t1 sz1 ∗
array۰inv t2 sz2 ∗
( ⌜0 ≤ j1⌝%Z -∗
⌜0 ≤ j2⌝%Z -∗
⌜0 ≤ n⌝%Z -∗
⌜j1 + n ≤ sz1⌝%Z -∗
⌜j2 + n ≤ sz2⌝%Z -∗
⌜i1 ≤ ₊j1⌝ ∗
⌜i2 ≤ ₊j2⌝ ∗
⌜₊j1 + n ≤ i1 + length vs1⌝%Z ∗
⌜₊j2 + n ≤ i2 + length vs2⌝%Z ∗
array۰slice t1 i1 dq1 vs1 ∗
array۰slice t2 i2 (DfracOwn 1) vs2
)
}}}
array٠copy_slice t1 #j1 t2 #j2 #n
{{{
RET ();
⌜0 ≤ j1⌝%Z ∗
⌜0 ≤ j2⌝%Z ∗
⌜0 ≤ n⌝%Z ∗
⌜j1 + n ≤ sz1⌝%Z ∗
⌜j2 + n ≤ sz2⌝%Z ∗
array۰slice t1 i1 dq1 vs1 ∗
array۰slice t2 i2 (DfracOwn 1) (with_slice (₊j2 - i2) ₊n vs2 (take ₊n (drop (₊j1 - i1) vs1)))
}}}.
Lemma array٠copy_sliceーspec t1 (i1 : Z) dq1 vs1 t2 (i2 : Z) vs2 (n : Z) :
{{{
array۰model t1 dq1 vs1 ∗
array۰model t2 (DfracOwn 1) vs2
}}}
array٠copy_slice t1 #i1 t2 #i2 #n
{{{
RET ();
⌜0 ≤ i1⌝%Z ∗
⌜0 ≤ i2⌝%Z ∗
⌜0 ≤ n⌝%Z ∗
⌜i1 + n ≤ length vs1⌝%Z ∗
⌜i2 + n ≤ length vs2⌝%Z ∗
array۰model t1 dq1 vs1 ∗
array۰model t2 (DfracOwn 1) (with_slice ₊i2 ₊n vs2 (take ₊n (drop ₊i1 vs1)))
}}}.
Lemma array٠unsafe_copyーspecーatomic Ψ t1 sz1 t2 sz2 (i2 : Z) :
(0 ≤ i2)%Z →
{{{
array۰inv t1 sz1 ∗
array۰inv t2 sz2 ∗
▷ Ψ 0 [] None ∗
□ (
∀ k vs o,
⌜k < sz1⌝ -∗
⌜k = length vs⌝ -∗
Ψ k vs o -∗
match o with
| None ⇒
au_load t1 k (λ v,
▷ Ψ k vs (Some v)
)
| Some v ⇒
au_store t2 (₊i2 + k) v (
▷ Ψ ˖k (vs ++ [v]) None
)
end
)
}}}
array٠unsafe_copy t1 t2 #i2
{{{
vs
, RET ();
⌜length vs = sz1⌝ ∗
Ψ sz1 vs None
}}}.
Lemma array٠unsafe_copyーspecーsliceーfit t1 dq1 vs1 t2 (i2 : Z) i2_ vs2 :
i2 = ⁺i2_ →
length vs1 = length vs2 →
{{{
array۰model t1 dq1 vs1 ∗
array۰slice t2 i2_ (DfracOwn 1) vs2
}}}
array٠unsafe_copy t1 t2 #i2
{{{
RET ();
array۰model t1 dq1 vs1 ∗
array۰slice t2 i2_ (DfracOwn 1) vs1
}}}.
Lemma array٠unsafe_copyーspecーslice t1 dq1 vs1 t2 i2 (j2 : Z) vs2 :
(i2 ≤ j2)%Z →
(j2 + length vs1 ≤ i2 + length vs2)%Z →
{{{
array۰model t1 dq1 vs1 ∗
array۰slice t2 i2 (DfracOwn 1) vs2
}}}
array٠unsafe_copy t1 t2 #j2
{{{
RET ();
array۰model t1 dq1 vs1 ∗
array۰slice t2 i2 (DfracOwn 1) (with_slice (₊j2 - i2) (length vs1) vs2 vs1)
}}}.
Lemma array٠unsafe_copyーspec t1 dq1 vs1 t2 (i2 : Z) vs2 :
(0 ≤ i2)%Z →
(i2 + length vs1 ≤ length vs2)%Z →
{{{
array۰model t1 dq1 vs1 ∗
array۰model t2 (DfracOwn 1) vs2
}}}
array٠unsafe_copy t1 t2 #i2
{{{
RET ();
array۰model t1 dq1 vs1 ∗
array۰model t2 (DfracOwn 1) (with_slice ₊i2 (length vs1) vs2 vs1)
}}}.
Lemma array٠copyーspecーsliceーfit t1 dq1 vs1 t2 sz2 (i2 : Z) i2_ vs2 :
i2_ = ₊i2 →
{{{
array۰model t1 dq1 vs1 ∗
array۰inv t2 sz2 ∗
( ⌜0 ≤ i2⌝%Z -∗
⌜i2 + length vs1 ≤ sz2⌝%Z -∗
⌜length vs1 = length vs2⌝ ∗
array۰slice t2 i2_ (DfracOwn 1) vs2
)
}}}
array٠copy t1 t2 #i2
{{{
RET ();
⌜0 ≤ i2⌝%Z ∗
⌜i2 + length vs1 ≤ sz2⌝%Z ∗
array۰model t1 dq1 vs1 ∗
array۰slice t2 i2_ (DfracOwn 1) vs1
}}}.
Lemma array٠copyーspecーslice t1 dq1 vs1 t2 sz2 i2 (j2 : Z) vs2 :
{{{
array۰model t1 dq1 vs1 ∗
array۰inv t2 sz2 ∗
( ⌜0 ≤ j2⌝%Z -∗
⌜j2 + length vs1 ≤ sz2⌝%Z -∗
⌜i2 ≤ j2⌝%Z ∗
⌜j2 + length vs1 ≤ i2 + length vs2⌝%Z ∗
array۰slice t2 i2 (DfracOwn 1) vs2
)
}}}
array٠copy t1 t2 #j2
{{{
RET ();
⌜0 ≤ i2⌝ ∗
⌜i2 + length vs1 ≤ sz2⌝ ∗
array۰model t1 dq1 vs1 ∗
array۰slice t2 i2 (DfracOwn 1) (with_slice (₊j2 - i2) (length vs1) vs2 vs1)
}}}.
Lemma array٠copyーspec t1 dq1 vs1 t2 (i2 : Z) vs2 :
{{{
array۰model t1 dq1 vs1 ∗
array۰model t2 (DfracOwn 1) vs2
}}}
array٠copy t1 t2 #i2
{{{
RET ();
⌜0 ≤ i2⌝%Z ∗
⌜i2 + length vs1 ≤ length vs2⌝%Z ∗
array۰model t1 dq1 vs1 ∗
array۰model t2 (DfracOwn 1) (with_slice ₊i2 (length vs1) vs2 vs1)
}}}.
Lemma array٠unsafe_growーspec t dq vs sz' v' :
(length vs ≤ sz')%Z →
{{{
array۰model t dq vs
}}}
array٠unsafe_grow t #sz' v'
{{{
t'
, RET t';
array۰model t dq vs ∗
array۰model t' (DfracOwn 1) (vs ++ replicate (₊sz' - length vs) v')
}}}.
Lemma array٠growーspec t dq vs sz' v' :
{{{
array۰model t dq vs
}}}
array٠grow t #sz' v'
{{{
t'
, RET t';
⌜length vs ≤ sz'⌝%Z ∗
array۰model t dq vs ∗
array۰model t' (DfracOwn 1) (vs ++ replicate (₊sz' - length vs) v')
}}}.
Lemma array٠unsafe_subーspecーsliceーfit t dq vs (i : Z) i_ (n : Z) :
i = ⁺i_ →
n = length vs →
{{{
array۰slice t i_ dq vs
}}}
array٠unsafe_sub t #i #n
{{{
t'
, RET t';
array۰slice t i_ dq vs ∗
array۰model t' (DfracOwn 1) (take ₊n vs)
}}}.
Lemma array٠unsafe_subーspecーslice t dq vs i (j n : Z) :
(i ≤ j)%Z →
(0 ≤ n)%Z →
(j + n ≤ i + length vs)%Z →
{{{
array۰slice t i dq vs
}}}
array٠unsafe_sub t #j #n
{{{
t'
, RET t';
array۰slice t i dq vs ∗
array۰model t' (DfracOwn 1) (take ₊n (drop (₊j - ₊i) vs))
}}}.
Lemma array٠unsafe_subーspec t dq vs (i n : Z) :
(0 ≤ i)%Z →
(0 ≤ n)%Z →
(i + n ≤ length vs)%Z →
{{{
array۰model t dq vs
}}}
array٠unsafe_sub t #i #n
{{{
t'
, RET t';
array۰model t dq vs ∗
array۰model t' (DfracOwn 1) (take ₊n (drop ₊i vs))
}}}.
Lemma array٠subーspecーsliceーfit t sz dq vs (i : Z) i_ (n : Z) :
i_ = ₊i →
{{{
array۰inv t sz ∗
( ⌜0 ≤ i⌝%Z -∗
⌜0 ≤ n⌝%Z -∗
⌜i + n ≤ sz⌝%Z -∗
⌜₊n = length vs⌝ ∗
array۰slice t i_ dq vs
)
}}}
array٠sub t #i #n
{{{
t'
, RET t';
⌜0 ≤ i⌝%Z ∗
⌜0 ≤ n⌝%Z ∗
⌜i + n ≤ sz⌝%Z ∗
array۰slice t i_ dq vs ∗
array۰model t' (DfracOwn 1) (take ₊n vs)
}}}.
Lemma array٠subーspecーslice t sz dq vs i (j n : Z) :
{{{
array۰inv t sz ∗
( ⌜0 ≤ j⌝%Z -∗
⌜0 ≤ n⌝%Z -∗
⌜j + n ≤ sz⌝%Z -∗
⌜i ≤ ₊j⌝ ∗
⌜₊j + ₊n ≤ i + length vs⌝ ∗
array۰slice t i dq vs
)
}}}
array٠sub t #j #n
{{{
t'
, RET t';
⌜0 ≤ j⌝%Z ∗
⌜0 ≤ n⌝%Z ∗
⌜j + n ≤ sz⌝%Z ∗
array۰slice t i dq vs ∗
array۰model t' (DfracOwn 1) (take ₊n (drop (₊j - ₊i) vs))
}}}.
Lemma array٠subーspec t dq vs (i n : Z) :
{{{
array۰model t dq vs
}}}
array٠sub t #i #n
{{{
t'
, RET t';
⌜0 ≤ i⌝%Z ∗
⌜0 ≤ n⌝%Z ∗
⌜i + n ≤ length vs⌝%Z ∗
array۰model t dq vs ∗
array۰model t' (DfracOwn 1) (take ₊n (drop ₊i vs))
}}}.
Lemma array٠unsafe_shrinkーspec t dq vs (n : Z) :
(0 ≤ n ≤ length vs)%Z →
{{{
array۰model t dq vs
}}}
array٠unsafe_shrink t #n
{{{
t'
, RET t';
array۰model t dq vs ∗
array۰model t' (DfracOwn 1) (take ₊n vs)
}}}.
Lemma array٠shrinkーspec t dq vs (n : Z) :
{{{
array۰model t dq vs
}}}
array٠shrink t #n
{{{
t'
, RET t';
⌜0 ≤ n ≤ length vs⌝%Z ∗
array۰model t dq vs ∗
array۰model t' (DfracOwn 1) (take ₊n vs)
}}}.
Lemma array٠cloneーspec t dq vs :
{{{
array۰model t dq vs
}}}
array٠clone t
{{{
t'
, RET t';
array۰model t dq vs ∗
array۰model t' (DfracOwn 1) vs
}}}.
Lemma array٠unsafe_cgetーspecーatomic t (j : Z) :
<<<
True
| ∀∀ sz i dq vs v,
⌜(i ≤ j)%Z⌝ ∗
⌜vs !! (₊j - i) = Some v⌝ ∗
array۰cslice t sz i dq vs
>>>
array٠unsafe_cget t #j
<<<
array۰cslice t sz i dq vs
| RET v;
£ 1
>>>.
Lemma array٠unsafe_cgetーspecーatomicーweak t (i : Z) :
(0 ≤ i)%Z →
<<<
True
| ∀∀ sz j dq vs,
array۰cslice t sz j dq vs ∗
⌜0 < sz⌝ ∗
⌜length vs = sz⌝
>>>
array٠unsafe_cget t #i
<<<
array۰cslice t sz j dq vs
| v,
RET v;
£ 1
>>>.
Lemma array٠unsafe_cgetーspecーatomicーcell t sz (i : Z) :
<<<
True
| ∀∀ i_ dq v,
⌜i = ⁺i_⌝ ∗
array۰cslice t sz i_ dq [v]
>>>
array٠unsafe_cget t #i
<<<
array۰cslice t sz i_ dq [v]
| RET v;
£ 1
>>>.
Lemma array٠unsafe_cgetーspec k v t sz i dq vs (j : Z) :
(i ≤ j)%Z →
vs !! k = Some v →
k = ₊j - i →
{{{
array۰cslice t sz i dq vs
}}}
array٠unsafe_cget t #j
{{{
RET v;
array۰cslice t sz i dq vs
}}}.
Lemma array٠unsafe_cgetーspecーcell t sz (i : Z) i_ dq v :
i = ⁺i_ →
{{{
array۰cslice t sz i_ dq [v]
}}}
array٠unsafe_cget t #i
{{{
RET v;
array۰cslice t sz i_ dq [v]
}}}.
Lemma array٠unsafe_cgetーspecーmodel v t dq vs (j : Z) :
(0 ≤ j)%Z →
vs !! (₊j `mod` length vs) = Some v →
{{{
array۰model t dq vs
}}}
array٠unsafe_cget t #j
{{{
RET v;
array۰model t dq vs
}}}.
Lemma array٠cgetーspecーatomic t sz (j : Z) :
<<<
array۰inv t sz
| ∀∀ dq vs i v,
⌜0 ≤ j⌝%Z -∗
⌜0 < sz⌝%Z -∗
⌜i ≤ ₊j⌝ ∗
⌜vs !! (₊j - i) = Some v⌝ ∗
array۰cslice t sz i dq vs
>>>
array٠cget t #j
<<<
array۰cslice t sz i dq vs
| RET v;
⌜0 ≤ j⌝%Z ∗
⌜0 < sz⌝%Z ∗
£ 1
>>>.
Lemma array٠cgetーspecーatomicーweak t sz (i : Z) :
<<<
array۰inv t sz
| ∀∀ j dq vs,
array۰cslice t sz j dq vs ∗
⌜length vs = sz⌝
>>>
array٠cget t #i
<<<
array۰cslice t sz j dq vs
| v,
RET v;
£ 1
>>>.
Lemma array٠cgetーspecーatomicーcell t sz (i : Z) i_ :
i_ = ₊i →
<<<
array۰inv t sz
| ∀∀ dq v,
⌜0 ≤ i⌝%Z -∗
⌜0 < sz⌝%Z -∗
array۰cslice t sz i_ dq [v]
>>>
array٠cget t #i
<<<
array۰cslice t sz i_ dq [v]
| RET v;
⌜0 ≤ i⌝%Z ∗
⌜0 < sz⌝%Z ∗
£ 1
>>>.
Lemma array٠cgetーspec k v t sz i dq vs (j : Z) :
{{{
array۰inv t sz ∗
( ⌜0 < sz⌝ -∗
⌜0 ≤ j⌝%Z -∗
⌜i ≤ ₊j⌝ ∗
⌜vs !! k = Some v⌝ ∗
⌜k = ₊j - i⌝ ∗
array۰cslice t sz i dq vs
)
}}}
array٠cget t #j
{{{
RET v;
⌜0 < sz⌝ ∗
⌜0 ≤ j⌝%Z ∗
array۰cslice t sz i dq vs
}}}.
Lemma array٠cgetーspecーcell t sz (i : Z) i_ dq v :
i_ = ₊i →
{{{
array۰inv t sz ∗
( ⌜0 < sz⌝ -∗
⌜0 ≤ i⌝%Z -∗
array۰cslice t sz i_ dq [v]
)
}}}
array٠cget t #i
{{{
RET v;
⌜0 < sz⌝ ∗
⌜0 ≤ i⌝%Z ∗
array۰cslice t sz i_ dq [v]
}}}.
Lemma array٠cgetーspecーmodel v t dq vs (j : Z) :
vs !! (₊j `mod` length vs) = Some v →
{{{
array۰model t dq vs
}}}
array٠cget t #j
{{{
RET v;
array۰model t dq vs
}}}.
Lemma array٠unsafe_csetーspecーatomic t (j : Z) v :
<<<
True
| ∀∀ sz i vs,
⌜i ≤ j < i + length vs⌝%Z ∗
array۰cslice t sz i (DfracOwn 1) vs
>>>
array٠unsafe_cset t #j v
<<<
array۰cslice t sz i (DfracOwn 1) (<[₊j - i := v]> vs)
| RET ();
£ 1
>>>.
Lemma array٠unsafe_csetーspecーatomicーcell t sz (i : Z) v :
<<<
True
| ∀∀ i_ w,
⌜i = ⁺i_⌝ ∗
array۰cslice t sz i_ (DfracOwn 1) [w]
>>>
array٠unsafe_cset t #i v
<<<
array۰cslice t sz i_ (DfracOwn 1) [v]
| RET ();
£ 1
>>>.
Lemma array٠unsafe_csetーspec t sz i vs (j : Z) v :
(i ≤ j < i + length vs)%Z →
{{{
array۰cslice t sz i (DfracOwn 1) vs
}}}
array٠unsafe_cset t #j v
{{{
RET ();
array۰cslice t sz i (DfracOwn 1) (<[₊j - i := v]> vs)
}}}.
Lemma array٠unsafe_csetーspecーcell t sz (i : Z) i_ w v :
i = ⁺i_ →
{{{
array۰cslice t sz i_ (DfracOwn 1) [w]
}}}
array٠unsafe_cset t #i v
{{{
RET ();
array۰cslice t sz i_ (DfracOwn 1) [v]
}}}.
Lemma array٠unsafe_csetーspecーmodel t vs (j : Z) v :
0 < length vs →
(0 ≤ j)%Z →
{{{
array۰model t (DfracOwn 1) vs
}}}
array٠unsafe_cset t #j v
{{{
RET ();
array۰model t (DfracOwn 1) (<[₊j `mod` length vs := v]> vs)
}}}.
Lemma array٠csetーspecーatomic t sz (j : Z) v :
<<<
array۰inv t sz
| ∀∀ vs i,
⌜0 < sz⌝ -∗
⌜0 ≤ j⌝%Z -∗
⌜i ≤ ₊j < i + length vs⌝ ∗
array۰cslice t sz i (DfracOwn 1) vs
>>>
array٠cset t #j v
<<<
array۰cslice t sz i (DfracOwn 1) (<[₊j - i := v]> vs)
| RET ();
⌜0 < sz⌝ ∗
⌜0 ≤ j⌝%Z ∗
£ 1
>>>.
Lemma array٠csetーspecーatomicーcell t sz (i : Z) i_ v :
i_ = ₊i →
<<<
array۰inv t sz
| ∀∀ w,
⌜0 < sz⌝ -∗
⌜0 ≤ i⌝%Z -∗
array۰cslice t sz i_ (DfracOwn 1) [w]
>>>
array٠cset t #i v
<<<
array۰cslice t sz i_ (DfracOwn 1) [v]
| RET ();
⌜0 < sz⌝ ∗
⌜0 ≤ i⌝%Z ∗
£ 1
>>>.
Lemma array٠csetーspec t sz i vs (j : Z) v :
{{{
array۰inv t sz ∗
( ⌜0 < sz⌝ -∗
⌜0 ≤ j⌝%Z -∗
⌜i ≤ ₊j < i + length vs⌝ ∗
array۰cslice t sz i (DfracOwn 1) vs
)
}}}
array٠cset t #j v
{{{
RET ();
⌜0 < sz⌝ ∗
⌜0 ≤ j⌝%Z ∗
array۰cslice t sz i (DfracOwn 1) (<[₊j - i := v]> vs)
}}}.
Lemma array٠csetーspecーcell t sz (i : Z) i_ w v :
i_ = ₊i →
{{{
array۰inv t sz ∗
( ⌜0 < sz⌝ -∗
⌜0 ≤ i⌝%Z -∗
array۰cslice t sz i_ (DfracOwn 1) [w]
)
}}}
array٠cset t #i v
{{{
RET ();
⌜0 < sz⌝ ∗
⌜0 ≤ i⌝%Z ∗
array۰cslice t sz i_ (DfracOwn 1) [v]
}}}.
Lemma array٠csetーspecーmodel t vs (j : Z) v :
{{{
array۰model t (DfracOwn 1) vs
}}}
array٠cset t #j v
{{{
RET ();
array۰model t (DfracOwn 1) (<[₊j `mod` length vs := v]> vs)
}}}.
#[local] Lemma array٠unsafe_ccopy_slice₁ーspec t1 (i1 : Z) i1_ dq1 vs1 t2 sz2 (i2 : Z) i2_ vs2 (n : Z) :
0 < sz2 →
i1 = ⁺i1_ →
i2 = ⁺i2_ →
n = length vs1 →
length vs1 = length vs2 →
{{{
array۰slice t1 i1_ dq1 vs1 ∗
array۰cslice t2 sz2 i2_ (DfracOwn 1) vs2
}}}
array٠unsafe_ccopy_slice₁ t1 #i1 t2 #i2 #n
{{{
RET ();
array۰slice t1 i1_ dq1 vs1 ∗
array۰cslice t2 sz2 i2_ (DfracOwn 1) vs1
}}}.
Lemma array٠unsafe_ccopy_sliceーspecーfit t1 sz1 (i1 : Z) i1_ dq1 vs1 t2 sz2 (i2 : Z) i2_ vs2 (n : Z) :
0 < sz1 →
length vs1 ≤ sz1 →
0 < sz2 →
i1 = ⁺i1_ →
i2 = ⁺i2_ →
n = length vs1 →
length vs1 = length vs2 →
{{{
array۰cslice t1 sz1 i1_ dq1 vs1 ∗
array۰cslice t2 sz2 i2_ (DfracOwn 1) vs2
}}}
array٠unsafe_ccopy_slice t1 #i1 t2 #i2 #n
{{{
RET ();
array۰cslice t1 sz1 i1_ dq1 vs1 ∗
array۰cslice t2 sz2 i2_ (DfracOwn 1) vs1
}}}.
Lemma array٠unsafe_ccopy_sliceーspecーfitーsrc t1 sz1 (i1 : Z) i1_ dq1 vs1 t2 sz2 i2 (j2 : Z) vs2 (n : Z) :
0 < sz1 →
length vs1 ≤ sz1 →
0 < sz2 →
i1 = ⁺i1_ →
(i2 ≤ j2)%Z →
n = length vs1 →
(j2 + n ≤ i2 + length vs2)%Z →
{{{
array۰cslice t1 sz1 i1_ dq1 vs1 ∗
array۰cslice t2 sz2 i2 (DfracOwn 1) vs2
}}}
array٠unsafe_ccopy_slice t1 #i1 t2 #j2 #n
{{{
RET ();
array۰cslice t1 sz1 i1_ dq1 vs1 ∗
array۰cslice t2 sz2 i2 (DfracOwn 1) (with_slice (₊j2 - i2) ₊n vs2 vs1)
}}}.
Lemma array٠unsafe_ccopy_sliceーspecーfitーdst t1 sz1 i1 (j1 : Z) dq1 vs1 t2 sz2 (i2 : Z) i2_ vs2 (n : Z) :
0 < sz1 →
length vs1 ≤ sz1 →
0 < sz2 →
(i1 ≤ j1)%Z →
i2 = ⁺i2_ →
n = length vs2 →
(j1 + n ≤ i1 + length vs1)%Z →
{{{
array۰cslice t1 sz1 i1 dq1 vs1 ∗
array۰cslice t2 sz2 i2_ (DfracOwn 1) vs2
}}}
array٠unsafe_ccopy_slice t1 #j1 t2 #i2 #n
{{{
RET ();
array۰cslice t1 sz1 i1 dq1 vs1 ∗
array۰cslice t2 sz2 i2_ (DfracOwn 1) (slice (₊j1 - i1) ₊n vs1)
}}}.
Lemma array٠unsafe_ccopy_sliceーspec t1 sz1 i1 (j1 : Z) dq1 vs1 t2 sz2 i2 (j2 : Z) vs2 (n : Z) :
0 < sz1 →
length vs1 ≤ sz1 →
0 < sz2 →
(i1 ≤ j1)%Z →
(i2 ≤ j2)%Z →
(0 ≤ n)%Z →
(j1 + n ≤ i1 + length vs1)%Z →
(j2 + n ≤ i2 + length vs2)%Z →
{{{
array۰cslice t1 sz1 i1 dq1 vs1 ∗
array۰cslice t2 sz2 i2 (DfracOwn 1) vs2
}}}
array٠unsafe_ccopy_slice t1 #j1 t2 #j2 #n
{{{
RET ();
array۰cslice t1 sz1 i1 dq1 vs1 ∗
array۰cslice t2 sz2 i2 (DfracOwn 1) (with_slice (₊j2 - i2) ₊n vs2 (take ₊n (drop (₊j1 - i1) vs1)))
}}}.
Lemma array٠ccopy_sliceーspecーfit t1 sz1 (i1 : Z) i1_ dq1 vs1 t2 sz2 (i2 : Z) i2_ vs2 (n : Z) :
i1_ = ₊i1 →
i2_ = ₊i2 →
{{{
array۰inv t1 sz1 ∗
array۰inv t2 sz2 ∗
( ⌜0 < sz1⌝ -∗
⌜0 < sz2⌝ -∗
⌜0 ≤ i1⌝%Z -∗
⌜0 ≤ i2⌝%Z -∗
⌜0 ≤ n⌝%Z -∗
⌜n ≤ sz1⌝%Z -∗
⌜n ≤ sz2⌝%Z -∗
⌜₊n = length vs1⌝ ∗
⌜length vs1 = length vs2⌝ ∗
array۰cslice t1 sz1 i1_ dq1 vs1 ∗
array۰cslice t2 sz2 i2_ (DfracOwn 1) vs2
)
}}}
array٠ccopy_slice t1 #i1 t2 #i2 #n
{{{
RET ();
⌜0 < sz1⌝ ∗
⌜0 < sz2⌝ ∗
⌜0 ≤ i1⌝%Z ∗
⌜0 ≤ i2⌝%Z ∗
⌜0 ≤ n⌝%Z ∗
⌜n ≤ sz1⌝%Z ∗
⌜n ≤ sz2⌝%Z ∗
array۰cslice t1 sz1 i1_ dq1 vs1 ∗
array۰cslice t2 sz2 i2_ (DfracOwn 1) vs1
}}}.
Lemma array٠ccopy_sliceーspec t1 sz1 i1 (j1 : Z) dq1 vs1 t2 sz2 i2 (j2 : Z) vs2 (n : Z) :
{{{
array۰inv t1 sz1 ∗
array۰inv t2 sz2 ∗
( ⌜0 < sz1⌝ -∗
⌜0 < sz2⌝ -∗
⌜0 ≤ j1⌝%Z -∗
⌜0 ≤ j2⌝%Z -∗
⌜0 ≤ n⌝%Z -∗
⌜n ≤ sz1⌝%Z -∗
⌜n ≤ sz2⌝%Z -∗
⌜length vs1 ≤ sz1⌝ ∗
⌜i1 ≤ ₊j1⌝ ∗
⌜i2 ≤ ₊j2⌝ ∗
⌜₊j1 + n ≤ i1 + length vs1⌝%Z ∗
⌜₊j2 + n ≤ i2 + length vs2⌝%Z ∗
array۰cslice t1 sz1 i1 dq1 vs1 ∗
array۰cslice t2 sz2 i2 (DfracOwn 1) vs2
)
}}}
array٠ccopy_slice t1 #j1 t2 #j2 #n
{{{
RET ();
⌜0 < sz1⌝ ∗
⌜0 < sz2⌝ ∗
⌜0 ≤ j1⌝%Z ∗
⌜0 ≤ j2⌝%Z ∗
⌜0 ≤ n⌝%Z ∗
⌜n ≤ sz1⌝%Z ∗
⌜n ≤ sz2⌝%Z ∗
array۰cslice t1 sz1 i1 dq1 vs1 ∗
array۰cslice t2 sz2 i2 (DfracOwn 1) (with_slice (₊j2 - i2) ₊n vs2 (take ₊n (drop (₊j1 - i1) vs1)))
}}}.
Lemma array٠unsafe_ccopyーspecーfit t1 sz1 (i1 : Z) i1_ dq1 vs1 t2 sz2 (i2 : Z) i2_ vs2 :
0 < sz1 →
0 < sz2 →
i1 = ⁺i1_ →
i2 = ⁺i2_ →
length vs1 = sz1 →
length vs1 = length vs2 →
{{{
array۰cslice t1 sz1 i1_ dq1 vs1 ∗
array۰cslice t2 sz2 i2_ (DfracOwn 1) vs2
}}}
array٠unsafe_ccopy t1 #i1 t2 #i2
{{{
RET ();
array۰cslice t1 sz1 i1_ dq1 vs1 ∗
array۰cslice t2 sz2 i2_ (DfracOwn 1) vs1
}}}.
Lemma array٠unsafe_ccopyーspec t1 sz1 (i1 : Z) i1_ dq1 vs1 t2 sz2 i2 (j2 : Z) vs2 :
0 < sz1 →
0 < sz2 →
i1 = ⁺i1_ →
length vs1 = sz1 →
(i2 ≤ j2)%Z →
(j2 + length vs1 ≤ i2 + length vs2)%Z →
{{{
array۰cslice t1 sz1 i1_ dq1 vs1 ∗
array۰cslice t2 sz2 i2 (DfracOwn 1) vs2
}}}
array٠unsafe_ccopy t1 #i1 t2 #j2
{{{
RET ();
array۰cslice t1 sz1 i1_ dq1 vs1 ∗
array۰cslice t2 sz2 i2 (DfracOwn 1) (with_slice (₊j2 - i2) (length vs1) vs2 vs1)
}}}.
Lemma array٠ccopyーspecーfit t1 sz1 (i1 : Z) i1_ dq1 vs1 t2 sz2 (i2 : Z) i2_ vs2 :
i1_ = ₊i1 →
i2_ = ₊i2 →
length vs1 = sz1 →
length vs1 = length vs2 →
{{{
array۰inv t1 sz1 ∗
array۰inv t2 sz2 ∗
( ⌜0 < sz1⌝ -∗
⌜0 < sz2⌝ -∗
⌜0 ≤ i1⌝%Z -∗
⌜0 ≤ i2⌝%Z -∗
array۰cslice t1 sz1 i1_ dq1 vs1 ∗
array۰cslice t2 sz2 i2_ (DfracOwn 1) vs2
)
}}}
array٠ccopy t1 #i1 t2 #i2
{{{
RET ();
⌜0 < sz1⌝ ∗
⌜0 < sz2⌝ ∗
⌜0 ≤ i1⌝%Z ∗
⌜0 ≤ i2⌝%Z ∗
array۰cslice t1 sz1 i1_ dq1 vs1 ∗
array۰cslice t2 sz2 i2_ (DfracOwn 1) vs1
}}}.
Lemma array٠ccopyーspec t1 sz1 (i1 : Z) dq1 vs1 t2 sz2 i2 (j2 : Z) vs2 :
length vs1 = sz1 →
{{{
array۰inv t1 sz1 ∗
array۰inv t2 sz2 ∗
( ⌜0 < sz1⌝ -∗
⌜0 < sz2⌝ -∗
⌜0 ≤ i1⌝%Z -∗
⌜0 ≤ j2⌝%Z -∗
⌜i2 ≤ ₊j2⌝%Z ∗
⌜₊j2 + length vs1 ≤ i2 + length vs2⌝%Z ∗
array۰cslice t1 sz1 ₊i1 dq1 vs1 ∗
array۰cslice t2 sz2 i2 (DfracOwn 1) vs2
)
}}}
array٠ccopy t1 #i1 t2 #j2
{{{
RET ();
⌜0 < sz1⌝ ∗
⌜0 < sz2⌝ ∗
⌜0 ≤ i1⌝%Z ∗
⌜0 ≤ j2⌝%Z ∗
array۰cslice t1 sz1 ₊i1 dq1 vs1 ∗
array۰cslice t2 sz2 i2 (DfracOwn 1) (with_slice (₊j2 - i2) (length vs1) vs2 vs1)
}}}.
Lemma array٠unsafe_cgrow_sliceーspec t sz (i : Z) i_ dq vs (n : Z) sz' v :
0 < sz →
length vs ≤ sz →
i = ⁺i_ →
n = ⁺(length vs) →
(0 < sz')%Z →
(n ≤ sz')%Z →
{{{
array۰cslice t sz i_ dq vs
}}}
array٠unsafe_cgrow_slice t #i #n #sz' v
{{{
t'
, RET t';
array۰cslice t sz i_ dq vs ∗
array۰cslice t' ₊sz' i_ (DfracOwn 1) (vs ++ replicate (₊sz' - ₊n) v)
}}}.
Lemma array٠unsafe_cgrowーspec t (sz : nat) (i : Z) i_ dq vs sz' v :
0 < sz →
i = ⁺i_ →
length vs = sz →
(0 < sz')%Z →
(sz ≤ sz')%Z →
{{{
array۰cslice t sz i_ dq vs
}}}
array٠unsafe_cgrow t #i #sz' v
{{{
t'
, RET t';
array۰cslice t sz i_ dq vs ∗
array۰cslice t' ₊sz' i_ (DfracOwn 1) (vs ++ replicate (₊sz' - sz) v)
}}}.
Lemma array٠unsafe_cshrink_sliceーspecーfit t sz (i : Z) i_ dq vs sz' :
0 < sz →
length vs ≤ sz →
i = ⁺i_ →
(0 < sz' ≤ length vs)%Z →
{{{
array۰cslice t sz i_ dq vs
}}}
array٠unsafe_cshrink_slice t #i #sz'
{{{
t'
, RET t';
array۰cslice t sz i_ dq vs ∗
array۰cslice t' ₊sz' i_ (DfracOwn 1) (take ₊sz' vs)
}}}.
Lemma array٠unsafe_cshrink_sliceーspec t sz i dq vs (j : Z) sz' :
0 < sz →
length vs ≤ sz →
(i ≤ j)%Z →
(0 < sz')%Z →
(j + sz' ≤ i + length vs)%Z →
{{{
array۰cslice t sz i dq vs
}}}
array٠unsafe_cshrink_slice t #j #sz'
{{{
t'
, RET t';
array۰cslice t sz i dq vs ∗
array۰cslice t' ₊sz' ₊j (DfracOwn 1) (slice (₊j - i) ₊sz' vs)
}}}.
Definition itype۰array τ `{!iType _ τ} (sz : nat) t : iProp Σ :=
∃ l,
⌜t = #l⌝ ∗
l ↦ₕ Header 0 sz ∗
itype۰chunk τ sz l.
#[global] Instance itype۰arrayーitype τ `{!iType _ τ} sz :
iType _ (itype۰array τ sz).
Lemma itype۰arrayーintro τ `{!iType _ τ} t vs :
array۰model t (DfracOwn 1) vs -∗
([∗ list] v ∈ vs, τ v) ={⊤}=∗
itype۰array τ (length vs) t.
Lemma itype۰arrayーintroーslice τ `{!iType _ τ} t sz vs :
length vs = sz →
array۰inv t sz -∗
array۰slice t 0 (DfracOwn 1) vs -∗
([∗ list] v ∈ vs, τ v) ={⊤}=∗
itype۰array τ sz t.
Lemma itype۰arrayーintroーcslice τ `{!iType _ τ} t sz i vs :
0 < sz →
length vs = sz →
array۰cslice t sz i (DfracOwn 1) vs -∗
([∗ list] v ∈ vs, τ v) ={⊤}=∗
itype۰array τ sz t.
Lemma itype۰arrayーtoーinv τ `{!iType _ τ} sz t :
itype۰array τ sz t ⊢
array۰inv t sz.
Lemma array٠createーtype τ `{!iType _ τ} :
{{{
True
}}}
array٠create ()
{{{
t
, RET t;
itype۰array τ 0 t
}}}.
Lemma array٠sizeーtype τ `{!iType _ τ} t sz :
{{{
itype۰array τ sz t
}}}
array٠size t
{{{
RET #sz;
True
}}}.
Lemma array٠unsafe_getーtype τ `{!iType _ τ} t (sz : nat) (i : Z) :
(0 ≤ i < sz)%Z →
{{{
itype۰array τ sz t
}}}
array٠unsafe_get t #i
{{{
v
, RET v;
τ v
}}}.
Lemma array٠getーtype τ `{!iType _ τ} t sz (i : Z) :
{{{
itype۰array τ sz t
}}}
array٠get t #i
{{{
v
, RET v;
⌜0 ≤ i < sz⌝%Z ∗
τ v
}}}.
Lemma array٠unsafe_setーtype τ `{!iType _ τ} t (sz : nat) (i : Z) v :
(0 ≤ i < sz)%Z →
{{{
itype۰array τ sz t ∗
τ v
}}}
array٠unsafe_set t #i v
{{{
RET ();
True
}}}.
Lemma array٠setーtype τ `{!iType _ τ} t sz (i : Z) v :
{{{
itype۰array τ sz t ∗
τ v
}}}
array٠set t #i v
{{{
RET ();
⌜0 ≤ i < sz⌝%Z
}}}.
Lemma array٠unsafe_xchgーtype τ `{!iType _ τ} t (sz : nat) (i : Z) v :
(0 ≤ i < sz)%Z →
{{{
itype۰array τ sz t ∗
τ v
}}}
array٠unsafe_xchg t #i v
{{{
w
, RET w;
τ w
}}}.
Lemma array٠unsafe_casーtype τ `{!iType _ τ} t (sz : nat) (i : Z) v1 v2 :
(0 ≤ i < sz)%Z →
{{{
itype۰array τ sz t ∗
τ v1 ∗
τ v2
}}}
array٠unsafe_cas t #i v1 v2
{{{
b
, RET #b;
True
}}}.
Lemma array٠unsafe_fill_sliceーtype τ `{!iType _ τ} t (sz : nat) (i n : Z) v :
(0 ≤ i)%Z →
(0 ≤ n)%Z →
(i + n ≤ sz)%Z →
{{{
itype۰array τ sz t ∗
τ v
}}}
array٠unsafe_fill_slice t #i #n v
{{{
RET ();
True
}}}.
Lemma array٠fill_sliceーtype τ `{!iType _ τ} t sz (i n : Z) v :
{{{
itype۰array τ sz t ∗
τ v
}}}
array٠fill_slice t #i #n v
{{{
RET ();
⌜0 ≤ i⌝%Z ∗
⌜0 ≤ n⌝%Z ∗
⌜i + n ≤ sz⌝%Z
}}}.
Lemma array٠fillーtype τ `{!iType _ τ} t sz v :
{{{
itype۰array τ sz t ∗
τ v
}}}
array٠fill t v
{{{
RET ();
True
}}}.
Lemma array٠unsafe_makeーtype τ `{!iType _ τ} sz v :
(0 ≤ sz)%Z →
{{{
τ v
}}}
array٠unsafe_make #sz v
{{{
t
, RET t;
itype۰array τ ₊sz t
}}}.
Lemma array٠makeーtype τ `{!iType _ τ} sz v :
{{{
τ v
}}}
array٠make #sz v
{{{
t
, RET t;
⌜0 ≤ sz⌝%Z ∗
itype۰array τ ₊sz t
}}}.
Lemma array٠foldliーtype τ `{!iType _ τ} υ `{!iType _ υ} fn acc t sz :
{{{
itype۰array τ sz t ∗
υ acc ∗
(itype۰nat_upto sz --> υ --> τ --> υ)%T fn
}}}
array٠foldli fn acc t
{{{
acc'
, RET acc';
υ acc'
}}}.
Lemma array٠foldlーtype τ `{!iType _ τ} υ `{!iType _ υ} fn acc t sz :
{{{
itype۰array τ sz t ∗
υ acc ∗
(υ --> τ --> υ)%T fn
}}}
array٠foldl fn acc t
{{{
acc'
, RET acc';
υ acc'
}}}.
Lemma array٠foldriーtype τ `{!iType _ τ} υ `{!iType _ υ} fn acc t sz :
{{{
itype۰array τ sz t ∗
(itype۰nat_upto sz --> τ --> υ --> υ)%T fn ∗
υ acc
}}}
array٠foldri fn t acc
{{{
acc'
, RET acc';
υ acc'
}}}.
Lemma array٠foldrーtype τ `{!iType _ τ} υ `{!iType _ υ} fn t sz acc :
{{{
itype۰array τ sz t ∗
(τ --> υ --> υ)%T fn ∗
υ acc
}}}
array٠foldr fn t acc
{{{
acc'
, RET acc';
υ acc'
}}}.
Lemma array٠unsafe_iteri_sliceーtype τ `{!iType _ τ} fn t (sz : nat) (i n : Z) :
(0 ≤ i ≤ sz)%Z →
(0 ≤ n)%Z →
(i + n ≤ sz)%Z →
{{{
itype۰array τ sz t ∗
(itype۰nat_upto ₊n --> τ --> itype۰unit)%T fn
}}}
array٠unsafe_iteri_slice fn t #i #n
{{{
RET ();
True
}}}.
Lemma array٠iteri_sliceーtype τ `{!iType _ τ} fn t (sz : nat) (i n : Z) :
{{{
itype۰array τ sz t ∗
(itype۰nat_upto ₊n --> τ --> itype۰unit)%T fn
}}}
array٠iteri_slice fn t #i #n
{{{
RET ();
⌜0 ≤ i ≤ sz⌝%Z ∗
⌜0 ≤ n⌝%Z ∗
⌜i + n ≤ sz⌝%Z
}}}.
Lemma array٠unsafe_iter_sliceーtype τ `{!iType _ τ} fn t (sz : nat) (i n : Z) :
(0 ≤ i ≤ sz)%Z →
(0 ≤ n)%Z →
(i + n ≤ sz)%Z →
{{{
itype۰array τ sz t ∗
(τ --> itype۰unit)%T fn
}}}
array٠unsafe_iter_slice fn t #i #n
{{{
RET ();
True
}}}.
Lemma array٠iter_sliceーtype τ `{!iType _ τ} fn t (sz : nat) (i n : Z) :
{{{
itype۰array τ sz t ∗
(τ --> itype۰unit)%T fn
}}}
array٠iter_slice fn t #i #n
{{{
RET ();
⌜0 ≤ i ≤ sz⌝%Z ∗
⌜0 ≤ n⌝%Z ∗
⌜i + n ≤ sz⌝%Z
}}}.
Lemma array٠iteriーtype τ `{!iType _ τ} fn t sz :
{{{
itype۰array τ sz t ∗
(itype۰nat_upto sz --> τ --> itype۰unit)%T fn
}}}
array٠iteri fn t
{{{
RET ();
True
}}}.
Lemma array٠iterーtype τ `{!iType _ τ} fn t sz :
{{{
itype۰array τ sz t ∗
(τ --> itype۰unit)%T fn
}}}
array٠iter fn t
{{{
RET ();
True
}}}.
Lemma array٠unsafe_applyi_sliceーtype τ `{!iType _ τ} fn t (sz : nat) (i n : Z) :
(0 ≤ i ≤ sz)%Z →
(0 ≤ n)%Z →
(i + n ≤ sz)%Z →
{{{
itype۰array τ sz t ∗
(itype۰nat_upto ₊n --> τ --> τ)%T fn
}}}
array٠unsafe_applyi_slice fn t #i #n
{{{
RET ();
True
}}}.
Lemma array٠applyi_sliceーtype τ `{!iType _ τ} fn t (sz : nat) (i n : Z) :
{{{
itype۰array τ sz t ∗
(itype۰nat_upto ₊n --> τ --> τ)%T fn
}}}
array٠applyi_slice fn t #i #n
{{{
RET ();
⌜0 ≤ i ≤ sz⌝%Z ∗
⌜0 ≤ n⌝%Z ∗
⌜i + n ≤ sz⌝%Z
}}}.
Lemma array٠unsafe_apply_sliceーtype τ `{!iType _ τ} fn t (sz : nat) (i n : Z) :
(0 ≤ i ≤ sz)%Z →
(0 ≤ n)%Z →
(i + n ≤ sz)%Z →
{{{
itype۰array τ sz t ∗
(τ --> τ)%T fn
}}}
array٠unsafe_apply_slice fn t #i #n
{{{
RET ();
True
}}}.
Lemma array٠apply_sliceーtype τ `{!iType _ τ} fn t (sz : nat) (i n : Z) :
{{{
itype۰array τ sz t ∗
(τ --> τ)%T fn
}}}
array٠apply_slice fn t #i #n
{{{
RET ();
⌜0 ≤ i ≤ sz⌝%Z ∗
⌜0 ≤ n⌝%Z ∗
⌜i + n ≤ sz⌝%Z
}}}.
Lemma array٠applyiーtype τ `{!iType _ τ} fn t sz :
{{{
itype۰array τ sz t ∗
(itype۰nat_upto sz --> τ --> τ)%T fn
}}}
array٠applyi fn t
{{{
RET ();
True
}}}.
Lemma array٠applyーtype τ `{!iType _ τ} fn t sz :
{{{
itype۰array τ sz t ∗
(τ --> τ)%T fn
}}}
array٠apply fn t
{{{
RET ();
True
}}}.
Lemma array٠unsafe_initiーtype τ `{!iType _ τ} sz sz_ fn :
sz = ⁺sz_ →
{{{
(itype۰nat_upto sz_ --> τ)%T fn
}}}
array٠unsafe_initi #sz fn
{{{
t
, RET t;
itype۰array τ sz_ t
}}}.
Lemma array٠initiーtype τ `{!iType _ τ} sz fn :
{{{
(itype۰nat_upto ₊sz --> τ)%T fn
}}}
array٠initi #sz fn
{{{
t
, RET t;
⌜0 ≤ sz⌝%Z ∗
itype۰array τ ₊sz t
}}}.
Lemma array٠unsafe_initーtype τ `{!iType _ τ} sz fn :
(0 ≤ sz)%Z →
{{{
(itype۰unit --> τ)%T fn
}}}
array٠unsafe_init #sz fn
{{{
t
, RET t;
itype۰array τ ₊sz t
}}}.
Lemma array٠initーtype τ `{!iType _ τ} sz fn :
{{{
(itype۰unit --> τ)%T fn
}}}
array٠init #sz fn
{{{
t
, RET t;
⌜0 ≤ sz⌝%Z ∗
itype۰array τ ₊sz t
}}}.
Lemma array٠mapiーtype τ `{!iType _ τ} υ `{!iType _ υ} fn t sz sz_ :
sz_ = ⁺sz →
{{{
itype۰array τ sz t ∗
(itype۰nat_upto sz --> τ --> υ)%T fn
}}}
array٠mapi fn t
{{{
t'
, RET t';
itype۰array υ sz t'
}}}.
Lemma array٠mapーtype τ `{!iType _ τ} υ `{!iType _ υ} fn t sz sz_ :
sz_ = ⁺sz →
{{{
itype۰array τ sz t ∗
(τ --> υ)%T fn
}}}
array٠map fn t
{{{
t'
, RET t';
itype۰array υ sz t'
}}}.
Lemma array٠unsafe_copy_sliceーtype τ `{!iType _ τ} t1 (sz1 : nat) (i1 : Z) t2 (sz2 : nat) (i2 n : Z) :
(0 ≤ i1)%Z →
(0 ≤ i2)%Z →
(0 ≤ n)%Z →
(i1 + n ≤ sz1)%Z →
(i2 + n ≤ sz2)%Z →
{{{
itype۰array τ sz1 t1 ∗
itype۰array τ sz2 t2
}}}
array٠unsafe_copy_slice t1 #i1 t2 #i2 #n
{{{
RET ();
True
}}}.
Lemma array٠unsafe_copy_slice۰type' τ `{!iType _ τ} t1 (sz : nat) (i1 : Z) t2 (i2 : Z) i2_ vs (n : Z) :
(0 ≤ i1)%Z →
i2 = ⁺i2_ →
n = length vs →
(i1 + n ≤ sz)%Z →
{{{
itype۰array τ sz t1 ∗
array۰slice t2 i2_ (DfracOwn 1) vs
}}}
array٠unsafe_copy_slice t1 #i1 t2 #i2 #n
{{{
ws
, RET ();
⌜length ws = length vs⌝ ∗
array۰slice t2 i2_ (DfracOwn 1) ws ∗
[∗ list] w ∈ ws, τ w
}}}.
Lemma array٠copy_sliceーtype τ `{!iType _ τ} t1 sz1 (i1 : Z) t2 sz2 (i2 n : Z) :
{{{
itype۰array τ sz1 t1 ∗
itype۰array τ sz2 t2
}}}
array٠copy_slice t1 #i1 t2 #i2 #n
{{{
RET ();
⌜0 ≤ i1⌝%Z ∗
⌜0 ≤ i2⌝%Z ∗
⌜0 ≤ n⌝%Z ∗
⌜i1 + n ≤ sz1⌝%Z ∗
⌜i2 + n ≤ sz2⌝%Z
}}}.
Lemma array٠unsafe_copyーtype τ `{!iType _ τ} t1 (sz1 : nat) t2 (sz2 : nat) (i2 : Z) :
(0 ≤ i2)%Z →
(i2 + sz1 ≤ sz2)%Z →
{{{
itype۰array τ sz1 t1 ∗
itype۰array τ sz2 t2
}}}
array٠unsafe_copy t1 t2 #i2
{{{
RET ();
⌜i2 + sz1 ≤ sz2⌝%Z
}}}.
Lemma array٠unsafe_copy۰type' τ `{!iType _ τ} t1 sz t2 (i2 : Z) i2_ vs :
i2 = ⁺i2_ →
sz = length vs →
{{{
itype۰array τ sz t1 ∗
array۰slice t2 i2_ (DfracOwn 1) vs
}}}
array٠unsafe_copy t1 t2 #i2
{{{
ws
, RET ();
⌜length ws = length vs⌝ ∗
array۰slice t2 i2_ (DfracOwn 1) ws ∗
[∗ list] w ∈ ws, τ w
}}}.
Lemma array٠copyーtype τ `{!iType _ τ} t1 sz1 t2 sz2 (i2 : Z) :
{{{
itype۰array τ sz1 t1 ∗
itype۰array τ sz2 t2
}}}
array٠copy t1 t2 #i2
{{{
RET ();
⌜0 ≤ i2⌝%Z ∗
⌜i2 + sz1 ≤ sz2⌝%Z
}}}.
Lemma array٠unsafe_growーtype τ `{!iType _ τ} t (sz : nat) sz' v' :
(sz ≤ sz')%Z →
{{{
itype۰array τ sz t ∗
τ v'
}}}
array٠unsafe_grow t #sz' v'
{{{
t'
, RET t';
itype۰array τ ₊sz' t'
}}}.
Lemma array٠growーtype τ `{!iType _ τ} t sz sz' v' :
{{{
itype۰array τ sz t ∗
τ v'
}}}
array٠grow t #sz' v'
{{{
t'
, RET t';
⌜sz ≤ sz'⌝ ∗
itype۰array τ ₊sz' t'
}}}.
Lemma array٠unsafe_subーtype τ `{!iType _ τ} t (sz : nat) (i n : Z) :
(0 ≤ i)%Z →
(0 ≤ n)%Z →
(i + n ≤ sz)%Z →
{{{
itype۰array τ sz t
}}}
array٠unsafe_sub t #i #n
{{{
t'
, RET t';
itype۰array τ ₊n t'
}}}.
Lemma array٠subーtype τ `{!iType _ τ} t sz (i n : Z) :
{{{
itype۰array τ sz t
}}}
array٠sub t #i #n
{{{
t'
, RET t';
⌜0 ≤ i⌝%Z ∗
⌜0 ≤ n⌝%Z ∗
⌜i + n ≤ sz⌝%Z ∗
itype۰array τ ₊n t'
}}}.
Lemma array٠unsafe_shrinkーtype τ `{!iType _ τ} t (sz : nat) (n : Z) :
(0 ≤ n ≤ sz)%Z →
{{{
itype۰array τ sz t
}}}
array٠unsafe_shrink t #n
{{{
t'
, RET t';
itype۰array τ ₊n t'
}}}.
Lemma array٠shrinkーtype τ `{!iType _ τ} t sz (n : Z) :
{{{
itype۰array τ sz t
}}}
array٠shrink t #n
{{{
t'
, RET t';
⌜0 ≤ n ≤ sz⌝%Z ∗
itype۰array τ ₊n t'
}}}.
Lemma array٠cloneーtype τ `{!iType _ τ} t sz :
{{{
itype۰array τ sz t
}}}
array٠clone t
{{{
t'
, RET t';
itype۰array τ sz t'
}}}.
Lemma array٠unsafe_cgetーtype τ `{!iType _ τ} t sz (i : Z) :
0 < sz →
(0 ≤ i)%Z →
{{{
itype۰array τ sz t
}}}
array٠unsafe_cget t #i
{{{
v
, RET v;
τ v
}}}.
Lemma array٠cgetーtype τ `{!iType _ τ} t sz (i : Z) :
{{{
itype۰array τ sz t
}}}
array٠cget t #i
{{{
v
, RET v;
⌜0 < sz⌝ ∗
⌜0 ≤ i⌝%Z ∗
τ v
}}}.
Lemma array٠unsafe_csetーtype τ `{!iType _ τ} t sz (i : Z) v :
0 < sz →
(0 ≤ i)%Z →
{{{
itype۰array τ sz t ∗
τ v
}}}
array٠unsafe_cset t #i v
{{{
RET ();
True
}}}.
Lemma array٠csetーtype τ `{!iType _ τ} t sz (i : Z) v :
{{{
itype۰array τ sz t ∗
τ v
}}}
array٠cset t #i v
{{{
RET ();
⌜0 < sz⌝ ∗
⌜0 ≤ i⌝%Z
}}}.
#[local] Lemma array٠unsafe_ccopy_slice₁ーtype τ `{!iType _ τ} t1 sz1 (i1 : Z) t2 sz2 (i2 n : Z) :
0 < sz1 →
0 < sz2 →
(0 ≤ i1)%Z →
(0 ≤ i2)%Z →
(0 ≤ n)%Z →
(i1 + n ≤ sz1)%Z →
(n ≤ sz2)%Z →
{{{
itype۰array τ sz1 t1 ∗
itype۰array τ sz2 t2
}}}
array٠unsafe_ccopy_slice₁ t1 #i1 t2 #i2 #n
{{{
RET ();
True
}}}.
Lemma array٠unsafe_ccopy_sliceーtype τ `{!iType _ τ} t1 sz1 (i1 : Z) t2 sz2 (i2 n : Z) :
0 < sz1 →
0 < sz2 →
(0 ≤ i1)%Z →
(0 ≤ i2)%Z →
(0 ≤ n)%Z →
(n ≤ sz1)%Z →
(n ≤ sz2)%Z →
{{{
itype۰array τ sz1 t1 ∗
itype۰array τ sz2 t2
}}}
array٠unsafe_ccopy_slice t1 #i1 t2 #i2 #n
{{{
RET ();
True
}}}.
#[local] Lemma array٠unsafe_ccopy_slice₁۰type' τ `{!iType _ τ} t1 sz1 (i1 : Z) t2 sz2 (i2 : Z) i2_ vs (n : Z) :
0 < sz1 →
0 < sz2 →
length vs ≤ sz2 →
(0 ≤ i1)%Z →
(i1 + length vs ≤ sz1)%Z →
i2 = ⁺i2_ →
n = length vs →
{{{
itype۰array τ sz1 t1 ∗
array۰cslice t2 sz2 i2_ (DfracOwn 1) vs
}}}
array٠unsafe_ccopy_slice₁ t1 #i1 t2 #i2 #n
{{{
ws
, RET ();
⌜length ws = length vs⌝ ∗
array۰cslice t2 sz2 i2_ (DfracOwn 1) ws ∗
[∗ list] w ∈ ws, τ w
}}}.
Lemma array٠unsafe_ccopy_slice۰type' τ `{!iType _ τ} t1 sz1 (i1 : Z) t2 sz2 (i2 : Z) i2_ vs (n : Z) :
0 < sz1 →
length vs ≤ sz1 →
0 < sz2 →
length vs ≤ sz2 →
(0 ≤ i1)%Z →
i2 = ⁺i2_ →
n = length vs →
{{{
itype۰array τ sz1 t1 ∗
array۰cslice t2 sz2 i2_ (DfracOwn 1) vs
}}}
array٠unsafe_ccopy_slice t1 #i1 t2 #i2 #n
{{{
ws
, RET ();
⌜length ws = length vs⌝ ∗
array۰cslice t2 sz2 i2_ (DfracOwn 1) ws ∗
[∗ list] w ∈ ws, τ w
}}}.
Lemma array٠ccopy_sliceーtype τ `{!iType _ τ} t1 sz1 (i1 : Z) t2 sz2 (i2 : Z) (n : Z) :
0 < sz1 →
0 < sz2 →
{{{
itype۰array τ sz1 t1 ∗
itype۰array τ sz2 t2
}}}
array٠ccopy_slice t1 #i1 t2 #i2 #n
{{{
RET ();
⌜0 < sz1⌝ ∗
⌜0 < sz2⌝ ∗
⌜0 ≤ i1⌝%Z ∗
⌜0 ≤ i2⌝%Z
}}}.
Lemma array٠unsafe_ccopyーtype τ `{!iType _ τ} t1 sz1 (i1 : Z) t2 sz2 (i2 : Z) :
0 < sz1 →
0 < sz2 →
sz1 ≤ sz2 →
(0 ≤ i1)%Z →
(0 ≤ i2)%Z →
{{{
itype۰array τ sz1 t1 ∗
itype۰array τ sz2 t2
}}}
array٠unsafe_ccopy t1 #i1 t2 #i2
{{{
RET ();
True
}}}.
Lemma array٠ccopyーtype τ `{!iType _ τ} t1 sz1 (i1 : Z) t2 sz2 (i2 : Z) :
{{{
itype۰array τ sz1 t1 ∗
itype۰array τ sz2 t2
}}}
array٠ccopy t1 #i1 t2 #i2
{{{
RET ();
⌜0 < sz1⌝ ∗
⌜0 < sz2⌝ ∗
⌜0 ≤ i1⌝%Z ∗
⌜0 ≤ i2⌝%Z
}}}.
Lemma array٠unsafe_cgrow_sliceーtype τ `{!iType _ τ} sz t (i n : Z) sz' v :
0 < sz →
(0 ≤ i)%Z →
(0 ≤ n)%Z →
(0 < sz')%Z →
(n ≤ sz)%Z →
(n ≤ sz')%Z →
{{{
itype۰array τ sz t ∗
τ v
}}}
array٠unsafe_cgrow_slice t #i #n #sz' v
{{{
t'
, RET t';
itype۰array τ ₊sz' t'
}}}.
Lemma array٠unsafe_cgrowーtype τ `{!iType _ τ} sz t (i n : Z) sz' v :
0 < sz →
(0 ≤ i)%Z →
(0 < sz')%Z →
(sz ≤ sz')%Z →
{{{
itype۰array τ sz t ∗
τ v
}}}
array٠unsafe_cgrow t #i #sz' v
{{{
t'
, RET t';
itype۰array τ ₊sz' t'
}}}.
Lemma array٠unsafe_cshrink_sliceーtype τ `{!iType _ τ} sz t (i : Z) sz' :
0 < sz →
(0 ≤ i)%Z →
(0 < sz')%Z →
(sz' ≤ sz)%Z →
{{{
itype۰array τ sz t
}}}
array٠unsafe_cshrink_slice t #i #sz'
{{{
t'
, RET t';
itype۰array τ ₊sz' t'
}}}.
End zoo۰G.
Require zoo_std.array__opaque.
#[global] Opaque array٠unsafe_xchg.
#[global] Opaque array٠unsafe_cas.
#[global] Opaque array٠unsafe_faa.
#[global] Opaque array۰inv.
#[global] Opaque array۰slice.
#[global] Opaque array۰model.
#[global] Opaque array۰cslice.
#[global] Opaque itype۰array.
Require Import zoo.prelude.
Require Import zoo.common.list.
Require Import zoo.common.math.
Require Import zoo.iris.bi.big_op.
Require Import zoo.base.
Require Import zoo_std.chunk.
Require Export zoo_std.array__code.
Require Import zoo_std.array__types.
Require Import zoo.options.
Implicit Type b : bool.
Implicit Type i j k n : nat.
Implicit Type l : location.
Implicit Type v t fn acc : val.
Implicit Type vs vs_left vs_right ws : list val.
Definition array٠unsafe_xchg : val :=
𝗳𝘂𝗻 "t" "i" "v" →
Xchg ("t", "i") "v".
Definition array٠unsafe_cas : val :=
𝗳𝘂𝗻 "t" "i" "v1" "v2" →
CAS ("t", "i") "v1" "v2".
Definition array٠unsafe_faa : val :=
𝗳𝘂𝗻 "t" "i" "incr" →
FAA ("t", "i") "incr".
Section zoo۰G.
Context `{zoo۰G : !ZooG Σ}.
Section array۰inv.
Definition array۰inv t (sz : nat) : iProp Σ :=
∃ l,
⌜t = #l⌝ ∗
l ↦ₕ Header 0 sz.
#[global] Instance array۰invーtimeless t sz :
Timeless (array۰inv t sz).
#[global] Instance array۰invーpersistent t sz :
Persistent (array۰inv t sz).
Lemma array۰invーagree t sz1 sz2 :
array۰inv t sz1 -∗
array۰inv t sz2 -∗
⌜sz1 = sz2⌝.
End array۰inv.
Section array۰slice.
Definition array۰slice t i dq vs : iProp Σ :=
∃ l,
⌜t = #l⌝ ∗
chunk۰model (l +ₗ i) dq vs.
#[global] Instance array۰sliceーtimeless t i dq vs :
Timeless (array۰slice t i dq vs).
#[global] Instance array۰sliceーpersistent t i vs :
Persistent (array۰slice t i DfracDiscarded vs).
#[global] Instance array۰sliceーfractional t i vs :
Fractional (λ q, array۰slice t i (DfracOwn q) vs).
#[global] Instance array۰sliceーas_fractional t i q vs :
AsFractional (array۰slice t i (DfracOwn q) vs) (λ q, array۰slice t i (DfracOwn q) vs) q.
Lemma array۰sliceーvalid t i dq vs :
0 < length vs →
array۰slice t i dq vs ⊢
⌜✓ dq⌝.
Lemma array۰sliceーcombine t i dq1 vs1 dq2 vs2 :
length vs1 = length vs2 →
array۰slice t i dq1 vs1 -∗
array۰slice t i dq2 vs2 -∗
⌜vs1 = vs2⌝ ∗
array۰slice t i (dq1 ⋅ dq2) vs1.
Lemma array۰sliceーvalidー2 t i dq1 vs1 dq2 vs2 :
0 < length vs1 →
length vs1 = length vs2 →
array۰slice t i dq1 vs1 -∗
array۰slice t i dq2 vs2 -∗
⌜✓ (dq1 ⋅ dq2)⌝ ∗
⌜vs1 = vs2⌝.
Lemma array۰sliceーagree t i dq1 vs1 dq2 vs2 :
length vs1 = length vs2 →
array۰slice t i dq1 vs1 -∗
array۰slice t i dq2 vs2 -∗
⌜vs1 = vs2⌝.
Lemma array۰sliceーdfracーne t1 i1 dq1 vs1 t2 i2 dq2 vs2 :
0 < length vs1 →
length vs1 = length vs2 →
¬ ✓ (dq1 ⋅ dq2) →
array۰slice t1 i1 dq1 vs1 -∗
array۰slice t2 i2 dq2 vs2 -∗
⌜t1 ≠ t2 ∨ i1 ≠ i2⌝.
Lemma array۰sliceーne t1 i1 vs1 t2 i2 dq2 vs2 :
0 < length vs1 →
length vs1 = length vs2 →
array۰slice t1 i1 (DfracOwn 1) vs1 -∗
array۰slice t2 i2 dq2 vs2 -∗
⌜t1 ≠ t2 ∨ i1 ≠ i2⌝.
Lemma array۰sliceーexclusive t i vs1 dq2 vs2 :
0 < length vs1 →
length vs1 = length vs2 →
array۰slice t i (DfracOwn 1) vs1 -∗
array۰slice t i dq2 vs2 -∗
False.
Lemma array۰sliceーpersist t i dq vs :
array۰slice t i dq vs ⊢ |==>
array۰slice t i DfracDiscarded vs.
Lemma array۰sliceーnil {t i1 dq1 vs1} i2 dq2 :
array۰slice t i1 dq1 vs1 ⊢
array۰slice t i2 dq2 [].
Lemma array۰sliceーapp t i dq vs1 vs2 :
array۰slice t i dq vs1 ∗
array۰slice t (i + length vs1) dq vs2 ⊣⊢
array۰slice t i dq (vs1 ++ vs2).
Lemma array۰sliceーapp₁ t i dq vs1 vs2 :
array۰slice t i dq vs1 -∗
array۰slice t (i + length vs1) dq vs2 -∗
array۰slice t i dq (vs1 ++ vs2).
Lemma array۰sliceーapp₁' {t dq i1 vs1} i2 vs2 :
i2 = i1 + length vs1 →
array۰slice t i1 dq vs1 -∗
array۰slice t i2 dq vs2 -∗
array۰slice t i1 dq (vs1 ++ vs2).
Lemma array۰sliceーapp₂ {t i dq vs} vs1 vs2 :
vs = vs1 ++ vs2 →
array۰slice t i dq vs ⊢
array۰slice t i dq vs1 ∗
array۰slice t (i + length vs1) dq vs2.
Lemma array۰sliceーappー3 {t i dq} vs1 vs2 vs3 :
array۰slice t i dq vs1 ∗
array۰slice t (i + length vs1) dq vs2 ∗
array۰slice t (i + length vs1 + length vs2) dq vs3 ⊣⊢
array۰slice t i dq (vs1 ++ vs2 ++ vs3).
Lemma array۰sliceーappー3₁ t dq i1 vs1 i2 vs2 i3 vs3 :
i2 = i1 + length vs1 →
i3 = i1 + length vs1 + length vs2 →
array۰slice t i1 dq vs1 -∗
array۰slice t i2 dq vs2 -∗
array۰slice t i3 dq vs3 -∗
array۰slice t i1 dq (vs1 ++ vs2 ++ vs3).
Lemma array۰sliceーappー3₂ {t i dq vs} vs1 vs2 vs3 :
vs = vs1 ++ vs2 ++ vs3 →
array۰slice t i dq vs ⊢
array۰slice t i dq vs1 ∗
array۰slice t (i + length vs1) dq vs2 ∗
array۰slice t (i + length vs1 + length vs2) dq vs3.
Lemma array۰sliceーcons t i dq v vs :
array۰slice t i dq (v :: vs) ⊣⊢
array۰slice t i dq [v] ∗
array۰slice t ˖i dq vs.
Lemma array۰sliceーcons₁ t i dq v vs :
array۰slice t i dq (v :: vs) ⊢
array۰slice t i dq [v] ∗
array۰slice t ˖i dq vs.
Lemma array۰sliceーcons₂ t i dq v vs :
array۰slice t i dq [v] -∗
array۰slice t ˖i dq vs -∗
array۰slice t i dq (v :: vs).
Lemma array۰sliceーcons₂' t i1 dq v i2 vs :
i2 = ˖i1 →
array۰slice t i1 dq [v] -∗
array۰slice t i2 dq vs -∗
array۰slice t i1 dq (v :: vs).
Lemma array۰sliceーatomize t i dq vs :
array۰slice t i dq vs ⊢
[∗ list] j ↦ v ∈ vs,
array۰slice t (i + j) dq [v].
Lemma array۰sliceーupdate {t i dq vs} j v :
vs !! j = Some v →
array۰slice t i dq vs ⊢
array۰slice t (i + j) dq [v] ∗
( ∀ w,
array۰slice t (i + j) dq [w] -∗
array۰slice t i dq (<[j := w]> vs)
).
Lemma array۰sliceーlookupーacc {t i dq vs} j v :
vs !! j = Some v →
array۰slice t i dq vs ⊢
array۰slice t (i + j) dq [v] ∗
( array۰slice t (i + j) dq [v] -∗
array۰slice t i dq vs
).
Lemma array۰sliceーlookup {t i dq vs} j v :
vs !! j = Some v →
array۰slice t i dq vs ⊢
array۰slice t (i + j) dq [v].
End array۰slice.
Section array۰model.
Definition array۰model t dq vs : iProp Σ :=
∃ l,
⌜t = #l⌝ ∗
l ↦ₕ Header 0 (length vs) ∗
chunk۰model l dq vs.
Lemma array۰modelーtoーinv t dq vs :
array۰model t dq vs ⊢
array۰inv t (length vs).
Lemma array۰sliceーtoーmodel t sz dq vs :
sz = length vs →
array۰inv t sz -∗
array۰slice t 0 dq vs -∗
array۰model t dq vs.
Lemma array۰modelーtoーslice t dq vs :
array۰model t dq vs ⊣⊢
array۰inv t (length vs) ∗
array۰slice t 0 dq vs.
Lemma array۰modelーtoーslice' t dq vs :
array۰model t dq vs ⊢
array۰slice t 0 dq vs ∗
□ (
∀ vs',
⌜length vs' = length vs⌝ -∗
array۰slice t 0 dq vs' -∗
array۰model t dq vs'
).
#[global] Instance array۰modelーtimeless t dq vs :
Timeless (array۰model t dq vs).
#[global] Instance array۰modelーpersistent t vs :
Persistent (array۰model t DfracDiscarded vs).
#[global] Instance array۰modelーfractional t vs :
Fractional (λ q, array۰model t (DfracOwn q) vs).
#[global] Instance array۰modelーas_fractional t q vs :
AsFractional (array۰model t (DfracOwn q) vs) (λ q, array۰model t (DfracOwn q) vs) q.
Lemma arrayーinvーmodelーagree t sz dq vs :
array۰inv t sz -∗
array۰model t dq vs -∗
⌜length vs = sz⌝.
Lemma array۰modelーvalid t dq vs :
0 < length vs →
array۰model t dq vs ⊢
⌜✓ dq⌝.
Lemma array۰modelーcombine t dq1 vs1 dq2 vs2 :
array۰model t dq1 vs1 -∗
array۰model t dq2 vs2 -∗
⌜vs1 = vs2⌝ ∗
array۰model t (dq1 ⋅ dq2) vs1.
Lemma array۰modelーvalidー2 t dq1 vs1 dq2 vs2 :
0 < length vs1 →
array۰model t dq1 vs1 -∗
array۰model t dq2 vs2 -∗
⌜✓ (dq1 ⋅ dq2)⌝ ∗
⌜vs1 = vs2⌝.
Lemma array۰modelーagree t dq1 vs1 dq2 vs2 :
array۰model t dq1 vs1 -∗
array۰model t dq2 vs2 -∗
⌜vs1 = vs2⌝.
Lemma array۰modelーdfracーne t1 dq1 vs1 t2 dq2 vs2 :
0 < length vs1 →
¬ ✓ (dq1 ⋅ dq2) →
array۰model t1 dq1 vs1 -∗
array۰model t2 dq2 vs2 -∗
⌜t1 ≠ t2⌝.
Lemma array۰modelーne t1 vs1 t2 dq2 vs2 :
0 < length vs1 →
array۰model t1 (DfracOwn 1) vs1 -∗
array۰model t2 dq2 vs2 -∗
⌜t1 ≠ t2⌝.
Lemma array۰modelーexclusive t vs1 dq2 vs2 :
0 < length vs1 →
array۰model t (DfracOwn 1) vs1 -∗
array۰model t dq2 vs2 -∗
False.
Lemma array۰modelーpersist t dq vs :
array۰model t dq vs ⊢ |==>
array۰model t DfracDiscarded vs.
Lemma array۰modelーatomize t dq vs :
array۰model t dq vs ⊢
array۰inv t (length vs) ∗
[∗ list] i ↦ v ∈ vs,
array۰slice t i dq [v].
#[local] Typeclasses Opaque array۰slice.
Lemma array۰modelーupdate {t dq vs} i v :
vs !! i = Some v →
array۰model t dq vs ⊢
array۰inv t (length vs) ∗
array۰slice t i dq [v] ∗
( ∀ w,
array۰slice t i dq [w] -∗
array۰model t dq (<[i := w]> vs)
).
Lemma array۰modelーlookupーacc {t dq vs} i v :
vs !! i = Some v →
array۰model t dq vs ⊢
array۰slice t i dq [v] ∗
( array۰slice t i dq [v] -∗
array۰model t dq vs
).
Lemma array۰modelーlookup {t dq vs} i v :
vs !! i = Some v →
array۰model t dq vs ⊢
array۰slice t i dq [v].
End array۰model.
Section array۰cslice.
Definition array۰cslice t (sz : nat) i dq vs : iProp Σ :=
∃ l,
⌜t = #l⌝ ∗
l ↦ₕ Header 0 sz ∗
chunk۰cslice l sz i dq vs.
Lemma array۰csliceーtoーinv t sz i dq vs :
array۰cslice t sz i dq vs ⊢
array۰inv t sz.
Lemma array۰modelーtoーcslice t dq vs :
array۰model t dq vs ⊢
array۰cslice t (length vs) 0 dq vs.
Lemma array۰csliceーtoーslice t sz i dq vs :
0 < sz →
length vs ≤ sz →
array۰cslice t sz i dq vs ⊣⊢
array۰inv t sz ∗
array۰slice t (i `mod` sz) dq (take (sz - i `mod` sz) vs) ∗
array۰slice t 0 dq (drop (sz - i `mod` sz) vs).
Lemma array۰csliceーtoーslice' t sz i dq vs :
0 < sz →
length vs ≤ sz →
array۰cslice t sz i dq vs ⊢
array۰slice t (i `mod` sz) dq (take (sz - i `mod` sz) vs) ∗
array۰slice t 0 dq (drop (sz - i `mod` sz) vs).
Lemma array۰csliceーtoーmodel t sz i dq vs :
0 < sz →
length vs = sz →
array۰cslice t sz i dq vs ⊣⊢
array۰model t dq (rotation (sz - i `mod` sz) vs).
Lemma array۰csliceーtoーsliceーcell t sz i dq v :
array۰cslice t sz i dq [v] ⊣⊢
array۰inv t sz ∗
array۰slice t (i `mod` sz) dq [v].
Lemma array۰csliceーtoーsliceーcell' t sz i dq v :
array۰cslice t sz i dq [v] ⊢
array۰slice t (i `mod` sz) dq [v].
Lemma array۰sliceーtoーcsliceーcell t sz i dq v :
array۰inv t sz -∗
array۰slice t (i `mod` sz) dq [v] -∗
array۰cslice t sz i dq [v].
#[global] Instance array۰csliceーtimeless t sz i dq vs :
Timeless (array۰cslice t sz i dq vs).
#[global] Instance array۰csliceーpersistent t sz i vs :
Persistent (array۰cslice t sz i DfracDiscarded vs).
#[global] Instance array۰csliceーfractional t sz i vs :
Fractional (λ q, array۰cslice t sz i (DfracOwn q) vs).
#[global] Instance array۰csliceーas_fractional t sz i q vs :
AsFractional (array۰cslice t sz i (DfracOwn q) vs) (λ q, array۰cslice t sz i (DfracOwn q) vs) q.
Lemma arrayーinvーcsliceーagree t sz1 sz2 i dq vs :
array۰inv t sz1 -∗
array۰cslice t sz2 i dq vs -∗
⌜sz1 = sz2⌝.
Lemma array۰csliceーnil t sz i dq :
array۰inv t sz ⊢
array۰cslice t sz i dq [].
Lemma array۰csliceーapp t sz i dq vs1 vs2 :
array۰cslice t sz i dq vs1 ∗
array۰cslice t sz (i + length vs1) dq vs2 ⊣⊢
array۰cslice t sz i dq (vs1 ++ vs2).
Lemma array۰csliceーapp₁ t sz dq i1 vs1 i2 vs2 :
i2 = i1 + length vs1 →
array۰cslice t sz i1 dq vs1 -∗
array۰cslice t sz i2 dq vs2 -∗
array۰cslice t sz i1 dq (vs1 ++ vs2).
Lemma array۰csliceーapp₂ {t sz i dq vs} vs1 vs2 :
vs = vs1 ++ vs2 →
array۰cslice t sz i dq vs ⊢
array۰cslice t sz i dq vs1 ∗
array۰cslice t sz (i + length vs1) dq vs2.
Lemma array۰csliceーappー3 t sz i dq vs1 vs2 vs3 :
array۰cslice t sz i dq vs1 ∗
array۰cslice t sz (i + length vs1) dq vs2 ∗
array۰cslice t sz (i + length vs1 + length vs2) dq vs3 ⊣⊢
array۰cslice t sz i dq (vs1 ++ vs2 ++ vs3).
Lemma array۰csliceーappー3₁ t sz dq i1 vs1 i2 vs2 i3 vs3 :
i2 = i1 + length vs1 →
i3 = i1 + length vs1 + length vs2 →
array۰cslice t sz i1 dq vs1 -∗
array۰cslice t sz i2 dq vs2 -∗
array۰cslice t sz i3 dq vs3 -∗
array۰cslice t sz i1 dq (vs1 ++ vs2 ++ vs3).
Lemma array۰csliceーappー3₂ {t sz i dq vs} vs1 vs2 vs3 :
vs = vs1 ++ vs2 ++ vs3 →
array۰cslice t sz i dq vs ⊢
array۰cslice t sz i dq vs1 ∗
array۰cslice t sz (i + length vs1) dq vs2 ∗
array۰cslice t sz (i + length vs1 + length vs2) dq vs3.
Lemma array۰csliceーcons t sz i dq v vs :
array۰cslice t sz i dq (v :: vs) ⊣⊢
array۰cslice t sz i dq [v] ∗
array۰cslice t sz ˖i dq vs.
Lemma array۰csliceーcons₁ t sz i dq v vs :
array۰cslice t sz i dq (v :: vs) ⊢
array۰cslice t sz i dq [v] ∗
array۰cslice t sz ˖i dq vs.
Lemma array۰csliceーcons₂ t sz i dq v vs :
array۰cslice t sz i dq [v] -∗
array۰cslice t sz ˖i dq vs -∗
array۰cslice t sz i dq (v :: vs).
Lemma array۰csliceーcons₂' t sz i1 dq v i2 vs :
i2 = ˖i1 →
array۰cslice t sz i1 dq [v] -∗
array۰cslice t sz i2 dq vs -∗
array۰cslice t sz i1 dq (v :: vs).
Lemma array۰csliceーatomize sz t i dq vs :
array۰cslice t sz i dq vs ⊢
[∗ list] j ↦ v ∈ vs,
array۰cslice t sz (i + j) dq [v].
Lemma array۰csliceーupdate {t sz i dq vs} j v :
vs !! j = Some v →
array۰cslice t sz i dq vs ⊢
array۰cslice t sz (i + j) dq [v] ∗
( ∀ w,
array۰cslice t sz (i + j) dq [w] -∗
array۰cslice t sz i dq (<[j := w]> vs)
).
Lemma array۰csliceーlookupーacc {t sz i dq vs} j v :
vs !! j = Some v →
array۰cslice t sz i dq vs ⊢
array۰cslice t sz (i + j) dq [v] ∗
( array۰cslice t sz (i + j) dq [v] -∗
array۰cslice t sz i dq vs
).
Lemma array۰csliceーlookup {t sz i dq vs} j v :
vs !! j = Some v →
array۰cslice t sz i dq vs ⊢
array۰cslice t sz (i + j) dq [v].
Lemma array۰csliceーshift t sz i dq vs :
array۰cslice t sz i dq vs ⊣⊢
array۰cslice t sz (i + sz) dq vs.
Lemma array۰csliceーshiftーright t sz i dq vs :
array۰cslice t sz i dq vs ⊢
array۰cslice t sz (i + sz) dq vs.
Lemma array۰csliceーshiftーright' {t sz i1 dq vs} i2 :
i2 = i1 + sz →
array۰cslice t sz i1 dq vs ⊢
array۰cslice t sz i2 dq vs.
Lemma array۰csliceーshiftーleft t sz i dq vs :
sz ≤ i →
array۰cslice t sz i dq vs ⊢
array۰cslice t sz (i - sz) dq vs.
Lemma array۰csliceーshiftーleft' {t sz i1 dq vs} i2 :
sz ≤ i1 →
i2 = i1 - sz →
array۰cslice t sz i1 dq vs ⊢
array۰cslice t sz i2 dq vs.
Lemma array۰csliceーrotationーright {t sz i dq vs} n :
0 < sz →
length vs = sz →
array۰cslice t sz i dq vs ⊣⊢
array۰cslice t sz (i + n) dq (rotation (n `mod` sz) vs).
Lemma array۰csliceーrotationーright₁ {t sz i dq vs} n :
0 < sz →
length vs = sz →
array۰cslice t sz i dq vs ⊢
array۰cslice t sz (i + n) dq (rotation (n `mod` sz) vs).
Lemma array۰csliceーrotationーrightー0 {t sz dq vs} i :
0 < sz →
length vs = sz →
array۰cslice t sz 0 dq vs ⊣⊢
array۰cslice t sz i dq (rotation (i `mod` sz) vs).
Lemma array۰csliceーrotationーright' {t sz i1 dq vs} i2 n :
0 < sz →
length vs = sz →
i2 = i1 + n →
array۰cslice t sz i1 dq vs ⊣⊢
array۰cslice t sz i2 dq (rotation (n `mod` sz) vs).
Lemma array۰csliceーrotationーright₁' {t sz i1 dq vs} i2 n :
0 < sz →
length vs = sz →
i2 = i1 + n →
array۰cslice t sz i1 dq vs ⊢
array۰cslice t sz i2 dq (rotation (n `mod` sz) vs).
Lemma array۰csliceーrotationーrightーsmall {t sz i dq vs} n :
0 < sz →
length vs = sz →
n < sz →
array۰cslice t sz i dq vs ⊣⊢
array۰cslice t sz (i + n) dq (rotation n vs).
Lemma array۰csliceーrotationーrightーsmall₁ {t sz i dq vs} n :
0 < sz →
length vs = sz →
n < sz →
array۰cslice t sz i dq vs ⊢
array۰cslice t sz (i + n) dq (rotation n vs).
Lemma array۰csliceーrotationーrightーsmall' {t sz i1 dq vs} i2 n :
0 < sz →
length vs = sz →
i2 = i1 + n →
n < sz →
array۰cslice t sz i1 dq vs ⊣⊢
array۰cslice t sz i2 dq (rotation n vs).
Lemma array۰csliceーrotationーrightーsmall₁' {t sz i1 dq vs} i2 n :
0 < sz →
length vs = sz →
i2 = i1 + n →
n < sz →
array۰cslice t sz i1 dq vs ⊢
array۰cslice t sz i2 dq (rotation n vs).
Lemma array۰csliceーrotationーleft t sz i n dq vs :
0 < sz →
length vs = sz →
array۰cslice t sz (i + n) dq vs ⊣⊢
array۰cslice t sz i dq (rotation (sz - n `mod` sz) vs).
Lemma array۰csliceーrotationーleft₁ t sz i n dq vs :
0 < sz →
length vs = sz →
array۰cslice t sz (i + n) dq vs ⊢
array۰cslice t sz i dq (rotation (sz - n `mod` sz) vs).
Lemma array۰csliceーrotationーleftー0 t sz i dq vs :
0 < sz →
length vs = sz →
array۰cslice t sz i dq vs ⊣⊢
array۰cslice t sz 0 dq (rotation (sz - i `mod` sz) vs).
Lemma array۰csliceーrotationーleft' {t sz i1 dq vs} i2 n :
0 < sz →
length vs = sz →
i1 = i2 + n →
array۰cslice t sz i1 dq vs ⊣⊢
array۰cslice t sz i2 dq (rotation (sz - n `mod` sz) vs).
Lemma array۰csliceーrotationーleft₁' {t sz i1 dq vs} i2 n :
0 < sz →
length vs = sz →
i1 = i2 + n →
array۰cslice t sz i1 dq vs ⊢
array۰cslice t sz i2 dq (rotation (sz - n `mod` sz) vs).
Lemma array۰csliceーrotationーleftーsmall t sz i n dq vs :
0 < sz →
length vs = sz →
n < sz →
array۰cslice t sz (i + n) dq vs ⊣⊢
array۰cslice t sz i dq (rotation (sz - n) vs).
Lemma array۰csliceーrotationーleftーsmall₁ t sz i n dq vs :
0 < sz →
length vs = sz →
n < sz →
array۰cslice t sz (i + n) dq vs ⊢
array۰cslice t sz i dq (rotation (sz - n) vs).
Lemma array۰csliceーrotationーleftーsmall' {t sz i1 dq vs} i2 n :
0 < sz →
length vs = sz →
i1 = i2 + n →
n < sz →
array۰cslice t sz i1 dq vs ⊣⊢
array۰cslice t sz i2 dq (rotation (sz - n) vs).
Lemma array۰csliceーrotationーleftーsmall₁' {t sz i1 dq vs} i2 n :
0 < sz →
length vs = sz →
i1 = i2 + n →
n < sz →
array۰cslice t sz i1 dq vs ⊢
array۰cslice t sz i2 dq (rotation (sz - n) vs).
Lemma array۰csliceーrebase {t sz i1 dq vs1} i2 :
0 < sz →
length vs1 = sz →
array۰cslice t sz i1 dq vs1 ⊢
∃ vs2 n,
⌜vs2 = rotation n vs1⌝ ∗
array۰cslice t sz i2 dq vs2 ∗
( array۰cslice t sz i2 dq vs2 -∗
array۰cslice t sz i1 dq vs1
).
Lemma array۰csliceーvalid t sz i dq vs :
0 < length vs →
array۰cslice t sz i dq vs ⊢
⌜✓ dq⌝.
Lemma array۰csliceーcombine t sz i dq1 vs1 dq2 vs2 :
length vs1 = length vs2 →
array۰cslice t sz i dq1 vs1 -∗
array۰cslice t sz i dq2 vs2 -∗
⌜vs1 = vs2⌝ ∗
array۰cslice t sz i (dq1 ⋅ dq2) vs1.
Lemma array۰csliceーvalidー2 t sz i dq1 vs1 dq2 vs2 :
0 < length vs1 →
length vs1 = length vs2 →
array۰cslice t sz i dq1 vs1 -∗
array۰cslice t sz i dq2 vs2 -∗
⌜✓ (dq1 ⋅ dq2)⌝ ∗
⌜vs1 = vs2⌝.
Lemma array۰csliceーagree t sz i dq1 vs1 dq2 vs2 :
length vs1 = length vs2 →
array۰cslice t sz i dq1 vs1 -∗
array۰cslice t sz i dq2 vs2 -∗
⌜vs1 = vs2⌝.
Lemma array۰csliceーdfracーne t sz i1 dq1 vs1 i2 dq2 vs2 :
0 < length vs1 →
length vs1 = length vs2 →
¬ ✓ (dq1 ⋅ dq2) →
array۰cslice t sz i1 dq1 vs1 -∗
array۰cslice t sz i2 dq2 vs2 -∗
⌜i1 ≠ i2⌝.
Lemma array۰csliceーne t sz i1 vs1 i2 dq2 vs2 :
0 < length vs1 →
length vs1 = length vs2 →
array۰cslice t sz i1 (DfracOwn 1) vs1 -∗
array۰cslice t sz i2 dq2 vs2 -∗
⌜i1 ≠ i2⌝.
Lemma array۰csliceーexclusive t sz i vs1 dq2 vs2 :
0 < length vs1 →
length vs1 = length vs2 →
array۰cslice t sz i (DfracOwn 1) vs1 -∗
array۰cslice t sz i dq2 vs2 -∗
False.
Lemma array۰csliceーpersist t sz i dq vs :
array۰cslice t sz i dq vs ⊢ |==>
array۰cslice t sz i DfracDiscarded vs.
Lemma array۰csliceーlength t sz i vs :
0 < sz →
array۰cslice t sz i (DfracOwn 1) vs ⊢
⌜length vs ≤ sz⌝.
End array۰cslice.
#[local] Typeclasses Opaque
array۰inv
array۰slice
array۰model
array۰cslice.
Notation au_load t i Φ := (
AU <{
∃∃ dq v,
array۰slice t i dq [v]
}> @ ⊤, ∅ <{
array۰slice t i dq [v],
COMM
Φ v
}>
)%I.
Notation au_store t i v P := (
AU <{
∃∃ w,
array۰slice t i (DfracOwn 1) [w]
}> @ ⊤, ∅ <{
array۰slice t i (DfracOwn 1) [v],
COMM
P
}>
)%I.
Lemma array٠unsafe_allocーspec sz :
(0 ≤ sz)%Z →
{{{
True
}}}
array٠unsafe_alloc #sz
{{{
t
, RET t;
array۰model t (DfracOwn 1) (replicate ₊sz ()%V)
}}}.
Lemma array٠allocーspec sz :
{{{
True
}}}
array٠alloc #sz
{{{
t
, RET t;
⌜0 ≤ sz⌝%Z ∗
array۰model t (DfracOwn 1) (replicate ₊sz ()%V)
}}}.
Lemma array٠createーspec :
{{{
True
}}}
array٠create ()
{{{
t
, RET t;
array۰model t (DfracOwn 1) []
}}}.
Lemma array٠sizeーspecーinv t sz :
{{{
array۰inv t sz
}}}
array٠size t
{{{
RET #sz;
True
}}}.
Lemma array٠sizeーspecーatomic t :
<<<
True
| ∀∀ dq vs,
array۰model t dq vs
>>>
array٠size t
<<<
array۰model t dq vs
| RET #(length vs);
£ 1 ∗
array۰inv t (length vs)
>>>.
Lemma array٠sizeーspecーatomicーcslice t :
<<<
True
| ∀∀ sz i dq vs,
array۰cslice t sz i dq vs
>>>
array٠size t
<<<
array۰cslice t sz i dq vs
| RET #sz;
£ 1 ∗
array۰inv t sz
>>>.
Lemma array٠sizeーspec t dq vs :
{{{
array۰model t dq vs
}}}
array٠size t
{{{
RET #(length vs);
array۰model t dq vs
}}}.
Lemma array٠sizeーspecーcslice t sz i dq vs :
{{{
array۰cslice t sz i dq vs
}}}
array٠size t
{{{
RET #sz;
array۰cslice t sz i dq vs
}}}.
Lemma array٠unsafe_getーspecーatomicーslice t (j : Z) :
<<<
True
| ∀∀ dq vs i v,
⌜(i ≤ j)%Z⌝ ∗
⌜vs !! (₊j - i) = Some v⌝ ∗
array۰slice t i dq vs
>>>
array٠unsafe_get t #j
<<<
array۰slice t i dq vs
| RET v;
£ 1
>>>.
Lemma array٠unsafe_getーspecーatomicーcell t (i : Z) :
<<<
True
| ∀∀ i_ dq v,
⌜i = ⁺i_⌝ ∗
array۰slice t i_ dq [v]
>>>
array٠unsafe_get t #i
<<<
array۰slice t ₊i dq [v]
| RET v;
£ 1
>>>.
Lemma array٠unsafe_getーspecーatomic t (i : Z) :
(0 ≤ i)%Z →
<<<
True
| ∀∀ dq vs v,
⌜vs !! ₊i = Some v⌝ ∗
array۰model t dq vs
>>>
array٠unsafe_get t #i
<<<
array۰model t dq vs
| RET v;
£ 1
>>>.
Lemma array٠unsafe_getーspecーatomicーinv t (sz : nat) (i : Z) :
(0 ≤ i < sz)%Z →
<<<
array۰inv t sz
| ∀∀ vs,
array۰model t (DfracOwn 1) vs
>>>
array٠unsafe_get t #i
<<<
∃∃ v,
⌜vs !! ₊i = Some v⌝ ∗
array۰model t (DfracOwn 1) vs
| RET v;
£ 1
>>>.
Lemma array٠unsafe_getーspecーslice k t i dq vs (j : Z) v :
(i ≤ j)%Z →
vs !! k = Some v →
k = ₊j - i →
{{{
array۰slice t i dq vs
}}}
array٠unsafe_get t #j
{{{
RET v;
array۰slice t i dq vs
}}}.
Lemma array٠unsafe_getーspecーcell t (i : Z) i_ dq v :
i = ₊i_ →
{{{
array۰slice t i_ dq [v]
}}}
array٠unsafe_get t #i
{{{
RET v;
array۰slice t i_ dq [v]
}}}.
Lemma array٠unsafe_getーspec i_ t (i : Z) dq vs v :
(0 ≤ i)%Z →
vs !! i_ = Some v →
i_ = ₊i →
{{{
array۰model t dq vs
}}}
array٠unsafe_get t #i
{{{
RET v;
array۰model t dq vs
}}}.
Lemma array٠getーspecーatomicーslice t sz (j : Z) :
<<<
array۰inv t sz
| ∀∀ dq vs i v,
⌜0 ≤ j < sz⌝%Z -∗
⌜i ≤ ₊j⌝ ∗
⌜vs !! (₊j - i) = Some v⌝ ∗
array۰slice t i dq vs
>>>
array٠get t #j
<<<
array۰slice t i dq vs
| RET v;
⌜0 ≤ j < sz⌝%Z ∗
£ 1
>>>.
Lemma array٠getーspecーatomicーcell t sz (i : Z) i_ :
i_ = ₊i →
<<<
array۰inv t sz
| ∀∀ dq v,
⌜0 ≤ i < sz⌝%Z -∗
array۰slice t i_ dq [v]
>>>
array٠get t #i
<<<
array۰slice t i_ dq [v]
| RET v;
⌜0 ≤ i < sz⌝%Z ∗
£ 1
>>>.
Lemma array٠getーspecーatomic t sz (i : Z) :
<<<
array۰inv t sz
| ∀∀ dq vs v,
⌜0 ≤ i < sz⌝%Z -∗
⌜vs !! ₊i = Some v⌝ ∗
array۰model t dq vs
>>>
array٠get t #i
<<<
array۰model t dq vs
| RET v;
⌜0 ≤ i < sz⌝%Z ∗
£ 1
>>>.
Lemma array٠getーspecーslice k t sz i dq vs (j : Z) v :
{{{
array۰inv t sz ∗
( ⌜0 ≤ j < sz⌝%Z -∗
⌜i ≤ ₊j⌝ ∗
⌜vs !! k = Some v⌝ ∗
⌜k = ₊j - i⌝ ∗
array۰slice t i dq vs
)
}}}
array٠get t #j
{{{
RET v;
⌜0 ≤ j < sz⌝%Z ∗
array۰slice t i dq vs
}}}.
Lemma array٠getーspecーcell t sz (i : Z) i_ dq v :
i_ = ₊i →
{{{
array۰inv t sz ∗
( ⌜0 ≤ i < sz⌝%Z -∗
array۰slice t i_ dq [v]
)
}}}
array٠get t #i
{{{
RET v;
⌜0 ≤ i < sz⌝%Z ∗
array۰slice t i_ dq [v]
}}}.
Lemma array٠getーspec t (i : Z) dq vs v :
{{{
array۰model t dq vs ∗
( ⌜0 ≤ i < length vs⌝%Z -∗
⌜vs !! ₊i = Some v⌝
)
}}}
array٠get t #i
{{{
RET v;
⌜0 ≤ i < length vs⌝%Z ∗
array۰model t dq vs
}}}.
Lemma array٠unsafe_setーspecーatomicーslice t (j : Z) v :
<<<
True
| ∀∀ vs i,
⌜i ≤ j < i + length vs⌝%Z ∗
array۰slice t i (DfracOwn 1) vs
>>>
array٠unsafe_set t #j v
<<<
∃∃ w,
⌜vs !! (₊j - i) = Some w⌝ ∗
array۰slice t i (DfracOwn 1) (<[₊j - i := v]> vs)
| RET ();
£ 1
>>>.
Lemma array٠unsafe_setーspecーatomicーcell t (i : Z) v :
<<<
True
| ∀∀ i_ w,
⌜i = ⁺i_⌝ ∗
array۰slice t i_ (DfracOwn 1) [w]
>>>
array٠unsafe_set t #i v
<<<
array۰slice t i_ (DfracOwn 1) [v]
| RET ();
£ 1
>>>.
Lemma array٠unsafe_setーspecーatomic t (i : Z) v :
(0 ≤ i)%Z →
<<<
True
| ∀∀ vs,
⌜i < length vs⌝%Z ∗
array۰model t (DfracOwn 1) vs
>>>
array٠unsafe_set t #i v
<<<
∃∃ w,
⌜vs !! ₊i = Some w⌝ ∗
array۰model t (DfracOwn 1) (<[₊i := v]> vs)
| RET ();
£ 1
>>>.
Lemma array٠unsafe_setーspecーatomicーinv t (sz : nat) (i : Z) v :
(0 ≤ i < sz)%Z →
<<<
array۰inv t sz
| ∀∀ vs,
array۰model t (DfracOwn 1) vs
>>>
array٠unsafe_set t #i v
<<<
∃∃ w,
⌜vs !! ₊i = Some w⌝ ∗
array۰model t (DfracOwn 1) (<[₊i := v]> vs)
| RET ();
£ 1
>>>.
Lemma array٠unsafe_setーspecーslice t i vs (j : Z) v :
(i ≤ j < i + length vs)%Z →
{{{
array۰slice t i (DfracOwn 1) vs
}}}
array٠unsafe_set t #j v
{{{
RET ();
array۰slice t i (DfracOwn 1) (<[₊j - i := v]> vs)
}}}.
Lemma array٠unsafe_setーspecーcell t (i : Z) i_ w v :
i = ⁺i_ →
{{{
array۰slice t i_ (DfracOwn 1) [w]
}}}
array٠unsafe_set t #i v
{{{
RET ();
array۰slice t i_ (DfracOwn 1) [v]
}}}.
Lemma array٠unsafe_setーspec t (i : Z) vs v :
(0 ≤ i < length vs)%Z →
{{{
array۰model t (DfracOwn 1) vs
}}}
array٠unsafe_set t #i v
{{{
RET ();
array۰model t (DfracOwn 1) (<[₊i := v]> vs)
}}}.
Lemma array٠setーspecーatomicーslice t sz (j : Z) v :
<<<
array۰inv t sz
| ∀∀ vs i,
⌜0 ≤ j < sz⌝%Z -∗
⌜i ≤ ₊j < i + length vs⌝ ∗
array۰slice t i (DfracOwn 1) vs
>>>
array٠set t #j v
<<<
array۰slice t i (DfracOwn 1) (<[₊j - i := v]> vs)
| RET ();
⌜0 ≤ j < sz⌝%Z ∗
£ 1
>>>.
Lemma array٠setーspecーatomicーcell t sz (i : Z) i_ v :
i_ = ₊i →
<<<
array۰inv t sz
| ∀∀ w,
⌜0 ≤ i < sz⌝%Z -∗
array۰slice t i_ (DfracOwn 1) [w]
>>>
array٠set t #i v
<<<
array۰slice t i_ (DfracOwn 1) [v]
| RET ();
⌜0 ≤ i < sz⌝%Z ∗
£ 1
>>>.
Lemma array٠setーspecーatomic t sz (i : Z) v :
<<<
array۰inv t sz
| ∀∀ vs,
⌜0 ≤ i < sz⌝%Z -∗
⌜(₊i < length vs)%Z⌝ ∗
array۰model t (DfracOwn 1) vs
>>>
array٠set t #i v
<<<
array۰model t (DfracOwn 1) (<[₊i := v]> vs)
| RET ();
⌜0 ≤ i < sz⌝%Z ∗
£ 1
>>>.
Lemma array٠setーspecーslice t sz i vs (j : Z) v :
{{{
array۰inv t sz ∗
( ⌜0 ≤ j < sz⌝%Z -∗
⌜i ≤ ₊j < i + length vs⌝ ∗
array۰slice t i (DfracOwn 1) vs
)
}}}
array٠set t #j v
{{{
RET ();
⌜0 ≤ j < sz⌝%Z ∗
array۰slice t i (DfracOwn 1) (<[₊j - i := v]> vs)
}}}.
Lemma array٠setーspecーcell t sz (i : Z) i_ w v :
i_ = ₊i →
{{{
array۰inv t sz ∗
( ⌜0 ≤ i < sz⌝%Z -∗
array۰slice t i_ (DfracOwn 1) [w]
)
}}}
array٠set t #i v
{{{
RET ();
⌜0 ≤ i < sz⌝%Z ∗
array۰slice t i_ (DfracOwn 1) [v]
}}}.
Lemma array٠setーspec t (i : Z) vs v :
{{{
array۰model t (DfracOwn 1) vs
}}}
array٠set t #i v
{{{
RET ();
array۰model t (DfracOwn 1) (<[₊i := v]> vs)
}}}.
Lemma array٠unsafe_xchgーspecーatomicーslice t (j : Z) v :
<<<
True
| ∀∀ vs i,
⌜i ≤ j < i + length vs⌝%Z ∗
array۰slice t i (DfracOwn 1) vs
>>>
array٠unsafe_xchg t #j v
<<<
∃∃ w,
⌜vs !! (₊j - i) = Some w⌝ ∗
array۰slice t i (DfracOwn 1) (<[₊j - i := v]> vs)
| RET w;
£ 1
>>>.
Lemma array٠unsafe_xchgーspecーatomicーcell t (i : Z) v :
<<<
True
| ∀∀ i_ w,
⌜i = ⁺i_⌝ ∗
array۰slice t i_ (DfracOwn 1) [w]
>>>
array٠unsafe_xchg t #i v
<<<
array۰slice t i_ (DfracOwn 1) [v]
| RET w;
£ 1
>>>.
Lemma array٠unsafe_xchgーspecーatomic t (i : Z) v :
(0 ≤ i)%Z →
<<<
True
| ∀∀ vs,
⌜i < length vs⌝%Z ∗
array۰model t (DfracOwn 1) vs
>>>
array٠unsafe_xchg t #i v
<<<
∃∃ w,
⌜vs !! ₊i = Some w⌝ ∗
array۰model t (DfracOwn 1) (<[₊i := v]> vs)
| RET w;
£ 1
>>>.
Lemma array٠unsafe_xchgーspecーatomicーinv t (sz : nat) (i : Z) v :
(0 ≤ i < sz)%Z →
<<<
array۰inv t sz
| ∀∀ vs,
array۰model t (DfracOwn 1) vs
>>>
array٠unsafe_xchg t #i v
<<<
∃∃ w,
⌜vs !! ₊i = Some w⌝ ∗
array۰model t (DfracOwn 1) (<[₊i := v]> vs)
| RET w;
£ 1
>>>.
Lemma array٠unsafe_xchgーspecーslice t i vs (j : Z) v :
(i ≤ j < i + length vs)%Z →
{{{
array۰slice t i (DfracOwn 1) vs
}}}
array٠unsafe_xchg t #j v
{{{
w
, RET w;
⌜vs !! (₊j - i) = Some w⌝ ∗
array۰slice t i (DfracOwn 1) (<[₊j - i := v]> vs)
}}}.
Lemma array٠unsafe_xchgーspecーcell t (i : Z) i_ w v :
i = ⁺i_ →
{{{
array۰slice t i_ (DfracOwn 1) [w]
}}}
array٠unsafe_xchg t #i v
{{{
RET w;
array۰slice t i_ (DfracOwn 1) [v]
}}}.
Lemma array٠unsafe_xchgーspec t (i : Z) vs v :
(0 ≤ i < length vs)%Z →
{{{
array۰model t (DfracOwn 1) vs
}}}
array٠unsafe_xchg t #i v
{{{
w
, RET w;
⌜vs !! ₊i = Some w⌝ ∗
array۰model t (DfracOwn 1) (<[₊i := v]> vs)
}}}.
Lemma array٠unsafe_casーspecーatomicーslice t (j : Z) v1 v2 :
<<<
True
| ∀∀ vs i,
⌜i ≤ j < i + length vs⌝%Z ∗
array۰slice t i (DfracOwn 1) vs
>>>
array٠unsafe_cas t #j v1 v2
<<<
∃∃ b v,
⌜vs !! (₊j - i) = Some v⌝ ∗
⌜(if b then (≈) else (≉)) v v1⌝ ∗
array۰slice t i (DfracOwn 1) (if b then <[₊j - i := v2]> vs else vs)
| RET #b;
£ 1
>>>.
Lemma array٠unsafe_casーspecーatomicーcell t (i : Z) v1 v2 :
<<<
True
| ∀∀ i_ v,
⌜i = ⁺i_⌝ ∗
array۰slice t i_ (DfracOwn 1) [v]
>>>
array٠unsafe_cas t #i v1 v2
<<<
∃∃ b,
⌜(if b then (≈) else (≉)) v v1⌝ ∗
array۰slice t i_ (DfracOwn 1) [if b then v2 else v]
| RET #b;
£ 1
>>>.
Lemma array٠unsafe_casーspecーatomic t (i : Z) v1 v2 :
(0 ≤ i)%Z →
<<<
True
| ∀∀ vs,
⌜i < length vs⌝%Z ∗
array۰model t (DfracOwn 1) vs
>>>
array٠unsafe_cas t #i v1 v2
<<<
∃∃ b v,
⌜vs !! ₊i = Some v⌝ ∗
⌜(if b then (≈) else (≉)) v v1⌝ ∗
array۰model t (DfracOwn 1) (if b then <[₊i := v2]> vs else vs)
| RET #b;
£ 1
>>>.
Lemma array٠unsafe_casーspecーatomicーinv t (sz : nat) (i : Z) v1 v2 :
(0 ≤ i < sz)%Z →
<<<
array۰inv t sz
| ∀∀ vs,
array۰model t (DfracOwn 1) vs
>>>
array٠unsafe_cas t #i v1 v2
<<<
∃∃ b v,
⌜vs !! ₊i = Some v⌝ ∗
⌜(if b then (≈) else (≉)) v v1⌝ ∗
array۰model t (DfracOwn 1) (if b then <[₊i := v2]> vs else vs)
| RET #b;
£ 1
>>>.
Lemma array٠unsafe_casーspecーslice t i vs (j : Z) v1 v2 :
(i ≤ j < i + length vs)%Z →
{{{
array۰slice t i (DfracOwn 1) vs
}}}
array٠unsafe_cas t #j v1 v2
{{{
b v
, RET #b;
⌜vs !! (₊j - i) = Some v⌝ ∗
⌜(if b then (≈) else (≉)) v v1⌝ ∗
array۰slice t i (DfracOwn 1) (if b then <[₊j - i := v2]> vs else vs)
}}}.
Lemma array٠unsafe_casーspecーcell t (i : Z) i_ v v1 v2 :
i = ⁺i_ →
{{{
array۰slice t i_ (DfracOwn 1) [v]
}}}
array٠unsafe_cas t #i v1 v2
{{{
b
, RET #b;
⌜(if b then (≈) else (≉)) v v1⌝ ∗
array۰slice t i_ (DfracOwn 1) [if b then v2 else v]
}}}.
Lemma array٠unsafe_casーspec t (i : Z) vs v1 v2 :
(0 ≤ i < length vs)%Z →
{{{
array۰model t (DfracOwn 1) vs
}}}
array٠unsafe_cas t #i v1 v2
{{{
b v
, RET #b;
⌜vs !! ₊i = Some v⌝ ∗
⌜(if b then (≈) else (≉)) v v1⌝ ∗
array۰model t (DfracOwn 1) (if b then <[₊i := v2]> vs else vs)
}}}.
Lemma array٠unsafe_swapーspecーslice {t i vs} {i1 : Z} k1 {v1} {i2 : Z} k2 v2 :
(i ≤ i1)%Z →
(i ≤ i2)%Z →
vs !! k1 = Some v1 →
k1 = ₊i1 - i →
vs !! k2 = Some v2 →
k2 = ₊i2 - i →
{{{
array۰slice t i (DfracOwn 1) vs
}}}
array٠unsafe_swap t #i1 #i2
{{{
RET ();
array۰slice t i (DfracOwn 1) (<[k2 := v1]> $ <[k1 := v2]> vs)
}}}.
Lemma array٠unsafe_swapーspecーsliceーid t i vs (i1 i2 : Z) :
i1 = i2 →
(i ≤ i1 < i + length vs)%Z →
{{{
array۰slice t i (DfracOwn 1) vs
}}}
array٠unsafe_swap t #i1 #i2
{{{
RET ();
array۰slice t i (DfracOwn 1) vs
}}}.
Lemma array٠unsafe_swapーspec {t vs} {i1 : Z} i1_ {v1} {i2 : Z} i2_ v2 :
(0 ≤ i1)%Z →
(0 ≤ i2)%Z →
vs !! i1_ = Some v1 →
i1_ = ₊i1 →
vs !! i2_ = Some v2 →
i2_ = ₊i2 →
{{{
array۰model t (DfracOwn 1) vs
}}}
array٠unsafe_swap t #i1 #i2
{{{
RET ();
array۰model t (DfracOwn 1) (<[i2_ := v1]> $ <[i1_ := v2]> vs)
}}}.
Lemma array٠unsafe_fill_sliceーspecーatomic Ψ t (i n : Z) v :
(0 ≤ i)%Z →
{{{
▷ Ψ 0 ∗
□ (
∀ j,
⌜j < ₊n⌝ -∗
Ψ j -∗
au_store t (₊i + j) v (
▷ Ψ ˖j
)
)
}}}
array٠unsafe_fill_slice t #i #n v
{{{
RET ();
Ψ ₊n
}}}.
Lemma array٠unsafe_fill_sliceーspecーsliceーfit t vs (i : Z) i_ (n : Z) v :
i = ⁺i_ →
₊n = length vs →
{{{
array۰slice t i_ (DfracOwn 1) vs
}}}
array٠unsafe_fill_slice t #i #n v
{{{
RET ();
array۰slice t i_ (DfracOwn 1) (replicate ₊n v)
}}}.
Lemma array٠unsafe_fill_sliceーspecーslice t vs (i : Z) j (n : Z) v :
(j ≤ i)%Z →
₊i + ₊n ≤ j + length vs →
{{{
array۰slice t j (DfracOwn 1) vs
}}}
array٠unsafe_fill_slice t #i #n v
{{{
RET ();
array۰slice t j (DfracOwn 1) (with_slice (₊i - j) ₊n vs (replicate ₊n v))
}}}.
Lemma array٠unsafe_fill_sliceーspec t vs (i : Z) (n : Z) v :
(0 ≤ i)%Z →
₊i + ₊n ≤ length vs →
{{{
array۰model t (DfracOwn 1) vs
}}}
array٠unsafe_fill_slice t #i #n v
{{{
RET ();
array۰model t (DfracOwn 1) (with_slice ₊i ₊n vs (replicate ₊n v))
}}}.
Lemma array٠fill_sliceーspec t sz vs (i : Z) i_ (n : Z) v :
i_ = ₊i →
₊n = length vs →
{{{
array۰inv t sz ∗
array۰slice t i_ (DfracOwn 1) vs
}}}
array٠fill_slice t #i #n v
{{{
RET ();
⌜0 ≤ i⌝%Z ∗
⌜0 ≤ n⌝%Z ∗
⌜i + n ≤ sz⌝%Z ∗
array۰slice t i_ (DfracOwn 1) (replicate ₊n v)
}}}.
Lemma array٠fillーspec t vs v :
{{{
array۰model t (DfracOwn 1) vs
}}}
array٠fill t v
{{{
RET ();
array۰model t (DfracOwn 1) (replicate (length vs) v)
}}}.
Lemma array٠unsafe_makeーspec sz v :
(0 ≤ sz)%Z →
{{{
True
}}}
array٠unsafe_make #sz v
{{{
t
, RET t;
array۰model t (DfracOwn 1) (replicate ₊sz v)
}}}.
Lemma array٠makeーspec sz v :
{{{
True
}}}
array٠make #sz v
{{{
t
, RET t;
⌜0 ≤ sz⌝%Z ∗
array۰model t (DfracOwn 1) (replicate ₊sz v)
}}}.
#[local] Lemma array٠foldli_auxーspec vs Ψ fn t sz i acc :
i ≤ sz →
i = length vs →
{{{
▷ Ψ i vs None acc ∗
□ (
∀ i vs (o : option val) acc,
⌜i < sz⌝ -∗
⌜i = length vs⌝ -∗
Ψ i vs o acc -∗
match o with
| None ⇒
au_load t i (λ v,
▷ Ψ i vs (Some v) acc
)
| Some v ⇒
WP fn #i acc v {{ acc,
▷ Ψ ˖i (vs ++ [v]) None acc
}}
end
)
}}}
array٠foldli_aux fn t #sz #i acc
{{{
vs' acc
, RET acc;
⌜(length vs + length vs')%nat = sz⌝ ∗
Ψ sz (vs ++ vs') None acc
}}}.
Lemma array٠foldliーspecーatomic Ψ fn acc t sz :
{{{
array۰inv t sz ∗
▷ Ψ 0 [] None acc ∗
□ (
∀ i vs (o : option val) acc,
⌜i < sz⌝ -∗
⌜i = length vs⌝ -∗
Ψ i vs o acc -∗
match o with
| None ⇒
au_load t i (λ v,
▷ Ψ i vs (Some v) acc
)
| Some v ⇒
WP fn #i acc v {{ acc,
▷ Ψ ˖i (vs ++ [v]) None acc
}}
end
)
}}}
array٠foldli fn acc t
{{{
vs acc
, RET acc;
⌜length vs = sz⌝ ∗
Ψ sz vs None acc
}}}.
Lemma array٠foldliーspec Ψ fn acc t dq vs :
{{{
▷ Ψ 0 [] acc ∗
array۰model t dq vs ∗
□ (
∀ i v acc,
⌜vs !! i = Some v⌝ -∗
Ψ i (take i vs) acc -∗
WP fn #i acc v {{ acc,
▷ Ψ ˖i (take i vs ++ [v]) acc
}}
)
}}}
array٠foldli fn acc t
{{{
acc
, RET acc;
array۰model t dq vs ∗
Ψ (length vs) vs acc
}}}.
Lemma array٠foldliーspec' Ψ fn acc t dq vs :
{{{
▷ Ψ 0 [] acc ∗
array۰model t dq vs ∗
( [∗ list] i ↦ v ∈ vs,
∀ acc,
Ψ i (take i vs) acc -∗
WP fn #i acc v {{ acc,
▷ Ψ ˖i (take i vs ++ [v]) acc
}}
)
}}}
array٠foldli fn acc t
{{{
acc
, RET acc;
array۰model t dq vs ∗
Ψ (length vs) vs acc
}}}.
Lemma array٠foldlーspecーatomic Ψ fn acc t sz :
{{{
array۰inv t sz ∗
▷ Ψ 0 [] None acc ∗
□ (
∀ i vs (o : option val) acc,
⌜i < sz⌝ -∗
⌜i = length vs⌝ -∗
Ψ i vs o acc -∗
match o with
| None ⇒
au_load t i (λ v,
▷ Ψ i vs (Some v) acc
)
| Some v ⇒
WP fn acc v {{ acc,
▷ Ψ ˖i (vs ++ [v]) None acc
}}
end
)
}}}
array٠foldl fn acc t
{{{
vs acc
, RET acc;
⌜length vs = sz⌝ ∗
Ψ sz vs None acc
}}}.
Lemma array٠foldlーspec Ψ fn acc t dq vs :
{{{
▷ Ψ 0 [] acc ∗
array۰model t dq vs ∗
□ (
∀ i v acc,
⌜vs !! i = Some v⌝ -∗
Ψ i (take i vs) acc -∗
WP fn acc v {{ acc,
▷ Ψ ˖i (take i vs ++ [v]) acc
}}
)
}}}
array٠foldl fn acc t
{{{
acc
, RET acc;
array۰model t dq vs ∗
Ψ (length vs) vs acc
}}}.
Lemma array٠foldlーspec' Ψ fn acc t dq vs :
{{{
▷ Ψ 0 [] acc ∗
array۰model t dq vs ∗
( [∗ list] i ↦ v ∈ vs,
∀ acc,
Ψ i (take i vs) acc -∗
WP fn acc v {{ acc,
▷ Ψ ˖i (take i vs ++ [v]) acc
}}
)
}}}
array٠foldl fn acc t
{{{
acc
, RET acc;
array۰model t dq vs ∗
Ψ (length vs) vs acc
}}}.
#[local] Lemma array٠foldri_auxーspec sz vs Ψ fn t (i : Z) acc :
₊i + length vs = sz →
{{{
▷ Ψ ₊i acc None vs ∗
□ (
∀ i acc (o : option val) vs,
⌜(˖i + length vs)%nat = sz⌝ -∗
Ψ ˖i acc o vs -∗
match o with
| None ⇒
au_load t i (λ v,
▷ Ψ ˖i acc (Some v) vs
)
| Some v ⇒
WP fn #i v acc {{ acc,
▷ Ψ i acc None (v :: vs)
}}
end
)
}}}
array٠foldri_aux fn t #i acc
{{{
acc vs'
, RET acc;
⌜(length vs' + length vs)%nat = sz⌝ ∗
Ψ 0 acc None (vs' ++ vs)
}}}.
Lemma array٠foldriーspecーatomic Ψ fn t sz acc :
{{{
array۰inv t sz ∗
▷ Ψ sz acc None [] ∗
□ (
∀ i acc (o : option val) vs,
⌜(˖i + length vs)%nat = sz⌝ -∗
Ψ ˖i acc o vs -∗
match o with
| None ⇒
au_load t i (λ v,
▷ Ψ ˖i acc (Some v) vs
)
| Some v ⇒
WP fn #i v acc {{ acc,
▷ Ψ i acc None (v :: vs)
}}
end
)
}}}
array٠foldri fn t acc
{{{
acc vs
, RET acc;
⌜length vs = sz⌝ ∗
Ψ 0 acc None vs
}}}.
Lemma array٠foldriーspec Ψ fn t dq vs acc :
{{{
array۰model t dq vs ∗
▷ Ψ (length vs) acc [] ∗
□ (
∀ i v acc,
⌜vs !! i = Some v⌝ -∗
Ψ ˖i acc (drop ˖i vs) -∗
WP fn #i v acc {{ acc,
▷ Ψ i acc (v :: drop ˖i vs)
}}
)
}}}
array٠foldri fn t acc
{{{
acc
, RET acc;
Ψ 0 acc vs ∗
array۰model t dq vs
}}}.
Lemma array٠foldriーspec' Ψ fn t dq vs acc :
{{{
array۰model t dq vs ∗
▷ Ψ (length vs) acc [] ∗
( [∗ list] i ↦ v ∈ vs,
∀ acc,
Ψ ˖i acc (drop ˖i vs) -∗
WP fn #i v acc {{ acc,
▷ Ψ i acc (v :: drop ˖i vs)
}}
)
}}}
array٠foldri fn t acc
{{{
acc
, RET acc;
Ψ 0 acc vs ∗
array۰model t dq vs
}}}.
Lemma array٠foldrーspecーatomic Ψ fn t sz acc :
{{{
array۰inv t sz ∗
▷ Ψ sz acc None [] ∗
□ (
∀ i acc (o : option val) vs,
⌜(˖i + length vs)%nat = sz⌝ -∗
Ψ ˖i acc o vs -∗
match o with
| None ⇒
au_load t i (λ v,
▷ Ψ ˖i acc (Some v) vs
)
| Some v ⇒
WP fn v acc {{ acc,
▷ Ψ i acc None (v :: vs)
}}
end
)
}}}
array٠foldr fn t acc
{{{
acc vs
, RET acc;
⌜length vs = sz⌝ ∗
Ψ 0 acc None vs
}}}.
Lemma array٠foldrーspec Ψ fn t dq vs acc :
{{{
array۰model t dq vs ∗
▷ Ψ (length vs) acc [] ∗
□ (
∀ i v acc,
⌜vs !! i = Some v⌝ -∗
Ψ ˖i acc (drop ˖i vs) -∗
WP fn v acc {{ acc,
▷ Ψ i acc (v :: drop ˖i vs)
}}
)
}}}
array٠foldr fn t acc
{{{
acc
, RET acc;
Ψ 0 acc vs ∗
array۰model t dq vs
}}}.
Lemma array٠foldrーspec' Ψ fn t dq vs acc :
{{{
array۰model t dq vs ∗
▷ Ψ (length vs) acc [] ∗
( [∗ list] i ↦ v ∈ vs,
∀ acc,
Ψ ˖i acc (drop ˖i vs) -∗
WP fn v acc {{ acc,
▷ Ψ i acc (v :: drop ˖i vs)
}}
)
}}}
array٠foldr fn t acc
{{{
acc
, RET acc;
Ψ 0 acc vs ∗
array۰model t dq vs
}}}.
Lemma array٠unsafe_iteri_sliceーspecーatomic Ψ fn t (sz : nat) (i n : Z) :
(0 ≤ i ≤ sz)%Z →
(0 ≤ n)%Z →
(i + n ≤ sz)%Z →
{{{
array۰inv t sz ∗
▷ Ψ 0 [] None ∗
□ (
∀ k vs (o : option val),
⌜k < ₊n⌝ -∗
⌜k = length vs⌝ -∗
Ψ k vs o -∗
match o with
| None ⇒
au_load t (₊i + k) (λ v,
▷ Ψ k vs (Some v)
)
| Some v ⇒
WP fn #k v {{ res,
⌜res = ()%V⌝ ∗
▷ Ψ ˖k (vs ++ [v]) None
}}
end
)
}}}
array٠unsafe_iteri_slice fn t #i #n
{{{
vs
, RET ();
⌜length vs = ₊n⌝ ∗
Ψ ₊n vs None
}}}.
Lemma array٠unsafe_iteri_sliceーspec Ψ fn t dq vs (i n : Z) :
(0 ≤ i ≤ length vs)%Z →
(0 ≤ n)%Z →
(i + n ≤ length vs)%Z →
{{{
▷ Ψ 0 [] ∗
array۰model t dq vs ∗
□ (
∀ k v,
⌜k < ₊n⌝ -∗
⌜vs !! (₊i + k)%nat = Some v⌝ -∗
Ψ k (slice ₊i k vs) -∗
WP fn #k v {{ res,
⌜res = ()%V⌝ ∗
▷ Ψ ˖k (slice ₊i k vs ++ [v])
}}
)
}}}
array٠unsafe_iteri_slice fn t #i #n
{{{
RET ();
array۰model t dq vs ∗
Ψ ₊n (slice ₊i ₊n vs)
}}}.
Lemma array٠unsafe_iteri_sliceーspec' Ψ fn t dq vs (i n : Z) :
(0 ≤ i ≤ length vs)%Z →
(0 ≤ n)%Z →
(i + n ≤ length vs)%Z →
{{{
▷ Ψ 0 [] ∗
array۰model t dq vs ∗
( [∗ list] k ↦ v ∈ slice ₊i ₊n vs,
Ψ k (slice ₊i k vs) -∗
WP fn #k v {{ res,
⌜res = ()%V⌝ ∗
▷ Ψ ˖k (slice ₊i k vs ++ [v])
}}
)
}}}
array٠unsafe_iteri_slice fn t #i #n
{{{
RET ();
array۰model t dq vs ∗
Ψ ₊n (slice ₊i ₊n vs)
}}}.
Lemma array٠unsafe_iteri_sliceーspecーdisentangled Ψ fn t dq vs (i n : Z) :
(0 ≤ i ≤ length vs)%Z →
(0 ≤ n)%Z →
(i + n ≤ length vs)%Z →
{{{
array۰model t dq vs ∗
□ (
∀ k v,
⌜k < ₊n⌝ -∗
⌜vs !! (₊i + k)%nat = Some v⌝ -∗
WP fn #k v {{ res,
⌜res = ()%V⌝ ∗
▷ Ψ k v
}}
)
}}}
array٠unsafe_iteri_slice fn t #i #n
{{{
RET ();
array۰model t dq vs ∗
( [∗ list] k ↦ v ∈ slice ₊i ₊n vs,
Ψ k v
)
}}}.
Lemma array٠unsafe_iteri_sliceーspecーdisentangled' Ψ fn t dq vs (i n : Z) :
(0 ≤ i ≤ length vs)%Z →
(0 ≤ n)%Z →
(i + n ≤ length vs)%Z →
{{{
array۰model t dq vs ∗
( [∗ list] k ↦ v ∈ slice ₊i ₊n vs,
WP fn #k v {{ res,
⌜res = ()%V⌝ ∗
▷ Ψ k v
}}
)
}}}
array٠unsafe_iteri_slice fn t #i #n
{{{
RET ();
array۰model t dq vs ∗
( [∗ list] k ↦ v ∈ slice ₊i ₊n vs,
Ψ k v
)
}}}.
Lemma array٠iteri_sliceーspecーatomic Ψ fn t (sz : nat) (i n : Z) :
{{{
array۰inv t sz ∗
▷ Ψ 0 [] None ∗
□ (
∀ k vs (o : option val),
⌜k < ₊n⌝ -∗
⌜k = length vs⌝ -∗
Ψ k vs o -∗
match o with
| None ⇒
au_load t (₊i + k) (λ v,
▷ Ψ k vs (Some v)
)
| Some v ⇒
WP fn #k v {{ res,
⌜res = ()%V⌝ ∗
▷ Ψ ˖k (vs ++ [v]) None
}}
end
)
}}}
array٠iteri_slice fn t #i #n
{{{
vs
, RET ();
⌜0 ≤ i ≤ sz⌝%Z ∗
⌜0 ≤ n⌝%Z ∗
⌜i + n ≤ sz⌝%Z ∗
⌜length vs = ₊n⌝ ∗
Ψ ₊n vs None
}}}.
Lemma array٠iteri_sliceーspec Ψ fn t dq vs (i n : Z) :
{{{
▷ Ψ 0 [] ∗
array۰model t dq vs ∗
□ (
∀ k v,
⌜k < ₊n⌝ -∗
⌜vs !! (₊i + k)%nat = Some v⌝ -∗
Ψ k (slice ₊i k vs) -∗
WP fn #k v {{ res,
⌜res = ()%V⌝ ∗
▷ Ψ ˖k (slice ₊i k vs ++ [v])
}}
)
}}}
array٠iteri_slice fn t #i #n
{{{
RET ();
⌜0 ≤ i ≤ length vs⌝%Z ∗
⌜0 ≤ n⌝%Z ∗
⌜i + n ≤ length vs⌝%Z ∗
array۰model t dq vs ∗
Ψ ₊n (slice ₊i ₊n vs)
}}}.
Lemma array٠iteri_sliceーspec' Ψ fn t dq vs (i n : Z) :
{{{
▷ Ψ 0 [] ∗
array۰model t dq vs ∗
( [∗ list] k ↦ v ∈ slice ₊i ₊n vs,
Ψ k (slice ₊i k vs) -∗
WP fn #k v {{ res,
⌜res = ()%V⌝ ∗
▷ Ψ ˖k (slice ₊i k vs ++ [v])
}}
)
}}}
array٠iteri_slice fn t #i #n
{{{
RET ();
⌜0 ≤ i ≤ length vs⌝%Z ∗
⌜0 ≤ n⌝%Z ∗
⌜i + n ≤ length vs⌝%Z ∗
array۰model t dq vs ∗
Ψ ₊n (slice ₊i ₊n vs)
}}}.
Lemma array٠iteri_sliceーspecーdisentangled Ψ fn t dq vs (i n : Z) :
{{{
array۰model t dq vs ∗
□ (
∀ k v,
⌜k < ₊n⌝ -∗
⌜vs !! (₊i + k)%nat = Some v⌝ -∗
WP fn #k v {{ res,
⌜res = ()%V⌝ ∗
▷ Ψ k v
}}
)
}}}
array٠iteri_slice fn t #i #n
{{{
RET ();
⌜0 ≤ i ≤ length vs⌝%Z ∗
⌜0 ≤ n⌝%Z ∗
⌜i + n ≤ length vs⌝%Z ∗
array۰model t dq vs ∗
( [∗ list] k ↦ v ∈ slice ₊i ₊n vs,
Ψ k v
)
}}}.
Lemma array٠iteri_sliceーspecーdisentangled' Ψ fn t dq vs (i n : Z) :
{{{
array۰model t dq vs ∗
( [∗ list] k ↦ v ∈ slice ₊i ₊n vs,
WP fn #k v {{ res,
⌜res = ()%V⌝ ∗
▷ Ψ k v
}}
)
}}}
array٠iteri_slice fn t #i #n
{{{
RET ();
⌜0 ≤ i ≤ length vs⌝%Z ∗
⌜0 ≤ n⌝%Z ∗
⌜i + n ≤ length vs⌝%Z ∗
array۰model t dq vs ∗
( [∗ list] k ↦ v ∈ slice ₊i ₊n vs,
Ψ k v
)
}}}.
Lemma array٠unsafe_iter_sliceーspecーatomic Ψ fn t (sz : nat) (i n : Z) :
(0 ≤ i ≤ sz)%Z →
(0 ≤ n)%Z →
(i + n ≤ sz)%Z →
{{{
array۰inv t sz ∗
▷ Ψ 0 [] None ∗
□ (
∀ k vs (o : option val),
⌜k < ₊n⌝ -∗
⌜k = length vs⌝ -∗
Ψ k vs o -∗
match o with
| None ⇒
au_load t (₊i + k) (λ v,
▷ Ψ k vs (Some v)
)
| Some v ⇒
WP fn v {{ res,
⌜res = ()%V⌝ ∗
▷ Ψ ˖k (vs ++ [v]) None
}}
end
)
}}}
array٠unsafe_iter_slice fn t #i #n
{{{
vs
, RET ();
⌜length vs = ₊n⌝ ∗
Ψ ₊n vs None
}}}.
Lemma array٠unsafe_iter_sliceーspec Ψ fn t dq vs (i n : Z) :
(0 ≤ i ≤ length vs)%Z →
(0 ≤ n)%Z →
(i + n ≤ length vs)%Z →
{{{
▷ Ψ 0 [] ∗
array۰model t dq vs ∗
□ (
∀ k v,
⌜k < ₊n⌝ -∗
⌜vs !! (₊i + k)%nat = Some v⌝ -∗
Ψ k (slice ₊i k vs) -∗
WP fn v {{ res,
⌜res = ()%V⌝ ∗
▷ Ψ ˖k (slice ₊i k vs ++ [v])
}}
)
}}}
array٠unsafe_iter_slice fn t #i #n
{{{
RET ();
array۰model t dq vs ∗
Ψ ₊n (slice ₊i ₊n vs)
}}}.
Lemma array٠unsafe_iter_sliceーspec' Ψ fn t dq vs (i n : Z) :
(0 ≤ i ≤ length vs)%Z →
(0 ≤ n)%Z →
(i + n ≤ length vs)%Z →
{{{
▷ Ψ 0 [] ∗
array۰model t dq vs ∗
( [∗ list] k ↦ v ∈ slice ₊i ₊n vs,
Ψ k (slice ₊i k vs) -∗
WP fn v {{ res,
⌜res = ()%V⌝ ∗
▷ Ψ ˖k (slice ₊i k vs ++ [v])
}}
)
}}}
array٠unsafe_iter_slice fn t #i #n
{{{
RET ();
array۰model t dq vs ∗
Ψ ₊n (slice ₊i ₊n vs)
}}}.
Lemma array٠unsafe_iter_sliceーspecーdisentangled Ψ fn t dq vs (i n : Z) :
(0 ≤ i ≤ length vs)%Z →
(0 ≤ n)%Z →
(i + n ≤ length vs)%Z →
{{{
array۰model t dq vs ∗
□ (
∀ k v,
⌜k < ₊n⌝ -∗
⌜vs !! (₊i + k)%nat = Some v⌝ -∗
WP fn v {{ res,
⌜res = ()%V⌝ ∗
▷ Ψ k v
}}
)
}}}
array٠unsafe_iter_slice fn t #i #n
{{{
RET ();
array۰model t dq vs ∗
( [∗ list] k ↦ v ∈ slice ₊i ₊n vs,
Ψ k v
)
}}}.
Lemma array٠unsafe_iter_sliceーspecーdisentangled' Ψ fn t dq vs (i n : Z) :
(0 ≤ i ≤ length vs)%Z →
(0 ≤ n)%Z →
(i + n ≤ length vs)%Z →
{{{
array۰model t dq vs ∗
( [∗ list] k ↦ v ∈ slice ₊i ₊n vs,
WP fn v {{ res,
⌜res = ()%V⌝ ∗
▷ Ψ k v
}}
)
}}}
array٠unsafe_iter_slice fn t #i #n
{{{
RET ();
array۰model t dq vs ∗
( [∗ list] k ↦ v ∈ slice ₊i ₊n vs,
Ψ k v
)
}}}.
Lemma array٠iter_sliceーspecーatomic Ψ fn t (sz : nat) (i n : Z) :
{{{
array۰inv t sz ∗
▷ Ψ 0 [] None ∗
□ (
∀ k vs (o : option val),
⌜k < ₊n⌝ -∗
⌜k = length vs⌝ -∗
Ψ k vs o -∗
match o with
| None ⇒
au_load t (₊i + k) (λ v,
▷ Ψ k vs (Some v)
)
| Some v ⇒
WP fn v {{ res,
⌜res = ()%V⌝ ∗
▷ Ψ ˖k (vs ++ [v]) None
}}
end
)
}}}
array٠iter_slice fn t #i #n
{{{
vs
, RET ();
⌜0 ≤ i ≤ sz⌝%Z ∗
⌜0 ≤ n⌝%Z ∗
⌜i + n ≤ sz⌝%Z ∗
⌜length vs = ₊n⌝ ∗
Ψ ₊n vs None
}}}.
Lemma array٠iter_sliceーspec Ψ fn t dq vs (i n : Z) :
{{{
▷ Ψ 0 [] ∗
array۰model t dq vs ∗
□ (
∀ k v,
⌜k < ₊n⌝ -∗
⌜vs !! (₊i + k)%nat = Some v⌝ -∗
Ψ k (slice ₊i k vs) -∗
WP fn v {{ res,
⌜res = ()%V⌝ ∗
▷ Ψ ˖k (slice ₊i k vs ++ [v])
}}
)
}}}
array٠iter_slice fn t #i #n
{{{
RET ();
⌜0 ≤ i ≤ length vs⌝%Z ∗
⌜0 ≤ n⌝%Z ∗
⌜i + n ≤ length vs⌝%Z ∗
array۰model t dq vs ∗
Ψ ₊n (slice ₊i ₊n vs)
}}}.
Lemma array٠iter_sliceーspec' Ψ fn t dq vs (i n : Z) :
{{{
▷ Ψ 0 [] ∗
array۰model t dq vs ∗
( [∗ list] k ↦ v ∈ slice ₊i ₊n vs,
Ψ k (slice ₊i k vs) -∗
WP fn v {{ res,
⌜res = ()%V⌝ ∗
▷ Ψ ˖k (slice ₊i k vs ++ [v])
}}
)
}}}
array٠iter_slice fn t #i #n
{{{
RET ();
⌜0 ≤ i ≤ length vs⌝%Z ∗
⌜0 ≤ n⌝%Z ∗
⌜i + n ≤ length vs⌝%Z ∗
array۰model t dq vs ∗
Ψ ₊n (slice ₊i ₊n vs)
}}}.
Lemma array٠iter_sliceーspecーdisentangled Ψ fn t dq vs (i n : Z) :
{{{
array۰model t dq vs ∗
□ (
∀ k v,
⌜k < ₊n⌝ -∗
⌜vs !! (₊i + k)%nat = Some v⌝ -∗
WP fn v {{ res,
⌜res = ()%V⌝ ∗
▷ Ψ k v
}}
)
}}}
array٠iter_slice fn t #i #n
{{{
RET ();
⌜0 ≤ i ≤ length vs⌝%Z ∗
⌜0 ≤ n⌝%Z ∗
⌜i + n ≤ length vs⌝%Z ∗
array۰model t dq vs ∗
( [∗ list] k ↦ v ∈ slice ₊i ₊n vs,
Ψ k v
)
}}}.
Lemma array٠iter_sliceーspecーdisentangled' Ψ fn t dq vs (i n : Z) :
{{{
array۰model t dq vs ∗
( [∗ list] k ↦ v ∈ slice ₊i ₊n vs,
WP fn v {{ res,
⌜res = ()%V⌝ ∗
▷ Ψ k v
}}
)
}}}
array٠iter_slice fn t #i #n
{{{
RET ();
⌜0 ≤ i ≤ length vs⌝%Z ∗
⌜0 ≤ n⌝%Z ∗
⌜i + n ≤ length vs⌝%Z ∗
array۰model t dq vs ∗
( [∗ list] k ↦ v ∈ slice ₊i ₊n vs,
Ψ k v
)
}}}.
Lemma array٠iteriーspecーatomic Ψ fn t sz :
{{{
array۰inv t sz ∗
▷ Ψ 0 [] None ∗
□ (
∀ i vs (o : option val),
⌜i < sz⌝ -∗
⌜i = length vs⌝ -∗
Ψ i vs o -∗
match o with
| None ⇒
au_load t i (λ v,
▷ Ψ i vs (Some v)
)
| Some v ⇒
WP fn #i v {{ res,
⌜res = ()%V⌝ ∗
▷ Ψ ˖i (vs ++ [v]) None
}}
end
)
}}}
array٠iteri fn t
{{{
vs
, RET ();
⌜length vs = sz⌝ ∗
Ψ sz vs None
}}}.
Lemma array٠iteriーspec Ψ fn t dq vs :
{{{
▷ Ψ 0 [] ∗
array۰model t dq vs ∗
□ (
∀ i v,
⌜vs !! i = Some v⌝ -∗
Ψ i (take i vs) -∗
WP fn #i v {{ res,
⌜res = ()%V⌝ ∗
▷ Ψ ˖i (take i vs ++ [v])
}}
)
}}}
array٠iteri fn t
{{{
RET ();
array۰model t dq vs ∗
Ψ (length vs) vs
}}}.
Lemma array٠iteriーspec' Ψ fn t dq vs :
{{{
▷ Ψ 0 [] ∗
array۰model t dq vs ∗
( [∗ list] i ↦ v ∈ vs,
Ψ i (take i vs) -∗
WP fn #i v {{ res,
⌜res = ()%V⌝ ∗
▷ Ψ ˖i (take i vs ++ [v])
}}
)
}}}
array٠iteri fn t
{{{
RET ();
array۰model t dq vs ∗
Ψ (length vs) vs
}}}.
Lemma array٠iteriーspecーdisentangled Ψ fn t dq vs :
{{{
array۰model t dq vs ∗
□ (
∀ i v,
⌜vs !! i = Some v⌝ -∗
WP fn #i v {{ res,
⌜res = ()%V⌝ ∗
▷ Ψ i v
}}
)
}}}
array٠iteri fn t
{{{
RET ();
array۰model t dq vs ∗
( [∗ list] i ↦ v ∈ vs,
Ψ i v
)
}}}.
Lemma array٠iteriーspecーdisentangled' Ψ fn t dq vs :
{{{
array۰model t dq vs ∗
( [∗ list] i ↦ v ∈ vs,
WP fn #i v {{ res,
⌜res = ()%V⌝ ∗
▷ Ψ i v
}}
)
}}}
array٠iteri fn t
{{{
RET ();
array۰model t dq vs ∗
( [∗ list] i ↦ v ∈ vs,
Ψ i v
)
}}}.
Lemma array٠iterーspecーatomic Ψ fn t sz :
{{{
array۰inv t sz ∗
▷ Ψ 0 [] None ∗
□ (
∀ i vs (o : option val),
⌜i < sz⌝ -∗
⌜i = length vs⌝ -∗
Ψ i vs o -∗
match o with
| None ⇒
au_load t i (λ v,
▷ Ψ i vs (Some v)
)
| Some v ⇒
WP fn v {{ res,
⌜res = ()%V⌝ ∗
▷ Ψ ˖i (vs ++ [v]) None
}}
end
)
}}}
array٠iter fn t
{{{
vs
, RET ();
⌜length vs = sz⌝ ∗
Ψ sz vs None
}}}.
Lemma array٠iterーspec Ψ fn t dq vs :
{{{
▷ Ψ 0 [] ∗
array۰model t dq vs ∗
□ (
∀ i v,
⌜vs !! i = Some v⌝ -∗
Ψ i (take i vs) -∗
WP fn v {{ res,
⌜res = ()%V⌝ ∗
▷ Ψ ˖i (take i vs ++ [v])
}}
)
}}}
array٠iter fn t
{{{
RET ();
array۰model t dq vs ∗
Ψ (length vs) vs
}}}.
Lemma array٠iterーspec' Ψ fn t dq vs :
{{{
▷ Ψ 0 [] ∗
array۰model t dq vs ∗
( [∗ list] i ↦ v ∈ vs,
Ψ i (take i vs) -∗
WP fn v {{ res,
⌜res = ()%V⌝ ∗
▷ Ψ ˖i (take i vs ++ [v])
}}
)
}}}
array٠iter fn t
{{{
RET ();
array۰model t dq vs ∗
Ψ (length vs) vs
}}}.
Lemma array٠iterーspecーdisentangled Ψ fn t dq vs :
{{{
array۰model t dq vs ∗
□ (
∀ i v,
⌜vs !! i = Some v⌝ -∗
WP fn v {{ res,
⌜res = ()%V⌝ ∗
▷ Ψ i v
}}
)
}}}
array٠iter fn t
{{{
RET ();
array۰model t dq vs ∗
( [∗ list] i ↦ v ∈ vs,
Ψ i v
)
}}}.
Lemma array٠iterーspecーdisentangled' Ψ fn t dq vs :
{{{
array۰model t dq vs ∗
( [∗ list] i ↦ v ∈ vs,
WP fn v {{ res,
⌜res = ()%V⌝ ∗
▷ Ψ i v
}}
)
}}}
array٠iter fn t
{{{
RET ();
array۰model t dq vs ∗
( [∗ list] i ↦ v ∈ vs,
Ψ i v
)
}}}.
Lemma array٠unsafe_applyi_sliceーspecーatomic Ψ fn t (sz : nat) (i n : Z) :
(0 ≤ i ≤ sz)%Z →
(0 ≤ n)%Z →
(i + n ≤ sz)%Z →
{{{
array۰inv t sz ∗
▷ Ψ 0 [] None [] ∗
□ (
∀ k vs (o : option (val + val × val)) ws,
⌜k < ₊n⌝ -∗
⌜k = length vs⌝ -∗
⌜length vs = length ws⌝ -∗
Ψ k vs o ws -∗
match o with
| None ⇒
au_load t (₊i + k) (λ v,
▷ Ψ k vs (Some $ inl v) ws
)
| Some (inl v) ⇒
WP fn #k v {{ w,
▷ Ψ k vs (Some $ inr (v, w)) ws
}}
| Some (inr (v, w)) ⇒
au_store t (₊i + k) w (
▷ Ψ ˖k (vs ++ [v]) None (ws ++ [w])
)
end
)
}}}
array٠unsafe_applyi_slice fn t #i #n
{{{
vs ws
, RET ();
⌜length vs = ₊n⌝ ∗
⌜length vs = length ws⌝ ∗
Ψ ₊n vs None ws
}}}.
Lemma array٠unsafe_applyi_sliceーspec Ψ fn t vs (i n : Z) :
(0 ≤ i ≤ length vs)%Z →
(0 ≤ n)%Z →
(i + n ≤ length vs)%Z →
{{{
▷ Ψ 0 [] [] ∗
array۰model t (DfracOwn 1) vs ∗
□ (
∀ k v ws,
⌜k = length ws⌝ -∗
⌜k < ₊n⌝ -∗
⌜vs !! (₊i + k)%nat = Some v⌝ -∗
Ψ k (slice ₊i k vs) ws -∗
WP fn #k v {{ w,
▷ Ψ ˖k (slice ₊i k vs ++ [v]) (ws ++ [w])
}}
)
}}}
array٠unsafe_applyi_slice fn t #i #n
{{{
ws
, RET ();
⌜length ws = ₊n⌝ ∗
array۰model t (DfracOwn 1) (with_slice ₊i ₊n vs ws) ∗
Ψ ₊n (slice ₊i ₊n vs) ws
}}}.
Lemma array٠unsafe_applyi_sliceーspec' Ψ fn t vs (i n : Z) :
(0 ≤ i ≤ length vs)%Z →
(0 ≤ n)%Z →
(i + n ≤ length vs)%Z →
{{{
▷ Ψ 0 [] [] ∗
array۰model t (DfracOwn 1) vs ∗
( [∗ list] k ↦ v ∈ slice ₊i ₊n vs,
∀ ws,
⌜k = length ws⌝ -∗
Ψ k (slice ₊i k vs) ws -∗
WP fn #k v {{ w,
▷ Ψ ˖k (slice ₊i k vs ++ [v]) (ws ++ [w])
}}
)
}}}
array٠unsafe_applyi_slice fn t #i #n
{{{
ws
, RET ();
⌜length ws = ₊n⌝ ∗
array۰model t (DfracOwn 1) (with_slice ₊i ₊n vs ws) ∗
Ψ ₊n (slice ₊i ₊n vs) ws
}}}.
Lemma array٠unsafe_applyi_sliceーspecーdisentangled Ψ fn t vs (i n : Z) :
(0 ≤ i ≤ length vs)%Z →
(0 ≤ n)%Z →
(i + n ≤ length vs)%Z →
{{{
array۰model t (DfracOwn 1) vs ∗
□ (
∀ k v,
⌜k < ₊n⌝ -∗
⌜vs !! (₊i + k)%nat = Some v⌝ -∗
WP fn #k v {{ w,
▷ Ψ k w
}}
)
}}}
array٠unsafe_applyi_slice fn t #i #n
{{{
ws
, RET ();
⌜length ws = ₊n⌝ ∗
array۰model t (DfracOwn 1) (with_slice ₊i ₊n vs ws) ∗
( [∗ list] i ↦ w ∈ ws,
Ψ i w
)
}}}.
Lemma array٠unsafe_applyi_sliceーspecーdisentangled' Ψ fn t vs (i n : Z) :
(0 ≤ i ≤ length vs)%Z →
(0 ≤ n)%Z →
(i + n ≤ length vs)%Z →
{{{
array۰model t (DfracOwn 1) vs ∗
( [∗ list] k ↦ v ∈ slice ₊i ₊n vs,
WP fn #k v {{ w,
▷ Ψ k w
}}
)
}}}
array٠unsafe_applyi_slice fn t #i #n
{{{
ws
, RET ();
array۰model t (DfracOwn 1) (with_slice ₊i ₊n vs ws) ∗
( [∗ list] i ↦ w ∈ ws,
Ψ i w
)
}}}.
Lemma array٠applyi_sliceーspecーatomic Ψ fn t (sz : nat) (i n : Z) :
{{{
array۰inv t sz ∗
▷ Ψ 0 [] None [] ∗
□ (
∀ k vs (o : option (val + val × val)) ws,
⌜k < ₊n⌝ -∗
⌜k = length vs⌝ -∗
⌜length vs = length ws⌝ -∗
Ψ k vs o ws -∗
match o with
| None ⇒
au_load t (₊i + k) (λ v,
▷ Ψ k vs (Some $ inl v) ws
)
| Some (inl v) ⇒
WP fn #k v {{ w,
▷ Ψ k vs (Some $ inr (v, w)) ws
}}
| Some (inr (v, w)) ⇒
au_store t (₊i + k) w (
▷ Ψ ˖k (vs ++ [v]) None (ws ++ [w])
)
end
)
}}}
array٠applyi_slice fn t #i #n
{{{
vs ws
, RET ();
⌜0 ≤ i ≤ sz⌝%Z ∗
⌜0 ≤ n⌝%Z ∗
⌜i + n ≤ sz⌝%Z ∗
⌜length vs = ₊n⌝ ∗
⌜length vs = length ws⌝ ∗
Ψ ₊n vs None ws
}}}.
Lemma array٠applyi_sliceーspec Ψ fn t vs (i n : Z) :
{{{
▷ Ψ 0 [] [] ∗
array۰model t (DfracOwn 1) vs ∗
□ (
∀ k v ws,
⌜k = length ws⌝ -∗
⌜k < ₊n⌝ -∗
⌜vs !! (₊i + k)%nat = Some v⌝ -∗
Ψ k (slice ₊i k vs) ws -∗
WP fn #k v {{ w,
▷ Ψ ˖k (slice ₊i k vs ++ [v]) (ws ++ [w])
}}
)
}}}
array٠applyi_slice fn t #i #n
{{{
ws
, RET ();
⌜0 ≤ i ≤ length vs⌝%Z ∗
⌜0 ≤ n⌝%Z ∗
⌜i + n ≤ length vs⌝%Z ∗
⌜length ws = ₊n⌝ ∗
array۰model t (DfracOwn 1) (with_slice ₊i ₊n vs ws) ∗
Ψ ₊n (slice ₊i ₊n vs) ws
}}}.
Lemma array٠applyi_sliceーspec' Ψ fn t vs (i n : Z) :
{{{
▷ Ψ 0 [] [] ∗
array۰model t (DfracOwn 1) vs ∗
( [∗ list] k ↦ v ∈ slice ₊i ₊n vs,
∀ ws,
⌜k = length ws⌝ -∗
Ψ k (slice ₊i k vs) ws -∗
WP fn #k v {{ w,
▷ Ψ ˖k (slice ₊i k vs ++ [v]) (ws ++ [w])
}}
)
}}}
array٠applyi_slice fn t #i #n
{{{
ws
, RET ();
⌜0 ≤ i ≤ length vs⌝%Z ∗
⌜0 ≤ n⌝%Z ∗
⌜i + n ≤ length vs⌝%Z ∗
⌜length ws = ₊n⌝ ∗
array۰model t (DfracOwn 1) (with_slice ₊i ₊n vs ws) ∗
Ψ ₊n (slice ₊i ₊n vs) ws
}}}.
Lemma array٠applyi_sliceーspecーdisentangled Ψ fn t vs (i n : Z) :
{{{
array۰model t (DfracOwn 1) vs ∗
□ (
∀ k v,
⌜k < ₊n⌝ -∗
⌜vs !! (₊i + k)%nat = Some v⌝ -∗
WP fn #k v {{ w,
▷ Ψ k w
}}
)
}}}
array٠applyi_slice fn t #i #n
{{{
ws
, RET ();
⌜0 ≤ i ≤ length vs⌝%Z ∗
⌜0 ≤ n⌝%Z ∗
⌜i + n ≤ length vs⌝%Z ∗
⌜length ws = ₊n⌝ ∗
array۰model t (DfracOwn 1) (with_slice ₊i ₊n vs ws) ∗
( [∗ list] i ↦ w ∈ ws,
Ψ i w
)
}}}.
Lemma array٠applyi_sliceーspecーdisentangled' Ψ fn t vs (i n : Z) :
{{{
array۰model t (DfracOwn 1) vs ∗
( [∗ list] k ↦ v ∈ slice ₊i ₊n vs,
WP fn #k v {{ w,
▷ Ψ k w
}}
)
}}}
array٠applyi_slice fn t #i #n
{{{
ws
, RET ();
⌜0 ≤ i ≤ length vs⌝%Z ∗
⌜0 ≤ n⌝%Z ∗
⌜i + n ≤ length vs⌝%Z ∗
array۰model t (DfracOwn 1) (with_slice ₊i ₊n vs ws) ∗
( [∗ list] i ↦ w ∈ ws,
Ψ i w
)
}}}.
Lemma array٠unsafe_apply_sliceーspecーatomic Ψ fn t (sz : nat) (i n : Z) :
(0 ≤ i ≤ sz)%Z →
(0 ≤ n)%Z →
(i + n ≤ sz)%Z →
{{{
array۰inv t sz ∗
▷ Ψ 0 [] None [] ∗
□ (
∀ k vs (o : option (val + val × val)) ws,
⌜k < ₊n⌝ -∗
⌜k = length vs⌝ -∗
⌜length vs = length ws⌝ -∗
Ψ k vs o ws -∗
match o with
| None ⇒
au_load t (₊i + k) (λ v,
▷ Ψ k vs (Some $ inl v) ws
)
| Some (inl v) ⇒
WP fn v {{ w,
▷ Ψ k vs (Some $ inr (v, w)) ws
}}
| Some (inr (v, w)) ⇒
au_store t (₊i + k) w (
▷ Ψ ˖k (vs ++ [v]) None (ws ++ [w])
)
end
)
}}}
array٠unsafe_apply_slice fn t #i #n
{{{
vs ws
, RET ();
⌜length vs = ₊n⌝ ∗
⌜length vs = length ws⌝ ∗
Ψ ₊n vs None ws
}}}.
Lemma array٠unsafe_apply_sliceーspec Ψ fn t vs (i n : Z) :
(0 ≤ i ≤ length vs)%Z →
(0 ≤ n)%Z →
(i + n ≤ length vs)%Z →
{{{
▷ Ψ 0 [] [] ∗
array۰model t (DfracOwn 1) vs ∗
□ (
∀ k v ws,
⌜k = length ws⌝ -∗
⌜k < ₊n⌝ -∗
⌜vs !! (₊i + k)%nat = Some v⌝ -∗
Ψ k (slice ₊i k vs) ws -∗
WP fn v {{ w,
▷ Ψ ˖k (slice ₊i k vs ++ [v]) (ws ++ [w])
}}
)
}}}
array٠unsafe_apply_slice fn t #i #n
{{{
ws
, RET ();
⌜length ws = ₊n⌝ ∗
array۰model t (DfracOwn 1) (with_slice ₊i ₊n vs ws) ∗
Ψ ₊n (slice ₊i ₊n vs) ws
}}}.
Lemma array٠unsafe_apply_sliceーspec' Ψ fn t vs (i n : Z) :
(0 ≤ i ≤ length vs)%Z →
(0 ≤ n)%Z →
(i + n ≤ length vs)%Z →
{{{
▷ Ψ 0 [] [] ∗
array۰model t (DfracOwn 1) vs ∗
( [∗ list] k ↦ v ∈ slice ₊i ₊n vs,
∀ ws,
⌜k = length ws⌝ -∗
Ψ k (slice ₊i k vs) ws -∗
WP fn v {{ w,
▷ Ψ ˖k (slice ₊i k vs ++ [v]) (ws ++ [w])
}}
)
}}}
array٠unsafe_apply_slice fn t #i #n
{{{
ws
, RET ();
⌜length ws = ₊n⌝ ∗
array۰model t (DfracOwn 1) (with_slice ₊i ₊n vs ws) ∗
Ψ ₊n (slice ₊i ₊n vs) ws
}}}.
Lemma array٠unsafe_apply_sliceーspecーdisentangled Ψ fn t vs (i n : Z) :
(0 ≤ i ≤ length vs)%Z →
(0 ≤ n)%Z →
(i + n ≤ length vs)%Z →
{{{
array۰model t (DfracOwn 1) vs ∗
□ (
∀ k v,
⌜k < ₊n⌝ -∗
⌜vs !! (₊i + k)%nat = Some v⌝ -∗
WP fn v {{ w,
▷ Ψ k w
}}
)
}}}
array٠unsafe_apply_slice fn t #i #n
{{{
ws
, RET ();
⌜length ws = ₊n⌝ ∗
array۰model t (DfracOwn 1) (with_slice ₊i ₊n vs ws) ∗
( [∗ list] i ↦ w ∈ ws,
Ψ i w
)
}}}.
Lemma array٠unsafe_apply_sliceーspecーdisentangled' Ψ fn t vs (i n : Z) :
(0 ≤ i ≤ length vs)%Z →
(0 ≤ n)%Z →
(i + n ≤ length vs)%Z →
{{{
array۰model t (DfracOwn 1) vs ∗
( [∗ list] k ↦ v ∈ slice ₊i ₊n vs,
WP fn v {{ w,
▷ Ψ k w
}}
)
}}}
array٠unsafe_apply_slice fn t #i #n
{{{
ws
, RET ();
array۰model t (DfracOwn 1) (with_slice ₊i ₊n vs ws) ∗
( [∗ list] i ↦ w ∈ ws,
Ψ i w
)
}}}.
Lemma array٠apply_sliceーspecーatomic Ψ fn t (sz : nat) (i n : Z) :
{{{
array۰inv t sz ∗
▷ Ψ 0 [] None [] ∗
□ (
∀ k vs (o : option (val + val × val)) ws,
⌜k < ₊n⌝ -∗
⌜k = length vs⌝ -∗
⌜length vs = length ws⌝ -∗
Ψ k vs o ws -∗
match o with
| None ⇒
au_load t (₊i + k) (λ v,
▷ Ψ k vs (Some $ inl v) ws
)
| Some (inl v) ⇒
WP fn v {{ w,
▷ Ψ k vs (Some $ inr (v, w)) ws
}}
| Some (inr (v, w)) ⇒
au_store t (₊i + k) w (
▷ Ψ ˖k (vs ++ [v]) None (ws ++ [w])
)
end
)
}}}
array٠apply_slice fn t #i #n
{{{
vs ws
, RET ();
⌜0 ≤ i ≤ sz⌝%Z ∗
⌜0 ≤ n⌝%Z ∗
⌜i + n ≤ sz⌝%Z ∗
⌜length vs = ₊n⌝ ∗
⌜length vs = length ws⌝ ∗
Ψ ₊n vs None ws
}}}.
Lemma array٠apply_sliceーspec Ψ fn t vs (i n : Z) :
{{{
▷ Ψ 0 [] [] ∗
array۰model t (DfracOwn 1) vs ∗
□ (
∀ k v ws,
⌜k = length ws⌝ -∗
⌜k < ₊n⌝ -∗
⌜vs !! (₊i + k)%nat = Some v⌝ -∗
Ψ k (slice ₊i k vs) ws -∗
WP fn v {{ w,
▷ Ψ ˖k (slice ₊i k vs ++ [v]) (ws ++ [w])
}}
)
}}}
array٠apply_slice fn t #i #n
{{{
ws
, RET ();
⌜0 ≤ i ≤ length vs⌝%Z ∗
⌜0 ≤ n⌝%Z ∗
⌜i + n ≤ length vs⌝%Z ∗
⌜length ws = ₊n⌝ ∗
array۰model t (DfracOwn 1) (with_slice ₊i ₊n vs ws) ∗
Ψ ₊n (slice ₊i ₊n vs) ws
}}}.
Lemma array٠apply_sliceーspec' Ψ fn t vs (i n : Z) :
{{{
▷ Ψ 0 [] [] ∗
array۰model t (DfracOwn 1) vs ∗
( [∗ list] k ↦ v ∈ slice ₊i ₊n vs,
∀ ws,
⌜k = length ws⌝ -∗
Ψ k (slice ₊i k vs) ws -∗
WP fn v {{ w,
▷ Ψ ˖k (slice ₊i k vs ++ [v]) (ws ++ [w])
}}
)
}}}
array٠apply_slice fn t #i #n
{{{
ws
, RET ();
⌜0 ≤ i ≤ length vs⌝%Z ∗
⌜0 ≤ n⌝%Z ∗
⌜i + n ≤ length vs⌝%Z ∗
⌜length ws = ₊n⌝ ∗
array۰model t (DfracOwn 1) (with_slice ₊i ₊n vs ws) ∗
Ψ ₊n (slice ₊i ₊n vs) ws
}}}.
Lemma array٠apply_sliceーspecーdisentangled Ψ fn t vs (i n : Z) :
{{{
array۰model t (DfracOwn 1) vs ∗
□ (
∀ k v,
⌜k < ₊n⌝ -∗
⌜vs !! (₊i + k)%nat = Some v⌝ -∗
WP fn v {{ w,
▷ Ψ k w
}}
)
}}}
array٠apply_slice fn t #i #n
{{{
ws
, RET ();
⌜0 ≤ i ≤ length vs⌝%Z ∗
⌜0 ≤ n⌝%Z ∗
⌜i + n ≤ length vs⌝%Z ∗
⌜length ws = ₊n⌝ ∗
array۰model t (DfracOwn 1) (with_slice ₊i ₊n vs ws) ∗
( [∗ list] i ↦ w ∈ ws,
Ψ i w
)
}}}.
Lemma array٠apply_sliceーspecーdisentangled' Ψ fn t vs (i n : Z) :
{{{
array۰model t (DfracOwn 1) vs ∗
( [∗ list] k ↦ v ∈ slice ₊i ₊n vs,
WP fn v {{ w,
▷ Ψ k w
}}
)
}}}
array٠apply_slice fn t #i #n
{{{
ws
, RET ();
⌜0 ≤ i ≤ length vs⌝%Z ∗
⌜0 ≤ n⌝%Z ∗
⌜i + n ≤ length vs⌝%Z ∗
array۰model t (DfracOwn 1) (with_slice ₊i ₊n vs ws) ∗
( [∗ list] i ↦ w ∈ ws,
Ψ i w
)
}}}.
Lemma array٠applyiーspecーatomic Ψ fn t sz :
{{{
array۰inv t sz ∗
▷ Ψ 0 [] None [] ∗
□ (
∀ i vs (o : option (val + val × val)) ws,
⌜i < sz⌝ -∗
⌜i = length vs⌝ -∗
⌜length vs = length ws⌝ -∗
Ψ i vs o ws -∗
match o with
| None ⇒
au_load t i (λ v,
▷ Ψ i vs (Some $ inl v) ws
)
| Some (inl v) ⇒
WP fn #i v {{ w,
▷ Ψ i vs (Some $ inr (v, w)) ws
}}
| Some (inr (v, w)) ⇒
au_store t i w (
▷ Ψ ˖i (vs ++ [v]) None (ws ++ [w])
)
end
)
}}}
array٠applyi fn t
{{{
vs ws
, RET ();
⌜length vs = sz⌝ ∗
⌜length vs = length ws⌝ ∗
Ψ sz vs None ws
}}}.
Lemma array٠applyiーspec Ψ fn t vs :
{{{
▷ Ψ 0 [] [] ∗
array۰model t (DfracOwn 1) vs ∗
□ (
∀ i v ws,
⌜i = length ws⌝ -∗
⌜vs !! i = Some v⌝ -∗
Ψ i (take i vs) ws -∗
WP fn #i v {{ w,
▷ Ψ ˖i (take i vs ++ [v]) (ws ++ [w])
}}
)
}}}
array٠applyi fn t
{{{
ws
, RET ();
⌜length vs = length ws⌝ ∗
array۰model t (DfracOwn 1) ws ∗
Ψ (length vs) vs ws
}}}.
Lemma array٠applyiーspec' Ψ fn t vs :
{{{
▷ Ψ 0 [] [] ∗
array۰model t (DfracOwn 1) vs ∗
( [∗ list] i ↦ v ∈ vs,
∀ ws,
⌜i = length ws⌝ -∗
Ψ i (take i vs) ws -∗
WP fn #i v {{ w,
▷ Ψ ˖i (take i vs ++ [v]) (ws ++ [w])
}}
)
}}}
array٠applyi fn t
{{{
ws
, RET ();
⌜length vs = length ws⌝ ∗
array۰model t (DfracOwn 1) ws ∗
Ψ (length vs) vs ws
}}}.
Lemma array٠applyiーspecーdisentangled Ψ fn t vs :
{{{
array۰model t (DfracOwn 1) vs ∗
□ (
∀ i v,
⌜vs !! i = Some v⌝ -∗
WP fn #i v {{ w,
▷ Ψ i w
}}
)
}}}
array٠applyi fn t
{{{
ws
, RET ();
⌜length vs = length ws⌝ ∗
array۰model t (DfracOwn 1) ws ∗
( [∗ list] i ↦ w ∈ ws,
Ψ i w
)
}}}.
Lemma array٠applyiーspecーdisentangled' Ψ fn t vs :
{{{
array۰model t (DfracOwn 1) vs ∗
( [∗ list] i ↦ v ∈ vs,
WP fn #i v {{ w,
▷ Ψ i w
}}
)
}}}
array٠applyi fn t
{{{
ws
, RET ();
array۰model t (DfracOwn 1) ws ∗
( [∗ list] i ↦ w ∈ ws,
Ψ i w
)
}}}.
Lemma array٠applyーspecーatomic Ψ fn t sz :
{{{
array۰inv t sz ∗
▷ Ψ 0 [] None [] ∗
□ (
∀ i vs (o : option (val + val × val)) ws,
⌜i < sz⌝ -∗
⌜i = length vs⌝ -∗
⌜length vs = length ws⌝ -∗
Ψ i vs o ws -∗
match o with
| None ⇒
au_load t i (λ v,
▷ Ψ i vs (Some $ inl v) ws
)
| Some (inl v) ⇒
WP fn v {{ w,
▷ Ψ i vs (Some $ inr (v, w)) ws
}}
| Some (inr (v, w)) ⇒
au_store t i w (
▷ Ψ ˖i (vs ++ [v]) None (ws ++ [w])
)
end
)
}}}
array٠apply fn t
{{{
vs ws
, RET ();
⌜length vs = sz⌝ ∗
⌜length vs = length ws⌝ ∗
Ψ sz vs None ws
}}}.
Lemma array٠applyーspec Ψ fn t vs :
{{{
▷ Ψ 0 [] [] ∗
array۰model t (DfracOwn 1) vs ∗
□ (
∀ i v ws,
⌜i = length ws⌝ -∗
⌜vs !! i = Some v⌝ -∗
Ψ i (take i vs) ws -∗
WP fn v {{ w,
▷ Ψ ˖i (take i vs ++ [v]) (ws ++ [w])
}}
)
}}}
array٠apply fn t
{{{
ws
, RET ();
⌜length vs = length ws⌝ ∗
array۰model t (DfracOwn 1) ws ∗
Ψ (length vs) vs ws
}}}.
Lemma array٠applyーspec' Ψ fn t vs :
{{{
▷ Ψ 0 [] [] ∗
array۰model t (DfracOwn 1) vs ∗
( [∗ list] i ↦ v ∈ vs,
∀ ws,
⌜i = length ws⌝ -∗
Ψ i (take i vs) ws -∗
WP fn v {{ w,
▷ Ψ ˖i (take i vs ++ [v]) (ws ++ [w])
}}
)
}}}
array٠apply fn t
{{{
ws
, RET ();
⌜length vs = length ws⌝ ∗
array۰model t (DfracOwn 1) ws ∗
Ψ (length vs) vs ws
}}}.
Lemma array٠applyーspecーdisentangled Ψ fn t vs :
{{{
array۰model t (DfracOwn 1) vs ∗
□ (
∀ i v,
⌜vs !! i = Some v⌝ -∗
WP fn v {{ w,
▷ Ψ i w
}}
)
}}}
array٠apply fn t
{{{
ws
, RET ();
⌜length vs = length ws⌝ ∗
array۰model t (DfracOwn 1) ws ∗
( [∗ list] i ↦ w ∈ ws,
Ψ i w
)
}}}.
Lemma array٠applyーspecーdisentangled' Ψ fn t vs :
{{{
array۰model t (DfracOwn 1) vs ∗
( [∗ list] i ↦ v ∈ vs,
WP fn v {{ w,
▷ Ψ i w
}}
)
}}}
array٠apply fn t
{{{
ws
, RET ();
array۰model t (DfracOwn 1) ws ∗
( [∗ list] i ↦ w ∈ ws,
Ψ i w
)
}}}.
Lemma array٠unsafe_initiーspec Ψ sz fn :
(0 ≤ sz)%Z →
{{{
▷ (
∀ t,
|={⊤}=> Ψ t 0 []
) ∗
□ (
∀ t i vs,
⌜i < ₊sz⌝ -∗
⌜i = length vs⌝ -∗
Ψ t i vs -∗
WP fn #i {{ v,
▷ Ψ t ˖i (vs ++ [v])
}}
)
}}}
array٠unsafe_initi #sz fn
{{{
t vs
, RET t;
⌜length vs = ₊sz⌝ ∗
array۰model t (DfracOwn 1) vs ∗
Ψ t ₊sz vs
}}}.
Lemma array٠unsafe_initiーspec' Ψ sz fn :
(0 ≤ sz)%Z →
{{{
▷ (
∀ t,
|={⊤}=> Ψ t 0 []
) ∗
( [∗ list] i ∈ seq 0 ₊sz,
∀ t vs,
⌜i = length vs⌝ -∗
Ψ t i vs -∗
WP fn #i {{ v,
▷ Ψ t ˖i (vs ++ [v])
}}
)
}}}
array٠unsafe_initi #sz fn
{{{
t vs
, RET t;
⌜length vs = ₊sz⌝ ∗
array۰model t (DfracOwn 1) vs ∗
Ψ t ₊sz vs
}}}.
Lemma array٠unsafe_initiーspecーdisentangledーstrong Χ Ψ sz fn :
(0 ≤ sz)%Z →
{{{
▷ (
∀ t,
|={⊤}=> Χ t
) ∗
□ (
∀ t i,
Χ t -∗
⌜i < ₊sz⌝ -∗
WP fn #i {{ v,
Χ t ∗
▷ Ψ t i v
}}
)
}}}
array٠unsafe_initi #sz fn
{{{
t vs
, RET t;
⌜length vs = ₊sz⌝ ∗
array۰model t (DfracOwn 1) vs ∗
Χ t ∗
( [∗ list] i ↦ v ∈ vs,
Ψ t i v
)
}}}.
Lemma array٠unsafe_initiーspecーdisentangled Ψ sz fn :
(0 ≤ sz)%Z →
{{{
□ (
∀ i,
⌜i < ₊sz⌝ -∗
WP fn #i {{ v,
▷ Ψ i v
}}
)
}}}
array٠unsafe_initi #sz fn
{{{
t vs
, RET t;
⌜length vs = ₊sz⌝ ∗
array۰model t (DfracOwn 1) vs ∗
( [∗ list] i ↦ v ∈ vs,
Ψ i v
)
}}}.
Lemma array٠unsafe_initiーspecーdisentangledーstrong' Χ Ψ sz fn :
(0 ≤ sz)%Z →
{{{
▷ (
∀ t,
|={⊤}=> Χ t
) ∗
( [∗ list] i ∈ seq 0 ₊sz,
∀ t,
Χ t -∗
WP fn #i {{ v,
Χ t ∗
▷ Ψ t i v
}}
)
}}}
array٠unsafe_initi #sz fn
{{{
t vs
, RET t;
⌜length vs = ₊sz⌝ ∗
array۰model t (DfracOwn 1) vs ∗
Χ t ∗
( [∗ list] i ↦ v ∈ vs,
Ψ t i v
)
}}}.
Lemma array٠unsafe_initiーspecーdisentangled' Ψ sz fn :
(0 ≤ sz)%Z →
{{{
( [∗ list] i ∈ seq 0 ₊sz,
WP fn #i {{ v,
▷ Ψ i v
}}
)
}}}
array٠unsafe_initi #sz fn
{{{
t vs
, RET t;
⌜length vs = ₊sz⌝ ∗
array۰model t (DfracOwn 1) vs ∗
( [∗ list] i ↦ v ∈ vs,
Ψ i v
)
}}}.
Lemma array٠initiーspec Ψ sz fn :
{{{
▷ (
∀ t,
|={⊤}=> Ψ t 0 []
) ∗
□ (
∀ t i vs,
⌜i < ₊sz⌝ -∗
⌜i = length vs⌝ -∗
Ψ t i vs -∗
WP fn #i {{ v,
▷ Ψ t ˖i (vs ++ [v])
}}
)
}}}
array٠initi #sz fn
{{{
t vs
, RET t;
⌜0 ≤ sz⌝%Z ∗
⌜length vs = ₊sz⌝ ∗
array۰model t (DfracOwn 1) vs ∗
Ψ t ₊sz vs
}}}.
Lemma array٠initiーspec' Ψ sz fn :
{{{
▷ (
∀ t,
|={⊤}=> Ψ t 0 []
) ∗
( [∗ list] i ∈ seq 0 ₊sz,
∀ t vs,
⌜i = length vs⌝ -∗
Ψ t i vs -∗
WP fn #i {{ v,
▷ Ψ t ˖i (vs ++ [v])
}}
)
}}}
array٠initi #sz fn
{{{
t vs
, RET t;
⌜0 ≤ sz⌝%Z ∗
⌜length vs = ₊sz⌝ ∗
array۰model t (DfracOwn 1) vs ∗
Ψ t ₊sz vs
}}}.
Lemma array٠initiーspecーdisentangled Ψ sz fn :
{{{
□ (
∀ i,
⌜i < ₊sz⌝ -∗
WP fn #i {{ v,
▷ Ψ i v
}}
)
}}}
array٠initi #sz fn
{{{
t vs
, RET t;
⌜0 ≤ sz⌝%Z ∗
⌜length vs = ₊sz⌝ ∗
array۰model t (DfracOwn 1) vs ∗
( [∗ list] i ↦ v ∈ vs,
Ψ i v
)
}}}.
Lemma array٠initiーspecーdisentangled' Ψ sz fn :
{{{
( [∗ list] i ∈ seq 0 ₊sz,
WP fn #i {{ v,
▷ Ψ i v
}}
)
}}}
array٠initi #sz fn
{{{
t vs
, RET t;
⌜0 ≤ sz⌝%Z ∗
⌜length vs = ₊sz⌝ ∗
array۰model t (DfracOwn 1) vs ∗
( [∗ list] i ↦ v ∈ vs,
Ψ i v
)
}}}.
Lemma array٠unsafe_initーspec Ψ sz fn :
(0 ≤ sz)%Z →
{{{
▷ (
∀ t,
|={⊤}=> Ψ t 0 []
) ∗
□ (
∀ t i vs,
⌜i < ₊sz⌝ -∗
⌜i = length vs⌝ -∗
Ψ t i vs -∗
WP fn () {{ v,
▷ Ψ t ˖i (vs ++ [v])
}}
)
}}}
array٠unsafe_init #sz fn
{{{
t vs
, RET t;
⌜length vs = ₊sz⌝ ∗
array۰model t (DfracOwn 1) vs ∗
Ψ t ₊sz vs
}}}.
Lemma array٠unsafe_initーspec' Ψ sz fn :
(0 ≤ sz)%Z →
{{{
▷ (
∀ t,
|={⊤}=> Ψ t 0 []
) ∗
( [∗ list] i ∈ seq 0 ₊sz,
∀ t vs,
⌜i = length vs⌝ -∗
Ψ t i vs -∗
WP fn () {{ v,
▷ Ψ t ˖i (vs ++ [v])
}}
)
}}}
array٠unsafe_init #sz fn
{{{
t vs
, RET t;
⌜length vs = ₊sz⌝ ∗
array۰model t (DfracOwn 1) vs ∗
Ψ t ₊sz vs
}}}.
Lemma array٠unsafe_initーspecーdisentangled Ψ sz fn :
(0 ≤ sz)%Z →
{{{
□ (
∀ i,
⌜i < ₊sz⌝ -∗
WP fn () {{ v,
▷ Ψ i v
}}
)
}}}
array٠unsafe_init #sz fn
{{{
t vs
, RET t;
⌜length vs = ₊sz⌝ ∗
array۰model t (DfracOwn 1) vs ∗
( [∗ list] i ↦ v ∈ vs,
Ψ i v
)
}}}.
Lemma array٠unsafe_initーspecーdisentangled' Ψ sz fn :
(0 ≤ sz)%Z →
{{{
( [∗ list] i ∈ seq 0 ₊sz,
WP fn () {{ v,
▷ Ψ i v
}}
)
}}}
array٠unsafe_init #sz fn
{{{
t vs
, RET t;
⌜length vs = ₊sz⌝ ∗
array۰model t (DfracOwn 1) vs ∗
( [∗ list] i ↦ v ∈ vs,
Ψ i v
)
}}}.
Lemma array٠initーspec Ψ sz fn :
{{{
▷ (
∀ t,
|={⊤}=> Ψ t 0 []
) ∗
□ (
∀ t i vs,
⌜i < ₊sz⌝ -∗
⌜i = length vs⌝ -∗
Ψ t i vs -∗
WP fn () {{ v,
▷ Ψ t ˖i (vs ++ [v])
}}
)
}}}
array٠init #sz fn
{{{
t vs
, RET t;
⌜0 ≤ sz⌝%Z ∗
⌜length vs = ₊sz⌝ ∗
array۰model t (DfracOwn 1) vs ∗
Ψ t ₊sz vs
}}}.
Lemma array٠initーspec' Ψ sz fn :
{{{
▷ (
∀ t,
|={⊤}=> Ψ t 0 []
) ∗
( [∗ list] i ∈ seq 0 ₊sz,
∀ t vs,
⌜i = length vs⌝ -∗
Ψ t i vs -∗
WP fn () {{ v,
▷ Ψ t ˖i (vs ++ [v])
}}
)
}}}
array٠init #sz fn
{{{
t vs
, RET t;
⌜0 ≤ sz⌝%Z ∗
⌜length vs = ₊sz⌝ ∗
array۰model t (DfracOwn 1) vs ∗
Ψ t ₊sz vs
}}}.
Lemma array٠initーspecーdisentangled Ψ sz fn :
{{{
□ (
∀ i,
⌜i < ₊sz⌝ -∗
WP fn () {{ v,
▷ Ψ i v
}}
)
}}}
array٠init #sz fn
{{{
t vs
, RET t;
⌜0 ≤ sz⌝%Z ∗
⌜length vs = ₊sz⌝ ∗
array۰model t (DfracOwn 1) vs ∗
( [∗ list] i ↦ v ∈ vs,
Ψ i v
)
}}}.
Lemma array٠initーspecーdisentangled' Ψ sz fn :
{{{
( [∗ list] i ∈ seq 0 ₊sz,
WP fn () {{ v,
▷ Ψ i v
}}
)
}}}
array٠init #sz fn
{{{
t vs
, RET t;
⌜0 ≤ sz⌝%Z ∗
⌜length vs = ₊sz⌝ ∗
array۰model t (DfracOwn 1) vs ∗
( [∗ list] i ↦ v ∈ vs,
Ψ i v
)
}}}.
Lemma array٠mapiーspecーatomic Ψ fn t sz :
{{{
array۰inv t sz ∗
▷ Ψ 0 [] None [] ∗
□ (
∀ i vs (o : option val) ws,
⌜i < sz⌝ -∗
⌜i = length vs⌝ -∗
⌜length vs = length ws⌝ -∗
Ψ i vs o ws -∗
match o with
| None ⇒
au_load t i (λ v,
▷ Ψ i vs (Some v) ws
)
| Some v ⇒
WP fn #i v {{ w,
▷ Ψ ˖i (vs ++ [v]) None (ws ++ [w])
}}
end
)
}}}
array٠mapi fn t
{{{
t' vs ws
, RET t';
⌜length vs = sz⌝ ∗
⌜length vs = length ws⌝ ∗
array۰model t' (DfracOwn 1) ws ∗
Ψ sz vs None ws
}}}.
Lemma array٠mapiーspec Ψ fn t dq vs :
{{{
▷ Ψ 0 [] [] ∗
array۰model t dq vs ∗
□ (
∀ i v ws,
⌜vs !! i = Some v⌝ -∗
⌜i = length ws⌝ -∗
Ψ i (take i vs) ws -∗
WP fn #i v {{ w,
▷ Ψ ˖i (take i vs ++ [v]) (ws ++ [w])
}}
)
}}}
array٠mapi fn t
{{{
t' ws
, RET t';
⌜length ws = length vs⌝ ∗
array۰model t dq vs ∗
array۰model t' (DfracOwn 1) ws ∗
Ψ (length vs) vs ws
}}}.
Lemma array٠mapiーspec' Ψ fn t dq vs :
{{{
▷ Ψ 0 [] [] ∗
array۰model t dq vs ∗
( [∗ list] i ↦ v ∈ vs,
∀ ws,
⌜i = length ws⌝ -∗
Ψ i (take i vs) ws -∗
WP fn #i v {{ w,
▷ Ψ ˖i (take i vs ++ [v]) (ws ++ [w])
}}
)
}}}
array٠mapi fn t
{{{
t' ws
, RET t';
⌜length ws = length vs⌝ ∗
array۰model t dq vs ∗
array۰model t' (DfracOwn 1) ws ∗
Ψ (length vs) vs ws
}}}.
Lemma array٠mapiーspecーdisentangled Ψ fn t dq vs :
{{{
array۰model t dq vs ∗
□ (
∀ i v,
⌜vs !! i = Some v⌝ -∗
WP fn #i v {{ w,
▷ Ψ i v w
}}
)
}}}
array٠mapi fn t
{{{
t' ws
, RET t';
⌜length ws = length vs⌝ ∗
array۰model t dq vs ∗
array۰model t' (DfracOwn 1) ws ∗
( [∗ list] i ↦ v; w ∈ vs; ws,
Ψ i v w
)
}}}.
Lemma array٠mapiーspecーdisentangled' Ψ fn t dq vs :
{{{
array۰model t dq vs ∗
( [∗ list] i ↦ v ∈ vs,
WP fn #i v {{ w,
▷ Ψ i v w
}}
)
}}}
array٠mapi fn t
{{{
t' ws
, RET t';
⌜length ws = length vs⌝ ∗
array۰model t dq vs ∗
array۰model t' (DfracOwn 1) ws ∗
( [∗ list] i ↦ v; w ∈ vs; ws,
Ψ i v w
)
}}}.
Lemma array٠mapーspecーatomic Ψ fn t sz :
{{{
array۰inv t sz ∗
▷ Ψ 0 [] None [] ∗
□ (
∀ i vs (o : option val) ws,
⌜i < ₊sz⌝ -∗
⌜i = length vs⌝ -∗
⌜length vs = length ws⌝ -∗
Ψ i vs o ws -∗
match o with
| None ⇒
au_load t i (λ v,
▷ Ψ i vs (Some v) ws
)
| Some v ⇒
WP fn v {{ w,
▷ Ψ ˖i (vs ++ [v]) None (ws ++ [w])
}}
end
)
}}}
array٠map fn t
{{{
t' vs ws
, RET t';
⌜length vs = sz⌝ ∗
⌜length vs = length ws⌝ ∗
array۰model t' (DfracOwn 1) ws ∗
Ψ sz vs None ws
}}}.
Lemma array٠mapーspec Ψ fn t dq vs :
{{{
▷ Ψ 0 [] [] ∗
array۰model t dq vs ∗
□ (
∀ i v ws,
⌜vs !! i = Some v⌝ -∗
⌜i = length ws⌝ -∗
Ψ i (take i vs) ws -∗
WP fn v {{ w,
▷ Ψ ˖i (take i vs ++ [v]) (ws ++ [w])
}}
)
}}}
array٠map fn t
{{{
t' ws
, RET t';
⌜length ws = length vs⌝ ∗
array۰model t dq vs ∗
array۰model t' (DfracOwn 1) ws ∗
Ψ (length vs) vs ws
}}}.
Lemma array٠mapーspec' Ψ fn t dq vs :
{{{
▷ Ψ 0 [] [] ∗
array۰model t dq vs ∗
( [∗ list] i ↦ v ∈ vs,
∀ ws,
⌜i = length ws⌝ -∗
Ψ i (take i vs) ws -∗
WP fn v {{ w,
▷ Ψ ˖i (take i vs ++ [v]) (ws ++ [w])
}}
)
}}}
array٠map fn t
{{{
t' ws
, RET t';
⌜length ws = length vs⌝ ∗
array۰model t dq vs ∗
array۰model t' (DfracOwn 1) ws ∗
Ψ (length vs) vs ws
}}}.
Lemma array٠mapーspecーdisentangled Ψ fn t dq vs :
{{{
array۰model t dq vs ∗
□ (
∀ i v,
⌜vs !! i = Some v⌝ -∗
WP fn v {{ w,
▷ Ψ i v w
}}
)
}}}
array٠map fn t
{{{
t' ws
, RET t';
⌜length ws = length vs⌝ ∗
array۰model t dq vs ∗
array۰model t' (DfracOwn 1) ws ∗
( [∗ list] i ↦ v; w ∈ vs; ws,
Ψ i v w
)
}}}.
Lemma array٠mapーspecーdisentangled' Ψ fn t dq vs :
{{{
array۰model t dq vs ∗
( [∗ list] i ↦ v ∈ vs,
WP fn v {{ w,
▷ Ψ i v w
}}
)
}}}
array٠map fn t
{{{
t' ws
, RET t';
⌜length ws = length vs⌝ ∗
array۰model t dq vs ∗
array۰model t' (DfracOwn 1) ws ∗
( [∗ list] i ↦ v; w ∈ vs; ws,
Ψ i v w
)
}}}.
Lemma array٠unsafe_copy_sliceーspecーatomic Ψ t1 (i1 : Z) t2 (i2 n : Z) :
(0 ≤ i1)%Z →
(0 ≤ i2)%Z →
(0 ≤ n)%Z →
{{{
▷ Ψ 0 [] None ∗
□ (
∀ k vs o,
⌜k < ₊n⌝ -∗
⌜k = length vs⌝ -∗
Ψ k vs o -∗
match o with
| None ⇒
au_load t1 (₊i1 + k) (λ v,
▷ Ψ k vs (Some v)
)
| Some v ⇒
au_store t2 (₊i2 + k) v (
▷ Ψ ˖k (vs ++ [v]) None
)
end
)
}}}
array٠unsafe_copy_slice t1 #i1 t2 #i2 #n
{{{
vs
, RET ();
⌜length vs = ₊n⌝ ∗
Ψ ₊n vs None
}}}.
Lemma array٠unsafe_copy_sliceーspecーsliceーfit t1 (i1 : Z) i1_ dq1 vs1 t2 (i2 : Z) i2_ vs2 (n : Z) :
i1 = ⁺i1_ →
i2 = ⁺i2_ →
n = length vs1 →
length vs1 = length vs2 →
{{{
array۰slice t1 i1_ dq1 vs1 ∗
array۰slice t2 i2_ (DfracOwn 1) vs2
}}}
array٠unsafe_copy_slice t1 #i1 t2 #i2 #n
{{{
RET ();
array۰slice t1 i1_ dq1 vs1 ∗
array۰slice t2 i2_ (DfracOwn 1) vs1
}}}.
Lemma array٠unsafe_copy_sliceーspecーsliceーfitーsrc t1 (i1 : Z) i1_ dq1 vs1 t2 i2 (j2 : Z) vs2 (n : Z) :
i1 = ⁺i1_ →
(i2 ≤ j2)%Z →
n = length vs1 →
(j2 + n ≤ i2 + length vs2)%Z →
{{{
array۰slice t1 i1_ dq1 vs1 ∗
array۰slice t2 i2 (DfracOwn 1) vs2
}}}
array٠unsafe_copy_slice t1 #i1 t2 #j2 #n
{{{
RET ();
array۰slice t1 i1_ dq1 vs1 ∗
array۰slice t2 i2 (DfracOwn 1) (with_slice (₊j2 - i2) ₊n vs2 vs1)
}}}.
Lemma array٠unsafe_copy_sliceーspecーsliceーfitーdst t1 i1 (j1 : Z) dq1 vs1 t2 (i2 : Z) i2_ vs2 (n : Z) :
(i1 ≤ j1)%Z →
i2 = ⁺i2_ →
n = length vs2 →
(j1 + n ≤ i1 + length vs1)%Z →
{{{
array۰slice t1 i1 dq1 vs1 ∗
array۰slice t2 i2_ (DfracOwn 1) vs2
}}}
array٠unsafe_copy_slice t1 #j1 t2 #i2 #n
{{{
RET ();
array۰slice t1 i1 dq1 vs1 ∗
array۰slice t2 i2_ (DfracOwn 1) (slice (₊j1 - i1) ₊n vs1)
}}}.
Lemma array٠unsafe_copy_sliceーspecーslice t1 i1 (j1 : Z) dq1 vs1 t2 i2 (j2 : Z) vs2 (n : Z) :
(i1 ≤ j1)%Z →
(i2 ≤ j2)%Z →
(0 ≤ n)%Z →
(j1 + n ≤ i1 + length vs1)%Z →
(j2 + n ≤ i2 + length vs2)%Z →
{{{
array۰slice t1 i1 dq1 vs1 ∗
array۰slice t2 i2 (DfracOwn 1) vs2
}}}
array٠unsafe_copy_slice t1 #j1 t2 #j2 #n
{{{
RET ();
array۰slice t1 i1 dq1 vs1 ∗
array۰slice t2 i2 (DfracOwn 1) (with_slice (₊j2 - i2) ₊n vs2 (take ₊n (drop (₊j1 - i1) vs1)))
}}}.
Lemma array٠unsafe_copy_sliceーspec t1 (i1 : Z) dq1 vs1 t2 (i2 : Z) vs2 (n : Z) :
(0 ≤ i1)%Z →
(0 ≤ i2)%Z →
(0 ≤ n)%Z →
(i1 + n ≤ length vs1)%Z →
(i2 + n ≤ length vs2)%Z →
{{{
array۰model t1 dq1 vs1 ∗
array۰model t2 (DfracOwn 1) vs2
}}}
array٠unsafe_copy_slice t1 #i1 t2 #i2 #n
{{{
RET ();
array۰model t1 dq1 vs1 ∗
array۰model t2 (DfracOwn 1) (with_slice ₊i2 ₊n vs2 (take ₊n (drop ₊i1 vs1)))
}}}.
Lemma array٠copy_sliceーspecーsliceーfit t1 sz1 (i1 : Z) i1_ dq1 vs1 t2 sz2 (i2 : Z) i2_ vs2 (n : Z) :
i1_ = ₊i1 →
i2_ = ₊i2 →
{{{
array۰inv t1 sz1 ∗
array۰inv t2 sz2 ∗
( ⌜0 ≤ i1⌝%Z -∗
⌜0 ≤ i2⌝%Z -∗
⌜0 ≤ n⌝%Z -∗
⌜i1 + n ≤ sz1⌝%Z -∗
⌜i2 + n ≤ sz2⌝%Z -∗
⌜₊n = length vs1⌝ ∗
⌜length vs1 = length vs2⌝ ∗
array۰slice t1 i1_ dq1 vs1 ∗
array۰slice t2 i2_ (DfracOwn 1) vs2
)
}}}
array٠copy_slice t1 #i1 t2 #i2 #n
{{{
RET ();
⌜0 ≤ i1⌝%Z ∗
⌜0 ≤ i2⌝%Z ∗
⌜0 ≤ n⌝%Z ∗
⌜i1 + n ≤ sz1⌝%Z ∗
⌜i2 + n ≤ sz2⌝%Z ∗
array۰slice t1 i1_ dq1 vs1 ∗
array۰slice t2 i2_ (DfracOwn 1) vs1
}}}.
Lemma array٠copy_sliceーspecーslice t1 sz1 i1 (j1 : Z) dq1 vs1 t2 sz2 i2 (j2 : Z) vs2 (n : Z) :
{{{
array۰inv t1 sz1 ∗
array۰inv t2 sz2 ∗
( ⌜0 ≤ j1⌝%Z -∗
⌜0 ≤ j2⌝%Z -∗
⌜0 ≤ n⌝%Z -∗
⌜j1 + n ≤ sz1⌝%Z -∗
⌜j2 + n ≤ sz2⌝%Z -∗
⌜i1 ≤ ₊j1⌝ ∗
⌜i2 ≤ ₊j2⌝ ∗
⌜₊j1 + n ≤ i1 + length vs1⌝%Z ∗
⌜₊j2 + n ≤ i2 + length vs2⌝%Z ∗
array۰slice t1 i1 dq1 vs1 ∗
array۰slice t2 i2 (DfracOwn 1) vs2
)
}}}
array٠copy_slice t1 #j1 t2 #j2 #n
{{{
RET ();
⌜0 ≤ j1⌝%Z ∗
⌜0 ≤ j2⌝%Z ∗
⌜0 ≤ n⌝%Z ∗
⌜j1 + n ≤ sz1⌝%Z ∗
⌜j2 + n ≤ sz2⌝%Z ∗
array۰slice t1 i1 dq1 vs1 ∗
array۰slice t2 i2 (DfracOwn 1) (with_slice (₊j2 - i2) ₊n vs2 (take ₊n (drop (₊j1 - i1) vs1)))
}}}.
Lemma array٠copy_sliceーspec t1 (i1 : Z) dq1 vs1 t2 (i2 : Z) vs2 (n : Z) :
{{{
array۰model t1 dq1 vs1 ∗
array۰model t2 (DfracOwn 1) vs2
}}}
array٠copy_slice t1 #i1 t2 #i2 #n
{{{
RET ();
⌜0 ≤ i1⌝%Z ∗
⌜0 ≤ i2⌝%Z ∗
⌜0 ≤ n⌝%Z ∗
⌜i1 + n ≤ length vs1⌝%Z ∗
⌜i2 + n ≤ length vs2⌝%Z ∗
array۰model t1 dq1 vs1 ∗
array۰model t2 (DfracOwn 1) (with_slice ₊i2 ₊n vs2 (take ₊n (drop ₊i1 vs1)))
}}}.
Lemma array٠unsafe_copyーspecーatomic Ψ t1 sz1 t2 sz2 (i2 : Z) :
(0 ≤ i2)%Z →
{{{
array۰inv t1 sz1 ∗
array۰inv t2 sz2 ∗
▷ Ψ 0 [] None ∗
□ (
∀ k vs o,
⌜k < sz1⌝ -∗
⌜k = length vs⌝ -∗
Ψ k vs o -∗
match o with
| None ⇒
au_load t1 k (λ v,
▷ Ψ k vs (Some v)
)
| Some v ⇒
au_store t2 (₊i2 + k) v (
▷ Ψ ˖k (vs ++ [v]) None
)
end
)
}}}
array٠unsafe_copy t1 t2 #i2
{{{
vs
, RET ();
⌜length vs = sz1⌝ ∗
Ψ sz1 vs None
}}}.
Lemma array٠unsafe_copyーspecーsliceーfit t1 dq1 vs1 t2 (i2 : Z) i2_ vs2 :
i2 = ⁺i2_ →
length vs1 = length vs2 →
{{{
array۰model t1 dq1 vs1 ∗
array۰slice t2 i2_ (DfracOwn 1) vs2
}}}
array٠unsafe_copy t1 t2 #i2
{{{
RET ();
array۰model t1 dq1 vs1 ∗
array۰slice t2 i2_ (DfracOwn 1) vs1
}}}.
Lemma array٠unsafe_copyーspecーslice t1 dq1 vs1 t2 i2 (j2 : Z) vs2 :
(i2 ≤ j2)%Z →
(j2 + length vs1 ≤ i2 + length vs2)%Z →
{{{
array۰model t1 dq1 vs1 ∗
array۰slice t2 i2 (DfracOwn 1) vs2
}}}
array٠unsafe_copy t1 t2 #j2
{{{
RET ();
array۰model t1 dq1 vs1 ∗
array۰slice t2 i2 (DfracOwn 1) (with_slice (₊j2 - i2) (length vs1) vs2 vs1)
}}}.
Lemma array٠unsafe_copyーspec t1 dq1 vs1 t2 (i2 : Z) vs2 :
(0 ≤ i2)%Z →
(i2 + length vs1 ≤ length vs2)%Z →
{{{
array۰model t1 dq1 vs1 ∗
array۰model t2 (DfracOwn 1) vs2
}}}
array٠unsafe_copy t1 t2 #i2
{{{
RET ();
array۰model t1 dq1 vs1 ∗
array۰model t2 (DfracOwn 1) (with_slice ₊i2 (length vs1) vs2 vs1)
}}}.
Lemma array٠copyーspecーsliceーfit t1 dq1 vs1 t2 sz2 (i2 : Z) i2_ vs2 :
i2_ = ₊i2 →
{{{
array۰model t1 dq1 vs1 ∗
array۰inv t2 sz2 ∗
( ⌜0 ≤ i2⌝%Z -∗
⌜i2 + length vs1 ≤ sz2⌝%Z -∗
⌜length vs1 = length vs2⌝ ∗
array۰slice t2 i2_ (DfracOwn 1) vs2
)
}}}
array٠copy t1 t2 #i2
{{{
RET ();
⌜0 ≤ i2⌝%Z ∗
⌜i2 + length vs1 ≤ sz2⌝%Z ∗
array۰model t1 dq1 vs1 ∗
array۰slice t2 i2_ (DfracOwn 1) vs1
}}}.
Lemma array٠copyーspecーslice t1 dq1 vs1 t2 sz2 i2 (j2 : Z) vs2 :
{{{
array۰model t1 dq1 vs1 ∗
array۰inv t2 sz2 ∗
( ⌜0 ≤ j2⌝%Z -∗
⌜j2 + length vs1 ≤ sz2⌝%Z -∗
⌜i2 ≤ j2⌝%Z ∗
⌜j2 + length vs1 ≤ i2 + length vs2⌝%Z ∗
array۰slice t2 i2 (DfracOwn 1) vs2
)
}}}
array٠copy t1 t2 #j2
{{{
RET ();
⌜0 ≤ i2⌝ ∗
⌜i2 + length vs1 ≤ sz2⌝ ∗
array۰model t1 dq1 vs1 ∗
array۰slice t2 i2 (DfracOwn 1) (with_slice (₊j2 - i2) (length vs1) vs2 vs1)
}}}.
Lemma array٠copyーspec t1 dq1 vs1 t2 (i2 : Z) vs2 :
{{{
array۰model t1 dq1 vs1 ∗
array۰model t2 (DfracOwn 1) vs2
}}}
array٠copy t1 t2 #i2
{{{
RET ();
⌜0 ≤ i2⌝%Z ∗
⌜i2 + length vs1 ≤ length vs2⌝%Z ∗
array۰model t1 dq1 vs1 ∗
array۰model t2 (DfracOwn 1) (with_slice ₊i2 (length vs1) vs2 vs1)
}}}.
Lemma array٠unsafe_growーspec t dq vs sz' v' :
(length vs ≤ sz')%Z →
{{{
array۰model t dq vs
}}}
array٠unsafe_grow t #sz' v'
{{{
t'
, RET t';
array۰model t dq vs ∗
array۰model t' (DfracOwn 1) (vs ++ replicate (₊sz' - length vs) v')
}}}.
Lemma array٠growーspec t dq vs sz' v' :
{{{
array۰model t dq vs
}}}
array٠grow t #sz' v'
{{{
t'
, RET t';
⌜length vs ≤ sz'⌝%Z ∗
array۰model t dq vs ∗
array۰model t' (DfracOwn 1) (vs ++ replicate (₊sz' - length vs) v')
}}}.
Lemma array٠unsafe_subーspecーsliceーfit t dq vs (i : Z) i_ (n : Z) :
i = ⁺i_ →
n = length vs →
{{{
array۰slice t i_ dq vs
}}}
array٠unsafe_sub t #i #n
{{{
t'
, RET t';
array۰slice t i_ dq vs ∗
array۰model t' (DfracOwn 1) (take ₊n vs)
}}}.
Lemma array٠unsafe_subーspecーslice t dq vs i (j n : Z) :
(i ≤ j)%Z →
(0 ≤ n)%Z →
(j + n ≤ i + length vs)%Z →
{{{
array۰slice t i dq vs
}}}
array٠unsafe_sub t #j #n
{{{
t'
, RET t';
array۰slice t i dq vs ∗
array۰model t' (DfracOwn 1) (take ₊n (drop (₊j - ₊i) vs))
}}}.
Lemma array٠unsafe_subーspec t dq vs (i n : Z) :
(0 ≤ i)%Z →
(0 ≤ n)%Z →
(i + n ≤ length vs)%Z →
{{{
array۰model t dq vs
}}}
array٠unsafe_sub t #i #n
{{{
t'
, RET t';
array۰model t dq vs ∗
array۰model t' (DfracOwn 1) (take ₊n (drop ₊i vs))
}}}.
Lemma array٠subーspecーsliceーfit t sz dq vs (i : Z) i_ (n : Z) :
i_ = ₊i →
{{{
array۰inv t sz ∗
( ⌜0 ≤ i⌝%Z -∗
⌜0 ≤ n⌝%Z -∗
⌜i + n ≤ sz⌝%Z -∗
⌜₊n = length vs⌝ ∗
array۰slice t i_ dq vs
)
}}}
array٠sub t #i #n
{{{
t'
, RET t';
⌜0 ≤ i⌝%Z ∗
⌜0 ≤ n⌝%Z ∗
⌜i + n ≤ sz⌝%Z ∗
array۰slice t i_ dq vs ∗
array۰model t' (DfracOwn 1) (take ₊n vs)
}}}.
Lemma array٠subーspecーslice t sz dq vs i (j n : Z) :
{{{
array۰inv t sz ∗
( ⌜0 ≤ j⌝%Z -∗
⌜0 ≤ n⌝%Z -∗
⌜j + n ≤ sz⌝%Z -∗
⌜i ≤ ₊j⌝ ∗
⌜₊j + ₊n ≤ i + length vs⌝ ∗
array۰slice t i dq vs
)
}}}
array٠sub t #j #n
{{{
t'
, RET t';
⌜0 ≤ j⌝%Z ∗
⌜0 ≤ n⌝%Z ∗
⌜j + n ≤ sz⌝%Z ∗
array۰slice t i dq vs ∗
array۰model t' (DfracOwn 1) (take ₊n (drop (₊j - ₊i) vs))
}}}.
Lemma array٠subーspec t dq vs (i n : Z) :
{{{
array۰model t dq vs
}}}
array٠sub t #i #n
{{{
t'
, RET t';
⌜0 ≤ i⌝%Z ∗
⌜0 ≤ n⌝%Z ∗
⌜i + n ≤ length vs⌝%Z ∗
array۰model t dq vs ∗
array۰model t' (DfracOwn 1) (take ₊n (drop ₊i vs))
}}}.
Lemma array٠unsafe_shrinkーspec t dq vs (n : Z) :
(0 ≤ n ≤ length vs)%Z →
{{{
array۰model t dq vs
}}}
array٠unsafe_shrink t #n
{{{
t'
, RET t';
array۰model t dq vs ∗
array۰model t' (DfracOwn 1) (take ₊n vs)
}}}.
Lemma array٠shrinkーspec t dq vs (n : Z) :
{{{
array۰model t dq vs
}}}
array٠shrink t #n
{{{
t'
, RET t';
⌜0 ≤ n ≤ length vs⌝%Z ∗
array۰model t dq vs ∗
array۰model t' (DfracOwn 1) (take ₊n vs)
}}}.
Lemma array٠cloneーspec t dq vs :
{{{
array۰model t dq vs
}}}
array٠clone t
{{{
t'
, RET t';
array۰model t dq vs ∗
array۰model t' (DfracOwn 1) vs
}}}.
Lemma array٠unsafe_cgetーspecーatomic t (j : Z) :
<<<
True
| ∀∀ sz i dq vs v,
⌜(i ≤ j)%Z⌝ ∗
⌜vs !! (₊j - i) = Some v⌝ ∗
array۰cslice t sz i dq vs
>>>
array٠unsafe_cget t #j
<<<
array۰cslice t sz i dq vs
| RET v;
£ 1
>>>.
Lemma array٠unsafe_cgetーspecーatomicーweak t (i : Z) :
(0 ≤ i)%Z →
<<<
True
| ∀∀ sz j dq vs,
array۰cslice t sz j dq vs ∗
⌜0 < sz⌝ ∗
⌜length vs = sz⌝
>>>
array٠unsafe_cget t #i
<<<
array۰cslice t sz j dq vs
| v,
RET v;
£ 1
>>>.
Lemma array٠unsafe_cgetーspecーatomicーcell t sz (i : Z) :
<<<
True
| ∀∀ i_ dq v,
⌜i = ⁺i_⌝ ∗
array۰cslice t sz i_ dq [v]
>>>
array٠unsafe_cget t #i
<<<
array۰cslice t sz i_ dq [v]
| RET v;
£ 1
>>>.
Lemma array٠unsafe_cgetーspec k v t sz i dq vs (j : Z) :
(i ≤ j)%Z →
vs !! k = Some v →
k = ₊j - i →
{{{
array۰cslice t sz i dq vs
}}}
array٠unsafe_cget t #j
{{{
RET v;
array۰cslice t sz i dq vs
}}}.
Lemma array٠unsafe_cgetーspecーcell t sz (i : Z) i_ dq v :
i = ⁺i_ →
{{{
array۰cslice t sz i_ dq [v]
}}}
array٠unsafe_cget t #i
{{{
RET v;
array۰cslice t sz i_ dq [v]
}}}.
Lemma array٠unsafe_cgetーspecーmodel v t dq vs (j : Z) :
(0 ≤ j)%Z →
vs !! (₊j `mod` length vs) = Some v →
{{{
array۰model t dq vs
}}}
array٠unsafe_cget t #j
{{{
RET v;
array۰model t dq vs
}}}.
Lemma array٠cgetーspecーatomic t sz (j : Z) :
<<<
array۰inv t sz
| ∀∀ dq vs i v,
⌜0 ≤ j⌝%Z -∗
⌜0 < sz⌝%Z -∗
⌜i ≤ ₊j⌝ ∗
⌜vs !! (₊j - i) = Some v⌝ ∗
array۰cslice t sz i dq vs
>>>
array٠cget t #j
<<<
array۰cslice t sz i dq vs
| RET v;
⌜0 ≤ j⌝%Z ∗
⌜0 < sz⌝%Z ∗
£ 1
>>>.
Lemma array٠cgetーspecーatomicーweak t sz (i : Z) :
<<<
array۰inv t sz
| ∀∀ j dq vs,
array۰cslice t sz j dq vs ∗
⌜length vs = sz⌝
>>>
array٠cget t #i
<<<
array۰cslice t sz j dq vs
| v,
RET v;
£ 1
>>>.
Lemma array٠cgetーspecーatomicーcell t sz (i : Z) i_ :
i_ = ₊i →
<<<
array۰inv t sz
| ∀∀ dq v,
⌜0 ≤ i⌝%Z -∗
⌜0 < sz⌝%Z -∗
array۰cslice t sz i_ dq [v]
>>>
array٠cget t #i
<<<
array۰cslice t sz i_ dq [v]
| RET v;
⌜0 ≤ i⌝%Z ∗
⌜0 < sz⌝%Z ∗
£ 1
>>>.
Lemma array٠cgetーspec k v t sz i dq vs (j : Z) :
{{{
array۰inv t sz ∗
( ⌜0 < sz⌝ -∗
⌜0 ≤ j⌝%Z -∗
⌜i ≤ ₊j⌝ ∗
⌜vs !! k = Some v⌝ ∗
⌜k = ₊j - i⌝ ∗
array۰cslice t sz i dq vs
)
}}}
array٠cget t #j
{{{
RET v;
⌜0 < sz⌝ ∗
⌜0 ≤ j⌝%Z ∗
array۰cslice t sz i dq vs
}}}.
Lemma array٠cgetーspecーcell t sz (i : Z) i_ dq v :
i_ = ₊i →
{{{
array۰inv t sz ∗
( ⌜0 < sz⌝ -∗
⌜0 ≤ i⌝%Z -∗
array۰cslice t sz i_ dq [v]
)
}}}
array٠cget t #i
{{{
RET v;
⌜0 < sz⌝ ∗
⌜0 ≤ i⌝%Z ∗
array۰cslice t sz i_ dq [v]
}}}.
Lemma array٠cgetーspecーmodel v t dq vs (j : Z) :
vs !! (₊j `mod` length vs) = Some v →
{{{
array۰model t dq vs
}}}
array٠cget t #j
{{{
RET v;
array۰model t dq vs
}}}.
Lemma array٠unsafe_csetーspecーatomic t (j : Z) v :
<<<
True
| ∀∀ sz i vs,
⌜i ≤ j < i + length vs⌝%Z ∗
array۰cslice t sz i (DfracOwn 1) vs
>>>
array٠unsafe_cset t #j v
<<<
array۰cslice t sz i (DfracOwn 1) (<[₊j - i := v]> vs)
| RET ();
£ 1
>>>.
Lemma array٠unsafe_csetーspecーatomicーcell t sz (i : Z) v :
<<<
True
| ∀∀ i_ w,
⌜i = ⁺i_⌝ ∗
array۰cslice t sz i_ (DfracOwn 1) [w]
>>>
array٠unsafe_cset t #i v
<<<
array۰cslice t sz i_ (DfracOwn 1) [v]
| RET ();
£ 1
>>>.
Lemma array٠unsafe_csetーspec t sz i vs (j : Z) v :
(i ≤ j < i + length vs)%Z →
{{{
array۰cslice t sz i (DfracOwn 1) vs
}}}
array٠unsafe_cset t #j v
{{{
RET ();
array۰cslice t sz i (DfracOwn 1) (<[₊j - i := v]> vs)
}}}.
Lemma array٠unsafe_csetーspecーcell t sz (i : Z) i_ w v :
i = ⁺i_ →
{{{
array۰cslice t sz i_ (DfracOwn 1) [w]
}}}
array٠unsafe_cset t #i v
{{{
RET ();
array۰cslice t sz i_ (DfracOwn 1) [v]
}}}.
Lemma array٠unsafe_csetーspecーmodel t vs (j : Z) v :
0 < length vs →
(0 ≤ j)%Z →
{{{
array۰model t (DfracOwn 1) vs
}}}
array٠unsafe_cset t #j v
{{{
RET ();
array۰model t (DfracOwn 1) (<[₊j `mod` length vs := v]> vs)
}}}.
Lemma array٠csetーspecーatomic t sz (j : Z) v :
<<<
array۰inv t sz
| ∀∀ vs i,
⌜0 < sz⌝ -∗
⌜0 ≤ j⌝%Z -∗
⌜i ≤ ₊j < i + length vs⌝ ∗
array۰cslice t sz i (DfracOwn 1) vs
>>>
array٠cset t #j v
<<<
array۰cslice t sz i (DfracOwn 1) (<[₊j - i := v]> vs)
| RET ();
⌜0 < sz⌝ ∗
⌜0 ≤ j⌝%Z ∗
£ 1
>>>.
Lemma array٠csetーspecーatomicーcell t sz (i : Z) i_ v :
i_ = ₊i →
<<<
array۰inv t sz
| ∀∀ w,
⌜0 < sz⌝ -∗
⌜0 ≤ i⌝%Z -∗
array۰cslice t sz i_ (DfracOwn 1) [w]
>>>
array٠cset t #i v
<<<
array۰cslice t sz i_ (DfracOwn 1) [v]
| RET ();
⌜0 < sz⌝ ∗
⌜0 ≤ i⌝%Z ∗
£ 1
>>>.
Lemma array٠csetーspec t sz i vs (j : Z) v :
{{{
array۰inv t sz ∗
( ⌜0 < sz⌝ -∗
⌜0 ≤ j⌝%Z -∗
⌜i ≤ ₊j < i + length vs⌝ ∗
array۰cslice t sz i (DfracOwn 1) vs
)
}}}
array٠cset t #j v
{{{
RET ();
⌜0 < sz⌝ ∗
⌜0 ≤ j⌝%Z ∗
array۰cslice t sz i (DfracOwn 1) (<[₊j - i := v]> vs)
}}}.
Lemma array٠csetーspecーcell t sz (i : Z) i_ w v :
i_ = ₊i →
{{{
array۰inv t sz ∗
( ⌜0 < sz⌝ -∗
⌜0 ≤ i⌝%Z -∗
array۰cslice t sz i_ (DfracOwn 1) [w]
)
}}}
array٠cset t #i v
{{{
RET ();
⌜0 < sz⌝ ∗
⌜0 ≤ i⌝%Z ∗
array۰cslice t sz i_ (DfracOwn 1) [v]
}}}.
Lemma array٠csetーspecーmodel t vs (j : Z) v :
{{{
array۰model t (DfracOwn 1) vs
}}}
array٠cset t #j v
{{{
RET ();
array۰model t (DfracOwn 1) (<[₊j `mod` length vs := v]> vs)
}}}.
#[local] Lemma array٠unsafe_ccopy_slice₁ーspec t1 (i1 : Z) i1_ dq1 vs1 t2 sz2 (i2 : Z) i2_ vs2 (n : Z) :
0 < sz2 →
i1 = ⁺i1_ →
i2 = ⁺i2_ →
n = length vs1 →
length vs1 = length vs2 →
{{{
array۰slice t1 i1_ dq1 vs1 ∗
array۰cslice t2 sz2 i2_ (DfracOwn 1) vs2
}}}
array٠unsafe_ccopy_slice₁ t1 #i1 t2 #i2 #n
{{{
RET ();
array۰slice t1 i1_ dq1 vs1 ∗
array۰cslice t2 sz2 i2_ (DfracOwn 1) vs1
}}}.
Lemma array٠unsafe_ccopy_sliceーspecーfit t1 sz1 (i1 : Z) i1_ dq1 vs1 t2 sz2 (i2 : Z) i2_ vs2 (n : Z) :
0 < sz1 →
length vs1 ≤ sz1 →
0 < sz2 →
i1 = ⁺i1_ →
i2 = ⁺i2_ →
n = length vs1 →
length vs1 = length vs2 →
{{{
array۰cslice t1 sz1 i1_ dq1 vs1 ∗
array۰cslice t2 sz2 i2_ (DfracOwn 1) vs2
}}}
array٠unsafe_ccopy_slice t1 #i1 t2 #i2 #n
{{{
RET ();
array۰cslice t1 sz1 i1_ dq1 vs1 ∗
array۰cslice t2 sz2 i2_ (DfracOwn 1) vs1
}}}.
Lemma array٠unsafe_ccopy_sliceーspecーfitーsrc t1 sz1 (i1 : Z) i1_ dq1 vs1 t2 sz2 i2 (j2 : Z) vs2 (n : Z) :
0 < sz1 →
length vs1 ≤ sz1 →
0 < sz2 →
i1 = ⁺i1_ →
(i2 ≤ j2)%Z →
n = length vs1 →
(j2 + n ≤ i2 + length vs2)%Z →
{{{
array۰cslice t1 sz1 i1_ dq1 vs1 ∗
array۰cslice t2 sz2 i2 (DfracOwn 1) vs2
}}}
array٠unsafe_ccopy_slice t1 #i1 t2 #j2 #n
{{{
RET ();
array۰cslice t1 sz1 i1_ dq1 vs1 ∗
array۰cslice t2 sz2 i2 (DfracOwn 1) (with_slice (₊j2 - i2) ₊n vs2 vs1)
}}}.
Lemma array٠unsafe_ccopy_sliceーspecーfitーdst t1 sz1 i1 (j1 : Z) dq1 vs1 t2 sz2 (i2 : Z) i2_ vs2 (n : Z) :
0 < sz1 →
length vs1 ≤ sz1 →
0 < sz2 →
(i1 ≤ j1)%Z →
i2 = ⁺i2_ →
n = length vs2 →
(j1 + n ≤ i1 + length vs1)%Z →
{{{
array۰cslice t1 sz1 i1 dq1 vs1 ∗
array۰cslice t2 sz2 i2_ (DfracOwn 1) vs2
}}}
array٠unsafe_ccopy_slice t1 #j1 t2 #i2 #n
{{{
RET ();
array۰cslice t1 sz1 i1 dq1 vs1 ∗
array۰cslice t2 sz2 i2_ (DfracOwn 1) (slice (₊j1 - i1) ₊n vs1)
}}}.
Lemma array٠unsafe_ccopy_sliceーspec t1 sz1 i1 (j1 : Z) dq1 vs1 t2 sz2 i2 (j2 : Z) vs2 (n : Z) :
0 < sz1 →
length vs1 ≤ sz1 →
0 < sz2 →
(i1 ≤ j1)%Z →
(i2 ≤ j2)%Z →
(0 ≤ n)%Z →
(j1 + n ≤ i1 + length vs1)%Z →
(j2 + n ≤ i2 + length vs2)%Z →
{{{
array۰cslice t1 sz1 i1 dq1 vs1 ∗
array۰cslice t2 sz2 i2 (DfracOwn 1) vs2
}}}
array٠unsafe_ccopy_slice t1 #j1 t2 #j2 #n
{{{
RET ();
array۰cslice t1 sz1 i1 dq1 vs1 ∗
array۰cslice t2 sz2 i2 (DfracOwn 1) (with_slice (₊j2 - i2) ₊n vs2 (take ₊n (drop (₊j1 - i1) vs1)))
}}}.
Lemma array٠ccopy_sliceーspecーfit t1 sz1 (i1 : Z) i1_ dq1 vs1 t2 sz2 (i2 : Z) i2_ vs2 (n : Z) :
i1_ = ₊i1 →
i2_ = ₊i2 →
{{{
array۰inv t1 sz1 ∗
array۰inv t2 sz2 ∗
( ⌜0 < sz1⌝ -∗
⌜0 < sz2⌝ -∗
⌜0 ≤ i1⌝%Z -∗
⌜0 ≤ i2⌝%Z -∗
⌜0 ≤ n⌝%Z -∗
⌜n ≤ sz1⌝%Z -∗
⌜n ≤ sz2⌝%Z -∗
⌜₊n = length vs1⌝ ∗
⌜length vs1 = length vs2⌝ ∗
array۰cslice t1 sz1 i1_ dq1 vs1 ∗
array۰cslice t2 sz2 i2_ (DfracOwn 1) vs2
)
}}}
array٠ccopy_slice t1 #i1 t2 #i2 #n
{{{
RET ();
⌜0 < sz1⌝ ∗
⌜0 < sz2⌝ ∗
⌜0 ≤ i1⌝%Z ∗
⌜0 ≤ i2⌝%Z ∗
⌜0 ≤ n⌝%Z ∗
⌜n ≤ sz1⌝%Z ∗
⌜n ≤ sz2⌝%Z ∗
array۰cslice t1 sz1 i1_ dq1 vs1 ∗
array۰cslice t2 sz2 i2_ (DfracOwn 1) vs1
}}}.
Lemma array٠ccopy_sliceーspec t1 sz1 i1 (j1 : Z) dq1 vs1 t2 sz2 i2 (j2 : Z) vs2 (n : Z) :
{{{
array۰inv t1 sz1 ∗
array۰inv t2 sz2 ∗
( ⌜0 < sz1⌝ -∗
⌜0 < sz2⌝ -∗
⌜0 ≤ j1⌝%Z -∗
⌜0 ≤ j2⌝%Z -∗
⌜0 ≤ n⌝%Z -∗
⌜n ≤ sz1⌝%Z -∗
⌜n ≤ sz2⌝%Z -∗
⌜length vs1 ≤ sz1⌝ ∗
⌜i1 ≤ ₊j1⌝ ∗
⌜i2 ≤ ₊j2⌝ ∗
⌜₊j1 + n ≤ i1 + length vs1⌝%Z ∗
⌜₊j2 + n ≤ i2 + length vs2⌝%Z ∗
array۰cslice t1 sz1 i1 dq1 vs1 ∗
array۰cslice t2 sz2 i2 (DfracOwn 1) vs2
)
}}}
array٠ccopy_slice t1 #j1 t2 #j2 #n
{{{
RET ();
⌜0 < sz1⌝ ∗
⌜0 < sz2⌝ ∗
⌜0 ≤ j1⌝%Z ∗
⌜0 ≤ j2⌝%Z ∗
⌜0 ≤ n⌝%Z ∗
⌜n ≤ sz1⌝%Z ∗
⌜n ≤ sz2⌝%Z ∗
array۰cslice t1 sz1 i1 dq1 vs1 ∗
array۰cslice t2 sz2 i2 (DfracOwn 1) (with_slice (₊j2 - i2) ₊n vs2 (take ₊n (drop (₊j1 - i1) vs1)))
}}}.
Lemma array٠unsafe_ccopyーspecーfit t1 sz1 (i1 : Z) i1_ dq1 vs1 t2 sz2 (i2 : Z) i2_ vs2 :
0 < sz1 →
0 < sz2 →
i1 = ⁺i1_ →
i2 = ⁺i2_ →
length vs1 = sz1 →
length vs1 = length vs2 →
{{{
array۰cslice t1 sz1 i1_ dq1 vs1 ∗
array۰cslice t2 sz2 i2_ (DfracOwn 1) vs2
}}}
array٠unsafe_ccopy t1 #i1 t2 #i2
{{{
RET ();
array۰cslice t1 sz1 i1_ dq1 vs1 ∗
array۰cslice t2 sz2 i2_ (DfracOwn 1) vs1
}}}.
Lemma array٠unsafe_ccopyーspec t1 sz1 (i1 : Z) i1_ dq1 vs1 t2 sz2 i2 (j2 : Z) vs2 :
0 < sz1 →
0 < sz2 →
i1 = ⁺i1_ →
length vs1 = sz1 →
(i2 ≤ j2)%Z →
(j2 + length vs1 ≤ i2 + length vs2)%Z →
{{{
array۰cslice t1 sz1 i1_ dq1 vs1 ∗
array۰cslice t2 sz2 i2 (DfracOwn 1) vs2
}}}
array٠unsafe_ccopy t1 #i1 t2 #j2
{{{
RET ();
array۰cslice t1 sz1 i1_ dq1 vs1 ∗
array۰cslice t2 sz2 i2 (DfracOwn 1) (with_slice (₊j2 - i2) (length vs1) vs2 vs1)
}}}.
Lemma array٠ccopyーspecーfit t1 sz1 (i1 : Z) i1_ dq1 vs1 t2 sz2 (i2 : Z) i2_ vs2 :
i1_ = ₊i1 →
i2_ = ₊i2 →
length vs1 = sz1 →
length vs1 = length vs2 →
{{{
array۰inv t1 sz1 ∗
array۰inv t2 sz2 ∗
( ⌜0 < sz1⌝ -∗
⌜0 < sz2⌝ -∗
⌜0 ≤ i1⌝%Z -∗
⌜0 ≤ i2⌝%Z -∗
array۰cslice t1 sz1 i1_ dq1 vs1 ∗
array۰cslice t2 sz2 i2_ (DfracOwn 1) vs2
)
}}}
array٠ccopy t1 #i1 t2 #i2
{{{
RET ();
⌜0 < sz1⌝ ∗
⌜0 < sz2⌝ ∗
⌜0 ≤ i1⌝%Z ∗
⌜0 ≤ i2⌝%Z ∗
array۰cslice t1 sz1 i1_ dq1 vs1 ∗
array۰cslice t2 sz2 i2_ (DfracOwn 1) vs1
}}}.
Lemma array٠ccopyーspec t1 sz1 (i1 : Z) dq1 vs1 t2 sz2 i2 (j2 : Z) vs2 :
length vs1 = sz1 →
{{{
array۰inv t1 sz1 ∗
array۰inv t2 sz2 ∗
( ⌜0 < sz1⌝ -∗
⌜0 < sz2⌝ -∗
⌜0 ≤ i1⌝%Z -∗
⌜0 ≤ j2⌝%Z -∗
⌜i2 ≤ ₊j2⌝%Z ∗
⌜₊j2 + length vs1 ≤ i2 + length vs2⌝%Z ∗
array۰cslice t1 sz1 ₊i1 dq1 vs1 ∗
array۰cslice t2 sz2 i2 (DfracOwn 1) vs2
)
}}}
array٠ccopy t1 #i1 t2 #j2
{{{
RET ();
⌜0 < sz1⌝ ∗
⌜0 < sz2⌝ ∗
⌜0 ≤ i1⌝%Z ∗
⌜0 ≤ j2⌝%Z ∗
array۰cslice t1 sz1 ₊i1 dq1 vs1 ∗
array۰cslice t2 sz2 i2 (DfracOwn 1) (with_slice (₊j2 - i2) (length vs1) vs2 vs1)
}}}.
Lemma array٠unsafe_cgrow_sliceーspec t sz (i : Z) i_ dq vs (n : Z) sz' v :
0 < sz →
length vs ≤ sz →
i = ⁺i_ →
n = ⁺(length vs) →
(0 < sz')%Z →
(n ≤ sz')%Z →
{{{
array۰cslice t sz i_ dq vs
}}}
array٠unsafe_cgrow_slice t #i #n #sz' v
{{{
t'
, RET t';
array۰cslice t sz i_ dq vs ∗
array۰cslice t' ₊sz' i_ (DfracOwn 1) (vs ++ replicate (₊sz' - ₊n) v)
}}}.
Lemma array٠unsafe_cgrowーspec t (sz : nat) (i : Z) i_ dq vs sz' v :
0 < sz →
i = ⁺i_ →
length vs = sz →
(0 < sz')%Z →
(sz ≤ sz')%Z →
{{{
array۰cslice t sz i_ dq vs
}}}
array٠unsafe_cgrow t #i #sz' v
{{{
t'
, RET t';
array۰cslice t sz i_ dq vs ∗
array۰cslice t' ₊sz' i_ (DfracOwn 1) (vs ++ replicate (₊sz' - sz) v)
}}}.
Lemma array٠unsafe_cshrink_sliceーspecーfit t sz (i : Z) i_ dq vs sz' :
0 < sz →
length vs ≤ sz →
i = ⁺i_ →
(0 < sz' ≤ length vs)%Z →
{{{
array۰cslice t sz i_ dq vs
}}}
array٠unsafe_cshrink_slice t #i #sz'
{{{
t'
, RET t';
array۰cslice t sz i_ dq vs ∗
array۰cslice t' ₊sz' i_ (DfracOwn 1) (take ₊sz' vs)
}}}.
Lemma array٠unsafe_cshrink_sliceーspec t sz i dq vs (j : Z) sz' :
0 < sz →
length vs ≤ sz →
(i ≤ j)%Z →
(0 < sz')%Z →
(j + sz' ≤ i + length vs)%Z →
{{{
array۰cslice t sz i dq vs
}}}
array٠unsafe_cshrink_slice t #j #sz'
{{{
t'
, RET t';
array۰cslice t sz i dq vs ∗
array۰cslice t' ₊sz' ₊j (DfracOwn 1) (slice (₊j - i) ₊sz' vs)
}}}.
Definition itype۰array τ `{!iType _ τ} (sz : nat) t : iProp Σ :=
∃ l,
⌜t = #l⌝ ∗
l ↦ₕ Header 0 sz ∗
itype۰chunk τ sz l.
#[global] Instance itype۰arrayーitype τ `{!iType _ τ} sz :
iType _ (itype۰array τ sz).
Lemma itype۰arrayーintro τ `{!iType _ τ} t vs :
array۰model t (DfracOwn 1) vs -∗
([∗ list] v ∈ vs, τ v) ={⊤}=∗
itype۰array τ (length vs) t.
Lemma itype۰arrayーintroーslice τ `{!iType _ τ} t sz vs :
length vs = sz →
array۰inv t sz -∗
array۰slice t 0 (DfracOwn 1) vs -∗
([∗ list] v ∈ vs, τ v) ={⊤}=∗
itype۰array τ sz t.
Lemma itype۰arrayーintroーcslice τ `{!iType _ τ} t sz i vs :
0 < sz →
length vs = sz →
array۰cslice t sz i (DfracOwn 1) vs -∗
([∗ list] v ∈ vs, τ v) ={⊤}=∗
itype۰array τ sz t.
Lemma itype۰arrayーtoーinv τ `{!iType _ τ} sz t :
itype۰array τ sz t ⊢
array۰inv t sz.
Lemma array٠createーtype τ `{!iType _ τ} :
{{{
True
}}}
array٠create ()
{{{
t
, RET t;
itype۰array τ 0 t
}}}.
Lemma array٠sizeーtype τ `{!iType _ τ} t sz :
{{{
itype۰array τ sz t
}}}
array٠size t
{{{
RET #sz;
True
}}}.
Lemma array٠unsafe_getーtype τ `{!iType _ τ} t (sz : nat) (i : Z) :
(0 ≤ i < sz)%Z →
{{{
itype۰array τ sz t
}}}
array٠unsafe_get t #i
{{{
v
, RET v;
τ v
}}}.
Lemma array٠getーtype τ `{!iType _ τ} t sz (i : Z) :
{{{
itype۰array τ sz t
}}}
array٠get t #i
{{{
v
, RET v;
⌜0 ≤ i < sz⌝%Z ∗
τ v
}}}.
Lemma array٠unsafe_setーtype τ `{!iType _ τ} t (sz : nat) (i : Z) v :
(0 ≤ i < sz)%Z →
{{{
itype۰array τ sz t ∗
τ v
}}}
array٠unsafe_set t #i v
{{{
RET ();
True
}}}.
Lemma array٠setーtype τ `{!iType _ τ} t sz (i : Z) v :
{{{
itype۰array τ sz t ∗
τ v
}}}
array٠set t #i v
{{{
RET ();
⌜0 ≤ i < sz⌝%Z
}}}.
Lemma array٠unsafe_xchgーtype τ `{!iType _ τ} t (sz : nat) (i : Z) v :
(0 ≤ i < sz)%Z →
{{{
itype۰array τ sz t ∗
τ v
}}}
array٠unsafe_xchg t #i v
{{{
w
, RET w;
τ w
}}}.
Lemma array٠unsafe_casーtype τ `{!iType _ τ} t (sz : nat) (i : Z) v1 v2 :
(0 ≤ i < sz)%Z →
{{{
itype۰array τ sz t ∗
τ v1 ∗
τ v2
}}}
array٠unsafe_cas t #i v1 v2
{{{
b
, RET #b;
True
}}}.
Lemma array٠unsafe_fill_sliceーtype τ `{!iType _ τ} t (sz : nat) (i n : Z) v :
(0 ≤ i)%Z →
(0 ≤ n)%Z →
(i + n ≤ sz)%Z →
{{{
itype۰array τ sz t ∗
τ v
}}}
array٠unsafe_fill_slice t #i #n v
{{{
RET ();
True
}}}.
Lemma array٠fill_sliceーtype τ `{!iType _ τ} t sz (i n : Z) v :
{{{
itype۰array τ sz t ∗
τ v
}}}
array٠fill_slice t #i #n v
{{{
RET ();
⌜0 ≤ i⌝%Z ∗
⌜0 ≤ n⌝%Z ∗
⌜i + n ≤ sz⌝%Z
}}}.
Lemma array٠fillーtype τ `{!iType _ τ} t sz v :
{{{
itype۰array τ sz t ∗
τ v
}}}
array٠fill t v
{{{
RET ();
True
}}}.
Lemma array٠unsafe_makeーtype τ `{!iType _ τ} sz v :
(0 ≤ sz)%Z →
{{{
τ v
}}}
array٠unsafe_make #sz v
{{{
t
, RET t;
itype۰array τ ₊sz t
}}}.
Lemma array٠makeーtype τ `{!iType _ τ} sz v :
{{{
τ v
}}}
array٠make #sz v
{{{
t
, RET t;
⌜0 ≤ sz⌝%Z ∗
itype۰array τ ₊sz t
}}}.
Lemma array٠foldliーtype τ `{!iType _ τ} υ `{!iType _ υ} fn acc t sz :
{{{
itype۰array τ sz t ∗
υ acc ∗
(itype۰nat_upto sz --> υ --> τ --> υ)%T fn
}}}
array٠foldli fn acc t
{{{
acc'
, RET acc';
υ acc'
}}}.
Lemma array٠foldlーtype τ `{!iType _ τ} υ `{!iType _ υ} fn acc t sz :
{{{
itype۰array τ sz t ∗
υ acc ∗
(υ --> τ --> υ)%T fn
}}}
array٠foldl fn acc t
{{{
acc'
, RET acc';
υ acc'
}}}.
Lemma array٠foldriーtype τ `{!iType _ τ} υ `{!iType _ υ} fn acc t sz :
{{{
itype۰array τ sz t ∗
(itype۰nat_upto sz --> τ --> υ --> υ)%T fn ∗
υ acc
}}}
array٠foldri fn t acc
{{{
acc'
, RET acc';
υ acc'
}}}.
Lemma array٠foldrーtype τ `{!iType _ τ} υ `{!iType _ υ} fn t sz acc :
{{{
itype۰array τ sz t ∗
(τ --> υ --> υ)%T fn ∗
υ acc
}}}
array٠foldr fn t acc
{{{
acc'
, RET acc';
υ acc'
}}}.
Lemma array٠unsafe_iteri_sliceーtype τ `{!iType _ τ} fn t (sz : nat) (i n : Z) :
(0 ≤ i ≤ sz)%Z →
(0 ≤ n)%Z →
(i + n ≤ sz)%Z →
{{{
itype۰array τ sz t ∗
(itype۰nat_upto ₊n --> τ --> itype۰unit)%T fn
}}}
array٠unsafe_iteri_slice fn t #i #n
{{{
RET ();
True
}}}.
Lemma array٠iteri_sliceーtype τ `{!iType _ τ} fn t (sz : nat) (i n : Z) :
{{{
itype۰array τ sz t ∗
(itype۰nat_upto ₊n --> τ --> itype۰unit)%T fn
}}}
array٠iteri_slice fn t #i #n
{{{
RET ();
⌜0 ≤ i ≤ sz⌝%Z ∗
⌜0 ≤ n⌝%Z ∗
⌜i + n ≤ sz⌝%Z
}}}.
Lemma array٠unsafe_iter_sliceーtype τ `{!iType _ τ} fn t (sz : nat) (i n : Z) :
(0 ≤ i ≤ sz)%Z →
(0 ≤ n)%Z →
(i + n ≤ sz)%Z →
{{{
itype۰array τ sz t ∗
(τ --> itype۰unit)%T fn
}}}
array٠unsafe_iter_slice fn t #i #n
{{{
RET ();
True
}}}.
Lemma array٠iter_sliceーtype τ `{!iType _ τ} fn t (sz : nat) (i n : Z) :
{{{
itype۰array τ sz t ∗
(τ --> itype۰unit)%T fn
}}}
array٠iter_slice fn t #i #n
{{{
RET ();
⌜0 ≤ i ≤ sz⌝%Z ∗
⌜0 ≤ n⌝%Z ∗
⌜i + n ≤ sz⌝%Z
}}}.
Lemma array٠iteriーtype τ `{!iType _ τ} fn t sz :
{{{
itype۰array τ sz t ∗
(itype۰nat_upto sz --> τ --> itype۰unit)%T fn
}}}
array٠iteri fn t
{{{
RET ();
True
}}}.
Lemma array٠iterーtype τ `{!iType _ τ} fn t sz :
{{{
itype۰array τ sz t ∗
(τ --> itype۰unit)%T fn
}}}
array٠iter fn t
{{{
RET ();
True
}}}.
Lemma array٠unsafe_applyi_sliceーtype τ `{!iType _ τ} fn t (sz : nat) (i n : Z) :
(0 ≤ i ≤ sz)%Z →
(0 ≤ n)%Z →
(i + n ≤ sz)%Z →
{{{
itype۰array τ sz t ∗
(itype۰nat_upto ₊n --> τ --> τ)%T fn
}}}
array٠unsafe_applyi_slice fn t #i #n
{{{
RET ();
True
}}}.
Lemma array٠applyi_sliceーtype τ `{!iType _ τ} fn t (sz : nat) (i n : Z) :
{{{
itype۰array τ sz t ∗
(itype۰nat_upto ₊n --> τ --> τ)%T fn
}}}
array٠applyi_slice fn t #i #n
{{{
RET ();
⌜0 ≤ i ≤ sz⌝%Z ∗
⌜0 ≤ n⌝%Z ∗
⌜i + n ≤ sz⌝%Z
}}}.
Lemma array٠unsafe_apply_sliceーtype τ `{!iType _ τ} fn t (sz : nat) (i n : Z) :
(0 ≤ i ≤ sz)%Z →
(0 ≤ n)%Z →
(i + n ≤ sz)%Z →
{{{
itype۰array τ sz t ∗
(τ --> τ)%T fn
}}}
array٠unsafe_apply_slice fn t #i #n
{{{
RET ();
True
}}}.
Lemma array٠apply_sliceーtype τ `{!iType _ τ} fn t (sz : nat) (i n : Z) :
{{{
itype۰array τ sz t ∗
(τ --> τ)%T fn
}}}
array٠apply_slice fn t #i #n
{{{
RET ();
⌜0 ≤ i ≤ sz⌝%Z ∗
⌜0 ≤ n⌝%Z ∗
⌜i + n ≤ sz⌝%Z
}}}.
Lemma array٠applyiーtype τ `{!iType _ τ} fn t sz :
{{{
itype۰array τ sz t ∗
(itype۰nat_upto sz --> τ --> τ)%T fn
}}}
array٠applyi fn t
{{{
RET ();
True
}}}.
Lemma array٠applyーtype τ `{!iType _ τ} fn t sz :
{{{
itype۰array τ sz t ∗
(τ --> τ)%T fn
}}}
array٠apply fn t
{{{
RET ();
True
}}}.
Lemma array٠unsafe_initiーtype τ `{!iType _ τ} sz sz_ fn :
sz = ⁺sz_ →
{{{
(itype۰nat_upto sz_ --> τ)%T fn
}}}
array٠unsafe_initi #sz fn
{{{
t
, RET t;
itype۰array τ sz_ t
}}}.
Lemma array٠initiーtype τ `{!iType _ τ} sz fn :
{{{
(itype۰nat_upto ₊sz --> τ)%T fn
}}}
array٠initi #sz fn
{{{
t
, RET t;
⌜0 ≤ sz⌝%Z ∗
itype۰array τ ₊sz t
}}}.
Lemma array٠unsafe_initーtype τ `{!iType _ τ} sz fn :
(0 ≤ sz)%Z →
{{{
(itype۰unit --> τ)%T fn
}}}
array٠unsafe_init #sz fn
{{{
t
, RET t;
itype۰array τ ₊sz t
}}}.
Lemma array٠initーtype τ `{!iType _ τ} sz fn :
{{{
(itype۰unit --> τ)%T fn
}}}
array٠init #sz fn
{{{
t
, RET t;
⌜0 ≤ sz⌝%Z ∗
itype۰array τ ₊sz t
}}}.
Lemma array٠mapiーtype τ `{!iType _ τ} υ `{!iType _ υ} fn t sz sz_ :
sz_ = ⁺sz →
{{{
itype۰array τ sz t ∗
(itype۰nat_upto sz --> τ --> υ)%T fn
}}}
array٠mapi fn t
{{{
t'
, RET t';
itype۰array υ sz t'
}}}.
Lemma array٠mapーtype τ `{!iType _ τ} υ `{!iType _ υ} fn t sz sz_ :
sz_ = ⁺sz →
{{{
itype۰array τ sz t ∗
(τ --> υ)%T fn
}}}
array٠map fn t
{{{
t'
, RET t';
itype۰array υ sz t'
}}}.
Lemma array٠unsafe_copy_sliceーtype τ `{!iType _ τ} t1 (sz1 : nat) (i1 : Z) t2 (sz2 : nat) (i2 n : Z) :
(0 ≤ i1)%Z →
(0 ≤ i2)%Z →
(0 ≤ n)%Z →
(i1 + n ≤ sz1)%Z →
(i2 + n ≤ sz2)%Z →
{{{
itype۰array τ sz1 t1 ∗
itype۰array τ sz2 t2
}}}
array٠unsafe_copy_slice t1 #i1 t2 #i2 #n
{{{
RET ();
True
}}}.
Lemma array٠unsafe_copy_slice۰type' τ `{!iType _ τ} t1 (sz : nat) (i1 : Z) t2 (i2 : Z) i2_ vs (n : Z) :
(0 ≤ i1)%Z →
i2 = ⁺i2_ →
n = length vs →
(i1 + n ≤ sz)%Z →
{{{
itype۰array τ sz t1 ∗
array۰slice t2 i2_ (DfracOwn 1) vs
}}}
array٠unsafe_copy_slice t1 #i1 t2 #i2 #n
{{{
ws
, RET ();
⌜length ws = length vs⌝ ∗
array۰slice t2 i2_ (DfracOwn 1) ws ∗
[∗ list] w ∈ ws, τ w
}}}.
Lemma array٠copy_sliceーtype τ `{!iType _ τ} t1 sz1 (i1 : Z) t2 sz2 (i2 n : Z) :
{{{
itype۰array τ sz1 t1 ∗
itype۰array τ sz2 t2
}}}
array٠copy_slice t1 #i1 t2 #i2 #n
{{{
RET ();
⌜0 ≤ i1⌝%Z ∗
⌜0 ≤ i2⌝%Z ∗
⌜0 ≤ n⌝%Z ∗
⌜i1 + n ≤ sz1⌝%Z ∗
⌜i2 + n ≤ sz2⌝%Z
}}}.
Lemma array٠unsafe_copyーtype τ `{!iType _ τ} t1 (sz1 : nat) t2 (sz2 : nat) (i2 : Z) :
(0 ≤ i2)%Z →
(i2 + sz1 ≤ sz2)%Z →
{{{
itype۰array τ sz1 t1 ∗
itype۰array τ sz2 t2
}}}
array٠unsafe_copy t1 t2 #i2
{{{
RET ();
⌜i2 + sz1 ≤ sz2⌝%Z
}}}.
Lemma array٠unsafe_copy۰type' τ `{!iType _ τ} t1 sz t2 (i2 : Z) i2_ vs :
i2 = ⁺i2_ →
sz = length vs →
{{{
itype۰array τ sz t1 ∗
array۰slice t2 i2_ (DfracOwn 1) vs
}}}
array٠unsafe_copy t1 t2 #i2
{{{
ws
, RET ();
⌜length ws = length vs⌝ ∗
array۰slice t2 i2_ (DfracOwn 1) ws ∗
[∗ list] w ∈ ws, τ w
}}}.
Lemma array٠copyーtype τ `{!iType _ τ} t1 sz1 t2 sz2 (i2 : Z) :
{{{
itype۰array τ sz1 t1 ∗
itype۰array τ sz2 t2
}}}
array٠copy t1 t2 #i2
{{{
RET ();
⌜0 ≤ i2⌝%Z ∗
⌜i2 + sz1 ≤ sz2⌝%Z
}}}.
Lemma array٠unsafe_growーtype τ `{!iType _ τ} t (sz : nat) sz' v' :
(sz ≤ sz')%Z →
{{{
itype۰array τ sz t ∗
τ v'
}}}
array٠unsafe_grow t #sz' v'
{{{
t'
, RET t';
itype۰array τ ₊sz' t'
}}}.
Lemma array٠growーtype τ `{!iType _ τ} t sz sz' v' :
{{{
itype۰array τ sz t ∗
τ v'
}}}
array٠grow t #sz' v'
{{{
t'
, RET t';
⌜sz ≤ sz'⌝ ∗
itype۰array τ ₊sz' t'
}}}.
Lemma array٠unsafe_subーtype τ `{!iType _ τ} t (sz : nat) (i n : Z) :
(0 ≤ i)%Z →
(0 ≤ n)%Z →
(i + n ≤ sz)%Z →
{{{
itype۰array τ sz t
}}}
array٠unsafe_sub t #i #n
{{{
t'
, RET t';
itype۰array τ ₊n t'
}}}.
Lemma array٠subーtype τ `{!iType _ τ} t sz (i n : Z) :
{{{
itype۰array τ sz t
}}}
array٠sub t #i #n
{{{
t'
, RET t';
⌜0 ≤ i⌝%Z ∗
⌜0 ≤ n⌝%Z ∗
⌜i + n ≤ sz⌝%Z ∗
itype۰array τ ₊n t'
}}}.
Lemma array٠unsafe_shrinkーtype τ `{!iType _ τ} t (sz : nat) (n : Z) :
(0 ≤ n ≤ sz)%Z →
{{{
itype۰array τ sz t
}}}
array٠unsafe_shrink t #n
{{{
t'
, RET t';
itype۰array τ ₊n t'
}}}.
Lemma array٠shrinkーtype τ `{!iType _ τ} t sz (n : Z) :
{{{
itype۰array τ sz t
}}}
array٠shrink t #n
{{{
t'
, RET t';
⌜0 ≤ n ≤ sz⌝%Z ∗
itype۰array τ ₊n t'
}}}.
Lemma array٠cloneーtype τ `{!iType _ τ} t sz :
{{{
itype۰array τ sz t
}}}
array٠clone t
{{{
t'
, RET t';
itype۰array τ sz t'
}}}.
Lemma array٠unsafe_cgetーtype τ `{!iType _ τ} t sz (i : Z) :
0 < sz →
(0 ≤ i)%Z →
{{{
itype۰array τ sz t
}}}
array٠unsafe_cget t #i
{{{
v
, RET v;
τ v
}}}.
Lemma array٠cgetーtype τ `{!iType _ τ} t sz (i : Z) :
{{{
itype۰array τ sz t
}}}
array٠cget t #i
{{{
v
, RET v;
⌜0 < sz⌝ ∗
⌜0 ≤ i⌝%Z ∗
τ v
}}}.
Lemma array٠unsafe_csetーtype τ `{!iType _ τ} t sz (i : Z) v :
0 < sz →
(0 ≤ i)%Z →
{{{
itype۰array τ sz t ∗
τ v
}}}
array٠unsafe_cset t #i v
{{{
RET ();
True
}}}.
Lemma array٠csetーtype τ `{!iType _ τ} t sz (i : Z) v :
{{{
itype۰array τ sz t ∗
τ v
}}}
array٠cset t #i v
{{{
RET ();
⌜0 < sz⌝ ∗
⌜0 ≤ i⌝%Z
}}}.
#[local] Lemma array٠unsafe_ccopy_slice₁ーtype τ `{!iType _ τ} t1 sz1 (i1 : Z) t2 sz2 (i2 n : Z) :
0 < sz1 →
0 < sz2 →
(0 ≤ i1)%Z →
(0 ≤ i2)%Z →
(0 ≤ n)%Z →
(i1 + n ≤ sz1)%Z →
(n ≤ sz2)%Z →
{{{
itype۰array τ sz1 t1 ∗
itype۰array τ sz2 t2
}}}
array٠unsafe_ccopy_slice₁ t1 #i1 t2 #i2 #n
{{{
RET ();
True
}}}.
Lemma array٠unsafe_ccopy_sliceーtype τ `{!iType _ τ} t1 sz1 (i1 : Z) t2 sz2 (i2 n : Z) :
0 < sz1 →
0 < sz2 →
(0 ≤ i1)%Z →
(0 ≤ i2)%Z →
(0 ≤ n)%Z →
(n ≤ sz1)%Z →
(n ≤ sz2)%Z →
{{{
itype۰array τ sz1 t1 ∗
itype۰array τ sz2 t2
}}}
array٠unsafe_ccopy_slice t1 #i1 t2 #i2 #n
{{{
RET ();
True
}}}.
#[local] Lemma array٠unsafe_ccopy_slice₁۰type' τ `{!iType _ τ} t1 sz1 (i1 : Z) t2 sz2 (i2 : Z) i2_ vs (n : Z) :
0 < sz1 →
0 < sz2 →
length vs ≤ sz2 →
(0 ≤ i1)%Z →
(i1 + length vs ≤ sz1)%Z →
i2 = ⁺i2_ →
n = length vs →
{{{
itype۰array τ sz1 t1 ∗
array۰cslice t2 sz2 i2_ (DfracOwn 1) vs
}}}
array٠unsafe_ccopy_slice₁ t1 #i1 t2 #i2 #n
{{{
ws
, RET ();
⌜length ws = length vs⌝ ∗
array۰cslice t2 sz2 i2_ (DfracOwn 1) ws ∗
[∗ list] w ∈ ws, τ w
}}}.
Lemma array٠unsafe_ccopy_slice۰type' τ `{!iType _ τ} t1 sz1 (i1 : Z) t2 sz2 (i2 : Z) i2_ vs (n : Z) :
0 < sz1 →
length vs ≤ sz1 →
0 < sz2 →
length vs ≤ sz2 →
(0 ≤ i1)%Z →
i2 = ⁺i2_ →
n = length vs →
{{{
itype۰array τ sz1 t1 ∗
array۰cslice t2 sz2 i2_ (DfracOwn 1) vs
}}}
array٠unsafe_ccopy_slice t1 #i1 t2 #i2 #n
{{{
ws
, RET ();
⌜length ws = length vs⌝ ∗
array۰cslice t2 sz2 i2_ (DfracOwn 1) ws ∗
[∗ list] w ∈ ws, τ w
}}}.
Lemma array٠ccopy_sliceーtype τ `{!iType _ τ} t1 sz1 (i1 : Z) t2 sz2 (i2 : Z) (n : Z) :
0 < sz1 →
0 < sz2 →
{{{
itype۰array τ sz1 t1 ∗
itype۰array τ sz2 t2
}}}
array٠ccopy_slice t1 #i1 t2 #i2 #n
{{{
RET ();
⌜0 < sz1⌝ ∗
⌜0 < sz2⌝ ∗
⌜0 ≤ i1⌝%Z ∗
⌜0 ≤ i2⌝%Z
}}}.
Lemma array٠unsafe_ccopyーtype τ `{!iType _ τ} t1 sz1 (i1 : Z) t2 sz2 (i2 : Z) :
0 < sz1 →
0 < sz2 →
sz1 ≤ sz2 →
(0 ≤ i1)%Z →
(0 ≤ i2)%Z →
{{{
itype۰array τ sz1 t1 ∗
itype۰array τ sz2 t2
}}}
array٠unsafe_ccopy t1 #i1 t2 #i2
{{{
RET ();
True
}}}.
Lemma array٠ccopyーtype τ `{!iType _ τ} t1 sz1 (i1 : Z) t2 sz2 (i2 : Z) :
{{{
itype۰array τ sz1 t1 ∗
itype۰array τ sz2 t2
}}}
array٠ccopy t1 #i1 t2 #i2
{{{
RET ();
⌜0 < sz1⌝ ∗
⌜0 < sz2⌝ ∗
⌜0 ≤ i1⌝%Z ∗
⌜0 ≤ i2⌝%Z
}}}.
Lemma array٠unsafe_cgrow_sliceーtype τ `{!iType _ τ} sz t (i n : Z) sz' v :
0 < sz →
(0 ≤ i)%Z →
(0 ≤ n)%Z →
(0 < sz')%Z →
(n ≤ sz)%Z →
(n ≤ sz')%Z →
{{{
itype۰array τ sz t ∗
τ v
}}}
array٠unsafe_cgrow_slice t #i #n #sz' v
{{{
t'
, RET t';
itype۰array τ ₊sz' t'
}}}.
Lemma array٠unsafe_cgrowーtype τ `{!iType _ τ} sz t (i n : Z) sz' v :
0 < sz →
(0 ≤ i)%Z →
(0 < sz')%Z →
(sz ≤ sz')%Z →
{{{
itype۰array τ sz t ∗
τ v
}}}
array٠unsafe_cgrow t #i #sz' v
{{{
t'
, RET t';
itype۰array τ ₊sz' t'
}}}.
Lemma array٠unsafe_cshrink_sliceーtype τ `{!iType _ τ} sz t (i : Z) sz' :
0 < sz →
(0 ≤ i)%Z →
(0 < sz')%Z →
(sz' ≤ sz)%Z →
{{{
itype۰array τ sz t
}}}
array٠unsafe_cshrink_slice t #i #sz'
{{{
t'
, RET t';
itype۰array τ ₊sz' t'
}}}.
End zoo۰G.
Require zoo_std.array__opaque.
#[global] Opaque array٠unsafe_xchg.
#[global] Opaque array٠unsafe_cas.
#[global] Opaque array٠unsafe_faa.
#[global] Opaque array۰inv.
#[global] Opaque array۰slice.
#[global] Opaque array۰model.
#[global] Opaque array۰cslice.
#[global] Opaque itype۰array.