Documentation

Init.Data.Array.Lemmas

Theorems about Array. #

Preliminaries #

toList #

@[simp]
theorem Array.toList_inj {α : Type u_1} {a b : Array α} :
a.toList = b.toList a = b
@[simp]
theorem Array.toList_eq_nil_iff {α : Type u_1} (l : Array α) :
l.toList = [] l = #[]
@[simp]
theorem Array.mem_toList_iff {α : Type u_1} (a : α) (l : Array α) :
a l.toList a l

empty #

@[simp]
theorem Array.empty_eq {α : Type u_1} {xs : Array α} :
#[] = xs xs = #[]

size #

theorem Array.eq_empty_of_size_eq_zero {α✝ : Type u_1} {l : Array α✝} (h : l.size = 0) :
l = #[]
theorem Array.ne_empty_of_size_eq_add_one {n : Nat} {α✝ : Type u_1} {l : Array α✝} (h : l.size = n + 1) :
l #[]
theorem Array.ne_empty_of_size_pos {α✝ : Type u_1} {l : Array α✝} (h : 0 < l.size) :
l #[]
theorem Array.size_eq_zero {α✝ : Type u_1} {l : Array α✝} :
l.size = 0 l = #[]
theorem Array.size_pos_of_mem {α : Type u_1} {a : α} {l : Array α} (h : a l) :
0 < l.size
theorem Array.exists_mem_of_size_pos {α : Type u_1} {l : Array α} (h : 0 < l.size) :
∃ (a : α), a l
theorem Array.size_pos_iff_exists_mem {α : Type u_1} {l : Array α} :
0 < l.size ∃ (a : α), a l
theorem Array.exists_mem_of_size_eq_add_one {α : Type u_1} {n : Nat} {l : Array α} (h : l.size = n + 1) :
∃ (a : α), a l
theorem Array.size_pos {α : Type u_1} {l : Array α} :
0 < l.size l #[]
theorem Array.size_eq_one {α : Type u_1} {l : Array α} :
l.size = 1 ∃ (a : α), l = #[a]

push #

