Module docstring
{"### Lemmas about List.toArray.
We prefer to pull List.toArray outwards past Array operations.
"}
{"### Lemmas about List.toArray.
We prefer to pull List.toArray outwards past Array operations.
"}
Array.toList_set
theorem
(xs : Array α) (i x h) : (xs.set i x).toList = xs.toList.set i x
Array.swap_def
theorem
(xs : Array α) (i j : Nat) (hi hj) : xs.swap i j hi hj = (xs.set i xs[j]).set j xs[i] (by simpa using hj)
Array.toList_swap
theorem
(xs : Array α) (i j : Nat) (hi hj) : (xs.swap i j hi hj).toList = (xs.toList.set i xs[j]).set j xs[i]
List.toArray_inj
theorem
{as bs : List α} (h : as.toArray = bs.toArray) : as = bs
List.toArray_eq_iff
theorem
{as : List α} {bs : Array α} : as.toArray = bs ↔ as = bs.toList
theorem toArray_eq_iff {as : List α} {bs : Array α} : as.toArray = bs ↔ as = bs.toList := by
cases bs
simp
List.size_toArrayAux
theorem
{as : List α} {xs : Array α} : (as.toArrayAux xs).size = xs.size + as.length
@[simp] theorem size_toArrayAux {as : List α} {xs : Array α} :
(as.toArrayAux xs).size = xs.size + as.length := by
simp [size]
List.toArray_cons
theorem
(a : α) (l : List α) : (a :: l).toArray = #[a] ++ l.toArray
List.push_toArray
theorem
(l : List α) (a : α) : l.toArray.push a = (l ++ [a]).toArray
List.push_toArray_fun
theorem
(l : List α) : l.toArray.push = fun a => (l ++ [a]).toArray
List.isEmpty_toArray
theorem
(l : List α) : l.toArray.isEmpty = l.isEmpty
@[simp] theorem isEmpty_toArray (l : List α) : l.toArray.isEmpty = l.isEmpty := by
cases l <;> simp [Array.isEmpty]
List.toArray_singleton
theorem
(a : α) : (List.singleton a).toArray = Array.singleton a
@[simp] theorem toArray_singleton (a : α) : (List.singleton a).toArray = Array.singleton a := rfl
List.back!_toArray
theorem
[Inhabited α] (l : List α) : l.toArray.back! = l.getLast!
@[simp] theorem back!_toArray [Inhabited α] (l : List α) : l.toArray.back! = l.getLast! := by
simp only [back!, size_toArray, getElem!_toArray, getLast!_eq_getElem!]
List.back?_toArray
theorem
(l : List α) : l.toArray.back? = l.getLast?
@[simp] theorem back?_toArray (l : List α) : l.toArray.back? = l.getLast? := by
simp [back?, List.getLast?_eq_getElem?]
List.back_toArray
theorem
(l : List α) (h) : l.toArray.back = l.getLast (by simp at h; exact ne_nil_of_length_pos h)
@[simp] theorem back_toArray (l : List α) (h) :
l.toArray.back = l.getLast (by simp at h; exact ne_nil_of_length_pos h) := by
simp [back, List.getLast_eq_getElem]
Array.getLast!_toList
theorem
[Inhabited α] (xs : Array α) : xs.toList.getLast! = xs.back!
Array.getLast?_toList
theorem
(xs : Array α) : xs.toList.getLast? = xs.back?
@[simp] theorem _root_.Array.getLast?_toList (xs : Array α) :
xs.toList.getLast? = xs.back? := by
rcases xs with ⟨xs⟩
simp
Array.getLast_toList
theorem
(xs : Array α) (h) : xs.toList.getLast h = xs.back (by simpa [ne_nil_iff_length_pos] using h)
@[simp] theorem _root_.Array.getLast_toList (xs : Array α) (h) :
xs.toList.getLast h = xs.back (by simpa [ne_nil_iff_length_pos] using h) := by
rcases xs with ⟨xs⟩
simp
List.set_toArray
theorem
(l : List α) (i : Nat) (a : α) (h : i < l.length) : (l.toArray.set i a) = (l.set i a).toArray
List.forIn'_loop_toArray
theorem
[Monad m] (l : List α) (f : (a : α) → a ∈ l.toArray → β → m (ForInStep β)) (i : Nat) (h : i ≤ l.length) (b : β) :
Array.forIn'.loop l.toArray f i h b =
forIn' (l.drop (l.length - i)) b (fun a m b => f a (by simpa using mem_of_mem_drop m) b)
@[simp] theorem forIn'_loop_toArray [Monad m] (l : List α) (f : (a : α) → a ∈ l.toArray → β → m (ForInStep β)) (i : Nat)
(h : i ≤ l.length) (b : β) :
Array.forIn'.loop l.toArray f i h b =
forIn' (l.drop (l.length - i)) b (fun a m b => f a (by simpa using mem_of_mem_drop m) b) := by
induction i generalizing l b with
| zero =>
simp [Array.forIn'.loop]
| succ i ih =>
simp only [Array.forIn'.loop, size_toArray, getElem_toArray, ih]
have t : drop (l.length - (i + 1)) l = l[l.length - i - 1]l[l.length - i - 1] :: drop (l.length - i) l := by
simp only [Nat.sub_add_eq]
rw [List.drop_sub_one (by omega), List.getElem?_eq_getElem (by omega)]
simp only [Option.toList_some, singleton_append]
simp [t]
have t : l.length - 1 - i = l.length - i - 1 := by omega
simp only [t]
congr
List.forIn'_toArray
theorem
[Monad m] (l : List α) (b : β) (f : (a : α) → a ∈ l.toArray → β → m (ForInStep β)) :
forIn' l.toArray b f = forIn' l b (fun a m b => f a (mem_toArray.mpr m) b)
@[simp] theorem forIn'_toArray [Monad m] (l : List α) (b : β) (f : (a : α) → a ∈ l.toArray → β → m (ForInStep β)) :
forIn' l.toArray b f = forIn' l b (fun a m b => f a (mem_toArray.mpr m) b) := by
change Array.forIn' _ _ _ = List.forIn' _ _ _
rw [Array.forIn', forIn'_loop_toArray]
simp
List.forIn_toArray
theorem
[Monad m] (l : List α) (b : β) (f : α → β → m (ForInStep β)) : forIn l.toArray b f = forIn l b f
@[simp] theorem forIn_toArray [Monad m] (l : List α) (b : β) (f : α → β → m (ForInStep β)) :
forIn l.toArray b f = forIn l b f := by
simpa using forIn'_toArray l b fun a m b => f a b
List.foldrM_toArray
theorem
[Monad m] (f : α → β → m β) (init : β) (l : List α) : l.toArray.foldrM f init = l.foldrM f init
theorem foldrM_toArray [Monad m] (f : α → β → m β) (init : β) (l : List α) :
l.toArray.foldrM f init = l.foldrM f init := by
rw [foldrM_eq_reverse_foldlM_toList]
simp
List.foldlM_toArray
theorem
[Monad m] (f : β → α → m β) (init : β) (l : List α) : l.toArray.foldlM f init = l.foldlM f init
theorem foldlM_toArray [Monad m] (f : β → α → m β) (init : β) (l : List α) :
l.toArray.foldlM f init = l.foldlM f init := by
rw [foldlM_toList]
List.foldr_toArray
theorem
(f : α → β → β) (init : β) (l : List α) : l.toArray.foldr f init = l.foldr f init
theorem foldr_toArray (f : α → β → β) (init : β) (l : List α) :
l.toArray.foldr f init = l.foldr f init := by
rw [foldr_toList]
List.foldl_toArray
theorem
(f : β → α → β) (init : β) (l : List α) : l.toArray.foldl f init = l.foldl f init
theorem foldl_toArray (f : β → α → β) (init : β) (l : List α) :
l.toArray.foldl f init = l.foldl f init := by
rw [foldl_toList]
List.foldrM_toArray'
theorem
[Monad m] (f : α → β → m β) (init : β) (l : List α) (h : start = l.toArray.size) :
l.toArray.foldrM f init start 0 = l.foldrM f init
/-- Variant of `foldrM_toArray` with a side condition for the `start` argument. -/
@[simp] theorem foldrM_toArray' [Monad m] (f : α → β → m β) (init : β) (l : List α)
(h : start = l.toArray.size) :
l.toArray.foldrM f init start 0 = l.foldrM f init := by
subst h
rw [foldrM_eq_reverse_foldlM_toList]
simp
List.foldlM_toArray'
theorem
[Monad m] (f : β → α → m β) (init : β) (l : List α) (h : stop = l.toArray.size) :
l.toArray.foldlM f init 0 stop = l.foldlM f init
/-- Variant of `foldlM_toArray` with a side condition for the `stop` argument. -/
@[simp] theorem foldlM_toArray' [Monad m] (f : β → α → m β) (init : β) (l : List α)
(h : stop = l.toArray.size) :
l.toArray.foldlM f init 0 stop = l.foldlM f init := by
subst h
rw [foldlM_toList]
List.forM_toArray'
theorem
[Monad m] (l : List α) (f : α → m PUnit) (h : stop = l.toArray.size) : (l.toArray.forM f 0 stop) = l.forM f
/-- Variant of `forM_toArray` with a side condition for the `stop` argument. -/
@[simp] theorem forM_toArray' [Monad m] (l : List α) (f : α → m PUnit) (h : stop = l.toArray.size) :
(l.toArray.forM f 0 stop) = l.forM f := by
subst h
rw [Array.forM]
simp only [size_toArray, foldlM_toArray']
induction l <;> simp_all
List.forM_toArray
theorem
[Monad m] (l : List α) (f : α → m PUnit) : (forM l.toArray f) = l.forM f
@[simp]
theorem forM_toArray [Monad m] (l : List α) (f : α → m PUnit) :
(forM l.toArray f) = l.forM f :=
forM_toArray' l f rfl
List.foldr_toArray'
theorem
(f : α → β → β) (init : β) (l : List α) (h : start = l.toArray.size) : l.toArray.foldr f init start 0 = l.foldr f init
/-- Variant of `foldr_toArray` with a side condition for the `start` argument. -/
@[simp] theorem foldr_toArray' (f : α → β → β) (init : β) (l : List α)
(h : start = l.toArray.size) :
l.toArray.foldr f init start 0 = l.foldr f init := by
subst h
rw [foldr_toList]
List.foldl_toArray'
theorem
(f : β → α → β) (init : β) (l : List α) (h : stop = l.toArray.size) : l.toArray.foldl f init 0 stop = l.foldl f init
/-- Variant of `foldl_toArray` with a side condition for the `stop` argument. -/
@[simp] theorem foldl_toArray' (f : β → α → β) (init : β) (l : List α)
(h : stop = l.toArray.size) :
l.toArray.foldl f init 0 stop = l.foldl f init := by
subst h
rw [foldl_toList]
List.sum_toArray
theorem
[Add α] [Zero α] (l : List α) : l.toArray.sum = l.sum
List.append_toArray
theorem
(l₁ l₂ : List α) : l₁.toArray ++ l₂.toArray = (l₁ ++ l₂).toArray
List.push_append_toArray
theorem
{as : Array α} {a : α} {bs : List α} : as.push a ++ bs.toArray = as ++ (a :: bs).toArray
List.foldl_push
theorem
{l : List α} {as : Array α} : l.foldl Array.push as = as ++ l.toArray
@[simp] theorem foldl_push {l : List α} {as : Array α} : l.foldl Array.push as = as ++ l.toArray := by
induction l generalizing as <;> simp [*]
List.foldr_push
theorem
{l : List α} {as : Array α} : l.foldr (fun a bs => push bs a) as = as ++ l.reverse.toArray
@[simp] theorem foldr_push {l : List α} {as : Array α} : l.foldr (fun a bs => push bs a) as = as ++ l.reverse.toArray := by
rw [foldr_eq_foldl_reverse, foldl_push]
List.findSomeM?_toArray
theorem
[Monad m] [LawfulMonad m] (f : α → m (Option β)) (l : List α) : l.toArray.findSomeM? f = l.findSomeM? f
@[simp] theorem findSomeM?_toArray [Monad m] [LawfulMonad m] (f : α → m (Option β)) (l : List α) :
l.toArray.findSomeM? f = l.findSomeM? f := by
rw [Array.findSomeM?]
simp only [bind_pure_comp, map_pure, forIn_toArray]
induction l with
| nil => simp
| cons a l ih =>
simp only [forIn_cons, LawfulMonad.bind_assoc, findSomeM?]
congr
ext1 (_|_) <;> simp [ih]
List.findSomeRevM?_find_toArray
theorem
[Monad m] [LawfulMonad m] (f : α → m (Option β)) (l : List α) (i : Nat) (h) :
findSomeRevM?.find f l.toArray i h = (l.take i).reverse.findSomeM? f
theorem findSomeRevM?_find_toArray [Monad m] [LawfulMonad m] (f : α → m (Option β)) (l : List α)
(i : Nat) (h) :
findSomeRevM?.find f l.toArray i h = (l.take i).reverse.findSomeM? f := by
induction i generalizing l with
| zero => simp [Array.findSomeRevM?.find.eq_def]
| succ i ih =>
rw [size_toArray] at h
rw [Array.findSomeRevM?.find, take_succ, getElem?_eq_getElem (by omega)]
simp only [ih, reverse_append]
congr
ext1 (_|_) <;> simp
List.findSomeRevM?_toArray
theorem
[Monad m] [LawfulMonad m] (f : α → m (Option β)) (l : List α) : l.toArray.findSomeRevM? f = l.reverse.findSomeM? f
theorem findSomeRevM?_toArray [Monad m] [LawfulMonad m] (f : α → m (Option β)) (l : List α) :
l.toArray.findSomeRevM? f = l.reverse.findSomeM? f := by
simp [Array.findSomeRevM?, findSomeRevM?_find_toArray]
List.findRevM?_toArray
theorem
[Monad m] [LawfulMonad m] (f : α → m Bool) (l : List α) : l.toArray.findRevM? f = l.reverse.findM? f
theorem findRevM?_toArray [Monad m] [LawfulMonad m] (f : α → m Bool) (l : List α) :
l.toArray.findRevM? f = l.reverse.findM? f := by
rw [Array.findRevM?, findSomeRevM?_toArray, findM?_eq_findSomeM?]
List.findM?_toArray
theorem
[Monad m] [LawfulMonad m] (f : α → m Bool) (l : List α) : l.toArray.findM? f = l.findM? f
@[simp] theorem findM?_toArray [Monad m] [LawfulMonad m] (f : α → m Bool) (l : List α) :
l.toArray.findM? f = l.findM? f := by
rw [Array.findM?]
simp only [bind_pure_comp, map_pure, forIn_toArray]
induction l with
| nil => simp
| cons a l ih =>
simp only [forIn_cons, LawfulMonad.bind_assoc, findM?]
congr
ext1 (_|_) <;> simp [ih]
List.findSome?_toArray
theorem
(f : α → Option β) (l : List α) : l.toArray.findSome? f = l.findSome? f
@[simp] theorem findSome?_toArray (f : α → Option β) (l : List α) :
l.toArray.findSome? f = l.findSome? f := by
rw [Array.findSome?, ← findSomeM?_id, findSomeM?_toArray, Id.run]
List.find?_toArray
theorem
(f : α → Bool) (l : List α) : l.toArray.find? f = l.find? f
@[simp] theorem find?_toArray (f : α → Bool) (l : List α) :
l.toArray.find? f = l.find? f := by
rw [Array.find?]
simp only [Id.run, Id, Id.pure_eq, Id.bind_eq, forIn_toArray]
induction l with
| nil => simp
| cons a l ih =>
simp only [forIn_cons, Id.pure_eq, Id.bind_eq, find?]
by_cases f a <;> simp_all
List.findFinIdx?_toArray
theorem
(p : α → Bool) (l : List α) : l.toArray.findFinIdx? p = l.findFinIdx? p
@[simp] theorem findFinIdx?_toArray (p : α → Bool) (l : List α) :
l.toArray.findFinIdx? p = l.findFinIdx? p := by
rw [Array.findFinIdx?, findFinIdx?, findFinIdx?_loop_toArray]
simp
List.findIdx?_toArray
theorem
(p : α → Bool) (l : List α) : l.toArray.findIdx? p = l.findIdx? p
@[simp] theorem findIdx?_toArray (p : α → Bool) (l : List α) :
l.toArray.findIdx? p = l.findIdx? p := by
rw [Array.findIdx?_eq_map_findFinIdx?_val, findIdx?_eq_map_findFinIdx?_val]
simp
List.finIdxOf?_toArray
theorem
[BEq α] (a : α) (l : List α) : l.toArray.finIdxOf? a = l.finIdxOf? a
@[simp] theorem finIdxOf?_toArray [BEq α] (a : α) (l : List α) :
l.toArray.finIdxOf? a = l.finIdxOf? a := by
rw [Array.finIdxOf?, finIdxOf?, findFinIdx?]
simp [idxAuxOf_toArray]
List.idxOf?_toArray
theorem
[BEq α] (a : α) (l : List α) : l.toArray.idxOf? a = l.idxOf? a
@[simp] theorem idxOf?_toArray [BEq α] (a : α) (l : List α) :
l.toArray.idxOf? a = l.idxOf? a := by
rw [Array.idxOf?, idxOf?]
simp [finIdxOf?, findIdx?_eq_map_findFinIdx?_val]
List.findIdx_toArray
theorem
{as : List α} {p : α → Bool} : as.toArray.findIdx p = as.findIdx p
@[simp] theorem findIdx_toArray {as : List α} {p : α → Bool} :
as.toArray.findIdx p = as.findIdx p := by
rw [Array.findIdx, findIdx?_toArray, findIdx_eq_getD_findIdx?]
List.idxOf_toArray
theorem
[BEq α] {as : List α} {a : α} : as.toArray.idxOf a = as.idxOf a
@[simp] theorem idxOf_toArray [BEq α] {as : List α} {a : α} :
as.toArray.idxOf a = as.idxOf a := by
rw [Array.idxOf, findIdx_toArray, idxOf]
List.isPrefixOfAux_toArray_succ
theorem
[BEq α] (l₁ l₂ : List α) (hle : l₁.length ≤ l₂.length) (i : Nat) :
Array.isPrefixOfAux l₁.toArray l₂.toArray hle (i + 1) =
Array.isPrefixOfAux l₁.tail.toArray l₂.tail.toArray (by simp; omega) i
theorem isPrefixOfAux_toArray_succ [BEq α] (l₁ l₂ : List α) (hle : l₁.length ≤ l₂.length) (i : Nat) :
Array.isPrefixOfAux l₁.toArray l₂.toArray hle (i + 1) =
Array.isPrefixOfAux l₁.tail.toArray l₂.tail.toArray (by simp; omega) i := by
rw [Array.isPrefixOfAux]
conv => rhs; rw [Array.isPrefixOfAux]
simp only [size_toArray, getElem_toArray, Bool.if_false_right, length_tail, getElem_tail]
split <;> rename_i h₁ <;> split <;> rename_i h₂
· rw [isPrefixOfAux_toArray_succ]
· omega
· omega
· rfl
List.isPrefixOfAux_toArray_succ'
theorem
[BEq α] (l₁ l₂ : List α) (hle : l₁.length ≤ l₂.length) (i : Nat) :
Array.isPrefixOfAux l₁.toArray l₂.toArray hle (i + 1) =
Array.isPrefixOfAux (l₁.drop (i + 1)).toArray (l₂.drop (i + 1)).toArray (by simp; omega) 0
theorem isPrefixOfAux_toArray_succ' [BEq α] (l₁ l₂ : List α) (hle : l₁.length ≤ l₂.length) (i : Nat) :
Array.isPrefixOfAux l₁.toArray l₂.toArray hle (i + 1) =
Array.isPrefixOfAux (l₁.drop (i+1)).toArray (l₂.drop (i+1)).toArray (by simp; omega) 0 := by
induction i generalizing l₁ l₂ with
| zero => simp [isPrefixOfAux_toArray_succ]
| succ i ih =>
rw [isPrefixOfAux_toArray_succ, ih]
simp
List.isPrefixOfAux_toArray_zero
theorem
[BEq α] (l₁ l₂ : List α) (hle : l₁.length ≤ l₂.length) :
Array.isPrefixOfAux l₁.toArray l₂.toArray hle 0 = l₁.isPrefixOf l₂
theorem isPrefixOfAux_toArray_zero [BEq α] (l₁ l₂ : List α) (hle : l₁.length ≤ l₂.length) :
Array.isPrefixOfAux l₁.toArray l₂.toArray hle 0 =
l₁.isPrefixOf l₂ := by
rw [Array.isPrefixOfAux]
match l₁, l₂ with
| [], _ => rw [dif_neg] <;> simp
| _::_, [] => simp at hle
| a::l₁, b::l₂ =>
simp [isPrefixOf_cons₂, isPrefixOfAux_toArray_succ', isPrefixOfAux_toArray_zero]
List.isPrefixOf_toArray
theorem
[BEq α] (l₁ l₂ : List α) : l₁.toArray.isPrefixOf l₂.toArray = l₁.isPrefixOf l₂
@[simp] theorem isPrefixOf_toArray [BEq α] (l₁ l₂ : List α) :
l₁.toArray.isPrefixOf l₂.toArray = l₁.isPrefixOf l₂ := by
rw [Array.isPrefixOf]
split <;> rename_i h
· simp [isPrefixOfAux_toArray_zero]
· simp only [Bool.false_eq]
induction l₁ generalizing l₂ with
| nil => simp at h
| cons a l₁ ih =>
cases l₂ with
| nil => simp
| cons b l₂ =>
simp only [isPrefixOf_cons₂, Bool.and_eq_false_imp]
intro w
rw [ih]
simp_all
List.zipWithAux_toArray_succ
theorem
(as : List α) (bs : List β) (f : α → β → γ) (i : Nat) (xs : Array γ) :
zipWithAux as.toArray bs.toArray f (i + 1) xs = zipWithAux as.tail.toArray bs.tail.toArray f i xs
theorem zipWithAux_toArray_succ (as : List α) (bs : List β) (f : α → β → γ) (i : Nat) (xs : Array γ) :
zipWithAux as.toArray bs.toArray f (i + 1) xs = zipWithAux as.tail.toArray bs.tail.toArray f i xs := by
rw [zipWithAux]
conv => rhs; rw [zipWithAux]
simp only [size_toArray, getElem_toArray, length_tail, getElem_tail]
split <;> rename_i h₁
· split <;> rename_i h₂
· rw [dif_pos (by omega), dif_pos (by omega), zipWithAux_toArray_succ]
· rw [dif_pos (by omega)]
rw [dif_neg (by omega)]
· rw [dif_neg (by omega)]
List.zipWithAux_toArray_succ'
theorem
(as : List α) (bs : List β) (f : α → β → γ) (i : Nat) (xs : Array γ) :
zipWithAux as.toArray bs.toArray f (i + 1) xs = zipWithAux (as.drop (i + 1)).toArray (bs.drop (i + 1)).toArray f 0 xs
theorem zipWithAux_toArray_succ' (as : List α) (bs : List β) (f : α → β → γ) (i : Nat) (xs : Array γ) :
zipWithAux as.toArray bs.toArray f (i + 1) xs = zipWithAux (as.drop (i+1)).toArray (bs.drop (i+1)).toArray f 0 xs := by
induction i generalizing as bs xs with
| zero => simp [zipWithAux_toArray_succ]
| succ i ih =>
rw [zipWithAux_toArray_succ, ih]
simp
List.zipWithAux_toArray_zero
theorem
(f : α → β → γ) (as : List α) (bs : List β) (xs : Array γ) :
zipWithAux as.toArray bs.toArray f 0 xs = xs ++ (List.zipWith f as bs).toArray
theorem zipWithAux_toArray_zero (f : α → β → γ) (as : List α) (bs : List β) (xs : Array γ) :
zipWithAux as.toArray bs.toArray f 0 xs = xs ++ (List.zipWith f as bs).toArray := by
rw [Array.zipWithAux]
match as, bs with
| [], _ => simp
| _, [] => simp
| a :: as, b :: bs =>
simp [zipWith_cons_cons, zipWithAux_toArray_succ', zipWithAux_toArray_zero, push_append_toArray]
List.zipWith_toArray
theorem
(as : List α) (bs : List β) (f : α → β → γ) : Array.zipWith f as.toArray bs.toArray = (List.zipWith f as bs).toArray
@[simp] theorem zipWith_toArray (as : List α) (bs : List β) (f : α → β → γ) :
Array.zipWith f as.toArray bs.toArray = (List.zipWith f as bs).toArray := by
rw [Array.zipWith]
simp [zipWithAux_toArray_zero]
List.zip_toArray
theorem
(as : List α) (bs : List β) : Array.zip as.toArray bs.toArray = (List.zip as bs).toArray
List.zipWithAll_go_toArray
theorem
(as : List α) (bs : List β) (f : Option α → Option β → γ) (i : Nat) (xs : Array γ) :
zipWithAll.go f as.toArray bs.toArray i xs = xs ++ (List.zipWithAll f (as.drop i) (bs.drop i)).toArray
theorem zipWithAll_go_toArray (as : List α) (bs : List β) (f : Option α → Option β → γ) (i : Nat) (xs : Array γ) :
zipWithAll.go f as.toArray bs.toArray i xs = xs ++ (List.zipWithAll f (as.drop i) (bs.drop i)).toArray := by
unfold zipWithAll.go
split <;> rename_i h
· rw [zipWithAll_go_toArray]
simp at h
simp only [getElem?_toArray, push_append_toArray]
if ha : i < as.length then
if hb : i < bs.length then
rw [List.drop_eq_getElem_cons ha, List.drop_eq_getElem_cons hb]
simp only [ha, hb, getElem?_eq_getElem, zipWithAll_cons_cons]
else
simp only [Nat.not_lt] at hb
rw [List.drop_eq_getElem_cons ha]
rw [(drop_eq_nil_iff (l := bs)).mpr (by omega), (drop_eq_nil_iff (l := bs)).mpr (by omega)]
simp only [zipWithAll_nil, map_drop, map_cons]
rw [getElem?_eq_getElem ha]
rw [getElem?_eq_none hb]
else
if hb : i < bs.length then
simp only [Nat.not_lt] at ha
rw [List.drop_eq_getElem_cons hb]
rw [(drop_eq_nil_iff (l := as)).mpr (by omega), (drop_eq_nil_iff (l := as)).mpr (by omega)]
simp only [nil_zipWithAll, map_drop, map_cons]
rw [getElem?_eq_getElem hb]
rw [getElem?_eq_none ha]
else
omega
· simp only [size_toArray, Nat.not_lt] at h
rw [drop_eq_nil_of_le (by omega), drop_eq_nil_of_le (by omega)]
simp
termination_by max as.length bs.length - i
decreasing_by simp_wf; decreasing_trivial_pre_omega
List.zipWithAll_toArray
theorem
(f : Option α → Option β → γ) (as : List α) (bs : List β) :
Array.zipWithAll f as.toArray bs.toArray = (List.zipWithAll f as bs).toArray
@[simp] theorem zipWithAll_toArray (f : Option α → Option β → γ) (as : List α) (bs : List β) :
Array.zipWithAll f as.toArray bs.toArray = (List.zipWithAll f as bs).toArray := by
simp [Array.zipWithAll, zipWithAll_go_toArray]
List.toArray_appendList
theorem
(l₁ l₂ : List α) : l₁.toArray ++ l₂ = (l₁ ++ l₂).toArray
@[simp] theorem toArray_appendList (l₁ l₂ : List α) :
l₁.toArray ++ l₂ = (l₁ ++ l₂).toArray := by
apply ext'
simp
List.pop_toArray
theorem
(l : List α) : l.toArray.pop = l.dropLast.toArray
List.takeWhile_go_succ
theorem
(p : α → Bool) (a : α) (l : List α) (i : Nat) :
takeWhile.go p (a :: l).toArray (i + 1) r = takeWhile.go p l.toArray i r
theorem takeWhile_go_succ (p : α → Bool) (a : α) (l : List α) (i : Nat) :
takeWhile.go p (a :: l).toArray (i+1) r = takeWhile.go p l.toArray i r := by
rw [takeWhile.go, takeWhile.go]
simp only [size_toArray, length_cons, Nat.add_lt_add_iff_right,
getElem_toArray, getElem_cons_succ]
split
rw [takeWhile_go_succ]
rfl
List.takeWhile_go_toArray
theorem
(p : α → Bool) (l : List α) (i : Nat) : Array.takeWhile.go p l.toArray i r = r ++ (takeWhile p (l.drop i)).toArray
theorem takeWhile_go_toArray (p : α → Bool) (l : List α) (i : Nat) :
Array.takeWhile.go p l.toArray i r = r ++ (takeWhile p (l.drop i)).toArray := by
induction l generalizing i r with
| nil => simp [takeWhile.go]
| cons a l ih =>
rw [takeWhile.go]
cases i with
| zero =>
simp [takeWhile_go_succ, ih, takeWhile_cons]
split <;> simp
| succ i =>
simp only [size_toArray, length_cons, Nat.add_lt_add_iff_right,
getElem_toArray, getElem_cons_succ, drop_succ_cons]
split <;> rename_i h₁
· rw [takeWhile_go_succ, ih]
rw [← getElem_cons_drop_succ_eq_drop h₁, takeWhile_cons]
split <;> simp_all
· simp_all [drop_eq_nil_of_le]
List.takeWhile_toArray
theorem
(p : α → Bool) (l : List α) : l.toArray.takeWhile p = (l.takeWhile p).toArray
@[simp] theorem takeWhile_toArray (p : α → Bool) (l : List α) :
l.toArray.takeWhile p = (l.takeWhile p).toArray := by
simp [Array.takeWhile, takeWhile_go_toArray]
List.popWhile_toArray
theorem
(p : α → Bool) (l : List α) : l.toArray.popWhile p = (l.reverse.dropWhile p).reverse.toArray
List.setIfInBounds_toArray
theorem
(l : List α) (i : Nat) (a : α) : l.toArray.setIfInBounds i a = (l.set i a).toArray
@[simp] theorem setIfInBounds_toArray (l : List α) (i : Nat) (a : α) :
l.toArray.setIfInBounds i a = (l.set i a).toArray := by
apply ext'
simp only [setIfInBounds]
split
· simp
· simp_all [List.set_eq_of_length_le]
List.toArray_replicate
theorem
(n : Nat) (v : α) : (List.replicate n v).toArray = Array.replicate n v
@[simp] theorem toArray_replicate (n : Nat) (v : α) :
(List.replicate n v).toArray = Array.replicate n v := rfl
Array.replicate_eq_toArray_replicate
theorem
: Array.replicate n v = (List.replicate n v).toArray
theorem _root_.Array.replicate_eq_toArray_replicate :
Array.replicate n v = (List.replicate n v).toArray := by
simp
Array.mkArray_eq_toArray_replicate
abbrev
@[deprecated _root_.Array.replicate_eq_toArray_replicate (since := "2025-03-18")]
abbrev _root_.Array.mkArray_eq_toArray_replicate := @_root_.Array.replicate_eq_toArray_replicate
List.flatMap_empty
theorem
{β} (f : α → Array β) : (#[] : Array α).flatMap f = #[]
List.flatMap_toArray_cons
theorem
{β} (f : α → Array β) (a : α) (as : List α) : (a :: as).toArray.flatMap f = f a ++ as.toArray.flatMap f
theorem flatMap_toArray_cons {β} (f : α → Array β) (a : α) (as : List α) :
(a :: as).toArray.flatMap f = f a ++ as.toArray.flatMap f := by
simp [Array.flatMap]
suffices ∀ xs, List.foldl (fun ys a => ys ++ f a) (f a ++ xs) as =
f a ++ List.foldl (fun ys a => ys ++ f a) xs as by
erw [empty_append] -- Why doesn't this work via `simp`?
simpa using this #[]
intro xs
induction as generalizing xs <;> simp_all
List.flatMap_toArray
theorem
{β} (f : α → Array β) (as : List α) : as.toArray.flatMap f = (as.flatMap (fun a => (f a).toList)).toArray
List.swap_toArray
theorem
(l : List α) (i j : Nat) {hi hj} : l.toArray.swap i j hi hj = ((l.set i l[j]).set j l[i]).toArray
List.eraseIdx_toArray
theorem
(l : List α) (i : Nat) (h : i < l.toArray.size) : l.toArray.eraseIdx i h = (l.eraseIdx i).toArray
@[simp] theorem eraseIdx_toArray (l : List α) (i : Nat) (h : i < l.toArray.size) :
l.toArray.eraseIdx i h = (l.eraseIdx i).toArray := by
rw [Array.eraseIdx]
split <;> rename_i h'
· rw [eraseIdx_toArray]
simp only [swap_toArray, Fin.getElem_fin, toList_toArray, mk.injEq]
rw [eraseIdx_set_gt (by simp), eraseIdx_set_eq]
simp
· simp at h h'
have t : i = l.length - 1 := by omega
simp [t]
termination_by l.length - i
decreasing_by
rename_i h
simp at h
simp
omega
List.eraseIdxIfInBounds_toArray
theorem
(l : List α) (i : Nat) : l.toArray.eraseIdxIfInBounds i = (l.eraseIdx i).toArray
@[simp] theorem eraseIdxIfInBounds_toArray (l : List α) (i : Nat) :
l.toArray.eraseIdxIfInBounds i = (l.eraseIdx i).toArray := by
rw [Array.eraseIdxIfInBounds]
split
· simp
· simp_all [eraseIdx_eq_self.2]
List.eraseP_toArray
theorem
{as : List α} {p : α → Bool} : as.toArray.eraseP p = (as.eraseP p).toArray
@[simp] theorem eraseP_toArray {as : List α} {p : α → Bool} :
as.toArray.eraseP p = (as.eraseP p).toArray := by
rw [Array.eraseP, List.eraseP_eq_eraseIdx, findFinIdx?_toArray]
split <;> simp [*, findIdx?_eq_map_findFinIdx?_val]
List.erase_toArray
theorem
[BEq α] {as : List α} {a : α} : as.toArray.erase a = (as.erase a).toArray
@[simp] theorem erase_toArray [BEq α] {as : List α} {a : α} :
as.toArray.erase a = (as.erase a).toArray := by
rw [Array.erase, finIdxOf?_toArray, List.erase_eq_eraseIdx]
rw [idxOf?_eq_map_finIdxOf?_val]
split <;> simp_all
List.insertIdx_toArray
theorem
(l : List α) (i : Nat) (a : α) (h : i ≤ l.toArray.size) : l.toArray.insertIdx i a = (l.insertIdx i a).toArray
@[simp] theorem insertIdx_toArray (l : List α) (i : Nat) (a : α) (h : i ≤ l.toArray.size):
l.toArray.insertIdx i a = (l.insertIdx i a).toArray := by
rw [Array.insertIdx]
rw [insertIdx_loop_toArray (h := h)]
ext j h₁ h₂
· simp at h
simp [length_insertIdx, h]
omega
· simp [length_insertIdx] at h₁ h₂
simp [getElem_insertIdx]
split <;> rename_i h₃
· rw [getElem_append_left (by simp; split at h₂ <;> omega)]
simp only [getElem_take]
rw [getElem_append_left]
· rw [getElem_append_right (by simp; omega)]
rw [getElem_cons]
simp
split <;> rename_i h₄
· rw [dif_pos (by omega)]
· rw [dif_neg (by omega)]
congr
omega
List.insertIdxIfInBounds_toArray
theorem
(l : List α) (i : Nat) (a : α) : l.toArray.insertIdxIfInBounds i a = (l.insertIdx i a).toArray
@[simp] theorem insertIdxIfInBounds_toArray (l : List α) (i : Nat) (a : α) :
l.toArray.insertIdxIfInBounds i a = (l.insertIdx i a).toArray := by
rw [Array.insertIdxIfInBounds]
split <;> rename_i h'
· simp
· simp only [size_toArray, Nat.not_le] at h'
rw [List.insertIdx_of_length_lt (h := h')]
List.replace_toArray
theorem
[BEq α] [LawfulBEq α] (l : List α) (a b : α) : l.toArray.replace a b = (l.replace a b).toArray
@[simp]
theorem replace_toArray [BEq α] [LawfulBEq α] (l : List α) (a b : α) :
l.toArray.replace a b = (l.replace a b).toArray := by
rw [Array.replace]
split <;> rename_i i h
· simp only [finIdxOf?_toArray, finIdxOf?_eq_none_iff] at h
rw [replace_of_not_mem]
simpa
· simp_all only [finIdxOf?_toArray, finIdxOf?_eq_some_iff, Fin.getElem_fin, set_toArray,
mk.injEq]
apply List.ext_getElem
· simp
· intro j h₁ h₂
rw [List.getElem_replace, List.getElem_set]
by_cases h₃ : j < i
· rw [if_neg (by omega), if_neg]
simp only [length_set] at h₁ h₃
simpa using h.2 ⟨j, by omega⟩ h₃
· by_cases h₃ : j = i
· rw [if_pos (by omega), if_pos, if_neg]
· simp only [mem_take_iff_getElem, not_exists]
intro k hk
simpa using h.2 ⟨k, by omega⟩ (by show k < i.1; omega)
· subst h₃
simpa using h.1
· rw [if_neg (by omega)]
split
· rw [if_pos]
· simp_all
· simp only [mem_take_iff_getElem]
simp only [length_set] at h₁
exact ⟨i, by omega, h.1⟩
· rfl
List.leftpad_toArray
theorem
(n : Nat) (a : α) (l : List α) : Array.leftpad n a l.toArray = (leftpad n a l).toArray
@[simp] theorem leftpad_toArray (n : Nat) (a : α) (l : List α) :
Array.leftpad n a l.toArray = (leftpad n a l).toArray := by
simp [leftpad, Array.leftpad, ← toArray_replicate]
List.rightpad_toArray
theorem
(n : Nat) (a : α) (l : List α) : Array.rightpad n a l.toArray = (rightpad n a l).toArray
@[simp] theorem rightpad_toArray (n : Nat) (a : α) (l : List α) :
Array.rightpad n a l.toArray = (rightpad n a l).toArray := by
simp [rightpad, Array.rightpad, ← toArray_replicate]