Basic properties of Lists #
length #
theorem
List.exists_mem_of_length_pos
{α : Type u_1}
{l : List α}
:
0 < List.length l → ∃ (a : α), a ∈ l
theorem
List.length_pos_iff_exists_mem
{α : Type u_1}
{l : List α}
:
0 < List.length l ↔ ∃ (a : α), a ∈ l
mem #
@[simp]
@[simp]
drop #
@[simp]
theorem
List.drop_left
{α : Type u_1}
(l₁ : List α)
(l₂ : List α)
:
List.drop (List.length l₁) (l₁ ++ l₂) = l₂
isEmpty #
@[simp]
append #
map #
zipWith #
@[simp]
theorem
List.length_zipWith
{α : Type u_1}
{β : Type u_2}
{γ : Type u_3}
(f : α → β → γ)
(l₁ : List α)
(l₂ : List β)
:
List.length (List.zipWith f l₁ l₂) = min (List.length l₁) (List.length l₂)
@[simp]
theorem
List.zipWith_map
{γ : Type u_1}
{δ : Type u_2}
{α : Type u_3}
{β : Type u_4}
{μ : Type u_5}
(f : γ → δ → μ)
(g : α → γ)
(h : β → δ)
(l₁ : List α)
(l₂ : List β)
:
List.zipWith f (List.map g l₁) (List.map h l₂) = List.zipWith (fun (a : α) (b : β) => f (g a) (h b)) l₁ l₂
theorem
List.zipWith_map_left
{α : Type u_1}
{β : Type u_2}
{α' : Type u_3}
{γ : Type u_4}
(l₁ : List α)
(l₂ : List β)
(f : α → α')
(g : α' → β → γ)
:
List.zipWith g (List.map f l₁) l₂ = List.zipWith (fun (a : α) (b : β) => g (f a) b) l₁ l₂
theorem
List.zipWith_map_right
{α : Type u_1}
{β : Type u_2}
{β' : Type u_3}
{γ : Type u_4}
(l₁ : List α)
(l₂ : List β)
(f : β → β')
(g : α → β' → γ)
:
List.zipWith g l₁ (List.map f l₂) = List.zipWith (fun (a : α) (b : β) => g a (f b)) l₁ l₂
theorem
List.zipWith_foldr_eq_zip_foldr
{α : Type u_1}
{β : Type u_2}
{γ : Type u_3}
{δ : Type u_4}
{l₁ : List α}
{l₂ : List β}
{g : γ → δ → δ}
{f : α → β → γ}
(i : δ)
:
List.foldr g i (List.zipWith f l₁ l₂) = List.foldr (fun (p : α × β) (r : δ) => g (f p.fst p.snd) r) i (List.zip l₁ l₂)
theorem
List.zipWith_foldl_eq_zip_foldl
{α : Type u_1}
{β : Type u_2}
{γ : Type u_3}
{δ : Type u_4}
{l₁ : List α}
{l₂ : List β}
{g : δ → γ → δ}
{f : α → β → γ}
(i : δ)
:
List.foldl g i (List.zipWith f l₁ l₂) = List.foldl (fun (r : δ) (p : α × β) => g r (f p.fst p.snd)) i (List.zip l₁ l₂)
theorem
List.map_zipWith
{α : Type u_1}
{β : Type u_2}
{γ : Type u_3}
{δ : Type u_4}
(f : α → β)
(g : γ → δ → α)
(l : List γ)
(l' : List δ)
:
List.map f (List.zipWith g l l') = List.zipWith (fun (x : γ) (y : δ) => f (g x y)) l l'
theorem
List.zipWith_append
{α : Type u_1}
{β : Type u_2}
{γ : Type u_3}
(f : α → β → γ)
(l : List α)
(la : List α)
(l' : List β)
(lb : List β)
(h : List.length l = List.length l')
:
List.zipWith f (l ++ la) (l' ++ lb) = List.zipWith f l l' ++ List.zipWith f la lb
zip #
@[simp]
theorem
List.length_zip
{α : Type u_1}
{β : Type u_2}
(l₁ : List α)
(l₂ : List β)
:
List.length (List.zip l₁ l₂) = min (List.length l₁) (List.length l₂)
theorem
List.map_fst_zip
{α : Type u_1}
{β : Type u_2}
(l₁ : List α)
(l₂ : List β)
:
List.length l₁ ≤ List.length l₂ → List.map Prod.fst (List.zip l₁ l₂) = l₁
theorem
List.map_snd_zip
{α : Type u_1}
{β : Type u_2}
(l₁ : List α)
(l₂ : List β)
:
List.length l₂ ≤ List.length l₁ → List.map Prod.snd (List.zip l₁ l₂) = l₂
join #
bind #
set-theoretic notation of Lists #
bounded quantifiers over Lists #
List subset #
replicate #
theorem
List.replicate_succ
{α : Type u_1}
(a : α)
(n : Nat)
:
List.replicate (n + 1) a = a :: List.replicate n a
theorem
List.eq_of_mem_replicate
{α : Type u_1}
{a : α}
{b : α}
{n : Nat}
(h : b ∈ List.replicate n a)
:
b = a
theorem
List.eq_replicate_of_mem
{α : Type u_1}
{a : α}
{l : List α}
:
(∀ (b : α), b ∈ l → b = a) → l = List.replicate (List.length l) a
theorem
List.eq_replicate
{α : Type u_1}
{a : α}
{n : Nat}
{l : List α}
:
l = List.replicate n a ↔ List.length l = n ∧ ∀ (b : α), b ∈ l → b = a
getLast #
theorem
List.getLast_cons'
{α : Type u_1}
{a : α}
{l : List α}
(h₁ : a :: l ≠ [])
(h₂ : l ≠ [])
:
List.getLast (a :: l) h₁ = List.getLast l h₂
@[simp]
theorem
List.getLast_append
{α : Type u_1}
{a : α}
(l : List α)
(h : l ++ [a] ≠ [])
:
List.getLast (l ++ [a]) h = a
theorem
List.getLast_concat :
∀ {α : Type u_1} {l : List α} {a : α} (h : List.concat l a ≠ []), List.getLast (List.concat l a) h = a
sublists #
theorem
List.Sublist.trans
{α : Type u_1}
{l₁ : List α}
{l₂ : List α}
{l₃ : List α}
(h₁ : List.Sublist l₁ l₂)
(h₂ : List.Sublist l₂ l₃)
:
List.Sublist l₁ l₃
Equations
- List.instTransListSublist = { trans := (_ : ∀ {a b c : List α}, List.Sublist a b → List.Sublist b c → List.Sublist a c) }
@[simp]
theorem
List.sublist_of_cons_sublist :
∀ {α : Type u_1} {a : α} {l₁ l₂ : List α}, List.Sublist (a :: l₁) l₂ → List.Sublist l₁ l₂
@[simp]
theorem
List.sublist_append_left
{α : Type u_1}
(l₁ : List α)
(l₂ : List α)
:
List.Sublist l₁ (l₁ ++ l₂)
@[simp]
theorem
List.sublist_append_right
{α : Type u_1}
(l₁ : List α)
(l₂ : List α)
:
List.Sublist l₂ (l₁ ++ l₂)
theorem
List.sublist_append_of_sublist_left :
∀ {α : Type u_1} {l l₁ l₂ : List α}, List.Sublist l l₁ → List.Sublist l (l₁ ++ l₂)
theorem
List.sublist_append_of_sublist_right :
∀ {α : Type u_1} {l l₂ l₁ : List α}, List.Sublist l l₂ → List.Sublist l (l₁ ++ l₂)
theorem
List.cons_sublist_cons :
∀ {α : Type u_1} {a : α} {l₁ l₂ : List α}, List.Sublist (a :: l₁) (a :: l₂) ↔ List.Sublist l₁ l₂
@[simp]
theorem
List.append_sublist_append_left :
∀ {α : Type u_1} {l₁ l₂ : List α} (l : List α), List.Sublist (l ++ l₁) (l ++ l₂) ↔ List.Sublist l₁ l₂
theorem
List.Sublist.append_left :
∀ {α : Type u_1} {l₁ l₂ : List α}, List.Sublist l₁ l₂ → ∀ (l : List α), List.Sublist (l ++ l₁) (l ++ l₂)
theorem
List.Sublist.append_right :
∀ {α : Type u_1} {l₁ l₂ : List α}, List.Sublist l₁ l₂ → ∀ (l : List α), List.Sublist (l₁ ++ l) (l₂ ++ l)
theorem
List.sublist_or_mem_of_sublist :
∀ {α : Type u_1} {l l₁ : List α} {a : α} {l₂ : List α},
List.Sublist l (l₁ ++ a :: l₂) → List.Sublist l (l₁ ++ l₂) ∨ a ∈ l
theorem
List.Sublist.reverse :
∀ {α : Type u_1} {l₁ l₂ : List α}, List.Sublist l₁ l₂ → List.Sublist (List.reverse l₁) (List.reverse l₂)
@[simp]
theorem
List.reverse_sublist :
∀ {α : Type u_1} {l₁ l₂ : List α}, List.Sublist (List.reverse l₁) (List.reverse l₂) ↔ List.Sublist l₁ l₂
@[simp]
theorem
List.append_sublist_append_right :
∀ {α : Type u_1} {l₁ l₂ : List α} (l : List α), List.Sublist (l₁ ++ l) (l₂ ++ l) ↔ List.Sublist l₁ l₂
theorem
List.Sublist.append :
∀ {α : Type u_1} {l₁ l₂ r₁ r₂ : List α}, List.Sublist l₁ l₂ → List.Sublist r₁ r₂ → List.Sublist (l₁ ++ r₁) (l₂ ++ r₂)
instance
List.instTransListSublistSubsetInstHasSubsetList
{α : Type u_1}
:
Trans List.Sublist Subset Subset
Equations
- List.instTransListSublistSubsetInstHasSubsetList = { trans := (_ : ∀ {a b c : List α}, List.Sublist a b → b ⊆ c → a ⊆ c) }
instance
List.instTransListSubsetSublistInstHasSubsetList
{α : Type u_1}
:
Trans Subset List.Sublist Subset
Equations
- List.instTransListSubsetSublistInstHasSubsetList = { trans := (_ : ∀ {a b c : List α}, a ⊆ b → List.Sublist b c → a ⊆ c) }
instance
List.instTransListMemInstMembershipListSublist
{α : Type u_1}
:
Trans Membership.mem List.Sublist Membership.mem
Equations
- List.instTransListMemInstMembershipListSublist = { trans := (_ : ∀ {a : α} {b c : List α}, a ∈ b → List.Sublist b c → a ∈ c) }
theorem
List.Sublist.length_le :
∀ {α : Type u_1} {l₁ l₂ : List α}, List.Sublist l₁ l₂ → List.length l₁ ≤ List.length l₂
theorem
List.Sublist.eq_of_length :
∀ {α : Type u_1} {l₁ l₂ : List α}, List.Sublist l₁ l₂ → List.length l₁ = List.length l₂ → l₁ = l₂
theorem
List.Sublist.eq_of_length_le :
∀ {α : Type u_1} {l₁ l₂ : List α}, List.Sublist l₁ l₂ → List.length l₂ ≤ List.length l₁ → l₁ = l₂
@[simp]
@[simp]
theorem
List.replicate_sublist_replicate
{α : Type u_1}
{m : Nat}
{n : Nat}
(a : α)
:
List.Sublist (List.replicate m a) (List.replicate n a) ↔ m ≤ n
theorem
List.isSublist_iff_sublist
{α : Type u_1}
[DecidableEq α]
{l₁ : List α}
{l₂ : List α}
:
List.isSublist l₁ l₂ = true ↔ List.Sublist l₁ l₂
instance
List.instDecidableSublist
{α : Type u_1}
[DecidableEq α]
(l₁ : List α)
(l₂ : List α)
:
Decidable (List.Sublist l₁ l₂)
Equations
- List.instDecidableSublist l₁ l₂ = decidable_of_iff (List.isSublist l₁ l₂ = true) (_ : List.isSublist l₁ l₂ = true ↔ List.Sublist l₁ l₂)
head #
theorem
List.head!_of_head?
{α : Type u_1}
{a : α}
[Inhabited α]
{l : List α}
:
List.head? l = some a → List.head! l = a
theorem
List.head?_eq_head
{α : Type u_1}
(l : List α)
(h : l ≠ [])
:
List.head? l = some (List.head l h)
tail #
@[simp]
theorem
List.tailD_eq_tail?
{α : Type u_1}
(l : List α)
(l' : List α)
:
List.tailD l l' = Option.getD (List.tail? l) l'
next? #
@[simp]
getLast #
@[simp]
theorem
List.getLastD_cons
{α : Type u_1}
(a : α)
(b : α)
(l : List α)
:
List.getLastD (b :: l) a = List.getLastD l b
theorem
List.getLast_eq_getLastD
{α : Type u_1}
(a : α)
(l : List α)
(h : a :: l ≠ [])
:
List.getLast (a :: l) h = List.getLastD l a
theorem
List.getLastD_eq_getLast?
{α : Type u_1}
(a : α)
(l : List α)
:
List.getLastD l a = Option.getD (List.getLast? l) a
theorem
List.getLast!_cons
{α : Type u_1}
{a : α}
{l : List α}
[Inhabited α]
:
List.getLast! (a :: l) = List.getLastD l a
theorem
List.getLast?_cons
{α : Type u_1}
{a : α}
{l : List α}
:
List.getLast? (a :: l) = some (List.getLastD l a)
dropLast #
NB: dropLast
is the specification for Array.pop
, so theorems about List.dropLast
are often used for theorems about Array.pop
.
@[simp]
theorem
List.dropLast_append_cons :
∀ {α : Type u_1} {l₁ : List α} {b : α} {l₂ : List α}, List.dropLast (l₁ ++ b :: l₂) = l₁ ++ List.dropLast (b :: l₂)
@[simp]
theorem
List.dropLast_concat :
∀ {α : Type u_1} {l₁ : List α} {b : α}, List.dropLast (l₁ ++ [b]) = l₁
@[simp]
theorem
List.length_dropLast
{α : Type u_1}
(xs : List α)
:
List.length (List.dropLast xs) = List.length xs - 1
@[simp]
theorem
List.get_dropLast
{α : Type u_1}
(xs : List α)
(i : Fin (List.length (List.dropLast xs)))
:
List.get (List.dropLast xs) i = List.get xs (Fin.castLE (_ : List.length (List.dropLast xs) ≤ List.length xs) i)
nth element #
theorem
List.get!_len_le
{α : Type u_1}
[Inhabited α]
{l : List α}
{n : Nat}
:
List.length l ≤ n → List.get! l n = default
@[simp]
theorem
List.get?_inj
{i : Nat}
:
∀ {α : Type u_1} {xs : List α} {j : Nat}, i < List.length xs → List.Nodup xs → List.get? xs i = List.get? xs j → i = j
@[simp]
theorem
List.get_map
{α : Type u_1}
{β : Type u_2}
(f : α → β)
{l : List α}
{n : Fin (List.length (List.map f l))}
:
theorem
List.get_of_eq
{α : Type u_1}
{l : List α}
{l' : List α}
(h : l = l')
(i : Fin (List.length l))
:
List.get l i = List.get l' { val := i.val, isLt := (_ : i.val < List.length l') }
If one has get l i hi
in a formula and h : l = l'
, one can not rw h
in the formula as
hi
gives i < l.length
and not i < l'.length
. The theorem get_of_eq
can be used to make
such a rewrite, with rw (get_of_eq h)
.
theorem
List.get_zero
{α : Type u_1}
{l : List α}
(h : 0 < List.length l)
:
some (List.get l { val := 0, isLt := h }) = List.head? l
theorem
List.get_append
{α : Type u_1}
{l₁ : List α}
{l₂ : List α}
(n : Nat)
(h : n < List.length l₁)
:
theorem
List.get?_append_right
{α : Type u_1}
{l₁ : List α}
{l₂ : List α}
{n : Nat}
:
List.length l₁ ≤ n → List.get? (l₁ ++ l₂) n = List.get? l₂ (n - List.length l₁)
theorem
List.get_append_right_aux
{α : Type u_1}
{l₁ : List α}
{l₂ : List α}
{n : Nat}
(h₁ : List.length l₁ ≤ n)
(h₂ : n < List.length (l₁ ++ l₂))
:
n - List.length l₁ < List.length l₂
theorem
List.get_append_right'
{α : Type u_1}
{l₁ : List α}
{l₂ : List α}
{n : Nat}
(h₁ : List.length l₁ ≤ n)
(h₂ : n < List.length (l₁ ++ l₂))
:
List.get (l₁ ++ l₂) { val := n, isLt := h₂ } = List.get l₂ { val := n - List.length l₁, isLt := (_ : n - List.length l₁ < List.length l₂) }
theorem
List.get_of_append_proof
{α : Type u_1}
{l₁ : List α}
{a : α}
{l₂ : List α}
{n : Nat}
{l : List α}
(eq : l = l₁ ++ a :: l₂)
(h : List.length l₁ = n)
:
n < List.length l
@[simp]
theorem
List.get_replicate
{α : Type u_1}
(a : α)
{n : Nat}
(m : Fin (List.length (List.replicate n a)))
:
List.get (List.replicate n a) m = a
@[simp]
theorem
List.getLastD_concat
{α : Type u_1}
(a : α)
(b : α)
(l : List α)
:
List.getLastD (l ++ [b]) a = b
theorem
List.get_cons_length
{α : Type u_1}
(x : α)
(xs : List α)
(n : Nat)
(h : n = List.length xs)
:
List.get (x :: xs) { val := n, isLt := (_ : n < Nat.succ (List.length xs)) } = List.getLast (x :: xs) (_ : x :: xs ≠ [])
theorem
List.ext_get
{α : Type u_1}
{l₁ : List α}
{l₂ : List α}
(hl : List.length l₁ = List.length l₂)
(h : ∀ (n : Nat) (h₁ : n < List.length l₁) (h₂ : n < List.length l₂),
List.get l₁ { val := n, isLt := h₁ } = List.get l₂ { val := n, isLt := h₂ })
:
l₁ = l₂
theorem
List.get?_reverse'
{α : Type u_1}
{l : List α}
(i : Nat)
(j : Nat)
:
i + j + 1 = List.length l → List.get? (List.reverse l) i = List.get? l j
theorem
List.get?_reverse
{α : Type u_1}
{l : List α}
(i : Nat)
(h : i < List.length l)
:
List.get? (List.reverse l) i = List.get? l (List.length l - 1 - i)
theorem
List.getD_eq_get?
{α : Type u_1}
(l : List α)
(n : Nat)
(a : α)
:
List.getD l n a = Option.getD (List.get? l n) a
take and drop #
@[simp]
theorem
List.length_take
{α : Type u_1}
(i : Nat)
(l : List α)
:
List.length (List.take i l) = min i (List.length l)
theorem
List.length_take_of_le
{n : Nat}
:
∀ {α : Type u_1} {l : List α}, n ≤ List.length l → List.length (List.take n l) = n
Dropping the elements up to n
in l₁ ++ l₂
is the same as dropping the elements up to n
in l₁
, dropping the elements up to n - l₁.length
in l₂
, and appending them.
modify nth #
theorem
List.removeNth_eq_nth_tail
{α : Type u_1}
(n : Nat)
(l : List α)
:
List.removeNth l n = List.modifyNthTail List.tail n l
theorem
List.modifyNthTail_length
{α : Type u_1}
(f : List α → List α)
(H : ∀ (l : List α), List.length (f l) = List.length l)
(n : Nat)
(l : List α)
:
List.length (List.modifyNthTail f n l) = List.length l
theorem
List.modifyNthTail_add
{α : Type u_1}
(f : List α → List α)
(n : Nat)
(l₁ : List α)
(l₂ : List α)
:
List.modifyNthTail f (List.length l₁ + n) (l₁ ++ l₂) = l₁ ++ List.modifyNthTail f n l₂
theorem
List.exists_of_modifyNthTail
{α : Type u_1}
(f : List α → List α)
{n : Nat}
{l : List α}
(h : n ≤ List.length l)
:
@[simp]
theorem
List.modify_get?_length
{α : Type u_1}
(f : α → α)
(n : Nat)
(l : List α)
:
List.length (List.modifyNth f n l) = List.length l
@[simp]
theorem
List.get?_modifyNth_eq
{α : Type u_1}
(f : α → α)
(n : Nat)
(l : List α)
:
List.get? (List.modifyNth f n l) n = f <$> List.get? l n
theorem
List.exists_of_modifyNth
{α : Type u_1}
(f : α → α)
{n : Nat}
{l : List α}
(h : n < List.length l)
:
set #
theorem
List.set_eq_modifyNth
{α : Type u_1}
(a : α)
(n : Nat)
(l : List α)
:
List.set l n a = List.modifyNth (fun (x : α) => a) n l
theorem
List.modifyNth_eq_set_get?
{α : Type u_1}
(f : α → α)
(n : Nat)
(l : List α)
:
List.modifyNth f n l = Option.getD ((fun (a : α) => List.set l n (f a)) <$> List.get? l n) l
theorem
List.modifyNth_eq_set_get
{α : Type u_1}
(f : α → α)
{n : Nat}
{l : List α}
(h : n < List.length l)
:
List.modifyNth f n l = List.set l n (f (List.get l { val := n, isLt := h }))
remove nth #
theorem
List.length_removeNth
{α : Type u_1}
{l : List α}
{i : Nat}
:
i < List.length l → List.length (List.removeNth l i) = List.length l - 1
tail #
@[simp]
all / any #
@[simp]
theorem
List.contains_cons
{α : Type u_1}
{a : α}
{as : List α}
{x : α}
[BEq α]
:
List.contains (a :: as) x = (x == a || List.contains as x)
theorem
List.contains_eq_any_beq
{α : Type u_1}
[BEq α]
(l : List α)
(a : α)
:
List.contains l a = List.any l fun (x : α) => a == x
reverse #
@[simp]
insert #
@[simp]
theorem
List.insert_of_mem
{α : Type u_1}
[DecidableEq α]
{a : α}
{l : List α}
(h : a ∈ l)
:
List.insert a l = l
@[simp]
theorem
List.insert_of_not_mem
{α : Type u_1}
[DecidableEq α]
{a : α}
{l : List α}
(h : ¬a ∈ l)
:
List.insert a l = a :: l
@[simp]
@[simp]
theorem
List.mem_insert_self
{α : Type u_1}
[DecidableEq α]
(a : α)
(l : List α)
:
a ∈ List.insert a l
theorem
List.mem_insert_of_mem
{α : Type u_1}
[DecidableEq α]
{a : α}
{b : α}
{l : List α}
(h : a ∈ l)
:
a ∈ List.insert b l
theorem
List.eq_or_mem_of_mem_insert
{α : Type u_1}
[DecidableEq α]
{a : α}
{b : α}
{l : List α}
(h : a ∈ List.insert b l)
:
@[simp]
theorem
List.length_insert_of_mem
{α : Type u_1}
[DecidableEq α]
{a : α}
{l : List α}
(h : a ∈ l)
:
List.length (List.insert a l) = List.length l
@[simp]
theorem
List.length_insert_of_not_mem
{α : Type u_1}
[DecidableEq α]
{a : α}
{l : List α}
(h : ¬a ∈ l)
:
List.length (List.insert a l) = List.length l + 1
eraseP #
theorem
List.eraseP_cons
{α : Type u_1}
{p : α → Bool}
(a : α)
(l : List α)
:
List.eraseP p (a :: l) = bif p a then l else a :: List.eraseP p l
@[simp]
theorem
List.eraseP_cons_of_pos
{α : Type u_1}
{a : α}
{l : List α}
(p : α → Bool)
(h : p a = true)
:
List.eraseP p (a :: l) = l
@[simp]
theorem
List.eraseP_cons_of_neg
{α : Type u_1}
{a : α}
{l : List α}
(p : α → Bool)
(h : ¬p a = true)
:
List.eraseP p (a :: l) = a :: List.eraseP p l
@[simp]
theorem
List.length_eraseP_of_mem :
∀ {α : Type u_1} {a : α} {l : List α} {p : α → Bool},
a ∈ l → p a = true → List.length (List.eraseP p l) = Nat.pred (List.length l)
theorem
List.eraseP_append_left
{α : Type u_1}
{p : α → Bool}
{a : α}
(pa : p a = true)
{l₁ : List α}
(l₂ : List α)
:
a ∈ l₁ → List.eraseP p (l₁ ++ l₂) = List.eraseP p l₁ ++ l₂
theorem
List.eraseP_append_right
{α : Type u_1}
{p : α → Bool}
{l₁ : List α}
(l₂ : List α)
:
(∀ (b : α), b ∈ l₁ → ¬p b = true) → List.eraseP p (l₁ ++ l₂) = l₁ ++ List.eraseP p l₂
theorem
List.eraseP_sublist
{α : Type u_1}
{p : α → Bool}
(l : List α)
:
List.Sublist (List.eraseP p l) l
theorem
List.Sublist.eraseP :
∀ {α : Type u_1} {l₁ l₂ : List α} {p : α → Bool},
List.Sublist l₁ l₂ → List.Sublist (List.eraseP p l₁) (List.eraseP p l₂)
theorem
List.mem_of_mem_eraseP
{α : Type u_1}
{a : α}
{p : α → Bool}
{l : List α}
:
a ∈ List.eraseP p l → a ∈ l
theorem
List.eraseP_map
{β : Type u_1}
{α : Type u_2}
{p : α → Bool}
(f : β → α)
(l : List β)
:
List.eraseP p (List.map f l) = List.map f (List.eraseP (p ∘ f) l)
@[simp]
theorem
List.extractP_eq_find?_eraseP
{α : Type u_1}
{p : α → Bool}
(l : List α)
:
List.extractP p l = (List.find? p l, List.eraseP p l)
theorem
List.extractP_eq_find?_eraseP.go
{α : Type u_1}
{p : α → Bool}
(l : List α)
(acc : Array α)
(xs : List α)
:
l = acc.data ++ xs → List.extractP.go p l xs acc = (List.find? p xs, acc.data ++ List.eraseP p xs)
erase #
theorem
List.erase_cons
{α : Type u_1}
[DecidableEq α]
(a : α)
(b : α)
(l : List α)
:
List.erase (b :: l) a = if b = a then l else b :: List.erase l a
@[simp]
theorem
List.erase_cons_head
{α : Type u_1}
[DecidableEq α]
(a : α)
(l : List α)
:
List.erase (a :: l) a = l
@[simp]
theorem
List.erase_cons_tail
{α : Type u_1}
[DecidableEq α]
{a : α}
{b : α}
(l : List α)
(h : b ≠ a)
:
List.erase (b :: l) a = b :: List.erase l a
theorem
List.erase_eq_eraseP
{α : Type u_1}
[DecidableEq α]
(a : α)
(l : List α)
:
List.erase l a = List.eraseP (fun (b : α) => decide (a = b)) l
theorem
List.Sublist.erase
{α : Type u_1}
[DecidableEq α]
(a : α)
{l₁ : List α}
{l₂ : List α}
(h : List.Sublist l₁ l₂)
:
List.Sublist (List.erase l₁ a) (List.erase l₂ a)
theorem
List.erase_of_not_mem
{α : Type u_1}
[DecidableEq α]
{a : α}
{l : List α}
:
¬a ∈ l → List.erase l a = l
@[simp]
theorem
List.length_erase_of_mem
{α : Type u_1}
[DecidableEq α]
{a : α}
{l : List α}
(h : a ∈ l)
:
List.length (List.erase l a) = Nat.pred (List.length l)
theorem
List.erase_append_left
{α : Type u_1}
[DecidableEq α]
{a : α}
{l₁ : List α}
(l₂ : List α)
(h : a ∈ l₁)
:
List.erase (l₁ ++ l₂) a = List.erase l₁ a ++ l₂
theorem
List.erase_append_right
{α : Type u_1}
[DecidableEq α]
{a : α}
{l₁ : List α}
(l₂ : List α)
(h : ¬a ∈ l₁)
:
List.erase (l₁ ++ l₂) a = l₁ ++ List.erase l₂ a
theorem
List.erase_sublist
{α : Type u_1}
[DecidableEq α]
(a : α)
(l : List α)
:
List.Sublist (List.erase l a) l
theorem
List.sublist.erase
{α : Type u_1}
[DecidableEq α]
(a : α)
{l₁ : List α}
{l₂ : List α}
(h : List.Sublist l₁ l₂)
:
List.Sublist (List.erase l₁ a) (List.erase l₂ a)
theorem
List.mem_of_mem_erase
{α : Type u_1}
[DecidableEq α]
{a : α}
{b : α}
{l : List α}
(h : a ∈ List.erase l b)
:
a ∈ l
@[simp]
theorem
List.mem_erase_of_ne
{α : Type u_1}
[DecidableEq α]
{a : α}
{b : α}
{l : List α}
(ab : a ≠ b)
:
a ∈ List.erase l b ↔ a ∈ l
theorem
List.erase_comm
{α : Type u_1}
[DecidableEq α]
(a : α)
(b : α)
(l : List α)
:
List.erase (List.erase l a) b = List.erase (List.erase l b) a
filter and partition #
@[simp]
theorem
List.filter_append
{α : Type u_1}
{p : α → Bool}
(l₁ : List α)
(l₂ : List α)
:
List.filter p (l₁ ++ l₂) = List.filter p l₁ ++ List.filter p l₂
@[simp]
theorem
List.filter_sublist
{α : Type u_1}
{p : α → Bool}
(l : List α)
:
List.Sublist (List.filter p l) l
@[simp]
theorem
List.partition_eq_filter_filter
{α : Type u_1}
(p : α → Bool)
(l : List α)
:
List.partition p l = (List.filter p l, List.filter (not ∘ p) l)
theorem
List.partition_eq_filter_filter.aux
{α : Type u_1}
(p : α → Bool)
(l : List α)
{as : List α}
{bs : List α}
:
List.partition.loop p l (as, bs) = (List.reverse as ++ List.filter p l, List.reverse bs ++ List.filter (not ∘ p) l)
theorem
List.filter_congr'
{α : Type u_1}
{p : α → Bool}
{q : α → Bool}
{l : List α}
:
(∀ (x : α), x ∈ l → (p x = true ↔ q x = true)) → List.filter p l = List.filter q l
filterMap #
@[simp]
theorem
List.filterMap_nil
{α : Type u_1}
{β : Type u_2}
(f : α → Option β)
:
List.filterMap f [] = []
@[simp]
theorem
List.filterMap_cons
{α : Type u_1}
{β : Type u_2}
(f : α → Option β)
(a : α)
(l : List α)
:
List.filterMap f (a :: l) = match f a with
| none => List.filterMap f l
| some b => b :: List.filterMap f l
theorem
List.filterMap_cons_none
{α : Type u_1}
{β : Type u_2}
{f : α → Option β}
(a : α)
(l : List α)
(h : f a = none)
:
List.filterMap f (a :: l) = List.filterMap f l
theorem
List.filterMap_cons_some
{α : Type u_1}
{β : Type u_2}
(f : α → Option β)
(a : α)
(l : List α)
{b : β}
(h : f a = some b)
:
List.filterMap f (a :: l) = b :: List.filterMap f l
theorem
List.filterMap_append
{α : Type u_1}
{β : Type u_2}
(l : List α)
(l' : List α)
(f : α → Option β)
:
List.filterMap f (l ++ l') = List.filterMap f l ++ List.filterMap f l'
theorem
List.filterMap_eq_map
{α : Type u_1}
{β : Type u_2}
(f : α → β)
:
List.filterMap (some ∘ f) = List.map f
theorem
List.filterMap_eq_filter
{α : Type u_1}
(p : α → Bool)
:
List.filterMap (Option.guard fun (x : α) => p x = true) = List.filter p
theorem
List.filterMap_filterMap
{α : Type u_1}
{β : Type u_2}
{γ : Type u_3}
(f : α → Option β)
(g : β → Option γ)
(l : List α)
:
List.filterMap g (List.filterMap f l) = List.filterMap (fun (x : α) => Option.bind (f x) g) l
theorem
List.map_filterMap
{α : Type u_1}
{β : Type u_2}
{γ : Type u_3}
(f : α → Option β)
(g : β → γ)
(l : List α)
:
List.map g (List.filterMap f l) = List.filterMap (fun (x : α) => Option.map g (f x)) l
theorem
List.filterMap_map
{α : Type u_1}
{β : Type u_2}
{γ : Type u_3}
(f : α → β)
(g : β → Option γ)
(l : List α)
:
List.filterMap g (List.map f l) = List.filterMap (g ∘ f) l
theorem
List.filter_filterMap
{α : Type u_1}
{β : Type u_2}
(f : α → Option β)
(p : β → Bool)
(l : List α)
:
List.filter p (List.filterMap f l) = List.filterMap (fun (x : α) => Option.filter p (f x)) l
theorem
List.filterMap_filter
{α : Type u_1}
{β : Type u_2}
(p : α → Bool)
(f : α → Option β)
(l : List α)
:
List.filterMap f (List.filter p l) = List.filterMap (fun (x : α) => if p x = true then f x else none) l
theorem
List.map_filterMap_some_eq_filter_map_is_some
{α : Type u_1}
{β : Type u_2}
(f : α → Option β)
(l : List α)
:
List.map some (List.filterMap f l) = List.filter (fun (b : Option β) => Option.isSome b) (List.map f l)
@[simp]
theorem
List.filterMap_join
{α : Type u_1}
{β : Type u_2}
(f : α → Option β)
(L : List (List α))
:
List.filterMap f (List.join L) = List.join (List.map (List.filterMap f) L)
theorem
List.map_filterMap_of_inv
{α : Type u_1}
{β : Type u_2}
(f : α → Option β)
(g : β → α)
(H : ∀ (x : α), Option.map g (f x) = some x)
(l : List α)
:
List.map g (List.filterMap f l) = l
theorem
List.length_filter_le
{α : Type u_1}
(p : α → Bool)
(l : List α)
:
List.length (List.filter p l) ≤ List.length l
theorem
List.length_filterMap_le
{α : Type u_1}
{β : Type u_2}
(f : α → Option β)
(l : List α)
:
List.length (List.filterMap f l) ≤ List.length l
theorem
List.Sublist.filterMap
{α : Type u_1}
{β : Type u_2}
{l₁ : List α}
{l₂ : List α}
(f : α → Option β)
(s : List.Sublist l₁ l₂)
:
List.Sublist (List.filterMap f l₁) (List.filterMap f l₂)
theorem
List.Sublist.filter
{α : Type u_1}
(p : α → Bool)
{l₁ : List α}
{l₂ : List α}
(s : List.Sublist l₁ l₂)
:
List.Sublist (List.filter p l₁) (List.filter p l₂)
theorem
List.map_filter
{β : Type u_1}
{α : Type u_2}
{p : α → Bool}
(f : β → α)
(l : List β)
:
List.filter p (List.map f l) = List.map f (List.filter (p ∘ f) l)
@[simp]
theorem
List.filter_filter :
∀ {α : Type u_1} {p : α → Bool} (q : α → Bool) (l : List α),
List.filter p (List.filter q l) = List.filter (fun (a : α) => decide (p a = true ∧ q a = true)) l
theorem
List.filter_length_eq_length :
∀ {α : Type u_1} {p : α → Bool} {l : List α},
List.length (List.filter p l) = List.length l ↔ ∀ (a : α), a ∈ l → p a = true
find? #
theorem
List.find?_cons_of_neg :
∀ {α : Type u_1} {p : α → Bool} {a : α} (l : List α), ¬p a = true → List.find? p (a :: l) = List.find? p l
@[simp]
findSome? #
findIdx #
theorem
List.findIdx_cons
{α : Type u_1}
(p : α → Bool)
(b : α)
(l : List α)
:
List.findIdx p (b :: l) = bif p b then 0 else List.findIdx p l + 1
theorem
List.findIdx_cons.findIdx_go_succ
{α : Type u_1}
(p : α → Bool)
(l : List α)
(n : Nat)
:
List.findIdx.go p l (n + 1) = List.findIdx.go p l n + 1
theorem
List.findIdx_get
{α : Type u_1}
{p : α → Bool}
{xs : List α}
{w : List.findIdx p xs < List.length xs}
:
p (List.get xs { val := List.findIdx p xs, isLt := w }) = true
theorem
List.findIdx_lt_length_of_exists
{α : Type u_1}
{p : α → Bool}
{xs : List α}
(h : ∃ (x : α), x ∈ xs ∧ p x = true)
:
List.findIdx p xs < List.length xs
theorem
List.findIdx_get?_eq_get_of_exists
{α : Type u_1}
{p : α → Bool}
{xs : List α}
(h : ∃ (x : α), x ∈ xs ∧ p x = true)
:
List.get? xs (List.findIdx p xs) = some (List.get xs { val := List.findIdx p xs, isLt := (_ : List.findIdx p xs < List.length xs) })
findIdx? #
@[simp]
@[simp]
@[simp]
theorem
List.findIdx?_succ
{α : Type u_1}
{xs : List α}
{p : α → Bool}
{i : Nat}
:
List.findIdx? p xs (i + 1) = Option.map (fun (i : Nat) => i + 1) (List.findIdx? p xs i)
@[simp]
theorem
List.findIdx?_append
{α : Type u_1}
{xs : List α}
{ys : List α}
{p : α → Bool}
:
List.findIdx? p (xs ++ ys) = HOrElse.hOrElse (List.findIdx? p xs) fun (x : Unit) =>
Option.map (fun (i : Nat) => i + List.length xs) (List.findIdx? p ys)
@[simp]
theorem
List.findIdx?_replicate
{n : Nat}
:
∀ {α : Type u_1} {a : α} {p : α → Bool},
List.findIdx? p (List.replicate n a) = if 0 < n ∧ p a = true then some 0 else none
pairwise #
theorem
List.Pairwise.sublist :
∀ {α : Type u_1} {l₁ l₂ : List α} {R : α → α → Prop}, List.Sublist l₁ l₂ → List.Pairwise R l₂ → List.Pairwise R l₁
theorem
List.pairwise_map
{α : Type u_1}
:
∀ {α_1 : Type u_2} {f : α → α_1} {R : α_1 → α_1 → Prop} {l : List α},
List.Pairwise R (List.map f l) ↔ List.Pairwise (fun (a b : α) => R (f a) (f b)) l
theorem
List.pairwise_append
{α : Type u_1}
{R : α → α → Prop}
{l₁ : List α}
{l₂ : List α}
:
List.Pairwise R (l₁ ++ l₂) ↔ List.Pairwise R l₁ ∧ List.Pairwise R l₂ ∧ ∀ (a : α), a ∈ l₁ → ∀ (b : α), b ∈ l₂ → R a b
theorem
List.pairwise_reverse
{α : Type u_1}
{R : α → α → Prop}
{l : List α}
:
List.Pairwise R (List.reverse l) ↔ List.Pairwise (fun (a b : α) => R b a) l
theorem
List.Pairwise.imp
{α : Type u_1}
{R : α → α → Prop}
{S : α → α → Prop}
(H : ∀ {a b : α}, R a b → S a b)
{l : List α}
:
List.Pairwise R l → List.Pairwise S l
replaceF #
theorem
List.replaceF_cons
{α : Type u_1}
{p : α → Option α}
(a : α)
(l : List α)
:
List.replaceF p (a :: l) = match p a with
| none => a :: List.replaceF p l
| some a' => a' :: l
theorem
List.replaceF_cons_of_none
{α : Type u_1}
{a : α}
{l : List α}
(p : α → Option α)
(h : p a = none)
:
List.replaceF p (a :: l) = a :: List.replaceF p l
theorem
List.replaceF_of_forall_none
{α : Type u_1}
{p : α → Option α}
{l : List α}
(h : ∀ (a : α), a ∈ l → p a = none)
:
List.replaceF p l = l
@[simp]
theorem
List.length_replaceF :
∀ {α : Type u_1} {f : α → Option α} {l : List α}, List.length (List.replaceF f l) = List.length l
disjoint #
theorem
List.disjoint_symm :
∀ {α : Type u_1} {l₁ l₂ : List α}, List.Disjoint l₁ l₂ → List.Disjoint l₂ l₁
theorem
List.disjoint_comm :
∀ {α : Type u_1} {l₁ l₂ : List α}, List.Disjoint l₁ l₂ ↔ List.Disjoint l₂ l₁
theorem
List.disjoint_of_subset_left :
∀ {α : Type u_1} {l₁ l l₂ : List α}, l₁ ⊆ l → List.Disjoint l l₂ → List.Disjoint l₁ l₂
theorem
List.disjoint_of_subset_right :
∀ {α : Type u_1} {l₂ l l₁ : List α}, l₂ ⊆ l → List.Disjoint l₁ l → List.Disjoint l₁ l₂
theorem
List.disjoint_of_disjoint_cons_left :
∀ {α : Type u_1} {a : α} {l₁ l₂ : List α}, List.Disjoint (a :: l₁) l₂ → List.Disjoint l₁ l₂
theorem
List.disjoint_of_disjoint_cons_right :
∀ {α : Type u_1} {a : α} {l₁ l₂ : List α}, List.Disjoint l₁ (a :: l₂) → List.Disjoint l₁ l₂
@[simp]
@[simp]
@[simp]
theorem
List.disjoint_append_left :
∀ {α : Type u_1} {l₁ l₂ l : List α}, List.Disjoint (l₁ ++ l₂) l ↔ List.Disjoint l₁ l ∧ List.Disjoint l₂ l
@[simp]
theorem
List.disjoint_append_right :
∀ {α : Type u_1} {l l₁ l₂ : List α}, List.Disjoint l (l₁ ++ l₂) ↔ List.Disjoint l l₁ ∧ List.Disjoint l l₂
@[simp]
theorem
List.disjoint_cons_left :
∀ {α : Type u_1} {a : α} {l₁ l₂ : List α}, List.Disjoint (a :: l₁) l₂ ↔ ¬a ∈ l₂ ∧ List.Disjoint l₁ l₂
@[simp]
theorem
List.disjoint_cons_right :
∀ {α : Type u_1} {l₁ : List α} {a : α} {l₂ : List α}, List.Disjoint l₁ (a :: l₂) ↔ ¬a ∈ l₁ ∧ List.Disjoint l₁ l₂
theorem
List.disjoint_of_disjoint_append_left_left :
∀ {α : Type u_1} {l₁ l₂ l : List α}, List.Disjoint (l₁ ++ l₂) l → List.Disjoint l₁ l
theorem
List.disjoint_of_disjoint_append_left_right :
∀ {α : Type u_1} {l₁ l₂ l : List α}, List.Disjoint (l₁ ++ l₂) l → List.Disjoint l₂ l
theorem
List.disjoint_of_disjoint_append_right_left :
∀ {α : Type u_1} {l l₁ l₂ : List α}, List.Disjoint l (l₁ ++ l₂) → List.Disjoint l l₁
theorem
List.disjoint_of_disjoint_append_right_right :
∀ {α : Type u_1} {l l₁ l₂ : List α}, List.Disjoint l (l₁ ++ l₂) → List.Disjoint l l₂
foldl / foldr #
theorem
List.foldl_map
{β₁ : Type u_1}
{β₂ : Type u_2}
{α : Type u_3}
(f : β₁ → β₂)
(g : α → β₂ → α)
(l : List β₁)
(init : α)
:
List.foldl g init (List.map f l) = List.foldl (fun (x : α) (y : β₁) => g x (f y)) init l
theorem
List.foldr_map
{α₁ : Type u_1}
{α₂ : Type u_2}
{β : Type u_3}
(f : α₁ → α₂)
(g : α₂ → β → β)
(l : List α₁)
(init : β)
:
List.foldr g init (List.map f l) = List.foldr (fun (x : α₁) (y : β) => g (f x) y) init l
theorem
List.foldl_hom
{α₁ : Type u_1}
{α₂ : Type u_2}
{β : Type u_3}
(f : α₁ → α₂)
(g₁ : α₁ → β → α₁)
(g₂ : α₂ → β → α₂)
(l : List β)
(init : α₁)
(H : ∀ (x : α₁) (y : β), g₂ (f x) y = f (g₁ x y))
:
List.foldl g₂ (f init) l = f (List.foldl g₁ init l)
theorem
List.foldr_hom
{β₁ : Type u_1}
{β₂ : Type u_2}
{α : Type u_3}
(f : β₁ → β₂)
(g₁ : α → β₁ → β₁)
(g₂ : α → β₂ → β₂)
(l : List α)
(init : β₁)
(H : ∀ (x : α) (y : β₁), g₂ x (f y) = f (g₁ x y))
:
List.foldr g₂ (f init) l = f (List.foldr g₁ init l)
union #
theorem
List.union_def
{α : Type u_1}
[DecidableEq α]
(l₁ : List α)
(l₂ : List α)
:
l₁ ∪ l₂ = List.foldr List.insert l₂ l₁
@[simp]
theorem
List.cons_union
{α : Type u_1}
[DecidableEq α]
(a : α)
(l₁ : List α)
(l₂ : List α)
:
a :: l₁ ∪ l₂ = List.insert a (l₁ ∪ l₂)
inter #
theorem
List.inter_def
{α : Type u_1}
[DecidableEq α]
(l₁ : List α)
(l₂ : List α)
:
l₁ ∩ l₂ = List.filter (fun (x : α) => decide (x ∈ l₂)) l₁
product #
leftpad #
theorem
List.leftpad_length
{α : Type u_1}
(n : Nat)
(a : α)
(l : List α)
:
List.length (List.leftpad n a l) = max n (List.length l)
The length of the List returned by List.leftpad n a l
is equal
to the larger of n
and l.length
theorem
List.leftpad_prefix
{α : Type u_1}
(n : Nat)
(a : α)
(l : List α)
:
List.replicate (n - List.length l) a <+: List.leftpad n a l
monadic operations #
theorem
List.forIn_eq_bindList
{m : Type u_1 → Type u_2}
{α : Type u_3}
{β : Type u_1}
[Monad m]
[LawfulMonad m]
(f : α → β → m (ForInStep β))
(l : List α)
(init : β)
:
forIn l init f = ForInStep.run <$> ForInStep.bindList f l (ForInStep.yield init)
diff #
@[simp]
theorem
List.diff_cons
{α : Type u_1}
[DecidableEq α]
(l₁ : List α)
(l₂ : List α)
(a : α)
:
List.diff l₁ (a :: l₂) = List.diff (List.erase l₁ a) l₂
theorem
List.diff_cons_right
{α : Type u_1}
[DecidableEq α]
(l₁ : List α)
(l₂ : List α)
(a : α)
:
List.diff l₁ (a :: l₂) = List.erase (List.diff l₁ l₂) a
theorem
List.diff_erase
{α : Type u_1}
[DecidableEq α]
(l₁ : List α)
(l₂ : List α)
(a : α)
:
List.erase (List.diff l₁ l₂) a = List.diff (List.erase l₁ a) l₂
@[simp]
theorem
List.cons_diff_of_mem
{α : Type u_1}
[DecidableEq α]
{a : α}
{l₂ : List α}
(h : a ∈ l₂)
(l₁ : List α)
:
List.diff (a :: l₁) l₂ = List.diff l₁ (List.erase l₂ a)
theorem
List.diff_eq_foldl
{α : Type u_1}
[DecidableEq α]
(l₁ : List α)
(l₂ : List α)
:
List.diff l₁ l₂ = List.foldl List.erase l₁ l₂
theorem
List.diff_sublist
{α : Type u_1}
[DecidableEq α]
(l₁ : List α)
(l₂ : List α)
:
List.Sublist (List.diff l₁ l₂) l₁
theorem
List.Sublist.diff_right
{α : Type u_1}
[DecidableEq α]
{l₁ : List α}
{l₂ : List α}
{l₃ : List α}
:
List.Sublist l₁ l₂ → List.Sublist (List.diff l₁ l₃) (List.diff l₂ l₃)
theorem
List.Sublist.erase_diff_erase_sublist
{α : Type u_1}
[DecidableEq α]
{a : α}
{l₁ : List α}
{l₂ : List α}
:
List.Sublist l₁ l₂ → List.Sublist (List.diff (List.erase l₂ a) (List.erase l₁ a)) (List.diff l₂ l₁)
prefix, suffix, infix #
theorem
List.infix_concat :
∀ {α : Type u_1} {l₁ l₂ : List α} {a : α}, l₁ <:+: l₂ → l₁ <:+: List.concat l₂ a
@[simp]
theorem
List.reverse_suffix :
∀ {α : Type u_1} {l₁ l₂ : List α}, List.reverse l₁ <:+ List.reverse l₂ ↔ l₁ <+: l₂
@[simp]
theorem
List.reverse_prefix :
∀ {α : Type u_1} {l₁ l₂ : List α}, List.reverse l₁ <+: List.reverse l₂ ↔ l₁ <:+ l₂
@[simp]
theorem
List.reverse_infix :
∀ {α : Type u_1} {l₁ l₂ : List α}, List.reverse l₁ <:+: List.reverse l₂ ↔ l₁ <:+: l₂
theorem
List.IsInfix.length_le :
∀ {α : Type u_1} {l₁ l₂ : List α}, l₁ <:+: l₂ → List.length l₁ ≤ List.length l₂
theorem
List.IsPrefix.length_le :
∀ {α : Type u_1} {l₁ l₂ : List α}, l₁ <+: l₂ → List.length l₁ ≤ List.length l₂
theorem
List.IsSuffix.length_le :
∀ {α : Type u_1} {l₁ l₂ : List α}, l₁ <:+ l₂ → List.length l₁ ≤ List.length l₂
theorem
List.IsInfix.eq_of_length :
∀ {α : Type u_1} {l₁ l₂ : List α}, l₁ <:+: l₂ → List.length l₁ = List.length l₂ → l₁ = l₂
theorem
List.IsPrefix.eq_of_length :
∀ {α : Type u_1} {l₁ l₂ : List α}, l₁ <+: l₂ → List.length l₁ = List.length l₂ → l₁ = l₂
theorem
List.IsSuffix.eq_of_length :
∀ {α : Type u_1} {l₁ l₂ : List α}, l₁ <:+ l₂ → List.length l₁ = List.length l₂ → l₁ = l₂
theorem
List.prefix_of_prefix_length_le
{α : Type u_1}
{l₁ : List α}
{l₂ : List α}
{l₃ : List α}
:
l₁ <+: l₃ → l₂ <+: l₃ → List.length l₁ ≤ List.length l₂ → l₁ <+: l₂
theorem
List.suffix_of_suffix_length_le :
∀ {α : Type u_1} {l₁ l₃ l₂ : List α}, l₁ <:+ l₃ → l₂ <:+ l₃ → List.length l₁ ≤ List.length l₂ → l₁ <:+ l₂
theorem
List.IsPrefix.filter
{α : Type u_1}
(p : α → Bool)
⦃l₁ : List α⦄
⦃l₂ : List α⦄
(h : l₁ <+: l₂)
:
List.filter p l₁ <+: List.filter p l₂
theorem
List.IsSuffix.filter
{α : Type u_1}
(p : α → Bool)
⦃l₁ : List α⦄
⦃l₂ : List α⦄
(h : l₁ <:+ l₂)
:
List.filter p l₁ <:+ List.filter p l₂
theorem
List.IsInfix.filter
{α : Type u_1}
(p : α → Bool)
⦃l₁ : List α⦄
⦃l₂ : List α⦄
(h : l₁ <:+: l₂)
:
List.filter p l₁ <:+: List.filter p l₂
theorem
List.disjoint_take_drop
{α : Type u_1}
{m : Nat}
{n : Nat}
{l : List α}
:
List.Nodup l → m ≤ n → List.Disjoint (List.take m l) (List.drop n l)
takeWhile and dropWhile #
@[simp]
theorem
List.takeWhile_append_dropWhile
{α : Type u_1}
(p : α → Bool)
(l : List α)
:
List.takeWhile p l ++ List.dropWhile p l = l
theorem
List.dropWhile_append
{α : Type u_1}
{p : α → Bool}
{xs : List α}
{ys : List α}
:
List.dropWhile p (xs ++ ys) = if List.isEmpty (List.dropWhile p xs) = true then List.dropWhile p ys else List.dropWhile p xs ++ ys
Chain #
@[simp]
theorem
List.chain_cons
{α : Type u_1}
{R : α → α → Prop}
{a : α}
{b : α}
{l : List α}
:
List.Chain R a (b :: l) ↔ R a b ∧ List.Chain R b l
theorem
List.rel_of_chain_cons
{α : Type u_1}
{R : α → α → Prop}
{a : α}
{b : α}
{l : List α}
(p : List.Chain R a (b :: l))
:
R a b
theorem
List.chain_of_chain_cons
{α : Type u_1}
{R : α → α → Prop}
{a : α}
{b : α}
{l : List α}
(p : List.Chain R a (b :: l))
:
List.Chain R b l
theorem
List.Chain.imp'
{α : Type u_1}
{R : α → α → Prop}
{S : α → α → Prop}
(HRS : ∀ ⦃a b : α⦄, R a b → S a b)
{a : α}
{b : α}
(Hab : ∀ ⦃c : α⦄, R a c → S b c)
{l : List α}
(p : List.Chain R a l)
:
List.Chain S b l
theorem
List.Chain.imp
{α : Type u_1}
{R : α → α → Prop}
{S : α → α → Prop}
(H : ∀ (a b : α), R a b → S a b)
{a : α}
{l : List α}
(p : List.Chain R a l)
:
List.Chain S a l
theorem
List.Pairwise.chain :
∀ {α : Type u_1} {R : α → α → Prop} {a : α} {l : List α}, List.Pairwise R (a :: l) → List.Chain R a l
range', range #
@[simp]
@[simp]
theorem
List.map_add_range'
(a : Nat)
(s : Nat)
(n : Nat)
(step : Nat)
:
List.map (fun (x : Nat) => a + x) (List.range' s n step) = List.range' (a + s) n step
theorem
List.map_sub_range'
{step : Nat}
(a : Nat)
(s : Nat)
(n : Nat)
(h : a ≤ s)
:
List.map (fun (x : Nat) => x - a) (List.range' s n step) = List.range' (s - a) n step
theorem
List.chain_succ_range'
(s : Nat)
(n : Nat)
(step : Nat)
:
List.Chain (fun (a b : Nat) => b = a + step) s (List.range' (s + step) n step)
theorem
List.chain_lt_range'
(s : Nat)
(n : Nat)
{step : Nat}
(h : 0 < step)
:
List.Chain (fun (x x_1 : Nat) => x < x_1) s (List.range' (s + step) n step)
theorem
List.range'_append
(s : Nat)
(m : Nat)
(n : Nat)
(step : Nat)
:
List.range' s m step ++ List.range' (s + step * m) n step = List.range' s (n + m) step
@[simp]
theorem
List.range'_append_1
(s : Nat)
(m : Nat)
(n : Nat)
:
List.range' s m ++ List.range' (s + m) n = List.range' s (n + m)
theorem
List.range'_sublist_right
{step : Nat}
{s : Nat}
{m : Nat}
{n : Nat}
:
List.Sublist (List.range' s m step) (List.range' s n step) ↔ m ≤ n
theorem
List.range'_subset_right
{step : Nat}
{s : Nat}
{m : Nat}
{n : Nat}
(step0 : 0 < step)
:
List.range' s m step ⊆ List.range' s n step ↔ m ≤ n
theorem
List.range'_subset_right_1
{s : Nat}
{m : Nat}
{n : Nat}
:
List.range' s m ⊆ List.range' s n ↔ m ≤ n
@[simp]
theorem
List.get_range'
{n : Nat}
{m : Nat}
{step : Nat}
(i : Nat)
(H : i < List.length (List.range' n m step))
:
List.get (List.range' n m step) { val := i, isLt := H } = n + step * i
theorem
List.range'_concat
{step : Nat}
(s : Nat)
(n : Nat)
:
List.range' s (n + 1) step = List.range' s n step ++ [s + step * n]
theorem
List.range'_1_concat
(s : Nat)
(n : Nat)
:
List.range' s (n + 1) = List.range' s n ++ [s + n]
theorem
List.range_loop_range'
(s : Nat)
(n : Nat)
:
List.range.loop s (List.range' s n) = List.range' 0 (n + s)
theorem
List.range_succ_eq_map
(n : Nat)
:
List.range (n + 1) = 0 :: List.map Nat.succ (List.range n)
theorem
List.range'_eq_map_range
(s : Nat)
(n : Nat)
:
List.range' s n = List.map (fun (x : Nat) => s + x) (List.range n)
theorem
List.range_add
(a : Nat)
(b : Nat)
:
List.range (a + b) = List.range a ++ List.map (fun (x : Nat) => a + x) (List.range b)
theorem
List.reverse_range'
(s : Nat)
(n : Nat)
:
List.reverse (List.range' s n) = List.map (fun (x : Nat) => s + n - 1 - x) (List.range n)
@[simp]
theorem
List.get_range
{n : Nat}
(i : Nat)
(H : i < List.length (List.range n))
:
List.get (List.range n) { val := i, isLt := H } = i
enum, enumFrom #
@[simp]
theorem
List.enumFrom_map_fst
{α : Type u_1}
(n : Nat)
(l : List α)
:
List.map Prod.fst (List.enumFrom n l) = List.range' n (List.length l)
@[simp]
theorem
List.enum_map_fst
{α : Type u_1}
(l : List α)
:
List.map Prod.fst (List.enum l) = List.range (List.length l)
@[simp]
theorem
List.enumFrom_length
{α : Type u_1}
{n : Nat}
{l : List α}
:
List.length (List.enumFrom n l) = List.length l
@[simp]
maximum? #
theorem
List.maximum?_cons
{α : Type u_1}
{x : α}
[Max α]
{xs : List α}
:
List.maximum? (x :: xs) = some (List.foldl max x xs)
@[simp]
theorem
List.maximum?_eq_none_iff
{α : Type u_1}
{xs : List α}
[Max α]
:
List.maximum? xs = none ↔ xs = []
indexOf and indexesOf #
theorem
List.foldrIdx_start
{α : Type u_1}
{xs : List α}
:
∀ {α_1 : Sort u_2} {f : Nat → α → α_1 → α_1} {i : α_1} {s : Nat},
List.foldrIdx f i xs s = List.foldrIdx (fun (i : Nat) => f (i + s)) i xs
@[simp]
theorem
List.foldrIdx_cons
{α : Type u_1}
{x : α}
{xs : List α}
:
∀ {α_1 : Sort u_2} {f : Nat → α → α_1 → α_1} {i : α_1} {s : Nat},
List.foldrIdx f i (x :: xs) s = f s x (List.foldrIdx f i xs (s + 1))
theorem
List.findIdxs_cons
{α : Type u_1}
{x : α}
{xs : List α}
{p : α → Bool}
:
List.findIdxs p (x :: xs) = bif p x then 0 :: List.map (fun (x : Nat) => x + 1) (List.findIdxs p xs)
else List.map (fun (x : Nat) => x + 1) (List.findIdxs p xs)
theorem
List.indexesOf_cons
{α : Type u_1}
{x : α}
{xs : List α}
{y : α}
[BEq α]
:
List.indexesOf y (x :: xs) = bif x == y then 0 :: List.map (fun (x : Nat) => x + 1) (List.indexesOf y xs)
else List.map (fun (x : Nat) => x + 1) (List.indexesOf y xs)
theorem
List.indexOf_cons
{α : Type u_1}
{x : α}
{xs : List α}
{y : α}
[BEq α]
:
List.indexOf y (x :: xs) = bif x == y then 0 else List.indexOf y xs + 1
theorem
List.indexOf_mem_indexesOf
{α : Type u_1}
{x : α}
[BEq α]
[LawfulBEq α]
{xs : List α}
(m : x ∈ xs)
:
List.indexOf x xs ∈ List.indexesOf x xs