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) ⋯ 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 = 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 = 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 : List α) (t : α) => t :: l) [] arr 0
Instances For
@[simp]
theorem
Array.toListRev_eq
{α : Type u_1}
(arr : Array α)
:
Array.toListRev arr = List.reverse arr.data
theorem
Array.get_push_lt
{α : Type u_1}
(a : Array α)
(x : α)
(i : Nat)
(h : i < Array.size a)
:
let_fun this := ⋯;
(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 : Array β) (a : α) => Array.push bs <$> f a) #[] arr 0
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 : Array β) (a : α) => Array.push bs <$> f a) r (List.drop i arr.data)
@[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
@[simp]
theorem
Array.appendList_cons
{α : Type u_1}
(arr : Array α)
(a : α)
(l : List α)
:
arr ++ a :: l = Array.push arr a ++ l
theorem
Array.foldl_data_eq_map
{α : Type u_1}
{β : Type u_2}
(l : List α)
(acc : Array β)
(G : α → β)
:
(List.foldl (fun (acc : Array β) (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
theorem
Array.anyM_eq_anyM_loop
{m : Type → Type u_1}
{α : Type u_2}
[Monad m]
(p : α → m Bool)
(as : Array α)
(start : Nat)
(stop : Nat)
:
Array.anyM p as start stop = Array.anyM.loop p as (min stop (Array.size as)) ⋯ start
theorem
Array.getElem?_ge
{α : Type u_1}
(a : Array α)
{i : Nat}
(h : i ≥ Array.size a)
:
a[i]? = none
@[simp]
theorem
Array.getElem?_len_le
{α : Type u_1}
(a : Array α)
{i : Nat}
(h : Array.size a ≤ i)
:
a[i]? = none
theorem
Array.getD_get?
{α : Type u_1}
(a : Array α)
(i : Nat)
(d : α)
:
Option.getD a[i]? d = if p : i < Array.size a then a[i] else d
@[simp]
theorem
Array.getD_eq_get?
{α : Type u_1}
(a : Array α)
(n : Nat)
(d : α)
:
Array.getD a n d = Option.getD a[n]? d
theorem
Array.get!_eq_getD
{α : Type u_1}
{n : Nat}
[Inhabited α]
(a : Array α)
:
Array.get! a n = Array.getD a n default
@[simp]
theorem
Array.get!_eq_getElem?
{α : Type u_1}
[Inhabited α]
(a : Array α)
(i : Nat)
:
Array.get! a i = Option.getD (Array.get? a i) default
@[simp]
theorem
Array.getElem_set_eq
{α : Type u_1}
(a : Array α)
(i : Fin (Array.size a))
(v : α)
{j : Nat}
(eq : ↑i = j)
(p : j < Array.size (Array.set a i v))
:
set #
@[simp]
theorem
Array.getElem_set_ne
{α : Type u_1}
(a : Array α)
(i : Fin (Array.size a))
(v : α)
{j : Nat}
(pj : j < Array.size (Array.set a i v))
(h : ↑i ≠ j)
:
theorem
Array.getElem_set
{α : Type u_1}
(a : Array α)
(i : Fin (Array.size a))
(v : α)
(j : Nat)
(h : j < Array.size (Array.set a i v))
:
@[simp]
@[simp]
theorem
Array.getElem?_set_ne
{α : Type u_1}
(a : Array α)
(i : Fin (Array.size a))
{j : Nat}
(v : α)
(ne : ↑i ≠ j)
:
@[simp]
theorem
Array.size_setD
{α : Type u_1}
(a : Array α)
(index : Nat)
(val : α)
:
Array.size (Array.setD a index val) = Array.size a
@[simp]
theorem
Array.getElem_setD_eq
{α : Type u_1}
(a : Array α)
{i : Nat}
(v : α)
(h : i < Array.size (Array.setD a i v))
:
(Array.setD a i v)[i] = v
@[simp]
theorem
Array.getElem?_setD_eq
{α : Type u_1}
(a : Array α)
{i : Nat}
(p : i < Array.size a)
(v : α)
:
(Array.setD a i v)[i]? = some v
@[simp]
theorem
Array.getD_get?_setD
{α : Type u_1}
(a : Array α)
(i : Nat)
(v : α)
(d : α)
:
Option.getD (Array.setD a i v)[i]? d = if i < Array.size a then v else d
Simplifies a normal form from get!