Module docstring
{"# Lemmas about List.range and List.enum
","## Ranges and enumeration ","### range' ","### range ","### iota ","### zipIdx ","### enumFrom ","### enum "}
{"# Lemmas about List.range and List.enum
","## Ranges and enumeration ","### range' ","### range ","### iota ","### zipIdx ","### enumFrom ","### enum "}
List.mem_range'_1
      theorem
     : m ∈ range' s n ↔ s ≤ m ∧ m < s + n
        
      List.getLast?_range'
      theorem
     {n : Nat} : (range' s n).getLast? = if n = 0 then none else some (s + n - 1)
        theorem getLast?_range' {n : Nat} : (range' s n).getLast? = if n = 0 then none else some (s + n - 1) := by
  induction n generalizing s with
  | zero => simp
  | succ n ih =>
    rw [range'_succ, getLast?_cons, ih]
    by_cases h : n = 0
    · rw [if_pos h]
      simp [h]
    · rw [if_neg h]
      simp
      omega
        List.getLast_range'
      theorem
     {n : Nat} (h) : (range' s n).getLast h = s + n - 1
        @[simp] theorem getLast_range' {n : Nat} (h) : (range' s n).getLast h = s + n - 1 := by
  cases n with
  | zero => simp at h
  | succ n => simp [getLast?_range', getLast_eq_iff_getLast?_eq_some]
        List.map_sub_range'
      theorem
     {a s : Nat} (h : a ≤ s) (n : Nat) : map (· - a) (range' s n step) = range' (s - a) n step
        theorem map_sub_range' {a s : Nat} (h : a ≤ s) (n : Nat) :
    map (· - a) (range' s n step) = range' (s - a) n step := by
  conv => lhs; rw [← Nat.add_sub_cancel' h]
  rw [← map_add_range', map_map, (?_ : _∘_ = _), map_id]
  funext x; apply Nat.add_sub_cancel_left
        List.range'_eq_singleton_iff
      theorem
     {s n a : Nat} : range' s n = [a] ↔ s = a ∧ n = 1
        @[simp] theorem range'_eq_singleton_iff {s n a : Nat} : range'range' s n = [a] ↔ s = a ∧ n = 1 := by
  rw [range'_eq_cons_iff]
  simp only [nil_eq, range'_eq_nil_iff, and_congr_right_iff]
  rintro rfl
  omega
        List.range'_eq_singleton
      abbrev
    
        @[deprecated range'_eq_singleton_iff (since := "2025-01-29")]
abbrev range'_eq_singleton := @range'_eq_singleton_iff
        List.range'_eq_append_iff
      theorem
     : range' s n = xs ++ ys ↔ ∃ k, k ≤ n ∧ xs = range' s k ∧ ys = range' (s + k) (n - k)
        theorem range'_eq_append_iff : range'range' s n = xs ++ ys ↔ ∃ k, k ≤ n ∧ xs = range' s k ∧ ys = range' (s + k) (n - k) := by
  induction n generalizing s xs ys with
  | zero => simp
  | succ n ih =>
    simp only [range'_succ]
    rw [cons_eq_append_iff]
    constructor
    · rintro (⟨rfl, rfl⟩ | ⟨_, rfl, h⟩)
      · exact ⟨0, by simp [range'_succ]⟩
      · simp only [ih] at h
        obtain ⟨k, h, rfl, rfl⟩ := h
        refine ⟨k + 1, ?_⟩
        simp_all [range'_succ]
        omega
    · rintro ⟨k, h, rfl, rfl⟩
      cases k with
      | zero => simp [range'_succ]
      | succ k =>
        simp only [range'_succ, reduceCtorEq, false_and, cons.injEq, true_and, ih, range'_inj, exists_eq_left', or_true, and_true, false_or]
        refine ⟨k, ?_⟩
        simp_all
        omega
        List.find?_range'_eq_some
      theorem
     {s n : Nat} {i : Nat} {p : Nat → Bool} :
  (range' s n).find? p = some i ↔ p i ∧ i ∈ range' s n ∧ ∀ j, s ≤ j → j < i → !p j
        @[simp] theorem find?_range'_eq_some {s n : Nat} {i : Nat} {p : Nat → Bool} :
    (range' s n).find? p = some i ↔ p i ∧ i ∈ range' s n ∧ ∀ j, s ≤ j → j < i → !p j := by
  rw [find?_eq_some_iff_append]
  simp only [Bool.not_eq_eq_eq_not, Bool.not_true, exists_and_right, mem_range'_1,
    and_congr_right_iff]
  simp only [range'_eq_append_iff, eq_comm (a := i :: _), range'_eq_cons_iff]
  intro h
  constructor
  · rintro ⟨as, ⟨_, k, h₁, rfl, rfl, h₂, rfl⟩, h₃⟩
    constructor
    · omega
    · simpa using h₃
  · rintro ⟨⟨h₁, h₂⟩, h₃⟩
    refine ⟨range' s (i - s), ⟨⟨range' (i + 1) (n - (i - s) - 1), i - s, ?_⟩ , ?_⟩⟩
    · simp; omega
    · simp only [mem_range'_1, and_imp]
      intro a a₁ a₂
      exact h₃ a a₁ (by omega)
        List.find?_range'_eq_none
      theorem
     {s n : Nat} {p : Nat → Bool} : (range' s n).find? p = none ↔ ∀ i, s ≤ i → i < s + n → !p i
        theorem find?_range'_eq_none {s n : Nat} {p : Nat → Bool} :
    (range' s n).find? p = none ↔ ∀ i, s ≤ i → i < s + n → !p i := by
  simp
        List.erase_range'
      theorem
     : (range' s n).erase i = range' s (min n (i - s)) ++ range' (max s (i + 1)) (min s (i + 1) + n - (i + 1))
        theorem erase_range' :
    (range' s n).erase i =
      range' s (min n (i - s)) ++ range' (max s (i + 1)) (min s (i + 1) + n - (i + 1)) := by
  by_cases h : i ∈ range' s n
  · obtain ⟨as, bs, h₁, h₂⟩ := eq_append_cons_of_mem h
    rw [h₁, erase_append_right _ h₂, erase_cons_head]
    rw [range'_eq_append_iff] at h₁
    obtain ⟨k, -, rfl, hbs⟩ := h₁
    rw [eq_comm, range'_eq_cons_iff] at hbs
    obtain ⟨rfl, -, rfl⟩ := hbs
    simp at h
    congr 2 <;> omega
  · rw [erase_of_not_mem h]
    simp only [mem_range'_1, not_and, Nat.not_lt] at h
    by_cases h' : s ≤ i
    · have p : min s (i + 1) + n - (i + 1) = 0 := by omega
      simp [p]
      omega
    · have p : i - s = 0 := by omega
      simp [p]
      omega
        List.reverse_range'
      theorem
     : ∀ {s n : Nat}, reverse (range' s n) = map (s + n - 1 - ·) (range n)
        theorem reverse_range' : ∀ {s n : Nat}, reverse (range' s n) = map (s + n - 1 - ·) (range n)
  | _, 0 => rfl
  | s, n + 1 => by
    rw [range'_1_concat, reverse_append, range_succ_eq_map,
      show s + (n + 1) - 1 = s + n from rfl, map, map_map]
    simp [reverse_range', Nat.sub_right_comm, Nat.sub_sub]
        List.mem_range
      theorem
     {m n : Nat} : m ∈ range n ↔ m < n
        @[simp]
theorem mem_range {m n : Nat} : m ∈ range nm ∈ range n ↔ m < n := by
  simp only [range_eq_range', mem_range'_1, Nat.zero_le, true_and, Nat.zero_add]
        List.not_mem_range_self
      theorem
     {n : Nat} : n ∉ range n
        theorem not_mem_range_self {n : Nat} : n ∉ range n := by simp
        List.self_mem_range_succ
      theorem
     {n : Nat} : n ∈ range (n + 1)
        theorem self_mem_range_succ {n : Nat} : n ∈ range (n + 1) := by simp
        List.pairwise_lt_range
      theorem
     {n : Nat} : Pairwise (· < ·) (range n)
        theorem pairwise_lt_range {n : Nat} : Pairwise (· < ·) (range n) := by
  simp +decide only [range_eq_range', pairwise_lt_range']
        List.pairwise_le_range
      theorem
     {n : Nat} : Pairwise (· ≤ ·) (range n)
        theorem pairwise_le_range {n : Nat} : Pairwise (· ≤ ·) (range n) :=
  Pairwise.imp Nat.le_of_lt pairwise_lt_range
        List.take_range
      theorem
     {i n : Nat} : take i (range n) = range (min i n)
        @[simp] theorem take_range {i n : Nat} : take i (range n) = range (min i n) := by
  apply List.ext_getElem
  · simp
  · simp +contextual [getElem_take, Nat.lt_min]
        List.nodup_range
      theorem
     {n : Nat} : Nodup (range n)
        theorem nodup_range {n : Nat} : Nodup (range n) := by
  simp +decide only [range_eq_range', nodup_range']
        List.find?_range_eq_some
      theorem
     {n : Nat} {i : Nat} {p : Nat → Bool} : (range n).find? p = some i ↔ p i ∧ i ∈ range n ∧ ∀ j, j < i → !p j
        @[simp] theorem find?_range_eq_some {n : Nat} {i : Nat} {p : Nat → Bool} :
    (range n).find? p = some i ↔ p i ∧ i ∈ range n ∧ ∀ j, j < i → !p j := by
  simp [range_eq_range']
        List.find?_range_eq_none
      theorem
     {n : Nat} {p : Nat → Bool} : (range n).find? p = none ↔ ∀ i, i < n → !p i
        theorem find?_range_eq_none {n : Nat} {p : Nat → Bool} :
    (range n).find? p = none ↔ ∀ i, i < n → !p i := by
  simp
        List.erase_range
      theorem
     : (range n).erase i = range (min n i) ++ range' (i + 1) (n - (i + 1))
        theorem erase_range : (range n).erase i = range (min n i) ++ range' (i + 1) (n - (i + 1)) := by
  simp [range_eq_range', erase_range']
        List.iota_eq_reverse_range'
      theorem
     : ∀ n : Nat, iota n = reverse (range' 1 n)
        @[deprecated "Use `(List.range' 1 n).reverse` instead of `iota n`." (since := "2025-01-20")]
theorem iota_eq_reverse_range' : ∀ n : Nat, iota n = reverse (range' 1 n)
  | 0 => rfl
  | n + 1 => by simp [iota, range'_concat, iota_eq_reverse_range' n, reverse_append, Nat.add_comm]
        List.length_iota
      theorem
     (n : Nat) : length (iota n) = n
        @[deprecated "Use `(List.range' 1 n).reverse` instead of `iota n`." (since := "2025-01-20"), simp]
theorem length_iota (n : Nat) : length (iota n) = n := by simp [iota_eq_reverse_range']
        List.iota_eq_nil
      theorem
     {n : Nat} : iota n = [] ↔ n = 0
        @[deprecated "Use `(List.range' 1 n).reverse` instead of `iota n`." (since := "2025-01-20"), simp]
theorem iota_eq_nil {n : Nat} : iotaiota n = [] ↔ n = 0 := by
  cases n <;> simp
        List.iota_ne_nil
      theorem
     {n : Nat} : iota n ≠ [] ↔ n ≠ 0
        @[deprecated "Use `(List.range' 1 n).reverse` instead of `iota n`." (since := "2025-01-20")]
theorem iota_ne_nil {n : Nat} : iotaiota n ≠ []iota n ≠ [] ↔ n ≠ 0 := by
  cases n <;> simp
        List.mem_iota
      theorem
     {m n : Nat} : m ∈ iota n ↔ 0 < m ∧ m ≤ n
        @[deprecated "Use `(List.range' 1 n).reverse` instead of `iota n`." (since := "2025-01-20"), simp]
theorem mem_iota {m n : Nat} : m ∈ iota nm ∈ iota n ↔ 0 < m ∧ m ≤ n := by
  simp [iota_eq_reverse_range', Nat.add_comm, Nat.lt_succ]
  omega
        List.iota_inj
      theorem
     : iota n = iota n' ↔ n = n'
        @[deprecated "Use `(List.range' 1 n).reverse` instead of `iota n`." (since := "2025-01-20"), simp]
theorem iota_inj : iotaiota n = iota n' ↔ n = n' := by
  constructor
  · intro h
    have h' := congrArg List.length h
    simp at h'
    exact h'
  · rintro rfl
    simp
        List.iota_eq_cons_iff
      theorem
     : iota n = a :: xs ↔ n = a ∧ 0 < n ∧ xs = iota (n - 1)
        @[deprecated "Use `(List.range' 1 n).reverse` instead of `iota n`." (since := "2025-01-20")]
theorem iota_eq_cons_iff : iotaiota n = a :: xs ↔ n = a ∧ 0 < n ∧ xs = iota (n - 1) := by
  simp [iota_eq_reverse_range']
  simp [range'_eq_append_iff, reverse_eq_iff]
  constructor
  · rintro ⟨k, h, rfl, h'⟩
    rw [eq_comm, range'_eq_singleton] at h'
    simp only [reverse_inj, range'_inj, or_true, and_true]
    omega
  · rintro ⟨rfl, h, rfl⟩
    refine ⟨n - 1, by simp, rfl, ?_⟩
    rw [eq_comm, range'_eq_singleton]
    omega
        List.iota_eq_append_iff
      theorem
     : iota n = xs ++ ys ↔ ∃ k, k ≤ n ∧ xs = (range' (k + 1) (n - k)).reverse ∧ ys = iota k
        @[deprecated "Use `(List.range' 1 n).reverse` instead of `iota n`." (since := "2025-01-20")]
theorem iota_eq_append_iff : iotaiota n = xs ++ ys ↔ ∃ k, k ≤ n ∧ xs = (range' (k + 1) (n - k)).reverse ∧ ys = iota k := by
  simp only [iota_eq_reverse_range']
  rw [reverse_eq_append_iff]
  rw [range'_eq_append_iff]
  simp only [reverse_eq_iff]
  constructor
  · rintro ⟨k, h, rfl, rfl⟩
    simp; omega
  · rintro ⟨k, h, rfl, rfl⟩
    exact ⟨k, by simp; omega⟩
        List.pairwise_gt_iota
      theorem
     (n : Nat) : Pairwise (· > ·) (iota n)
        @[deprecated "Use `(List.range' 1 n).reverse` instead of `iota n`." (since := "2025-01-20")]
theorem pairwise_gt_iota (n : Nat) : Pairwise (· > ·) (iota n) := by
  simpa only [iota_eq_reverse_range', pairwise_reverse] using pairwise_lt_range'
        List.nodup_iota
      theorem
     (n : Nat) : Nodup (iota n)
        @[deprecated "Use `(List.range' 1 n).reverse` instead of `iota n`." (since := "2025-01-20")]
theorem nodup_iota (n : Nat) : Nodup (iota n) :=
  (pairwise_gt_iota n).imp Nat.ne_of_gt
        List.head?_iota
      theorem
     (n : Nat) : (iota n).head? = if n = 0 then none else some n
        @[deprecated "Use `(List.range' 1 n).reverse` instead of `iota n`." (since := "2025-01-20"), simp]
theorem head?_iota (n : Nat) : (iota n).head? = if n = 0 then none else some n := by
  cases n <;> simp
        List.head_iota
      theorem
     (n : Nat) (h) : (iota n).head h = n
        
      List.tail_iota
      theorem
     (n : Nat) : (iota n).tail = iota (n - 1)
        
      List.reverse_iota
      theorem
     : reverse (iota n) = range' 1 n
        @[deprecated "Use `(List.range' 1 n).reverse` instead of `iota n`." (since := "2025-01-20"), simp]
theorem reverse_iota : reverse (iota n) = range' 1 n := by
  induction n with
  | zero => simp
  | succ n ih =>
    rw [iota_succ, reverse_cons, ih, range'_1_concat, Nat.add_comm]
        List.getLast?_iota
      theorem
     (n : Nat) : (iota n).getLast? = if n = 0 then none else some 1
        @[deprecated "Use `(List.range' 1 n).reverse` instead of `iota n`." (since := "2025-01-20"), simp]
theorem getLast?_iota (n : Nat) : (iota n).getLast? = if n = 0 then none else some 1 := by
  rw [getLast?_eq_head?_reverse]
  simp [head?_range']
        List.getLast_iota
      theorem
     (n : Nat) (h) : (iota n).getLast h = 1
        @[deprecated "Use `(List.range' 1 n).reverse` instead of `iota n`." (since := "2025-01-20"), simp]
theorem getLast_iota (n : Nat) (h) : (iota n).getLast h = 1 := by
  rw [getLast_eq_head_reverse]
  simp
        List.find?_iota_eq_none
      theorem
     {n : Nat} {p : Nat → Bool} : (iota n).find? p = none ↔ ∀ i, 0 < i → i ≤ n → !p i
        @[deprecated "Use `(List.range' 1 n).reverse` instead of `iota n`." (since := "2025-01-20")]
theorem find?_iota_eq_none {n : Nat} {p : Nat → Bool} :
    (iota n).find? p = none ↔ ∀ i, 0 < i → i ≤ n → !p i := by
  simp
        List.find?_iota_eq_some
      theorem
     {n : Nat} {i : Nat} {p : Nat → Bool} : (iota n).find? p = some i ↔ p i ∧ i ∈ iota n ∧ ∀ j, i < j → j ≤ n → !p j
        @[deprecated "Use `(List.range' 1 n).reverse` instead of `iota n`." (since := "2025-01-20"), simp]
theorem find?_iota_eq_some {n : Nat} {i : Nat} {p : Nat → Bool} :
    (iota n).find? p = some i ↔ p i ∧ i ∈ iota n ∧ ∀ j, i < j → j ≤ n → !p j := by
  rw [find?_eq_some_iff_append]
  simp only [iota_eq_reverse_range', reverse_eq_append_iff, reverse_cons, append_assoc, cons_append,
    nil_append, Bool.not_eq_eq_eq_not, Bool.not_true, exists_and_right, mem_reverse, mem_range'_1,
    and_congr_right_iff]
  intro h
  constructor
  · rintro ⟨as, ⟨xs, h⟩, h'⟩
    constructor
    · replace h : i ∈ range' 1 n := by
        rw [h]
        exact mem_append_cons_self
      simpa using h
    · rw [range'_eq_append_iff] at h
      simp [reverse_eq_iff] at h
      obtain ⟨k, h₁, rfl, h₂⟩ := h
      rw [eq_comm, range'_eq_cons_iff, reverse_eq_iff] at h₂
      obtain ⟨rfl, -, rfl⟩ := h₂
      intro j j₁ j₂
      apply h'
      simp; omega
  · rintro ⟨⟨i₁, i₂⟩, h⟩
    refine ⟨(range' (i+1) (n-i)).reverse, ⟨(range' 1 (i-1)).reverse, ?_⟩, ?_⟩
    · simp [← range'_succ]
      rw [range'_eq_append_iff]
      refine ⟨i-1, ?_⟩
      constructor
      · omega
      · simp
        omega
    · simp
      intros a a₁ a₂
      apply h
      · omega
      · omega
        List.zipIdx_singleton
      theorem
     {x : α} {k : Nat} : zipIdx [x] k = [(x, k)]
        
      List.head?_zipIdx
      theorem
     {l : List α} {k : Nat} : (zipIdx l k).head? = l.head?.map fun a => (a, k)
        @[simp] theorem head?_zipIdx {l : List α} {k : Nat} :
    (zipIdx l k).head? = l.head?.map fun a => (a, k) := by
  simp [head?_eq_getElem?]
        List.getLast?_zipIdx
      theorem
     {l : List α} {k : Nat} : (zipIdx l k).getLast? = l.getLast?.map fun a => (a, k + l.length - 1)
        @[simp] theorem getLast?_zipIdx {l : List α} {k : Nat} :
    (zipIdx l k).getLast? = l.getLast?.map fun a => (a, k + l.length - 1) := by
  simp [getLast?_eq_getElem?]
  cases l <;> simp; omega
        List.mk_add_mem_zipIdx_iff_getElem?
      theorem
     {k i : Nat} {x : α} {l : List α} : (x, k + i) ∈ zipIdx l k ↔ l[i]? = some x
        theorem mk_add_mem_zipIdx_iff_getElem? {k i : Nat} {x : α} {l : List α} :
    (x, k + i)(x, k + i) ∈ zipIdx l k(x, k + i) ∈ zipIdx l k ↔ l[i]? = some x := by
  simp [mem_iff_getElem?, and_left_comm]
        List.mk_mem_zipIdx_iff_le_and_getElem?_sub
      theorem
     {k i : Nat} {x : α} {l : List α} : (x, i) ∈ zipIdx l k ↔ k ≤ i ∧ l[i - k]? = some x
        theorem mk_mem_zipIdx_iff_le_and_getElem?_sub {k i : Nat} {x : α} {l : List α} :
    (x, i)(x, i) ∈ zipIdx l k(x, i) ∈ zipIdx l k ↔ k ≤ i ∧ l[i - k]? = some x := by
  if h : k ≤ i then
    rcases Nat.exists_eq_add_of_le h with ⟨i, rfl⟩
    simp [mk_add_mem_zipIdx_iff_getElem?, Nat.add_sub_cancel_left]
  else
    have : ∀ m, k + m ≠ i := by rintro _ rfl; simp at h
    simp [h, mem_iff_getElem?, this]
        List.mk_mem_zipIdx_iff_getElem?
      theorem
     {i : Nat} {x : α} {l : List α} : (x, i) ∈ zipIdx l ↔ l[i]? = x
        /-- Variant of `mk_mem_zipIdx_iff_le_and_getElem?_sub` specialized at `k = 0`,
to avoid the inequality and the subtraction. -/
theorem mk_mem_zipIdx_iff_getElem? {i : Nat} {x : α} {l : List α} : (x, i)(x, i) ∈ zipIdx l(x, i) ∈ zipIdx l ↔ l[i]? = x := by
  simp [mk_mem_zipIdx_iff_le_and_getElem?_sub]
        List.mem_zipIdx_iff_le_and_getElem?_sub
      theorem
     {x : α × Nat} {l : List α} {k : Nat} : x ∈ zipIdx l k ↔ k ≤ x.2 ∧ l[x.2 - k]? = some x.1
        theorem mem_zipIdx_iff_le_and_getElem?_sub {x : α × Nat} {l : List α} {k : Nat} :
    x ∈ zipIdx l kx ∈ zipIdx l k ↔ k ≤ x.2 ∧ l[x.2 - k]? = some x.1 := by
  cases x
  simp [mk_mem_zipIdx_iff_le_and_getElem?_sub]
        List.mem_zipIdx_iff_getElem?
      theorem
     {x : α × Nat} {l : List α} : x ∈ zipIdx l ↔ l[x.2]? = some x.1
        /-- Variant of `mem_zipIdx_iff_le_and_getElem?_sub` specialized at `k = 0`,
to avoid the inequality and the subtraction. -/
theorem mem_zipIdx_iff_getElem? {x : α × Nat} {l : List α} : x ∈ zipIdx lx ∈ zipIdx l ↔ l[x.2]? = some x.1 := by
  cases x
  simp [mk_mem_zipIdx_iff_le_and_getElem?_sub]
        List.le_snd_of_mem_zipIdx
      theorem
     {x : α × Nat} {k : Nat} {l : List α} (h : x ∈ zipIdx l k) : k ≤ x.2
        theorem le_snd_of_mem_zipIdx {x : α × Nat} {k : Nat} {l : List α} (h : x ∈ zipIdx l k) :
    k ≤ x.2 :=
  (mk_mem_zipIdx_iff_le_and_getElem?_sub.1 h).1
        List.snd_lt_add_of_mem_zipIdx
      theorem
     {x : α × Nat} {l : List α} {k : Nat} (h : x ∈ zipIdx l k) : x.2 < k + length l
        theorem snd_lt_add_of_mem_zipIdx {x : α × Nat} {l : List α} {k : Nat} (h : x ∈ zipIdx l k) :
    x.2 < k + length l := by
  rcases mem_iff_get.1 h with ⟨i, rfl⟩
  simpa using i.isLt
        List.snd_lt_of_mem_zipIdx
      theorem
     {x : α × Nat} {l : List α} {k : Nat} (h : x ∈ l.zipIdx k) : x.2 < l.length + k
        theorem snd_lt_of_mem_zipIdx {x : α × Nat} {l : List α} {k : Nat} (h : x ∈ l.zipIdx k) : x.2 < l.length + k := by
  simpa [Nat.add_comm] using snd_lt_add_of_mem_zipIdx h
        List.map_zipIdx
      theorem
     {f : α → β} {l : List α} {k : Nat} : map (Prod.map f id) (zipIdx l k) = zipIdx (l.map f) k
        
      List.fst_mem_of_mem_zipIdx
      theorem
     {x : α × Nat} {l : List α} {k : Nat} (h : x ∈ zipIdx l k) : x.1 ∈ l
        theorem fst_mem_of_mem_zipIdx {x : α × Nat} {l : List α} {k : Nat} (h : x ∈ zipIdx l k) : x.1 ∈ l :=
  zipIdx_map_fst k l ▸ mem_map_of_mem h
        List.fst_eq_of_mem_zipIdx
      theorem
     {x : α × Nat} {l : List α} {k : Nat} (h : x ∈ zipIdx l k) :
  x.1 = l[x.2 - k]'(by have := le_snd_of_mem_zipIdx h; have := snd_lt_add_of_mem_zipIdx h; omega)
        theorem fst_eq_of_mem_zipIdx {x : α × Nat} {l : List α} {k : Nat} (h : x ∈ zipIdx l k) :
    x.1 = l[x.2 - k]'(by have := le_snd_of_mem_zipIdx h; have := snd_lt_add_of_mem_zipIdx h; omega) := by
  induction l generalizing k with
  | nil => cases h
  | cons hd tl ih =>
    cases h with
    | head _ => simp
    | tail h m =>
      specialize ih m
      have : x.2 - k = x.2 - (k + 1) + 1 := by
        have := le_snd_of_mem_zipIdx m
        omega
      simp [this, ih]
        List.mem_zipIdx
      theorem
     {x : α} {i : Nat} {xs : List α} {k : Nat} (h : (x, i) ∈ xs.zipIdx k) :
  k ≤ i ∧
    i < k + xs.length ∧ x = xs[i - k]'(by have := le_snd_of_mem_zipIdx h; have := snd_lt_add_of_mem_zipIdx h; omega)
        theorem mem_zipIdx {x : α} {i : Nat} {xs : List α} {k : Nat} (h : (x, i)(x, i) ∈ xs.zipIdx k) :
    k ≤ i ∧ i < k + xs.length ∧
      x = xs[i - k]'(by have := le_snd_of_mem_zipIdx h; have := snd_lt_add_of_mem_zipIdx h; omega) :=
  ⟨le_snd_of_mem_zipIdx h, snd_lt_add_of_mem_zipIdx h, fst_eq_of_mem_zipIdx h⟩
        List.mem_zipIdx'
      theorem
     {x : α} {i : Nat} {xs : List α} (h : (x, i) ∈ xs.zipIdx) :
  i < xs.length ∧ x = xs[i]'(by have := le_snd_of_mem_zipIdx h; have := snd_lt_add_of_mem_zipIdx h; omega)
        /-- Variant of `mem_zipIdx` specialized at `k = 0`. -/
theorem mem_zipIdx' {x : α} {i : Nat} {xs : List α} (h : (x, i)(x, i) ∈ xs.zipIdx) :
    i < xs.length ∧ x = xs[i]'(by have := le_snd_of_mem_zipIdx h; have := snd_lt_add_of_mem_zipIdx h; omega) :=
  ⟨by simpa using snd_lt_add_of_mem_zipIdx h, fst_eq_of_mem_zipIdx h⟩
        List.zipIdx_map
      theorem
     {l : List α} {k : Nat} {f : α → β} : zipIdx (l.map f) k = (zipIdx l k).map (Prod.map f id)
        
      List.zipIdx_append
      theorem
     {xs ys : List α} {k : Nat} : zipIdx (xs ++ ys) k = zipIdx xs k ++ zipIdx ys (k + xs.length)
        theorem zipIdx_append {xs ys : List α} {k : Nat} :
    zipIdx (xs ++ ys) k = zipIdx xs k ++ zipIdx ys (k + xs.length) := by
  induction xs generalizing ys k with
  | nil => simp
  | cons x xs IH =>
    rw [cons_append, zipIdx_cons, IH, ← cons_append, ← zipIdx_cons, length, Nat.add_right_comm,
      Nat.add_assoc]
        List.zipIdx_eq_cons_iff
      theorem
     {l : List α} {k : Nat} : zipIdx l k = x :: l' ↔ ∃ a as, l = a :: as ∧ x = (a, k) ∧ l' = zipIdx as (k + 1)
        theorem zipIdx_eq_cons_iff {l : List α} {k : Nat} :
    zipIdxzipIdx l k = x :: l' ↔ ∃ a as, l = a :: as ∧ x = (a, k) ∧ l' = zipIdx as (k + 1) := by
  rw [zipIdx_eq_zip_range', zip_eq_cons_iff]
  constructor
  · rintro ⟨l₁, l₂, rfl, h, rfl⟩
    rw [range'_eq_cons_iff] at h
    obtain ⟨rfl, -, rfl⟩ := h
    exact ⟨x.1, l₁, by simp [zipIdx_eq_zip_range']⟩
  · rintro ⟨a, as, rfl, rfl, rfl⟩
    refine ⟨as, range' (k+1) as.length, ?_⟩
    simp [zipIdx_eq_zip_range', range'_succ]
        List.zipIdx_eq_append_iff
      theorem
     {l : List α} {k : Nat} :
  zipIdx l k = l₁ ++ l₂ ↔ ∃ l₁' l₂', l = l₁' ++ l₂' ∧ l₁ = zipIdx l₁' k ∧ l₂ = zipIdx l₂' (k + l₁'.length)
        theorem zipIdx_eq_append_iff {l : List α} {k : Nat} :
    zipIdxzipIdx l k = l₁ ++ l₂ ↔
      ∃ l₁' l₂', l = l₁' ++ l₂' ∧ l₁ = zipIdx l₁' k ∧ l₂ = zipIdx l₂' (k + l₁'.length) := by
  rw [zipIdx_eq_zip_range', zip_eq_append_iff]
  constructor
  · rintro ⟨ws, xs, ys, zs, h, rfl, h', rfl, rfl⟩
    rw [range'_eq_append_iff] at h'
    obtain ⟨k, -, rfl, rfl⟩ := h'
    simp only [length_range'] at h
    obtain rfl := h
    refine ⟨ws, xs, rfl, ?_⟩
    simp only [zipIdx_eq_zip_range', length_append, true_and]
    congr
    omega
  · rintro ⟨l₁', l₂', rfl, rfl, rfl⟩
    simp only [zipIdx_eq_zip_range']
    refine ⟨l₁', l₂', range' k l₁'.length, range' (k + l₁'.length) l₂'.length, ?_⟩
    simp [Nat.add_comm]
        List.enumFrom_singleton
      theorem
     (x : α) (n : Nat) : enumFrom n [x] = [(n, x)]
        @[deprecated zipIdx_singleton (since := "2025-01-21"), simp]
theorem enumFrom_singleton (x : α) (n : Nat) : enumFrom n [x] = [(n, x)] :=
  rfl
        List.head?_enumFrom
      theorem
     (n : Nat) (l : List α) : (enumFrom n l).head? = l.head?.map fun a => (n, a)
        @[deprecated head?_zipIdx (since := "2025-01-21"), simp]
theorem head?_enumFrom (n : Nat) (l : List α) :
    (enumFrom n l).head? = l.head?.map fun a => (n, a) := by
  simp [head?_eq_getElem?]
        List.getLast?_enumFrom
      theorem
     (n : Nat) (l : List α) : (enumFrom n l).getLast? = l.getLast?.map fun a => (n + l.length - 1, a)
        @[deprecated getLast?_zipIdx (since := "2025-01-21"), simp]
theorem getLast?_enumFrom (n : Nat) (l : List α) :
    (enumFrom n l).getLast? = l.getLast?.map fun a => (n + l.length - 1, a) := by
  simp [getLast?_eq_getElem?]
  cases l <;> simp; omega
        List.mk_add_mem_enumFrom_iff_getElem?
      theorem
     {n i : Nat} {x : α} {l : List α} : (n + i, x) ∈ enumFrom n l ↔ l[i]? = some x
        @[deprecated mk_add_mem_zipIdx_iff_getElem? (since := "2025-01-21")]
theorem mk_add_mem_enumFrom_iff_getElem? {n i : Nat} {x : α} {l : List α} :
    (n + i, x)(n + i, x) ∈ enumFrom n l(n + i, x) ∈ enumFrom n l ↔ l[i]? = some x := by
  simp [mem_iff_get?]
        List.mk_mem_enumFrom_iff_le_and_getElem?_sub
      theorem
     {n i : Nat} {x : α} {l : List α} : (i, x) ∈ enumFrom n l ↔ n ≤ i ∧ l[i - n]? = x
        @[deprecated mk_mem_zipIdx_iff_le_and_getElem?_sub (since := "2025-01-21")]
theorem mk_mem_enumFrom_iff_le_and_getElem?_sub {n i : Nat} {x : α} {l : List α} :
    (i, x)(i, x) ∈ enumFrom n l(i, x) ∈ enumFrom n l ↔ n ≤ i ∧ l[i - n]? = x := by
  if h : n ≤ i then
    rcases Nat.exists_eq_add_of_le h with ⟨i, rfl⟩
    simp [mk_add_mem_enumFrom_iff_getElem?, Nat.add_sub_cancel_left]
  else
    have : ∀ k, n + k ≠ i := by rintro k rfl; simp at h
    simp [h, mem_iff_get?, this]
        List.le_fst_of_mem_enumFrom
      theorem
     {x : Nat × α} {n : Nat} {l : List α} (h : x ∈ enumFrom n l) : n ≤ x.1
        @[deprecated le_snd_of_mem_zipIdx (since := "2025-01-21")]
theorem le_fst_of_mem_enumFrom {x : NatNat × α} {n : Nat} {l : List α} (h : x ∈ enumFrom n l) :
    n ≤ x.1 :=
  (mk_mem_enumFrom_iff_le_and_getElem?_sub.1 h).1
        List.fst_lt_add_of_mem_enumFrom
      theorem
     {x : Nat × α} {n : Nat} {l : List α} (h : x ∈ enumFrom n l) : x.1 < n + length l
        @[deprecated snd_lt_add_of_mem_zipIdx (since := "2025-01-21")]
theorem fst_lt_add_of_mem_enumFrom {x : NatNat × α} {n : Nat} {l : List α} (h : x ∈ enumFrom n l) :
    x.1 < n + length l := by
  rcases mem_iff_get.1 h with ⟨i, rfl⟩
  simpa using i.isLt
        List.map_enumFrom
      theorem
     (f : α → β) (n : Nat) (l : List α) : map (Prod.map id f) (enumFrom n l) = enumFrom n (map f l)
        @[deprecated map_zipIdx (since := "2025-01-21")]
theorem map_enumFrom (f : α → β) (n : Nat) (l : List α) :
    map (Prod.map id f) (enumFrom n l) = enumFrom n (map f l) := by
  induction l generalizing n <;> simp_all
        List.snd_mem_of_mem_enumFrom
      theorem
     {x : Nat × α} {n : Nat} {l : List α} (h : x ∈ enumFrom n l) : x.2 ∈ l
        @[deprecated fst_mem_of_mem_zipIdx (since := "2025-01-21")]
theorem snd_mem_of_mem_enumFrom {x : NatNat × α} {n : Nat} {l : List α} (h : x ∈ enumFrom n l) : x.2 ∈ l :=
  enumFrom_map_snd n l ▸ mem_map_of_mem h
        List.snd_eq_of_mem_enumFrom
      theorem
     {x : Nat × α} {n : Nat} {l : List α} (h : x ∈ enumFrom n l) :
  x.2 = l[x.1 - n]'(by have := le_fst_of_mem_enumFrom h; have := fst_lt_add_of_mem_enumFrom h; omega)
        @[deprecated fst_eq_of_mem_zipIdx (since := "2025-01-21")]
theorem snd_eq_of_mem_enumFrom {x : NatNat × α} {n : Nat} {l : List α} (h : x ∈ enumFrom n l) :
    x.2 = l[x.1 - n]'(by have := le_fst_of_mem_enumFrom h; have := fst_lt_add_of_mem_enumFrom h; omega) := by
  induction l generalizing n with
  | nil => cases h
  | cons hd tl ih =>
    cases h with
    | head _ => simp
    | tail h m =>
      specialize ih m
      have : x.1 - n = x.1 - (n + 1) + 1 := by
        have := le_fst_of_mem_enumFrom m
        omega
      simp [this, ih]
        List.mem_enumFrom
      theorem
     {x : α} {i j : Nat} {xs : List α} (h : (i, x) ∈ xs.enumFrom j) :
  j ≤ i ∧
    i < j + xs.length ∧ x = xs[i - j]'(by have := le_fst_of_mem_enumFrom h; have := fst_lt_add_of_mem_enumFrom h; omega)
        @[deprecated mem_zipIdx (since := "2025-01-21")]
theorem mem_enumFrom {x : α} {i j : Nat} {xs : List α} (h : (i, x)(i, x) ∈ xs.enumFrom j) :
    j ≤ i ∧ i < j + xs.length ∧
      x = xs[i - j]'(by have := le_fst_of_mem_enumFrom h; have := fst_lt_add_of_mem_enumFrom h; omega) :=
  ⟨le_fst_of_mem_enumFrom h, fst_lt_add_of_mem_enumFrom h, snd_eq_of_mem_enumFrom h⟩
        List.enumFrom_map
      theorem
     (n : Nat) (l : List α) (f : α → β) : enumFrom n (l.map f) = (enumFrom n l).map (Prod.map id f)
        @[deprecated zipIdx_map (since := "2025-01-21")]
theorem enumFrom_map (n : Nat) (l : List α) (f : α → β) :
    enumFrom n (l.map f) = (enumFrom n l).map (Prod.map id f) := by
  induction l with
  | nil => rfl
  | cons hd tl IH =>
    rw [map_cons, enumFrom_cons', enumFrom_cons', map_cons, map_map, IH, map_map]
    rfl
        List.enumFrom_append
      theorem
     (xs ys : List α) (n : Nat) : enumFrom n (xs ++ ys) = enumFrom n xs ++ enumFrom (n + xs.length) ys
        @[deprecated zipIdx_append (since := "2025-01-21")]
theorem enumFrom_append (xs ys : List α) (n : Nat) :
    enumFrom n (xs ++ ys) = enumFrom n xs ++ enumFrom (n + xs.length) ys := by
  induction xs generalizing ys n with
  | nil => simp
  | cons x xs IH =>
    rw [cons_append, enumFrom_cons, IH, ← cons_append, ← enumFrom_cons, length, Nat.add_right_comm,
      Nat.add_assoc]
        List.enumFrom_eq_cons_iff
      theorem
     {l : List α} {n : Nat} : l.enumFrom n = x :: l' ↔ ∃ a as, l = a :: as ∧ x = (n, a) ∧ l' = enumFrom (n + 1) as
        @[deprecated zipIdx_eq_cons_iff (since := "2025-01-21")]
theorem enumFrom_eq_cons_iff {l : List α} {n : Nat} :
    l.enumFrom n = x :: l' ↔ ∃ a as, l = a :: as ∧ x = (n, a) ∧ l' = enumFrom (n + 1) as := by
  rw [enumFrom_eq_zip_range', zip_eq_cons_iff]
  constructor
  · rintro ⟨l₁, l₂, h, rfl, rfl⟩
    rw [range'_eq_cons_iff] at h
    obtain ⟨rfl, -, rfl⟩ := h
    exact ⟨x.2, l₂, by simp [enumFrom_eq_zip_range']⟩
  · rintro ⟨a, as, rfl, rfl, rfl⟩
    refine ⟨range' (n+1) as.length, as, ?_⟩
    simp [enumFrom_eq_zip_range', range'_succ]
        List.enumFrom_eq_append_iff
      theorem
     {l : List α} {n : Nat} :
  l.enumFrom n = l₁ ++ l₂ ↔ ∃ l₁' l₂', l = l₁' ++ l₂' ∧ l₁ = l₁'.enumFrom n ∧ l₂ = l₂'.enumFrom (n + l₁'.length)
        @[deprecated zipIdx_eq_append_iff (since := "2025-01-21")]
theorem enumFrom_eq_append_iff {l : List α} {n : Nat} :
    l.enumFrom n = l₁ ++ l₂ ↔
      ∃ l₁' l₂', l = l₁' ++ l₂' ∧ l₁ = l₁'.enumFrom n ∧ l₂ = l₂'.enumFrom (n + l₁'.length) := by
  rw [enumFrom_eq_zip_range', zip_eq_append_iff]
  constructor
  · rintro ⟨ws, xs, ys, zs, h, h', rfl, rfl, rfl⟩
    rw [range'_eq_append_iff] at h'
    obtain ⟨k, -, rfl, rfl⟩ := h'
    simp only [length_range'] at h
    obtain rfl := h
    refine ⟨ys, zs, rfl, ?_⟩
    simp only [enumFrom_eq_zip_range', length_append, true_and]
    congr
    omega
  · rintro ⟨l₁', l₂', rfl, rfl, rfl⟩
    simp only [enumFrom_eq_zip_range']
    refine ⟨range' n l₁'.length, range' (n + l₁'.length) l₂'.length, l₁', l₂', ?_⟩
    simp [Nat.add_comm]
        List.enum_eq_nil_iff
      theorem
     {l : List α} : List.enum l = [] ↔ l = []
        @[deprecated zipIdx_eq_nil_iff (since := "2025-01-21"), simp]
theorem enum_eq_nil_iff {l : List α} : List.enumList.enum l = [] ↔ l = [] := enumFrom_eq_nil
        List.enum_eq_nil
      theorem
     {l : List α} : List.enum l = [] ↔ l = []
        @[deprecated zipIdx_eq_nil_iff (since := "2024-11-04")]
theorem enum_eq_nil {l : List α} : List.enumList.enum l = [] ↔ l = [] := enum_eq_nil_iff
        List.enum_singleton
      theorem
     (x : α) : enum [x] = [(0, x)]
        @[deprecated zipIdx_singleton (since := "2025-01-21"), simp]
theorem enum_singleton (x : α) : enum [x] = [(0, x)] := rfl
        List.enum_length
      theorem
     : (enum l).length = l.length
        @[deprecated length_zipIdx (since := "2025-01-21"), simp]
theorem enum_length : (enum l).length = l.length :=
  enumFrom_length
        List.getElem?_enum
      theorem
     (l : List α) (i : Nat) : (enum l)[i]? = l[i]?.map fun a => (i, a)
        @[deprecated getElem?_zipIdx (since := "2025-01-21"), simp]
theorem getElem?_enum (l : List α) (i : Nat) : (enum l)[i]? = l[i]?.map fun a => (i, a) := by
  rw [enum, getElem?_enumFrom, Nat.zero_add]
        List.getElem_enum
      theorem
     (l : List α) (i : Nat) (h : i < l.enum.length) : l.enum[i] = (i, l[i]'(by simpa [enum_length] using h))
        @[deprecated getElem_zipIdx (since := "2025-01-21"), simp]
theorem getElem_enum (l : List α) (i : Nat) (h : i < l.enum.length) :
    l.enum[i] = (i, l[i]'(by simpa [enum_length] using h)) := by
  simp [enum]
        List.head?_enum
      theorem
     (l : List α) : l.enum.head? = l.head?.map fun a => (0, a)
        @[deprecated head?_zipIdx (since := "2025-01-21"), simp] theorem head?_enum (l : List α) :
    l.enum.head? = l.head?.map fun a => (0, a) := by
  simp [head?_eq_getElem?]
        List.getLast?_enum
      theorem
     (l : List α) : l.enum.getLast? = l.getLast?.map fun a => (l.length - 1, a)
        @[deprecated getLast?_zipIdx (since := "2025-01-21"), simp]
theorem getLast?_enum (l : List α) :
    l.enum.getLast? = l.getLast?.map fun a => (l.length - 1, a) := by
  simp [getLast?_eq_getElem?]
        List.tail_enum
      theorem
     (l : List α) : (enum l).tail = enumFrom 1 l.tail
        
      List.mk_mem_enum_iff_getElem?
      theorem
     {i : Nat} {x : α} {l : List α} : (i, x) ∈ enum l ↔ l[i]? = x
        @[deprecated mk_mem_zipIdx_iff_getElem? (since := "2025-01-21")]
theorem mk_mem_enum_iff_getElem? {i : Nat} {x : α} {l : List α} : (i, x)(i, x) ∈ enum l(i, x) ∈ enum l ↔ l[i]? = x := by
  simp [enum, mk_mem_enumFrom_iff_le_and_getElem?_sub]
        List.mem_enum_iff_getElem?
      theorem
     {x : Nat × α} {l : List α} : x ∈ enum l ↔ l[x.1]? = some x.2
        @[deprecated mem_zipIdx_iff_getElem? (since := "2025-01-21")]
theorem mem_enum_iff_getElem? {x : NatNat × α} {l : List α} : x ∈ enum lx ∈ enum l ↔ l[x.1]? = some x.2 :=
  mk_mem_enum_iff_getElem?
        List.fst_lt_of_mem_enum
      theorem
     {x : Nat × α} {l : List α} (h : x ∈ enum l) : x.1 < length l
        @[deprecated snd_lt_of_mem_zipIdx (since := "2025-01-21")]
theorem fst_lt_of_mem_enum {x : NatNat × α} {l : List α} (h : x ∈ enum l) : x.1 < length l := by
  simpa using fst_lt_add_of_mem_enumFrom h
        List.snd_mem_of_mem_enum
      theorem
     {x : Nat × α} {l : List α} (h : x ∈ enum l) : x.2 ∈ l
        @[deprecated fst_mem_of_mem_zipIdx (since := "2025-01-21")]
theorem snd_mem_of_mem_enum {x : NatNat × α} {l : List α} (h : x ∈ enum l) : x.2 ∈ l :=
  snd_mem_of_mem_enumFrom h
        List.snd_eq_of_mem_enum
      theorem
     {x : Nat × α} {l : List α} (h : x ∈ enum l) : x.2 = l[x.1]'(fst_lt_of_mem_enum h)
        @[deprecated fst_eq_of_mem_zipIdx (since := "2025-01-21")]
theorem snd_eq_of_mem_enum {x : NatNat × α} {l : List α} (h : x ∈ enum l) :
    x.2 = l[x.1]'(fst_lt_of_mem_enum h) :=
  snd_eq_of_mem_enumFrom h
        List.mem_enum
      theorem
     {x : α} {i : Nat} {xs : List α} (h : (i, x) ∈ xs.enum) : i < xs.length ∧ x = xs[i]'(fst_lt_of_mem_enum h)
        @[deprecated mem_zipIdx (since := "2025-01-21")]
theorem mem_enum {x : α} {i : Nat} {xs : List α} (h : (i, x)(i, x) ∈ xs.enum) :
    i < xs.length ∧ x = xs[i]'(fst_lt_of_mem_enum h) :=
  by simpa using mem_enumFrom h
        List.map_enum
      theorem
     (f : α → β) (l : List α) : map (Prod.map id f) (enum l) = enum (map f l)
        @[deprecated map_zipIdx (since := "2025-01-21")]
theorem map_enum (f : α → β) (l : List α) : map (Prod.map id f) (enum l) = enum (map f l) :=
  map_enumFrom f 0 l
        List.enum_map_fst
      theorem
     (l : List α) : map Prod.fst (enum l) = range l.length
        @[deprecated zipIdx_map_snd (since := "2025-01-21"), simp]
theorem enum_map_fst (l : List α) : map Prod.fst (enum l) = range l.length := by
  simp only [enum, enumFrom_map_fst, range_eq_range']
        List.enum_map_snd
      theorem
     (l : List α) : map Prod.snd (enum l) = l
        @[deprecated zipIdx_map_fst (since := "2025-01-21"), simp]
theorem enum_map_snd (l : List α) : map Prod.snd (enum l) = l :=
  enumFrom_map_snd _ _
        List.enum_map
      theorem
     (l : List α) (f : α → β) : (l.map f).enum = l.enum.map (Prod.map id f)
        @[deprecated zipIdx_map (since := "2025-01-21")]
theorem enum_map (l : List α) (f : α → β) : (l.map f).enum = l.enum.map (Prod.map id f) :=
  enumFrom_map _ _ _
        List.enum_append
      theorem
     (xs ys : List α) : enum (xs ++ ys) = enum xs ++ enumFrom xs.length ys
        @[deprecated zipIdx_append (since := "2025-01-21")]
theorem enum_append (xs ys : List α) : enum (xs ++ ys) = enum xs ++ enumFrom xs.length ys := by
  simp [enum, enumFrom_append]
        List.enum_eq_zip_range
      theorem
     (l : List α) : l.enum = (range l.length).zip l
        @[deprecated zipIdx_eq_zip_range' (since := "2025-01-21")]
theorem enum_eq_zip_range (l : List α) : l.enum = (range l.length).zip l :=
  zip_of_prod (enum_map_fst _) (enum_map_snd _)
        List.unzip_enum_eq_prod
      theorem
     (l : List α) : l.enum.unzip = (range l.length, l)
        @[deprecated unzip_zipIdx_eq_prod (since := "2025-01-21"), simp]
theorem unzip_enum_eq_prod (l : List α) : l.enum.unzip = (range l.length, l) := by
  simp only [enum_eq_zip_range, unzip_zip, length_range]
        List.enum_eq_cons_iff
      theorem
     {l : List α} : l.enum = x :: l' ↔ ∃ a as, l = a :: as ∧ x = (0, a) ∧ l' = enumFrom 1 as
        @[deprecated zipIdx_eq_cons_iff (since := "2025-01-21")]
theorem enum_eq_cons_iff {l : List α} :
    l.enum = x :: l' ↔ ∃ a as, l = a :: as ∧ x = (0, a) ∧ l' = enumFrom 1 as := by
  rw [enum, enumFrom_eq_cons_iff]
        List.enum_eq_append_iff
      theorem
     {l : List α} : l.enum = l₁ ++ l₂ ↔ ∃ l₁' l₂', l = l₁' ++ l₂' ∧ l₁ = l₁'.enum ∧ l₂ = l₂'.enumFrom l₁'.length
        @[deprecated zipIdx_eq_append_iff (since := "2025-01-21")]
theorem enum_eq_append_iff {l : List α} :
    l.enum = l₁ ++ l₂ ↔
      ∃ l₁' l₂', l = l₁' ++ l₂' ∧ l₁ = l₁'.enum ∧ l₂ = l₂'.enumFrom l₁'.length := by
  simp [enum, enumFrom_eq_append_iff]