theorem Array.push_ne_empty {α : Type u_1} {a : α} {xs : Array α} :
xs.push a #[]
@[simp]
theorem Array.push_ne_self {α : Type u_1} {a : α} {xs : Array α} :
xs.push a xs
@[simp]
theorem Array.ne_push_self {α : Type u_1} {a : α} {xs : Array α} :
xs xs.push a
theorem Array.back_eq_of_push_eq {α : Type u_1} {a b : α} {xs ys : Array α} (h : xs.push a = ys.push b) :
a = b
theorem Array.pop_eq_of_push_eq {α : Type u_1} {a b : α} {xs ys : Array α} (h : xs.push a = ys.push b) :
xs = ys
theorem Array.push_inj_left {α : Type u_1} {a : α} {xs ys : Array α} :
xs.push a = ys.push a xs = ys
theorem Array.push_inj_right {α : Type u_1} {a b : α} {xs : Array α} :
xs.push a = xs.push b a = b
theorem Array.push_eq_push {α : Type u_1} {a b : α} {xs ys : Array α} :
xs.push a = ys.push b a = b xs = ys
theorem Array.exists_push_of_ne_empty {α : Type u_1} {xs : Array α} (h : xs #[]) :
∃ (ys : Array α), ∃ (a : α), xs = ys.push a
theorem Array.ne_empty_iff_exists_push {α : Type u_1} {xs : Array α} :
xs #[] ∃ (ys : Array α), ∃ (a : α), xs = ys.push a
theorem Array.exists_push_of_size_pos {α : Type u_1} {xs : Array α} (h : 0 < xs.size) :
∃ (ys : Array α), ∃ (a : α), xs = ys.push a
theorem Array.size_pos_iff_exists_push {α : Type u_1} {xs : Array α} :
0 < xs.size ∃ (ys : Array α), ∃ (a : α), xs = ys.push a
theorem Array.exists_push_of_size_eq_add_one {α : Type u_1} {n : Nat} {xs : Array α} (h : xs.size = n + 1) :
∃ (ys : Array α), ∃ (a : α), xs = ys.push a
theorem Array.singleton_inj {α✝ : Type u_1} {a b : α✝} :
#[a] = #[b] a = b

mkArray #

@[simp]
theorem Array.size_mkArray {α : Type u_1} (n : Nat) (v : α) :
(mkArray n v).size = n
@[simp]
theorem Array.toList_mkArray {n : Nat} {α✝ : Type u_1} {a : α✝} :
(mkArray n a).toList = List.replicate n a
@[simp]
theorem Array.mkArray_zero {α✝ : Type u_1} {a : α✝} :
mkArray 0 a = #[]
theorem Array.mkArray_succ {n : Nat} {α✝ : Type u_1} {a : α✝} :
mkArray (n + 1) a = (mkArray n a).push a
theorem Array.mkArray_inj {n : Nat} {α✝ : Type u_1} {a : α✝} {m : Nat} {b : α✝} :
mkArray n a = mkArray m b n = m (n = 0 a = b)
@[simp]
theorem Array.getElem_mkArray {α : Type u_1} {i : Nat} (n : Nat) (v : α) (h : i < (mkArray n v).size) :
(mkArray n v)[i] = v
theorem Array.getElem?_mkArray {α : Type u_1} (n : Nat) (v : α) (i : Nat) :
(mkArray n v)[i]? = if i < n then some v else none

L[i] and L[i]? #

@[simp]
theorem Array.getElem?_eq_none_iff {α : Type u_1} {i : Nat} {a : Array α} :
a[i]? = none a.size i
@[simp]
theorem Array.none_eq_getElem?_iff {α : Type u_1} {a : Array α} {i : Nat} :
none = a[i]? a.size i
theorem Array.getElem?_eq_none {α : Type u_1} {i : Nat} {a : Array α} (h : a.size i) :
a[i]? = none
@[simp]
theorem Array.getElem?_eq_getElem {α : Type u_1} {a : Array α} {i : Nat} (h : i < a.size) :
a[i]? = some a[i]
theorem Array.getElem?_eq_some_iff {α : Type u_1} {i : Nat} {b : α} {a : Array α} :
a[i]? = some b ∃ (h : i < a.size), a[i] = b
theorem Array.some_eq_getElem?_iff {α : Type u_1} {b : α} {i : Nat} {a : Array α} :
some b = a[i]? ∃ (h : i < a.size), a[i] = b
@[simp]
theorem Array.some_getElem_eq_getElem?_iff {α : Type u_1} (a : Array α) (i : Nat) (h : i < a.size) :
some a[i] = a[i]? True
@[simp]
theorem Array.getElem?_eq_some_getElem_iff {α : Type u_1} (a : Array α) (i : Nat) (h : i < a.size) :
a[i]? = some a[i] True
theorem Array.getElem_eq_iff {α : Type u_1} {x : α} {a : Array α} {i : Nat} {h : i < a.size} :
a[i] = x a[i]? = some x
theorem Array.getElem_eq_getElem?_get {α : Type u_1} (a : Array α) (i : Nat) (h : i < a.size) :
a[i] = a[i]?.get
theorem Array.getD_getElem? {α : Type u_1} (a : Array α) (i : Nat) (d : α) :
a[i]?.getD d = if p : i < a.size then a[i] else d
@[simp]
theorem Array.getElem?_empty {α : Type u_1} {i : Nat} :
#[][i]? = none
theorem Array.getElem_push_lt {α : Type u_1} (a : Array α) (x : α) (i : Nat) (h : i < a.size) :
let_fun this := ; (a.push x)[i] = a[i]
@[simp]
theorem Array.getElem_push_eq {α : Type u_1} (a : Array α) (x : α) :
(a.push x)[a.size] = x
theorem Array.getElem_push {α : Type u_1} (a : Array α) (x : α) (i : Nat) (h : i < (a.push x).size) :
(a.push x)[i] = if h : i < a.size then a[i] else x
theorem Array.getElem?_push {α : Type u_1} {i : Nat} {a : Array α} {x : α} :
(a.push x)[i]? = if i = a.size then some x else a[i]?
@[simp]
theorem Array.getElem?_push_size {α : Type u_1} {a : Array α} {x : α} :
(a.push x)[a.size]? = some x
@[simp]
theorem Array.getElem_singleton {α : Type u_1} {i : Nat} (a : α) (h : i < 1) :
#[a][i] = a
theorem Array.getElem?_singleton {α : Type u_1} (a : α) (i : Nat) :
#[a][i]? = if i = 0 then some a else none

mem #

theorem Array.not_mem_empty {α : Type u_1} (a : α) :
¬a #[]
@[simp]
theorem Array.mem_push {α : Type u_1} {a : Array α} {x y : α} :
x a.push y x a x = y
theorem Array.mem_push_self {α : Type u_1} {a : Array α} {x : α} :
x a.push x
theorem Array.eq_push_append_of_mem {α : Type u_1} {xs : Array α} {x : α} (h : x xs) :
∃ (as : Array α), ∃ (bs : Array α), xs = as.push x ++ bs ¬x as
theorem Array.mem_push_of_mem {α : Type u_1} {a : Array α} {x : α} (y : α) (h : x a) :
x a.push y
theorem Array.exists_mem_of_ne_empty {α : Type u_1} (l : Array α) (h : l #[]) :
∃ (x : α), x l
theorem Array.eq_empty_iff_forall_not_mem {α : Type u_1} {l : Array α} :
l = #[] ∀ (a : α), ¬a l
@[simp]
theorem Array.mem_dite_empty_left {α : Type u_1} {p : Prop} {x : α} [Decidable p] {l : ¬pArray α} :
(x if h : p then #[] else l h) ∃ (h : ¬p), x l h
@[simp]
theorem Array.mem_dite_empty_right {α : Type u_1} {p : Prop} {x : α} [Decidable p] {l : pArray α} :
(x if h : p then l h else #[]) ∃ (h : p), x l h
@[simp]
theorem Array.mem_ite_empty_left {α : Type u_1} {p : Prop} {x : α} [Decidable p] {l : Array α} :
(x if p then #[] else l) ¬p x l
@[simp]
theorem Array.mem_ite_empty_right {α : Type u_1} {p : Prop} {x : α} [Decidable p] {l : Array α} :
(x if p then l else #[]) p x l
theorem Array.eq_of_mem_singleton {α✝ : Type u_1} {b a : α✝} (h : a #[b]) :
a = b
@[simp]
theorem Array.mem_singleton {α : Type u_1} {a b : α} :
a #[b] a = b
theorem Array.forall_mem_push {α : Type u_1} {p : αProp} {xs : Array α} {a : α} :
(∀ (x : α), x xs.push ap x) p a ∀ (x : α), x xsp x
theorem Array.forall_mem_ne {α : Type u_1} {a : α} {l : Array α} :
(∀ (a' : α), a' l¬a = a') ¬a l
theorem Array.forall_mem_ne' {α : Type u_1} {a : α} {l : Array α} :
(∀ (a' : α), a' l¬a' = a) ¬a l
theorem Array.exists_mem_empty {α : Type u_1} (p : αProp) :
¬∃ (x : α), ∃ (x_1 : x #[]), p x
theorem Array.forall_mem_empty {α : Type u_1} (p : αProp) (x : α) :
x #[]p x
theorem Array.exists_mem_push {α : Type u_1} {p : αProp} {a : α} {xs : Array α} :
(∃ (x : α), ∃ (x_1 : x xs.push a), p x) p a ∃ (x : α), ∃ (x_1 : x xs), p x
theorem Array.forall_mem_singleton {α : Type u_1} {p : αProp} {a : α} :
(∀ (x : α), x #[a]p x) p a
theorem Array.mem_empty_iff {α : Type u_1} (a : α) :
a #[] False
theorem Array.mem_singleton_self {α : Type u_1} (a : α) :
a #[a]
theorem Array.mem_of_mem_push_of_mem {α : Type u_1} {a b : α} {l : Array α} :
a l.push bb la l
theorem Array.eq_or_ne_mem_of_mem {α : Type u_1} {a b : α} {l : Array α} (h' : a l.push b) :
a = b a b a l
theorem Array.ne_empty_of_mem {α : Type u_1} {a : α} {l : Array α} (h : a l) :
l #[]
theorem Array.mem_of_ne_of_mem {α : Type u_1} {a y : α} {l : Array α} (h₁ : a y) (h₂ : a l.push y) :
a l
theorem Array.ne_of_not_mem_push {α : Type u_1} {a b : α} {l : Array α} (h : ¬a l.push b) :
a b
theorem Array.not_mem_of_not_mem_push {α : Type u_1} {a b : α} {l : Array α} (h : ¬a l.push b) :
¬a l
theorem Array.not_mem_push_of_ne_of_not_mem {α : Type u_1} {a y : α} {l : Array α} :
a y¬a l¬a l.push y
theorem Array.ne_and_not_mem_of_not_mem_push {α : Type u_1} {a y : α} {l : Array α} :
¬a l.push ya y ¬a l
theorem Array.getElem_of_mem {α : Type u_1} {a : α} {l : Array α} (h : a l) :
∃ (i : Nat), ∃ (h : i < l.size), l[i] = a
theorem Array.getElem?_of_mem {α : Type u_1} {a : α} {l : Array α} (h : a l) :
∃ (i : Nat), l[i]? = some a
theorem Array.mem_of_getElem? {α : Type u_1} {l : Array α} {i : Nat} {a : α} (e : l[i]? = some a) :
a l
theorem Array.mem_iff_getElem {α : Type u_1} {a : α} {l : Array α} :
a l ∃ (i : Nat), ∃ (h : i < l.size), l[i] = a
theorem Array.mem_iff_getElem? {α : Type u_1} {a : α} {l : Array α} :
a l ∃ (i : Nat), l[i]? = some a
theorem Array.forall_getElem {α : Type u_1} {l : Array α} {p : αProp} :
(∀ (i : Nat) (h : i < l.size), p l[i]) ∀ (a : α), a lp a

isEmpty #

@[simp]
theorem Array.isEmpty_toList {α : Type u_1} {l : Array α} :
l.toList.isEmpty = l.isEmpty
theorem Array.isEmpty_iff {α : Type u_1} {l : Array α} :
l.isEmpty = true l = #[]
theorem Array.isEmpty_eq_false_iff_exists_mem {α : Type u_1} {xs : Array α} :
xs.isEmpty = false ∃ (x : α), x xs
theorem Array.isEmpty_iff_size_eq_zero {α : Type u_1} {l : Array α} :
l.isEmpty = true l.size = 0
@[simp]
theorem Array.isEmpty_eq_true {α : Type u_1} {l : Array α} :
l.isEmpty = true l = #[]
@[simp]
theorem Array.isEmpty_eq_false {α : Type u_1} {l : Array α} :
l.isEmpty = false l #[]

Decidability of bounded quantifiers #

instance Array.instDecidableForallForallMemOfDecidablePred {α : Type u_1} {xs : Array α} {p : αProp} [DecidablePred p] :
Decidable (∀ (x : α), x xsp x)
Equations
instance Array.instDecidableExistsAndMemOfDecidablePred {α : Type u_1} {xs : Array α} {p : αProp} [DecidablePred p] :
Decidable (∃ (x : α), x xs p x)
Equations

any / all #

theorem Array.anyM_eq_anyM_loop {m : TypeType u_1} {α : Type u_2} [Monad m] (p : αm Bool) (as : Array α) (start stop : Nat) :
Array.anyM p as start stop = Array.anyM.loop p as (min stop as.size) start
theorem Array.anyM_stop_le_start {m : TypeType u_1} {α : Type u_2} [Monad m] (p : αm Bool) (as : Array α) (start stop : Nat) (h : min stop as.size start) :
Array.anyM p as start stop = pure false
@[irreducible]
theorem Array.anyM_loop_cons {m : TypeType u_1} {α : Type u_2} [Monad m] (p : αm Bool) (a : α) (as : List α) (stop start : Nat) (h : stop + 1 (a :: as).length) :
Array.anyM.loop p { toList := a :: as } (stop + 1) h (start + 1) = Array.anyM.loop p { toList := as } stop start
@[simp, irreducible]
theorem Array.anyM_toList {m : TypeType u_1} {α : Type u_2} [Monad m] (p : αm Bool) (as : Array α) :
List.anyM p as.toList = Array.anyM p as
@[irreducible]
theorem Array.anyM_loop_iff_exists {α : Type u_1} {p : αBool} {as : Array α} {start stop : Nat} (h : stop as.size) :
Array.anyM.loop p as stop h start = true ∃ (i : Nat), ∃ (x : i < as.size), start i i < stop p as[i] = true
theorem Array.any_iff_exists {α : Type u_1} {p : αBool} {as : Array α} {start stop : Nat} :
as.any p start stop = true ∃ (i : Nat), ∃ (x : i < as.size), start i i < stop p as[i] = true
@[simp]
theorem Array.any_eq_true {α : Type u_1} {p : αBool} {as : Array α} :
as.any p = true ∃ (i : Nat), ∃ (x : i < as.size), p as[i] = true
@[simp]
theorem Array.any_eq_false {α : Type u_1} {p : αBool} {as : Array α} :
as.any p = false ∀ (i : Nat) (x : i < as.size), ¬p as[i] = true
@[simp]
theorem Array.any_toList {α : Type u_1} {p : αBool} (as : Array α) :
as.toList.any p = as.any p
theorem Array.allM_eq_not_anyM_not {m : TypeType u_1} {α : Type u_2} [Monad m] [LawfulMonad m] (p : αm Bool) (as : Array α) :
Array.allM p as = (fun (x : Bool) => !x) <$> Array.anyM (fun (x : α) => (fun (x : Bool) => !x) <$> p x) as
@[simp]
theorem Array.allM_toList {m : TypeType u_1} {α : Type u_2} [Monad m] [LawfulMonad m] (p : αm Bool) (as : Array α) :
List.allM p as.toList = Array.allM p as
theorem Array.all_eq_not_any_not {α : Type u_1} (p : αBool) (as : Array α) (start stop : Nat) :
as.all p start stop = !as.any (fun (x : α) => !p x) start stop
theorem Array.all_iff_forall {α : Type u_1} {p : αBool} {as : Array α} {start stop : Nat} :
as.all p start stop = true ∀ (i : Nat) (x : i < as.size), start i i < stopp as[i] = true
@[simp]
theorem Array.all_eq_true {α : Type u_1} {p : αBool} {as : Array α} :
as.all p = true ∀ (i : Nat) (x : i < as.size), p as[i] = true
@[simp]
theorem Array.all_eq_false {α : Type u_1} {p : αBool} {as : Array α} :
as.all p = false ∃ (i : Nat), ∃ (x : i < as.size), ¬p as[i] = true
@[simp]
theorem Array.all_toList {α : Type u_1} {p : αBool} (as : Array α) :
as.toList.all p = as.all p
theorem Array.all_eq_true_iff_forall_mem {α : Type u_1} {p : αBool} {l : Array α} :
l.all p = true ∀ (x : α), x lp x = true
@[simp]
theorem List.anyM_toArray' {m : TypeType u_1} {α : Type u_2} {stop : Nat} [Monad m] [LawfulMonad m] (p : αm Bool) (l : List α) (h : stop = l.toArray.size) :
Array.anyM p l.toArray 0 stop = List.anyM p l

Variant of anyM_toArray with a side condition on stop.

@[simp]
theorem List.any_toArray' {α : Type u_1} {stop : Nat} (p : αBool) (l : List α) (h : stop = l.toArray.size) :
l.toArray.any p 0 stop = l.any p

Variant of any_toArray with a side condition on stop.

@[simp]
theorem List.allM_toArray' {m : TypeType u_1} {α : Type u_2} {stop : Nat} [Monad m] [LawfulMonad m] (p : αm Bool) (l : List α) (h : stop = l.toArray.size) :
Array.allM p l.toArray 0 stop = List.allM p l

Variant of allM_toArray with a side condition on stop.

@[simp]
theorem List.all_toArray' {α : Type u_1} {stop : Nat} (p : αBool) (l : List α) (h : stop = l.toArray.size) :
l.toArray.all p 0 stop = l.all p

Variant of all_toArray with a side condition on stop.

theorem List.anyM_toArray {m : TypeType u_1} {α : Type u_2} [Monad m] [LawfulMonad m] (p : αm Bool) (l : List α) :
Array.anyM p l.toArray = List.anyM p l
theorem List.any_toArray {α : Type u_1} (p : αBool) (l : List α) :
l.toArray.any p = l.any p
theorem List.allM_toArray {m : TypeType u_1} {α : Type u_2} [Monad m] [LawfulMonad m] (p : αm Bool) (l : List α) :
Array.allM p l.toArray = List.allM p l
theorem List.all_toArray {α : Type u_1} (p : αBool) (l : List α) :
l.toArray.all p = l.all p
theorem Array.any_eq_true' {α : Type u_1} {p : αBool} {as : Array α} :
as.any p = true ∃ (x : α), x as p x = true

Variant of any_eq_true in terms of membership rather than an array index.

theorem Array.any_eq_false' {α : Type u_1} {p : αBool} {as : Array α} :
as.any p = false ∀ (x : α), x as¬p x = true

Variant of any_eq_false in terms of membership rather than an array index.

theorem Array.all_eq_true' {α : Type u_1} {p : αBool} {as : Array α} :
as.all p = true ∀ (x : α), x asp x = true

Variant of all_eq_true in terms of membership rather than an array index.

theorem Array.all_eq_false' {α : Type u_1} {p : αBool} {as : Array α} :
as.all p = false ∃ (x : α), x as ¬p x = true

Variant of all_eq_false in terms of membership rather than an array index.

theorem Array.any_eq {α : Type u_1} {xs : Array α} {p : αBool} :
xs.any p = decide (∃ (i : Nat), ∃ (h : i < xs.size), p xs[i] = true)
theorem Array.any_eq' {α : Type u_1} {xs : Array α} {p : αBool} :
xs.any p = decide (∃ (x : α), x xs p x = true)

Variant of any_eq in terms of membership rather than an array index.

theorem Array.all_eq {α : Type u_1} {xs : Array α} {p : αBool} :
xs.all p = decide (∀ (i : Nat) (x : i < xs.size), p xs[i] = true)
theorem Array.all_eq' {α : Type u_1} {xs : Array α} {p : αBool} :
xs.all p = decide (∀ (x : α), x xsp x = true)

Variant of all_eq in terms of membership rather than an array index.

theorem Array.decide_exists_mem {α : Type u_1} {xs : Array α} {p : αProp} [DecidablePred p] :
decide (∃ (x : α), x xs p x) = xs.any fun (b : α) => decide (p b)
theorem Array.decide_forall_mem {α : Type u_1} {xs : Array α} {p : αProp} [DecidablePred p] :
decide (∀ (x : α), x xsp x) = xs.all fun (b : α) => decide (p b)
@[simp]
theorem List.contains_toArray {α : Type u_1} [BEq α] {l : List α} {a : α} :
l.toArray.contains a = l.contains a
theorem List.elem_toArray {α : Type u_1} [BEq α] {l : List α} {a : α} :
Array.elem a l.toArray = List.elem a l
theorem Array.any_beq {α : Type u_1} [BEq α] {xs : Array α} {a : α} :
(xs.any fun (x : α) => a == x) = xs.contains a
theorem Array.any_beq' {α : Type u_1} {a : α} [BEq α] [PartialEquivBEq α] {xs : Array α} :
(xs.any fun (x : α) => x == a) = xs.contains a

Variant of any_beq with == reversed.

theorem Array.all_bne {α : Type u_1} {a : α} [BEq α] {xs : Array α} :
(xs.all fun (x : α) => a != x) = !xs.contains a
theorem Array.all_bne' {α : Type u_1} {a : α} [BEq α] [PartialEquivBEq α] {xs : Array α} :
(xs.all fun (x : α) => x != a) = !xs.contains a

Variant of all_bne with != reversed.

theorem Array.mem_of_contains_eq_true {α : Type u_1} [BEq α] [LawfulBEq α] {a : α} {as : Array α} :
as.contains a = truea as
@[reducible, inline, deprecated Array.mem_of_contains_eq_true (since := "2024-12-12")]
abbrev Array.mem_of_elem_eq_true {α : Type u_1} [BEq α] [LawfulBEq α] {a : α} {as : Array α} :
as.contains a = truea as
Equations
Instances For
    theorem Array.contains_eq_true_of_mem {α : Type u_1} [BEq α] [LawfulBEq α] {a : α} {as : Array α} (h : a as) :
    as.contains a = true
    @[reducible, inline, deprecated Array.contains_eq_true_of_mem (since := "2024-12-12")]
    abbrev Array.elem_eq_true_of_mem {α : Type u_1} [BEq α] [LawfulBEq α] {a : α} {as : Array α} (h : a as) :
    as.contains a = true
    Equations
    Instances For
      @[simp]
      theorem Array.elem_eq_contains {α : Type u_1} [BEq α] {a : α} {l : Array α} :
      Array.elem a l = l.contains a
      theorem Array.elem_iff {α : Type u_1} [BEq α] [LawfulBEq α] {a : α} {as : Array α} :
      Array.elem a as = true a as
      theorem Array.contains_iff {α : Type u_1} [BEq α] [LawfulBEq α] {a : α} {as : Array α} :
      as.contains a = true a as
      theorem Array.elem_eq_mem {α : Type u_1} [BEq α] [LawfulBEq α] (a : α) (as : Array α) :
      Array.elem a as = decide (a as)
      @[simp]
      theorem Array.contains_eq_mem {α : Type u_1} [BEq α] [LawfulBEq α] (a : α) (as : Array α) :
      as.contains a = decide (a as)
      @[simp]
      theorem Array.any_push' {α : Type u_1} {stop : Nat} [BEq α] {as : Array α} {a : α} {p : αBool} (h : stop = as.size + 1) :
      (as.push a).any p 0 stop = (as.any p || p a)

      Variant of any_push with a side condition on stop.

      theorem Array.any_push {α : Type u_1} [BEq α] {as : Array α} {a : α} {p : αBool} :
      (as.push a).any p = (as.any p || p a)
      @[simp]
      theorem Array.all_push' {α : Type u_1} {stop : Nat} [BEq α] {as : Array α} {a : α} {p : αBool} (h : stop = as.size + 1) :
      (as.push a).all p 0 stop = (as.all p && p a)

      Variant of all_push with a side condition on stop.

      theorem Array.all_push {α : Type u_1} [BEq α] {as : Array α} {a : α} {p : αBool} :
      (as.push a).all p = (as.all p && p a)
      @[simp]
      theorem Array.contains_push {α : Type u_1} [BEq α] {l : Array α} {a b : α} :
      (l.push a).contains b = (l.contains b || b == a)

      set #

      @[simp]
      theorem Array.getElem_set_self {α : Type u_1} (a : Array α) (i : Nat) (h : i < a.size) (v : α) {j : Nat} (eq : i = j) (p : j < (a.set i v h).size) :
      (a.set i v h)[j] = v
      @[reducible, inline, deprecated Array.getElem_set_self (since := "2024-12-11")]
      abbrev Array.getElem_set_eq {α : Type u_1} (a : Array α) (i : Nat) (h : i < a.size) (v : α) {j : Nat} (eq : i = j) (p : j < (a.set i v h).size) :
      (a.set i v h)[j] = v
      Equations
      Instances For
        @[simp]
        theorem Array.getElem?_set_self {α : Type u_1} (a : Array α) (i : Nat) (h : i < a.size) (v : α) :
        (a.set i v h)[i]? = some v
        @[reducible, inline, deprecated Array.getElem?_set_self (since := "2024-12-11")]
        abbrev Array.getElem?_set_eq {α : Type u_1} (a : Array α) (i : Nat) (h : i < a.size) (v : α) :
        (a.set i v h)[i]? = some v
        Equations
        Instances For
          @[simp]
          theorem Array.getElem_set_ne {α : Type u_1} (a : Array α) (i : Nat) (h' : i < a.size) (v : α) {j : Nat} (pj : j < (a.set i v h').size) (h : i j) :
          (a.set i v h')[j] = a[j]
          @[simp]
          theorem Array.getElem?_set_ne {α : Type u_1} (a : Array α) (i : Nat) (h : i < a.size) {j : Nat} (v : α) (ne : i j) :
          (a.set i v h)[j]? = a[j]?
          theorem Array.getElem_set {α : Type u_1} (a : Array α) (i : Nat) (h' : i < a.size) (v : α) (j : Nat) (h : j < (a.set i v h').size) :
          (a.set i v h')[j] = if i = j then v else a[j]
          theorem Array.getElem?_set {α : Type u_1} (a : Array α) (i : Nat) (h : i < a.size) (v : α) (j : Nat) :
          (a.set i v h)[j]? = if i = j then some v else a[j]?
          @[simp]
          theorem Array.set_getElem_self {α : Type u_1} {as : Array α} {i : Nat} (h : i < as.size) :
          as.set i as[i] h = as
          @[simp]
          theorem Array.set_eq_empty_iff {α : Type u_1} {as : Array α} (n : Nat) (a : α) (h : n < as.size) :
          as.set n a h = #[] as = #[]
          theorem Array.set_comm {α : Type u_1} (a b : α) {i j : Nat} (as : Array α) {hi : i < as.size} {hj : j < (as.set i a hi).size} (h : i j) :
          (as.set i a hi).set j b hj = (as.set j b ).set i a
          @[simp]
          theorem Array.set_set {α : Type u_1} (a b : α) (as : Array α) (i : Nat) (h : i < as.size) :
          (as.set i a h).set i b = as.set i b h
          theorem Array.mem_set {α : Type u_1} (as : Array α) (i : Nat) (h : i < as.size) (a : α) :
          a as.set i a h
          theorem Array.mem_or_eq_of_mem_set {α : Type u_1} {as : Array α} {i : Nat} {a b : α} {w : i < as.size} (h : a as.set i b w) :
          a as a = b
          @[simp]
          theorem Array.toList_set {α : Type u_1} (a : Array α) (i : Nat) (x : α) (h : i < a.size) :
          (a.set i x h).toList = a.toList.set i x

          setIfInBounds #

          @[reducible, inline, deprecated Array.set!_eq_setIfInBounds (since := "2024-12-12")]
          Equations
          Instances For
            @[simp]
            theorem Array.size_setIfInBounds {α : Type u_1} (as : Array α) (index : Nat) (val : α) :
            (as.setIfInBounds index val).size = as.size
            theorem Array.getElem_setIfInBounds {α : Type u_1} (as : Array α) (i : Nat) (v : α) (j : Nat) (hj : j < (as.setIfInBounds i v).size) :
            (as.setIfInBounds i v)[j] = if i = j then v else as[j]
            @[simp]
            theorem Array.getElem_setIfInBounds_self {α : Type u_1} (as : Array α) {i : Nat} (v : α) (h : i < (as.setIfInBounds i v).size) :
            (as.setIfInBounds i v)[i] = v
            @[reducible, inline, deprecated Array.getElem_setIfInBounds_self (since := "2024-12-11")]
            abbrev Array.getElem_setIfInBounds_eq {α : Type u_1} (as : Array α) {i : Nat} (v : α) (h : i < (as.setIfInBounds i v).size) :
            (as.setIfInBounds i v)[i] = v
            Equations
            Instances For
              @[simp]
              theorem Array.getElem_setIfInBounds_ne {α : Type u_1} (as : Array α) {i : Nat} (v : α) {j : Nat} (hj : j < (as.setIfInBounds i v).size) (h : i j) :
              (as.setIfInBounds i v)[j] = as[j]
              theorem Array.getElem?_setIfInBounds {α : Type u_1} {as : Array α} {i j : Nat} {a : α} :
              (as.setIfInBounds i a)[j]? = if i = j then if i < as.size then some a else none else as[j]?
              theorem Array.getElem?_setIfInBounds_self {α : Type u_1} (as : Array α) {i : Nat} (v : α) :
              (as.setIfInBounds i v)[i]? = if i < as.size then some v else none
              @[simp]
              theorem Array.getElem?_setIfInBounds_self_of_lt {α : Type u_1} (as : Array α) {i : Nat} (v : α) (h : i < as.size) :
              (as.setIfInBounds i v)[i]? = some v
              @[reducible, inline, deprecated Array.getElem?_setIfInBounds_self (since := "2024-12-11")]
              abbrev Array.getElem?_setIfInBounds_eq {α : Type u_1} (as : Array α) {i : Nat} (v : α) :
              (as.setIfInBounds i v)[i]? = if i < as.size then some v else none
              Equations
              Instances For
                @[simp]
                theorem Array.getElem?_setIfInBounds_ne {α : Type u_1} {as : Array α} {i j : Nat} (h : i j) {a : α} :
                (as.setIfInBounds i a)[j]? = as[j]?
                theorem Array.setIfInBounds_eq_of_size_le {α : Type u_1} {l : Array α} {n : Nat} (h : l.size n) {a : α} :
                l.setIfInBounds n a = l
                @[simp]
                theorem Array.setIfInBounds_eq_empty_iff {α : Type u_1} {as : Array α} (n : Nat) (a : α) :
                as.setIfInBounds n a = #[] as = #[]
                theorem Array.setIfInBounds_comm {α : Type u_1} (a b : α) {i j : Nat} (as : Array α) (h : i j) :
                (as.setIfInBounds i a).setIfInBounds j b = (as.setIfInBounds j b).setIfInBounds i a
                @[simp]
                theorem Array.setIfInBounds_setIfInBounds {α : Type u_1} (a b : α) (as : Array α) (i : Nat) :
                (as.setIfInBounds i a).setIfInBounds i b = as.setIfInBounds i b
                theorem Array.mem_setIfInBounds {α : Type u_1} (as : Array α) (i : Nat) (h : i < as.size) (a : α) :
                a as.setIfInBounds i a
                theorem Array.mem_or_eq_of_mem_setIfInBounds {α : Type u_1} {as : Array α} {i : Nat} {a b : α} (h : a as.setIfInBounds i b) :
                a as a = b
                @[simp]
                theorem Array.getD_get?_setIfInBounds {α : Type u_1} (a : Array α) (i : Nat) (v d : α) :
                (a.setIfInBounds i v)[i]?.getD d = if i < a.size then v else d

                Simplifies a normal form from get!

                @[simp]
                theorem Array.toList_setIfInBounds {α : Type u_1} (a : Array α) (i : Nat) (x : α) :
                (a.setIfInBounds i x).toList = a.toList.set i x

                BEq #

                @[simp]
                theorem Array.beq_empty_iff {α : Type u_1} [BEq α] {xs : Array α} :
                (xs == #[]) = xs.isEmpty
                @[simp]
                theorem Array.empty_beq_iff {α : Type u_1} [BEq α] {xs : Array α} :
                (#[] == xs) = xs.isEmpty
                @[simp]
                theorem Array.push_beq_push {α : Type u_1} [BEq α] {a b : α} {v w : Array α} :
                (v.push a == w.push b) = (v == w && a == b)
                theorem Array.size_eq_of_beq {α : Type u_1} [BEq α] {xs ys : Array α} (h : (xs == ys) = true) :
                xs.size = ys.size
                @[simp, irreducible]
                theorem Array.mkArray_beq_mkArray {α : Type u_1} [BEq α] {a b : α} {n : Nat} :
                (mkArray n a == mkArray n b) = (n == 0 || a == b)
                @[simp]
                theorem Array.reflBEq_iff {α : Type u_1} [BEq α] :
                @[simp]
                theorem Array.lawfulBEq_iff {α : Type u_1} [BEq α] :

                isEqv #

                @[simp]
                theorem Array.isEqv_eq {α : Type u_1} [DecidableEq α] {l₁ l₂ : Array α} :
                ((l₁.isEqv l₂ fun (x1 x2 : α) => x1 == x2) = true) = (l₁ = l₂)

                Content below this point has not yet been aligned with List.

                theorem Array.singleton_eq_toArray_singleton {α : Type u_1} (a : α) :
                #[a] = #[a]
                @[simp]
                theorem Array.singleton_def {α : Type u_1} (v : α) :
                @[simp]
                theorem Array.toArray_toList {α : Type u_1} (a : Array α) :
                a.toList.toArray = a
                @[simp]
                theorem Array.length_toList {α : Type u_1} {l : Array α} :
                l.toList.length = l.size
                @[simp]
                theorem Array.mkEmpty_eq (α : Type u_1) (n : Nat) :
                @[deprecated Array.size_toArray (since := "2024-12-11")]
                theorem Array.size_mk {α : Type u_1} (as : List α) :
                { toList := as }.size = as.length
                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 (arr.push a) = do let initf a init Array.foldrM f init 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 : α) {start : Nat} (h : start = arr.size + 1) :
                Array.foldrM f init (arr.push a) start = do let initf a init Array.foldrM f init arr

                Variant of foldrM_push with h : start = arr.size + 1 rather than (arr.push a).size as the argument.

                theorem Array.foldr_push {α : Type u_1} {β : Type u_2} (f : αββ) (init : β) (arr : Array α) (a : α) :
                Array.foldr f init (arr.push a) = Array.foldr f (f a init) arr
                @[simp]
                theorem Array.foldr_push' {α : Type u_1} {β : Type u_2} (f : αββ) (init : β) (arr : Array α) (a : α) {start : Nat} (h : start = arr.size + 1) :
                Array.foldr f init (arr.push a) start = Array.foldr f (f a init) arr

                Variant of foldr_push with the h : start = arr.size + 1 rather than (arr.push a).size as the argument.

                @[inline]
                def Array.toListRev {α : Type u_1} (arr : Array α) :
                List α

                A more efficient version of arr.toList.reverse.

                Equations
                Instances For
                  @[simp]
                  theorem Array.toListRev_eq {α : Type u_1} (arr : Array α) :
                  arr.toListRev = arr.toList.reverse
                  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 : α) => bs.push <$> f a) #[] arr
                  @[irreducible]
                  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 : α) => bs.push <$> f a) r (List.drop i arr.toList)
                  @[simp]
                  theorem Array.toList_map {α : Type u_1} {β : Type u_2} (f : αβ) (arr : Array α) :
                  (Array.map f arr).toList = List.map f arr.toList
                  @[simp]
                  theorem Array.size_map {α : Type u_1} {β : Type u_2} (f : αβ) (arr : Array α) :
                  (Array.map f arr).size = arr.size
                  @[simp]
                  theorem Array.mapM_empty {m : Type u_1 → Type u_2} {α : Type u_3} {β : Type u_1} [Monad m] (f : αm β) :
                  Array.mapM f #[] = pure #[]
                  @[simp]
                  theorem Array.map_empty {α : Type u_1} {β : Type u_2} (f : αβ) :
                  Array.map f #[] = #[]
                  @[simp]
                  theorem Array.appendList_nil {α : Type u_1} (arr : Array α) :
                  arr ++ [] = arr
                  @[simp]
                  theorem Array.appendList_cons {α : Type u_1} (arr : Array α) (a : α) (l : List α) :
                  arr ++ a :: l = arr.push a ++ l
                  theorem Array.foldl_toList_eq_flatMap {α : Type u_1} {β : Type u_2} (l : List α) (acc : Array β) (F : Array βαArray β) (G : αList β) (H : ∀ (acc : Array β) (a : α), (F acc a).toList = acc.toList ++ G a) :
                  (List.foldl F acc l).toList = acc.toList ++ l.flatMap G
                  theorem Array.foldl_toList_eq_map {α : Type u_1} {β : Type u_2} (l : List α) (acc : Array β) (G : αβ) :
                  (List.foldl (fun (acc : Array β) (a : α) => acc.push (G a)) acc l).toList = acc.toList ++ List.map G l

                  uset #

                  theorem Array.size_uset {α : Type u_1} (a : Array α) (v : α) (i : USize) (h : i.toNat < a.size) :
                  (a.uset i v h).size = a.size

                  get #

                  @[deprecated Array.getElem?_eq_getElem (since := "2024-12-11")]
                  theorem Array.getElem?_lt {α : Type u_1} (a : Array α) {i : Nat} (h : i < a.size) :
                  a[i]? = some a[i]
                  @[deprecated Array.getElem?_eq_none (since := "2024-12-11")]
                  theorem Array.getElem?_ge {α : Type u_1} (a : Array α) {i : Nat} (h : i a.size) :
                  a[i]? = none
                  @[simp]
                  theorem Array.get?_eq_getElem? {α : Type u_1} (a : Array α) (i : Nat) :
                  a.get? i = a[i]?
                  @[deprecated Array.getElem?_eq_none (since := "2024-12-11")]
                  theorem Array.getElem?_len_le {α : Type u_1} (a : Array α) {i : Nat} (h : a.size i) :
                  a[i]? = none
                  @[reducible, inline, deprecated Array.getD_getElem? (since := "2024-12-11")]
                  abbrev Array.getD_get? {α : Type u_1} (a : Array α) (i : Nat) (d : α) :
                  a[i]?.getD d = if p : i < a.size then a[i] else d
                  Equations
                  Instances For
                    @[simp]
                    theorem Array.getD_eq_get? {α : Type u_1} (a : Array α) (i : Nat) (d : α) :
                    a.getD i d = a[i]?.getD d
                    theorem Array.get!_eq_getD {α : Type u_1} {n : Nat} [Inhabited α] (a : Array α) :
                    a.get! n = a.getD n default
                    theorem Array.get!_eq_getElem? {α : Type u_1} [Inhabited α] (a : Array α) (i : Nat) :
                    a.get! i = (a.get? i).getD default

                    ofFn #

                    @[simp, irreducible]
                    theorem Array.size_ofFn_go {α : Type u_1} {n : Nat} (f : Fin nα) (i : Nat) (acc : Array α) :
                    (Array.ofFn.go f i acc).size = acc.size + (n - i)
                    @[simp]
                    theorem Array.size_ofFn {n : Nat} {α : Type u_1} (f : Fin nα) :
                    (Array.ofFn f).size = n
                    @[irreducible]
                    theorem Array.getElem_ofFn_go {n : Nat} {α : Type u_1} (f : Fin nα) (i : Nat) {acc : Array α} {k : Nat} (hki : k < n) (hin : i n) (hi : i = acc.size) (hacc : ∀ (j : Nat) (hj : j < acc.size), acc[j] = f j, ) :
                    (Array.ofFn.go f i acc)[k] = f k, hki
                    @[simp]
                    theorem Array.getElem_ofFn {n : Nat} {α : Type u_1} (f : Fin nα) (i : Nat) (h : i < (Array.ofFn f).size) :
                    (Array.ofFn f)[i] = f i,
                    theorem Array.getElem?_ofFn {n : Nat} {α : Type u_1} (f : Fin nα) (i : Nat) :
                    (Array.ofFn f)[i]? = if h : i < n then some (f i, h) else none
                    @[simp]
                    theorem Array.ofFn_zero {α : Type u_1} (f : Fin 0α) :
                    theorem Array.ofFn_succ {n : Nat} {α : Type u_1} (f : Fin (n + 1)α) :
                    Array.ofFn f = (Array.ofFn fun (i : Fin n) => f i.castSucc).push (f n, )

                    mem #

                    @[simp]
                    theorem Array.mem_toList {α : Type u_1} {a : α} {l : Array α} :
                    a l.toList a l
                    theorem Array.not_mem_nil {α : Type u_1} (a : α) :
                    ¬a #[]

                    get lemmas #

                    theorem Array.lt_of_getElem {α : Type u_1} {x : α} {a : Array α} {idx : Nat} {hidx : idx < a.size} :
                    a[idx] = xidx < a.size
                    theorem Array.getElem_fin_eq_getElem_toList {α : Type u_1} (a : Array α) (i : Fin a.size) :
                    a[i] = a.toList[i]
                    @[simp]
                    theorem Array.ugetElem_eq_getElem {α : Type u_1} (a : Array α) {i : USize} (h : i.toNat < a.size) :
                    a[i] = a[i.toNat]
                    theorem Array.getElem?_size_le {α : Type u_1} (a : Array α) (i : Nat) (h : a.size i) :
                    a[i]? = none
                    @[reducible, inline, deprecated Array.getElem?_size_le (since := "2024-10-21")]
                    abbrev Array.get?_len_le {α : Type u_1} (a : Array α) (i : Nat) (h : a.size i) :
                    a[i]? = none
                    Equations
                    Instances For
                      theorem Array.getElem_mem_toList {α : Type u_1} {i : Nat} (a : Array α) (h : i < a.size) :
                      a[i] a.toList
                      theorem Array.get?_eq_get?_toList {α : Type u_1} (a : Array α) (i : Nat) :
                      a.get? i = a.toList.get? i
                      theorem Array.get!_eq_get? {α : Type u_1} {n : Nat} [Inhabited α] (a : Array α) :
                      a.get! n = (a.get? n).getD default
                      theorem Array.back!_eq_back? {α : Type u_1} [Inhabited α] (a : Array α) :
                      a.back! = a.back?.getD default
                      @[simp]
                      theorem Array.back?_push {α : Type u_1} {x : α} (a : Array α) :
                      (a.push x).back? = some x
                      @[simp]
                      theorem Array.back!_push {α : Type u_1} {x : α} [Inhabited α] (a : Array α) :
                      (a.push x).back! = x
                      theorem Array.mem_of_back?_eq_some {α : Type u_1} {xs : Array α} {a : α} (h : xs.back? = some a) :
                      a xs
                      theorem Array.getElem?_push_lt {α : Type u_1} (a : Array α) (x : α) (i : Nat) (h : i < a.size) :
                      (a.push x)[i]? = some a[i]
                      @[reducible, inline, deprecated Array.getElem?_push_lt (since := "2024-10-21")]
                      abbrev Array.get?_push_lt {α : Type u_1} (a : Array α) (x : α) (i : Nat) (h : i < a.size) :
                      (a.push x)[i]? = some a[i]
                      Equations
                      Instances For
                        theorem Array.getElem?_push_eq {α : Type u_1} (a : Array α) (x : α) :
                        (a.push x)[a.size]? = some x
                        @[reducible, inline, deprecated Array.getElem?_push_eq (since := "2024-10-21")]
                        abbrev Array.get?_push_eq {α : Type u_1} (a : Array α) (x : α) :
                        (a.push x)[a.size]? = some x
                        Equations
                        Instances For
                          @[reducible, inline, deprecated Array.getElem?_push (since := "2024-10-21")]
                          abbrev Array.get?_push {α : Type u_1} {i : Nat} {a : Array α} {x : α} :
                          (a.push x)[i]? = if i = a.size then some x else a[i]?
                          Equations
                          Instances For
                            @[simp]
                            theorem Array.getElem?_size {α : Type u_1} {a : Array α} :
                            a[a.size]? = none
                            @[reducible, inline, deprecated Array.getElem?_size (since := "2024-10-21")]
                            abbrev Array.get?_size {α : Type u_1} {a : Array α} :
                            a[a.size]? = none
                            Equations
                            Instances For
                              theorem Array.get_set_eq {α : Type u_1} (a : Array α) (i : Nat) (v : α) (h : i < a.size) :
                              (a.set i v h)[i] = v
                              theorem Array.get?_set_eq {α : Type u_1} (a : Array α) (i : Nat) (v : α) (h : i < a.size) :
                              (a.set i v h)[i]? = some v
                              @[simp]
                              theorem Array.get?_set_ne {α : Type u_1} (a : Array α) (i : Nat) (h' : i < a.size) {j : Nat} (v : α) (h : i j) :
                              (a.set i v h')[j]? = a[j]?
                              theorem Array.get?_set {α : Type u_1} (a : Array α) (i : Nat) (h : i < a.size) (j : Nat) (v : α) :
                              (a.set i v h)[j]? = if i = j then some v else a[j]?
                              theorem Array.get_set {α : Type u_1} (a : Array α) (i : Nat) (hi : i < a.size) (j : Nat) (hj : j < a.size) (v : α) :
                              (a.set i v hi)[j] = if i = j then v else a[j]
                              @[simp]
                              theorem Array.get_set_ne {α : Type u_1} (a : Array α) (i : Nat) (hi : i < a.size) {j : Nat} (v : α) (hj : j < a.size) (h : i j) :
                              (a.set i v hi)[j] = a[j]
                              theorem Array.swap_def {α : Type u_1} (a : Array α) (i j : Nat) (hi : i < a.size) (hj : j < a.size) :
                              a.swap i j hi hj = (a.set i a[j] hi).set j a[i]
                              @[simp]
                              theorem Array.toList_swap {α : Type u_1} (a : Array α) (i j : Nat) (hi : i < a.size) (hj : j < a.size) :
                              (a.swap i j hi hj).toList = (a.toList.set i a[j]).set j a[i]
                              theorem Array.getElem?_swap {α : Type u_1} (a : Array α) (i j : Nat) (hi : i < a.size) (hj : j < a.size) (k : Nat) :
                              (a.swap i j hi hj)[k]? = if j = k then some a[i] else if i = k then some a[j] else a[k]?
                              @[simp]
                              theorem Array.swapAt_def {α : Type u_1} (a : Array α) (i : Nat) (v : α) (hi : i < a.size) :
                              a.swapAt i v hi = (a[i], a.set i v hi)
                              theorem Array.size_swapAt {α : Type u_1} (a : Array α) (i : Nat) (v : α) (hi : i < a.size) :
                              (a.swapAt i v hi).snd.size = a.size
                              @[simp]
                              theorem Array.swapAt!_def {α : Type u_1} (a : Array α) (i : Nat) (v : α) (h : i < a.size) :
                              a.swapAt! i v = (a[i], a.set i v h)
                              @[simp]
                              theorem Array.size_swapAt! {α : Type u_1} (a : Array α) (i : Nat) (v : α) :
                              (a.swapAt! i v).snd.size = a.size
                              @[simp]
                              theorem Array.toList_pop {α : Type u_1} (a : Array α) :
                              a.pop.toList = a.toList.dropLast
                              @[simp]
                              theorem Array.pop_empty {α : Type u_1} :
                              #[].pop = #[]
                              @[simp]
                              theorem Array.pop_push {α : Type u_1} {x : α} (a : Array α) :
                              (a.push x).pop = a
                              @[simp]
                              theorem Array.getElem_pop {α : Type u_1} (a : Array α) (i : Nat) (hi : i < a.pop.size) :
                              a.pop[i] = a[i]
                              theorem Array.eq_push_pop_back!_of_size_ne_zero {α : Type u_1} [Inhabited α] {as : Array α} (h : as.size 0) :
                              as = as.pop.push as.back!
                              theorem Array.eq_push_of_size_ne_zero {α : Type u_1} {as : Array α} (h : as.size 0) :
                              ∃ (bs : Array α), ∃ (c : α), as = bs.push c
                              theorem Array.size_eq_length_toList {α : Type u_1} (as : Array α) :
                              as.size = as.toList.length
                              @[simp]
                              theorem Array.size_swapIfInBounds {α : Type u_1} (a : Array α) (i j : Nat) :
                              (a.swapIfInBounds i j).size = a.size
                              @[reducible, inline, deprecated Array.size_swapIfInBounds (since := "2024-11-24")]
                              abbrev Array.size_swap! {α : Type u_1} (a : Array α) (i j : Nat) :
                              (a.swapIfInBounds i j).size = a.size
                              Equations
                              Instances For
                                @[simp]
                                theorem Array.size_reverse {α : Type u_1} (a : Array α) :
                                a.reverse.size = a.size
                                @[irreducible]
                                theorem Array.size_reverse.go {α : Type u_1} (as : Array α) (i : Nat) (j : Fin as.size) :
                                (Array.reverse.loop as i j).size = as.size
                                @[simp]
                                theorem Array.size_range {n : Nat} :
                                (Array.range n).size = n
                                @[simp]
                                theorem Array.toList_range (n : Nat) :
                                (Array.range n).toList = List.range n
                                @[simp]
                                theorem Array.getElem_range {n x : Nat} (h : x < (Array.range n).size) :
                                (Array.range n)[x] = x
                                @[simp]
                                theorem Array.toList_reverse {α : Type u_1} (a : Array α) :
                                a.reverse.toList = a.toList.reverse
                                @[irreducible]
                                theorem Array.toList_reverse.go {α : Type u_1} (a as : Array α) (i j : Nat) (hj : j < as.size) (h : i + j + 1 = a.size) (h₂ : as.size = a.size) (H : ∀ (k : Nat), as.toList[k]? = if i k k j then a.toList[k]? else a.toList.reverse[k]?) (k : Nat) :
                                (Array.reverse.loop as i j, hj).toList[k]? = a.toList.reverse[k]?

                                take #

                                @[simp]
                                theorem Array.size_take_loop {α : Type u_1} (a : Array α) (n : Nat) :
                                (Array.take.loop n a).size = a.size - n
                                @[simp]
                                theorem Array.getElem_take_loop {α : Type u_1} (a : Array α) (n i : Nat) (h : i < (Array.take.loop n a).size) :
                                (Array.take.loop n a)[i] = a[i]
                                @[simp]
                                theorem Array.size_take {α : Type u_1} (a : Array α) (n : Nat) :
                                (a.take n).size = min n a.size
                                @[simp]
                                theorem Array.getElem_take {α : Type u_1} (a : Array α) (n i : Nat) (h : i < (a.take n).size) :
                                (a.take n)[i] = a[i]
                                @[simp]
                                theorem Array.toList_take {α : Type u_1} (a : Array α) (n : Nat) :
                                (a.take n).toList = List.take n a.toList

                                forIn #

                                @[simp]
                                theorem Array.forIn_toList {m : Type u_1 → Type u_2} {α : Type u_3} {β : Type u_1} [Monad m] (as : Array α) (b : β) (f : αβm (ForInStep β)) :
                                forIn as.toList b f = forIn as b f
                                @[simp]
                                theorem Array.forIn'_toList {m : Type u_1 → Type u_2} {α : Type u_3} {β : Type u_1} [Monad m] (as : Array α) (b : β) (f : (a : α) → a as.toListβm (ForInStep β)) :
                                forIn' as.toList b f = forIn' as b fun (a : α) (m : a as) (b : β) => f a b

                                foldl / foldr #

                                @[simp]
                                theorem Array.foldlM_loop_empty {m : Type u_1 → Type u_2} {β : Type u_1} {α : Type u_3} {s : Nat} {h : s #[].size} [Monad m] (f : βαm β) (init : β) (i j : Nat) :
                                Array.foldlM.loop f #[] s h i j init = pure init
                                @[simp]
                                theorem Array.foldlM_empty {m : Type u_1 → Type u_2} {β : Type u_1} {α : Type u_3} {start stop : Nat} [Monad m] (f : βαm β) (init : β) :
                                Array.foldlM f init #[] start stop = pure init
                                @[simp]
                                theorem Array.foldrM_fold_empty {m : Type u_1 → Type u_2} {α : Type u_3} {β : Type u_1} [Monad m] (f : αβm β) (init : β) (i j : Nat) (h : j #[].size) :
                                Array.foldrM.fold f #[] i j h init = pure init
                                @[simp]
                                theorem Array.foldrM_empty {m : Type u_1 → Type u_2} {α : Type u_3} {β : Type u_1} {start stop : Nat} [Monad m] (f : αβm β) (init : β) :
                                Array.foldrM f init #[] start stop = pure init
                                theorem Array.foldl_induction {α : Type u_1} {β : Type u_2} {as : Array α} (motive : NatβProp) {init : β} (h0 : motive 0 init) {f : βαβ} (hf : ∀ (i : Fin as.size) (b : β), motive (↑i) bmotive (i + 1) (f b as[i])) :
                                motive as.size (Array.foldl f init as)
                                @[irreducible]
                                theorem Array.foldl_induction.go {α : Type u_1} {β : Type u_2} {as : Array α} (motive : NatβProp) {f : βαβ} (hf : ∀ (i : Fin as.size) (b : β), motive (↑i) bmotive (i + 1) (f b as[i])) {i j : Nat} {b : β} (h₁ : j as.size) (h₂ : as.size i + j) (H : motive j b) :
                                motive as.size (Array.foldlM.loop f as as.size i j b)
                                theorem Array.foldr_induction {α : Type u_1} {β : Type u_2} {as : Array α} (motive : NatβProp) {init : β} (h0 : motive as.size init) {f : αββ} (hf : ∀ (i : Fin as.size) (b : β), motive (i + 1) bmotive (↑i) (f as[i] b)) :
                                motive 0 (Array.foldr f init as)
                                @[irreducible]
                                theorem Array.foldr_induction.go {α : Type u_1} {β : Type u_2} {as : Array α} (motive : NatβProp) {f : αββ} (hf : ∀ (i : Fin as.size) (b : β), motive (i + 1) bmotive (↑i) (f as[i] b)) {i : Nat} {b : β} (hi : i as.size) (H : motive i b) :
                                motive 0 (Array.foldrM.fold f as 0 i hi b)
                                theorem Array.foldl_congr {α : Type u_1} {β : Type u_2} {as bs : Array α} (h₀ : as = bs) {f g : βαβ} (h₁ : f = g) {a b : β} (h₂ : a = b) {start start' stop stop' : Nat} (h₃ : start = start') (h₄ : stop = stop') :
                                Array.foldl f a as start stop = Array.foldl g b bs start' stop'
                                theorem Array.foldr_congr {α : Type u_1} {β : Type u_2} {as bs : Array α} (h₀ : as = bs) {f g : αββ} (h₁ : f = g) {a b : β} (h₂ : a = b) {start start' stop stop' : Nat} (h₃ : start = start') (h₄ : stop = stop') :
                                Array.foldr f a as start stop = Array.foldr g b bs start' stop'
                                theorem Array.foldl_eq_foldlM {β : Type u_1} {α : Type u_2} (f : βαβ) (b : β) (l : Array α) :
                                theorem Array.foldr_eq_foldrM {α : Type u_1} {β : Type u_2} (f : αββ) (b : β) (l : Array α) :
                                @[simp]
                                theorem Array.id_run_foldlM {β : Type u_1} {α : Type u_2} (f : βαId β) (b : β) (l : Array α) :
                                (Array.foldlM f b l).run = Array.foldl f b l
                                @[simp]
                                theorem Array.id_run_foldrM {α : Type u_1} {β : Type u_2} (f : αβId β) (b : β) (l : Array α) :
                                (Array.foldrM f b l).run = Array.foldr f b l
                                theorem Array.foldl_hom {α₁ : Type u_1} {α₂ : Type u_2} {β : Type u_3} (f : α₁α₂) (g₁ : α₁βα₁) (g₂ : α₂βα₂) (l : Array β) (init : α₁) (H : ∀ (x : α₁) (y : β), g₂ (f x) y = f (g₁ x y)) :
                                Array.foldl g₂ (f init) l = f (Array.foldl g₁ init l)
                                theorem Array.foldr_hom {β₁ : Type u_1} {β₂ : Type u_2} {α : Type u_3} (f : β₁β₂) (g₁ : αβ₁β₁) (g₂ : αβ₂β₂) (l : Array α) (init : β₁) (H : ∀ (x : α) (y : β₁), g₂ x (f y) = f (g₁ x y)) :
                                Array.foldr g₂ (f init) l = f (Array.foldr g₁ init l)

                                map #

                                @[simp]
                                theorem Array.mem_map {α : Type u_1} {β : Type u_2} {b : β} {f : αβ} {l : Array α} :
                                b Array.map f l ∃ (a : α), a l f a = b
                                theorem Array.exists_of_mem_map {α✝ : Type u_1} {α✝¹ : Type u_2} {f : α✝α✝¹} {l : Array α✝} {b : α✝¹} (h : b Array.map f l) :
                                ∃ (a : α✝), a l f a = b
                                theorem Array.mem_map_of_mem {α : Type u_1} {β : Type u_2} {l : Array α} {a : α} (f : αβ) (h : a l) :
                                f a Array.map f l
                                theorem Array.mapM_eq_mapM_toList {m : Type u_1 → Type u_2} {α : Type u_3} {β : Type u_1} [Monad m] [LawfulMonad m] (f : αm β) (arr : Array α) :
                                @[simp]
                                theorem Array.toList_mapM {m : Type u_1 → Type u_2} {α : Type u_3} {β : Type u_1} [Monad m] [LawfulMonad m] (f : αm β) (arr : Array α) :
                                @[irreducible]
                                theorem Array.mapM_map_eq_foldl {α : Type u_1} {β : Type u_2} {b : Array β} (as : Array α) (f : αβ) (i : Nat) :
                                Array.mapM.map f as i b = Array.foldl (fun (r : Array β) (a : α) => r.push (f a)) b as i
                                theorem Array.map_eq_foldl {α : Type u_1} {β : Type u_2} (as : Array α) (f : αβ) :
                                Array.map f as = Array.foldl (fun (r : Array β) (a : α) => r.push (f a)) #[] as
                                theorem Array.map_induction {α : Type u_1} {β : Type u_2} (as : Array α) (f : αβ) (motive : NatProp) (h0 : motive 0) (p : Fin as.sizeβProp) (hs : ∀ (i : Fin as.size), motive ip i (f as[i]) motive (i + 1)) :
                                motive as.size ∃ (eq : (Array.map f as).size = as.size), ∀ (i : Nat) (h : i < as.size), p i, h (Array.map f as)[i]
                                theorem Array.map_spec {α : Type u_1} {β : Type u_2} (as : Array α) (f : αβ) (p : Fin as.sizeβProp) (hs : ∀ (i : Fin as.size), p i (f as[i])) :
                                ∃ (eq : (Array.map f as).size = as.size), ∀ (i : Nat) (h : i < as.size), p i, h (Array.map f as)[i]
                                @[simp]
                                theorem Array.getElem_map {α : Type u_1} {β : Type u_2} (f : αβ) (as : Array α) (i : Nat) (h : i < (Array.map f as).size) :
                                (Array.map f as)[i] = f as[i]
                                @[simp]
                                theorem Array.getElem?_map {α : Type u_1} {β : Type u_2} (f : αβ) (as : Array α) (i : Nat) :
                                (Array.map f as)[i]? = Option.map f as[i]?
                                @[simp]
                                theorem Array.map_push {α : Type u_1} {β : Type u_2} {f : αβ} {as : Array α} {x : α} :
                                Array.map f (as.push x) = (Array.map f as).push (f x)
                                @[simp]
                                theorem Array.map_pop {α : Type u_1} {β : Type u_2} {f : αβ} {as : Array α} :
                                Array.map f as.pop = (Array.map f as).pop

                                modify #

                                @[simp]
                                theorem Array.size_modify {α : Type u_1} (a : Array α) (i : Nat) (f : αα) :
                                (a.modify i f).size = a.size
                                theorem Array.getElem_modify {α : Type u_1} {f : αα} {as : Array α} {x i : Nat} (h : i < (as.modify x f).size) :
                                (as.modify x f)[i] = if x = i then f as[i] else as[i]
                                @[simp]
                                theorem Array.toList_modify {α : Type u_1} {x : Nat} (as : Array α) (f : αα) :
                                (as.modify x f).toList = List.modify f x as.toList
                                theorem Array.getElem_modify_self {α : Type u_1} {as : Array α} {i : Nat} (f : αα) (h : i < (as.modify i f).size) :
                                (as.modify i f)[i] = f as[i]
                                theorem Array.getElem_modify_of_ne {α : Type u_1} {j : Nat} {as : Array α} {i : Nat} (h : i j) (f : αα) (hj : j < (as.modify i f).size) :
                                (as.modify i f)[j] = as[j]
                                theorem Array.getElem?_modify {α : Type u_1} {as : Array α} {i : Nat} {f : αα} {j : Nat} :
                                (as.modify i f)[j]? = if i = j then Option.map f as[j]? else as[j]?

                                filter #

                                @[simp]
                                theorem Array.toList_filter {α : Type u_1} (p : αBool) (l : Array α) :
                                (Array.filter p l).toList = List.filter p l.toList
                                @[simp]
                                theorem Array.filter_filter {α : Type u_1} {p : αBool} (q : αBool) (l : Array α) :
                                Array.filter p (Array.filter q l) = Array.filter (fun (a : α) => p a && q a) l
                                @[simp]
                                theorem Array.mem_filter {α✝ : Type u_1} {p : α✝Bool} {as : Array α✝} {x : α✝} :
                                x Array.filter p as x as p x = true
                                theorem Array.mem_of_mem_filter {α : Type u_1} {p : αBool} {a : α} {l : Array α} (h : a Array.filter p l) :
                                a l
                                theorem Array.filter_congr {α : Type u_1} {as bs : Array α} (h : as = bs) {f g : αBool} (h' : f = g) {start stop start' stop' : Nat} (h₁ : start = start') (h₂ : stop = stop') :
                                Array.filter f as start stop = Array.filter g bs start' stop'

                                filterMap #

                                @[simp]
                                theorem Array.toList_filterMap {α : Type u_1} {β : Type u_2} (f : αOption β) (l : Array α) :
                                (Array.filterMap f l).toList = List.filterMap f l.toList
                                @[simp]
                                theorem Array.mem_filterMap {α : Type u_1} {β : Type u_2} {f : αOption β} {l : Array α} {b : β} :
                                b Array.filterMap f l ∃ (a : α), a l f a = some b
                                theorem Array.filterMap_congr {α : Type u_1} {β : Type u_2} {as bs : Array α} (h : as = bs) {f g : αOption β} (h' : f = g) {start stop start' stop' : Nat} (h₁ : start = start') (h₂ : stop = stop') :
                                Array.filterMap f as start stop = Array.filterMap g bs start' stop'

                                empty #

                                theorem Array.size_empty {α : Type u_1} :
                                #[].size = 0

                                append #

                                theorem Array.push_eq_append_singleton {α : Type u_1} (as : Array α) (x : α) :
                                as.push x = as ++ #[x]
                                @[simp]
                                theorem Array.mem_append {α : Type u_1} {a : α} {s t : Array α} :
                                a s ++ t a s a t
                                theorem Array.mem_append_left {α : Type u_1} {a : α} {l₁ : Array α} (l₂ : Array α) (h : a l₁) :
                                a l₁ ++ l₂
                                theorem Array.mem_append_right {α : Type u_1} {a : α} (l₁ : Array α) {l₂ : Array α} (h : a l₂) :
                                a l₁ ++ l₂
                                @[simp]
                                theorem Array.size_append {α : Type u_1} (as bs : Array α) :
                                (as ++ bs).size = as.size + bs.size
                                theorem Array.empty_append {α : Type u_1} (as : Array α) :
                                #[] ++ as = as
                                theorem Array.append_empty {α : Type u_1} (as : Array α) :
                                as ++ #[] = as
                                theorem Array.getElem_append {α : Type u_1} {i : Nat} {as bs : Array α} (h : i < (as ++ bs).size) :
                                (as ++ bs)[i] = if h' : i < as.size then as[i] else bs[i - as.size]
                                theorem Array.getElem_append_left {α : Type u_1} {i : Nat} {as bs : Array α} {h : i < (as ++ bs).size} (hlt : i < as.size) :
                                (as ++ bs)[i] = as[i]
                                theorem Array.getElem_append_right {α : Type u_1} {i : Nat} {as bs : Array α} {h : i < (as ++ bs).size} (hle : as.size i) :
                                (as ++ bs)[i] = bs[i - as.size]
                                theorem Array.getElem?_append_left {α : Type u_1} {as bs : Array α} {i : Nat} (hn : i < as.size) :
                                (as ++ bs)[i]? = as[i]?
                                theorem Array.getElem?_append_right {α : Type u_1} {as bs : Array α} {i : Nat} (h : as.size i) :
                                (as ++ bs)[i]? = bs[i - as.size]?
                                theorem Array.getElem?_append {α : Type u_1} {as bs : Array α} {i : Nat} :
                                (as ++ bs)[i]? = if i < as.size then as[i]? else bs[i - as.size]?
                                @[simp]
                                theorem Array.toArray_eq_append_iff {α : Type u_1} {xs : List α} {as bs : Array α} :
                                xs.toArray = as ++ bs xs = as.toList ++ bs.toList
                                @[simp]
                                theorem Array.append_eq_toArray_iff {α : Type u_1} {as bs : Array α} {xs : List α} :
                                as ++ bs = xs.toArray as.toList ++ bs.toList = xs

                                flatten #

                                @[simp]
                                theorem Array.toList_flatten {α : Type u_1} {l : Array (Array α)} :
                                l.flatten.toList = (List.map Array.toList l.toList).flatten
                                theorem Array.mem_flatten {α : Type u_1} {a : α} {L : Array (Array α)} :
                                a L.flatten ∃ (l : Array α), l L a l

                                extract #

                                theorem Array.extract_loop_zero {α : Type u_1} (as bs : Array α) (start : Nat) :
                                Array.extract.loop as 0 start bs = bs
                                theorem Array.extract_loop_succ {α : Type u_1} (as bs : Array α) (size start : Nat) (h : start < as.size) :
                                Array.extract.loop as (size + 1) start bs = Array.extract.loop as size (start + 1) (bs.push as[start])
                                theorem Array.extract_loop_of_ge {α : Type u_1} (as bs : Array α) (size start : Nat) (h : start as.size) :
                                Array.extract.loop as size start bs = bs
                                theorem Array.extract_loop_eq_aux {α : Type u_1} (as bs : Array α) (size start : Nat) :
                                Array.extract.loop as size start bs = bs ++ Array.extract.loop as size start #[]
                                theorem Array.extract_loop_eq {α : Type u_1} (as bs : Array α) (size start : Nat) (h : start + size as.size) :
                                Array.extract.loop as size start bs = bs ++ as.extract start (start + size)
                                theorem Array.size_extract_loop {α : Type u_1} (as bs : Array α) (size start : Nat) :
                                (Array.extract.loop as size start bs).size = bs.size + min size (as.size - start)
                                @[simp]
                                theorem Array.size_extract {α : Type u_1} (as : Array α) (start stop : Nat) :
                                (as.extract start stop).size = min stop as.size - start
                                theorem Array.getElem_extract_loop_lt_aux {α : Type u_1} {i : Nat} (as bs : Array α) (size start : Nat) (hlt : i < bs.size) :
                                i < (Array.extract.loop as size start bs).size
                                theorem Array.getElem_extract_loop_lt {α : Type u_1} {i : Nat} (as bs : Array α) (size start : Nat) (hlt : i < bs.size) (h : i < (Array.extract.loop as size start bs).size := ) :
                                (Array.extract.loop as size start bs)[i] = bs[i]
                                theorem Array.getElem_extract_loop_ge_aux {α : Type u_1} {i : Nat} (as bs : Array α) (size start : Nat) (hge : i bs.size) (h : i < (Array.extract.loop as size start bs).size) :
                                start + i - bs.size < as.size
                                theorem Array.getElem_extract_loop_ge {α : Type u_1} {i : Nat} (as bs : Array α) (size start : Nat) (hge : i bs.size) (h : i < (Array.extract.loop as size start bs).size) (h' : start + i - bs.size < as.size := ) :
                                (Array.extract.loop as size start bs)[i] = as[start + i - bs.size]
                                theorem Array.getElem_extract_aux {α : Type u_1} {i : Nat} {as : Array α} {start stop : Nat} (h : i < (as.extract start stop).size) :
                                start + i < as.size
                                @[simp]
                                theorem Array.getElem_extract {α : Type u_1} {i : Nat} {as : Array α} {start stop : Nat} (h : i < (as.extract start stop).size) :
                                (as.extract start stop)[i] = as[start + i]
                                theorem Array.getElem?_extract {α : Type u_1} {i : Nat} {as : Array α} {start stop : Nat} :
                                (as.extract start stop)[i]? = if i < min stop as.size - start then as[start + i]? else none
                                @[simp]
                                theorem Array.toList_extract {α : Type u_1} (as : Array α) (start stop : Nat) :
                                (as.extract start stop).toList = List.take (stop - start) (List.drop start as.toList)
                                @[simp]
                                theorem Array.extract_all {α : Type u_1} (as : Array α) :
                                as.extract 0 as.size = as
                                theorem Array.extract_empty_of_stop_le_start {α : Type u_1} (as : Array α) {start stop : Nat} (h : stop start) :
                                as.extract start stop = #[]
                                theorem Array.extract_empty_of_size_le_start {α : Type u_1} (as : Array α) {start stop : Nat} (h : as.size start) :
                                as.extract start stop = #[]
                                @[simp]
                                theorem Array.extract_empty {α : Type u_1} (start stop : Nat) :
                                #[].extract start stop = #[]

                                contains #

                                theorem Array.contains_def {α : Type u_1} [DecidableEq α] {a : α} {as : Array α} :
                                as.contains a = true a as
                                instance Array.instDecidableMemOfDecidableEq {α : Type u_1} [DecidableEq α] (a : α) (as : Array α) :
                                Decidable (a as)
                                Equations

                                swap #

                                @[simp]
                                theorem Array.getElem_swap_right {α : Type u_1} (a : Array α) {i j : Nat} {hi : i < a.size} {hj : j < a.size} :
                                (a.swap i j hi hj)[j] = a[i]
                                @[simp]
                                theorem Array.getElem_swap_left {α : Type u_1} (a : Array α) {i j : Nat} {hi : i < a.size} {hj : j < a.size} :
                                (a.swap i j hi hj)[i] = a[j]
                                @[simp]
                                theorem Array.getElem_swap_of_ne {α : Type u_1} {p : Nat} (a : Array α) {i j : Nat} {hi : i < a.size} {hj : j < a.size} (hp : p < a.size) (hi' : p i) (hj' : p j) :
                                (a.swap i j hi hj)[p] = a[p]
                                theorem Array.getElem_swap' {α : Type u_1} (a : Array α) (i j : Nat) {hi : i < a.size} {hj : j < a.size} (k : Nat) (hk : k < a.size) :
                                (a.swap i j hi hj)[k] = if k = i then a[j] else if k = j then a[i] else a[k]
                                theorem Array.getElem_swap {α : Type u_1} (a : Array α) (i j : Nat) {hi : i < a.size} {hj : j < a.size} (k : Nat) (hk : k < (a.swap i j hi hj).size) :
                                (a.swap i j hi hj)[k] = if k = i then a[j] else if k = j then a[i] else a[k]
                                @[simp]
                                theorem Array.swap_swap {α : Type u_1} (a : Array α) {i j : Nat} (hi : i < a.size) (hj : j < a.size) :
                                (a.swap i j hi hj).swap i j = a
                                theorem Array.swap_comm {α : Type u_1} (a : Array α) {i j : Nat} {hi : i < a.size} {hj : j < a.size} :
                                a.swap i j hi hj = a.swap j i hj hi

                                eraseIdx #

                                theorem Array.eraseIdx_eq_eraseIdxIfInBounds {α : Type u_1} {a : Array α} {i : Nat} (h : i < a.size) :
                                a.eraseIdx i h = a.eraseIdxIfInBounds i

                                isPrefixOf #

                                @[simp]
                                theorem Array.isPrefixOf_toList {α : Type u_1} [BEq α] {as bs : Array α} :
                                as.toList.isPrefixOf bs.toList = as.isPrefixOf bs

                                zipWith #

                                @[simp]
                                theorem Array.toList_zipWith {α : Type u_1} {β : Type u_2} {γ : Type u_3} (f : αβγ) (as : Array α) (bs : Array β) :
                                (as.zipWith bs f).toList = List.zipWith f as.toList bs.toList
                                @[simp]
                                theorem Array.toList_zip {α : Type u_1} {β : Type u_2} (as : Array α) (bs : Array β) :
                                (as.zip bs).toList = as.toList.zip bs.toList
                                @[simp]
                                theorem Array.toList_zipWithAll {α : Type u_1} {β : Type u_2} {γ : Type u_3} (f : Option αOption βγ) (as : Array α) (bs : Array β) :
                                (as.zipWithAll bs f).toList = List.zipWithAll f as.toList bs.toList
                                @[simp]
                                theorem Array.size_zipWith {α : Type u_1} {β : Type u_2} {γ : Type u_3} (as : Array α) (bs : Array β) (f : αβγ) :
                                (as.zipWith bs f).size = min as.size bs.size
                                @[simp]
                                theorem Array.size_zip {α : Type u_1} {β : Type u_2} (as : Array α) (bs : Array β) :
                                (as.zip bs).size = min as.size bs.size
                                @[simp]
                                theorem Array.getElem_zipWith {α : Type u_1} {β : Type u_2} {γ : Type u_3} (as : Array α) (bs : Array β) (f : αβγ) (i : Nat) (hi : i < (as.zipWith bs f).size) :
                                (as.zipWith bs f)[i] = f as[i] bs[i]

                                findSomeM?, findM?, findSome?, find? #

                                @[simp]
                                theorem Array.findSomeM?_toList {m : Type u_1 → Type u_2} {α : Type u_3} {β : Type u_1} [Monad m] [LawfulMonad m] (p : αm (Option β)) (as : Array α) :
                                @[simp]
                                theorem Array.findM?_toList {m : TypeType} {α : Type} [Monad m] [LawfulMonad m] (p : αm Bool) (as : Array α) :
                                List.findM? p as.toList = Array.findM? p as
                                @[simp]
                                theorem Array.findSome?_toList {α : Type u_1} {β : Type u_2} (p : αOption β) (as : Array α) :
                                @[simp]
                                theorem Array.find?_toList {α : Type u_1} (p : αBool) (as : Array α) :
                                List.find? p as.toList = Array.find? p as

                                More theorems about List.toArray, followed by an Array operation. #

                                Our goal is to have simp "pull List.toArray outwards" as much as possible.

                                theorem List.toListRev_toArray {α : Type u_1} (l : List α) :
                                l.toArray.toListRev = l.reverse
                                @[simp]
                                theorem List.take_toArray {α : Type u_1} (l : List α) (n : Nat) :
                                l.toArray.take n = (List.take n l).toArray
                                @[simp]
                                theorem List.mapM_toArray {m : Type u_1 → Type u_2} {α : Type u_3} {β : Type u_1} [Monad m] [LawfulMonad m] (f : αm β) (l : List α) :
                                @[simp]
                                theorem List.map_toArray {α : Type u_1} {β : Type u_2} (f : αβ) (l : List α) :
                                Array.map f l.toArray = (List.map f l).toArray
                                theorem List.uset_toArray {α : Type u_1} (l : List α) (i : USize) (a : α) (h : i.toNat < l.toArray.size) :
                                l.toArray.uset i a h = (l.set i.toNat a).toArray
                                @[simp]
                                theorem List.swap_toArray {α : Type u_1} (l : List α) (i j : Nat) {hi : i < l.toArray.size} {hj : j < l.toArray.size} :
                                l.toArray.swap i j hi hj = ((l.set i l[j]).set j l[i]).toArray
                                @[simp]
                                theorem List.reverse_toArray {α : Type u_1} (l : List α) :
                                l.toArray.reverse = l.reverse.toArray
                                @[simp]
                                theorem List.modify_toArray {α : Type u_1} {i : Nat} (f : αα) (l : List α) :
                                l.toArray.modify i f = (List.modify f i l).toArray
                                @[simp]
                                theorem List.filter_toArray' {α : Type u_1} {stop : Nat} (p : αBool) (l : List α) (h : stop = l.toArray.size) :
                                Array.filter p l.toArray 0 stop = (List.filter p l).toArray
                                @[simp]
                                theorem List.filterMap_toArray' {α : Type u_1} {β : Type u_2} {stop : Nat} (f : αOption β) (l : List α) (h : stop = l.toArray.size) :
                                Array.filterMap f l.toArray 0 stop = (List.filterMap f l).toArray
                                theorem List.filter_toArray {α : Type u_1} (p : αBool) (l : List α) :
                                Array.filter p l.toArray = (List.filter p l).toArray
                                theorem List.filterMap_toArray {α : Type u_1} {β : Type u_2} (f : αOption β) (l : List α) :
                                Array.filterMap f l.toArray = (List.filterMap f l).toArray
                                @[simp]
                                theorem List.flatten_toArray {α : Type u_1} (l : List (List α)) :
                                (Array.map List.toArray l.toArray).flatten = l.flatten.toArray
                                @[simp]
                                theorem List.toArray_range (n : Nat) :
                                (List.range n).toArray = Array.range n
                                @[simp]
                                theorem List.extract_toArray {α : Type u_1} (l : List α) (start stop : Nat) :
                                l.toArray.extract start stop = (List.take (stop - start) (List.drop start l)).toArray
                                @[simp]
                                theorem List.toArray_ofFn {n : Nat} {α : Type u_1} (f : Fin nα) :
                                (List.ofFn f).toArray = Array.ofFn f
                                @[simp, irreducible]
                                theorem List.eraseIdx_toArray {α : Type u_1} (l : List α) (i : Nat) (h : i < l.toArray.size) :
                                l.toArray.eraseIdx i h = (l.eraseIdx i).toArray
                                @[simp]
                                theorem List.eraseIdxIfInBounds_toArray {α : Type u_1} (l : List α) (i : Nat) :
                                l.toArray.eraseIdxIfInBounds i = (l.eraseIdx i).toArray
                                @[simp]
                                theorem Array.mapM_id {α : Type u_1} {β : Type u_2} {l : Array α} {f : αId β} :
                                @[simp]
                                theorem Array.toList_ofFn {n : Nat} {α : Type u_1} (f : Fin nα) :
                                (Array.ofFn f).toList = List.ofFn f
                                @[simp]
                                theorem Array.toList_takeWhile {α : Type u_1} (p : αBool) (as : Array α) :
                                (Array.takeWhile p as).toList = List.takeWhile p as.toList
                                @[simp]
                                theorem Array.toList_eraseIdx {α : Type u_1} (as : Array α) (i : Nat) (h : i < as.size) :
                                (as.eraseIdx i h).toList = as.toList.eraseIdx i
                                @[simp]
                                theorem Array.toList_eraseIdxIfInBounds {α : Type u_1} (as : Array α) (i : Nat) :
                                (as.eraseIdxIfInBounds i).toList = as.toList.eraseIdx i

                                map #

                                @[simp]
                                theorem Array.map_map {α : Type u_1} {β : Type u_2} {γ : Type u_3} {f : αβ} {g : βγ} {as : Array α} :
                                Array.map g (Array.map f as) = Array.map (g f) as
                                @[simp]
                                theorem Array.map_id_fun {α : Type u_1} :
                                @[simp]
                                theorem Array.map_id_fun' {α : Type u_1} :
                                (Array.map fun (a : α) => a) = id

                                map_id_fun' differs from map_id_fun by representing the identity function as a lambda, rather than id.

                                theorem Array.map_id {α : Type u_1} (as : Array α) :
                                Array.map id as = as
                                theorem Array.map_id' {α : Type u_1} (as : Array α) :
                                Array.map (fun (a : α) => a) as = as

                                map_id' differs from map_id by representing the identity function as a lambda, rather than id.

                                theorem Array.map_id'' {α : Type u_1} {f : αα} (h : ∀ (x : α), f x = x) (as : Array α) :
                                Array.map f as = as

                                Variant of map_id, with a side condition that the function is pointwise the identity.

                                theorem Array.array_array_induction {α : Type u_1} (P : Array (Array α)Prop) (h : ∀ (xss : List (List α)), P (List.map List.toArray xss).toArray) (ass : Array (Array α)) :
                                P ass
                                theorem Array.foldl_map {β₁ : Type u_1} {β₂ : Type u_2} {α : Type u_3} (f : β₁β₂) (g : αβ₂α) (l : Array β₁) (init : α) :
                                Array.foldl g init (Array.map f l) = Array.foldl (fun (x : α) (y : β₁) => g x (f y)) init l
                                theorem Array.foldr_map {α₁ : Type u_1} {α₂ : Type u_2} {β : Type u_3} (f : α₁α₂) (g : α₂ββ) (l : Array α₁) (init : β) :
                                Array.foldr g init (Array.map f l) = Array.foldr (fun (x : α₁) (y : β) => g (f x) y) init l
                                theorem Array.foldl_filterMap {α : Type u_1} {β : Type u_2} {γ : Type u_3} (f : αOption β) (g : γβγ) (l : Array α) (init : γ) :
                                Array.foldl g init (Array.filterMap f l) = Array.foldl (fun (x : γ) (y : α) => match f y with | some b => g x b | none => x) init l
                                theorem Array.foldr_filterMap {α : Type u_1} {β : Type u_2} {γ : Type u_3} (f : αOption β) (g : βγγ) (l : Array α) (init : γ) :
                                Array.foldr g init (Array.filterMap f l) = Array.foldr (fun (x : α) (y : γ) => match f x with | some b => g b y | none => y) init l
                                theorem Array.foldl_map' {α : Type u_1} {β : Type u_2} (g : αβ) (f : ααα) (f' : βββ) (a : α) (l : Array α) (h : ∀ (x y : α), f' (g x) (g y) = g (f x y)) :
                                Array.foldl f' (g a) (Array.map g l) = g (Array.foldl f a l)
                                theorem Array.foldr_map' {α : Type u_1} {β : Type u_2} (g : αβ) (f : ααα) (f' : βββ) (a : α) (l : List α) (h : ∀ (x y : α), f' (g x) (g y) = g (f x y)) :
                                List.foldr f' (g a) (List.map g l) = g (List.foldr f a l)

                                flatten #

                                @[simp]
                                theorem Array.flatten_empty {α : Type u_1} :
                                #[].flatten = #[]
                                @[simp]
                                theorem Array.flatten_toArray_map_toArray {α : Type u_1} (xss : List (List α)) :
                                (List.map List.toArray xss).toArray.flatten = xss.flatten.toArray

                                reverse #

                                @[simp]
                                theorem Array.mem_reverse {α : Type u_1} {x : α} {as : Array α} :
                                x as.reverse x as
                                @[simp]
                                theorem Array.getElem_reverse {α : Type u_1} (as : Array α) (i : Nat) (hi : i < as.reverse.size) :
                                as.reverse[i] = as[as.size - 1 - i]

                                findSomeRevM?, findRevM?, findSomeRev?, findRev? #

                                @[simp]
                                theorem Array.findSomeRevM?_eq_findSomeM?_reverse {m : Type u_1 → Type u_2} {α : Type u_3} {β : Type u_1} [Monad m] [LawfulMonad m] (f : αm (Option β)) (as : Array α) :
                                @[simp]
                                theorem Array.findRevM?_eq_findM?_reverse {m : TypeType} {α : Type} [Monad m] [LawfulMonad m] (f : αm Bool) (as : Array α) :
                                Array.findRevM? f as = Array.findM? f as.reverse
                                @[simp]
                                theorem Array.findSomeRev?_eq_findSome?_reverse {α : Type u_1} {β : Type u_2} (f : αOption β) (as : Array α) :
                                @[simp]
                                theorem Array.findRev?_eq_find?_reverse {α : Type} (f : αBool) (as : Array α) :
                                Array.findRev? f as = Array.find? f as.reverse

                                unzip #

                                @[simp]
                                theorem Array.fst_unzip {α : Type u_1} {β : Type u_2} (as : Array (α × β)) :
                                as.unzip.fst = Array.map Prod.fst as
                                @[simp]
                                theorem Array.snd_unzip {α : Type u_1} {β : Type u_2} (as : Array (α × β)) :
                                as.unzip.snd = Array.map Prod.snd as

                                take #

                                @[simp]
                                theorem Array.take_size {α : Type u_1} (a : Array α) :
                                a.take a.size = a
                                @[simp]
                                theorem List.unzip_toArray {α : Type u_1} {β : Type u_2} (as : List (α × β)) :
                                as.toArray.unzip = Prod.map List.toArray List.toArray as.unzip
                                theorem Array.toList_fst_unzip {α : Type u_1} {β : Type u_2} (as : Array (α × β)) :
                                as.unzip.fst.toList = as.toList.unzip.fst
                                theorem Array.toList_snd_unzip {α : Type u_1} {β : Type u_2} (as : Array (α × β)) :
                                as.unzip.snd.toList = as.toList.unzip.snd
                                @[simp]
                                theorem Array.flatMap_empty {α : Type u_1} {β : Type u_2} (f : αArray β) :
                                Array.flatMap f #[] = #[]
                                theorem Array.flatMap_toArray_cons {α : Type u_1} {β : Type u_2} (f : αArray β) (a : α) (as : List α) :
                                Array.flatMap f (a :: as).toArray = f a ++ Array.flatMap f as.toArray
                                @[simp]
                                theorem Array.flatMap_toArray {α : Type u_1} {β : Type u_2} (f : αArray β) (as : List α) :
                                Array.flatMap f as.toArray = (as.flatMap fun (a : α) => (f a).toList).toArray

                                Deprecations #

                                @[reducible, inline, deprecated List.back!_toArray (since := "2024-10-31")]
                                abbrev List.back_toArray {α : Type u_1} [Inhabited α] (l : List α) :
                                l.toArray.back! = l.getLast!
                                Equations
                                Instances For
                                  @[reducible, inline, deprecated List.setIfInBounds_toArray (since := "2024-11-24")]
                                  abbrev List.setD_toArray {α : Type u_1} (l : List α) (i : Nat) (a : α) :
                                  l.toArray.setIfInBounds i a = (l.set i a).toArray
                                  Equations
                                  Instances For
                                    @[reducible, inline, deprecated Array.foldl_toList_eq_flatMap (since := "2024-10-16")]
                                    abbrev Array.foldl_toList_eq_bind {α : Type u_1} {β : Type u_2} (l : List α) (acc : Array β) (F : Array βαArray β) (G : αList β) (H : ∀ (acc : Array β) (a : α), (F acc a).toList = acc.toList ++ G a) :
                                    (List.foldl F acc l).toList = acc.toList ++ l.flatMap G
                                    Equations
                                    Instances For
                                      @[reducible, inline, deprecated Array.foldl_toList_eq_flatMap (since := "2024-10-16")]
                                      abbrev Array.foldl_data_eq_bind {α : Type u_1} {β : Type u_2} (l : List α) (acc : Array β) (F : Array βαArray β) (G : αList β) (H : ∀ (acc : Array β) (a : α), (F acc a).toList = acc.toList ++ G a) :
                                      (List.foldl F acc l).toList = acc.toList ++ l.flatMap G
                                      Equations
                                      Instances For
                                        @[reducible, inline, deprecated Array.getElem_mem (since := "2024-10-17")]
                                        abbrev Array.getElem?_mem {α : Type u_1} {l : Array α} {i : Nat} (h : i < l.size) :
                                        l[i] l
                                        Equations
                                        Instances For
                                          @[reducible, inline, deprecated Array.getElem_fin_eq_getElem_toList (since := "2024-10-17")]
                                          abbrev Array.getElem_fin_eq_toList_get {α : Type u_1} (a : Array α) (i : Fin a.size) :
                                          a[i] = a.toList[i]
                                          Equations
                                          Instances For
                                            @[reducible, inline, deprecated "Use reverse direction of `getElem?_toList`" (since := "2024-10-17")]
                                            abbrev Array.getElem?_eq_toList_getElem? {α : Type u_1} {a : Array α} {i : Nat} :
                                            a.toList[i]? = a[i]?
                                            Equations
                                            Instances For
                                              @[reducible, inline, deprecated Array.get?_eq_get?_toList (since := "2024-10-17")]
                                              abbrev Array.get?_eq_toList_get? {α : Type u_1} (a : Array α) (i : Nat) :
                                              a.get? i = a.toList.get? i
                                              Equations
                                              Instances For
                                                @[reducible, inline, deprecated Array.getElem?_swap (since := "2024-10-17")]
                                                abbrev Array.get?_swap {α : Type u_1} (a : Array α) (i j : Nat) (hi : i < a.size) (hj : j < a.size) (k : Nat) :
                                                (a.swap i j hi hj)[k]? = if j = k then some a[i] else if i = k then some a[j] else a[k]?
                                                Equations
                                                Instances For
                                                  @[reducible, inline, deprecated Array.getElem_push (since := "2024-10-21")]
                                                  abbrev Array.get_push {α : Type u_1} (a : Array α) (x : α) (i : Nat) (h : i < (a.push x).size) :
                                                  (a.push x)[i] = if h : i < a.size then a[i] else x
                                                  Equations
                                                  Instances For
                                                    @[reducible, inline, deprecated Array.getElem_push_lt (since := "2024-10-21")]
                                                    abbrev Array.get_push_lt {α : Type u_1} (a : Array α) (x : α) (i : Nat) (h : i < a.size) :
                                                    let_fun this := ; (a.push x)[i] = a[i]
                                                    Equations
                                                    Instances For
                                                      @[reducible, inline, deprecated Array.getElem_push_eq (since := "2024-10-21")]
                                                      abbrev Array.get_push_eq {α : Type u_1} (a : Array α) (x : α) :
                                                      (a.push x)[a.size] = x
                                                      Equations
                                                      Instances For
                                                        @[reducible, inline, deprecated Array.back!_eq_back? (since := "2024-10-31")]
                                                        abbrev Array.back_eq_back? {α : Type u_1} [Inhabited α] (a : Array α) :
                                                        a.back! = a.back?.getD default
                                                        Equations
                                                        Instances For
                                                          @[reducible, inline, deprecated Array.back!_push (since := "2024-10-31")]
                                                          abbrev Array.back_push {α : Type u_1} {x : α} [Inhabited α] (a : Array α) :
                                                          (a.push x).back! = x
                                                          Equations
                                                          Instances For
                                                            @[reducible, inline, deprecated Array.eq_push_pop_back!_of_size_ne_zero (since := "2024-10-31")]
                                                            abbrev Array.eq_push_pop_back_of_size_ne_zero {α : Type u_1} [Inhabited α] {as : Array α} (h : as.size 0) :
                                                            as = as.pop.push as.back!
                                                            Equations
                                                            Instances For
                                                              @[reducible, inline, deprecated Array.set!_is_setIfInBounds (since := "2024-11-24")]
                                                              Equations
                                                              Instances For
                                                                @[reducible, inline, deprecated Array.size_setIfInBounds (since := "2024-11-24")]
                                                                abbrev Array.size_setD {α : Type u_1} (as : Array α) (index : Nat) (val : α) :
                                                                (as.setIfInBounds index val).size = as.size
                                                                Equations
                                                                Instances For
                                                                  @[reducible, inline, deprecated Array.getElem_setIfInBounds_eq (since := "2024-11-24")]
                                                                  abbrev Array.getElem_setD_eq {α : Type u_1} (as : Array α) {i : Nat} (v : α) (h : i < (as.setIfInBounds i v).size) :
                                                                  (as.setIfInBounds i v)[i] = v
                                                                  Equations
                                                                  Instances For
                                                                    @[reducible, inline, deprecated Array.getElem?_setIfInBounds_eq (since := "2024-11-24")]
                                                                    abbrev Array.get?_setD_eq {α : Type u_1} (as : Array α) {i : Nat} (v : α) :
                                                                    (as.setIfInBounds i v)[i]? = if i < as.size then some v else none
                                                                    Equations
                                                                    Instances For
                                                                      @[reducible, inline, deprecated Array.getD_get?_setIfInBounds (since := "2024-11-24")]
                                                                      abbrev Array.getD_setD {α : Type u_1} (a : Array α) (i : Nat) (v d : α) :
                                                                      (a.setIfInBounds i v)[i]?.getD d = if i < a.size then v else d
                                                                      Equations
                                                                      Instances For
                                                                        @[reducible, inline, deprecated Array.getElem_setIfInBounds (since := "2024-11-24")]
                                                                        abbrev Array.getElem_setD {α : Type u_1} (as : Array α) (i : Nat) (v : α) (j : Nat) (hj : j < (as.setIfInBounds i v).size) :
                                                                        (as.setIfInBounds i v)[j] = if i = j then v else as[j]
                                                                        Equations
                                                                        Instances For
                                                                          @[deprecated List.getElem_toArray (since := "2024-11-29")]
                                                                          theorem Array.getElem_mk {α : Type u_1} {xs : List α} {i : Nat} (h : i < xs.length) :
                                                                          { toList := xs }[i] = xs[i]
                                                                          @[deprecated Array.getElem_toList (since := "2024-12-08")]
                                                                          theorem Array.getElem_eq_getElem_toList {α : Type u_1} {i : Nat} {a : Array α} (h : i < a.size) :
                                                                          a[i] = a.toList[i]
                                                                          @[deprecated Array.getElem?_toList (since := "2024-12-08")]
                                                                          theorem Array.getElem?_eq_getElem?_toList {α : Type u_1} (a : Array α) (i : Nat) :
                                                                          a[i]? = a.toList[i]?
                                                                          @[deprecated LawfulGetElem.getElem?_def (since := "2024-12-08")]
                                                                          theorem Array.getElem?_eq {α : Type u_1} {a : Array α} {i : Nat} :
                                                                          a[i]? = if h : i < a.size then some a[i] else none