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