Documentation

Init.Data.List.Lemmas

Bootstrapping theorems for lists #

These are theorems used in the definitions of Std.Data.List.Basic and tactics. New theorems should be added to Std.Data.List.Lemmas if they are not needed by the bootstrap.

@[simp]
theorem List.get?_nil {α : Type u_1} {n : Nat} :
List.get? [] n = none
@[simp]
theorem List.get?_cons_zero {α : Type u_1} {a : α} {l : List α} :
List.get? (a :: l) 0 = some a
@[simp]
theorem List.get?_cons_succ {α : Type u_1} {a : α} {l : List α} {n : Nat} :
List.get? (a :: l) (n + 1) = List.get? l n
@[simp]
theorem List.get_cons_zero :
∀ {α : Type u_1} {a : α} {l : List α}, List.get (a :: l) 0 = a
@[simp]
theorem List.head?_nil {α : Type u_1} :
List.head? [] = none
@[simp]
theorem List.head?_cons {α : Type u_1} {a : α} {l : List α} :
@[simp]
theorem List.headD_nil {α : Type u_1} {d : α} :
List.headD [] d = d
@[simp]
theorem List.headD_cons {α : Type u_1} {a : α} {l : List α} {d : α} :
List.headD (a :: l) d = a
@[simp]
theorem List.head_cons {α : Type u_1} {a : α} {l : List α} {h : a :: l []} :
List.head (a :: l) h = a
@[simp]
theorem List.tail?_nil {α : Type u_1} :
List.tail? [] = none
@[simp]
theorem List.tail?_cons {α : Type u_1} {a : α} {l : List α} :
@[simp]
theorem List.tail!_cons {α : Type u_1} {a : α} {l : List α} :
List.tail! (a :: l) = l
@[simp]
theorem List.tailD_nil {α : Type u_1} {l' : List α} :
List.tailD [] l' = l'
@[simp]
theorem List.tailD_cons {α : Type u_1} {a : α} {l : List α} {l' : List α} :
List.tailD (a :: l) l' = l
@[simp]
theorem List.any_nil :
∀ {α : Type u_1} {f : αBool}, List.any [] f = false
@[simp]
theorem List.any_cons :
∀ {α : Type u_1} {a : α} {l : List α} {f : αBool}, List.any (a :: l) f = (f a || List.any l f)
@[simp]
theorem List.all_nil :
∀ {α : Type u_1} {f : αBool}, List.all [] f = true
@[simp]
theorem List.all_cons :
∀ {α : Type u_1} {a : α} {l : List α} {f : αBool}, List.all (a :: l) f = (f a && List.all l f)
@[simp]
@[simp]
theorem List.or_cons {a : Bool} {l : List Bool} :
List.or (a :: l) = (a || List.or l)
@[simp]
@[simp]
theorem List.and_cons {a : Bool} {l : List Bool} :
List.and (a :: l) = (a && List.and l)

length #

theorem List.eq_nil_of_length_eq_zero :
∀ {α : Type u_1} {l : List α}, List.length l = 0l = []
theorem List.ne_nil_of_length_eq_succ :
∀ {α : Type u_1} {l : List α} {n : Nat}, List.length l = Nat.succ nl []
theorem List.length_eq_zero :
∀ {α : Type u_1} {l : List α}, List.length l = 0 l = []

mem #

@[simp]
theorem List.not_mem_nil {α : Type u_1} (a : α) :
¬a []
@[simp]
theorem List.mem_cons :
∀ {α : Type u_1} {a b : α} {l : List α}, a b :: l a = b a l
theorem List.mem_cons_self {α : Type u_1} (a : α) (l : List α) :
a a :: l
theorem List.mem_cons_of_mem {α : Type u_1} (y : α) {a : α} {l : List α} :
a la y :: l
theorem List.eq_nil_iff_forall_not_mem {α : Type u_1} {l : List α} :
l = [] ∀ (a : α), ¬a l

append #

@[simp]
theorem List.singleton_append :
∀ {α : Type u_1} {x : α} {l : List α}, [x] ++ l = x :: l
theorem List.append_inj {α : Type u_1} {s₁ : List α} {s₂ : List α} {t₁ : List α} {t₂ : List α} :
s₁ ++ t₁ = s₂ ++ t₂List.length s₁ = List.length s₂s₁ = s₂ t₁ = t₂
theorem List.append_inj_right :
∀ {α : Type u_1} {s₁ t₁ s₂ t₂ : List α}, s₁ ++ t₁ = s₂ ++ t₂List.length s₁ = List.length s₂t₁ = t₂
theorem List.append_inj_left :
∀ {α : Type u_1} {s₁ t₁ s₂ t₂ : List α}, s₁ ++ t₁ = s₂ ++ t₂List.length s₁ = List.length s₂s₁ = s₂
theorem List.append_inj' :
∀ {α : Type u_1} {s₁ t₁ s₂ t₂ : List α}, s₁ ++ t₁ = s₂ ++ t₂List.length t₁ = List.length t₂s₁ = s₂ t₁ = t₂
theorem List.append_inj_right' :
∀ {α : Type u_1} {s₁ t₁ s₂ t₂ : List α}, s₁ ++ t₁ = s₂ ++ t₂List.length t₁ = List.length t₂t₁ = t₂
theorem List.append_inj_left' :
∀ {α : Type u_1} {s₁ t₁ s₂ t₂ : List α}, s₁ ++ t₁ = s₂ ++ t₂List.length t₁ = List.length t₂s₁ = s₂
theorem List.append_right_inj {α : Type u_1} {t₁ : List α} {t₂ : List α} (s : List α) :
s ++ t₁ = s ++ t₂ t₁ = t₂
theorem List.append_left_inj {α : Type u_1} {s₁ : List α} {s₂ : List α} (t : List α) :
s₁ ++ t = s₂ ++ t s₁ = s₂
@[simp]
theorem List.append_eq_nil :
∀ {α : Type u_1} {p q : List α}, p ++ q = [] p = [] q = []
theorem List.get_append {α : Type u_1} {l₁ : List α} {l₂ : List α} (n : Nat) (h : n < List.length l₁) :
List.get (l₁ ++ l₂) { val := n, isLt := } = List.get l₁ { val := n, isLt := h }

map #

@[simp]
theorem List.map_nil {α : Type u_1} {β : Type u_2} {f : αβ} :
List.map f [] = []
@[simp]
theorem List.map_cons {α : Type u_1} {β : Type u_2} (f : αβ) (a : α) (l : List α) :
List.map f (a :: l) = f a :: List.map f l
@[simp]
theorem List.map_append {α : Type u_1} {β : Type u_2} (f : αβ) (l₁ : List α) (l₂ : List α) :
List.map f (l₁ ++ l₂) = List.map f l₁ ++ List.map f l₂
@[simp]
theorem List.map_id {α : Type u_1} (l : List α) :
List.map id l = l
@[simp]
theorem List.map_id' {α : Type u_1} (l : List α) :
List.map (fun (a : α) => a) l = l
@[simp]
theorem List.mem_map {α : Type u_1} {β : Type u_2} {b : β} {f : αβ} {l : List α} :
b List.map f l ∃ (a : α), a l f a = b
theorem List.mem_map_of_mem {α : Type u_1} {β : Type u_2} {a : α} {l : List α} (f : αβ) (h : a l) :
f a List.map f l
@[simp]
theorem List.map_map {β : Type u_1} {γ : Type u_2} {α : Type u_3} (g : βγ) (f : αβ) (l : List α) :
List.map g (List.map f l) = List.map (g f) l

bind #

@[simp]
theorem List.nil_bind {α : Type u_1} {β : Type u_2} (f : αList β) :
List.bind [] f = []
@[simp]
theorem List.cons_bind {α : Type u_1} {β : Type u_2} (x : α) (xs : List α) (f : αList β) :
List.bind (x :: xs) f = f x ++ List.bind xs f
@[simp]
theorem List.append_bind {α : Type u_1} {β : Type u_2} (xs : List α) (ys : List α) (f : αList β) :
List.bind (xs ++ ys) f = List.bind xs f ++ List.bind ys f
@[simp]
theorem List.bind_id {α : Type u_1} (l : List (List α)) :

join #

@[simp]
theorem List.join_nil {α : Type u_1} :
List.join [] = []
@[simp]
theorem List.join_cons :
∀ {α : Type u_1} {l : List α} {ls : List (List α)}, List.join (l :: ls) = l ++ List.join ls

bounded quantifiers over Lists #

theorem List.forall_mem_cons {α : Type u_1} {p : αProp} {a : α} {l : List α} :
(∀ (x : α), x a :: lp x) p a ∀ (x : α), x lp x

reverse #

@[simp]
theorem List.reverseAux_nil :
∀ {α : Type u_1} {r : List α}, List.reverseAux [] r = r
@[simp]
theorem List.reverseAux_cons :
∀ {α : Type u_1} {a : α} {l r : List α}, List.reverseAux (a :: l) r = List.reverseAux l (a :: r)
theorem List.reverseAux_eq {α : Type u_1} (as : List α) (bs : List α) :
theorem List.reverse_map {α : Type u_1} {β : Type u_2} (f : αβ) (l : List α) :
@[simp]
theorem List.reverse_eq_nil_iff {α : Type u_1} {xs : List α} :
List.reverse xs = [] xs = []

nth element #

theorem List.get_of_mem {α : Type u_1} {a : α} {l : List α} :
a l∃ (n : Fin (List.length l)), List.get l n = a
theorem List.get_mem {α : Type u_1} (l : List α) (n : Nat) (h : n < List.length l) :
List.get l { val := n, isLt := h } l
theorem List.mem_iff_get {α : Type u_1} {a : α} {l : List α} :
a l ∃ (n : Fin (List.length l)), List.get l n = a
theorem List.get?_len_le {α : Type u_1} {l : List α} {n : Nat} :
List.length l nList.get? l n = none
theorem List.get?_eq_get {α : Type u_1} {l : List α} {n : Nat} (h : n < List.length l) :
List.get? l n = some (List.get l { val := n, isLt := h })
theorem List.get?_eq_some :
∀ {α : Type u_1} {a : α} {l : List α} {n : Nat}, List.get? l n = some a ∃ (h : n < List.length l), List.get l { val := n, isLt := h } = a
@[simp]
theorem List.get?_eq_none :
∀ {α : Type u_1} {l : List α} {n : Nat}, List.get? l n = none List.length l n
@[simp]
theorem List.get?_map {α : Type u_1} {β : Type u_2} (f : αβ) (l : List α) (n : Nat) :
theorem List.get?_append {α : Type u_1} {l₁ : List α} {l₂ : List α} {n : Nat} (hn : n < List.length l₁) :
List.get? (l₁ ++ l₂) n = List.get? l₁ n
@[simp]
theorem List.get?_concat_length {α : Type u_1} (l : List α) (a : α) :
List.get? (l ++ [a]) (List.length l) = some a
theorem List.getLast_eq_get {α : Type u_1} (l : List α) (h : l []) :
List.getLast l h = List.get l { val := List.length l - 1, isLt := }
@[simp]
theorem List.getLast?_nil {α : Type u_1} :
theorem List.getLast?_eq_getLast {α : Type u_1} (l : List α) (h : l []) :
@[simp]
theorem List.getLast?_concat {α : Type u_1} {a : α} (l : List α) :
theorem List.getD_eq_get? {α : Type u_1} (l : List α) (n : Nat) (a : α) :
theorem List.get?_append_right {α : Type u_1} {l₁ : List α} {l₂ : List α} {n : Nat} :
List.length l₁ nList.get? (l₁ ++ l₂) n = List.get? l₂ (n - List.length l₁)
theorem List.get?_reverse' {α : Type u_1} {l : List α} (i : Nat) (j : Nat) :
theorem List.get?_reverse {α : Type u_1} {l : List α} (i : Nat) (h : i < List.length l) :

take and drop #

@[simp]
theorem List.take_append_drop {α : Type u_1} (n : Nat) (l : List α) :
@[simp]
theorem List.length_drop {α : Type u_1} (i : Nat) (l : List α) :
theorem List.drop_length_le {α : Type u_1} {i : Nat} {l : List α} (h : List.length l i) :
List.drop i l = []
theorem List.take_length_le {α : Type u_1} {i : Nat} {l : List α} (h : List.length l i) :
List.take i l = l
@[simp]
theorem List.take_zero {α : Type u_1} (l : List α) :
List.take 0 l = []
@[simp]
theorem List.take_nil {α : Type u_1} {i : Nat} :
List.take i [] = []
@[simp]
theorem List.take_cons_succ :
∀ {α : Type u_1} {a : α} {as : List α} {i : Nat}, List.take (i + 1) (a :: as) = a :: List.take i as
@[simp]
theorem List.drop_zero {α : Type u_1} (l : List α) :
List.drop 0 l = l
@[simp]
theorem List.drop_succ_cons :
∀ {α : Type u_1} {a : α} {l : List α} {n : Nat}, List.drop (n + 1) (a :: l) = List.drop n l
@[simp]
theorem List.drop_length {α : Type u_1} (l : List α) :
@[simp]
theorem List.take_length {α : Type u_1} (l : List α) :
theorem List.take_concat_get {α : Type u_1} (l : List α) (i : Nat) (h : i < List.length l) :
List.concat (List.take i l) l[i] = List.take (i + 1) l
theorem List.reverse_concat {α : Type u_1} (l : List α) (a : α) :

takeWhile and dropWhile #

@[simp]
theorem List.dropWhile_nil {α : Type u_1} {p : αBool} :
theorem List.dropWhile_cons {α : Type u_1} {x : α} {xs : List α} {p : αBool} :
List.dropWhile p (x :: xs) = if p x = true then List.dropWhile p xs else x :: xs

foldlM and foldrM #

@[simp]
theorem List.foldlM_reverse {m : Type u_1 → Type u_2} {α : Type u_3} {β : Type u_1} [Monad m] (l : List α) (f : βαm β) (b : β) :
List.foldlM f b (List.reverse l) = List.foldrM (fun (x : α) (y : β) => f y x) b l
@[simp]
theorem List.foldlM_nil {m : Type u_1 → Type u_2} {β : Type u_1} {α : Type u_3} [Monad m] (f : βαm β) (b : β) :
List.foldlM f b [] = pure b
@[simp]
theorem List.foldlM_cons {m : Type u_1 → Type u_2} {β : Type u_1} {α : Type u_3} [Monad m] (f : βαm β) (b : β) (a : α) (l : List α) :
List.foldlM f b (a :: l) = do let init ← f b a List.foldlM f init l
@[simp]
theorem List.foldlM_append {m : Type u_1 → Type u_2} {β : Type u_1} {α : Type u_3} [Monad m] [LawfulMonad m] (f : βαm β) (b : β) (l : List α) (l' : List α) :
List.foldlM f b (l ++ l') = do let init ← List.foldlM f b l List.foldlM f init l'
@[simp]
theorem List.foldrM_nil {m : Type u_1 → Type u_2} {α : Type u_3} {β : Type u_1} [Monad m] (f : αβm β) (b : β) :
List.foldrM f b [] = pure b
@[simp]
theorem List.foldrM_cons {m : Type u_1 → Type u_2} {α : Type u_3} {β : Type u_1} [Monad m] [LawfulMonad m] (a : α) (l : List α) (f : αβm β) (b : β) :
List.foldrM f b (a :: l) = List.foldrM f b l >>= f a
@[simp]
theorem List.foldrM_reverse {m : Type u_1 → Type u_2} {α : Type u_3} {β : Type u_1} [Monad m] (l : List α) (f : αβm β) (b : β) :
List.foldrM f b (List.reverse l) = List.foldlM (fun (x : β) (y : α) => f y x) b l
theorem List.foldl_eq_foldlM {β : Type u_1} {α : Type u_2} (f : βαβ) (b : β) (l : List α) :
theorem List.foldr_eq_foldrM {α : Type u_1} {β : Type u_2} (f : αββ) (b : β) (l : List α) :

foldl and foldr #

@[simp]
theorem List.foldl_reverse {α : Type u_1} {β : Type u_2} (l : List α) (f : βαβ) (b : β) :
List.foldl f b (List.reverse l) = List.foldr (fun (x : α) (y : β) => f y x) b l
@[simp]
theorem List.foldr_reverse {α : Type u_1} {β : Type u_2} (l : List α) (f : αββ) (b : β) :
List.foldr f b (List.reverse l) = List.foldl (fun (x : β) (y : α) => f y x) b l
@[simp]
theorem List.foldrM_append {m : Type u_1 → Type u_2} {α : Type u_3} {β : Type u_1} [Monad m] [LawfulMonad m] (f : αβm β) (b : β) (l : List α) (l' : List α) :
List.foldrM f b (l ++ l') = do let init ← List.foldrM f b l' List.foldrM f init l
@[simp]
theorem List.foldl_append {α : Type u_1} {β : Type u_2} (f : βαβ) (b : β) (l : List α) (l' : List α) :
List.foldl f b (l ++ l') = List.foldl f (List.foldl f b l) l'
@[simp]
theorem List.foldr_append {α : Type u_1} {β : Type u_2} (f : αββ) (b : β) (l : List α) (l' : List α) :
List.foldr f b (l ++ l') = List.foldr f (List.foldr f b l') l
@[simp]
theorem List.foldl_nil :
∀ {α : Type u_1} {β : Type u_2} {f : αβα} {b : α}, List.foldl f b [] = b
@[simp]
theorem List.foldl_cons {α : Type u_1} {β : Type u_2} {a : α} {f : βαβ} (l : List α) (b : β) :
List.foldl f b (a :: l) = List.foldl f (f b a) l
@[simp]
theorem List.foldr_nil :
∀ {α : Type u_1} {α_1 : Type u_2} {f : αα_1α_1} {b : α_1}, List.foldr f b [] = b
@[simp]
theorem List.foldr_cons {α : Type u_1} {a : α} :
∀ {α_1 : Type u_2} {f : αα_1α_1} {b : α_1} (l : List α), List.foldr f b (a :: l) = f a (List.foldr f b l)
@[simp]
theorem List.foldr_self_append {α : Type u_1} {l' : List α} (l : List α) :
List.foldr List.cons l' l = l ++ l'
theorem List.foldr_self {α : Type u_1} (l : List α) :
List.foldr List.cons [] l = l

mapM #

def List.mapM' {m : Type u_1 → Type u_2} {α : Type u_3} {β : Type u_1} [Monad m] (f : αm β) :
List αm (List β)

Alternate (non-tail-recursive) form of mapM for proofs.

Equations
Instances For
    @[simp]
    theorem List.mapM'_nil {m : Type u_1 → Type u_2} {α : Type u_3} {β : Type u_1} [Monad m] {f : αm β} :
    List.mapM' f [] = pure []
    @[simp]
    theorem List.mapM'_cons {m : Type u_1 → Type u_2} {α : Type u_3} {β : Type u_1} {a : α} {l : List α} [Monad m] {f : αm β} :
    List.mapM' f (a :: l) = do let __do_lift ← f a let __do_lift_1 ← List.mapM' f l pure (__do_lift :: __do_lift_1)
    theorem List.mapM'_eq_mapM {m : Type u_1 → Type u_2} {α : Type u_3} {β : Type u_1} [Monad m] [LawfulMonad m] (f : αm β) (l : List α) :
    theorem List.mapM'_eq_mapM.go {m : Type u_1 → Type u_2} {α : Type u_3} {β : Type u_1} [Monad m] [LawfulMonad m] (f : αm β) (l : List α) (acc : List β) :
    List.mapM.loop f l acc = do let __do_lift ← List.mapM' f l pure (List.reverse acc ++ __do_lift)
    @[simp]
    theorem List.mapM_nil {m : Type u_1 → Type u_2} {α : Type u_3} {β : Type u_1} [Monad m] (f : αm β) :
    List.mapM f [] = pure []
    @[simp]
    theorem List.mapM_cons {m : Type u_1 → Type u_2} {α : Type u_3} {β : Type u_1} {a : α} {l : List α} [Monad m] [LawfulMonad m] (f : αm β) :
    List.mapM f (a :: l) = do let __do_lift ← f a let __do_lift_1 ← List.mapM f l pure (__do_lift :: __do_lift_1)
    @[simp]
    theorem List.mapM_append {m : Type u_1 → Type u_2} {α : Type u_3} {β : Type u_1} [Monad m] [LawfulMonad m] (f : αm β) {l₁ : List α} {l₂ : List α} :
    List.mapM f (l₁ ++ l₂) = do let __do_lift ← List.mapM f l₁ let __do_lift_1 ← List.mapM f l₂ pure (__do_lift ++ __do_lift_1)

    forM #

    @[simp]
    theorem List.forM_nil' {m : Type u_1 → Type u_2} {α : Type u_3} {f : αm PUnit} [Monad m] :
    @[simp]
    theorem List.forM_cons' {m : Type u_1 → Type u_2} :
    ∀ {α : Type u_3} {a : α} {as : List α} {f : αm PUnit} [inst : Monad m], List.forM (a :: as) f = do f a List.forM as f

    eraseIdx #

    @[simp]
    theorem List.eraseIdx_nil {α : Type u_1} {i : Nat} :
    @[simp]
    theorem List.eraseIdx_cons_zero :
    ∀ {α : Type u_1} {a : α} {as : List α}, List.eraseIdx (a :: as) 0 = as
    @[simp]
    theorem List.eraseIdx_cons_succ :
    ∀ {α : Type u_1} {a : α} {as : List α} {i : Nat}, List.eraseIdx (a :: as) (i + 1) = a :: List.eraseIdx as i

    find? #

    @[simp]
    theorem List.find?_nil {α : Type u_1} {p : αBool} :
    List.find? p [] = none
    theorem List.find?_cons :
    ∀ {α : Type u_1} {a : α} {as : List α} {p : αBool}, List.find? p (a :: as) = match p a with | true => some a | false => List.find? p as

    filter #

    @[simp]
    theorem List.filter_nil {α : Type u_1} (p : αBool) :
    List.filter p [] = []
    @[simp]
    theorem List.filter_cons_of_pos {α : Type u_1} {p : αBool} {a : α} (l : List α) (pa : p a = true) :
    List.filter p (a :: l) = a :: List.filter p l
    @[simp]
    theorem List.filter_cons_of_neg {α : Type u_1} {p : αBool} {a : α} (l : List α) (pa : ¬p a = true) :
    theorem List.filter_cons {α : Type u_1} {x : α} {xs : List α} {p : αBool} :
    List.filter p (x :: xs) = if p x = true then x :: List.filter p xs else List.filter p xs
    theorem List.mem_filter :
    ∀ {α : Type u_1} {x : α} {p : αBool} {as : List α}, x List.filter p as x as p x = true
    theorem List.filter_eq_nil :
    ∀ {α : Type u_1} {p : αBool} {l : List α}, List.filter p l = [] ∀ (a : α), a l¬p a = true

    findSome? #

    @[simp]
    theorem List.findSome?_nil {α : Type u_1} :
    ∀ {α_1 : Type u_2} {f : αOption α_1}, List.findSome? f [] = none
    theorem List.findSome?_cons {α : Type u_1} {β : Type u_2} {a : α} {as : List α} {f : αOption β} :
    List.findSome? f (a :: as) = match f a with | some b => some b | none => List.findSome? f as

    replace #

    @[simp]
    theorem List.replace_nil {α : Type u_1} {a : α} {b : α} [BEq α] :
    List.replace [] a b = []
    theorem List.replace_cons {α : Type u_1} {as : List α} {b : α} {c : α} [BEq α] {a : α} :
    List.replace (a :: as) b c = match a == b with | true => c :: as | false => a :: List.replace as b c
    @[simp]
    theorem List.replace_cons_self {α : Type u_1} {as : List α} {b : α} [BEq α] [LawfulBEq α] {a : α} :
    List.replace (a :: as) a b = b :: as

    elem #

    @[simp]
    theorem List.elem_nil {α : Type u_1} {a : α} [BEq α] :
    theorem List.elem_cons {α : Type u_1} {as : List α} {b : α} [BEq α] {a : α} :
    List.elem b (a :: as) = match b == a with | true => true | false => List.elem b as
    @[simp]
    theorem List.elem_cons_self {α : Type u_1} {as : List α} [BEq α] [LawfulBEq α] {a : α} :
    List.elem a (a :: as) = true

    lookup #

    @[simp]
    theorem List.lookup_nil {α : Type u_1} {β : Type u_2} {a : α} [BEq α] :
    List.lookup a [] = none
    theorem List.lookup_cons {α : Type u_1} :
    ∀ {β : Type u_2} {b : β} {es : List (α × β)} {a : α} [inst : BEq α] {k : α}, List.lookup a ((k, b) :: es) = match a == k with | true => some b | false => List.lookup a es
    @[simp]
    theorem List.lookup_cons_self {α : Type u_1} :
    ∀ {β : Type u_2} {b : β} {es : List (α × β)} [inst : BEq α] [inst_1 : LawfulBEq α] {k : α}, List.lookup k ((k, b) :: es) = some b

    zipWith #

    @[simp]
    theorem List.zipWith_nil_left {α : Type u_1} {β : Type u_2} {γ : Type u_3} {l : List β} {f : αβγ} :
    List.zipWith f [] l = []
    @[simp]
    theorem List.zipWith_nil_right {α : Type u_1} {β : Type u_2} {γ : Type u_3} {l : List α} {f : αβγ} :
    List.zipWith f l [] = []
    @[simp]
    theorem List.zipWith_cons_cons {α : Type u_1} {β : Type u_2} {γ : Type u_3} {a : α} {as : List α} {b : β} {bs : List β} {f : αβγ} :
    List.zipWith f (a :: as) (b :: bs) = f a b :: List.zipWith f as bs
    theorem List.zipWith_get? {α : Type u_1} {β : Type u_2} {γ : Type u_3} {as : List α} {bs : List β} {i : Nat} {f : αβγ} :
    List.get? (List.zipWith f as bs) i = match List.get? as i, List.get? bs i with | some a, some b => some (f a b) | x, x_1 => none

    zipWithAll #

    theorem List.zipWithAll_get? {α : Type u_1} {β : Type u_2} {γ : Type u_3} {as : List α} {bs : List β} {i : Nat} {f : Option αOption βγ} :
    List.get? (List.zipWithAll f as bs) i = match List.get? as i, List.get? bs i with | none, none => none | a?, b? => some (f a? b?)

    zip #

    @[simp]
    theorem List.zip_nil_left {α : Type u_1} {β : Type u_2} {l : List β} :
    List.zip [] l = []
    @[simp]
    theorem List.zip_nil_right {α : Type u_1} {l : List α} {β : Type u_2} :
    List.zip l [] = []
    @[simp]
    theorem List.zip_cons_cons :
    ∀ {α : Type u_1} {a : α} {as : List α} {α_1 : Type u_2} {b : α_1} {bs : List α_1}, List.zip (a :: as) (b :: bs) = (a, b) :: List.zip as bs

    unzip #

    @[simp]
    theorem List.unzip_nil {α : Type u_1} {β : Type u_2} :
    List.unzip [] = ([], [])
    @[simp]
    theorem List.unzip_cons {α : Type u_1} {β : Type u_2} {t : List (α × β)} {h : α × β} :
    List.unzip (h :: t) = match List.unzip t with | (al, bl) => (h.fst :: al, h.snd :: bl)

    all / any #

    @[simp]
    theorem List.all_eq_true {α : Type u_1} {p : αBool} {l : List α} :
    List.all l p = true ∀ (x : α), x lp x = true
    @[simp]
    theorem List.any_eq_true {α : Type u_1} {p : αBool} {l : List α} :
    List.any l p = true ∃ (x : α), x l p x = true

    enumFrom #

    @[simp]
    theorem List.enumFrom_nil {α : Type u_1} {i : Nat} :
    @[simp]
    theorem List.enumFrom_cons :
    ∀ {α : Type u_1} {a : α} {as : List α} {i : Nat}, List.enumFrom i (a :: as) = (i, a) :: List.enumFrom (i + 1) as

    iota #

    @[simp]
    theorem List.iota_zero :
    @[simp]
    theorem List.iota_succ {i : Nat} :
    List.iota (i + 1) = (i + 1) :: List.iota i

    intersperse #

    @[simp]
    theorem List.intersperse_nil {α : Type u_1} (sep : α) :
    @[simp]
    theorem List.intersperse_single {α : Type u_1} {x : α} (sep : α) :
    List.intersperse sep [x] = [x]
    @[simp]
    theorem List.intersperse_cons₂ {α : Type u_1} {x : α} {y : α} {zs : List α} (sep : α) :
    List.intersperse sep (x :: y :: zs) = x :: sep :: List.intersperse sep (y :: zs)

    isPrefixOf #

    @[simp]
    theorem List.isPrefixOf_nil_left {α : Type u_1} {l : List α} [BEq α] :
    @[simp]
    theorem List.isPrefixOf_cons_nil {α : Type u_1} {a : α} {as : List α} [BEq α] :
    theorem List.isPrefixOf_cons₂ {α : Type u_1} {as : List α} {b : α} {bs : List α} [BEq α] {a : α} :
    List.isPrefixOf (a :: as) (b :: bs) = (a == b && List.isPrefixOf as bs)
    @[simp]
    theorem List.isPrefixOf_cons₂_self {α : Type u_1} {as : List α} {bs : List α} [BEq α] [LawfulBEq α] {a : α} :
    List.isPrefixOf (a :: as) (a :: bs) = List.isPrefixOf as bs

    isEqv #

    @[simp]
    theorem List.isEqv_nil_nil {α : Type u_1} {eqv : ααBool} :
    List.isEqv [] [] eqv = true
    @[simp]
    theorem List.isEqv_nil_cons {α : Type u_1} {a : α} {as : List α} {eqv : ααBool} :
    List.isEqv [] (a :: as) eqv = false
    @[simp]
    theorem List.isEqv_cons_nil {α : Type u_1} {a : α} {as : List α} {eqv : ααBool} :
    List.isEqv (a :: as) [] eqv = false
    theorem List.isEqv_cons₂ :
    ∀ {α : Type u_1} {a : α} {as : List α} {b : α} {bs : List α} {eqv : ααBool}, List.isEqv (a :: as) (b :: bs) eqv = (eqv a b && List.isEqv as bs eqv)

    dropLast #

    @[simp]
    theorem List.dropLast_nil {α : Type u_1} :
    @[simp]
    theorem List.dropLast_single :
    ∀ {α : Type u_1} {x : α}, List.dropLast [x] = []
    @[simp]
    theorem List.dropLast_cons₂ :
    ∀ {α : Type u_1} {x y : α} {zs : List α}, List.dropLast (x :: y :: zs) = x :: List.dropLast (y :: zs)

    minimum? #

    @[simp]
    theorem List.minimum?_nil {α : Type u_1} [Min α] :
    theorem List.minimum?_cons {α : Type u_1} {x : α} [Min α] {xs : List α} :
    List.minimum? (x :: xs) = some (List.foldl min x xs)
    @[simp]
    theorem List.minimum?_eq_none_iff {α : Type u_1} {xs : List α} [Min α] :
    List.minimum? xs = none xs = []
    theorem List.minimum?_mem {α : Type u_1} {a : α} [Min α] (min_eq_or : ∀ (a b : α), min a b = a min a b = b) {xs : List α} :
    List.minimum? xs = some aa xs
    theorem List.le_minimum?_iff {α : Type u_1} {a : α} [Min α] [LE α] (le_min_iff : ∀ (a b c : α), a min b c a b a c) {xs : List α} :
    List.minimum? xs = some a∀ (x : α), x a ∀ (b : α), b xsx b
    theorem List.minimum?_eq_some_iff {α : Type u_1} {a : α} [Min α] [LE α] [anti : Antisymm fun (x x_1 : α) => x x_1] (le_refl : ∀ (a : α), a a) (min_eq_or : ∀ (a b : α), min a b = a min a b = b) (le_min_iff : ∀ (a b c : α), a min b c a b a c) {xs : List α} :
    List.minimum? xs = some a a xs ∀ (b : α), b xsa b
    @[simp]
    theorem List.get_cons_succ {α : Type u_1} {i : Nat} {a : α} {as : List α} {h : i + 1 < List.length (a :: as)} :
    List.get (a :: as) { val := i + 1, isLt := h } = List.get as { val := i, isLt := }
    @[simp]
    theorem List.get_cons_succ' {α : Type u_1} {a : α} {as : List α} {i : Fin (List.length as)} :
    List.get (a :: as) (Fin.succ i) = List.get as i
    @[simp]
    theorem List.set_nil {α : Type u_1} (n : Nat) (a : α) :
    List.set [] n a = []
    @[simp]
    theorem List.set_zero {α : Type u_1} (x : α) (xs : List α) (a : α) :
    List.set (x :: xs) 0 a = a :: xs
    @[simp]
    theorem List.set_succ {α : Type u_1} (x : α) (xs : List α) (n : Nat) (a : α) :
    List.set (x :: xs) (Nat.succ n) a = x :: List.set xs n a
    @[simp]
    theorem List.get_set_eq {α : Type u_1} (l : List α) (i : Nat) (a : α) (h : i < List.length (List.set l i a)) :
    List.get (List.set l i a) { val := i, isLt := h } = a
    @[simp]
    theorem List.get_set_ne {α : Type u_1} (l : List α) {i : Nat} {j : Nat} (h : i j) (a : α) (hj : j < List.length (List.set l i a)) :
    List.get (List.set l i a) { val := j, isLt := hj } = List.get l { val := j, isLt := }