Module docstring
{"# Take and Drop lemmas for lists
This file provides lemmas about List.take and List.drop and related functions.
","### take, drop ","### filter ","### Miscellaneous lemmas "}
{"# Take and Drop lemmas for lists
This file provides lemmas about List.take and List.drop and related functions.
","### take, drop ","### filter ","### Miscellaneous lemmas "}
List.take_one_drop_eq_of_lt_length
theorem
{l : List α} {n : ℕ} (h : n < l.length) : (l.drop n).take 1 = [l.get ⟨n, h⟩]
theorem take_one_drop_eq_of_lt_length {l : List α} {n : ℕ} (h : n < l.length) :
(l.drop n).take 1 = [l.get ⟨n, h⟩] := by
rw [drop_eq_getElem_cons h, take, take]
simp
List.take_eq_self_iff
theorem
(x : List α) {n : ℕ} : x.take n = x ↔ x.length ≤ n
@[simp] lemma take_eq_self_iff (x : List α) {n : ℕ} : x.take n = x ↔ x.length ≤ n :=
⟨fun h ↦ by rw [← h]; simp; omega, take_of_length_le⟩
List.take_self_eq_iff
theorem
(x : List α) {n : ℕ} : x = x.take n ↔ x.length ≤ n
@[simp] lemma take_self_eq_iff (x : List α) {n : ℕ} : x = x.take n ↔ x.length ≤ n := by
rw [Eq.comm, take_eq_self_iff]
List.take_eq_left_iff
theorem
{x y : List α} {n : ℕ} : (x ++ y).take n = x.take n ↔ y = [] ∨ n ≤ x.length
@[simp] lemma take_eq_left_iff {x y : List α} {n : ℕ} :
(x ++ y).take n = x.take n ↔ y = [] ∨ n ≤ x.length := by
simp [take_append_eq_append_take, Nat.sub_eq_zero_iff_le, Or.comm]
List.left_eq_take_iff
theorem
{x y : List α} {n : ℕ} : x.take n = (x ++ y).take n ↔ y = [] ∨ n ≤ x.length
@[simp] lemma left_eq_take_iff {x y : List α} {n : ℕ} :
x.take n = (x ++ y).take n ↔ y = [] ∨ n ≤ x.length := by
rw [Eq.comm]; apply take_eq_left_iff
List.drop_take_append_drop
theorem
(x : List α) (m n : ℕ) : (x.drop m).take n ++ x.drop (m + n) = x.drop m
@[simp] lemma drop_take_append_drop (x : List α) (m n : ℕ) :
(x.drop m).take n ++ x.drop (m + n) = x.drop m := by rw [← drop_drop, take_append_drop]
List.drop_take_append_drop'
theorem
(x : List α) (m n : ℕ) : (x.drop m).take n ++ x.drop (n + m) = x.drop m
/-- Compared to `drop_take_append_drop`, the order of summands is swapped. -/
@[simp] lemma drop_take_append_drop' (x : List α) (m n : ℕ) :
(x.drop m).take n ++ x.drop (n + m) = x.drop m := by rw [Nat.add_comm, drop_take_append_drop]
List.take_concat_get'
theorem
(l : List α) (i : ℕ) (h : i < l.length) : l.take i ++ [l[i]] = l.take (i + 1)
List.cons_getElem_drop_succ
theorem
{l : List α} {n : Nat} {h : n < l.length} : l[n] :: l.drop (n + 1) = l.drop n
theorem cons_getElem_drop_succ {l : List α} {n : Nat} {h : n < l.length} :
l[n]l[n] :: l.drop (n + 1) = l.drop n :=
(drop_eq_getElem_cons h).symm
List.cons_get_drop_succ
theorem
{l : List α} {n} : l.get n :: l.drop (n.1 + 1) = l.drop n.1
theorem cons_get_drop_succ {l : List α} {n} :
l.get n :: l.drop (n.1 + 1) = l.drop n.1 :=
(drop_eq_getElem_cons n.2).symm
List.drop_length_sub_one
theorem
{l : List α} (h : l ≠ []) : l.drop (l.length - 1) = [l.getLast h]
lemma drop_length_sub_one {l : List α} (h : l ≠ []) : l.drop (l.length - 1) = [l.getLast h] := by
induction l with
| nil => aesop
| cons a l ih =>
by_cases hl : l = []
· aesop
rw [length_cons, Nat.add_one_sub_one, List.drop_length_cons hl a]
simp [getLast_cons, hl]
List.takeI_length
theorem
: ∀ n l, length (@takeI α _ n l) = n
@[simp]
theorem takeI_length : ∀ n l, length (@takeI α _ n l) = n
| 0, _ => rfl
| _ + 1, _ => congr_arg succ (takeI_length _ _)
List.takeI_nil
theorem
: ∀ n, takeI n (@nil α) = replicate n default
List.takeI_eq_take
theorem
: ∀ {n} {l : List α}, n ≤ length l → takeI n l = take n l
List.takeI_left
theorem
(l₁ l₂ : List α) : takeI (length l₁) (l₁ ++ l₂) = l₁
@[simp]
theorem takeI_left (l₁ l₂ : List α) : takeI (length l₁) (l₁ ++ l₂) = l₁ :=
(takeI_eq_take (by simp only [length_append, Nat.le_add_right])).trans take_left
List.takeI_left'
theorem
{l₁ l₂ : List α} {n} (h : length l₁ = n) : takeI n (l₁ ++ l₂) = l₁
theorem takeI_left' {l₁ l₂ : List α} {n} (h : length l₁ = n) : takeI n (l₁ ++ l₂) = l₁ := by
rw [← h]; apply takeI_left
List.takeD_length
theorem
: ∀ n l a, length (@takeD α n l a) = n
@[simp]
theorem takeD_length : ∀ n l a, length (@takeD α n l a) = n
| 0, _, _ => rfl
| _ + 1, _, _ => congr_arg succ (takeD_length _ _ _)
List.takeD_eq_take
theorem
: ∀ {n} {l : List α} a, n ≤ length l → takeD n l a = take n l
theorem takeD_eq_take : ∀ {n} {l : List α} a, n ≤ length l → takeD n l a = take n l
| 0, _, _, _ => rfl
| _ + 1, _ :: _, a, h => congr_arg (cons _) <| takeD_eq_take a <| le_of_succ_le_succ h
List.takeD_left
theorem
(l₁ l₂ : List α) (a : α) : takeD (length l₁) (l₁ ++ l₂) a = l₁
@[simp]
theorem takeD_left (l₁ l₂ : List α) (a : α) : takeD (length l₁) (l₁ ++ l₂) a = l₁ :=
(takeD_eq_take a (by simp only [length_append, Nat.le_add_right])).trans take_left
List.takeD_left'
theorem
{l₁ l₂ : List α} {n} {a} (h : length l₁ = n) : takeD n (l₁ ++ l₂) a = l₁
theorem takeD_left' {l₁ l₂ : List α} {n} {a} (h : length l₁ = n) : takeD n (l₁ ++ l₂) a = l₁ := by
rw [← h]; apply takeD_left
List.span_eq_takeWhile_dropWhile
theorem
(l : List α) : span p l = (takeWhile p l, dropWhile p l)
@[simp]
theorem span_eq_takeWhile_dropWhile (l : List α) : span p l = (takeWhile p l, dropWhile p l) := by
simpa using span.loop_eq_take_drop p l []
List.dropSlice_eq
theorem
(xs : List α) (n m : ℕ) : dropSlice n m xs = xs.take n ++ xs.drop (n + m)
theorem dropSlice_eq (xs : List α) (n m : ℕ) : dropSlice n m xs = xs.take n ++ xs.drop (n + m) := by
induction n generalizing xs
· cases xs <;> simp [dropSlice]
· cases xs <;> simp [dropSlice, *, Nat.succ_add]
List.length_dropSlice
theorem
(i j : ℕ) (xs : List α) : (List.dropSlice i j xs).length = xs.length - min j (xs.length - i)
@[simp]
theorem length_dropSlice (i j : ℕ) (xs : List α) :
(List.dropSlice i j xs).length = xs.length - min j (xs.length - i) := by
induction xs generalizing i j with
| nil => simp
| cons x xs xs_ih =>
cases i <;> simp only [List.dropSlice]
· cases j with
| zero => simp
| succ n => simp_all [xs_ih]; omega
· simp [xs_ih]; omega
List.length_dropSlice_lt
theorem
(i j : ℕ) (hj : 0 < j) (xs : List α) (hi : i < xs.length) : (List.dropSlice i j xs).length < xs.length