Bootstrapping theorems about arrays #
This file contains some theorems about Array
and List
needed for Std.List.Basic
.
@[simp]
theorem
Array.size_toArray
{α : Type u_1}
(as : List α)
:
Array.size (List.toArray as) = List.length as
@[simp]
theorem
Array.foldlM_eq_foldlM_data.aux
{m : Type u_1 → Type u_2}
{β : Type u_1}
{α : Type u_3}
[Monad m]
(f : β → α → m β)
(arr : Array α)
(i : Nat)
(j : Nat)
(H : Array.size arr ≤ i + j)
(b : β)
:
Array.foldlM.loop f arr (Array.size arr) (_ : Array.size arr ≤ Array.size arr) i j b = List.foldlM f b (List.drop j arr.data)
theorem
Array.foldlM_eq_foldlM_data
{m : Type u_1 → Type u_2}
{β : Type u_1}
{α : Type u_3}
[Monad m]
(f : β → α → m β)
(init : β)
(arr : Array α)
:
Array.foldlM f init arr 0 (Array.size arr) = List.foldlM f init arr.data
theorem
Array.foldl_eq_foldl_data
{β : Type u_1}
{α : Type u_2}
(f : β → α → β)
(init : β)
(arr : Array α)
:
Array.foldl f init arr 0 (Array.size arr) = List.foldl f init arr.data
theorem
Array.foldrM_eq_reverse_foldlM_data.aux
{m : Type u_1 → Type u_2}
{α : Type u_3}
{β : Type u_1}
[Monad m]
(f : α → β → m β)
(arr : Array α)
(init : β)
(i : Nat)
(h : i ≤ Array.size arr)
:
List.foldlM (fun x y => f y x) init (List.reverse (List.take i arr.data)) = Array.foldrM.fold f arr 0 i h init
theorem
Array.foldrM_eq_reverse_foldlM_data
{m : Type u_1 → Type u_2}
{α : Type u_3}
{β : Type u_1}
[Monad m]
(f : α → β → m β)
(init : β)
(arr : Array α)
:
Array.foldrM f init arr (Array.size arr) = List.foldlM (fun x y => f y x) init (List.reverse arr.data)
theorem
Array.foldrM_eq_foldrM_data
{m : Type u_1 → Type u_2}
{α : Type u_3}
{β : Type u_1}
[Monad m]
(f : α → β → m β)
(init : β)
(arr : Array α)
:
Array.foldrM f init arr (Array.size arr) = List.foldrM f init arr.data
theorem
Array.foldr_eq_foldr_data
{α : Type u_1}
{β : Type u_2}
(f : α → β → β)
(init : β)
(arr : Array α)
:
Array.foldr f init arr (Array.size arr) = List.foldr f init arr.data
@[simp]
theorem
Array.push_data
{α : Type u_1}
(arr : Array α)
(a : α)
:
(Array.push arr a).data = arr.data ++ [a]
theorem
Array.foldrM_push
{m : Type u_1 → Type u_2}
{α : Type u_3}
{β : Type u_1}
[Monad m]
(f : α → β → m β)
(init : β)
(arr : Array α)
(a : α)
:
Array.foldrM f init (Array.push arr a) (Array.size (Array.push arr a)) = do
let init ← f a init
Array.foldrM f init arr (Array.size arr)
@[simp]
theorem
Array.foldrM_push'
{m : Type u_1 → Type u_2}
{α : Type u_3}
{β : Type u_1}
[Monad m]
(f : α → β → m β)
(init : β)
(arr : Array α)
(a : α)
:
Array.foldrM f init (Array.push arr a) (Array.size arr + 1) = do
let init ← f a init
Array.foldrM f init arr (Array.size arr)
theorem
Array.foldr_push
{α : Type u_1}
{β : Type u_2}
(f : α → β → β)
(init : β)
(arr : Array α)
(a : α)
:
Array.foldr f init (Array.push arr a) (Array.size (Array.push arr a)) = Array.foldr f (f a init) arr (Array.size arr)
@[simp]
theorem
Array.foldr_push'
{α : Type u_1}
{β : Type u_2}
(f : α → β → β)
(init : β)
(arr : Array α)
(a : α)
:
Array.foldr f init (Array.push arr a) (Array.size arr + 1) = Array.foldr f (f a init) arr (Array.size arr)
@[simp]
theorem
Array.toListAppend_eq
{α : Type u_1}
(arr : Array α)
(l : List α)
:
Array.toListAppend arr l = arr.data ++ l
@[inline]
A more efficient version of arr.toList.reverse
.
Equations
- Array.toListRev arr = Array.foldl (fun l t => t :: l) [] arr 0 (Array.size arr)
Instances For
@[simp]
theorem
Array.toListRev_eq
{α : Type u_1}
(arr : Array α)
:
Array.toListRev arr = List.reverse arr.data
theorem
Array.SatisfiesM_foldlM
{m : Type u_1 → Type u_2}
{α : Type u_3}
{β : Type u_1}
[Monad m]
[LawfulMonad m]
{as : Array α}
(motive : Nat → β → Prop)
{init : β}
(h0 : motive 0 init)
{f : β → α → m β}
(hf : ∀ (i : Fin (Array.size as)) (b : β), motive i.val b → SatisfiesM (motive (i.val + 1)) (f b as[i]))
:
SatisfiesM (motive (Array.size as)) (Array.foldlM f init as 0 (Array.size as))
theorem
Array.SatisfiesM_foldlM.go
{m : Type u_1 → Type u_2}
{α : Type u_3}
{β : Type u_1}
[Monad m]
[LawfulMonad m]
{as : Array α}
(motive : Nat → β → Prop)
{f : β → α → m β}
(hf : ∀ (i : Fin (Array.size as)) (b : β), motive i.val b → SatisfiesM (motive (i.val + 1)) (f b as[i]))
{i : Nat}
{j : Nat}
{b : β}
(h₁ : j ≤ Array.size as)
(h₂ : Array.size as ≤ i + j)
(H : motive j b)
:
SatisfiesM (motive (Array.size as)) (Array.foldlM.loop f as (Array.size as) (_ : Array.size as ≤ Array.size as) i j b)
theorem
Array.foldl_induction
{α : Type u_1}
{β : Type u_2}
{as : Array α}
(motive : Nat → β → Prop)
{init : β}
(h0 : motive 0 init)
{f : β → α → β}
(hf : (i : Fin (Array.size as)) → (b : β) → motive i.val b → motive (i.val + 1) (f b as[i]))
:
motive (Array.size as) (Array.foldl f init as 0 (Array.size as))
theorem
Array.get_push_lt
{α : Type u_1}
(a : Array α)
(x : α)
(i : Nat)
(h : i < Array.size a)
:
(Array.push a x)[i] = a[i]
@[simp]
theorem
Array.get_push
{α : Type u_1}
(a : Array α)
(x : α)
(i : Nat)
(h : i < Array.size (Array.push a x))
:
(Array.push a x)[i] = if h : i < Array.size a then a[i] else x
theorem
Array.mapM_eq_foldlM
{m : Type u_1 → Type u_2}
{α : Type u_3}
{β : Type u_1}
[Monad m]
[LawfulMonad m]
(f : α → m β)
(arr : Array α)
:
Array.mapM f arr = Array.foldlM (fun bs a => Array.push bs <$> f a) #[] arr 0 (Array.size arr)
theorem
Array.mapM_eq_foldlM.aux
{m : Type u_1 → Type u_2}
{α : Type u_3}
{β : Type u_1}
[Monad m]
[LawfulMonad m]
(f : α → m β)
(arr : Array α)
(i : Nat)
(r : Array β)
:
Array.mapM.map f arr i r = List.foldlM (fun bs a => Array.push bs <$> f a) r (List.drop i arr.data)
theorem
Array.SatisfiesM_mapM
{m : Type u_1 → Type u_2}
{α : Type u_3}
{β : Type u_1}
[Monad m]
[LawfulMonad m]
(as : Array α)
(f : α → m β)
(motive : Nat → Prop)
(h0 : motive 0)
(p : Fin (Array.size as) → β → Prop)
(hs : ∀ (i : Fin (Array.size as)), motive i.val → SatisfiesM (fun x => p i x ∧ motive (i.val + 1)) (f as[i]))
:
SatisfiesM
(fun arr => motive (Array.size as) ∧ ∃ eq, (i : Nat) → (h : i < Array.size as) → p { val := i, isLt := h } arr[i])
(Array.mapM f as)
theorem
Array.SatisfiesM_mapM'
{m : Type u_1 → Type u_2}
{α : Type u_3}
{β : Type u_1}
[Monad m]
[LawfulMonad m]
(as : Array α)
(f : α → m β)
(p : Fin (Array.size as) → β → Prop)
(hs : ∀ (i : Fin (Array.size as)), SatisfiesM (p i) (f as[i]))
:
SatisfiesM (fun arr => ∃ eq, (i : Nat) → (h : i < Array.size as) → p { val := i, isLt := h } arr[i]) (Array.mapM f as)
theorem
Array.size_mapM
{m : Type u_1 → Type u_2}
{α : Type u_3}
{β : Type u_1}
[Monad m]
[LawfulMonad m]
(f : α → m β)
(as : Array α)
:
SatisfiesM (fun arr => Array.size arr = Array.size as) (Array.mapM f as)
@[simp]
theorem
Array.size_map
{α : Type u_1}
{β : Type u_2}
(f : α → β)
(arr : Array α)
:
Array.size (Array.map f arr) = Array.size arr
@[simp]
theorem
Array.pop_data
{α : Type u_1}
(arr : Array α)
:
(Array.pop arr).data = List.dropLast arr.data
@[simp]
theorem
Array.append_eq_append
{α : Type u_1}
(arr : Array α)
(arr' : Array α)
:
Array.append arr arr' = arr ++ arr'
@[simp]
theorem
Array.appendList_eq_append
{α : Type u_1}
(arr : Array α)
(l : List α)
:
Array.appendList arr l = arr ++ l
theorem
Array.foldl_data_eq_map
{α : Type u_1}
{β : Type u_2}
(l : List α)
(acc : Array β)
(G : α → β)
:
(List.foldl (fun acc a => Array.push acc (G a)) acc l).data = acc.data ++ List.map G l
theorem
Array.size_uset
{α : Type u_1}
(a : Array α)
(v : α)
(i : USize)
(h : USize.toNat i < Array.size a)
:
Array.size (Array.uset a i v h) = Array.size a