Module docstring
{"### List.takeWhile and List.dropWhile "}
{"### List.takeWhile and List.dropWhile "}
List.dropWhile_get_zero_not
      theorem
     (l : List α) (hl : 0 < (l.dropWhile p).length) : ¬p ((l.dropWhile p).get ⟨0, hl⟩)
        theorem dropWhile_get_zero_not (l : List α) (hl : 0 < (l.dropWhile p).length) :
    ¬p ((l.dropWhile p).get ⟨0, hl⟩) := by
  induction l with
  | nil => cases hl
  | cons hd tl IH =>
    simp only [dropWhile]
    by_cases hp : p hd
    · simp_all only [get_eq_getElem]
      apply IH
      simp_all only [dropWhile_cons_of_pos]
    · simp [hp]
        List.dropWhile_eq_nil_iff
      theorem
     : dropWhile p l = [] ↔ ∀ x ∈ l, p x
        @[simp]
theorem dropWhile_eq_nil_iff : dropWhiledropWhile p l = [] ↔ ∀ x ∈ l, p x := by
  induction l with
  | nil => simp [dropWhile]
  | cons x xs IH => by_cases hp : p x <;> simp [hp, IH]
        List.takeWhile_eq_self_iff
      theorem
     : takeWhile p l = l ↔ ∀ x ∈ l, p x
        @[simp]
theorem takeWhile_eq_self_iff : takeWhiletakeWhile p l = l ↔ ∀ x ∈ l, p x := by
  induction l with
  | nil => simp
  | cons x xs IH => by_cases hp : p x <;> simp [hp, IH]
        List.takeWhile_eq_nil_iff
      theorem
     : takeWhile p l = [] ↔ ∀ hl : 0 < l.length, ¬p (l.get ⟨0, hl⟩)
        @[simp]
theorem takeWhile_eq_nil_iff : takeWhiletakeWhile p l = [] ↔ ∀ hl : 0 < l.length, ¬p (l.get ⟨0, hl⟩) := by
  induction l with
  | nil =>
    simp only [takeWhile_nil, Bool.not_eq_true, true_iff]
    intro h
    simp at h
  | cons x xs IH => by_cases hp : p x <;> simp [hp, IH]
        List.mem_takeWhile_imp
      theorem
     {x : α} (hx : x ∈ takeWhile p l) : p x
        theorem mem_takeWhile_imp {x : α} (hx : x ∈ takeWhile p l) : p x := by
  induction l with simp [takeWhile] at hx
  | cons hd tl IH =>
    cases hp : p hd
    · simp [hp] at hx
    · rw [hp, mem_cons] at hx
      rcases hx with (rfl | hx)
      · exact hp
      · exact IH hx
        List.takeWhile_takeWhile
      theorem
     (p q : α → Bool) (l : List α) : takeWhile p (takeWhile q l) = takeWhile (fun a => p a ∧ q a) l
        theorem takeWhile_takeWhile (p q : α → Bool) (l : List α) :
    takeWhile p (takeWhile q l) = takeWhile (fun a => p a ∧ q a) l := by
  induction l with
  | nil => simp
  | cons hd tl IH => by_cases hp : p hd <;> by_cases hq : q hd <;> simp [takeWhile, hp, hq, IH]
        List.takeWhile_idem
      theorem
     : takeWhile p (takeWhile p l) = takeWhile p l
        theorem takeWhile_idem : takeWhile p (takeWhile p l) = takeWhile p l := by
  simp_rw [takeWhile_takeWhile, and_self_iff, Bool.decide_coe]
        List.find?_eq_head?_dropWhile_not
      theorem
     : l.find? p = (l.dropWhile (fun x ↦ !(p x))).head?
        lemma find?_eq_head?_dropWhile_not :
    l.find? p = (l.dropWhile (fun x ↦ ! (p x))).head? := by
  induction l
  case nil => simp
  case cons head tail hi =>
    set ph := p head with phh
    rcases ph with rfl | rfl
    · have phh' : ¬(p head = true) := by simp [phh.symm]
      rw [find?_cons_of_neg phh', dropWhile_cons_of_pos]
      · exact hi
      · simpa using phh
    · rw [find?_cons_of_pos phh.symm, dropWhile_cons_of_neg]
      · simp
      · simpa using phh
        List.find?_not_eq_head?_dropWhile
      theorem
     : l.find? (fun x ↦ !(p x)) = (l.dropWhile p).head?
        lemma find?_not_eq_head?_dropWhile :
    l.find? (fun x ↦ ! (p x)) = (l.dropWhile p).head? := by
  convert l.find?_eq_head?_dropWhile_not ?_
  simp
        List.find?_eq_head_dropWhile_not
      theorem
     (h : ∃ x ∈ l, p x) : l.find? p = some ((l.dropWhile (fun x ↦ !(p x))).head (by simpa using h))
        lemma find?_eq_head_dropWhile_not (h : ∃ x ∈ l, p x) :
    l.find? p = some ((l.dropWhile (fun x ↦ ! (p x))).head (by simpa using h)) := by
  rw [l.find?_eq_head?_dropWhile_not p, ← head_eq_iff_head?_eq_some]
        List.find?_not_eq_head_dropWhile
      theorem
     (h : ∃ x ∈ l, ¬p x) : l.find? (fun x ↦ !(p x)) = some ((l.dropWhile p).head (by simpa using h))
        lemma find?_not_eq_head_dropWhile (h : ∃ x ∈ l, ¬p x) :
    l.find? (fun x ↦ ! (p x)) = some ((l.dropWhile p).head (by simpa using h)) := by
  convert l.find?_eq_head_dropWhile_not ?_
  · simp
  · simpa using h