data.list.basicMathlib.Data.List.Basic

This file has been ported!

Changes since the initial port

The following section lists changes to this file in mathlib3 and mathlib4 that occured after the initial port. Most recent changes are shown first. Hovering over a commit will show all commits associated with the same mathlib3 commit.

Changes in mathlib3

(last sync)

feat(data/{list,multiset,finset}/*): attach and filter lemmas (#18087)

Left commutativity and cardinality of list.filter/multiset.filter/finset.filter. Interaction of count/countp and attach.

Diff
@@ -2716,6 +2716,8 @@ end split_at_on
   with the same elements but in the type `{x // x ∈ l}`. -/
 def attach (l : list α) : list {x // x ∈ l} := pmap subtype.mk l (λ a, id)
 
+@[simp] lemma attach_nil : ([] : list α).attach = [] := rfl
+
 theorem sizeof_lt_sizeof_of_mem [has_sizeof α] {x : α} {l : list α} (hx : x ∈ l) :
   sizeof x < sizeof l :=
 begin
@@ -3250,12 +3252,35 @@ theorem map_filter (f : β → α) (l : list β) :
   filter p (map f l) = map f (filter (p ∘ f) l) :=
 by rw [← filter_map_eq_map, filter_filter_map, filter_map_filter]; refl
 
+lemma map_filter' {f : α → β} (hf : injective f) (l : list α)
+  [decidable_pred (λ b, ∃ a, p a ∧ f a = b)] :
+  (l.filter p).map f = (l.map f).filter (λ b, ∃ a, p a ∧ f a = b) :=
+by simp [(∘), map_filter, hf.eq_iff]
+
+lemma filter_attach' (l : list α) (p : {a // a ∈ l} → Prop) [decidable_eq α] [decidable_pred p] :
+  l.attach.filter p = (l.filter $ λ x, ∃ h, p ⟨x, h⟩).attach.map
+    (subtype.map id $ λ x hx, let ⟨h, _⟩ := of_mem_filter hx in h) :=
+begin
+  classical,
+  refine map_injective_iff.2 subtype.coe_injective _,
+  simp [(∘), map_filter' _ subtype.coe_injective],
+end
+
+@[simp] lemma filter_attach (l : list α) (p : α → Prop) [decidable_pred p] :
+  l.attach.filter (λ x, p ↑x) = (l.filter p).attach.map (subtype.map id $ λ _, mem_of_mem_filter) :=
+map_injective_iff.2 subtype.coe_injective $ by
+  simp_rw [map_map, (∘), subtype.map, subtype.coe_mk, id.def, ←map_filter, attach_map_coe]
+
 @[simp] theorem filter_filter (q) [decidable_pred q] : ∀ l,
   filter p (filter q l) = filter (λ a, p a ∧ q a) l
 | [] := rfl
 | (a :: l) := by by_cases hp : p a; by_cases hq : q a; simp only [hp, hq, filter, if_true, if_false,
     true_and, false_and, filter_filter l, eq_self_iff_true]
 
+lemma filter_comm (q) [decidable_pred q] (l : list α) :
+  filter p (filter q l) = filter q (filter p l) :=
+by simp [and_comm]
+
 @[simp] lemma filter_true {h : decidable_pred (λ a : α, true)} (l : list α) :
   @filter α (λ _, true) h l = l :=
 by convert filter_eq_self.2 (λ _ _, trivial)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

feat(data/list/basic): missing lemmas about list.enum (#18489)

The primed versions of these lemmas are more convenient when inducting over the list argument.

Forward-ported at https://github.com/leanprover-community/mathlib4/pull/2469.

Diff
@@ -3704,6 +3704,26 @@ lemma map_fst_add_enum_eq_enum_from (l : list α) (n : ℕ) :
   map (prod.map (+ n) id) (enum l) = enum_from n l :=
 map_fst_add_enum_from_eq_enum_from l _ _
 
+lemma enum_from_cons' (n : ℕ) (x : α) (xs : list α) :
+  enum_from n (x :: xs) = (n, x) :: (enum_from n xs).map (prod.map nat.succ id) :=
+by rw [enum_from_cons, add_comm, ←map_fst_add_enum_from_eq_enum_from]
+
+lemma enum_cons' (x : α) (xs : list α) :
+  enum (x :: xs) = (0, x) :: (enum xs).map (prod.map nat.succ id) :=
+enum_from_cons' _ _ _
+
+lemma enum_from_map (n : ℕ) (l : list α) (f : α → β) :
+  enum_from n (l.map f) = (enum_from n l).map (prod.map id f) :=
+begin
+  induction l with hd tl IH,
+  { refl },
+  { rw [map_cons, enum_from_cons', enum_from_cons', map_cons, map_map, IH, map_map],
+    refl, },
+end
+
+lemma enum_map (l : list α) (f : α → β) : (l.map f).enum = l.enum.map (prod.map id f) :=
+enum_from_map _ _ _
+
 lemma nth_le_enum_from (l : list α) (n i : ℕ)
   (hi' : i < (l.enum_from n).length)
   (hi : i < l.length := by simpa [length_enum_from] using hi') :

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

chore(data/list): reorder arguments of list.nthd (#18182)

Sync it with List.getD in Mathlib 4.

Diff
@@ -4103,13 +4103,13 @@ section nthd
 
 variables (l : list α) (x : α) (xs : list α) (d : α) (n : ℕ)
 
-@[simp] lemma nthd_nil : nthd d [] n = d := rfl
+@[simp] lemma nthd_nil : nthd [] n d = d := rfl
 
-@[simp] lemma nthd_cons_zero : nthd d (x::xs) 0 = x := rfl
+@[simp] lemma nthd_cons_zero : nthd (x::xs) 0 d = x := rfl
 
-@[simp] lemma nthd_cons_succ : nthd d (x::xs) (n + 1) = nthd d xs n := rfl
+@[simp] lemma nthd_cons_succ : nthd (x::xs) (n + 1) d = nthd xs n d := rfl
 
-lemma nthd_eq_nth_le {n : ℕ} (hn : n < l.length) : l.nthd d n = l.nth_le n hn :=
+lemma nthd_eq_nth_le {n : ℕ} (hn : n < l.length) : l.nthd n d = l.nth_le n hn :=
 begin
   induction l with hd tl IH generalizing n,
   { exact absurd hn (not_lt_of_ge (nat.zero_le _)) },
@@ -4118,7 +4118,7 @@ begin
     { exact IH _ } }
 end
 
-lemma nthd_eq_default {n : ℕ} (hn : l.length ≤ n) : l.nthd d n = d :=
+lemma nthd_eq_default {n : ℕ} (hn : l.length ≤ n) : l.nthd n d = d :=
 begin
   induction l with hd tl IH generalizing n,
   { exact nthd_nil _ _ },
@@ -4130,12 +4130,12 @@ end
 /-- An empty list can always be decidably checked for the presence of an element.
 Not an instance because it would clash with `decidable_eq α`. -/
 def decidable_nthd_nil_ne {α} (a : α) : decidable_pred
-  (λ (i : ℕ), nthd a ([] : list α) i ≠ a) := λ i, is_false $ λ H, H (nthd_nil _ _)
+  (λ (i : ℕ), nthd ([] : list α) i a ≠ a) := λ i, is_false $ λ H, H (nthd_nil _ _)
 
-@[simp] lemma nthd_singleton_default_eq (n : ℕ) : [d].nthd d n = d :=
+@[simp] lemma nthd_singleton_default_eq (n : ℕ) : [d].nthd n d = d :=
 by { cases n; simp }
 
-@[simp] lemma nthd_replicate_default_eq (r n : ℕ) : (replicate r d).nthd d n = d :=
+@[simp] lemma nthd_replicate_default_eq (r n : ℕ) : (replicate r d).nthd n d = d :=
 begin
   induction r with r IH generalizing n,
   { simp },
@@ -4145,11 +4145,11 @@ end
 
 lemma nthd_append (l l' : list α) (d : α) (n : ℕ) (h : n < l.length)
   (h' : n < (l ++ l').length := h.trans_le ((length_append l l').symm ▸ le_self_add)) :
-  (l ++ l').nthd d n = l.nthd d n :=
+  (l ++ l').nthd n d = l.nthd n d :=
 by rw [nthd_eq_nth_le _ _ h', nth_le_append h' h, nthd_eq_nth_le]
 
 lemma nthd_append_right (l l' : list α) (d : α) (n : ℕ) (h : l.length ≤ n) :
-  (l ++ l').nthd d n = l'.nthd d (n - l.length) :=
+  (l ++ l').nthd n d = l'.nthd (n - l.length) d :=
 begin
   cases lt_or_le _ _ with h' h',
   { rw [nthd_eq_nth_le _ _ h', nth_le_append_right h h', nthd_eq_nth_le] },
@@ -4158,7 +4158,7 @@ begin
 end
 
 lemma nthd_eq_get_or_else_nth (n : ℕ) :
-  l.nthd d n = (l.nth n).get_or_else d :=
+  l.nthd n d = (l.nth n).get_or_else d :=
 begin
   cases lt_or_le _ _ with h h,
   { rw [nthd_eq_nth_le _ _ h, nth_le_nth h, option.get_or_else_some] },
@@ -4181,7 +4181,7 @@ lemma inth_eq_nth_le {n : ℕ} (hn : n < l.length) : l.inth n = l.nth_le n hn :=
 
 lemma inth_eq_default {n : ℕ} (hn : l.length ≤ n) : l.inth n = default := nthd_eq_default _ _ hn
 
-lemma nthd_default_eq_inth : l.nthd default = l.inth := rfl
+lemma nthd_default_eq_inth : l.nthd n default = l.inth n := rfl
 
 lemma inth_append (l l' : list α) (n : ℕ) (h : n < l.length)
   (h' : n < (l ++ l').length := h.trans_le ((length_append l l').symm ▸ le_self_add)) :

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

chore(*): sync list.replicate with Mathlib 4 (#18181)

Sync arguments order and golfs with leanprover-community/mathlib4#1579

Diff
@@ -450,13 +450,13 @@ append_inj_right h rfl
 theorem append_right_cancel {s₁ s₂ t : list α} (h : s₁ ++ t = s₂ ++ t) : s₁ = s₂ :=
 append_inj_left' h rfl
 
-theorem append_right_injective (s : list α) : function.injective (λ t, s ++ t) :=
+theorem append_right_injective (s : list α) : injective (λ t, s ++ t) :=
 λ t₁ t₂, append_left_cancel
 
 theorem append_right_inj {t₁ t₂ : list α} (s) : s ++ t₁ = s ++ t₂ ↔ t₁ = t₂ :=
 (append_right_injective s).eq_iff
 
-theorem append_left_injective (t : list α) : function.injective (λ s, s ++ t) :=
+theorem append_left_injective (t : list α) : injective (λ s, s ++ t) :=
 λ s₁ s₂, append_right_cancel
 
 theorem append_left_inj {s₁ s₂ : list α} (t) : s₁ ++ t = s₂ ++ t ↔ s₁ = s₂ :=
@@ -475,7 +475,9 @@ end
 
 /-! ### replicate -/
 
+@[simp] theorem replicate_zero (a : α) : replicate 0 a = [] := rfl
 @[simp] theorem replicate_succ (a : α) (n) : replicate (n + 1) a = a :: replicate n a := rfl
+theorem replicate_one (a : α) : replicate 1 a = [a] := rfl
 
 @[simp] theorem length_replicate : ∀ n (a : α), length (replicate n a) = n
 | 0 a := rfl
@@ -498,16 +500,19 @@ theorem eq_replicate {a : α} {n} {l : list α} : l = replicate n a ↔ length l
 ⟨λ h, h.symm ▸ ⟨length_replicate _ _, λ b, eq_of_mem_replicate⟩,
  λ ⟨e, al⟩, e ▸ eq_replicate_of_mem al⟩
 
-theorem replicate_add (a : α) (m n) : replicate (m + n) a = replicate m a ++ replicate n a :=
+theorem replicate_add (m n) (a : α) : replicate (m + n) a = replicate m a ++ replicate n a :=
 by induction m; simp only [*, zero_add, succ_add, replicate]; refl
 
-theorem replicate_subset_singleton (a : α) (n) : replicate n a ⊆ [a] :=
+theorem replicate_succ' (n) (a : α) : replicate (n + 1) a = replicate n a ++ [a] :=
+replicate_add n 1 a
+
+theorem replicate_subset_singleton (n) (a : α) : replicate n a ⊆ [a] :=
 λ b h, mem_singleton.2 (eq_of_mem_replicate h)
 
 lemma subset_singleton_iff {a : α} {L : list α} : L ⊆ [a] ↔ ∃ n, L = replicate n a :=
 by simp only [eq_replicate, subset_def, mem_singleton, exists_eq_left']
 
-@[simp] theorem map_replicate (f : α → β) (a : α) (n) : map f (replicate n a) = replicate n (f a) :=
+@[simp] theorem map_replicate (f : α → β) (n a) : map f (replicate n a) = replicate n (f a) :=
 by induction n; [refl, simp only [*, replicate, map]]; split; refl
 
 @[simp] theorem tail_replicate (n) (a : α) : tail (replicate n a) = replicate (n - 1) a :=
@@ -516,8 +521,7 @@ by cases n; refl
 @[simp] theorem join_replicate_nil (n : ℕ) : join (replicate n []) = @nil α :=
 by induction n; [refl, simp only [*, replicate, join, append_nil]]
 
-lemma replicate_right_injective {n : ℕ} (hn : n ≠ 0) :
-  function.injective (replicate n : α → list α) :=
+lemma replicate_right_injective {n : ℕ} (hn : n ≠ 0) : injective (replicate n : α → list α) :=
 λ _ _ h, (eq_replicate.1 h).2 _ $ mem_replicate.2 ⟨hn, rfl⟩
 
 lemma replicate_right_inj {a b : α} {n : ℕ} (hn : n ≠ 0) :
@@ -529,8 +533,8 @@ lemma replicate_right_inj {a b : α} {n : ℕ} (hn : n ≠ 0) :
 | 0 := by simp
 | (n + 1) := (replicate_right_inj n.succ_ne_zero).trans $ by simp only [n.succ_ne_zero, false_or]
 
-lemma replicate_left_injective (a : α) : function.injective (λ n, replicate n a) :=
-function.left_inverse.injective (λ n, length_replicate n a)
+lemma replicate_left_injective (a : α) : injective (λ n, replicate n a) :=
+left_inverse.injective (λ n, length_replicate n a)
 
 @[simp] lemma replicate_left_inj {a : α} {n m : ℕ} :
   replicate n a = replicate m a ↔ n = m :=
@@ -660,8 +664,8 @@ by simp only [reverse_core_eq, map_append, map_reverse]
 by induction l; [refl, simp only [*, reverse_cons, mem_append, mem_singleton, mem_cons_iff,
   not_mem_nil, false_or, or_false, or_comm]]
 
-@[simp] theorem reverse_replicate (a : α) (n) : reverse (replicate n a) = replicate n a :=
-eq_replicate.2 ⟨by simp only [length_reverse, length_replicate],
+@[simp] theorem reverse_replicate (n) (a : α) : reverse (replicate n a) = replicate n a :=
+eq_replicate.2 ⟨by rw [length_reverse, length_replicate],
   λ b h, eq_of_mem_replicate (mem_reverse.1 h)⟩
 
 /-! ### empty -/
@@ -729,12 +733,11 @@ theorem last_mem : ∀ {l : list α} (h : l ≠ []), last l h ∈ l
 | [a] h := or.inl rfl
 | (a::b::l) h := or.inr $ by { rw [last_cons_cons], exact last_mem (cons_ne_nil b l) }
 
-lemma last_replicate_succ (a m : ℕ) :
+lemma last_replicate_succ (m : ℕ) (a : α) :
   (replicate (m + 1) a).last (ne_nil_of_length_eq_succ (length_replicate (m + 1) a)) = a :=
 begin
-  induction m with k IH,
-  { simp },
-  { simpa only [replicate_succ, last] }
+  simp only [replicate_succ'],
+  exact last_append_singleton _
 end
 
 /-! ### last' -/
@@ -1796,12 +1799,13 @@ lemma map_eq_replicate_iff {l : list α} {f : α → β} {b : β} :
   l.map f = replicate l.length b ↔ (∀ x ∈ l, f x = b) :=
 by simp [eq_replicate]
 
-@[simp]
-theorem map_const (l : list α) (b : β) : map (function.const α b) l = replicate l.length b :=
+@[simp] theorem map_const (l : list α) (b : β) : map (const α b) l = replicate l.length b :=
 map_eq_replicate_iff.mpr (λ x _, rfl)
 
-theorem eq_of_mem_map_const {b₁ b₂ : β} {l : list α} (h : b₁ ∈ map (function.const α b₂) l) :
-  b₁ = b₂ :=
+-- Not a `simp` lemma because `function.const` is reducible in Lean 3
+theorem map_const' (l : list α) (b : β) : map (λ _, b) l = replicate l.length b := map_const l b
+
+theorem eq_of_mem_map_const {b₁ b₂ : β} {l : list α} (h : b₁ ∈ map (const α b₂) l) : b₁ = b₂ :=
 by rw map_const at h; exact eq_of_mem_replicate h
 
 /-! ### map₂ -/

(no changes)

(no changes)

refactor(*): define list.replicate and migrate to it (#18127)

This definition differs from list.repeat by the order of arguments. The new order is in sync with the Lean 4 version.

Diff
@@ -473,72 +473,68 @@ begin
   apply nat.le_add_right
 end
 
-/-! ### repeat -/
+/-! ### replicate -/
 
-@[simp] theorem repeat_succ (a : α) (n) : repeat a (n + 1) = a :: repeat a n := rfl
+@[simp] theorem replicate_succ (a : α) (n) : replicate (n + 1) a = a :: replicate n a := rfl
 
-theorem mem_repeat {a b : α} : ∀ {n}, b ∈ repeat a n ↔ n ≠ 0 ∧ b = a
+@[simp] theorem length_replicate : ∀ n (a : α), length (replicate n a) = n
+| 0 a := rfl
+| (n + 1) a := congr_arg nat.succ (length_replicate n a)
+
+theorem mem_replicate {a b : α} : ∀ {n}, b ∈ replicate n a ↔ n ≠ 0 ∧ b = a
 | 0 := by simp
-| (n + 1) := by simp [mem_repeat]
+| (n + 1) := by simp [mem_replicate]
 
-theorem eq_of_mem_repeat {a b : α} {n} (h :  b ∈ repeat a n) : b = a :=
-(mem_repeat.1 h).2
+theorem eq_of_mem_replicate {a b : α} {n} (h :  b ∈ replicate n a) : b = a :=
+(mem_replicate.1 h).2
 
-theorem eq_repeat_of_mem {a : α} : ∀ {l : list α}, (∀ b ∈ l, b = a) → l = repeat a l.length
-| []     H := rfl
-| (b::l) H := by cases forall_mem_cons.1 H with H₁ H₂;
-  unfold length repeat; congr; [exact H₁, exact eq_repeat_of_mem H₂]
+theorem eq_replicate_length {a : α} : ∀ {l : list α}, l = replicate l.length a ↔ ∀ b ∈ l, b = a
+| [] := by simp
+| (b :: l) := by simp [eq_replicate_length]
 
-theorem eq_repeat' {a : α} {l : list α} : l = repeat a l.length ↔ ∀ b ∈ l, b = a :=
-⟨λ h, h.symm ▸ λ b, eq_of_mem_repeat, eq_repeat_of_mem⟩
+alias eq_replicate_length ↔ _ eq_replicate_of_mem
 
-theorem eq_repeat {a : α} {n} {l : list α} : l = repeat a n ↔ length l = n ∧ ∀ b ∈ l, b = a :=
-⟨λ h, h.symm ▸ ⟨length_repeat _ _, λ b, eq_of_mem_repeat⟩,
- λ ⟨e, al⟩, e ▸ eq_repeat_of_mem al⟩
+theorem eq_replicate {a : α} {n} {l : list α} : l = replicate n a ↔ length l = n ∧ ∀ b ∈ l, b = a :=
+⟨λ h, h.symm ▸ ⟨length_replicate _ _, λ b, eq_of_mem_replicate⟩,
+ λ ⟨e, al⟩, e ▸ eq_replicate_of_mem al⟩
 
-theorem repeat_add (a : α) (m n) : repeat a (m + n) = repeat a m ++ repeat a n :=
-by induction m; simp only [*, zero_add, succ_add, repeat]; split; refl
+theorem replicate_add (a : α) (m n) : replicate (m + n) a = replicate m a ++ replicate n a :=
+by induction m; simp only [*, zero_add, succ_add, replicate]; refl
 
-theorem repeat_subset_singleton (a : α) (n) : repeat a n ⊆ [a] :=
-λ b h, mem_singleton.2 (eq_of_mem_repeat h)
+theorem replicate_subset_singleton (a : α) (n) : replicate n a ⊆ [a] :=
+λ b h, mem_singleton.2 (eq_of_mem_replicate h)
 
-lemma subset_singleton_iff {a : α} : ∀ L : list α, L ⊆ [a] ↔ ∃ n, L = repeat a n
-| [] := ⟨λ h, ⟨0, by simp⟩, by simp⟩
-| (h :: L) := begin
-  refine ⟨λ h, _, λ ⟨k, hk⟩, by simp [hk, repeat_subset_singleton]⟩,
-  rw [cons_subset] at h,
-  obtain ⟨n, rfl⟩ := (subset_singleton_iff L).mp h.2,
-  exact ⟨n.succ, by simp [mem_singleton.mp h.1]⟩
-end
+lemma subset_singleton_iff {a : α} {L : list α} : L ⊆ [a] ↔ ∃ n, L = replicate n a :=
+by simp only [eq_replicate, subset_def, mem_singleton, exists_eq_left']
 
-@[simp] theorem map_repeat (f : α → β) (a : α) (n) : map f (repeat a n) = repeat (f a) n :=
-by induction n; [refl, simp only [*, repeat, map]]; split; refl
+@[simp] theorem map_replicate (f : α → β) (a : α) (n) : map f (replicate n a) = replicate n (f a) :=
+by induction n; [refl, simp only [*, replicate, map]]; split; refl
 
-@[simp] theorem tail_repeat (a : α) (n) : tail (repeat a n) = repeat a n.pred :=
+@[simp] theorem tail_replicate (n) (a : α) : tail (replicate n a) = replicate (n - 1) a :=
 by cases n; refl
 
-@[simp] theorem join_repeat_nil (n : ℕ) : join (repeat [] n) = @nil α :=
-by induction n; [refl, simp only [*, repeat, join, append_nil]]
+@[simp] theorem join_replicate_nil (n : ℕ) : join (replicate n []) = @nil α :=
+by induction n; [refl, simp only [*, replicate, join, append_nil]]
 
-lemma repeat_left_injective {n : ℕ} (hn : n ≠ 0) :
-  function.injective (λ a : α, repeat a n) :=
-λ a b h, (eq_repeat.1 h).2 _ $ mem_repeat.2 ⟨hn, rfl⟩
+lemma replicate_right_injective {n : ℕ} (hn : n ≠ 0) :
+  function.injective (replicate n : α → list α) :=
+λ _ _ h, (eq_replicate.1 h).2 _ $ mem_replicate.2 ⟨hn, rfl⟩
 
-lemma repeat_left_inj {a b : α} {n : ℕ} (hn : n ≠ 0) :
-  repeat a n = repeat b n ↔ a = b :=
-(repeat_left_injective hn).eq_iff
+lemma replicate_right_inj {a b : α} {n : ℕ} (hn : n ≠ 0) :
+  replicate n a = replicate n b ↔ a = b :=
+(replicate_right_injective hn).eq_iff
 
-@[simp] lemma repeat_left_inj' {a b : α} :
-  ∀ {n}, repeat a n = repeat b n ↔ n = 0 ∨ a = b
+@[simp] lemma replicate_right_inj' {a b : α} :
+  ∀ {n}, replicate n a = replicate n b ↔ n = 0 ∨ a = b
 | 0 := by simp
-| (n + 1) := (repeat_left_inj n.succ_ne_zero).trans $ by simp only [n.succ_ne_zero, false_or]
+| (n + 1) := (replicate_right_inj n.succ_ne_zero).trans $ by simp only [n.succ_ne_zero, false_or]
 
-lemma repeat_right_injective (a : α) : function.injective (repeat a) :=
-function.left_inverse.injective (length_repeat a)
+lemma replicate_left_injective (a : α) : function.injective (λ n, replicate n a) :=
+function.left_inverse.injective (λ n, length_replicate n a)
 
-@[simp] lemma repeat_right_inj {a : α} {n m : ℕ} :
-  repeat a n = repeat a m ↔ n = m :=
-(repeat_right_injective a).eq_iff
+@[simp] lemma replicate_left_inj {a : α} {n m : ℕ} :
+  replicate n a = replicate m a ↔ n = m :=
+(replicate_left_injective a).eq_iff
 
 /-! ### pure -/
 
@@ -664,9 +660,9 @@ by simp only [reverse_core_eq, map_append, map_reverse]
 by induction l; [refl, simp only [*, reverse_cons, mem_append, mem_singleton, mem_cons_iff,
   not_mem_nil, false_or, or_false, or_comm]]
 
-@[simp] theorem reverse_repeat (a : α) (n) : reverse (repeat a n) = repeat a n :=
-eq_repeat.2 ⟨by simp only [length_reverse, length_repeat],
-  λ b h, eq_of_mem_repeat (mem_reverse.1 h)⟩
+@[simp] theorem reverse_replicate (a : α) (n) : reverse (replicate n a) = replicate n a :=
+eq_replicate.2 ⟨by simp only [length_reverse, length_replicate],
+  λ b h, eq_of_mem_replicate (mem_reverse.1 h)⟩
 
 /-! ### empty -/
 
@@ -733,13 +729,12 @@ theorem last_mem : ∀ {l : list α} (h : l ≠ []), last l h ∈ l
 | [a] h := or.inl rfl
 | (a::b::l) h := or.inr $ by { rw [last_cons_cons], exact last_mem (cons_ne_nil b l) }
 
-lemma last_repeat_succ (a m : ℕ) :
-  (repeat a m.succ).last (ne_nil_of_length_eq_succ
-  (show (repeat a m.succ).length = m.succ, by rw length_repeat)) = a :=
+lemma last_replicate_succ (a m : ℕ) :
+  (replicate (m + 1) a).last (ne_nil_of_length_eq_succ (length_replicate (m + 1) a)) = a :=
 begin
   induction m with k IH,
   { simp },
-  { simpa only [repeat_succ, last] }
+  { simpa only [replicate_succ, last] }
 end
 
 /-! ### last' -/
@@ -1068,15 +1063,16 @@ eq_nil_of_subset_nil $ s.subset
 @[simp] theorem sublist_nil_iff_eq_nil {l : list α} : l <+ [] ↔ l = [] :=
 ⟨eq_nil_of_sublist_nil, λ H, H ▸ sublist.refl _⟩
 
-@[simp] theorem repeat_sublist_repeat (a : α) {m n} : repeat a m <+ repeat a n ↔ m ≤ n :=
-⟨λ h, by simpa only [length_repeat] using h.length_le,
- λ h, by induction h; [refl, simp only [*, repeat_succ, sublist.cons]] ⟩
+@[simp] theorem replicate_sublist_replicate (a : α) {m n} :
+  replicate m a <+ replicate n a ↔ m ≤ n :=
+⟨λ h, by simpa only [length_replicate] using h.length_le,
+ λ h, by induction h; [refl, simp only [*, replicate_succ, sublist.cons]] ⟩
 
-lemma sublist_repeat_iff {l : list α} {a : α} {n : ℕ} :
-  l <+ repeat a n ↔ ∃ (k ≤ n), l = repeat a k :=
-⟨λ h, ⟨l.length, h.length_le.trans (length_repeat _ _).le, eq_repeat.mpr
-         ⟨rfl, λ b hb, list.eq_of_mem_repeat (h.subset hb)⟩⟩,
- by { rintro ⟨k, h, rfl⟩, exact (repeat_sublist_repeat _).mpr h }⟩
+lemma sublist_replicate_iff {l : list α} {a : α} {n : ℕ} :
+  l <+ replicate n a ↔ ∃ k ≤ n, l = replicate k a :=
+⟨λ h, ⟨l.length, h.length_le.trans (length_replicate _ _).le, eq_replicate_length.mpr $
+         λ b hb, eq_of_mem_replicate (h.subset hb)⟩,
+ by { rintro ⟨k, h, rfl⟩, exact (replicate_sublist_replicate _).mpr h }⟩
 
 theorem sublist.eq_of_length : ∀ {l₁ l₂ : list α}, l₁ <+ l₂ → length l₁ = length l₂ → l₁ = l₂
 | ._ ._ sublist.slnil             h := rfl
@@ -1303,9 +1299,9 @@ lemma nth_le_append_right : ∀ {l₁ l₂ : list α} {n : ℕ} (h₁ : l₁.len
     rw nth_le_append_right (nat.lt_succ_iff.mp h₁),
   end
 
-@[simp] lemma nth_le_repeat (a : α) {n m : ℕ} (h : m < (list.repeat a n).length) :
-  (list.repeat a n).nth_le m h = a :=
-eq_of_mem_repeat (nth_le_mem _ _ _)
+@[simp] lemma nth_le_replicate (a : α) {n m : ℕ} (h : m < (list.replicate n a).length) :
+  (list.replicate n a).nth_le m h = a :=
+eq_of_mem_replicate (nth_le_mem _ _ _)
 
 lemma nth_append {l₁ l₂ : list α} {n : ℕ} (hn : n < l₁.length) :
   (l₁ ++ l₂).nth n = l₁.nth n :=
@@ -1796,22 +1792,17 @@ begin
     { simpa using l_ih } }
 end
 
-lemma map_eq_repeat_iff {l : list α} {f : α → β} {b : β} :
-  l.map f = repeat b l.length ↔ (∀ x ∈ l, f x = b) :=
-begin
-  induction l with x l' ih,
-  { simp only [repeat, length, not_mem_nil, is_empty.forall_iff, implies_true_iff,
-               map_nil, eq_self_iff_true], },
-  { simp only [map, length, mem_cons_iff, forall_eq_or_imp, repeat_succ, and.congr_right_iff],
-    exact λ _, ih, }
-end
+lemma map_eq_replicate_iff {l : list α} {f : α → β} {b : β} :
+  l.map f = replicate l.length b ↔ (∀ x ∈ l, f x = b) :=
+by simp [eq_replicate]
 
-@[simp] theorem map_const (l : list α) (b : β) : map (function.const α b) l = repeat b l.length :=
-map_eq_repeat_iff.mpr (λ x _, rfl)
+@[simp]
+theorem map_const (l : list α) (b : β) : map (function.const α b) l = replicate l.length b :=
+map_eq_replicate_iff.mpr (λ x _, rfl)
 
 theorem eq_of_mem_map_const {b₁ b₂ : β} {l : list α} (h : b₁ ∈ map (function.const α b₂) l) :
   b₁ = b₂ :=
-by rw map_const at h; exact eq_of_mem_repeat h
+by rw map_const at h; exact eq_of_mem_replicate h
 
 /-! ### map₂ -/
 
@@ -1865,10 +1856,10 @@ theorem take_take : ∀ (n m) (l : list α), take n (take m l) = take (min n m)
 | (succ n)  (succ m) nil    := by simp only [take_nil]
 | (succ n)  (succ m) (a::l) := by simp only [take, min_succ_succ, take_take n m l]; split; refl
 
-theorem take_repeat (a : α) : ∀ (n m : ℕ), take n (repeat a m) = repeat a (min n m)
+theorem take_replicate (a : α) : ∀ (n m : ℕ), take n (replicate m a) = replicate (min n m) a
 | n        0        := by simp
 | 0        m        := by simp
-| (succ n) (succ m) := by simp [min_succ_succ, take_repeat]
+| (succ n) (succ m) := by simp [min_succ_succ, take_replicate]
 
 lemma map_take {α β : Type*} (f : α → β) :
   ∀ (L : list α) (i : ℕ), (L.take i).map f = (L.map f).take i
@@ -2188,7 +2179,7 @@ variable [inhabited α]
 | 0     l := rfl
 | (n+1) l := congr_arg succ (take'_length _ _)
 
-@[simp] theorem take'_nil : ∀ n, take' n (@nil α) = repeat default n
+@[simp] theorem take'_nil : ∀ n, take' n (@nil α) = replicate n default
 | 0     := rfl
 | (n+1) := congr_arg (cons _) (take'_nil _)
 
@@ -4140,7 +4131,7 @@ def decidable_nthd_nil_ne {α} (a : α) : decidable_pred
 @[simp] lemma nthd_singleton_default_eq (n : ℕ) : [d].nthd d n = d :=
 by { cases n; simp }
 
-@[simp] lemma nthd_repeat_default_eq (r n : ℕ) : (repeat d r).nthd d n = d :=
+@[simp] lemma nthd_replicate_default_eq (r n : ℕ) : (replicate r d).nthd d n = d :=
 begin
   induction r with r IH generalizing n,
   { simp },

(no changes)

(no changes)

(no changes)

(no changes)

chore(archive/100-theorems-list/30_ballot_problem): golf (#18126)

Also add some supporting lemmas.

Diff
@@ -318,6 +318,8 @@ iff.intro or_exists_of_exists_mem_cons
 
 /-! ### list subset -/
 
+instance : is_trans (list α) (⊆) := ⟨λ _ _ _, list.subset.trans⟩
+
 theorem subset_def {l₁ l₂ : list α} : l₁ ⊆ l₂ ↔ ∀ ⦃a : α⦄, a ∈ l₁ → a ∈ l₂ := iff.rfl
 
 theorem subset_append_of_subset_left (l l₁ l₂ : list α) : l ⊆ l₁ → l ⊆ l₁++l₂ :=

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(first ported)

Changes in mathlib3port

mathlib3
mathlib3port
Diff
@@ -1730,16 +1730,16 @@ theorem sublist_append_of_sublist_right {l l₁ l₂ : List α} (s : l <+ l₂)
 #align list.sublist_append_of_sublist_right List.sublist_append_of_sublist_right
 -/
 
-#print List.sublist_of_cons_sublist_cons /-
-theorem sublist_of_cons_sublist_cons {l₁ l₂ : List α} : ∀ {a : α}, a :: l₁ <+ a :: l₂ → l₁ <+ l₂
+#print List.Sublist.of_cons_cons /-
+theorem List.Sublist.of_cons_cons {l₁ l₂ : List α} : ∀ {a : α}, a :: l₁ <+ a :: l₂ → l₁ <+ l₂
   | _, sublist.cons _ _ a s => sublist_of_cons_sublist s
   | _, sublist.cons2 _ _ a s => s
-#align list.sublist_of_cons_sublist_cons List.sublist_of_cons_sublist_cons
+#align list.sublist_of_cons_sublist_cons List.Sublist.of_cons_cons
 -/
 
 #print List.cons_sublist_cons_iff /-
 theorem cons_sublist_cons_iff {l₁ l₂ : List α} {a : α} : a :: l₁ <+ a :: l₂ ↔ l₁ <+ l₂ :=
-  ⟨sublist_of_cons_sublist_cons, Sublist.cons_cons _⟩
+  ⟨List.Sublist.of_cons_cons, Sublist.cons_cons _⟩
 #align list.cons_sublist_cons_iff List.cons_sublist_cons_iff
 -/
 
@@ -5663,21 +5663,21 @@ theorem enum_length : ∀ l : List α, length (enum l) = length l :=
 #align list.length_enum List.enum_length
 -/
 
-#print List.enumFrom_get? /-
+#print List.get?_enumFrom /-
 @[simp]
-theorem enumFrom_get? :
+theorem get?_enumFrom :
     ∀ (n) (l : List α) (m), get? (enumFrom n l) m = (fun a => (n + m, a)) <$> get? l m
   | n, [], m => rfl
   | n, a :: l, 0 => rfl
   | n, a :: l, m + 1 => (enum_from_nth (n + 1) l m).trans <| by rw [add_right_comm] <;> rfl
-#align list.enum_from_nth List.enumFrom_get?
+#align list.enum_from_nth List.get?_enumFrom
 -/
 
-#print List.enum_get? /-
+#print List.get?_enum /-
 @[simp]
-theorem enum_get? : ∀ (l : List α) (n), get? (enum l) n = (fun a => (n, a)) <$> get? l n := by
+theorem get?_enum : ∀ (l : List α) (n), get? (enum l) n = (fun a => (n, a)) <$> get? l n := by
   simp only [enum, enum_from_nth, zero_add] <;> intros <;> rfl
-#align list.enum_nth List.enum_get?
+#align list.enum_nth List.get?_enum
 -/
 
 #print List.enumFrom_map_snd /-
@@ -6317,15 +6317,15 @@ theorem ilast'_mem : ∀ a l, @ilast' α a l ∈ a :: l
 #align list.ilast'_mem List.ilast'_mem
 -/
 
-#print List.nthLe_attach /-
+#print List.get_attach /-
 @[simp]
-theorem nthLe_attach (L : List α) (i) (H : i < L.attach.length) :
+theorem get_attach (L : List α) (i) (H : i < L.attach.length) :
     (L.attach.nthLe i H).1 = L.nthLe i (length_attach L ▸ H) :=
   calc
     (L.attach.nthLe i H).1 = (L.attach.map Subtype.val).nthLe i (by simpa using H) := by
       rw [nth_le_map']
     _ = L.nthLe i _ := by congr <;> apply attach_map_val
-#align list.nth_le_attach List.nthLe_attach
+#align list.nth_le_attach List.get_attach
 -/
 
 #print List.mem_map_swap /-
Diff
@@ -661,7 +661,7 @@ theorem nil_eq_append {a b : List α} : [] = a ++ b ↔ a = [] ∧ b = [] := by
 theorem append_eq_cons {a b c : List α} {x : α} :
     a ++ b = x :: c ↔ a = [] ∧ b = x :: c ∨ ∃ a', a = x :: a' ∧ c = a' ++ b := by
   cases a <;>
-    simp only [and_assoc', @eq_comm _ c, nil_append, cons_append, eq_self_iff_true, true_and_iff,
+    simp only [and_assoc, @eq_comm _ c, nil_append, cons_append, eq_self_iff_true, true_and_iff,
       false_and_iff, exists_false, false_or_iff, or_false_iff, exists_and_left, exists_eq_left']
 #align list.append_eq_cons_iff List.append_eq_cons
 -/
@@ -687,7 +687,7 @@ theorem append_eq_append_iff {a b c d : List α} :
     · simp only [cons_append, nil_append, false_and_iff, exists_false, false_or_iff,
         exists_eq_left']
       exact eq_comm
-    · simp only [cons_append, @eq_comm _ a, ih, and_assoc', and_or_left, exists_and_left]
+    · simp only [cons_append, @eq_comm _ a, ih, and_assoc, and_or_left, exists_and_left]
 #align list.append_eq_append_iff List.append_eq_append_iff
 -/
 
@@ -1193,7 +1193,7 @@ theorem map_reverseAux (f : α → β) (l₁ l₂ : List α) :
 theorem mem_reverse {a : α} {l : List α} : a ∈ reverse l ↔ a ∈ l := by
   induction l <;> [rfl;
     simp only [*, reverse_cons, mem_append, mem_singleton, mem_cons_iff, not_mem_nil, false_or_iff,
-      or_false_iff, or_comm']]
+      or_false_iff, or_comm]]
 #align list.mem_reverse List.mem_reverse
 -/
 
@@ -2675,7 +2675,7 @@ theorem mem_insertNth {a b : α} :
   | n + 1, [], h => (Nat.not_succ_le_zero _ h).elim
   | n + 1, a' :: as, h => by
     dsimp [List.insertNth]
-    erw [mem_insert_nth (Nat.le_of_succ_le_succ h), ← or_assoc, or_comm' (a = a'), or_assoc]
+    erw [mem_insert_nth (Nat.le_of_succ_le_succ h), ← or_assoc, or_comm (a = a'), or_assoc]
 #align list.mem_insert_nth List.mem_insertNth
 -/
 
@@ -5136,7 +5136,7 @@ theorem filter_filter (q) [DecidablePred q] :
 
 #print List.filter_comm /-
 theorem filter_comm (q) [DecidablePred q] (l : List α) :
-    filter p (filter q l) = filter q (filter p l) := by simp [and_comm']
+    filter p (filter q l) = filter q (filter p l) := by simp [and_comm]
 #align list.filter_comm List.filter_comm
 -/
 
@@ -6336,7 +6336,7 @@ theorem mem_map_swap (x : α) (y : β) (xs : List (α × β)) :
   induction' xs with x xs
   · simp only [not_mem_nil, map_nil]
   · cases' x with a b
-    simp only [mem_cons_iff, Prod.mk.inj_iff, map, Prod.swap_prod_mk, Prod.exists, xs_ih, and_comm']
+    simp only [mem_cons_iff, Prod.mk.inj_iff, map, Prod.swap_prod_mk, Prod.exists, xs_ih, and_comm]
 #align list.mem_map_swap List.mem_map_swap
 -/
 
Diff
@@ -550,10 +550,10 @@ theorem subset_append_of_subset_left (l l₁ l₂ : List α) : l ⊆ l₁ → l
 #align list.subset_append_of_subset_left List.subset_append_of_subset_left
 -/
 
-#print List.subset_append_of_subset_right' /-
-theorem subset_append_of_subset_right' (l l₁ l₂ : List α) : l ⊆ l₂ → l ⊆ l₁ ++ l₂ := fun s =>
+#print List.subset_append_of_subset_right /-
+theorem subset_append_of_subset_right (l l₁ l₂ : List α) : l ⊆ l₂ → l ⊆ l₁ ++ l₂ := fun s =>
   Subset.trans s <| subset_append_right _ _
-#align list.subset_append_of_subset_right List.subset_append_of_subset_right'
+#align list.subset_append_of_subset_right List.subset_append_of_subset_right
 -/
 
 #print List.cons_subset /-
@@ -1006,11 +1006,11 @@ theorem concat_cons (a b : α) (l : List α) : concat (a :: l) b = a :: concat l
 #align list.concat_cons List.concat_cons
 -/
 
-#print List.concat_eq_append' /-
+#print List.concat_eq_append /-
 @[simp]
-theorem concat_eq_append' (a : α) (l : List α) : concat l a = l ++ [a] := by
+theorem concat_eq_append (a : α) (l : List α) : concat l a = l ++ [a] := by
   induction l <;> simp only [*, concat] <;> constructor <;> rfl
-#align list.concat_eq_append List.concat_eq_append'
+#align list.concat_eq_append List.concat_eq_append
 -/
 
 #print List.init_eq_of_concat_eq /-
@@ -1041,10 +1041,10 @@ theorem concat_append (a : α) (l₁ l₂ : List α) : concat l₁ a ++ l₂ = l
 #align list.concat_append List.concat_append
 -/
 
-#print List.length_concat' /-
-theorem length_concat' (a : α) (l : List α) : length (concat l a) = succ (length l) := by
+#print List.length_concat /-
+theorem length_concat (a : α) (l : List α) : length (concat l a) = succ (length l) := by
   simp only [concat_eq_append, length_append, length]
-#align list.length_concat List.length_concat'
+#align list.length_concat List.length_concat
 -/
 
 #print List.append_concat /-
@@ -2264,8 +2264,8 @@ theorem nthLe_cons_length (x : α) (xs : List α) (n : ℕ) (h : n = xs.length)
 #align list.nth_le_cons_length List.nthLe_cons_length
 -/
 
-#print List.take_one_drop_eq_of_lt_length' /-
-theorem take_one_drop_eq_of_lt_length' {l : List α} {n : ℕ} (h : n < l.length) :
+#print List.take_one_drop_eq_of_lt_length /-
+theorem take_one_drop_eq_of_lt_length {l : List α} {n : ℕ} (h : n < l.length) :
     (l.drop n).take 1 = [l.nthLe n h] :=
   by
   induction' l with x l ih generalizing n
@@ -2274,7 +2274,7 @@ theorem take_one_drop_eq_of_lt_length' {l : List α} {n : ℕ} (h : n < l.length
     · subst h₁; rw [nth_le_singleton]; simp [lt_succ_iff] at h; subst h; simp
     have h₂ := h; rw [length_cons, Nat.lt_succ_iff, le_iff_eq_or_lt] at h₂
     cases n; · simp; rw [drop, nth_le]; apply ih
-#align list.take_one_drop_eq_of_lt_length List.take_one_drop_eq_of_lt_length'
+#align list.take_one_drop_eq_of_lt_length List.take_one_drop_eq_of_lt_length
 -/
 
 #print List.ext /-
@@ -5826,22 +5826,22 @@ theorem enum_map (l : List α) (f : α → β) : (l.map f).enum = l.enum.map (Pr
 #align list.enum_map List.enum_map
 -/
 
-#print List.nthLe_enumFrom /-
-theorem nthLe_enumFrom (l : List α) (n i : ℕ) (hi' : i < (l.enumFrom n).length)
+#print List.get_enumFrom /-
+theorem get_enumFrom (l : List α) (n i : ℕ) (hi' : i < (l.enumFrom n).length)
     (hi : i < l.length := (by simpa [length_enum_from] using hi')) :
     (l.enumFrom n).nthLe i hi' = (n + i, l.nthLe i hi) :=
   by
   rw [← Option.some_inj, ← nth_le_nth]
   simp [enum_from_nth, nth_le_nth hi]
-#align list.nth_le_enum_from List.nthLe_enumFrom
+#align list.nth_le_enum_from List.get_enumFrom
 -/
 
-#print List.nthLe_enum /-
-theorem nthLe_enum (l : List α) (i : ℕ) (hi' : i < l.enum.length)
+#print List.get_enum /-
+theorem get_enum (l : List α) (i : ℕ) (hi' : i < l.enum.length)
     (hi : i < l.length := (by simpa [length_enum] using hi')) :
     l.enum.nthLe i hi' = (i, l.nthLe i hi) := by convert nth_le_enum_from _ _ _ hi';
   exact (zero_add _).symm
-#align list.nth_le_enum List.nthLe_enum
+#align list.nth_le_enum List.get_enum
 -/
 
 section Choose
@@ -6396,14 +6396,16 @@ theorem getD_cons_succ : getD (x :: xs) (n + 1) d = getD xs n d :=
   rfl
 #align list.nthd_cons_succ List.getD_cons_succₓ
 
-theorem getD_eq_nthLe {n : ℕ} (hn : n < l.length) : l.getD n d = l.nthLe n hn :=
+#print List.getD_eq_get /-
+theorem getD_eq_get {n : ℕ} (hn : n < l.length) : l.getD n d = l.nthLe n hn :=
   by
   induction' l with hd tl IH generalizing n
   · exact absurd hn (not_lt_of_ge (Nat.zero_le _))
   · cases n
     · exact nthd_cons_zero _ _ _
     · exact IH _
-#align list.nthd_eq_nth_le List.getD_eq_nthLeₓ
+#align list.nthd_eq_nth_le List.getD_eq_get
+-/
 
 theorem getD_eq_default {n : ℕ} (hn : l.length ≤ n) : l.getD n d = d :=
   by
@@ -6481,10 +6483,10 @@ theorem getI_cons_succ : getI (x :: xs) (n + 1) = getI xs n :=
 #align list.inth_cons_succ List.getI_cons_succ
 -/
 
-#print List.getI_eq_nthLe /-
-theorem getI_eq_nthLe {n : ℕ} (hn : n < l.length) : l.getI n = l.nthLe n hn :=
-  getD_eq_nthLe _ _ _
-#align list.inth_eq_nth_le List.getI_eq_nthLe
+#print List.getI_eq_get /-
+theorem getI_eq_get {n : ℕ} (hn : n < l.length) : l.getI n = l.nthLe n hn :=
+  getD_eq_get _ _ _
+#align list.inth_eq_nth_le List.getI_eq_get
 -/
 
 #print List.getI_eq_default /-
Diff
@@ -657,20 +657,20 @@ theorem nil_eq_append {a b : List α} : [] = a ++ b ↔ a = [] ∧ b = [] := by
 #align list.nil_eq_append_iff List.nil_eq_append
 -/
 
-#print List.append_eq_cons_iff /-
-theorem append_eq_cons_iff {a b c : List α} {x : α} :
+#print List.append_eq_cons /-
+theorem append_eq_cons {a b c : List α} {x : α} :
     a ++ b = x :: c ↔ a = [] ∧ b = x :: c ∨ ∃ a', a = x :: a' ∧ c = a' ++ b := by
   cases a <;>
     simp only [and_assoc', @eq_comm _ c, nil_append, cons_append, eq_self_iff_true, true_and_iff,
       false_and_iff, exists_false, false_or_iff, or_false_iff, exists_and_left, exists_eq_left']
-#align list.append_eq_cons_iff List.append_eq_cons_iff
+#align list.append_eq_cons_iff List.append_eq_cons
 -/
 
-#print List.cons_eq_append_iff /-
-theorem cons_eq_append_iff {a b c : List α} {x : α} :
+#print List.cons_eq_append /-
+theorem cons_eq_append {a b c : List α} {x : α} :
     (x :: c : List α) = a ++ b ↔ a = [] ∧ b = x :: c ∨ ∃ a', a = x :: a' ∧ c = a' ++ b := by
   rw [eq_comm, append_eq_cons_iff]
-#align list.cons_eq_append_iff List.cons_eq_append_iff
+#align list.cons_eq_append_iff List.cons_eq_append
 -/
 
 #print List.append_eq_append_iff /-
Diff
@@ -3,7 +3,7 @@ Copyright (c) 2014 Parikshit Khanna. All rights reserved.
 Released under Apache 2.0 license as described in the file LICENSE.
 Authors: Parikshit Khanna, Jeremy Avigad, Leonardo de Moura, Floris van Doorn, Mario Carneiro
 -/
-import Data.Nat.Order.Basic
+import Algebra.Order.Group.Nat
 
 #align_import data.list.basic from "leanprover-community/mathlib"@"65a1391a0106c9204fe45bc73a039f056558cb83"
 
Diff
@@ -166,14 +166,14 @@ theorem ne_nil_of_mem {a : α} {l : List α} (h : a ∈ l) : l ≠ [] := by
 #align list.ne_nil_of_mem List.ne_nil_of_mem
 -/
 
-#print List.mem_split /-
-theorem mem_split {a : α} {l : List α} (h : a ∈ l) : ∃ s t : List α, l = s ++ a :: t :=
+#print List.append_of_mem /-
+theorem append_of_mem {a : α} {l : List α} (h : a ∈ l) : ∃ s t : List α, l = s ++ a :: t :=
   by
   induction' l with b l ih; · cases h; rcases h with (rfl | h)
   · exact ⟨[], l, rfl⟩
   · rcases ih h with ⟨s, t, rfl⟩
     exact ⟨b :: s, t, rfl⟩
-#align list.mem_split List.mem_split
+#align list.mem_split List.append_of_mem
 -/
 
 #print List.mem_of_ne_of_mem /-
@@ -941,7 +941,7 @@ theorem replicate_left_inj {a : α} {n m : ℕ} : replicate n a = replicate m a
 
 #print List.mem_pure /-
 @[simp]
-theorem mem_pure {α} (x y : α) : x ∈ (pure y : List α) ↔ x = y := by simp! [pure, List.ret]
+theorem mem_pure {α} (x y : α) : x ∈ (pure y : List α) ↔ x = y := by simp! [pure, List.pure]
 #align list.mem_pure List.mem_pure
 -/
 
@@ -1819,7 +1819,7 @@ theorem Sublist.subset : ∀ {l₁ l₂ : List α}, l₁ <+ l₂ → l₁ ⊆ l
 @[simp]
 theorem singleton_sublist {a : α} {l} : [a] <+ l ↔ a ∈ l :=
   ⟨fun h => h.Subset (mem_singleton_self _), fun h =>
-    let ⟨s, t, e⟩ := mem_split h
+    let ⟨s, t, e⟩ := append_of_mem h
     e.symm ▸ ((nil_sublist _).cons_cons _).trans (sublist_append_right _ _)⟩
 #align list.singleton_sublist List.singleton_sublist
 -/
@@ -2856,13 +2856,13 @@ theorem map_join (f : α → β) (L : List (List α)) : map f (join L) = join (m
 #align list.map_join List.map_join
 -/
 
-#print List.bind_ret_eq_map /-
-theorem bind_ret_eq_map (f : α → β) (l : List α) : l.bind (List.ret ∘ f) = map f l := by
+#print List.bind_pure_eq_map /-
+theorem bind_pure_eq_map (f : α → β) (l : List α) : l.bind (List.pure ∘ f) = map f l := by
   unfold List.bind <;> induction l <;>
-        simp only [map, join, List.ret, cons_append, nil_append, *] <;>
+        simp only [map, join, List.pure, cons_append, nil_append, *] <;>
       constructor <;>
     rfl
-#align list.bind_ret_eq_map List.bind_ret_eq_map
+#align list.bind_ret_eq_map List.bind_pure_eq_map
 -/
 
 #print List.bind_congr /-
Diff
@@ -162,7 +162,7 @@ theorem not_mem_append {a : α} {s t : List α} (h₁ : a ∉ s) (h₂ : a ∉ t
 
 #print List.ne_nil_of_mem /-
 theorem ne_nil_of_mem {a : α} {l : List α} (h : a ∈ l) : l ≠ [] := by
-  intro e <;> rw [e] at h  <;> cases h
+  intro e <;> rw [e] at h <;> cases h
 #align list.ne_nil_of_mem List.ne_nil_of_mem
 -/
 
@@ -731,7 +731,7 @@ theorem append_inj' {s₁ s₂ t₁ t₂ : List α} (h : s₁ ++ t₁ = s₂ ++
     @Nat.add_right_cancel _ (length t₁) _ <|
       by
       let hap := congr_arg length h
-      simp only [length_append] at hap  <;> rwa [← hl] at hap 
+      simp only [length_append] at hap <;> rwa [← hl] at hap
 #align list.append_inj' List.append_inj'ₓ
 
 theorem append_inj_right' {s₁ s₂ t₁ t₂ : List α} (h : s₁ ++ t₁ = s₂ ++ t₂)
@@ -785,7 +785,7 @@ theorem map_eq_append_split {f : α → β} {l : List α} {s₁ s₂ : List β}
     ∃ l₁ l₂, l = l₁ ++ l₂ ∧ map f l₁ = s₁ ∧ map f l₂ = s₂ :=
   by
   have := h; rw [← take_append_drop (length s₁) l] at this ⊢
-  rw [map_append] at this 
+  rw [map_append] at this
   refine' ⟨_, _, rfl, append_inj this _⟩
   rw [length_map, length_take, min_eq_left]
   rw [← length_map f l, h, length_append]
@@ -1017,7 +1017,7 @@ theorem concat_eq_append' (a : α) (l : List α) : concat l a = l ++ [a] := by
 theorem init_eq_of_concat_eq {a : α} {l₁ l₂ : List α} : concat l₁ a = concat l₂ a → l₁ = l₂ :=
   by
   intro h
-  rw [concat_eq_append, concat_eq_append] at h 
+  rw [concat_eq_append, concat_eq_append] at h
   exact append_right_cancel h
 #align list.init_eq_of_concat_eq List.init_eq_of_concat_eq
 -/
@@ -1026,7 +1026,7 @@ theorem init_eq_of_concat_eq {a : α} {l₁ l₂ : List α} : concat l₁ a = co
 theorem last_eq_of_concat_eq {a b : α} {l : List α} : concat l a = concat l b → a = b :=
   by
   intro h
-  rw [concat_eq_append, concat_eq_append] at h 
+  rw [concat_eq_append, concat_eq_append] at h
   exact head_eq_of_cons_eq (append_left_cancel h)
 #align list.last_eq_of_concat_eq List.last_eq_of_concat_eq
 -/
@@ -1344,7 +1344,7 @@ theorem mem_getLast?_eq_getLast : ∀ {l : List α} {x : α}, x ∈ l.getLast? 
     have : a = x := by simpa using hx
     this ▸ ⟨cons_ne_nil a [], rfl⟩
   | a :: b :: l, x, hx => by
-    rw [last'] at hx 
+    rw [last'] at hx
     rcases mem_last'_eq_last hx with ⟨h₁, h₂⟩
     use cons_ne_nil _ _
     rwa [last_cons]
@@ -1377,7 +1377,7 @@ theorem mem_of_mem_getLast? {l : List α} {a : α} (ha : a ∈ l.getLast?) : a 
 theorem dropLast_append_getLast? : ∀ {l : List α}, ∀ a ∈ l.getLast?, dropLast l ++ [a] = l
   | [], a, ha => (Option.not_mem_none a ha).elim
   | [a], _, rfl => rfl
-  | a :: b :: l, c, hc => by rw [last'] at hc ; rw [init, cons_append, init_append_last' _ hc]
+  | a :: b :: l, c, hc => by rw [last'] at hc; rw [init, cons_append, init_append_last' _ hc]
 #align list.init_append_last' List.dropLast_append_getLast?
 -/
 
@@ -1451,7 +1451,7 @@ theorem surjective_tail : Surjective (@tail α)
 #print List.eq_cons_of_mem_head? /-
 theorem eq_cons_of_mem_head? {x : α} : ∀ {l : List α}, x ∈ l.head? → l = x :: tail l
   | [], h => (Option.not_mem_none _ h).elim
-  | a :: l, h => by simp only [head', Option.mem_def] at h ; exact h ▸ rfl
+  | a :: l, h => by simp only [head', Option.mem_def] at h; exact h ▸ rfl
 #align list.eq_cons_of_mem_head' List.eq_cons_of_mem_head?
 -/
 
@@ -1512,7 +1512,7 @@ theorem tail_append_singleton_of_ne_nil {a : α} {l : List α} (h : l ≠ nil) :
 #print List.cons_head?_tail /-
 theorem cons_head?_tail : ∀ {l : List α} {a : α} (h : a ∈ head? l), a :: tail l = l
   | [], a, h => by contradiction
-  | b :: l, a, h => by simp at h ; simp [h]
+  | b :: l, a, h => by simp at h; simp [h]
 #align list.cons_head'_tail List.cons_head?_tail
 -/
 
@@ -1533,7 +1533,7 @@ theorem cons_head!_tail [Inhabited α] {l : List α} (h : l ≠ []) : headI l ::
 theorem head!_mem_self [Inhabited α] {l : List α} (h : l ≠ nil) : l.headI ∈ l :=
   by
   have h' := mem_cons_self l.head l.tail
-  rwa [cons_head_tail h] at h' 
+  rwa [cons_head_tail h] at h'
 #align list.head_mem_self List.head!_mem_self
 -/
 
@@ -1580,7 +1580,7 @@ theorem nthLe_cons {l : List α} {a : α} {n} (hl) :
   split_ifs
   · simp [nth_le, h]
   cases l
-  · rw [length_singleton, lt_succ_iff, nonpos_iff_eq_zero] at hl ; contradiction
+  · rw [length_singleton, lt_succ_iff, nonpos_iff_eq_zero] at hl; contradiction
   cases n
   · contradiction
   rfl
@@ -1861,7 +1861,7 @@ theorem Sublist.eq_of_length : ∀ {l₁ l₂ : List α}, l₁ <+ l₂ → lengt
   | _, _, sublist.cons l₁ l₂ a s, h => by
     cases s.length_le.not_lt (by rw [h] <;> apply lt_succ_self)
   | _, _, sublist.cons2 l₁ l₂ a s, h => by
-    rw [length, length] at h  <;> injection h with h <;> rw [s.eq_of_length h]
+    rw [length, length] at h <;> injection h with h <;> rw [s.eq_of_length h]
 #align list.sublist.eq_of_length List.Sublist.eq_of_length
 -/
 
@@ -2030,8 +2030,8 @@ theorem get?_length (l : List α) : l.get? l.length = none :=
 #print List.get?_eq_some' /-
 theorem get?_eq_some' {l : List α} {n a} : get? l n = some a ↔ ∃ h, nthLe l n h = a :=
   ⟨fun e =>
-    have h : n < length l := lt_of_not_ge fun hn => by rw [nth_len_le hn] at e  <;> contradiction
-    ⟨h, by rw [nth_le_nth h] at e  <;> injection e with e <;> apply nth_le_mem⟩,
+    have h : n < length l := lt_of_not_ge fun hn => by rw [nth_len_le hn] at e <;> contradiction
+    ⟨h, by rw [nth_le_nth h] at e <;> injection e with e <;> apply nth_le_mem⟩,
     fun ⟨h, e⟩ => e ▸ nthLe_get? _⟩
 #align list.nth_eq_some List.get?_eq_some'
 -/
@@ -2043,7 +2043,7 @@ theorem get?_eq_none : ∀ {l : List α} {n}, get? l n = none ↔ length l ≤ n
   intros; constructor
   · intro h; by_contra h'
     have h₂ : ∃ h, l.nth_le n h = l.nth_le n (lt_of_not_ge h') := ⟨lt_of_not_ge h', rfl⟩
-    rw [← nth_eq_some, h] at h₂ ; cases h₂
+    rw [← nth_eq_some, h] at h₂; cases h₂
   · solve_by_elim [nth_len_le]
 #align list.nth_eq_none_iff List.get?_eq_none
 -/
@@ -2098,7 +2098,7 @@ theorem get?_injective {α : Type u} {xs : List α} {i j : ℕ} (h₀ : i < xs.l
       congr; cases h₁
       apply xs_ih <;> solve_by_elim [lt_of_succ_lt_succ]
     iterate 2 
-      dsimp at h₂ 
+      dsimp at h₂
       cases' h₁ with _ _ h h'
       cases h x _ rfl
       rw [mem_iff_nth]
@@ -2176,7 +2176,7 @@ theorem nthLe_append :
 theorem get_append_right_aux {l₁ l₂ : List α} {n : ℕ} (h₁ : l₁.length ≤ n)
     (h₂ : n < (l₁ ++ l₂).length) : n - l₁.length < l₂.length :=
   by
-  rw [List.length_append] at h₂ 
+  rw [List.length_append] at h₂
   apply lt_of_add_lt_add_right
   rwa [Nat.sub_add_cancel h₁, Nat.add_comm]
 #align list.nth_le_append_right_aux List.get_append_right_aux
@@ -2222,7 +2222,7 @@ theorem get?_append_right {l₁ l₂ : List α} {n : ℕ} (hn : l₁.length ≤
   by_cases hl : n < (l₁ ++ l₂).length
   · rw [nth_le_nth hl, nth_le_nth, nth_le_append_right hn]
   · rw [nth_len_le (le_of_not_lt hl), nth_len_le]
-    rw [not_lt, length_append] at hl 
+    rw [not_lt, length_append] at hl
     exact le_tsub_of_add_le_left hl
 #align list.nth_append_right List.get?_append_right
 -/
@@ -2271,8 +2271,8 @@ theorem take_one_drop_eq_of_lt_length' {l : List α} {n : ℕ} (h : n < l.length
   induction' l with x l ih generalizing n
   · cases h
   · by_cases h₁ : l = []
-    · subst h₁; rw [nth_le_singleton]; simp [lt_succ_iff] at h ; subst h; simp
-    have h₂ := h; rw [length_cons, Nat.lt_succ_iff, le_iff_eq_or_lt] at h₂ 
+    · subst h₁; rw [nth_le_singleton]; simp [lt_succ_iff] at h; subst h; simp
+    have h₂ := h; rw [length_cons, Nat.lt_succ_iff, le_iff_eq_or_lt] at h₂
     cases n; · simp; rw [drop, nth_le]; apply ih
 #align list.take_one_drop_eq_of_lt_length List.take_one_drop_eq_of_lt_length'
 -/
@@ -2348,7 +2348,7 @@ theorem get_reverse_aux₂ :
   | [], r, i, h1, h2 => absurd h2 (Nat.not_lt_zero _)
   | a :: l, r, 0, h1, h2 => by
     have aux := nth_le_reverse_aux1 l (a :: r) 0
-    rw [zero_add] at aux 
+    rw [zero_add] at aux
     exact aux _ (zero_lt_succ _)
   | a :: l, r, i + 1, h1, h2 =>
     by
@@ -2357,7 +2357,7 @@ theorem get_reverse_aux₂ :
       calc
         length (a :: l) - 1 - (i + 1) = length l - (1 + i) := by rw [add_comm] <;> rfl
         _ = length l - 1 - i := by rw [← tsub_add_eq_tsub_tsub]
-    rw [← HEq] at aux 
+    rw [← HEq] at aux
     apply aux
 #align list.nth_le_reverse_aux2 List.get_reverse_aux₂
 -/
@@ -2688,7 +2688,7 @@ theorem insertNth_of_length_lt (l : List α) (x : α) (n : ℕ) (h : l.length <
     · simp
   · cases n
     · simpa using h
-    · simp only [Nat.succ_lt_succ_iff, length] at h 
+    · simp only [Nat.succ_lt_succ_iff, length] at h
       simpa using IH _ h
 #align list.insert_nth_of_length_lt List.insertNth_of_length_lt
 -/
@@ -2736,7 +2736,7 @@ theorem nthLe_insertNth_of_lt (l : List α) (x : α) (n k : ℕ) (hn : k < n) (h
     · simp
     · cases k
       · simp
-      · rw [Nat.succ_lt_succ_iff] at hn 
+      · rw [Nat.succ_lt_succ_iff] at hn
         simpa using IH _ _ hn _
 #align list.nth_le_insert_nth_of_lt List.nthLe_insertNth_of_lt
 -/
@@ -2748,11 +2748,11 @@ theorem nthLe_insertNth_self (l : List α) (x : α) (n : ℕ) (hn : n ≤ l.leng
     (insertNth n x l).nthLe n hn' = x :=
   by
   induction' l with hd tl IH generalizing n
-  · simp only [length, nonpos_iff_eq_zero] at hn 
+  · simp only [length, nonpos_iff_eq_zero] at hn
     simp [hn]
   · cases n
     · simp
-    · simp only [Nat.succ_le_succ_iff, length] at hn 
+    · simp only [Nat.succ_le_succ_iff, length] at hn
       simpa using IH _ hn
 #align list.nth_le_insert_nth_self List.nthLe_insertNth_self
 -/
@@ -2816,7 +2816,7 @@ theorem map_congr {f g : α → β} : ∀ {l : List α}, (∀ x ∈ l, f x = g x
 theorem map_eq_map_iff {f g : α → β} {l : List α} : map f l = map g l ↔ ∀ x ∈ l, f x = g x :=
   by
   refine' ⟨_, map_congr⟩; intro h x hx
-  rw [mem_iff_nth_le] at hx ; rcases hx with ⟨n, hn, rfl⟩
+  rw [mem_iff_nth_le] at hx; rcases hx with ⟨n, hn, rfl⟩
   rw [nth_le_map_rev f, nth_le_map_rev g]; congr; exact h
 #align list.map_eq_map_iff List.map_eq_map_iff
 -/
@@ -2892,7 +2892,7 @@ theorem map_injective_iff {f : α → β} : Injective (map f) ↔ Injective f :=
   constructor <;> intro h x y hxy
   · suffices [x] = [y] by simpa using this; apply h; simp [hxy]
   · induction y generalizing x; simpa using hxy
-    cases x; simpa using hxy; simp at hxy ; simp [y_ih hxy.2, h hxy.1]
+    cases x; simpa using hxy; simp at hxy; simp [y_ih hxy.2, h hxy.1]
 #align list.map_injective_iff List.map_injective_iff
 -/
 
@@ -2957,7 +2957,7 @@ theorem map_const' (l : List α) (b : β) : map (fun _ => b) l = replicate l.len
 
 #print List.eq_of_mem_map_const /-
 theorem eq_of_mem_map_const {b₁ b₂ : β} {l : List α} (h : b₁ ∈ map (const α b₂) l) : b₁ = b₂ := by
-  rw [map_const] at h  <;> exact eq_of_mem_replicate h
+  rw [map_const] at h <;> exact eq_of_mem_replicate h
 #align list.eq_of_mem_map_const List.eq_of_mem_map_const
 -/
 
@@ -3106,7 +3106,7 @@ theorem nthLe_take (L : List α) {i j : ℕ} (hi : i < L.length) (hj : i < j) :
 /-- The `i`-th element of a list coincides with the `i`-th element of any of its prefixes of
 length `> i`. Version designed to rewrite from the small list to the big list. -/
 theorem nthLe_take' (L : List α) {i j : ℕ} (hi : i < (L.take j).length) :
-    nthLe (L.take j) i hi = nthLe L i (lt_of_lt_of_le hi (by simp [le_refl])) := by simp at hi ;
+    nthLe (L.take j) i hi = nthLe L i (lt_of_lt_of_le hi (by simp [le_refl])) := by simp at hi;
   rw [nth_le_take L _ hi.1]
 #align list.nth_le_take' List.nthLe_take'
 -/
@@ -3115,7 +3115,7 @@ theorem nthLe_take' (L : List α) {i j : ℕ} (hi : i < (L.take j).length) :
 theorem get?_take {l : List α} {n m : ℕ} (h : m < n) : (l.take n).get? m = l.get? m :=
   by
   induction' n with n hn generalizing l m
-  · simp only [Nat.zero_eq] at h 
+  · simp only [Nat.zero_eq] at h
     exact absurd h (not_lt_of_le m.zero_le)
   · cases' l with hd tl
     · simp only [take_nil]
@@ -3173,7 +3173,7 @@ theorem take_add (l : List α) (m n : ℕ) : l.take (m + n) = l.take m ++ (l.dro
   simp only [take_eq_take, length_take, length_drop]
   generalize l.length = k; by_cases h : m ≤ k
   · simp [min_eq_left_iff.mpr h]
-  · push_neg at h ; simp [Nat.sub_eq_zero_of_le (le_of_lt h)]
+  · push_neg at h; simp [Nat.sub_eq_zero_of_le (le_of_lt h)]
 #align list.take_add List.take_add
 -/
 
@@ -3225,11 +3225,11 @@ theorem drop_eq_nil_iff_le {l : List α} {k : ℕ} : l.drop k = [] ↔ l.length
   by
   refine' ⟨fun h => _, drop_eq_nil_of_le⟩
   induction' k with k hk generalizing l
-  · simp only [drop] at h 
+  · simp only [drop] at h
     simp [h]
   · cases l
     · simp
-    · simp only [drop] at h 
+    · simp only [drop] at h
       simpa [Nat.succ_le_succ_iff] using hk h
 #align list.drop_eq_nil_iff_le List.drop_eq_nil_iff_le
 -/
@@ -3253,7 +3253,7 @@ theorem cons_nthLe_drop_succ {l : List α} {n : ℕ} (hn : n < l.length) :
   · exact absurd n.zero_le (not_le_of_lt (by simpa using hn))
   · cases n
     · simp
-    · simp only [Nat.succ_lt_succ_iff, List.length] at hn 
+    · simp only [Nat.succ_lt_succ_iff, List.length] at hn
       simpa [List.nthLe, List.drop] using hl hn
 #align list.cons_nth_le_drop_succ List.cons_nthLe_drop_succ
 -/
@@ -3364,7 +3364,7 @@ theorem nthLe_drop (L : List α) {i j : ℕ} (h : i + j < L.length) :
       nthLe (L.drop i) j
         (by
           have A : i < L.length := lt_of_le_of_lt (Nat.le.intro rfl) h
-          rw [(take_append_drop i L).symm] at h 
+          rw [(take_append_drop i L).symm] at h
           simpa only [le_of_lt A, min_eq_left, add_lt_add_iff_left, length_take,
             length_append] using h) :=
   by
@@ -3538,7 +3538,7 @@ theorem foldl_ext (f g : α → β → α) (a : α) {l : List β} (H : ∀ a : 
 theorem foldr_ext (f g : α → β → β) (b : β) {l : List α} (H : ∀ a ∈ l, ∀ b : β, f a b = g a b) :
     foldr f b l = foldr g b l := by
   induction' l with hd tl ih; · rfl
-  simp only [mem_cons_iff, or_imp, forall_and, forall_eq] at H 
+  simp only [mem_cons_iff, or_imp, forall_and, forall_eq] at H
   simp only [foldr, ih H.2, H.1]
 #align list.foldr_ext List.foldr_ext
 -/
@@ -3649,7 +3649,7 @@ theorem foldr_reverse (f : α → β → β) (a : β) (l : List α) :
     foldr f a (reverse l) = foldl (fun x y => f y x) a l :=
   by
   let t := foldl_reverse (fun x y => f y x) a (reverse l)
-  rw [reverse_reverse l] at t  <;> rwa [t]
+  rw [reverse_reverse l] at t <;> rwa [t]
 #align list.foldr_reverse List.foldr_reverse
 -/
 
@@ -3878,11 +3878,11 @@ theorem nthLe_succ_scanl {i : ℕ} {h : i + 1 < (scanl f b l).length} :
   by
   induction' i with i hi generalizing b l
   · cases l
-    · simp only [length, zero_add, scanl_nil] at h 
+    · simp only [length, zero_add, scanl_nil] at h
       exact absurd h (lt_irrefl 1)
     · simp only [scanl_cons, singleton_append, nth_le_zero_scanl, nth_le]
   · cases l
-    · simp only [length, add_lt_iff_neg_right, scanl_nil] at h 
+    · simp only [length, add_lt_iff_neg_right, scanl_nil] at h
       exact absurd h (not_lt_of_lt Nat.succ_pos')
     · simp_rw [scanl_cons]
       rw [nth_le_append_right _]
@@ -4238,7 +4238,7 @@ theorem intercalate_splitOn (x : α) [DecidableEq α] : [x].intercalate (xs.spli
   simp only [intercalate, split_on]
   induction' xs with hd tl ih; · simp [join]; simp only [split_on_p_cons]
   cases' h' : split_on_p (· = x) tl with hd' tl'; · exact (split_on_p_ne_nil _ tl h').elim
-  rw [h'] at ih ; split_ifs; · subst h; simp [ih, join]
+  rw [h'] at ih; split_ifs; · subst h; simp [ih, join]
   cases tl' <;> simpa [join] using ih
 #align list.intercalate_split_on List.intercalate_splitOn
 -/
@@ -4253,13 +4253,13 @@ theorem splitOn_intercalate [DecidableEq α] (x : α) (hx : ∀ l ∈ ls, x ∉
   induction' ls with hd tl ih; · contradiction
   cases tl
   · suffices hd.split_on x = [hd] by simpa [join]
-    refine' split_on_p_eq_single _ _ _; intro y hy H; rw [H] at hy 
+    refine' split_on_p_eq_single _ _ _; intro y hy H; rw [H] at hy
     refine' hx hd _ hy; simp
   · simp only [intersperse_cons_cons, singleton_append, join]
     specialize ih _ _; · intro l hl; apply hx l; simp at hl ⊢; tauto; · trivial
     have := split_on_p_first (· = x) hd _ x rfl _
     · simp only [split_on] at ih ⊢; rw [this]; rw [ih]
-    intro y hy H; rw [H] at hy ; exact hx hd (Or.inl rfl) hy
+    intro y hy H; rw [H] at hy; exact hx hd (Or.inl rfl) hy
 #align list.split_on_intercalate List.splitOn_intercalate
 -/
 
@@ -4449,7 +4449,7 @@ theorem nthLe_pmap {p : α → Prop} (f : ∀ a, p a → β) {l : List α} (h :
         (h _ (nthLe_mem l n (@length_pmap _ _ p f l h ▸ hn))) :=
   by
   induction' l with hd tl hl generalizing n
-  · simp only [length, pmap] at hn 
+  · simp only [length, pmap] at hn
     exact absurd hn (not_lt_of_le n.zero_le)
   · cases n
     · simp
@@ -4525,8 +4525,8 @@ theorem find?_some (H : find? p l = some a) : p a :=
   by
   induction' l with b l IH; · contradiction
   by_cases h : p b
-  · rw [find_cons_of_pos _ h] at H ; cases H; exact h
-  · rw [find_cons_of_neg _ h] at H ; exact IH H
+  · rw [find_cons_of_pos _ h] at H; cases H; exact h
+  · rw [find_cons_of_neg _ h] at H; exact IH H
 #align list.find_some List.find?_some
 -/
 
@@ -4536,8 +4536,8 @@ theorem find?_mem (H : find? p l = some a) : a ∈ l :=
   by
   induction' l with b l IH; · contradiction
   by_cases h : p b
-  · rw [find_cons_of_pos _ h] at H ; cases H; apply mem_cons_self
-  · rw [find_cons_of_neg _ h] at H ; exact mem_cons_of_mem _ (IH H)
+  · rw [find_cons_of_pos _ h] at H; cases H; apply mem_cons_self
+  · rw [find_cons_of_neg _ h] at H; exact mem_cons_of_mem _ (IH H)
 #align list.find_mem List.find?_mem
 -/
 
@@ -4773,7 +4773,7 @@ theorem mem_filterMap (f : α → Option β) (l : List α) {b : β} :
   · have : f a ≠ some b := by rw [h]; intro; contradiction
     simp only [filter_map_cons_none _ _ h, IH, mem_cons_iff, or_and_right, exists_or,
       exists_eq_left, this, false_or_iff]
-  · have : f a = some b ↔ b = b' := by constructor <;> intro t; · rw [t] at h  <;> injection h;
+  · have : f a = some b ↔ b = b' := by constructor <;> intro t; · rw [t] at h <;> injection h;
       · exact t.symm ▸ h
     simp only [filter_map_cons_some _ _ _ h, IH, mem_cons_iff, or_and_right, exists_or, this,
       exists_eq_left]
@@ -4895,7 +4895,7 @@ theorem reduceOption_length_eq_iff {l : List (Option α)} :
         reduce_option_cons_of_none, length, Option.isSome_none, iff_false_iff]
       intro H
       have := reduce_option_length_le tl
-      rw [H] at this 
+      rw [H] at this
       exact absurd (Nat.lt_succ_self _) (not_lt_of_le this)
     ·
       simp only [hl, true_and_iff, mem_cons_iff, forall_eq_or_imp, add_left_inj, Bool.coeSort_true,
@@ -4924,7 +4924,7 @@ theorem reduceOption_concat (l : List (Option α)) (x : Option α) :
   by
   induction' l with hd tl hl generalizing x
   · cases x <;> simp [Option.toList]
-  · simp only [concat_eq_append, reduce_option_append] at hl 
+  · simp only [concat_eq_append, reduce_option_append] at hl
     cases hd <;> simp [hl, reduce_option_append]
 #align list.reduce_option_concat List.reduceOption_concat
 -/
@@ -4974,7 +4974,7 @@ theorem filter_congr' {p q : α → Prop} [DecidablePred p] [DecidablePred q] :
     ∀ {l : List α}, (∀ x ∈ l, p x ↔ q x) → filter p l = filter q l
   | [], _ => rfl
   | a :: l, h => by
-    rw [forall_mem_cons] at h  <;> by_cases pa : p a <;>
+    rw [forall_mem_cons] at h <;> by_cases pa : p a <;>
           [simp only [filter_cons_of_pos _ pa, filter_cons_of_pos _ (h.1.1 pa), filter_congr' h.2];
           simp only [filter_cons_of_neg _ pa, filter_cons_of_neg _ (mt h.1.2 pa),
             filter_congr' h.2]] <;>
@@ -4995,9 +4995,9 @@ theorem of_mem_filter {a : α} : ∀ {l}, a ∈ filter p l → p a
   | b :: l, ain =>
     if pb : p b then
       have : a ∈ b :: filter p l := by simpa only [filter_cons_of_pos _ pb] using ain
-      Or.elim (eq_or_mem_of_mem_cons this) (fun this : a = b => by rw [← this] at pb ; exact pb)
+      Or.elim (eq_or_mem_of_mem_cons this) (fun this : a = b => by rw [← this] at pb; exact pb)
         fun this : a ∈ filter p l => of_mem_filter this
-    else by simp only [filter_cons_of_neg _ pb] at ain ; exact of_mem_filter ain
+    else by simp only [filter_cons_of_neg _ pb] at ain; exact of_mem_filter ain
 #align list.of_mem_filter List.of_mem_filter
 -/
 
@@ -5225,9 +5225,9 @@ theorem mem_takeWhile_imp {x : α} (hx : x ∈ takeWhile p l) : p x :=
   by
   induction' l with hd tl IH
   · simpa [take_while] using hx
-  · simp only [take_while] at hx 
-    split_ifs at hx 
-    · rw [mem_cons_iff] at hx 
+  · simp only [take_while] at hx
+    split_ifs at hx
+    · rw [mem_cons_iff] at hx
       rcases hx with (rfl | hx)
       · exact h
       · exact IH hx
@@ -5302,7 +5302,7 @@ theorem exists_or_eq_self_of_eraseP (p : α → Prop) [DecidablePred p] (l : Lis
   by_cases h : ∃ a ∈ l, p a
   · rcases h with ⟨a, ha, pa⟩
     exact Or.inr (exists_of_erasep ha pa)
-  · simp at h ; exact Or.inl (erasep_of_forall_not h)
+  · simp at h; exact Or.inl (erasep_of_forall_not h)
 #align list.exists_or_eq_self_of_erasep List.exists_or_eq_self_of_erasePₓ
 
 @[simp]
@@ -5367,7 +5367,7 @@ theorem mem_eraseP_of_neg {a : α} {l : List α} (pa : ¬p a) : a ∈ l.eraseP
     by
     rcases exists_or_eq_self_of_erasep p l with (h | ⟨c, l₁, l₂, h₁, h₂, h₃, h₄⟩)
     · rwa [h]
-    · rw [h₄]; rw [h₃] at al 
+    · rw [h₄]; rw [h₃] at al
       have : a ≠ c := by rintro rfl; exact pa.elim h₂
       simpa [this] using al⟩
 #align list.mem_erasep_of_neg List.mem_eraseP_of_negₓ
@@ -6033,8 +6033,8 @@ theorem map₂Left_eq_zipWith :
     ∀ as bs, length as ≤ length bs → map₂Left f as bs = zipWith (fun a b => f a (some b)) as bs
   | [], [], h => by simp!
   | [], b :: bs, h => by simp!
-  | a :: as, [], h => by simp at h ; contradiction
-  | a :: as, b :: bs, h => by simp at h ; simp! [*]
+  | a :: as, [], h => by simp at h; contradiction
+  | a :: as, b :: bs, h => by simp at h; simp! [*]
 #align list.map₂_left_eq_map₂ List.map₂Left_eq_zipWith
 -/
 
@@ -6214,7 +6214,7 @@ theorem toChunksAux_join {n} : ∀ {xs i l L}, @toChunksAux α n xs i = (l, L) 
   | x :: xs, i, l, L, e => by
     cases i <;> [cases' e' : to_chunks_aux n xs n with l L;
         cases' e' : to_chunks_aux n xs i with l L] <;>
-      · rw [to_chunks_aux, e', to_chunks_aux] at e ; cases e
+      · rw [to_chunks_aux, e', to_chunks_aux] at e; cases e
         exact (congr_arg (cons x) (to_chunks_aux_join e') : _)
 #align list.to_chunks_aux_join List.toChunksAux_join
 
@@ -6233,7 +6233,7 @@ theorem toChunks_length_le : ∀ n xs, n ≠ 0 → ∀ l : List α, l ∈ @toChu
   | n + 1, xs, _, l => by
     refine' (measure_wf length).induction xs _; intro xs IH h
     by_cases x0 : xs = []; · subst xs; cases h
-    rw [to_chunks_eq_cons' _ x0] at h ; rcases h with (rfl | h)
+    rw [to_chunks_eq_cons' _ x0] at h; rcases h with (rfl | h)
     · apply length_take_le
     · refine' IH _ _ h
       simp only [Measure, InvImage, length_drop]
Diff
@@ -46,7 +46,7 @@ instance : Std.LawfulLeftIdentity (List α) Append.append [] :=
 instance : Std.LawfulRightIdentity (List α) Append.append [] :=
   ⟨append_nil⟩
 
-instance : IsAssociative (List α) Append.append :=
+instance : Std.Associative (List α) Append.append :=
   ⟨append_assoc⟩
 
 #print List.cons_ne_nil /-
@@ -3988,7 +3988,7 @@ end FoldlEqFoldlr'
 
 section
 
-variable {op : α → α → α} [ha : IsAssociative α op] [hc : IsCommutative α op]
+variable {op : α → α → α} [ha : Std.Associative α op] [hc : Std.Commutative α op]
 
 local notation a " * " b => op a b
 
Diff
@@ -40,10 +40,10 @@ instance uniqueOfIsEmpty [IsEmpty α] : Unique (List α) :=
 #align list.unique_of_is_empty List.uniqueOfIsEmpty
 -/
 
-instance : IsLeftId (List α) Append.append [] :=
+instance : Std.LawfulLeftIdentity (List α) Append.append [] :=
   ⟨nil_append⟩
 
-instance : IsRightId (List α) Append.append [] :=
+instance : Std.LawfulRightIdentity (List α) Append.append [] :=
   ⟨append_nil⟩
 
 instance : IsAssociative (List α) Append.append :=
@@ -1612,7 +1612,7 @@ def reverseRecOn {C : List α → Sort _} (l : List α) (H0 : C [])
 #align list.reverse_rec_on List.reverseRecOn
 -/
 
-/- ./././Mathport/Syntax/Translate/Command.lean:298:8: warning: using_well_founded used, estimated equivalent -/
+/- ./././Mathport/Syntax/Translate/Command.lean:299:8: warning: using_well_founded used, estimated equivalent -/
 /-- Bidirectional induction principle for lists: if a property holds for the empty list, the
 singleton list, and `a :: (l ++ [b])` from `l`, then it holds for all lists. This can be used to
 prove statements about palindromes. The principle is given for a `Sort`-valued predicate, i.e., it
@@ -1628,8 +1628,7 @@ def bidirectionalRec {C : List α → Sort _} (H0 : C []) (H1 : ∀ a : α, C [a
     rw [← init_append_last (cons_ne_nil b l)]
     have : C l' := bidirectional_rec l'
     exact Hn a l' b' ‹C l'›
-termination_by
-  _ x => WellFounded.wrap (measure_wf List.length) x
+termination_by x => WellFounded.wrap (measure_wf List.length) x
 #align list.bidirectional_rec List.bidirectionalRecₓ
 
 #print List.bidirectionalRecOn /-
Diff
@@ -150,7 +150,7 @@ theorem Decidable.List.eq_or_ne_mem_of_mem [DecidableEq α] {a b : α} {l : List
 
 #print List.eq_or_ne_mem_of_mem /-
 theorem eq_or_ne_mem_of_mem {a b : α} {l : List α} : a ∈ b :: l → a = b ∨ a ≠ b ∧ a ∈ l := by
-  classical
+  classical exact Decidable.List.eq_or_ne_mem_of_mem
 #align list.eq_or_ne_mem_of_mem List.eq_or_ne_mem_of_mem
 -/
 
@@ -5106,7 +5106,10 @@ theorem filter_attach' (l : List α) (p : { a // a ∈ l } → Prop) [DecidableE
         (Subtype.map id fun x hx =>
           let ⟨h, _⟩ := of_mem_filter hx
           h) :=
-  by classical
+  by
+  classical
+  refine' map_injective_iff.2 Subtype.coe_injective _
+  simp [(· ∘ ·), map_filter' _ Subtype.coe_injective]
 #align list.filter_attach' List.filter_attach'
 -/
 
Diff
@@ -150,7 +150,7 @@ theorem Decidable.List.eq_or_ne_mem_of_mem [DecidableEq α] {a b : α} {l : List
 
 #print List.eq_or_ne_mem_of_mem /-
 theorem eq_or_ne_mem_of_mem {a b : α} {l : List α} : a ∈ b :: l → a = b ∨ a ≠ b ∧ a ∈ l := by
-  classical exact Decidable.List.eq_or_ne_mem_of_mem
+  classical
 #align list.eq_or_ne_mem_of_mem List.eq_or_ne_mem_of_mem
 -/
 
@@ -5106,10 +5106,7 @@ theorem filter_attach' (l : List α) (p : { a // a ∈ l } → Prop) [DecidableE
         (Subtype.map id fun x hx =>
           let ⟨h, _⟩ := of_mem_filter hx
           h) :=
-  by
-  classical
-  refine' map_injective_iff.2 Subtype.coe_injective _
-  simp [(· ∘ ·), map_filter' _ Subtype.coe_injective]
+  by classical
 #align list.filter_attach' List.filter_attach'
 -/
 
Diff
@@ -744,21 +744,21 @@ theorem append_inj_left' {s₁ s₂ t₁ t₂ : List α} (h : s₁ ++ t₁ = s
   (append_inj' h hl).left
 #align list.append_inj_left' List.append_inj_left'ₓ
 
-#print List.append_left_cancel /-
-theorem append_left_cancel {s t₁ t₂ : List α} (h : s ++ t₁ = s ++ t₂) : t₁ = t₂ :=
+#print List.append_cancel_left /-
+theorem append_cancel_left {s t₁ t₂ : List α} (h : s ++ t₁ = s ++ t₂) : t₁ = t₂ :=
   append_inj_right h rfl
-#align list.append_left_cancel List.append_left_cancel
+#align list.append_left_cancel List.append_cancel_left
 -/
 
-#print List.append_right_cancel /-
-theorem append_right_cancel {s₁ s₂ t : List α} (h : s₁ ++ t = s₂ ++ t) : s₁ = s₂ :=
+#print List.append_cancel_right /-
+theorem append_cancel_right {s₁ s₂ t : List α} (h : s₁ ++ t = s₂ ++ t) : s₁ = s₂ :=
   append_inj_left' h rfl
-#align list.append_right_cancel List.append_right_cancel
+#align list.append_right_cancel List.append_cancel_right
 -/
 
 #print List.append_right_injective /-
 theorem append_right_injective (s : List α) : Injective fun t => s ++ t := fun t₁ t₂ =>
-  append_left_cancel
+  append_cancel_left
 #align list.append_right_injective List.append_right_injective
 -/
 
@@ -770,7 +770,7 @@ theorem append_right_inj {t₁ t₂ : List α} (s) : s ++ t₁ = s ++ t₂ ↔ t
 
 #print List.append_left_injective /-
 theorem append_left_injective (t : List α) : Injective fun s => s ++ t := fun s₁ s₂ =>
-  append_right_cancel
+  append_cancel_right
 #align list.append_left_injective List.append_left_injective
 -/
 
Diff
@@ -1612,6 +1612,7 @@ def reverseRecOn {C : List α → Sort _} (l : List α) (H0 : C [])
 #align list.reverse_rec_on List.reverseRecOn
 -/
 
+/- ./././Mathport/Syntax/Translate/Command.lean:298:8: warning: using_well_founded used, estimated equivalent -/
 /-- Bidirectional induction principle for lists: if a property holds for the empty list, the
 singleton list, and `a :: (l ++ [b])` from `l`, then it holds for all lists. This can be used to
 prove statements about palindromes. The principle is given for a `Sort`-valued predicate, i.e., it
@@ -1627,7 +1628,8 @@ def bidirectionalRec {C : List α → Sort _} (H0 : C []) (H1 : ∀ a : α, C [a
     rw [← init_append_last (cons_ne_nil b l)]
     have : C l' := bidirectional_rec l'
     exact Hn a l' b' ‹C l'›
-termination_by' ⟨_, measure_wf List.length⟩
+termination_by
+  _ x => WellFounded.wrap (measure_wf List.length) x
 #align list.bidirectional_rec List.bidirectionalRecₓ
 
 #print List.bidirectionalRecOn /-
Diff
@@ -2829,17 +2829,17 @@ theorem map_concat (f : α → β) (a : α) (l : List α) : map f (concat l a) =
 #align list.map_concat List.map_concat
 -/
 
-#print List.map_id'' /-
+#print List.map_id' /-
 @[simp]
-theorem map_id'' (l : List α) : map (fun x => x) l = l :=
+theorem map_id' (l : List α) : map (fun x => x) l = l :=
   map_id _
-#align list.map_id'' List.map_id''
+#align list.map_id'' List.map_id'
 -/
 
-#print List.map_id' /-
-theorem map_id' {f : α → α} (h : ∀ x, f x = x) (l : List α) : map f l = l := by
+#print List.map_id'' /-
+theorem map_id'' {f : α → α} (h : ∀ x, f x = x) (l : List α) : map f l = l := by
   simp [show f = id from funext h]
-#align list.map_id' List.map_id'
+#align list.map_id' List.map_id''
 -/
 
 #print List.eq_nil_of_map_eq_nil /-
Diff
@@ -1154,11 +1154,11 @@ theorem reverse_eq_iff {l l' : List α} : l.reverse = l' ↔ l = l'.reverse :=
 #align list.reverse_eq_iff List.reverse_eq_iff
 -/
 
-#print List.reverse_eq_nil /-
+#print List.reverse_eq_nil_iff /-
 @[simp]
-theorem reverse_eq_nil {l : List α} : reverse l = [] ↔ l = [] :=
+theorem reverse_eq_nil_iff {l : List α} : reverse l = [] ↔ l = [] :=
   @reverse_inj _ l []
-#align list.reverse_eq_nil List.reverse_eq_nil
+#align list.reverse_eq_nil List.reverse_eq_nil_iff
 -/
 
 #print List.concat_eq_reverse_cons /-
Diff
@@ -5649,17 +5649,17 @@ end Diff
 /-! ### enum -/
 
 
-#print List.length_enumFrom /-
-theorem length_enumFrom : ∀ (n) (l : List α), length (enumFrom n l) = length l
+#print List.enumFrom_length /-
+theorem enumFrom_length : ∀ (n) (l : List α), length (enumFrom n l) = length l
   | n, [] => rfl
   | n, a :: l => congr_arg Nat.succ (length_enum_from _ _)
-#align list.length_enum_from List.length_enumFrom
+#align list.length_enum_from List.enumFrom_length
 -/
 
-#print List.length_enum /-
-theorem length_enum : ∀ l : List α, length (enum l) = length l :=
-  length_enumFrom _
-#align list.length_enum List.length_enum
+#print List.enum_length /-
+theorem enum_length : ∀ l : List α, length (enum l) = length l :=
+  enumFrom_length _
+#align list.length_enum List.enum_length
 -/
 
 #print List.enumFrom_get? /-
Diff
@@ -4287,10 +4287,12 @@ def attach (l : List α) : List { x // x ∈ l } :=
 #align list.attach List.attach
 -/
 
+#print List.attach_nil /-
 @[simp]
 theorem attach_nil : ([] : List α).attach = [] :=
   rfl
 #align list.attach_nil List.attach_nil
+-/
 
 #print List.sizeOf_lt_sizeOf_of_mem /-
 theorem sizeOf_lt_sizeOf_of_mem [SizeOf α] {x : α} {l : List α} (hx : x ∈ l) :
@@ -5087,12 +5089,15 @@ theorem map_filter (f : β → α) (l : List β) : filter p (map f l) = map f (f
 #align list.map_filter List.map_filter
 -/
 
+#print List.map_filter' /-
 theorem map_filter' {f : α → β} (hf : Injective f) (l : List α)
     [DecidablePred fun b => ∃ a, p a ∧ f a = b] :
     (l.filterₓ p).map f = (l.map f).filterₓ fun b => ∃ a, p a ∧ f a = b := by
   simp [(· ∘ ·), map_filter, hf.eq_iff]
 #align list.map_filter' List.map_filter'
+-/
 
+#print List.filter_attach' /-
 theorem filter_attach' (l : List α) (p : { a // a ∈ l } → Prop) [DecidableEq α] [DecidablePred p] :
     l.attach.filterₓ p =
       (l.filterₓ fun x => ∃ h, p ⟨x, h⟩).attach.map
@@ -5103,15 +5108,18 @@ theorem filter_attach' (l : List α) (p : { a // a ∈ l } → Prop) [DecidableE
   classical
   refine' map_injective_iff.2 Subtype.coe_injective _
   simp [(· ∘ ·), map_filter' _ Subtype.coe_injective]
-#align list.filter_attach' List.filterₓ_attach'
+#align list.filter_attach' List.filter_attach'
+-/
 
+#print List.filter_attach /-
 @[simp]
 theorem filter_attach (l : List α) (p : α → Prop) [DecidablePred p] :
     (l.attach.filterₓ fun x => p ↑x) =
       (l.filterₓ p).attach.map (Subtype.map id fun _ => mem_of_mem_filter) :=
   map_injective_iff.2 Subtype.coe_injective <| by
     simp_rw [map_map, (· ∘ ·), Subtype.map, Subtype.coe_mk, id.def, ← map_filter, attach_map_coe]
-#align list.filter_attach List.filterₓ_attach
+#align list.filter_attach List.filter_attach
+-/
 
 #print List.filter_filter /-
 @[simp]
@@ -5125,9 +5133,11 @@ theorem filter_filter (q) [DecidablePred q] :
 #align list.filter_filter List.filter_filter
 -/
 
+#print List.filter_comm /-
 theorem filter_comm (q) [DecidablePred q] (l : List α) :
     filter p (filter q l) = filter q (filter p l) := by simp [and_comm']
-#align list.filter_comm List.filterₓ_comm
+#align list.filter_comm List.filter_comm
+-/
 
 #print List.filter_true /-
 @[simp]
Diff
@@ -5,7 +5,7 @@ Authors: Parikshit Khanna, Jeremy Avigad, Leonardo de Moura, Floris van Doorn, M
 -/
 import Data.Nat.Order.Basic
 
-#align_import data.list.basic from "leanprover-community/mathlib"@"9da1b3534b65d9661eb8f42443598a92bbb49211"
+#align_import data.list.basic from "leanprover-community/mathlib"@"65a1391a0106c9204fe45bc73a039f056558cb83"
 
 /-!
 # Basic properties of lists
@@ -4287,6 +4287,11 @@ def attach (l : List α) : List { x // x ∈ l } :=
 #align list.attach List.attach
 -/
 
+@[simp]
+theorem attach_nil : ([] : List α).attach = [] :=
+  rfl
+#align list.attach_nil List.attach_nil
+
 #print List.sizeOf_lt_sizeOf_of_mem /-
 theorem sizeOf_lt_sizeOf_of_mem [SizeOf α] {x : α} {l : List α} (hx : x ∈ l) :
     SizeOf.sizeOf x < SizeOf.sizeOf l :=
@@ -5082,6 +5087,32 @@ theorem map_filter (f : β → α) (l : List β) : filter p (map f l) = map f (f
 #align list.map_filter List.map_filter
 -/
 
+theorem map_filter' {f : α → β} (hf : Injective f) (l : List α)
+    [DecidablePred fun b => ∃ a, p a ∧ f a = b] :
+    (l.filterₓ p).map f = (l.map f).filterₓ fun b => ∃ a, p a ∧ f a = b := by
+  simp [(· ∘ ·), map_filter, hf.eq_iff]
+#align list.map_filter' List.map_filter'
+
+theorem filter_attach' (l : List α) (p : { a // a ∈ l } → Prop) [DecidableEq α] [DecidablePred p] :
+    l.attach.filterₓ p =
+      (l.filterₓ fun x => ∃ h, p ⟨x, h⟩).attach.map
+        (Subtype.map id fun x hx =>
+          let ⟨h, _⟩ := of_mem_filter hx
+          h) :=
+  by
+  classical
+  refine' map_injective_iff.2 Subtype.coe_injective _
+  simp [(· ∘ ·), map_filter' _ Subtype.coe_injective]
+#align list.filter_attach' List.filterₓ_attach'
+
+@[simp]
+theorem filter_attach (l : List α) (p : α → Prop) [DecidablePred p] :
+    (l.attach.filterₓ fun x => p ↑x) =
+      (l.filterₓ p).attach.map (Subtype.map id fun _ => mem_of_mem_filter) :=
+  map_injective_iff.2 Subtype.coe_injective <| by
+    simp_rw [map_map, (· ∘ ·), Subtype.map, Subtype.coe_mk, id.def, ← map_filter, attach_map_coe]
+#align list.filter_attach List.filterₓ_attach
+
 #print List.filter_filter /-
 @[simp]
 theorem filter_filter (q) [DecidablePred q] :
@@ -5094,6 +5125,10 @@ theorem filter_filter (q) [DecidablePred q] :
 #align list.filter_filter List.filter_filter
 -/
 
+theorem filter_comm (q) [DecidablePred q] (l : List α) :
+    filter p (filter q l) = filter q (filter p l) := by simp [and_comm']
+#align list.filter_comm List.filterₓ_comm
+
 #print List.filter_true /-
 @[simp]
 theorem filter_true {h : DecidablePred fun a : α => True} (l : List α) :
Diff
@@ -6203,37 +6203,37 @@ section All₂
 
 variable {p q : α → Prop} {l : List α}
 
-#print List.all₂_cons /-
+#print List.forall_cons /-
 @[simp]
-theorem all₂_cons (p : α → Prop) (x : α) : ∀ l : List α, All₂ p (x :: l) ↔ p x ∧ All₂ p l
+theorem forall_cons (p : α → Prop) (x : α) : ∀ l : List α, Forall p (x :: l) ↔ p x ∧ Forall p l
   | [] => (and_true_iff _).symm
   | x :: l => Iff.rfl
-#align list.all₂_cons List.all₂_cons
+#align list.all₂_cons List.forall_cons
 -/
 
-#print List.all₂_iff_forall /-
-theorem all₂_iff_forall : ∀ {l : List α}, All₂ p l ↔ ∀ x ∈ l, p x
+#print List.forall_iff_forall_mem /-
+theorem forall_iff_forall_mem : ∀ {l : List α}, Forall p l ↔ ∀ x ∈ l, p x
   | [] => (iff_true_intro <| forall_mem_nil _).symm
   | x :: l => by rw [ball_cons, all₂_cons, all₂_iff_forall]
-#align list.all₂_iff_forall List.all₂_iff_forall
+#align list.all₂_iff_forall List.forall_iff_forall_mem
 -/
 
-#print List.All₂.imp /-
-theorem All₂.imp (h : ∀ x, p x → q x) : ∀ {l : List α}, All₂ p l → All₂ q l
+#print List.Forall.imp /-
+theorem Forall.imp (h : ∀ x, p x → q x) : ∀ {l : List α}, Forall p l → Forall q l
   | [] => id
   | x :: l => by simpa using And.imp (h x) all₂.imp
-#align list.all₂.imp List.All₂.imp
+#align list.all₂.imp List.Forall.imp
 -/
 
-#print List.all₂_map_iff /-
+#print List.forall_map_iff /-
 @[simp]
-theorem all₂_map_iff {p : β → Prop} (f : α → β) : All₂ p (l.map f) ↔ All₂ (p ∘ f) l := by
+theorem forall_map_iff {p : β → Prop} (f : α → β) : Forall p (l.map f) ↔ Forall (p ∘ f) l := by
   induction l <;> simp [*]
-#align list.all₂_map_iff List.all₂_map_iff
+#align list.all₂_map_iff List.forall_map_iff
 -/
 
-instance (p : α → Prop) [DecidablePred p] : DecidablePred (All₂ p) := fun l =>
-  decidable_of_iff' _ all₂_iff_forall
+instance (p : α → Prop) [DecidablePred p] : DecidablePred (Forall p) := fun l =>
+  decidable_of_iff' _ forall_iff_forall_mem
 
 end All₂
 
Diff
@@ -3,7 +3,7 @@ Copyright (c) 2014 Parikshit Khanna. All rights reserved.
 Released under Apache 2.0 license as described in the file LICENSE.
 Authors: Parikshit Khanna, Jeremy Avigad, Leonardo de Moura, Floris van Doorn, Mario Carneiro
 -/
-import Mathbin.Data.Nat.Order.Basic
+import Data.Nat.Order.Basic
 
 #align_import data.list.basic from "leanprover-community/mathlib"@"9da1b3534b65d9661eb8f42443598a92bbb49211"
 
Diff
@@ -1430,15 +1430,15 @@ theorem head!_eq_head? [Inhabited α] (l : List α) : headI l = (head? l).iget :
 #align list.head_eq_head' List.head!_eq_head?
 -/
 
-#print List.surjective_head /-
-theorem surjective_head [Inhabited α] : Surjective (@headI α _) := fun x => ⟨[x], rfl⟩
-#align list.surjective_head List.surjective_head
+#print List.surjective_head! /-
+theorem surjective_head! [Inhabited α] : Surjective (@headI α _) := fun x => ⟨[x], rfl⟩
+#align list.surjective_head List.surjective_head!
 -/
 
-#print List.surjective_head' /-
-theorem surjective_head' : Surjective (@head? α) :=
+#print List.surjective_head? /-
+theorem surjective_head? : Surjective (@head? α) :=
   Option.forall.2 ⟨⟨[], rfl⟩, fun x => ⟨[x], rfl⟩⟩
-#align list.surjective_head' List.surjective_head'
+#align list.surjective_head' List.surjective_head?
 -/
 
 #print List.surjective_tail /-
Diff
@@ -222,7 +222,7 @@ theorem mem_map {f : α → β} {b : β} {l : List α} : b ∈ map f l ↔ ∃ a
 #align list.mem_map List.mem_map
 -/
 
-alias mem_map ↔ exists_of_mem_map _
+alias ⟨exists_of_mem_map, _⟩ := mem_map
 #align list.exists_of_mem_map List.exists_of_mem_map
 
 theorem mem_map_of_mem (f : α → β) {a : α} {l : List α} (h : a ∈ l) : f a ∈ map f l :=
@@ -431,7 +431,7 @@ theorem length_eq_three {l : List α} : l.length = 3 ↔ ∃ a b c, l = [a, b, c
 #align list.length_eq_three List.length_eq_three
 -/
 
-alias length_le_of_sublist ← sublist.length_le
+alias sublist.length_le := length_le_of_sublist
 #align list.sublist.length_le List.Sublist.length_le
 
 /-! ### set-theoretic notation of lists -/
@@ -846,7 +846,7 @@ theorem eq_replicate_length {a : α} : ∀ {l : List α}, l = replicate l.length
 #align list.eq_replicate_length List.eq_replicate_length
 -/
 
-alias eq_replicate_length ↔ _ eq_replicate_of_mem
+alias ⟨_, eq_replicate_of_mem⟩ := eq_replicate_length
 #align list.eq_replicate_of_mem List.eq_replicate_of_mem
 
 #print List.eq_replicate /-
Diff
@@ -955,12 +955,14 @@ theorem bind_eq_bind {α β} (f : α → List β) (l : List α) : l >>= f = l.bi
 #align list.bind_eq_bind List.bind_eq_bind
 -/
 
-#print List.bind_append /-
+/- warning: list.bind_append clashes with list.append_bind -> List.append_bind
+Case conversion may be inaccurate. Consider using '#align list.bind_append List.append_bindₓ'. -/
+#print List.append_bind /-
 -- TODO: duplicate of a lemma in core
-theorem bind_append (f : α → List β) (l₁ l₂ : List α) :
+theorem append_bind (f : α → List β) (l₁ l₂ : List α) :
     (l₁ ++ l₂).bind f = l₁.bind f ++ l₂.bind f :=
   append_bind _ _ _
-#align list.bind_append List.bind_append
+#align list.bind_append List.append_bind
 -/
 
 #print List.bind_singleton /-
Diff
@@ -816,6 +816,8 @@ theorem replicate_one (a : α) : replicate 1 a = [a] :=
 #align list.replicate_one List.replicate_one
 -/
 
+/- warning: list.length_replicate clashes with list.length_repeat -> List.length_replicate
+Case conversion may be inaccurate. Consider using '#align list.length_replicate List.length_replicateₓ'. -/
 #print List.length_replicate /-
 @[simp]
 theorem length_replicate : ∀ (n) (a : α), length (replicate n a) = n
@@ -1184,20 +1186,20 @@ theorem map_reverseAux (f : α → β) (l₁ l₂ : List α) :
 #align list.map_reverse_core List.map_reverseAux
 -/
 
-#print List.mem_reverse' /-
+#print List.mem_reverse /-
 @[simp]
-theorem mem_reverse' {a : α} {l : List α} : a ∈ reverse l ↔ a ∈ l := by
+theorem mem_reverse {a : α} {l : List α} : a ∈ reverse l ↔ a ∈ l := by
   induction l <;> [rfl;
     simp only [*, reverse_cons, mem_append, mem_singleton, mem_cons_iff, not_mem_nil, false_or_iff,
       or_false_iff, or_comm']]
-#align list.mem_reverse List.mem_reverse'
+#align list.mem_reverse List.mem_reverse
 -/
 
 #print List.reverse_replicate /-
 @[simp]
 theorem reverse_replicate (n) (a : α) : reverse (replicate n a) = replicate n a :=
   eq_replicate.2
-    ⟨by rw [length_reverse, length_replicate], fun b h => eq_of_mem_replicate (mem_reverse'.1 h)⟩
+    ⟨by rw [length_reverse, length_replicate], fun b h => eq_of_mem_replicate (mem_reverse.1 h)⟩
 #align list.reverse_replicate List.reverse_replicate
 -/
 
@@ -5036,7 +5038,7 @@ theorem filter_eq_self {l} : filter p l = l ↔ ∀ a ∈ l, p a :=
 
 #print List.filter_length_eq_length /-
 theorem filter_length_eq_length {l} : (filter p l).length = l.length ↔ ∀ a ∈ l, p a :=
-  Iff.trans ⟨l.filter_sublist.eq_of_length, congr_arg List.length⟩ filter_eq_self
+  Iff.trans ⟨l.filter_sublistₓ.eq_of_length, congr_arg List.length⟩ filter_eq_self
 #align list.filter_length_eq_length List.filter_length_eq_length
 -/
 
Diff
@@ -2,14 +2,11 @@
 Copyright (c) 2014 Parikshit Khanna. All rights reserved.
 Released under Apache 2.0 license as described in the file LICENSE.
 Authors: Parikshit Khanna, Jeremy Avigad, Leonardo de Moura, Floris van Doorn, Mario Carneiro
-
-! This file was ported from Lean 3 source module data.list.basic
-! leanprover-community/mathlib commit 9da1b3534b65d9661eb8f42443598a92bbb49211
-! Please do not edit these lines, except to modify the commit id
-! if you have ported upstream changes.
 -/
 import Mathbin.Data.Nat.Order.Basic
 
+#align_import data.list.basic from "leanprover-community/mathlib"@"9da1b3534b65d9661eb8f42443598a92bbb49211"
+
 /-!
 # Basic properties of lists
 
Diff
@@ -472,6 +472,8 @@ theorem doubleton_eq [DecidableEq α] {x y : α} (h : x ≠ y) : ({x, y} : List
 /-! ### bounded quantifiers over lists -/
 
 
+/- warning: list.forall_mem_nil clashes with list.ball_nil -> List.forall_mem_nil
+Case conversion may be inaccurate. Consider using '#align list.forall_mem_nil List.forall_mem_nilₓ'. -/
 #print List.forall_mem_nil /-
 theorem forall_mem_nil (p : α → Prop) : ∀ x ∈ @nil α, p x :=
   fun.
Diff
@@ -4909,7 +4909,7 @@ theorem reduceOption_singleton (x : Option α) : [x].reduceOption = x.toList :=
 
 #print List.reduceOption_concat /-
 theorem reduceOption_concat (l : List (Option α)) (x : Option α) :
-    (l.concat x).reduceOption = l.reduceOption ++ x.toList :=
+    (l.push x).reduceOption = l.reduceOption ++ x.toList :=
   by
   induction' l with hd tl hl generalizing x
   · cases x <;> simp [Option.toList]
@@ -4920,7 +4920,7 @@ theorem reduceOption_concat (l : List (Option α)) (x : Option α) :
 
 #print List.reduceOption_concat_of_some /-
 theorem reduceOption_concat_of_some (l : List (Option α)) (x : α) :
-    (l.concat (some x)).reduceOption = l.reduceOption.concat x := by
+    (l.push (some x)).reduceOption = l.reduceOption.push x := by
   simp only [reduce_option_nil, concat_eq_append, reduce_option_append, reduce_option_cons_of_some]
 #align list.reduce_option_concat_of_some List.reduceOption_concat_of_some
 -/
Diff
@@ -209,6 +209,7 @@ theorem ne_and_not_mem_of_not_mem_cons {a y : α} {l : List α} : a ∉ y :: l 
 #align list.ne_and_not_mem_of_not_mem_cons List.ne_and_not_mem_of_not_mem_cons
 -/
 
+#print List.mem_map /-
 @[simp]
 theorem mem_map {f : α → β} {b : β} {l : List α} : b ∈ map f l ↔ ∃ a, a ∈ l ∧ f a = b :=
   by
@@ -222,6 +223,7 @@ theorem mem_map {f : α → β} {b : β} {l : List α} : b ∈ map f l ↔ ∃ a
     · rintro ⟨c, hc | hc, h⟩
       exacts [Or.inl <| (congr_arg f hc.symm).trans h, Or.inr ⟨c, hc, h⟩]
 #align list.mem_map List.mem_map
+-/
 
 alias mem_map ↔ exists_of_mem_map _
 #align list.exists_of_mem_map List.exists_of_mem_map
@@ -523,11 +525,13 @@ theorem or_exists_of_exists_mem_cons {p : α → Prop} {a : α} {l : List α} (h
       fun this : x ∈ l => Or.inr (BEx.intro x this px)
 #align list.or_exists_of_exists_mem_cons List.or_exists_of_exists_mem_consₓ
 
+#print List.exists_mem_cons_iff /-
 theorem exists_mem_cons_iff (p : α → Prop) (a : α) (l : List α) :
     (∃ x ∈ a :: l, p x) ↔ p a ∨ ∃ x ∈ l, p x :=
   Iff.intro or_exists_of_exists_mem_cons fun h =>
     Or.elim h (exists_mem_cons_of l) exists_mem_cons_of_exists
 #align list.exists_mem_cons_iff List.exists_mem_cons_iff
+-/
 
 /-! ### list subset -/
 
@@ -596,9 +600,11 @@ theorem eq_nil_iff_forall_not_mem {l : List α} : l = [] ↔ ∀ a, a ∉ l :=
 #align list.eq_nil_iff_forall_not_mem List.eq_nil_iff_forall_not_mem
 -/
 
+#print List.map_subset /-
 theorem map_subset {l₁ l₂ : List α} (f : α → β) (H : l₁ ⊆ l₂) : map f l₁ ⊆ map f l₂ := fun x => by
   simp only [mem_map, not_and, exists_imp, and_imp] <;> exact fun a h e => ⟨a, H h, e⟩
 #align list.map_subset List.map_subset
+-/
 
 #print List.map_subset_iff /-
 theorem map_subset_iff {l₁ l₂ : List α} (f : α → β) (h : Injective f) :
@@ -775,6 +781,7 @@ theorem append_left_inj {s₁ s₂ : List α} (t) : s₁ ++ t = s₂ ++ t ↔ s
 #align list.append_left_inj List.append_left_inj
 -/
 
+#print List.map_eq_append_split /-
 theorem map_eq_append_split {f : α → β} {l : List α} {s₁ s₂ : List β} (h : map f l = s₁ ++ s₂) :
     ∃ l₁ l₂, l = l₁ ++ l₂ ∧ map f l₁ = s₁ ∧ map f l₂ = s₂ :=
   by
@@ -785,6 +792,7 @@ theorem map_eq_append_split {f : α → β} {l : List α} {s₁ s₂ : List β}
   rw [← length_map f l, h, length_append]
   apply Nat.le_add_right
 #align list.map_eq_append_split List.map_eq_append_split
+-/
 
 /-! ### replicate -/
 
@@ -878,10 +886,12 @@ theorem map_replicate (f : α → β) (n a) : map f (replicate n a) = replicate
 #align list.map_replicate List.map_replicate
 -/
 
+#print List.tail_replicate /-
 @[simp]
 theorem tail_replicate (n) (a : α) : tail (replicate n a) = replicate (n - 1) a := by
   cases n <;> rfl
 #align list.tail_replicate List.tail_replicate
+-/
 
 #print List.join_replicate_nil /-
 @[simp]
@@ -928,17 +938,21 @@ theorem replicate_left_inj {a : α} {n m : ℕ} : replicate n a = replicate m a
 /-! ### pure -/
 
 
+#print List.mem_pure /-
 @[simp]
 theorem mem_pure {α} (x y : α) : x ∈ (pure y : List α) ↔ x = y := by simp! [pure, List.ret]
 #align list.mem_pure List.mem_pure
+-/
 
 /-! ### bind -/
 
 
+#print List.bind_eq_bind /-
 @[simp]
 theorem bind_eq_bind {α β} (f : α → List β) (l : List α) : l >>= f = l.bind f :=
   rfl
 #align list.bind_eq_bind List.bind_eq_bind
+-/
 
 #print List.bind_append /-
 -- TODO: duplicate of a lemma in core
@@ -962,13 +976,17 @@ theorem bind_singleton' (l : List α) : (l.bind fun x => [x]) = l :=
 #align list.bind_singleton' List.bind_singleton'
 -/
 
+#print List.map_eq_bind /-
 theorem map_eq_bind {α β} (f : α → β) (l : List α) : map f l = l.bind fun x => [f x] := by trans;
   rw [← bind_singleton' l, bind_map]; rfl
 #align list.map_eq_bind List.map_eq_bind
+-/
 
+#print List.bind_assoc /-
 theorem bind_assoc {α β} (l : List α) (f : α → List β) (g : β → List γ) :
     (l.bind f).bind g = l.bind fun x => (f x).bind g := by induction l <;> simp [*]
 #align list.bind_assoc List.bind_assoc
+-/
 
 /-! ### concat -/
 
@@ -1552,6 +1570,7 @@ theorem nthLe_cons_aux {l : List α} {a : α} {n} (hn : n ≠ 0) (h : n < (a ::
 #align list.nth_le_cons_aux List.nthLe_cons_aux
 -/
 
+#print List.nthLe_cons /-
 theorem nthLe_cons {l : List α} {a : α} {n} (hl) :
     (a :: l).nthLe n hl = if hn : n = 0 then a else l.nthLe (n - 1) (nthLe_cons_aux hn hl) :=
   by
@@ -1563,6 +1582,7 @@ theorem nthLe_cons {l : List α} {a : α} {n} (hl) :
   · contradiction
   rfl
 #align list.nth_le_cons List.nthLe_cons
+-/
 
 #print List.modifyHead_modifyHead /-
 @[simp]
@@ -1700,9 +1720,11 @@ theorem sublist_append_of_sublist_left {l l₁ l₂ : List α} (s : l <+ l₁) :
 #align list.sublist_append_of_sublist_left List.sublist_append_of_sublist_left
 -/
 
+#print List.sublist_append_of_sublist_right /-
 theorem sublist_append_of_sublist_right {l l₁ l₂ : List α} (s : l <+ l₂) : l <+ l₁ ++ l₂ :=
   s.trans <| sublist_append_right _ _
 #align list.sublist_append_of_sublist_right List.sublist_append_of_sublist_right
+-/
 
 #print List.sublist_of_cons_sublist_cons /-
 theorem sublist_of_cons_sublist_cons {l₁ l₂ : List α} : ∀ {a : α}, a :: l₁ <+ a :: l₂ → l₁ <+ l₂
@@ -1735,6 +1757,7 @@ theorem Sublist.append_right {l₁ l₂ : List α} (h : l₁ <+ l₂) (l) : l₁
 #align list.sublist.append_right List.Sublist.append_right
 -/
 
+#print List.sublist_or_mem_of_sublist /-
 theorem sublist_or_mem_of_sublist {l l₁ l₂ : List α} {a : α} (h : l <+ l₁ ++ a :: l₂) :
     l <+ l₁ ++ l₂ ∨ a ∈ l := by
   induction' l₁ with b l₁ IH generalizing l
@@ -1743,6 +1766,7 @@ theorem sublist_or_mem_of_sublist {l l₁ l₂ : List α} {a : α} (h : l <+ l
     · exact Or.imp_left (sublist_cons_of_sublist _) (IH h)
     · exact (IH h).imp (sublist.cons_cons _) (mem_cons_of_mem _)
 #align list.sublist_or_mem_of_sublist List.sublist_or_mem_of_sublist
+-/
 
 #print List.Sublist.reverse /-
 theorem Sublist.reverse {l₁ l₂ : List α} (h : l₁ <+ l₂) : l₁.reverse <+ l₂.reverse :=
@@ -1809,12 +1833,15 @@ theorem sublist_nil_iff_eq_nil {l : List α} : l <+ [] ↔ l = [] :=
 #align list.sublist_nil_iff_eq_nil List.sublist_nil_iff_eq_nil
 -/
 
+#print List.replicate_sublist_replicate /-
 @[simp]
 theorem replicate_sublist_replicate (a : α) {m n} : replicate m a <+ replicate n a ↔ m ≤ n :=
   ⟨fun h => by simpa only [length_replicate] using h.length_le, fun h => by
     induction h <;> [rfl; simp only [*, replicate_succ, sublist.cons]]⟩
 #align list.replicate_sublist_replicate List.replicate_sublist_replicate
+-/
 
+#print List.sublist_replicate_iff /-
 theorem sublist_replicate_iff {l : List α} {a : α} {n : ℕ} :
     l <+ replicate n a ↔ ∃ k ≤ n, l = replicate k a :=
   ⟨fun h =>
@@ -1822,6 +1849,7 @@ theorem sublist_replicate_iff {l : List α} {a : α} {n : ℕ} :
       eq_replicate_length.mpr fun b hb => eq_of_mem_replicate (h.Subset hb)⟩,
     by rintro ⟨k, h, rfl⟩; exact (replicate_sublist_replicate _).mpr h⟩
 #align list.sublist_replicate_iff List.sublist_replicate_iff
+-/
 
 #print List.Sublist.eq_of_length /-
 theorem Sublist.eq_of_length : ∀ {l₁ l₂ : List α}, l₁ <+ l₂ → length l₁ = length l₂ → l₁ = l₂
@@ -2076,12 +2104,14 @@ theorem get?_injective {α : Type u} {xs : List α} {i j : ℕ} (h₀ : i < xs.l
 #align list.nth_injective List.get?_injective
 -/
 
+#print List.get?_map /-
 @[simp]
 theorem get?_map (f : α → β) : ∀ l n, get? (map f l) n = (get? l n).map f
   | [], n => rfl
   | a :: l, 0 => rfl
   | a :: l, n + 1 => nth_map l n
 #align list.nth_map List.get?_map
+-/
 
 #print List.nthLe_map /-
 theorem nthLe_map (f : α → β) {l n} (H1 H2) : nthLe (map f l) n H1 = f (nthLe l n H2) :=
@@ -2422,6 +2452,7 @@ theorem set_eq_modifyNth (a : α) : ∀ (n) (l : List α), set l n a = modifyNth
 #align list.update_nth_eq_modify_nth List.set_eq_modifyNth
 -/
 
+#print List.modifyNth_eq_set /-
 theorem modifyNth_eq_set (f : α → α) :
     ∀ (n) (l : List α), modifyNth f n l = ((fun a => set l n (f a)) <$> get? l n).getD l
   | 0, l => by cases l <;> rfl
@@ -2429,7 +2460,9 @@ theorem modifyNth_eq_set (f : α → α) :
   | n + 1, b :: l =>
     (congr_arg (cons b) (modify_nth_eq_update_nth n l)).trans <| by cases nth l n <;> rfl
 #align list.modify_nth_eq_update_nth List.modifyNth_eq_set
+-/
 
+#print List.get?_modifyNth /-
 theorem get?_modifyNth (f : α → α) :
     ∀ (n) (l : List α) (m),
       get? (modifyNth f n l) m = (fun a => if n = m then f a else a) <$> get? l m
@@ -2442,6 +2475,7 @@ theorem get?_modifyNth (f : α → α) :
         simp only [h, if_pos, if_true, if_false, Option.map_none, Option.map_some, mt succ.inj,
           not_false_iff]
 #align list.nth_modify_nth List.get?_modifyNth
+-/
 
 #print List.length_modifyNthTail /-
 theorem length_modifyNthTail (f : List α → List α) (H : ∀ l, length (f l) = length l) :
@@ -2466,10 +2500,12 @@ theorem length_set (l : List α) (n) (a : α) : length (set l n a) = length l :=
 #align list.update_nth_length List.length_set
 -/
 
+#print List.get?_modifyNth_eq /-
 @[simp]
 theorem get?_modifyNth_eq (f : α → α) (n) (l : List α) :
     get? (modifyNth f n l) n = f <$> get? l n := by simp only [nth_modify_nth, if_pos]
 #align list.nth_modify_nth_eq List.get?_modifyNth_eq
+-/
 
 #print List.get?_modifyNth_ne /-
 @[simp]
@@ -2478,9 +2514,11 @@ theorem get?_modifyNth_ne (f : α → α) {m n} (l : List α) (h : m ≠ n) :
 #align list.nth_modify_nth_ne List.get?_modifyNth_ne
 -/
 
+#print List.get?_set_eq /-
 theorem get?_set_eq (a : α) (n) (l : List α) : get? (set l n a) n = (fun _ => a) <$> get? l n := by
   simp only [update_nth_eq_modify_nth, nth_modify_nth_eq]
 #align list.nth_update_nth_eq List.get?_set_eq
+-/
 
 #print List.get?_set_eq_of_lt /-
 theorem get?_set_eq_of_lt (a : α) {n} {l : List α} (h : n < length l) :
@@ -2748,10 +2786,12 @@ end InsertNth
 /-! ### map -/
 
 
+#print List.map_nil /-
 @[simp]
 theorem map_nil (f : α → β) : map f [] = [] :=
   rfl
 #align list.map_nil List.map_nil
+-/
 
 #print List.map_eq_foldr /-
 theorem map_eq_foldr (f : α → β) (l : List α) : map f l = foldr (fun a bs => f a :: bs) [] l := by
@@ -2828,10 +2868,12 @@ theorem bind_congr {l : List α} {f g : α → List β} (h : ∀ x ∈ l, f x =
 #align list.bind_congr List.bind_congr
 -/
 
+#print List.map_eq_map /-
 @[simp]
 theorem map_eq_map {α β} (f : α → β) (l : List α) : f <$> l = map f l :=
   rfl
 #align list.map_eq_map List.map_eq_map
+-/
 
 #print List.map_tail /-
 @[simp]
@@ -2870,10 +2912,12 @@ theorem map_comp_map (g : β → γ) (f : α → β) : map g ∘ map f = map (g
 #align list.map_comp_map List.map_comp_map
 -/
 
+#print List.map_filter_eq_foldr /-
 theorem map_filter_eq_foldr (f : α → β) (p : α → Prop) [DecidablePred p] (as : List α) :
     map f (filter p as) = foldr (fun a bs => if p a then f a :: bs else bs) [] as := by
   induction as; · rfl; · simp! [*, apply_ite (map f)]
 #align list.map_filter_eq_foldr List.map_filter_eq_foldr
+-/
 
 #print List.getLast_map /-
 theorem getLast_map (f : α → β) {l : List α} (hl : l ≠ []) :
@@ -2993,6 +3037,7 @@ theorem take_left' {l₁ l₂ : List α} {n} (h : length l₁ = n) : take n (l
 #align list.take_left' List.take_left'
 -/
 
+#print List.take_take /-
 theorem take_take : ∀ (n m) (l : List α), take n (take m l) = take (min n m) l
   | n, 0, l => by rw [min_zero, take_zero, take_nil]
   | 0, m, l => by rw [zero_min, take_zero, take_zero]
@@ -3000,19 +3045,24 @@ theorem take_take : ∀ (n m) (l : List α), take n (take m l) = take (min n m)
   | succ n, succ m, a :: l => by
     simp only [take, min_succ_succ, take_take n m l] <;> constructor <;> rfl
 #align list.take_take List.take_take
+-/
 
+#print List.take_replicate /-
 theorem take_replicate (a : α) : ∀ n m : ℕ, take n (replicate m a) = replicate (min n m) a
   | n, 0 => by simp
   | 0, m => by simp
   | succ n, succ m => by simp [min_succ_succ, take_replicate]
 #align list.take_replicate List.take_replicate
+-/
 
+#print List.map_take /-
 theorem map_take {α β : Type _} (f : α → β) :
     ∀ (L : List α) (i : ℕ), (L.take i).map f = (L.map f).take i
   | [], i => by simp
   | L, 0 => by simp
   | h :: t, n + 1 => by dsimp; rw [map_take]
 #align list.map_take List.map_take
+-/
 
 #print List.take_append_eq_append_take /-
 /-- Taking the first `n` elements in `l₁ ++ l₂` is the same as appending the first `n` elements
@@ -3096,6 +3146,7 @@ theorem take_eq_nil_iff {l : List α} {k : ℕ} : l.take k = [] ↔ l = [] ∨ k
 #align list.take_eq_nil_iff List.take_eq_nil_iff
 -/
 
+#print List.take_eq_take /-
 theorem take_eq_take :
     ∀ {l : List α} {m n : ℕ}, l.take m = l.take n ↔ min m l.length = min n l.length
   | [], m, n => by simp
@@ -3104,6 +3155,7 @@ theorem take_eq_take :
   | x :: xs, 0, n + 1 => by simp [@eq_comm ℕ 0]
   | x :: xs, m + 1, n + 1 => by simp [Nat.min_succ_succ, take_eq_take]
 #align list.take_eq_take List.take_eq_take
+-/
 
 #print List.take_add /-
 theorem take_add (l : List α) (m n : ℕ) : l.take (m + n) = l.take m ++ (l.drop m).take n :=
@@ -3289,6 +3341,7 @@ theorem drop_append {l₁ l₂ : List α} (i : ℕ) : drop (l₁.length + i) (l
 #align list.drop_append List.drop_append
 -/
 
+#print List.drop_sizeOf_le /-
 theorem drop_sizeOf_le [SizeOf α] (l : List α) : ∀ n : ℕ, (l.drop n).sizeOf ≤ l.sizeOf :=
   by
   induction' l with _ _ lih <;> intro n
@@ -3297,6 +3350,7 @@ theorem drop_sizeOf_le [SizeOf α] (l : List α) : ∀ n : ℕ, (l.drop n).sizeO
     · rfl
     · exact trans (lih _) le_add_self
 #align list.drop_sizeof_le List.drop_sizeOf_le
+-/
 
 #print List.nthLe_drop /-
 /-- The `i + j`-th element of a list coincides with the `j`-th element of the list obtained by
@@ -3315,12 +3369,14 @@ theorem nthLe_drop (L : List α) {i j : ℕ} (h : i + j < L.length) :
 #align list.nth_le_drop List.nthLe_drop
 -/
 
+#print List.nthLe_drop' /-
 /-- The `i + j`-th element of a list coincides with the `j`-th element of the list obtained by
 dropping the first `i` elements. Version designed to rewrite from the small list to the big list. -/
 theorem nthLe_drop' (L : List α) {i j : ℕ} (h : j < (L.drop i).length) :
     nthLe (L.drop i) j h = nthLe L (i + j) (lt_tsub_iff_left.mp (length_drop i L ▸ h)) := by
   rw [nth_le_drop]
 #align list.nth_le_drop' List.nthLe_drop'
+-/
 
 #print List.get?_drop /-
 theorem get?_drop (L : List α) (i j : ℕ) : get? (L.drop i) j = get? L (i + j) :=
@@ -3354,12 +3410,14 @@ theorem drop_take : ∀ (m : ℕ) (n : ℕ) (l : List α), drop m (take (m + n)
 #align list.drop_take List.drop_take
 -/
 
+#print List.map_drop /-
 theorem map_drop {α β : Type _} (f : α → β) :
     ∀ (L : List α) (i : ℕ), (L.drop i).map f = (L.map f).drop i
   | [], i => by simp
   | L, 0 => by simp
   | h :: t, n + 1 => by dsimp; rw [map_drop]
 #align list.map_drop List.map_drop
+-/
 
 #print List.modifyNthTail_eq_take_drop /-
 theorem modifyNthTail_eq_take_drop (f : List α → List α) (H : f [] = []) :
@@ -3511,19 +3569,23 @@ theorem foldr_cons (f : α → β → β) (b : β) (a : α) (l : List α) :
 #align list.foldr_cons List.foldr_cons
 -/
 
+#print List.foldl_append /-
 @[simp]
 theorem foldl_append (f : α → β → α) :
     ∀ (a : α) (l₁ l₂ : List β), foldl f a (l₁ ++ l₂) = foldl f (foldl f a l₁) l₂
   | a, [], l₂ => rfl
   | a, b :: l₁, l₂ => by simp only [cons_append, foldl_cons, foldl_append (f a b) l₁ l₂]
 #align list.foldl_append List.foldl_append
+-/
 
+#print List.foldr_append /-
 @[simp]
 theorem foldr_append (f : α → β → β) :
     ∀ (b : β) (l₁ l₂ : List α), foldr f b (l₁ ++ l₂) = foldr f (foldr f b l₂) l₁
   | b, [], l₂ => rfl
   | b, a :: l₁, l₂ => by simp only [cons_append, foldr_cons, foldr_append b l₁ l₂]
 #align list.foldr_append List.foldr_append
+-/
 
 #print List.foldl_fixed' /-
 theorem foldl_fixed' {f : α → β → α} {a : α} (hf : ∀ b, f a b = a) : ∀ l : List β, foldl f a l = a
@@ -3571,17 +3633,21 @@ theorem foldr_join (f : α → β → β) :
 #align list.foldr_join List.foldr_join
 -/
 
+#print List.foldl_reverse /-
 theorem foldl_reverse (f : α → β → α) (a : α) (l : List β) :
     foldl f a (reverse l) = foldr (fun x y => f y x) a l := by
   induction l <;> [rfl; simp only [*, reverse_cons, foldl_append, foldl_cons, foldl_nil, foldr]]
 #align list.foldl_reverse List.foldl_reverse
+-/
 
+#print List.foldr_reverse /-
 theorem foldr_reverse (f : α → β → β) (a : β) (l : List α) :
     foldr f a (reverse l) = foldl (fun x y => f y x) a l :=
   by
   let t := foldl_reverse (fun x y => f y x) a (reverse l)
   rw [reverse_reverse l] at t  <;> rwa [t]
 #align list.foldr_reverse List.foldr_reverse
+-/
 
 #print List.foldr_eta /-
 @[simp]
@@ -3598,17 +3664,21 @@ theorem reverse_foldl {l : List α} : reverse (foldl (fun t h => h :: t) [] l) =
 #align list.reverse_foldl List.reverse_foldl
 -/
 
+#print List.foldl_map /-
 @[simp]
 theorem foldl_map (g : β → γ) (f : α → γ → α) (a : α) (l : List β) :
     foldl f a (map g l) = foldl (fun x y => f x (g y)) a l := by
   revert a <;> induction l <;> intros <;> [rfl; simp only [*, map, foldl]]
 #align list.foldl_map List.foldl_map
+-/
 
+#print List.foldr_map /-
 @[simp]
 theorem foldr_map (g : β → γ) (f : γ → α → α) (a : α) (l : List β) :
     foldr f a (map g l) = foldr (f ∘ g) a l := by
   revert a <;> induction l <;> intros <;> [rfl; simp only [*, map, foldr]]
 #align list.foldr_map List.foldr_map
+-/
 
 #print List.foldl_map' /-
 theorem foldl_map' {α β : Type u} (g : α → β) (f : α → α → α) (f' : β → β → β) (a : α) (l : List α)
@@ -3630,27 +3700,35 @@ theorem foldr_map' {α β : Type u} (g : α → β) (f : α → α → α) (f' :
 #align list.foldr_map' List.foldr_map'
 -/
 
+#print List.foldl_hom /-
 theorem foldl_hom (l : List γ) (f : α → β) (op : α → γ → α) (op' : β → γ → β) (a : α)
     (h : ∀ a x, f (op a x) = op' (f a) x) : foldl op' (f a) l = f (foldl op a l) :=
   Eq.symm <| by revert a; induction l <;> intros <;> [rfl; simp only [*, foldl]]
 #align list.foldl_hom List.foldl_hom
+-/
 
+#print List.foldr_hom /-
 theorem foldr_hom (l : List γ) (f : α → β) (op : γ → α → α) (op' : γ → β → β) (a : α)
     (h : ∀ x a, f (op x a) = op' x (f a)) : foldr op' (f a) l = f (foldr op a l) := by revert a;
   induction l <;> intros <;> [rfl; simp only [*, foldr]]
 #align list.foldr_hom List.foldr_hom
+-/
 
+#print List.foldl_hom₂ /-
 theorem foldl_hom₂ (l : List ι) (f : α → β → γ) (op₁ : α → ι → α) (op₂ : β → ι → β)
     (op₃ : γ → ι → γ) (a : α) (b : β) (h : ∀ a b i, f (op₁ a i) (op₂ b i) = op₃ (f a b) i) :
     foldl op₃ (f a b) l = f (foldl op₁ a l) (foldl op₂ b l) :=
   Eq.symm <| by revert a b; induction l <;> intros <;> [rfl; simp only [*, foldl]]
 #align list.foldl_hom₂ List.foldl_hom₂
+-/
 
+#print List.foldr_hom₂ /-
 theorem foldr_hom₂ (l : List ι) (f : α → β → γ) (op₁ : ι → α → α) (op₂ : ι → β → β)
     (op₃ : ι → γ → γ) (a : α) (b : β) (h : ∀ a b i, f (op₁ i a) (op₂ i b) = op₃ i (f a b)) :
     foldr op₃ (f a b) l = f (foldr op₁ a l) (foldr op₂ b l) := by revert a;
   induction l <;> intros <;> [rfl; simp only [*, foldr]]
 #align list.foldr_hom₂ List.foldr_hom₂
+-/
 
 #print List.injective_foldl_comp /-
 theorem injective_foldl_comp {α : Type _} {l : List (α → α)} {f : α → α}
@@ -3699,12 +3777,15 @@ def foldlRecOn {C : β → Sort _} (l : List α) (op : β → α → β) (b : β
 #align list.foldl_rec_on List.foldlRecOn
 -/
 
+#print List.foldrRecOn_nil /-
 @[simp]
 theorem foldrRecOn_nil {C : β → Sort _} (op : α → β → β) (b) (hb : C b) (hl) :
     foldrRecOn [] op b hb hl = hb :=
   rfl
 #align list.foldr_rec_on_nil List.foldrRecOn_nil
+-/
 
+#print List.foldrRecOn_cons /-
 @[simp]
 theorem foldrRecOn_cons {C : β → Sort _} (x : α) (l : List α) (op : α → β → β) (b) (hb : C b)
     (hl : ∀ (b : β) (hb : C b) (a : α) (ha : a ∈ x :: l), C (op a b)) :
@@ -3713,12 +3794,15 @@ theorem foldrRecOn_cons {C : β → Sort _} (x : α) (l : List α) (op : α →
         (mem_cons_self _ _) :=
   rfl
 #align list.foldr_rec_on_cons List.foldrRecOn_cons
+-/
 
+#print List.foldlRecOn_nil /-
 @[simp]
 theorem foldlRecOn_nil {C : β → Sort _} (op : β → α → β) (b) (hb : C b) (hl) :
     foldlRecOn [] op b hb hl = hb :=
   rfl
 #align list.foldl_rec_on_nil List.foldlRecOn_nil
+-/
 
 -- scanl
 section Scanl
@@ -3835,8 +3919,6 @@ section FoldlEqFoldr
 -- foldl and foldr coincide when f is commutative and associative
 variable {f : α → α → α} (hcomm : Commutative f) (hassoc : Associative f)
 
-include hassoc
-
 #print List.foldl1_eq_foldr1 /-
 theorem foldl1_eq_foldr1 : ∀ a b l, foldl f a (l ++ [b]) = foldr f b (a :: l)
   | a, b, nil => rfl
@@ -3845,8 +3927,6 @@ theorem foldl1_eq_foldr1 : ∀ a b l, foldl f a (l ++ [b]) = foldr f b (a :: l)
 #align list.foldl1_eq_foldr1 List.foldl1_eq_foldr1
 -/
 
-include hcomm
-
 #print List.foldl_eq_of_comm_of_assoc /-
 theorem foldl_eq_of_comm_of_assoc : ∀ a b l, foldl f a (b :: l) = f b (foldl f a l)
   | a, b, nil => hcomm a b
@@ -3871,8 +3951,6 @@ variable {f : α → β → α}
 
 variable (hf : ∀ a b c, f (f a b) c = f (f a c) b)
 
-include hf
-
 #print List.foldl_eq_of_comm' /-
 theorem foldl_eq_of_comm' : ∀ a b l, foldl f a (b :: l) = f (foldl f a l) b
   | a, b, [] => rfl
@@ -3895,8 +3973,6 @@ variable {f : α → β → β}
 
 variable (hf : ∀ a b c, f a (f b c) = f b (f a c))
 
-include hf
-
 #print List.foldr_eq_of_comm' /-
 theorem foldr_eq_of_comm' : ∀ a b l, foldr f a (b :: l) = foldr f (f b a) l
   | a, b, [] => rfl
@@ -3910,14 +3986,10 @@ section
 
 variable {op : α → α → α} [ha : IsAssociative α op] [hc : IsCommutative α op]
 
--- mathport name: op
 local notation a " * " b => op a b
 
--- mathport name: foldl
 local notation l " <*> " a => foldl op a l
 
-include ha
-
 #print List.foldl_assoc /-
 theorem foldl_assoc : ∀ {l : List α} {a₁ a₂}, (l <*> a₁ * a₂) = a₁ * l <*> a₂
   | [], a₁, a₂ => rfl
@@ -3937,8 +4009,6 @@ theorem foldl_op_eq_op_foldr_assoc :
 #align list.foldl_op_eq_op_foldr_assoc List.foldl_op_eq_op_foldr_assoc
 -/
 
-include hc
-
 #print List.foldl_assoc_comm_cons /-
 theorem foldl_assoc_comm_cons {l : List α} {a₁ a₂} : ((a₁ :: l) <*> a₂) = a₁ * l <*> a₂ := by
   rw [foldl_cons, hc.comm, foldl_assoc]
@@ -3961,10 +4031,12 @@ theorem foldlM_nil (f : β → α → m β) {b} : foldlM f b [] = pure b :=
 #align list.mfoldl_nil List.foldlM_nil
 -/
 
+#print List.foldrM_nil /-
 @[simp]
 theorem foldrM_nil (f : α → β → m β) {b} : foldrM f b [] = pure b :=
   rfl
 #align list.mfoldr_nil List.foldrM_nil
+-/
 
 #print List.foldlM_cons /-
 @[simp]
@@ -3974,14 +4046,18 @@ theorem foldlM_cons {f : β → α → m β} {b a l} :
 #align list.mfoldl_cons List.foldlM_cons
 -/
 
+#print List.foldrM_cons /-
 @[simp]
 theorem foldrM_cons {f : α → β → m β} {b a l} : foldrM f b (a :: l) = foldrM f b l >>= f a :=
   rfl
 #align list.mfoldr_cons List.foldrM_cons
+-/
 
+#print List.foldrM_eq_foldr /-
 theorem foldrM_eq_foldr (f : α → β → m β) (b l) :
     foldrM f b l = foldr (fun a mb => mb >>= f a) (pure b) l := by induction l <;> simp [*]
 #align list.mfoldr_eq_foldr List.foldrM_eq_foldr
+-/
 
 attribute [simp] mmap mmap'
 
@@ -4000,19 +4076,23 @@ theorem foldlM_eq_foldl (f : β → α → m β) (b l) :
 #align list.mfoldl_eq_foldl List.foldlM_eq_foldl
 -/
 
+#print List.foldlM_append /-
 @[simp]
 theorem foldlM_append {f : β → α → m β} :
     ∀ {b l₁ l₂}, foldlM f b (l₁ ++ l₂) = foldlM f b l₁ >>= fun x => foldlM f x l₂
   | _, [], _ => by simp only [nil_append, mfoldl_nil, pure_bind]
   | _, _ :: _, _ => by simp only [cons_append, mfoldl_cons, mfoldl_append, LawfulMonad.bind_assoc]
 #align list.mfoldl_append List.foldlM_append
+-/
 
+#print List.foldrM_append /-
 @[simp]
 theorem foldrM_append {f : α → β → m β} :
     ∀ {b l₁ l₂}, foldrM f b (l₁ ++ l₂) = foldrM f b l₂ >>= fun x => foldrM f x l₁
   | _, [], _ => by simp only [nil_append, mfoldr_nil, bind_pure]
   | _, _ :: _, _ => by simp only [mfoldr_cons, cons_append, mfoldr_append, LawfulMonad.bind_assoc]
 #align list.mfoldr_append List.foldrM_append
+-/
 
 end MfoldlMfoldr
 
@@ -4204,6 +4284,7 @@ def attach (l : List α) : List { x // x ∈ l } :=
 #align list.attach List.attach
 -/
 
+#print List.sizeOf_lt_sizeOf_of_mem /-
 theorem sizeOf_lt_sizeOf_of_mem [SizeOf α] {x : α} {l : List α} (hx : x ∈ l) :
     SizeOf.sizeOf x < SizeOf.sizeOf l :=
   by
@@ -4211,6 +4292,7 @@ theorem sizeOf_lt_sizeOf_of_mem [SizeOf α] {x : α} {l : List α} (hx : x ∈ l
   · rw [hx]; exact lt_add_of_lt_of_nonneg (lt_one_add _) (Nat.zero_le _)
   · exact lt_add_of_pos_of_le (zero_lt_one_add _) (le_of_lt (ih hx))
 #align list.sizeof_lt_sizeof_of_mem List.sizeOf_lt_sizeOf_of_mem
+-/
 
 #print List.pmap_eq_map /-
 @[simp]
@@ -4324,6 +4406,7 @@ theorem attach_eq_nil (l : List α) : l.attach = [] ↔ l = [] :=
 #align list.attach_eq_nil List.attach_eq_nil
 -/
 
+#print List.getLast_pmap /-
 theorem getLast_pmap {α β : Type _} (p : α → Prop) (f : ∀ a, p a → β) (l : List α)
     (hl₁ : ∀ a ∈ l, p a) (hl₂ : l ≠ []) :
     (l.pmap f hl₁).getLast (mt List.pmap_eq_nil.1 hl₂) =
@@ -4335,6 +4418,7 @@ theorem getLast_pmap {α β : Type _} (p : α → Prop) (f : ∀ a, p a → β)
     · simp
     · apply l_ih
 #align list.last_pmap List.getLast_pmap
+-/
 
 #print List.get?_pmap /-
 theorem get?_pmap {p : α → Prop} (f : ∀ a, p a → β) {l : List α} (h : ∀ a ∈ l, p a) (n : ℕ) :
@@ -4362,6 +4446,7 @@ theorem nthLe_pmap {p : α → Prop} (f : ∀ a, p a → β) {l : List α} (h :
 #align list.nth_le_pmap List.nthLe_pmap
 -/
 
+#print List.pmap_append /-
 theorem pmap_append {p : ι → Prop} (f : ∀ a : ι, p a → α) (l₁ l₂ : List ι)
     (h : ∀ a ∈ l₁ ++ l₂, p a) :
     (l₁ ++ l₂).pmap f h =
@@ -4373,13 +4458,16 @@ theorem pmap_append {p : ι → Prop} (f : ∀ a : ι, p a → α) (l₁ l₂ :
   · dsimp only [pmap, cons_append]
     rw [ih]
 #align list.pmap_append List.pmap_append
+-/
 
+#print List.pmap_append' /-
 theorem pmap_append' {α β : Type _} {p : α → Prop} (f : ∀ a : α, p a → β) (l₁ l₂ : List α)
     (h₁ : ∀ a ∈ l₁, p a) (h₂ : ∀ a ∈ l₂, p a) :
     ((l₁ ++ l₂).pmap f fun a ha => (List.mem_append.1 ha).elim (h₁ a) (h₂ a)) =
       l₁.pmap f h₁ ++ l₂.pmap f h₂ :=
   pmap_append f l₁ l₂ _
 #align list.pmap_append' List.pmap_append'
+-/
 
 /-! ### find -/
 
@@ -4388,21 +4476,28 @@ section Find
 
 variable {p : α → Prop} [DecidablePred p] {l : List α} {a : α}
 
+#print List.find?_nil /-
 @[simp]
 theorem find?_nil (p : α → Prop) [DecidablePred p] : find? p [] = none :=
   rfl
 #align list.find_nil List.find?_nil
+-/
 
+#print List.find?_cons_of_pos /-
 @[simp]
 theorem find?_cons_of_pos (l) (h : p a) : find? p (a :: l) = some a :=
   if_pos h
 #align list.find_cons_of_pos List.find?_cons_of_pos
+-/
 
+#print List.find?_cons_of_neg /-
 @[simp]
 theorem find?_cons_of_neg (l) (h : ¬p a) : find? p (a :: l) = find? p l :=
   if_neg h
 #align list.find_cons_of_neg List.find?_cons_of_neg
+-/
 
+#print List.find?_eq_none /-
 @[simp]
 theorem find?_eq_none : find? p l = none ↔ ∀ x ∈ l, ¬p x :=
   by
@@ -4412,7 +4507,9 @@ theorem find?_eq_none : find? p l = none ↔ ∀ x ∈ l, ¬p x :=
   · simp only [find_cons_of_pos _ h, h, not_true, false_and_iff]
   · rwa [find_cons_of_neg _ h, iff_true_intro h, true_and_iff]
 #align list.find_eq_none List.find?_eq_none
+-/
 
+#print List.find?_some /-
 theorem find?_some (H : find? p l = some a) : p a :=
   by
   induction' l with b l IH; · contradiction
@@ -4420,7 +4517,9 @@ theorem find?_some (H : find? p l = some a) : p a :=
   · rw [find_cons_of_pos _ h] at H ; cases H; exact h
   · rw [find_cons_of_neg _ h] at H ; exact IH H
 #align list.find_some List.find?_some
+-/
 
+#print List.find?_mem /-
 @[simp]
 theorem find?_mem (H : find? p l = some a) : a ∈ l :=
   by
@@ -4429,6 +4528,7 @@ theorem find?_mem (H : find? p l = some a) : a ∈ l :=
   · rw [find_cons_of_pos _ h] at H ; cases H; apply mem_cons_self
   · rw [find_cons_of_neg _ h] at H ; exact mem_cons_of_mem _ (IH H)
 #align list.find_mem List.find?_mem
+-/
 
 end Find
 
@@ -4520,22 +4620,29 @@ end Lookmap
 /-! ### filter_map -/
 
 
+#print List.filterMap_nil /-
 @[simp]
 theorem filterMap_nil (f : α → Option β) : filterMap f [] = [] :=
   rfl
 #align list.filter_map_nil List.filterMap_nil
+-/
 
+#print List.filterMap_cons_none /-
 @[simp]
 theorem filterMap_cons_none {f : α → Option β} (a : α) (l : List α) (h : f a = none) :
     filterMap f (a :: l) = filterMap f l := by simp only [filter_map, h]
 #align list.filter_map_cons_none List.filterMap_cons_none
+-/
 
+#print List.filterMap_cons_some /-
 @[simp]
 theorem filterMap_cons_some (f : α → Option β) (a : α) (l : List α) {b : β} (h : f a = some b) :
     filterMap f (a :: l) = b :: filterMap f l := by
   simp only [filter_map, h] <;> constructor <;> rfl
 #align list.filter_map_cons_some List.filterMap_cons_some
+-/
 
+#print List.filterMap_cons /-
 theorem filterMap_cons (f : α → Option β) (a : α) (l : List α) :
     filterMap f (a :: l) = Option.casesOn (f a) (filterMap f l) fun b => b :: filterMap f l :=
   by
@@ -4544,7 +4651,9 @@ theorem filterMap_cons (f : α → Option β) (a : α) (l : List α) :
   · rw [filter_map_cons_none _ _ Eq]
   · rw [filter_map_cons_some _ _ _ Eq]
 #align list.filter_map_cons List.filterMap_cons
+-/
 
+#print List.filterMap_append /-
 theorem filterMap_append {α β : Type _} (l l' : List α) (f : α → Option β) :
     filterMap f (l ++ l') = filterMap f l ++ filterMap f l' :=
   by
@@ -4553,14 +4662,18 @@ theorem filterMap_append {α β : Type _} (l l' : List α) (f : α → Option β
   · rw [cons_append, filter_map, filter_map]
     cases f hd <;> simp only [filter_map, hl, cons_append, eq_self_iff_true, and_self_iff]
 #align list.filter_map_append List.filterMap_append
+-/
 
+#print List.filterMap_eq_map /-
 theorem filterMap_eq_map (f : α → β) : filterMap (some ∘ f) = map f :=
   by
   funext l
   induction' l with a l IH; · rfl
   simp only [filter_map_cons_some (some ∘ f) _ _ rfl, IH, map_cons]; constructor <;> rfl
 #align list.filter_map_eq_map List.filterMap_eq_map
+-/
 
+#print List.filterMap_eq_filter /-
 theorem filterMap_eq_filter (p : α → Prop) [DecidablePred p] :
     filterMap (Option.guard p) = filter p := by
   funext l
@@ -4570,7 +4683,9 @@ theorem filterMap_eq_filter (p : α → Prop) [DecidablePred p] :
     constructor <;> rfl
   · simp only [filter_map, Option.guard, IH, if_neg pa, filter_cons_of_neg _ pa]
 #align list.filter_map_eq_filter List.filterMap_eq_filter
+-/
 
+#print List.filterMap_filterMap /-
 theorem filterMap_filterMap (f : α → Option β) (g : β → Option γ) (l : List α) :
     filterMap g (filterMap f l) = filterMap (fun x => (f x).bind g) l :=
   by
@@ -4583,22 +4698,30 @@ theorem filterMap_filterMap (f : α → Option β) (g : β → Option γ) (l : L
       rw [filter_map_cons_some _ _ _ h', filter_map_cons_some, IH]] <;>
     simp only [h, h', Option.some_bind']
 #align list.filter_map_filter_map List.filterMap_filterMap
+-/
 
+#print List.map_filterMap /-
 theorem map_filterMap (f : α → Option β) (g : β → γ) (l : List α) :
     map g (filterMap f l) = filterMap (fun x => (f x).map g) l := by
   rw [← filter_map_eq_map, filter_map_filter_map] <;> rfl
 #align list.map_filter_map List.map_filterMap
+-/
 
+#print List.filterMap_map /-
 theorem filterMap_map (f : α → β) (g : β → Option γ) (l : List α) :
     filterMap g (map f l) = filterMap (g ∘ f) l := by
   rw [← filter_map_eq_map, filter_map_filter_map] <;> rfl
 #align list.filter_map_map List.filterMap_map
+-/
 
+#print List.filter_filterMap /-
 theorem filter_filterMap (f : α → Option β) (p : β → Prop) [DecidablePred p] (l : List α) :
     filter p (filterMap f l) = filterMap (fun x => (f x).filterₓ p) l := by
   rw [← filter_map_eq_filter, filter_map_filter_map] <;> rfl
 #align list.filter_filter_map List.filter_filterMap
+-/
 
+#print List.filterMap_filter /-
 theorem filterMap_filter (p : α → Prop) [DecidablePred p] (f : α → Option β) (l : List α) :
     filterMap f (filter p l) = filterMap (fun x => if p x then f x else none) l :=
   by
@@ -4609,6 +4732,7 @@ theorem filterMap_filter (p : α → Prop) [DecidablePred p] (f : α → Option
   · simp only [Option.guard, if_pos h, Option.some_bind']
   · simp only [Option.guard, if_neg h, Option.none_bind']
 #align list.filter_map_filter List.filterMap_filter
+-/
 
 #print List.filterMap_some /-
 @[simp]
@@ -4617,6 +4741,7 @@ theorem filterMap_some (l : List α) : filterMap some l = l := by
 #align list.filter_map_some List.filterMap_some
 -/
 
+#print List.map_filterMap_some_eq_filter_map_is_some /-
 theorem map_filterMap_some_eq_filter_map_is_some (f : α → Option β) (l : List α) :
     (l.filterMap f).map some = (l.map f).filterₓ fun b => b.isSome :=
   by
@@ -4624,7 +4749,9 @@ theorem map_filterMap_some_eq_filter_map_is_some (f : α → Option β) (l : Lis
   · simp
   · cases h : f x <;> rw [List.filterMap_cons, h] <;> simp [h, ih]
 #align list.map_filter_map_some_eq_filter_map_is_some List.map_filterMap_some_eq_filter_map_is_some
+-/
 
+#print List.mem_filterMap /-
 @[simp]
 theorem mem_filterMap (f : α → Option β) (l : List α) {b : β} :
     b ∈ filterMap f l ↔ ∃ a, a ∈ l ∧ f a = some b :=
@@ -4640,7 +4767,9 @@ theorem mem_filterMap (f : α → Option β) (l : List α) {b : β} :
     simp only [filter_map_cons_some _ _ _ h, IH, mem_cons_iff, or_and_right, exists_or, this,
       exists_eq_left]
 #align list.mem_filter_map List.mem_filterMap
+-/
 
+#print List.filterMap_join /-
 @[simp]
 theorem filterMap_join (f : α → Option β) (L : List (List α)) :
     filterMap f (join L) = join (map (filterMap f) L) :=
@@ -4649,28 +4778,35 @@ theorem filterMap_join (f : α → Option β) (L : List (List α)) :
   · rfl
   · rw [map, join, join, filter_map_append, ih]
 #align list.filter_map_join List.filterMap_join
+-/
 
+#print List.map_filterMap_of_inv /-
 theorem map_filterMap_of_inv (f : α → Option β) (g : β → α) (H : ∀ x : α, (f x).map g = some x)
     (l : List α) : map g (filterMap f l) = l := by simp only [map_filter_map, H, filter_map_some]
 #align list.map_filter_map_of_inv List.map_filterMap_of_inv
+-/
 
 theorem length_filter_le (p : α → Prop) [DecidablePred p] (l : List α) :
     (l.filterₓ p).length ≤ l.length :=
   (List.filter_sublist _).length_le
 #align list.length_filter_le List.length_filter_leₓ
 
+#print List.length_filterMap_le /-
 theorem length_filterMap_le (f : α → Option β) (l : List α) :
     (List.filterMap f l).length ≤ l.length :=
   by
   rw [← List.length_map some, List.map_filterMap_some_eq_filter_map_is_some, ← List.length_map f]
   apply List.length_filter_le
 #align list.length_filter_map_le List.length_filterMap_le
+-/
 
+#print List.Sublist.filterMap /-
 theorem Sublist.filterMap (f : α → Option β) {l₁ l₂ : List α} (s : l₁ <+ l₂) :
     filterMap f l₁ <+ filterMap f l₂ := by
   induction' s with l₁ l₂ a s IH l₁ l₂ a s IH <;> simp only [filter_map] <;> cases' f a with b <;>
     simp only [filter_map, IH, sublist.cons, sublist.cons2]
 #align list.sublist.filter_map List.Sublist.filterMap
+-/
 
 #print List.Sublist.map /-
 theorem Sublist.map (f : α → β) {l₁ l₂ : List α} (s : l₁ <+ l₂) : map f l₁ <+ map f l₂ :=
@@ -4809,15 +4945,20 @@ section Filter
 
 variable {p : α → Prop} [DecidablePred p]
 
+#print List.filter_singleton /-
 theorem filter_singleton {a : α} : [a].filterₓ p = if p a then [a] else [] :=
   rfl
 #align list.filter_singleton List.filter_singleton
+-/
 
+#print List.filter_eq_foldr /-
 theorem filter_eq_foldr (p : α → Prop) [DecidablePred p] (l : List α) :
     filter p l = foldr (fun a out => if p a then a :: out else out) [] l := by
   induction l <;> simp [*, Filter]
 #align list.filter_eq_foldr List.filter_eq_foldr
+-/
 
+#print List.filter_congr' /-
 theorem filter_congr' {p q : α → Prop} [DecidablePred p] [DecidablePred q] :
     ∀ {l : List α}, (∀ x ∈ l, p x ↔ q x) → filter p l = filter q l
   | [], _ => rfl
@@ -4829,12 +4970,16 @@ theorem filter_congr' {p q : α → Prop} [DecidablePred p] [DecidablePred q] :
         constructor <;>
       rfl
 #align list.filter_congr' List.filter_congr'
+-/
 
+#print List.filter_subset /-
 @[simp]
 theorem filter_subset (l : List α) : filter p l ⊆ l :=
   (filter_sublist l).Subset
 #align list.filter_subset List.filter_subset
+-/
 
+#print List.of_mem_filter /-
 theorem of_mem_filter {a : α} : ∀ {l}, a ∈ filter p l → p a
   | b :: l, ain =>
     if pb : p b then
@@ -4843,11 +4988,15 @@ theorem of_mem_filter {a : α} : ∀ {l}, a ∈ filter p l → p a
         fun this : a ∈ filter p l => of_mem_filter this
     else by simp only [filter_cons_of_neg _ pb] at ain ; exact of_mem_filter ain
 #align list.of_mem_filter List.of_mem_filter
+-/
 
+#print List.mem_of_mem_filter /-
 theorem mem_of_mem_filter {a : α} {l} (h : a ∈ filter p l) : a ∈ l :=
   filter_subset l h
 #align list.mem_of_mem_filter List.mem_of_mem_filter
+-/
 
+#print List.mem_filter_of_mem /-
 theorem mem_filter_of_mem {a : α} : ∀ {l}, a ∈ l → p a → a ∈ filter p l
   | _ :: l, Or.inl rfl, pa => by rw [filter_cons_of_pos _ pa] <;> apply mem_cons_self
   | b :: l, Or.inr ain, pa =>
@@ -4855,19 +5004,25 @@ theorem mem_filter_of_mem {a : α} : ∀ {l}, a ∈ l → p a → a ∈ filter p
       rw [filter_cons_of_pos _ pb] <;> apply mem_cons_of_mem <;> apply mem_filter_of_mem ain pa
     else by rw [filter_cons_of_neg _ pb] <;> apply mem_filter_of_mem ain pa
 #align list.mem_filter_of_mem List.mem_filter_of_mem
+-/
 
+#print List.mem_filter /-
 @[simp]
 theorem mem_filter {a : α} {l} : a ∈ filter p l ↔ a ∈ l ∧ p a :=
   ⟨fun h => ⟨mem_of_mem_filter h, of_mem_filter h⟩, fun ⟨h₁, h₂⟩ => mem_filter_of_mem h₁ h₂⟩
 #align list.mem_filter List.mem_filter
+-/
 
+#print List.monotone_filter_left /-
 theorem monotone_filter_left (p : α → Prop) [DecidablePred p] ⦃l l' : List α⦄ (h : l ⊆ l') :
     filter p l ⊆ filter p l' := by
   intro x hx
   rw [mem_filter] at hx ⊢
   exact ⟨h hx.left, hx.right⟩
 #align list.monotone_filter_left List.monotone_filter_left
+-/
 
+#print List.filter_eq_self /-
 theorem filter_eq_self {l} : filter p l = l ↔ ∀ a ∈ l, p a :=
   by
   induction' l with a l ih
@@ -4878,21 +5033,29 @@ theorem filter_eq_self {l} : filter p l = l ↔ ∀ a ∈ l, p a :=
     rw [hl]
     exact mem_cons_self _ _
 #align list.filter_eq_self List.filter_eq_self
+-/
 
+#print List.filter_length_eq_length /-
 theorem filter_length_eq_length {l} : (filter p l).length = l.length ↔ ∀ a ∈ l, p a :=
   Iff.trans ⟨l.filter_sublist.eq_of_length, congr_arg List.length⟩ filter_eq_self
 #align list.filter_length_eq_length List.filter_length_eq_length
+-/
 
+#print List.filter_eq_nil /-
 theorem filter_eq_nil {l} : filter p l = [] ↔ ∀ a ∈ l, ¬p a := by
   simp only [eq_nil_iff_forall_not_mem, mem_filter, not_and]
 #align list.filter_eq_nil List.filter_eq_nil
+-/
 
 variable (p)
 
+#print List.Sublist.filter /-
 theorem Sublist.filter {l₁ l₂} (s : l₁ <+ l₂) : filter p l₁ <+ filter p l₂ :=
   filterMap_eq_filter p ▸ s.filterMap _
 #align list.sublist.filter List.Sublist.filter
+-/
 
+#print List.monotone_filter_right /-
 theorem monotone_filter_right (l : List α) ⦃p q : α → Prop⦄ [DecidablePred p] [DecidablePred q]
     (h : p ≤ q) : l.filterₓ p <+ l.filterₓ q :=
   by
@@ -4908,11 +5071,15 @@ theorem monotone_filter_right (l : List α) ⦃p q : α → Prop⦄ [DecidablePr
       · rw [filter_cons_of_neg _ hq]
         exact IH
 #align list.monotone_filter_right List.monotone_filter_right
+-/
 
+#print List.map_filter /-
 theorem map_filter (f : β → α) (l : List β) : filter p (map f l) = map f (filter (p ∘ f) l) := by
   rw [← filter_map_eq_map, filter_filter_map, filter_map_filter] <;> rfl
 #align list.map_filter List.map_filter
+-/
 
+#print List.filter_filter /-
 @[simp]
 theorem filter_filter (q) [DecidablePred q] :
     ∀ l, filter p (filter q l) = filter (fun a => p a ∧ q a) l
@@ -4922,17 +5089,23 @@ theorem filter_filter (q) [DecidablePred q] :
       simp only [hp, hq, Filter, if_true, if_false, true_and_iff, false_and_iff, filter_filter l,
         eq_self_iff_true]
 #align list.filter_filter List.filter_filter
+-/
 
+#print List.filter_true /-
 @[simp]
 theorem filter_true {h : DecidablePred fun a : α => True} (l : List α) :
     @filter α (fun _ => True) h l = l := by convert filter_eq_self.2 fun _ _ => trivial
 #align list.filter_true List.filter_true
+-/
 
+#print List.filter_false /-
 @[simp]
 theorem filter_false {h : DecidablePred fun a : α => False} (l : List α) :
     @filter α (fun _ => False) h l = [] := by convert filter_eq_nil.2 fun _ _ => id
 #align list.filter_false List.filter_false
+-/
 
+#print List.span_eq_take_drop /-
 @[simp]
 theorem span_eq_take_drop : ∀ l : List α, span p l = (takeWhile p l, dropWhile p l)
   | [] => rfl
@@ -4940,7 +5113,9 @@ theorem span_eq_take_drop : ∀ l : List α, span p l = (takeWhile p l, dropWhil
     if pa : p a then by simp only [span, if_pos pa, span_eq_take_drop l, take_while, drop_while]
     else by simp only [span, take_while, drop_while, if_neg pa]
 #align list.span_eq_take_drop List.span_eq_take_drop
+-/
 
+#print List.takeWhile_append_dropWhile /-
 @[simp]
 theorem takeWhile_append_dropWhile : ∀ l : List α, takeWhile p l ++ dropWhile p l = l
   | [] => rfl
@@ -4949,7 +5124,9 @@ theorem takeWhile_append_dropWhile : ∀ l : List α, takeWhile p l ++ dropWhile
       rw [take_while, drop_while, if_pos pa, if_pos pa, cons_append, take_while_append_drop l]
     else by rw [take_while, drop_while, if_neg pa, if_neg pa, nil_append]
 #align list.take_while_append_drop List.takeWhile_append_dropWhile
+-/
 
+#print List.dropWhile_nthLe_zero_not /-
 theorem dropWhile_nthLe_zero_not (l : List α) (hl : 0 < (l.dropWhileₓ p).length) :
     ¬p ((l.dropWhileₓ p).nthLe 0 hl) :=
   by
@@ -4960,9 +5137,11 @@ theorem dropWhile_nthLe_zero_not (l : List α) (hl : 0 < (l.dropWhileₓ p).leng
     · exact IH _
     · simpa using hp
 #align list.drop_while_nth_le_zero_not List.dropWhile_nthLe_zero_not
+-/
 
 variable {p} {l : List α}
 
+#print List.dropWhile_eq_nil_iff /-
 @[simp]
 theorem dropWhile_eq_nil_iff : dropWhile p l = [] ↔ ∀ x ∈ l, p x :=
   by
@@ -4970,7 +5149,9 @@ theorem dropWhile_eq_nil_iff : dropWhile p l = [] ↔ ∀ x ∈ l, p x :=
   · simp [drop_while]
   · by_cases hp : p x <;> simp [hp, drop_while, IH]
 #align list.drop_while_eq_nil_iff List.dropWhile_eq_nil_iff
+-/
 
+#print List.takeWhile_eq_self_iff /-
 @[simp]
 theorem takeWhile_eq_self_iff : takeWhile p l = l ↔ ∀ x ∈ l, p x :=
   by
@@ -4978,7 +5159,9 @@ theorem takeWhile_eq_self_iff : takeWhile p l = l ↔ ∀ x ∈ l, p x :=
   · simp [take_while]
   · by_cases hp : p x <;> simp [hp, take_while, IH]
 #align list.take_while_eq_self_iff List.takeWhile_eq_self_iff
+-/
 
+#print List.takeWhile_eq_nil_iff /-
 @[simp]
 theorem takeWhile_eq_nil_iff : takeWhile p l = [] ↔ ∀ hl : 0 < l.length, ¬p (l.nthLe 0 hl) :=
   by
@@ -4986,7 +5169,9 @@ theorem takeWhile_eq_nil_iff : takeWhile p l = [] ↔ ∀ hl : 0 < l.length, ¬p
   · simp
   · by_cases hp : p x <;> simp [hp, take_while, IH]
 #align list.take_while_eq_nil_iff List.takeWhile_eq_nil_iff
+-/
 
+#print List.mem_takeWhile_imp /-
 theorem mem_takeWhile_imp {x : α} (hx : x ∈ takeWhile p l) : p x :=
   by
   induction' l with hd tl IH
@@ -4999,7 +5184,9 @@ theorem mem_takeWhile_imp {x : α} (hx : x ∈ takeWhile p l) : p x :=
       · exact IH hx
     · simpa using hx
 #align list.mem_take_while_imp List.mem_takeWhile_imp
+-/
 
+#print List.takeWhile_takeWhile /-
 theorem takeWhile_takeWhile (p q : α → Prop) [DecidablePred p] [DecidablePred q] (l : List α) :
     takeWhile p (takeWhile q l) = takeWhile (fun a => p a ∧ q a) l :=
   by
@@ -5007,10 +5194,13 @@ theorem takeWhile_takeWhile (p q : α → Prop) [DecidablePred p] [DecidablePred
   · simp [take_while]
   · by_cases hp : p hd <;> by_cases hq : q hd <;> simp [take_while, hp, hq, IH]
 #align list.take_while_take_while List.takeWhile_takeWhile
+-/
 
+#print List.takeWhile_idem /-
 theorem takeWhile_idem : takeWhile p (takeWhile p l) = takeWhile p l := by
   simp_rw [take_while_take_while, and_self_iff]
 #align list.take_while_idem List.takeWhile_idem
+-/
 
 end Filter
 
@@ -5251,17 +5441,21 @@ theorem erase_comm (a b : α) (l : List α) : (l.eraseₓ a).eraseₓ b = (l.era
     else by simp only [erase_of_not_mem ha, erase_of_not_mem (mt mem_of_mem_erase ha)]
 #align list.erase_comm List.erase_commₓ
 
+#print List.map_erase /-
 theorem map_erase [DecidableEq β] {f : α → β} (finj : Injective f) {a : α} (l : List α) :
     map f (l.eraseₓ a) = (map f l).eraseₓ (f a) :=
   by
   have this : Eq a = Eq (f a) ∘ f := by ext b; simp [finj.eq_iff]
   simp [erase_eq_erasep, erase_eq_erasep, erasep_map, this]
 #align list.map_erase List.map_erase
+-/
 
+#print List.map_foldl_erase /-
 theorem map_foldl_erase [DecidableEq β] {f : α → β} (finj : Injective f) {l₁ l₂ : List α} :
     map f (foldl List.erase l₁ l₂) = foldl (fun l a => l.eraseₓ (f a)) (map f l₁) l₂ := by
   induction l₂ generalizing l₁ <;> [rfl; simp only [foldl_cons, map_erase finj, *]]
 #align list.map_foldl_erase List.map_foldl_erase
+-/
 
 end Erase
 
@@ -5279,28 +5473,37 @@ theorem diff_nil (l : List α) : l.diffₓ [] = l :=
 #align list.diff_nil List.diff_nil
 -/
 
+#print List.diff_cons /-
 @[simp]
 theorem diff_cons (l₁ l₂ : List α) (a : α) : l₁.diffₓ (a :: l₂) = (l₁.eraseₓ a).diffₓ l₂ :=
   if h : a ∈ l₁ then by simp only [List.diff, if_pos h]
   else by simp only [List.diff, if_neg h, erase_of_not_mem h]
 #align list.diff_cons List.diff_cons
+-/
 
+#print List.diff_cons_right /-
 theorem diff_cons_right (l₁ l₂ : List α) (a : α) : l₁.diffₓ (a :: l₂) = (l₁.diffₓ l₂).eraseₓ a :=
   by
   induction' l₂ with b l₂ ih generalizing l₁ a
   · simp_rw [diff_cons, diff_nil]
   · rw [diff_cons, diff_cons, erase_comm, ← diff_cons, ih, ← diff_cons]
 #align list.diff_cons_right List.diff_cons_right
+-/
 
+#print List.diff_erase /-
 theorem diff_erase (l₁ l₂ : List α) (a : α) : (l₁.diffₓ l₂).eraseₓ a = (l₁.eraseₓ a).diffₓ l₂ := by
   rw [← diff_cons_right, diff_cons]
 #align list.diff_erase List.diff_erase
+-/
 
+#print List.nil_diff /-
 @[simp]
 theorem nil_diff (l : List α) : [].diffₓ l = [] := by
   induction l <;> [rfl; simp only [*, diff_cons, erase_of_not_mem (not_mem_nil _)]]
 #align list.nil_diff List.nil_diff
+-/
 
+#print List.cons_diff /-
 theorem cons_diff (a : α) (l₁ l₂ : List α) :
     (a :: l₁).diffₓ l₂ = if a ∈ l₂ then l₁.diffₓ (l₂.eraseₓ a) else a :: l₁.diffₓ l₂ :=
   by
@@ -5310,31 +5513,43 @@ theorem cons_diff (a : α) (l₁ l₂ : List α) :
   · simp only [mem_cons_iff, *, false_or_iff, diff_cons_right]
     split_ifs with h₂ <;> simp [diff_erase, List.erase, hne, hne.symm]
 #align list.cons_diff List.cons_diff
+-/
 
+#print List.cons_diff_of_mem /-
 theorem cons_diff_of_mem {a : α} {l₂ : List α} (h : a ∈ l₂) (l₁ : List α) :
     (a :: l₁).diffₓ l₂ = l₁.diffₓ (l₂.eraseₓ a) := by rw [cons_diff, if_pos h]
 #align list.cons_diff_of_mem List.cons_diff_of_mem
+-/
 
+#print List.cons_diff_of_not_mem /-
 theorem cons_diff_of_not_mem {a : α} {l₂ : List α} (h : a ∉ l₂) (l₁ : List α) :
     (a :: l₁).diffₓ l₂ = a :: l₁.diffₓ l₂ := by rw [cons_diff, if_neg h]
 #align list.cons_diff_of_not_mem List.cons_diff_of_not_mem
+-/
 
+#print List.diff_eq_foldl /-
 theorem diff_eq_foldl : ∀ l₁ l₂ : List α, l₁.diffₓ l₂ = foldl List.erase l₁ l₂
   | l₁, [] => rfl
   | l₁, a :: l₂ => (diff_cons l₁ l₂ a).trans (diff_eq_foldl _ _)
 #align list.diff_eq_foldl List.diff_eq_foldl
+-/
 
+#print List.diff_append /-
 @[simp]
 theorem diff_append (l₁ l₂ l₃ : List α) : l₁.diffₓ (l₂ ++ l₃) = (l₁.diffₓ l₂).diffₓ l₃ := by
   simp only [diff_eq_foldl, foldl_append]
 #align list.diff_append List.diff_append
+-/
 
+#print List.map_diff /-
 @[simp]
 theorem map_diff [DecidableEq β] {f : α → β} (finj : Injective f) {l₁ l₂ : List α} :
     map f (l₁.diffₓ l₂) = (map f l₁).diffₓ (map f l₂) := by
   simp only [diff_eq_foldl, foldl_map, map_foldl_erase finj]
 #align list.map_diff List.map_diff
+-/
 
+#print List.diff_sublist /-
 theorem diff_sublist : ∀ l₁ l₂ : List α, l₁.diffₓ l₂ <+ l₁
   | l₁, [] => Sublist.refl _
   | l₁, a :: l₂ =>
@@ -5343,11 +5558,15 @@ theorem diff_sublist : ∀ l₁ l₂ : List α, l₁.diffₓ l₂ <+ l₁
       _ <+ l₁.eraseₓ a := (diff_sublist _ _)
       _ <+ l₁ := List.erase_sublist _ _
 #align list.diff_sublist List.diff_sublist
+-/
 
+#print List.diff_subset /-
 theorem diff_subset (l₁ l₂ : List α) : l₁.diffₓ l₂ ⊆ l₁ :=
   (diff_sublist _ _).Subset
 #align list.diff_subset List.diff_subset
+-/
 
+#print List.mem_diff_of_mem /-
 theorem mem_diff_of_mem {a : α} : ∀ {l₁ l₂ : List α}, a ∈ l₁ → a ∉ l₂ → a ∈ l₁.diffₓ l₂
   | l₁, [], h₁, h₂ => h₁
   | l₁, b :: l₂, h₁, h₂ => by
@@ -5356,12 +5575,16 @@ theorem mem_diff_of_mem {a : α} : ∀ {l₁ l₂ : List α}, a ∈ l₁ → a 
         mem_diff_of_mem ((mem_erase_of_ne (ne_of_not_mem_cons h₂)).2 h₁)
           (not_mem_of_not_mem_cons h₂)
 #align list.mem_diff_of_mem List.mem_diff_of_mem
+-/
 
+#print List.Sublist.diff_right /-
 theorem Sublist.diff_right : ∀ {l₁ l₂ l₃ : List α}, l₁ <+ l₂ → l₁.diffₓ l₃ <+ l₂.diffₓ l₃
   | l₁, l₂, [], h => h
   | l₁, l₂, a :: l₃, h => by simp only [diff_cons, (h.erase _).diff_right]
 #align list.sublist.diff_right List.Sublist.diff_right
+-/
 
+#print List.erase_diff_erase_sublist_of_sublist /-
 theorem erase_diff_erase_sublist_of_sublist {a : α} :
     ∀ {l₁ l₂ : List α}, l₁ <+ l₂ → (l₂.eraseₓ a).diffₓ (l₁.eraseₓ a) <+ l₂.diffₓ l₁
   | [], l₂, h => erase_sublist _ _
@@ -5371,6 +5594,7 @@ theorem erase_diff_erase_sublist_of_sublist {a : α} :
       simpa only [erase_cons_head, erase_cons_tail _ HEq, diff_cons, erase_comm a b l₂] using
         erase_diff_erase_sublist_of_sublist (h.erase b)
 #align list.erase_diff_erase_sublist_of_sublist List.erase_diff_erase_sublist_of_sublist
+-/
 
 end Diff
 
@@ -5390,6 +5614,7 @@ theorem length_enum : ∀ l : List α, length (enum l) = length l :=
 #align list.length_enum List.length_enum
 -/
 
+#print List.enumFrom_get? /-
 @[simp]
 theorem enumFrom_get? :
     ∀ (n) (l : List α) (m), get? (enumFrom n l) m = (fun a => (n + m, a)) <$> get? l m
@@ -5397,11 +5622,14 @@ theorem enumFrom_get? :
   | n, a :: l, 0 => rfl
   | n, a :: l, m + 1 => (enum_from_nth (n + 1) l m).trans <| by rw [add_right_comm] <;> rfl
 #align list.enum_from_nth List.enumFrom_get?
+-/
 
+#print List.enum_get? /-
 @[simp]
 theorem enum_get? : ∀ (l : List α) (n), get? (enum l) n = (fun a => (n, a)) <$> get? l n := by
   simp only [enum, enum_from_nth, zero_add] <;> intros <;> rfl
 #align list.enum_nth List.enum_get?
+-/
 
 #print List.enumFrom_map_snd /-
 @[simp]
@@ -6072,6 +6300,7 @@ theorem dropSlice_eq (xs : List α) (n m : ℕ) : dropSlice n m xs = xs.take n +
 #align list.slice_eq List.dropSlice_eq
 -/
 
+#print List.sizeOf_dropSlice_lt /-
 theorem sizeOf_dropSlice_lt [SizeOf α] (i j : ℕ) (hj : 0 < j) (xs : List α) (hi : i < xs.length) :
     SizeOf.sizeOf (List.dropSlice i j xs) < SizeOf.sizeOf xs :=
   by
@@ -6094,6 +6323,7 @@ theorem sizeOf_dropSlice_lt [SizeOf α] (i j : ℕ) (hj : 0 < j) (xs : List α)
     · unfold_wf; apply xs_ih _ _ h
       apply lt_of_succ_lt_succ hi
 #align list.sizeof_slice_lt List.sizeOf_dropSlice_lt
+-/
 
 /-! ### nthd and inth -/
 
Diff
@@ -2323,7 +2323,6 @@ theorem get_reverse_aux₂ :
       calc
         length (a :: l) - 1 - (i + 1) = length l - (1 + i) := by rw [add_comm] <;> rfl
         _ = length l - 1 - i := by rw [← tsub_add_eq_tsub_tsub]
-        
     rw [← HEq] at aux 
     apply aux
 #align list.nth_le_reverse_aux2 List.get_reverse_aux₂
@@ -3249,7 +3248,6 @@ theorem drop_length (l : List α) : l.drop l.length = [] :=
   calc
     l.drop l.length = (l ++ []).drop l.length := by simp
     _ = [] := drop_left _ _
-    
 #align list.drop_length List.drop_length
 -/
 
@@ -3343,7 +3341,6 @@ theorem drop_drop (n : ℕ) : ∀ (m) (l : List α), drop n (drop m l) = drop (n
       drop n (drop (m + 1) (a :: l)) = drop n (drop m l) := rfl
       _ = drop (n + m) l := (drop_drop m l)
       _ = drop (n + (m + 1)) (a :: l) := rfl
-      
 #align list.drop_drop List.drop_drop
 -/
 
@@ -3928,7 +3925,6 @@ theorem foldl_assoc : ∀ {l : List α} {a₁ a₂}, (l <*> a₁ * a₂) = a₁
     calc
       ((a :: l) <*> a₁ * a₂) = l <*> a₁ * a₂ * a := by simp only [foldl_cons, ha.assoc]
       _ = a₁ * (a :: l) <*> a₂ := by rw [foldl_assoc, foldl_cons]
-      
 #align list.foldl_assoc List.foldl_assoc
 -/
 
@@ -5346,7 +5342,6 @@ theorem diff_sublist : ∀ l₁ l₂ : List α, l₁.diffₓ l₂ <+ l₁
       l₁.diffₓ (a :: l₂) = (l₁.eraseₓ a).diffₓ l₂ := diff_cons _ _ _
       _ <+ l₁.eraseₓ a := (diff_sublist _ _)
       _ <+ l₁ := List.erase_sublist _ _
-      
 #align list.diff_sublist List.diff_sublist
 
 theorem diff_subset (l₁ l₂ : List α) : l₁.diffₓ l₂ ⊆ l₁ :=
@@ -6053,7 +6048,6 @@ theorem nthLe_attach (L : List α) (i) (H : i < L.attach.length) :
     (L.attach.nthLe i H).1 = (L.attach.map Subtype.val).nthLe i (by simpa using H) := by
       rw [nth_le_map']
     _ = L.nthLe i _ := by congr <;> apply attach_map_val
-    
 #align list.nth_le_attach List.nthLe_attach
 -/
 
Diff
@@ -108,7 +108,7 @@ theorem exists_cons_of_ne_nil {l : List α} (h : l ≠ nil) : ∃ b L, l = b ::
 -/
 
 #print List.set_of_mem_cons /-
-theorem set_of_mem_cons (l : List α) (a : α) : { x | x ∈ a :: l } = insert a { x | x ∈ l } :=
+theorem set_of_mem_cons (l : List α) (a : α) : {x | x ∈ a :: l} = insert a {x | x ∈ l} :=
   rfl
 #align list.set_of_mem_cons List.set_of_mem_cons
 -/
@@ -3118,7 +3118,7 @@ theorem take_add (l : List α) (m n : ℕ) : l.take (m + n) = l.take m ++ (l.dro
   simp only [take_eq_take, length_take, length_drop]
   generalize l.length = k; by_cases h : m ≤ k
   · simp [min_eq_left_iff.mpr h]
-  · push_neg  at h ; simp [Nat.sub_eq_zero_of_le (le_of_lt h)]
+  · push_neg at h ; simp [Nat.sub_eq_zero_of_le (le_of_lt h)]
 #align list.take_add List.take_add
 -/
 
@@ -4996,7 +4996,7 @@ theorem mem_takeWhile_imp {x : α} (hx : x ∈ takeWhile p l) : p x :=
   induction' l with hd tl IH
   · simpa [take_while] using hx
   · simp only [take_while] at hx 
-    split_ifs  at hx 
+    split_ifs at hx 
     · rw [mem_cons_iff] at hx 
       rcases hx with (rfl | hx)
       · exact h
Diff
@@ -165,7 +165,7 @@ theorem not_mem_append {a : α} {s t : List α} (h₁ : a ∉ s) (h₂ : a ∉ t
 
 #print List.ne_nil_of_mem /-
 theorem ne_nil_of_mem {a : α} {l : List α} (h : a ∈ l) : l ≠ [] := by
-  intro e <;> rw [e] at h <;> cases h
+  intro e <;> rw [e] at h  <;> cases h
 #align list.ne_nil_of_mem List.ne_nil_of_mem
 -/
 
@@ -218,9 +218,9 @@ theorem mem_map {f : α → β} {b : β} {l : List α} : b ∈ map f l ↔ ∃ a
   · refine' (or_congr eq_comm ihl).trans _
     constructor
     · rintro (h | ⟨c, hcl, h⟩)
-      exacts[⟨a, Or.inl rfl, h⟩, ⟨c, Or.inr hcl, h⟩]
+      exacts [⟨a, Or.inl rfl, h⟩, ⟨c, Or.inr hcl, h⟩]
     · rintro ⟨c, hc | hc, h⟩
-      exacts[Or.inl <| (congr_arg f hc.symm).trans h, Or.inr ⟨c, hc, h⟩]
+      exacts [Or.inl <| (congr_arg f hc.symm).trans h, Or.inr ⟨c, hc, h⟩]
 #align list.mem_map List.mem_map
 
 alias mem_map ↔ exists_of_mem_map _
@@ -405,7 +405,7 @@ theorem length_injective_iff : Injective (List.length : List α → ℕ) ↔ Sub
   · intro h; refine' ⟨fun x y => _⟩; suffices [x] = [y] by simpa using this; apply h; rfl
   · intro hα l1 l2 hl; induction l1 generalizing l2 <;> cases l2
     · rfl; · cases hl; · cases hl
-    congr ; exact Subsingleton.elim _ _; apply l1_ih; simpa using hl
+    congr; exact Subsingleton.elim _ _; apply l1_ih; simpa using hl
 #align list.length_injective_iff List.length_injective_iff
 -/
 
@@ -726,7 +726,7 @@ theorem append_inj' {s₁ s₂ t₁ t₂ : List α} (h : s₁ ++ t₁ = s₂ ++
     @Nat.add_right_cancel _ (length t₁) _ <|
       by
       let hap := congr_arg length h
-      simp only [length_append] at hap <;> rwa [← hl] at hap
+      simp only [length_append] at hap  <;> rwa [← hl] at hap 
 #align list.append_inj' List.append_inj'ₓ
 
 theorem append_inj_right' {s₁ s₂ t₁ t₂ : List α} (h : s₁ ++ t₁ = s₂ ++ t₂)
@@ -778,8 +778,8 @@ theorem append_left_inj {s₁ s₂ : List α} (t) : s₁ ++ t = s₂ ++ t ↔ s
 theorem map_eq_append_split {f : α → β} {l : List α} {s₁ s₂ : List β} (h : map f l = s₁ ++ s₂) :
     ∃ l₁ l₂, l = l₁ ++ l₂ ∧ map f l₁ = s₁ ∧ map f l₂ = s₂ :=
   by
-  have := h; rw [← take_append_drop (length s₁) l] at this⊢
-  rw [map_append] at this
+  have := h; rw [← take_append_drop (length s₁) l] at this ⊢
+  rw [map_append] at this 
   refine' ⟨_, _, rfl, append_inj this _⟩
   rw [length_map, length_take, min_eq_left]
   rw [← length_map f l, h, length_append]
@@ -874,7 +874,7 @@ theorem subset_singleton_iff {a : α} {L : List α} : L ⊆ [a] ↔ ∃ n, L = r
 #print List.map_replicate /-
 @[simp]
 theorem map_replicate (f : α → β) (n a) : map f (replicate n a) = replicate n (f a) := by
-  induction n <;> [rfl;simp only [*, replicate, map]] <;> constructor <;> rfl
+  induction n <;> [rfl; simp only [*, replicate, map]] <;> constructor <;> rfl
 #align list.map_replicate List.map_replicate
 -/
 
@@ -886,7 +886,7 @@ theorem tail_replicate (n) (a : α) : tail (replicate n a) = replicate (n - 1) a
 #print List.join_replicate_nil /-
 @[simp]
 theorem join_replicate_nil (n : ℕ) : join (replicate n []) = @nil α := by
-  induction n <;> [rfl;simp only [*, replicate, join, append_nil]]
+  induction n <;> [rfl; simp only [*, replicate, join, append_nil]]
 #align list.join_replicate_nil List.join_replicate_nil
 -/
 
@@ -996,7 +996,7 @@ theorem concat_eq_append' (a : α) (l : List α) : concat l a = l ++ [a] := by
 theorem init_eq_of_concat_eq {a : α} {l₁ l₂ : List α} : concat l₁ a = concat l₂ a → l₁ = l₂ :=
   by
   intro h
-  rw [concat_eq_append, concat_eq_append] at h
+  rw [concat_eq_append, concat_eq_append] at h 
   exact append_right_cancel h
 #align list.init_eq_of_concat_eq List.init_eq_of_concat_eq
 -/
@@ -1005,7 +1005,7 @@ theorem init_eq_of_concat_eq {a : α} {l₁ l₂ : List α} : concat l₁ a = co
 theorem last_eq_of_concat_eq {a b : α} {l : List α} : concat l a = concat l b → a = b :=
   by
   intro h
-  rw [concat_eq_append, concat_eq_append] at h
+  rw [concat_eq_append, concat_eq_append] at h 
   exact head_eq_of_cons_eq (append_left_cancel h)
 #align list.last_eq_of_concat_eq List.last_eq_of_concat_eq
 -/
@@ -1047,14 +1047,15 @@ attribute [local simp] reverse_core
 @[simp]
 theorem reverse_cons (a : α) (l : List α) : reverse (a :: l) = reverse l ++ [a] :=
   have aux : ∀ l₁ l₂, reverseAux l₁ l₂ ++ [a] = reverseAux l₁ (l₂ ++ [a]) := by
-    intro l₁ <;> induction l₁ <;> intros <;> [rfl;simp only [*, reverse_core, cons_append]]
+    intro l₁ <;> induction l₁ <;> intros <;> [rfl; simp only [*, reverse_core, cons_append]]
   (aux l nil).symm
 #align list.reverse_cons List.reverse_cons
 -/
 
 #print List.reverseAux_eq /-
 theorem reverseAux_eq (l₁ l₂ : List α) : reverseAux l₁ l₂ = reverse l₁ ++ l₂ := by
-  induction l₁ generalizing l₂ <;> [rfl;simp only [*, reverse_core, reverse_cons, append_assoc]] <;>
+  induction l₁ generalizing l₂ <;> [rfl;
+      simp only [*, reverse_core, reverse_cons, append_assoc]] <;>
     rfl
 #align list.reverse_core_eq List.reverseAux_eq
 -/
@@ -1075,9 +1076,8 @@ theorem reverse_singleton (a : α) : reverse [a] = [a] :=
 #print List.reverse_append /-
 @[simp]
 theorem reverse_append (s t : List α) : reverse (s ++ t) = reverse t ++ reverse s := by
-  induction s <;>
-    [rw [nil_append, reverse_nil,
-      append_nil];simp only [*, cons_append, reverse_cons, append_assoc]]
+  induction s <;> [rw [nil_append, reverse_nil, append_nil];
+    simp only [*, cons_append, reverse_cons, append_assoc]]
 #align list.reverse_append List.reverse_append
 -/
 
@@ -1090,7 +1090,7 @@ theorem reverse_concat (l : List α) (a : α) : reverse (concat l a) = a :: reve
 #print List.reverse_reverse /-
 @[simp]
 theorem reverse_reverse (l : List α) : reverse (reverse l) = l := by
-  induction l <;> [rfl;simp only [*, reverse_cons, reverse_append]] <;> rfl
+  induction l <;> [rfl; simp only [*, reverse_cons, reverse_append]] <;> rfl
 #align list.reverse_reverse List.reverse_reverse
 -/
 
@@ -1149,14 +1149,14 @@ theorem concat_eq_reverse_cons (a : α) (l : List α) : concat l a = reverse (a
 #print List.length_reverse /-
 @[simp]
 theorem length_reverse (l : List α) : length (reverse l) = length l := by
-  induction l <;> [rfl;simp only [*, reverse_cons, length_append, length]]
+  induction l <;> [rfl; simp only [*, reverse_cons, length_append, length]]
 #align list.length_reverse List.length_reverse
 -/
 
 #print List.map_reverse /-
 @[simp]
 theorem map_reverse (f : α → β) (l : List α) : map f (reverse l) = reverse (map f l) := by
-  induction l <;> [rfl;simp only [*, map, reverse_cons, map_append]]
+  induction l <;> [rfl; simp only [*, map, reverse_cons, map_append]]
 #align list.map_reverse List.map_reverse
 -/
 
@@ -1170,9 +1170,9 @@ theorem map_reverseAux (f : α → β) (l₁ l₂ : List α) :
 #print List.mem_reverse' /-
 @[simp]
 theorem mem_reverse' {a : α} {l : List α} : a ∈ reverse l ↔ a ∈ l := by
-  induction l <;>
-    [rfl;simp only [*, reverse_cons, mem_append, mem_singleton, mem_cons_iff, not_mem_nil,
-      false_or_iff, or_false_iff, or_comm']]
+  induction l <;> [rfl;
+    simp only [*, reverse_cons, mem_append, mem_singleton, mem_cons_iff, not_mem_nil, false_or_iff,
+      or_false_iff, or_comm']]
 #align list.mem_reverse List.mem_reverse'
 -/
 
@@ -1216,7 +1216,7 @@ theorem length_dropLast : ∀ l : List α, length (dropLast l) = length l - 1
 #print List.getLast_cons /-
 @[simp]
 theorem getLast_cons {a : α} {l : List α} :
-    ∀ h : l ≠ nil, getLast (a :: l) (cons_ne_nil a l) = getLast l h := by induction l <;> intros ;
+    ∀ h : l ≠ nil, getLast (a :: l) (cons_ne_nil a l) = getLast l h := by induction l <;> intros;
   contradiction; rfl
 #align list.last_cons List.getLast_cons
 -/
@@ -1225,8 +1225,8 @@ theorem getLast_cons {a : α} {l : List α} :
 @[simp]
 theorem getLast_append_singleton {a : α} (l : List α) :
     getLast (l ++ [a]) (append_ne_nil_of_ne_nil_right l _ (cons_ne_nil a _)) = a := by
-  induction l <;>
-    [rfl;simp only [cons_append, last_cons fun H => cons_ne_nil _ _ (append_eq_nil.1 H).2, *]]
+  induction l <;> [rfl;
+    simp only [cons_append, last_cons fun H => cons_ne_nil _ _ (append_eq_nil.1 H).2, *]]
 #align list.last_append_singleton List.getLast_append_singleton
 -/
 
@@ -1323,7 +1323,7 @@ theorem mem_getLast?_eq_getLast : ∀ {l : List α} {x : α}, x ∈ l.getLast? 
     have : a = x := by simpa using hx
     this ▸ ⟨cons_ne_nil a [], rfl⟩
   | a :: b :: l, x, hx => by
-    rw [last'] at hx
+    rw [last'] at hx 
     rcases mem_last'_eq_last hx with ⟨h₁, h₂⟩
     use cons_ne_nil _ _
     rwa [last_cons]
@@ -1356,7 +1356,7 @@ theorem mem_of_mem_getLast? {l : List α} {a : α} (ha : a ∈ l.getLast?) : a 
 theorem dropLast_append_getLast? : ∀ {l : List α}, ∀ a ∈ l.getLast?, dropLast l ++ [a] = l
   | [], a, ha => (Option.not_mem_none a ha).elim
   | [a], _, rfl => rfl
-  | a :: b :: l, c, hc => by rw [last'] at hc; rw [init, cons_append, init_append_last' _ hc]
+  | a :: b :: l, c, hc => by rw [last'] at hc ; rw [init, cons_append, init_append_last' _ hc]
 #align list.init_append_last' List.dropLast_append_getLast?
 -/
 
@@ -1430,7 +1430,7 @@ theorem surjective_tail : Surjective (@tail α)
 #print List.eq_cons_of_mem_head? /-
 theorem eq_cons_of_mem_head? {x : α} : ∀ {l : List α}, x ∈ l.head? → l = x :: tail l
   | [], h => (Option.not_mem_none _ h).elim
-  | a :: l, h => by simp only [head', Option.mem_def] at h; exact h ▸ rfl
+  | a :: l, h => by simp only [head', Option.mem_def] at h ; exact h ▸ rfl
 #align list.eq_cons_of_mem_head' List.eq_cons_of_mem_head?
 -/
 
@@ -1491,7 +1491,7 @@ theorem tail_append_singleton_of_ne_nil {a : α} {l : List α} (h : l ≠ nil) :
 #print List.cons_head?_tail /-
 theorem cons_head?_tail : ∀ {l : List α} {a : α} (h : a ∈ head? l), a :: tail l = l
   | [], a, h => by contradiction
-  | b :: l, a, h => by simp at h; simp [h]
+  | b :: l, a, h => by simp at h ; simp [h]
 #align list.cons_head'_tail List.cons_head?_tail
 -/
 
@@ -1512,7 +1512,7 @@ theorem cons_head!_tail [Inhabited α] {l : List α} (h : l ≠ []) : headI l ::
 theorem head!_mem_self [Inhabited α] {l : List α} (h : l ≠ nil) : l.headI ∈ l :=
   by
   have h' := mem_cons_self l.head l.tail
-  rwa [cons_head_tail h] at h'
+  rwa [cons_head_tail h] at h' 
 #align list.head_mem_self List.head!_mem_self
 -/
 
@@ -1558,7 +1558,7 @@ theorem nthLe_cons {l : List α} {a : α} {n} (hl) :
   split_ifs
   · simp [nth_le, h]
   cases l
-  · rw [length_singleton, lt_succ_iff, nonpos_iff_eq_zero] at hl; contradiction
+  · rw [length_singleton, lt_succ_iff, nonpos_iff_eq_zero] at hl ; contradiction
   cases n
   · contradiction
   rfl
@@ -1603,7 +1603,8 @@ def bidirectionalRec {C : List α → Sort _} (H0 : C []) (H1 : ∀ a : α, C [a
     have : length l' < length (a :: b :: l) := by change _ < length l + 2; simp
     rw [← init_append_last (cons_ne_nil b l)]
     have : C l' := bidirectional_rec l'
-    exact Hn a l' b' ‹C l'›termination_by' ⟨_, measure_wf List.length⟩
+    exact Hn a l' b' ‹C l'›
+termination_by' ⟨_, measure_wf List.length⟩
 #align list.bidirectional_rec List.bidirectionalRecₓ
 
 #print List.bidirectionalRecOn /-
@@ -1811,7 +1812,7 @@ theorem sublist_nil_iff_eq_nil {l : List α} : l <+ [] ↔ l = [] :=
 @[simp]
 theorem replicate_sublist_replicate (a : α) {m n} : replicate m a <+ replicate n a ↔ m ≤ n :=
   ⟨fun h => by simpa only [length_replicate] using h.length_le, fun h => by
-    induction h <;> [rfl;simp only [*, replicate_succ, sublist.cons]]⟩
+    induction h <;> [rfl; simp only [*, replicate_succ, sublist.cons]]⟩
 #align list.replicate_sublist_replicate List.replicate_sublist_replicate
 
 theorem sublist_replicate_iff {l : List α} {a : α} {n : ℕ} :
@@ -1828,7 +1829,7 @@ theorem Sublist.eq_of_length : ∀ {l₁ l₂ : List α}, l₁ <+ l₂ → lengt
   | _, _, sublist.cons l₁ l₂ a s, h => by
     cases s.length_le.not_lt (by rw [h] <;> apply lt_succ_self)
   | _, _, sublist.cons2 l₁ l₂ a s, h => by
-    rw [length, length] at h <;> injection h with h <;> rw [s.eq_of_length h]
+    rw [length, length] at h  <;> injection h with h <;> rw [s.eq_of_length h]
 #align list.sublist.eq_of_length List.Sublist.eq_of_length
 -/
 
@@ -1997,8 +1998,8 @@ theorem get?_length (l : List α) : l.get? l.length = none :=
 #print List.get?_eq_some' /-
 theorem get?_eq_some' {l : List α} {n a} : get? l n = some a ↔ ∃ h, nthLe l n h = a :=
   ⟨fun e =>
-    have h : n < length l := lt_of_not_ge fun hn => by rw [nth_len_le hn] at e <;> contradiction
-    ⟨h, by rw [nth_le_nth h] at e <;> injection e with e <;> apply nth_le_mem⟩,
+    have h : n < length l := lt_of_not_ge fun hn => by rw [nth_len_le hn] at e  <;> contradiction
+    ⟨h, by rw [nth_le_nth h] at e  <;> injection e with e <;> apply nth_le_mem⟩,
     fun ⟨h, e⟩ => e ▸ nthLe_get? _⟩
 #align list.nth_eq_some List.get?_eq_some'
 -/
@@ -2007,10 +2008,10 @@ theorem get?_eq_some' {l : List α} {n a} : get? l n = some a ↔ ∃ h, nthLe l
 @[simp]
 theorem get?_eq_none : ∀ {l : List α} {n}, get? l n = none ↔ length l ≤ n :=
   by
-  intros ; constructor
+  intros; constructor
   · intro h; by_contra h'
     have h₂ : ∃ h, l.nth_le n h = l.nth_le n (lt_of_not_ge h') := ⟨lt_of_not_ge h', rfl⟩
-    rw [← nth_eq_some, h] at h₂; cases h₂
+    rw [← nth_eq_some, h] at h₂ ; cases h₂
   · solve_by_elim [nth_len_le]
 #align list.nth_eq_none_iff List.get?_eq_none
 -/
@@ -2062,14 +2063,16 @@ theorem get?_injective {α : Type u} {xs : List α} {i j : ℕ} (h₀ : i < xs.l
   · cases i <;> cases j
     case zero.zero => rfl
     case succ.succ =>
-      congr ; cases h₁
+      congr; cases h₁
       apply xs_ih <;> solve_by_elim [lt_of_succ_lt_succ]
     iterate 2 
-      dsimp at h₂
+      dsimp at h₂ 
       cases' h₁ with _ _ h h'
       cases h x _ rfl
       rw [mem_iff_nth]
-      first |exact ⟨_, h₂.symm⟩|exact ⟨_, h₂⟩
+      first
+      | exact ⟨_, h₂.symm⟩
+      | exact ⟨_, h₂⟩
 #align list.nth_injective List.get?_injective
 -/
 
@@ -2107,7 +2110,7 @@ theorem nthLe_map' (f : α → β) {l n} (H) :
 `hi` gives `i < L.length` and not `i < L'.length`. The lemma `nth_le_of_eq` can be used to make
 such a rewrite, with `rw (nth_le_of_eq h)`. -/
 theorem nthLe_of_eq {L L' : List α} (h : L = L') {i : ℕ} (hi : i < L.length) :
-    nthLe L i hi = nthLe L' i (h ▸ hi) := by congr ; exact h
+    nthLe L i hi = nthLe L' i (h ▸ hi) := by congr; exact h
 #align list.nth_le_of_eq List.nthLe_of_eq
 -/
 
@@ -2139,7 +2142,7 @@ theorem nthLe_append :
 theorem get_append_right_aux {l₁ l₂ : List α} {n : ℕ} (h₁ : l₁.length ≤ n)
     (h₂ : n < (l₁ ++ l₂).length) : n - l₁.length < l₂.length :=
   by
-  rw [List.length_append] at h₂
+  rw [List.length_append] at h₂ 
   apply lt_of_add_lt_add_right
   rwa [Nat.sub_add_cancel h₁, Nat.add_comm]
 #align list.nth_le_append_right_aux List.get_append_right_aux
@@ -2185,7 +2188,7 @@ theorem get?_append_right {l₁ l₂ : List α} {n : ℕ} (hn : l₁.length ≤
   by_cases hl : n < (l₁ ++ l₂).length
   · rw [nth_le_nth hl, nth_le_nth, nth_le_append_right hn]
   · rw [nth_len_le (le_of_not_lt hl), nth_len_le]
-    rw [not_lt, length_append] at hl
+    rw [not_lt, length_append] at hl 
     exact le_tsub_of_add_le_left hl
 #align list.nth_append_right List.get?_append_right
 -/
@@ -2234,8 +2237,8 @@ theorem take_one_drop_eq_of_lt_length' {l : List α} {n : ℕ} (h : n < l.length
   induction' l with x l ih generalizing n
   · cases h
   · by_cases h₁ : l = []
-    · subst h₁; rw [nth_le_singleton]; simp [lt_succ_iff] at h; subst h; simp
-    have h₂ := h; rw [length_cons, Nat.lt_succ_iff, le_iff_eq_or_lt] at h₂
+    · subst h₁; rw [nth_le_singleton]; simp [lt_succ_iff] at h ; subst h; simp
+    have h₂ := h; rw [length_cons, Nat.lt_succ_iff, le_iff_eq_or_lt] at h₂ 
     cases n; · simp; rw [drop, nth_le]; apply ih
 #align list.take_one_drop_eq_of_lt_length List.take_one_drop_eq_of_lt_length'
 -/
@@ -2300,7 +2303,7 @@ theorem indexOf_inj [DecidableEq α] {l : List α} {x y : α} (hx : x ∈ l) (hy
       nthLe l (indexOf x l) (indexOf_lt_length.2 hx) =
         nthLe l (indexOf y l) (indexOf_lt_length.2 hy) :=
       by simp only [h]
-    simpa only [index_of_nth_le] , fun h => by subst h⟩
+    simpa only [index_of_nth_le], fun h => by subst h⟩
 #align list.index_of_inj List.indexOf_inj
 -/
 
@@ -2311,7 +2314,7 @@ theorem get_reverse_aux₂ :
   | [], r, i, h1, h2 => absurd h2 (Nat.not_lt_zero _)
   | a :: l, r, 0, h1, h2 => by
     have aux := nth_le_reverse_aux1 l (a :: r) 0
-    rw [zero_add] at aux
+    rw [zero_add] at aux 
     exact aux _ (zero_lt_succ _)
   | a :: l, r, i + 1, h1, h2 =>
     by
@@ -2321,7 +2324,7 @@ theorem get_reverse_aux₂ :
         length (a :: l) - 1 - (i + 1) = length l - (1 + i) := by rw [add_comm] <;> rfl
         _ = length l - 1 - i := by rw [← tsub_add_eq_tsub_tsub]
         
-    rw [← HEq] at aux
+    rw [← HEq] at aux 
     apply aux
 #align list.nth_le_reverse_aux2 List.get_reverse_aux₂
 -/
@@ -2644,7 +2647,7 @@ theorem insertNth_of_length_lt (l : List α) (x : α) (n : ℕ) (h : l.length <
     · simp
   · cases n
     · simpa using h
-    · simp only [Nat.succ_lt_succ_iff, length] at h
+    · simp only [Nat.succ_lt_succ_iff, length] at h 
       simpa using IH _ h
 #align list.insert_nth_of_length_lt List.insertNth_of_length_lt
 -/
@@ -2692,7 +2695,7 @@ theorem nthLe_insertNth_of_lt (l : List α) (x : α) (n k : ℕ) (hn : k < n) (h
     · simp
     · cases k
       · simp
-      · rw [Nat.succ_lt_succ_iff] at hn
+      · rw [Nat.succ_lt_succ_iff] at hn 
         simpa using IH _ _ hn _
 #align list.nth_le_insert_nth_of_lt List.nthLe_insertNth_of_lt
 -/
@@ -2704,11 +2707,11 @@ theorem nthLe_insertNth_self (l : List α) (x : α) (n : ℕ) (hn : n ≤ l.leng
     (insertNth n x l).nthLe n hn' = x :=
   by
   induction' l with hd tl IH generalizing n
-  · simp only [length, nonpos_iff_eq_zero] at hn
+  · simp only [length, nonpos_iff_eq_zero] at hn 
     simp [hn]
   · cases n
     · simp
-    · simp only [Nat.succ_le_succ_iff, length] at hn
+    · simp only [Nat.succ_le_succ_iff, length] at hn 
       simpa using IH _ hn
 #align list.nth_le_insert_nth_self List.nthLe_insertNth_self
 -/
@@ -2733,7 +2736,11 @@ theorem insertNth_injective (n : ℕ) (x : α) : Function.Injective (insertNth n
   induction' n with n IH
   · have : insert_nth 0 x = cons x := funext fun _ => rfl
     simp [this]
-  · rintro (_ | ⟨a, as⟩) (_ | ⟨b, bs⟩) h <;> first |simpa [IH.eq_iff] using h|rfl
+  ·
+    rintro (_ | ⟨a, as⟩) (_ | ⟨b, bs⟩) h <;>
+      first
+      | simpa [IH.eq_iff] using h
+      | rfl
 #align list.insert_nth_injective List.insertNth_injective
 -/
 
@@ -2766,15 +2773,15 @@ theorem map_congr {f g : α → β} : ∀ {l : List α}, (∀ x ∈ l, f x = g x
 theorem map_eq_map_iff {f g : α → β} {l : List α} : map f l = map g l ↔ ∀ x ∈ l, f x = g x :=
   by
   refine' ⟨_, map_congr⟩; intro h x hx
-  rw [mem_iff_nth_le] at hx; rcases hx with ⟨n, hn, rfl⟩
-  rw [nth_le_map_rev f, nth_le_map_rev g]; congr ; exact h
+  rw [mem_iff_nth_le] at hx ; rcases hx with ⟨n, hn, rfl⟩
+  rw [nth_le_map_rev f, nth_le_map_rev g]; congr; exact h
 #align list.map_eq_map_iff List.map_eq_map_iff
 -/
 
 #print List.map_concat /-
 theorem map_concat (f : α → β) (a : α) (l : List α) : map f (concat l a) = concat (map f l) (f a) :=
   by
-  induction l <;> [rfl;simp only [*, concat_eq_append, cons_append, map, map_append]] <;>
+  induction l <;> [rfl; simp only [*, concat_eq_append, cons_append, map, map_append]] <;>
       constructor <;>
     rfl
 #align list.map_concat List.map_concat
@@ -2802,7 +2809,7 @@ theorem eq_nil_of_map_eq_nil {f : α → β} {l : List α} (h : map f l = nil) :
 #print List.map_join /-
 @[simp]
 theorem map_join (f : α → β) (L : List (List α)) : map f (join L) = join (map (map f) L) := by
-  induction L <;> [rfl;simp only [*, join, map, map_append]]
+  induction L <;> [rfl; simp only [*, join, map, map_append]]
 #align list.map_join List.map_join
 -/
 
@@ -2840,7 +2847,7 @@ theorem map_injective_iff {f : α → β} : Injective (map f) ↔ Injective f :=
   constructor <;> intro h x y hxy
   · suffices [x] = [y] by simpa using this; apply h; simp [hxy]
   · induction y generalizing x; simpa using hxy
-    cases x; simpa using hxy; simp at hxy; simp [y_ih hxy.2, h hxy.1]
+    cases x; simpa using hxy; simp at hxy ; simp [y_ih hxy.2, h hxy.1]
 #align list.map_injective_iff List.map_injective_iff
 -/
 
@@ -2903,7 +2910,7 @@ theorem map_const' (l : List α) (b : β) : map (fun _ => b) l = replicate l.len
 
 #print List.eq_of_mem_map_const /-
 theorem eq_of_mem_map_const {b₁ b₂ : β} {l : List α} (h : b₁ ∈ map (const α b₂) l) : b₁ = b₂ := by
-  rw [map_const] at h <;> exact eq_of_mem_replicate h
+  rw [map_const] at h  <;> exact eq_of_mem_replicate h
 #align list.eq_of_mem_map_const List.eq_of_mem_map_const
 -/
 
@@ -3046,7 +3053,7 @@ theorem nthLe_take (L : List α) {i j : ℕ} (hi : i < L.length) (hj : i < j) :
 /-- The `i`-th element of a list coincides with the `i`-th element of any of its prefixes of
 length `> i`. Version designed to rewrite from the small list to the big list. -/
 theorem nthLe_take' (L : List α) {i j : ℕ} (hi : i < (L.take j).length) :
-    nthLe (L.take j) i hi = nthLe L i (lt_of_lt_of_le hi (by simp [le_refl])) := by simp at hi;
+    nthLe (L.take j) i hi = nthLe L i (lt_of_lt_of_le hi (by simp [le_refl])) := by simp at hi ;
   rw [nth_le_take L _ hi.1]
 #align list.nth_le_take' List.nthLe_take'
 -/
@@ -3055,7 +3062,7 @@ theorem nthLe_take' (L : List α) {i j : ℕ} (hi : i < (L.take j).length) :
 theorem get?_take {l : List α} {n m : ℕ} (h : m < n) : (l.take n).get? m = l.get? m :=
   by
   induction' n with n hn generalizing l m
-  · simp only [Nat.zero_eq] at h
+  · simp only [Nat.zero_eq] at h 
     exact absurd h (not_lt_of_le m.zero_le)
   · cases' l with hd tl
     · simp only [take_nil]
@@ -3111,7 +3118,7 @@ theorem take_add (l : List α) (m n : ℕ) : l.take (m + n) = l.take m ++ (l.dro
   simp only [take_eq_take, length_take, length_drop]
   generalize l.length = k; by_cases h : m ≤ k
   · simp [min_eq_left_iff.mpr h]
-  · push_neg  at h; simp [Nat.sub_eq_zero_of_le (le_of_lt h)]
+  · push_neg  at h ; simp [Nat.sub_eq_zero_of_le (le_of_lt h)]
 #align list.take_add List.take_add
 -/
 
@@ -3163,11 +3170,11 @@ theorem drop_eq_nil_iff_le {l : List α} {k : ℕ} : l.drop k = [] ↔ l.length
   by
   refine' ⟨fun h => _, drop_eq_nil_of_le⟩
   induction' k with k hk generalizing l
-  · simp only [drop] at h
+  · simp only [drop] at h 
     simp [h]
   · cases l
     · simp
-    · simp only [drop] at h
+    · simp only [drop] at h 
       simpa [Nat.succ_le_succ_iff] using hk h
 #align list.drop_eq_nil_iff_le List.drop_eq_nil_iff_le
 -/
@@ -3191,7 +3198,7 @@ theorem cons_nthLe_drop_succ {l : List α} {n : ℕ} (hn : n < l.length) :
   · exact absurd n.zero_le (not_le_of_lt (by simpa using hn))
   · cases n
     · simp
-    · simp only [Nat.succ_lt_succ_iff, List.length] at hn
+    · simp only [Nat.succ_lt_succ_iff, List.length] at hn 
       simpa [List.nthLe, List.drop] using hl hn
 #align list.cons_nth_le_drop_succ List.cons_nthLe_drop_succ
 -/
@@ -3301,7 +3308,7 @@ theorem nthLe_drop (L : List α) {i j : ℕ} (h : i + j < L.length) :
       nthLe (L.drop i) j
         (by
           have A : i < L.length := lt_of_le_of_lt (Nat.le.intro rfl) h
-          rw [(take_append_drop i L).symm] at h
+          rw [(take_append_drop i L).symm] at h 
           simpa only [le_of_lt A, min_eq_left, add_lt_add_iff_left, length_take,
             length_append] using h) :=
   by
@@ -3472,7 +3479,7 @@ theorem foldl_ext (f g : α → β → α) (a : α) {l : List β} (H : ∀ a : 
 theorem foldr_ext (f g : α → β → β) (b : β) {l : List α} (H : ∀ a ∈ l, ∀ b : β, f a b = g a b) :
     foldr f b l = foldr g b l := by
   induction' l with hd tl ih; · rfl
-  simp only [mem_cons_iff, or_imp, forall_and, forall_eq] at H
+  simp only [mem_cons_iff, or_imp, forall_and, forall_eq] at H 
   simp only [foldr, ih H.2, H.1]
 #align list.foldr_ext List.foldr_ext
 -/
@@ -3569,14 +3576,14 @@ theorem foldr_join (f : α → β → β) :
 
 theorem foldl_reverse (f : α → β → α) (a : α) (l : List β) :
     foldl f a (reverse l) = foldr (fun x y => f y x) a l := by
-  induction l <;> [rfl;simp only [*, reverse_cons, foldl_append, foldl_cons, foldl_nil, foldr]]
+  induction l <;> [rfl; simp only [*, reverse_cons, foldl_append, foldl_cons, foldl_nil, foldr]]
 #align list.foldl_reverse List.foldl_reverse
 
 theorem foldr_reverse (f : α → β → β) (a : β) (l : List α) :
     foldr f a (reverse l) = foldl (fun x y => f y x) a l :=
   by
   let t := foldl_reverse (fun x y => f y x) a (reverse l)
-  rw [reverse_reverse l] at t <;> rwa [t]
+  rw [reverse_reverse l] at t  <;> rwa [t]
 #align list.foldr_reverse List.foldr_reverse
 
 #print List.foldr_eta /-
@@ -3597,13 +3604,13 @@ theorem reverse_foldl {l : List α} : reverse (foldl (fun t h => h :: t) [] l) =
 @[simp]
 theorem foldl_map (g : β → γ) (f : α → γ → α) (a : α) (l : List β) :
     foldl f a (map g l) = foldl (fun x y => f x (g y)) a l := by
-  revert a <;> induction l <;> intros <;> [rfl;simp only [*, map, foldl]]
+  revert a <;> induction l <;> intros <;> [rfl; simp only [*, map, foldl]]
 #align list.foldl_map List.foldl_map
 
 @[simp]
 theorem foldr_map (g : β → γ) (f : γ → α → α) (a : α) (l : List β) :
     foldr f a (map g l) = foldr (f ∘ g) a l := by
-  revert a <;> induction l <;> intros <;> [rfl;simp only [*, map, foldr]]
+  revert a <;> induction l <;> intros <;> [rfl; simp only [*, map, foldr]]
 #align list.foldr_map List.foldr_map
 
 #print List.foldl_map' /-
@@ -3628,24 +3635,24 @@ theorem foldr_map' {α β : Type u} (g : α → β) (f : α → α → α) (f' :
 
 theorem foldl_hom (l : List γ) (f : α → β) (op : α → γ → α) (op' : β → γ → β) (a : α)
     (h : ∀ a x, f (op a x) = op' (f a) x) : foldl op' (f a) l = f (foldl op a l) :=
-  Eq.symm <| by revert a; induction l <;> intros <;> [rfl;simp only [*, foldl]]
+  Eq.symm <| by revert a; induction l <;> intros <;> [rfl; simp only [*, foldl]]
 #align list.foldl_hom List.foldl_hom
 
 theorem foldr_hom (l : List γ) (f : α → β) (op : γ → α → α) (op' : γ → β → β) (a : α)
     (h : ∀ x a, f (op x a) = op' x (f a)) : foldr op' (f a) l = f (foldr op a l) := by revert a;
-  induction l <;> intros <;> [rfl;simp only [*, foldr]]
+  induction l <;> intros <;> [rfl; simp only [*, foldr]]
 #align list.foldr_hom List.foldr_hom
 
 theorem foldl_hom₂ (l : List ι) (f : α → β → γ) (op₁ : α → ι → α) (op₂ : β → ι → β)
     (op₃ : γ → ι → γ) (a : α) (b : β) (h : ∀ a b i, f (op₁ a i) (op₂ b i) = op₃ (f a b) i) :
     foldl op₃ (f a b) l = f (foldl op₁ a l) (foldl op₂ b l) :=
-  Eq.symm <| by revert a b; induction l <;> intros <;> [rfl;simp only [*, foldl]]
+  Eq.symm <| by revert a b; induction l <;> intros <;> [rfl; simp only [*, foldl]]
 #align list.foldl_hom₂ List.foldl_hom₂
 
 theorem foldr_hom₂ (l : List ι) (f : α → β → γ) (op₁ : ι → α → α) (op₂ : ι → β → β)
     (op₃ : ι → γ → γ) (a : α) (b : β) (h : ∀ a b i, f (op₁ i a) (op₂ i b) = op₃ i (f a b)) :
     foldr op₃ (f a b) l = f (foldr op₁ a l) (foldr op₂ b l) := by revert a;
-  induction l <;> intros <;> [rfl;simp only [*, foldr]]
+  induction l <;> intros <;> [rfl; simp only [*, foldr]]
 #align list.foldr_hom₂ List.foldr_hom₂
 
 #print List.injective_foldl_comp /-
@@ -3786,11 +3793,11 @@ theorem nthLe_succ_scanl {i : ℕ} {h : i + 1 < (scanl f b l).length} :
   by
   induction' i with i hi generalizing b l
   · cases l
-    · simp only [length, zero_add, scanl_nil] at h
+    · simp only [length, zero_add, scanl_nil] at h 
       exact absurd h (lt_irrefl 1)
     · simp only [scanl_cons, singleton_append, nth_le_zero_scanl, nth_le]
   · cases l
-    · simp only [length, add_lt_iff_neg_right, scanl_nil] at h
+    · simp only [length, add_lt_iff_neg_right, scanl_nil] at h 
       exact absurd h (not_lt_of_lt Nat.succ_pos')
     · simp_rw [scanl_cons]
       rw [nth_le_append_right _]
@@ -4083,7 +4090,7 @@ theorem splitOnPAux_eq : splitOnPAux' p xs ys = splitOnPAux p xs ((· ++ ·) ys)
     simp! only [append_nil, eq_self_iff_true, and_self_iff]
   split_ifs <;> rw [ih]
   · refine' ⟨rfl, rfl⟩
-  · congr ; ext; simp
+  · congr; ext; simp
 #align list.split_on_p_aux_eq List.splitOnPAux_eq
 
 theorem splitOnPAux_nil : splitOnPAux p xs id = splitOnPAux' p xs [] := by rw [split_on_p_aux_eq];
@@ -4151,7 +4158,7 @@ theorem intercalate_splitOn (x : α) [DecidableEq α] : [x].intercalate (xs.spli
   simp only [intercalate, split_on]
   induction' xs with hd tl ih; · simp [join]; simp only [split_on_p_cons]
   cases' h' : split_on_p (· = x) tl with hd' tl'; · exact (split_on_p_ne_nil _ tl h').elim
-  rw [h'] at ih; split_ifs; · subst h; simp [ih, join]
+  rw [h'] at ih ; split_ifs; · subst h; simp [ih, join]
   cases tl' <;> simpa [join] using ih
 #align list.intercalate_split_on List.intercalate_splitOn
 -/
@@ -4166,13 +4173,13 @@ theorem splitOn_intercalate [DecidableEq α] (x : α) (hx : ∀ l ∈ ls, x ∉
   induction' ls with hd tl ih; · contradiction
   cases tl
   · suffices hd.split_on x = [hd] by simpa [join]
-    refine' split_on_p_eq_single _ _ _; intro y hy H; rw [H] at hy
+    refine' split_on_p_eq_single _ _ _; intro y hy H; rw [H] at hy 
     refine' hx hd _ hy; simp
   · simp only [intersperse_cons_cons, singleton_append, join]
-    specialize ih _ _; · intro l hl; apply hx l; simp at hl⊢; tauto; · trivial
+    specialize ih _ _; · intro l hl; apply hx l; simp at hl ⊢; tauto; · trivial
     have := split_on_p_first (· = x) hd _ x rfl _
-    · simp only [split_on] at ih⊢; rw [this]; rw [ih]
-    intro y hy H; rw [H] at hy; exact hx hd (Or.inl rfl) hy
+    · simp only [split_on] at ih ⊢; rw [this]; rw [ih]
+    intro y hy H; rw [H] at hy ; exact hx hd (Or.inl rfl) hy
 #align list.split_on_intercalate List.splitOn_intercalate
 -/
 
@@ -4213,7 +4220,7 @@ theorem sizeOf_lt_sizeOf_of_mem [SizeOf α] {x : α} {l : List α} (hx : x ∈ l
 @[simp]
 theorem pmap_eq_map (p : α → Prop) (f : α → β) (l : List α) (H) :
     @pmap _ _ p (fun a _ => f a) l H = map f l := by
-  induction l <;> [rfl;simp only [*, pmap, map]] <;> constructor <;> rfl
+  induction l <;> [rfl; simp only [*, pmap, map]] <;> constructor <;> rfl
 #align list.pmap_eq_map List.pmap_eq_map
 -/
 
@@ -4230,14 +4237,14 @@ theorem pmap_congr {p q : α → Prop} {f : ∀ a, p a → β} {g : ∀ a, q a 
 #print List.map_pmap /-
 theorem map_pmap {p : α → Prop} (g : β → γ) (f : ∀ a, p a → β) (l H) :
     map g (pmap f l H) = pmap (fun a h => g (f a h)) l H := by
-  induction l <;> [rfl;simp only [*, pmap, map]] <;> constructor <;> rfl
+  induction l <;> [rfl; simp only [*, pmap, map]] <;> constructor <;> rfl
 #align list.map_pmap List.map_pmap
 -/
 
 #print List.pmap_map /-
 theorem pmap_map {p : β → Prop} (g : ∀ b, p b → γ) (f : α → β) (l H) :
     pmap g (map f l) H = pmap (fun a h => g (f a) h) l fun a h => H _ (mem_map_of_mem _ h) := by
-  induction l <;> [rfl;simp only [*, pmap, map]] <;> constructor <;> rfl
+  induction l <;> [rfl; simp only [*, pmap, map]] <;> constructor <;> rfl
 #align list.pmap_map List.pmap_map
 -/
 
@@ -4288,7 +4295,7 @@ theorem mem_attach (l : List α) : ∀ x, x ∈ l.attach
 #print List.mem_pmap /-
 @[simp]
 theorem mem_pmap {p : α → Prop} {f : ∀ a, p a → β} {l H b} :
-    b ∈ pmap f l H ↔ ∃ (a : _)(h : a ∈ l), f a (H a h) = b := by
+    b ∈ pmap f l H ↔ ∃ (a : _) (h : a ∈ l), f a (H a h) = b := by
   simp only [pmap_eq_map_attach, mem_map, mem_attach, true_and_iff, Subtype.exists]
 #align list.mem_pmap List.mem_pmap
 -/
@@ -4296,7 +4303,7 @@ theorem mem_pmap {p : α → Prop} {f : ∀ a, p a → β} {l H b} :
 #print List.length_pmap /-
 @[simp]
 theorem length_pmap {p : α → Prop} {f : ∀ a, p a → β} {l H} : length (pmap f l H) = length l := by
-  induction l <;> [rfl;simp only [*, pmap, length]]
+  induction l <;> [rfl; simp only [*, pmap, length]]
 #align list.length_pmap List.length_pmap
 -/
 
@@ -4351,7 +4358,7 @@ theorem nthLe_pmap {p : α → Prop} (f : ∀ a, p a → β) {l : List α} (h :
         (h _ (nthLe_mem l n (@length_pmap _ _ p f l h ▸ hn))) :=
   by
   induction' l with hd tl hl generalizing n
-  · simp only [length, pmap] at hn
+  · simp only [length, pmap] at hn 
     exact absurd hn (not_lt_of_le n.zero_le)
   · cases n
     · simp
@@ -4414,8 +4421,8 @@ theorem find?_some (H : find? p l = some a) : p a :=
   by
   induction' l with b l IH; · contradiction
   by_cases h : p b
-  · rw [find_cons_of_pos _ h] at H; cases H; exact h
-  · rw [find_cons_of_neg _ h] at H; exact IH H
+  · rw [find_cons_of_pos _ h] at H ; cases H; exact h
+  · rw [find_cons_of_neg _ h] at H ; exact IH H
 #align list.find_some List.find?_some
 
 @[simp]
@@ -4423,8 +4430,8 @@ theorem find?_mem (H : find? p l = some a) : a ∈ l :=
   by
   induction' l with b l IH; · contradiction
   by_cases h : p b
-  · rw [find_cons_of_pos _ h] at H; cases H; apply mem_cons_self
-  · rw [find_cons_of_neg _ h] at H; exact mem_cons_of_mem _ (IH H)
+  · rw [find_cons_of_pos _ h] at H ; cases H; apply mem_cons_self
+  · rw [find_cons_of_neg _ h] at H ; exact mem_cons_of_mem _ (IH H)
 #align list.find_mem List.find?_mem
 
 end Find
@@ -4576,9 +4583,8 @@ theorem filterMap_filterMap (f : α → Option β) (g : β → Option γ) (l : L
   · rw [filter_map_cons_none _ _ h, filter_map_cons_none, IH]
     simp only [h, Option.none_bind']
   rw [filter_map_cons_some _ _ _ h]
-  cases' h' : g b with c <;>
-      [rw [filter_map_cons_none _ _ h', filter_map_cons_none,
-        IH];rw [filter_map_cons_some _ _ _ h', filter_map_cons_some, IH]] <;>
+  cases' h' : g b with c <;> [rw [filter_map_cons_none _ _ h', filter_map_cons_none, IH];
+      rw [filter_map_cons_some _ _ _ h', filter_map_cons_some, IH]] <;>
     simp only [h, h', Option.some_bind']
 #align list.filter_map_filter_map List.filterMap_filterMap
 
@@ -4630,10 +4636,10 @@ theorem mem_filterMap (f : α → Option β) (l : List α) {b : β} :
   induction' l with a l IH
   · constructor; · intro H; cases H; · rintro ⟨_, H, _⟩; cases H
   cases' h : f a with b'
-  · have : f a ≠ some b := by rw [h]; intro ; contradiction
+  · have : f a ≠ some b := by rw [h]; intro; contradiction
     simp only [filter_map_cons_none _ _ h, IH, mem_cons_iff, or_and_right, exists_or,
       exists_eq_left, this, false_or_iff]
-  · have : f a = some b ↔ b = b' := by constructor <;> intro t; · rw [t] at h <;> injection h;
+  · have : f a = some b ↔ b = b' := by constructor <;> intro t; · rw [t] at h  <;> injection h;
       · exact t.symm ▸ h
     simp only [filter_map_cons_some _ _ _ h, IH, mem_cons_iff, or_and_right, exists_or, this,
       exists_eq_left]
@@ -4746,7 +4752,7 @@ theorem reduceOption_length_eq_iff {l : List (Option α)} :
         reduce_option_cons_of_none, length, Option.isSome_none, iff_false_iff]
       intro H
       have := reduce_option_length_le tl
-      rw [H] at this
+      rw [H] at this 
       exact absurd (Nat.lt_succ_self _) (not_lt_of_le this)
     ·
       simp only [hl, true_and_iff, mem_cons_iff, forall_eq_or_imp, add_left_inj, Bool.coeSort_true,
@@ -4775,7 +4781,7 @@ theorem reduceOption_concat (l : List (Option α)) (x : Option α) :
   by
   induction' l with hd tl hl generalizing x
   · cases x <;> simp [Option.toList]
-  · simp only [concat_eq_append, reduce_option_append] at hl
+  · simp only [concat_eq_append, reduce_option_append] at hl 
     cases hd <;> simp [hl, reduce_option_append]
 #align list.reduce_option_concat List.reduceOption_concat
 -/
@@ -4820,10 +4826,9 @@ theorem filter_congr' {p q : α → Prop} [DecidablePred p] [DecidablePred q] :
     ∀ {l : List α}, (∀ x ∈ l, p x ↔ q x) → filter p l = filter q l
   | [], _ => rfl
   | a :: l, h => by
-    rw [forall_mem_cons] at h <;> by_cases pa : p a <;>
-          [simp only [filter_cons_of_pos _ pa, filter_cons_of_pos _ (h.1.1 pa),
-            filter_congr'
-              h.2];simp only [filter_cons_of_neg _ pa, filter_cons_of_neg _ (mt h.1.2 pa),
+    rw [forall_mem_cons] at h  <;> by_cases pa : p a <;>
+          [simp only [filter_cons_of_pos _ pa, filter_cons_of_pos _ (h.1.1 pa), filter_congr' h.2];
+          simp only [filter_cons_of_neg _ pa, filter_cons_of_neg _ (mt h.1.2 pa),
             filter_congr' h.2]] <;>
         constructor <;>
       rfl
@@ -4838,9 +4843,9 @@ theorem of_mem_filter {a : α} : ∀ {l}, a ∈ filter p l → p a
   | b :: l, ain =>
     if pb : p b then
       have : a ∈ b :: filter p l := by simpa only [filter_cons_of_pos _ pb] using ain
-      Or.elim (eq_or_mem_of_mem_cons this) (fun this : a = b => by rw [← this] at pb; exact pb)
+      Or.elim (eq_or_mem_of_mem_cons this) (fun this : a = b => by rw [← this] at pb ; exact pb)
         fun this : a ∈ filter p l => of_mem_filter this
-    else by simp only [filter_cons_of_neg _ pb] at ain; exact of_mem_filter ain
+    else by simp only [filter_cons_of_neg _ pb] at ain ; exact of_mem_filter ain
 #align list.of_mem_filter List.of_mem_filter
 
 theorem mem_of_mem_filter {a : α} {l} (h : a ∈ filter p l) : a ∈ l :=
@@ -4863,7 +4868,7 @@ theorem mem_filter {a : α} {l} : a ∈ filter p l ↔ a ∈ l ∧ p a :=
 theorem monotone_filter_left (p : α → Prop) [DecidablePred p] ⦃l l' : List α⦄ (h : l ⊆ l') :
     filter p l ⊆ filter p l' := by
   intro x hx
-  rw [mem_filter] at hx⊢
+  rw [mem_filter] at hx ⊢
   exact ⟨h hx.left, hx.right⟩
 #align list.monotone_filter_left List.monotone_filter_left
 
@@ -4990,9 +4995,9 @@ theorem mem_takeWhile_imp {x : α} (hx : x ∈ takeWhile p l) : p x :=
   by
   induction' l with hd tl IH
   · simpa [take_while] using hx
-  · simp only [take_while] at hx
-    split_ifs  at hx
-    · rw [mem_cons_iff] at hx
+  · simp only [take_while] at hx 
+    split_ifs  at hx 
+    · rw [mem_cons_iff] at hx 
       rcases hx with (rfl | hx)
       · exact h
       · exact IH hx
@@ -5041,7 +5046,7 @@ theorem eraseP_cons_of_neg {a : α} {l : List α} (h : ¬p a) :
 #align list.erasep_cons_of_neg List.eraseP_cons_of_negₓ
 
 theorem eraseP_of_forall_not {l : List α} (h : ∀ a ∈ l, ¬p a) : l.erasePₓ p = l := by
-  induction' l with _ _ ih <;> [rfl;simp [h _ (Or.inl rfl), ih (forall_mem_of_forall_mem_cons h)]]
+  induction' l with _ _ ih <;> [rfl; simp [h _ (Or.inl rfl), ih (forall_mem_of_forall_mem_cons h)]]
 #align list.erasep_of_forall_not List.eraseP_of_forall_notₓ
 
 theorem exists_of_eraseP {l : List α} {a} (al : a ∈ l) (pa : p a) :
@@ -5062,7 +5067,7 @@ theorem exists_or_eq_self_of_eraseP (p : α → Prop) [DecidablePred p] (l : Lis
   by_cases h : ∃ a ∈ l, p a
   · rcases h with ⟨a, ha, pa⟩
     exact Or.inr (exists_of_erasep ha pa)
-  · simp at h; exact Or.inl (erasep_of_forall_not h)
+  · simp at h ; exact Or.inl (erasep_of_forall_not h)
 #align list.exists_or_eq_self_of_erasep List.exists_or_eq_self_of_erasePₓ
 
 @[simp]
@@ -5097,8 +5102,8 @@ theorem eraseP_append_right :
 #align list.erasep_append_right List.eraseP_append_rightₓ
 
 theorem eraseP_sublist (l : List α) : l.erasePₓ p <+ l := by
-  rcases exists_or_eq_self_of_erasep p l with (h | ⟨c, l₁, l₂, h₁, h₂, h₃, h₄⟩) <;>
-    [rw [h];· rw [h₄, h₃]; simp]
+  rcases exists_or_eq_self_of_erasep p l with (h | ⟨c, l₁, l₂, h₁, h₂, h₃, h₄⟩) <;> [rw [h];
+    · rw [h₄, h₃]; simp]
 #align list.erasep_sublist List.eraseP_sublistₓ
 
 theorem eraseP_subset (l : List α) : l.erasePₓ p ⊆ l :=
@@ -5111,10 +5116,10 @@ theorem Sublist.eraseP {l₁ l₂ : List α} (s : l₁ <+ l₂) : l₁.erasePₓ
   case slnil => rfl
   case cons l₁ l₂ a s IH =>
     by_cases h : p a <;> simp [h]
-    exacts[IH.trans (erasep_sublist _), IH.cons _ _ _]
+    exacts [IH.trans (erasep_sublist _), IH.cons _ _ _]
   case cons2 l₁ l₂ a s IH =>
     by_cases h : p a <;> simp [h]
-    exacts[s, IH.cons2 _ _ _]
+    exacts [s, IH.cons2 _ _ _]
 #align list.sublist.erasep List.Sublist.erasePₓ
 
 theorem mem_of_mem_eraseP {a : α} {l : List α} : a ∈ l.erasePₓ p → a ∈ l :=
@@ -5127,7 +5132,7 @@ theorem mem_eraseP_of_neg {a : α} {l : List α} (pa : ¬p a) : a ∈ l.eraseP
     by
     rcases exists_or_eq_self_of_erasep p l with (h | ⟨c, l₁, l₂, h₁, h₂, h₃, h₄⟩)
     · rwa [h]
-    · rw [h₄]; rw [h₃] at al
+    · rw [h₄]; rw [h₃] at al 
       have : a ≠ c := by rintro rfl; exact pa.elim h₂
       simpa [this] using al⟩
 #align list.mem_erasep_of_neg List.mem_eraseP_of_negₓ
@@ -5177,7 +5182,7 @@ theorem erase_cons_tail {a b : α} (l : List α) (h : b ≠ a) : (b :: l).erase
 theorem erase_eq_eraseP (a : α) (l : List α) : l.eraseₓ a = l.erasePₓ (Eq a) :=
   by
   induction' l with b l; · rfl
-  by_cases a = b <;> [simp [h];simp [h, Ne.symm h, *]]
+  by_cases a = b <;> [simp [h]; simp [h, Ne.symm h, *]]
 #align list.erase_eq_erasep List.erase_eq_erasePₓ
 
 @[simp]
@@ -5259,7 +5264,7 @@ theorem map_erase [DecidableEq β] {f : α → β} (finj : Injective f) {a : α}
 
 theorem map_foldl_erase [DecidableEq β] {f : α → β} (finj : Injective f) {l₁ l₂ : List α} :
     map f (foldl List.erase l₁ l₂) = foldl (fun l a => l.eraseₓ (f a)) (map f l₁) l₂ := by
-  induction l₂ generalizing l₁ <;> [rfl;simp only [foldl_cons, map_erase finj, *]]
+  induction l₂ generalizing l₁ <;> [rfl; simp only [foldl_cons, map_erase finj, *]]
 #align list.map_foldl_erase List.map_foldl_erase
 
 end Erase
@@ -5297,7 +5302,7 @@ theorem diff_erase (l₁ l₂ : List α) (a : α) : (l₁.diffₓ l₂).eraseₓ
 
 @[simp]
 theorem nil_diff (l : List α) : [].diffₓ l = [] := by
-  induction l <;> [rfl;simp only [*, diff_cons, erase_of_not_mem (not_mem_nil _)]]
+  induction l <;> [rfl; simp only [*, diff_cons, erase_of_not_mem (not_mem_nil _)]]
 #align list.nil_diff List.nil_diff
 
 theorem cons_diff (a : α) (l₁ l₂ : List α) :
@@ -5756,8 +5761,8 @@ theorem map₂Left_eq_zipWith :
     ∀ as bs, length as ≤ length bs → map₂Left f as bs = zipWith (fun a b => f a (some b)) as bs
   | [], [], h => by simp!
   | [], b :: bs, h => by simp!
-  | a :: as, [], h => by simp at h; contradiction
-  | a :: as, b :: bs, h => by simp at h; simp! [*]
+  | a :: as, [], h => by simp at h ; contradiction
+  | a :: as, b :: bs, h => by simp at h ; simp! [*]
 #align list.map₂_left_eq_map₂ List.map₂Left_eq_zipWith
 -/
 
@@ -5935,9 +5940,9 @@ theorem toChunks_eq_cons :
 theorem toChunksAux_join {n} : ∀ {xs i l L}, @toChunksAux α n xs i = (l, L) → l ++ L.join = xs
   | [], _, _, _, rfl => rfl
   | x :: xs, i, l, L, e => by
-    cases i <;>
-        [cases' e' : to_chunks_aux n xs n with l L;cases' e' : to_chunks_aux n xs i with l L] <;>
-      · rw [to_chunks_aux, e', to_chunks_aux] at e; cases e
+    cases i <;> [cases' e' : to_chunks_aux n xs n with l L;
+        cases' e' : to_chunks_aux n xs i with l L] <;>
+      · rw [to_chunks_aux, e', to_chunks_aux] at e ; cases e
         exact (congr_arg (cons x) (to_chunks_aux_join e') : _)
 #align list.to_chunks_aux_join List.toChunksAux_join
 
@@ -5956,7 +5961,7 @@ theorem toChunks_length_le : ∀ n xs, n ≠ 0 → ∀ l : List α, l ∈ @toChu
   | n + 1, xs, _, l => by
     refine' (measure_wf length).induction xs _; intro xs IH h
     by_cases x0 : xs = []; · subst xs; cases h
-    rw [to_chunks_eq_cons' _ x0] at h; rcases h with (rfl | h)
+    rw [to_chunks_eq_cons' _ x0] at h ; rcases h with (rfl | h)
     · apply length_take_le
     · refine' IH _ _ h
       simp only [Measure, InvImage, length_drop]
@@ -6078,8 +6083,8 @@ theorem sizeOf_dropSlice_lt [SizeOf α] (i j : ℕ) (hj : 0 < j) (xs : List α)
   by
   induction xs generalizing i j
   case nil i j h => cases hi
-  case
-    cons x xs xs_ih i j h =>
+  case cons x xs xs_ih i j
+    h =>
     cases i <;> simp only [-slice_eq, List.dropSlice]
     · cases j; cases h
       dsimp only [drop]; unfold_wf
Diff
@@ -3809,16 +3809,14 @@ theorem scanr_nil (f : α → β → β) (b : β) : scanr f b [] = [b] :=
 #align list.scanr_nil List.scanr_nil
 -/
 
-/- warning: list.scanr_aux_cons clashes with [anonymous] -> [anonymous]
-Case conversion may be inaccurate. Consider using '#align list.scanr_aux_cons [anonymous]ₓ'. -/
 @[simp]
-theorem [anonymous] (f : α → β → β) (b : β) :
+theorem scanrAux_cons (f : α → β → β) (b : β) :
     ∀ (a : α) (l : List α), scanrAux f b (a :: l) = (foldr f b (a :: l), scanr f b l)
   | a, [] => rfl
   | a, x :: l => by
     let t := scanr_aux_cons x l
     simp only [scanr, scanr_aux, t, foldr_cons]
-#align list.scanr_aux_cons [anonymous]
+#align list.scanr_aux_cons List.scanrAux_cons
 
 #print List.scanr_cons /-
 @[simp]
@@ -4069,33 +4067,28 @@ theorem splitOnP_nil : [].splitOnP p = [[]] :=
   rfl
 #align list.split_on_p_nil List.splitOnP_nilₓ
 
-/- warning: list.split_on_p_aux' clashes with [anonymous] -> [anonymous]
-Case conversion may be inaccurate. Consider using '#align list.split_on_p_aux' [anonymous]ₓ'. -/
 /-- An auxiliary definition for proving a specification lemma for `split_on_p`.
 
 `split_on_p_aux' P xs ys` splits the list `ys ++ xs` at every element satisfying `P`,
 where `ys` is an accumulating parameter for the initial segment of elements not satisfying `P`.
 -/
-def [anonymous] {α : Type u} (P : α → Prop) [DecidablePred P] : List α → List α → List (List α)
+def splitOnPAux' {α : Type u} (P : α → Prop) [DecidablePred P] : List α → List α → List (List α)
   | [], xs => [xs]
   | h :: t, xs => if P h then xs :: split_on_p_aux' t [] else split_on_p_aux' t (xs ++ [h])
-#align list.split_on_p_aux' [anonymous]
+#align list.split_on_p_aux' List.splitOnPAux'
 
-/- warning: list.split_on_p_aux_eq clashes with [anonymous] -> [anonymous]
-Case conversion may be inaccurate. Consider using '#align list.split_on_p_aux_eq [anonymous]ₓ'. -/
-theorem [anonymous] : [anonymous] p xs ys = splitOnPAux p xs ((· ++ ·) ys) :=
+theorem splitOnPAux_eq : splitOnPAux' p xs ys = splitOnPAux p xs ((· ++ ·) ys) :=
   by
   induction' xs with a t ih generalizing ys <;>
     simp! only [append_nil, eq_self_iff_true, and_self_iff]
   split_ifs <;> rw [ih]
   · refine' ⟨rfl, rfl⟩
   · congr ; ext; simp
-#align list.split_on_p_aux_eq [anonymous]
+#align list.split_on_p_aux_eq List.splitOnPAux_eq
 
-/- warning: list.split_on_p_aux_nil clashes with [anonymous] -> [anonymous]
-Case conversion may be inaccurate. Consider using '#align list.split_on_p_aux_nil [anonymous]ₓ'. -/
-theorem [anonymous] : splitOnPAux p xs id = [anonymous] p xs [] := by rw [split_on_p_aux_eq]; rfl
-#align list.split_on_p_aux_nil [anonymous]
+theorem splitOnPAux_nil : splitOnPAux p xs id = splitOnPAux' p xs [] := by rw [split_on_p_aux_eq];
+  rfl
+#align list.split_on_p_aux_nil List.splitOnPAux_nil
 
 /-- The original list `L` can be recovered by joining the lists produced by `split_on_p p L`,
 interspersed with the elements `L.filter p`. -/
@@ -4113,27 +4106,23 @@ theorem splitOnP_spec (as : List α) :
   split_ifs <;> simp [zip_with, join, *]
 #align list.split_on_p_spec List.splitOnP_specₓ
 
-/- warning: list.split_on_p_aux_ne_nil clashes with [anonymous] -> [anonymous]
-Case conversion may be inaccurate. Consider using '#align list.split_on_p_aux_ne_nil [anonymous]ₓ'. -/
-theorem [anonymous] : splitOnPAux p xs f ≠ [] :=
+theorem splitOnPAux_ne_nil : splitOnPAux p xs f ≠ [] :=
   by
   induction' xs with _ _ ih generalizing f; · trivial
   simp only [split_on_p_aux]; split_ifs; · trivial; exact ih _
-#align list.split_on_p_aux_ne_nil [anonymous]
+#align list.split_on_p_aux_ne_nil List.splitOnPAux_ne_nil
 
-/- warning: list.split_on_p_aux_spec clashes with [anonymous] -> [anonymous]
-Case conversion may be inaccurate. Consider using '#align list.split_on_p_aux_spec [anonymous]ₓ'. -/
-theorem [anonymous] : splitOnPAux p xs f = (xs.splitOnP p).modifyHead f :=
+theorem splitOnPAux_spec : splitOnPAux p xs f = (xs.splitOnP p).modifyHead f :=
   by
   simp only [split_on_p]
   induction' xs with hd tl ih generalizing f; · simp [split_on_p_aux]
   simp only [split_on_p_aux]; split_ifs; · simp
   rw [ih fun l => f (hd :: l), ih fun l => id (hd :: l)]
   simp
-#align list.split_on_p_aux_spec [anonymous]
+#align list.split_on_p_aux_spec List.splitOnPAux_spec
 
 theorem splitOnP_ne_nil : xs.splitOnP p ≠ [] :=
-  [anonymous] _ _ id
+  splitOnPAux_ne_nil _ _ id
 #align list.split_on_p_ne_nil List.splitOnP_ne_nilₓ
 
 @[simp]
@@ -5918,64 +5907,51 @@ end ZipRight
 
 section ToChunks
 
-/- warning: list.to_chunks_nil clashes with [anonymous] -> [anonymous]
-Case conversion may be inaccurate. Consider using '#align list.to_chunks_nil [anonymous]ₓ'. -/
 @[simp]
-theorem [anonymous] (n) : @toChunks α n [] = [] := by cases n <;> rfl
-#align list.to_chunks_nil [anonymous]
+theorem toChunks_nil (n) : @toChunks α n [] = [] := by cases n <;> rfl
+#align list.to_chunks_nil List.toChunks_nil
 
-/- warning: list.to_chunks_aux_eq clashes with [anonymous] -> [anonymous]
-Case conversion may be inaccurate. Consider using '#align list.to_chunks_aux_eq [anonymous]ₓ'. -/
-theorem [anonymous] (n) : ∀ xs i, @toChunksAux α n xs i = (xs.take i, (xs.drop i).toChunks (n + 1))
+theorem toChunksAux_eq (n) :
+    ∀ xs i, @toChunksAux α n xs i = (xs.take i, (xs.drop i).toChunks (n + 1))
   | [], i => by cases i <;> rfl
   | x :: xs, 0 => by rw [to_chunks_aux, drop, to_chunks] <;> cases to_chunks_aux n xs n <;> rfl
   | x :: xs, i + 1 => by rw [to_chunks_aux, to_chunks_aux_eq] <;> rfl
-#align list.to_chunks_aux_eq [anonymous]
+#align list.to_chunks_aux_eq List.toChunksAux_eq
 
-/- warning: list.to_chunks_eq_cons' clashes with [anonymous] -> [anonymous]
-Case conversion may be inaccurate. Consider using '#align list.to_chunks_eq_cons' [anonymous]ₓ'. -/
-theorem [anonymous] (n) :
+theorem toChunks_eq_cons' (n) :
     ∀ {xs : List α} (h : xs ≠ []),
       xs.toChunks (n + 1) = xs.take (n + 1) :: (xs.drop (n + 1)).toChunks (n + 1)
   | [], e => (e rfl).elim
   | x :: xs, _ => by rw [to_chunks, to_chunks_aux_eq] <;> rfl
-#align list.to_chunks_eq_cons' [anonymous]
+#align list.to_chunks_eq_cons' List.toChunks_eq_cons'
 
-/- warning: list.to_chunks_eq_cons clashes with [anonymous] -> [anonymous]
-Case conversion may be inaccurate. Consider using '#align list.to_chunks_eq_cons [anonymous]ₓ'. -/
-theorem [anonymous] :
+theorem toChunks_eq_cons :
     ∀ {n} {xs : List α} (n0 : n ≠ 0) (x0 : xs ≠ []),
       xs.toChunks n = xs.take n :: (xs.drop n).toChunks n
   | 0, _, e => (e rfl).elim
-  | n + 1, xs, _ => [anonymous] _
-#align list.to_chunks_eq_cons [anonymous]
+  | n + 1, xs, _ => toChunks_eq_cons' _
+#align list.to_chunks_eq_cons List.toChunks_eq_cons
 
-/- warning: list.to_chunks_aux_join clashes with [anonymous] -> [anonymous]
-Case conversion may be inaccurate. Consider using '#align list.to_chunks_aux_join [anonymous]ₓ'. -/
-theorem [anonymous] {n} : ∀ {xs i l L}, @toChunksAux α n xs i = (l, L) → l ++ L.join = xs
+theorem toChunksAux_join {n} : ∀ {xs i l L}, @toChunksAux α n xs i = (l, L) → l ++ L.join = xs
   | [], _, _, _, rfl => rfl
   | x :: xs, i, l, L, e => by
     cases i <;>
         [cases' e' : to_chunks_aux n xs n with l L;cases' e' : to_chunks_aux n xs i with l L] <;>
       · rw [to_chunks_aux, e', to_chunks_aux] at e; cases e
         exact (congr_arg (cons x) (to_chunks_aux_join e') : _)
-#align list.to_chunks_aux_join [anonymous]
+#align list.to_chunks_aux_join List.toChunksAux_join
 
-/- warning: list.to_chunks_join clashes with [anonymous] -> [anonymous]
-Case conversion may be inaccurate. Consider using '#align list.to_chunks_join [anonymous]ₓ'. -/
 @[simp]
-theorem [anonymous] : ∀ n xs, (@toChunks α n xs).join = xs
+theorem toChunks_join : ∀ n xs, (@toChunks α n xs).join = xs
   | n, [] => by cases n <;> rfl
   | 0, x :: xs => by simp only [to_chunks, join] <;> rw [append_nil]
   | n + 1, x :: xs => by
     rw [to_chunks]
     cases' e : to_chunks_aux n xs n with l L
     exact (congr_arg (cons x) (to_chunks_aux_join e) : _)
-#align list.to_chunks_join [anonymous]
+#align list.to_chunks_join List.toChunks_join
 
-/- warning: list.to_chunks_length_le clashes with [anonymous] -> [anonymous]
-Case conversion may be inaccurate. Consider using '#align list.to_chunks_length_le [anonymous]ₓ'. -/
-theorem [anonymous] : ∀ n xs, n ≠ 0 → ∀ l : List α, l ∈ @toChunks α n xs → l.length ≤ n
+theorem toChunks_length_le : ∀ n xs, n ≠ 0 → ∀ l : List α, l ∈ @toChunks α n xs → l.length ≤ n
   | 0, _, e, _ => (e rfl).elim
   | n + 1, xs, _, l => by
     refine' (measure_wf length).induction xs _; intro xs IH h
@@ -5985,7 +5961,7 @@ theorem [anonymous] : ∀ n xs, n ≠ 0 → ∀ l : List α, l ∈ @toChunks α
     · refine' IH _ _ h
       simp only [Measure, InvImage, length_drop]
       exact tsub_lt_self (length_pos_iff_ne_nil.2 x0) (succ_pos _)
-#align list.to_chunks_length_le [anonymous]
+#align list.to_chunks_length_le List.toChunks_length_le
 
 end ToChunks
 
Diff
@@ -2681,6 +2681,7 @@ theorem length_insertNth_le_succ (l : List α) (x : α) (n : ℕ) :
 #align list.length_insert_nth_le_succ List.length_insertNth_le_succ
 -/
 
+#print List.nthLe_insertNth_of_lt /-
 theorem nthLe_insertNth_of_lt (l : List α) (x : α) (n k : ℕ) (hn : k < n) (hk : k < l.length)
     (hk' : k < (insertNth n x l).length := hk.trans_le (length_le_length_insertNth _ _ _)) :
     (insertNth n x l).nthLe k hk' = l.nthLe k hk :=
@@ -2694,6 +2695,7 @@ theorem nthLe_insertNth_of_lt (l : List α) (x : α) (n k : ℕ) (hn : k < n) (h
       · rw [Nat.succ_lt_succ_iff] at hn
         simpa using IH _ _ hn _
 #align list.nth_le_insert_nth_of_lt List.nthLe_insertNth_of_lt
+-/
 
 #print List.nthLe_insertNth_self /-
 @[simp]
@@ -6241,11 +6243,13 @@ theorem getD_default_eq_getI : l.getD n default = l.getI n :=
   rfl
 #align list.nthd_default_eq_inth List.getD_default_eq_getIₓ
 
+#print List.getI_append /-
 theorem getI_append (l l' : List α) (n : ℕ) (h : n < l.length)
     (h' : n < (l ++ l').length := h.trans_le ((length_append l l').symm ▸ le_self_add)) :
     (l ++ l').getI n = l.getI n :=
   getD_append _ _ _ _ h h'
 #align list.inth_append List.getI_append
+-/
 
 #print List.getI_append_right /-
 theorem getI_append_right (l l' : List α) (n : ℕ) (h : l.length ≤ n) :
Diff
@@ -209,12 +209,6 @@ theorem ne_and_not_mem_of_not_mem_cons {a y : α} {l : List α} : a ∉ y :: l 
 #align list.ne_and_not_mem_of_not_mem_cons List.ne_and_not_mem_of_not_mem_cons
 -/
 
-/- warning: list.mem_map -> List.mem_map is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u2}} {f : α -> β} {b : β} {l : List.{u1} α}, Iff (Membership.Mem.{u2, u2} β (List.{u2} β) (List.hasMem.{u2} β) b (List.map.{u1, u2} α β f l)) (Exists.{succ u1} α (fun (a : α) => And (Membership.Mem.{u1, u1} α (List.{u1} α) (List.hasMem.{u1} α) a l) (Eq.{succ u2} β (f a) b)))
-but is expected to have type
-  forall {α : Type.{u2}} {β : Type.{u1}} {f : β} {b : α -> β} {l : List.{u2} α}, Iff (Membership.mem.{u1, u1} β (List.{u1} β) (List.instMembershipList.{u1} β) f (List.map.{u2, u1} α β b l)) (Exists.{succ u2} α (fun (a : α) => And (Membership.mem.{u2, u2} α (List.{u2} α) (List.instMembershipList.{u2} α) a l) (Eq.{succ u1} β (b a) f)))
-Case conversion may be inaccurate. Consider using '#align list.mem_map List.mem_mapₓ'. -/
 @[simp]
 theorem mem_map {f : α → β} {b : β} {l : List α} : b ∈ map f l ↔ ∃ a, a ∈ l ∧ f a = b :=
   by
@@ -229,12 +223,6 @@ theorem mem_map {f : α → β} {b : β} {l : List α} : b ∈ map f l ↔ ∃ a
       exacts[Or.inl <| (congr_arg f hc.symm).trans h, Or.inr ⟨c, hc, h⟩]
 #align list.mem_map List.mem_map
 
-/- warning: list.exists_of_mem_map -> List.exists_of_mem_map is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u2}} {f : α -> β} {b : β} {l : List.{u1} α}, (Membership.Mem.{u2, u2} β (List.{u2} β) (List.hasMem.{u2} β) b (List.map.{u1, u2} α β f l)) -> (Exists.{succ u1} α (fun (a : α) => And (Membership.Mem.{u1, u1} α (List.{u1} α) (List.hasMem.{u1} α) a l) (Eq.{succ u2} β (f a) b)))
-but is expected to have type
-  forall {α : Type.{u2}} {β : α} {f : Type.{u1}} {b : f -> α} {l : List.{u1} f}, (Membership.mem.{u2, u2} α (List.{u2} α) (List.instMembershipList.{u2} α) β (List.map.{u1, u2} f α b l)) -> (Exists.{succ u1} f (fun (a : f) => And (Membership.mem.{u1, u1} f (List.{u1} f) (List.instMembershipList.{u1} f) a l) (Eq.{succ u2} α (b a) β)))
-Case conversion may be inaccurate. Consider using '#align list.exists_of_mem_map List.exists_of_mem_mapₓ'. -/
 alias mem_map ↔ exists_of_mem_map _
 #align list.exists_of_mem_map List.exists_of_mem_map
 
@@ -535,12 +523,6 @@ theorem or_exists_of_exists_mem_cons {p : α → Prop} {a : α} {l : List α} (h
       fun this : x ∈ l => Or.inr (BEx.intro x this px)
 #align list.or_exists_of_exists_mem_cons List.or_exists_of_exists_mem_consₓ
 
-/- warning: list.exists_mem_cons_iff -> List.exists_mem_cons_iff is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} (p : α -> Prop) (a : α) (l : List.{u1} α), Iff (Exists.{succ u1} α (fun (x : α) => Exists.{0} (Membership.Mem.{u1, u1} α (List.{u1} α) (List.hasMem.{u1} α) x (List.cons.{u1} α a l)) (fun (H : Membership.Mem.{u1, u1} α (List.{u1} α) (List.hasMem.{u1} α) x (List.cons.{u1} α a l)) => p x))) (Or (p a) (Exists.{succ u1} α (fun (x : α) => Exists.{0} (Membership.Mem.{u1, u1} α (List.{u1} α) (List.hasMem.{u1} α) x l) (fun (H : Membership.Mem.{u1, u1} α (List.{u1} α) (List.hasMem.{u1} α) x l) => p x))))
-but is expected to have type
-  forall {α : Type.{u1}} (p : α -> Prop) (a : α) (l : List.{u1} α), Iff (Exists.{succ u1} α (fun (x : α) => And (Membership.mem.{u1, u1} α (List.{u1} α) (List.instMembershipList.{u1} α) x (List.cons.{u1} α a l)) (p x))) (Or (p a) (Exists.{succ u1} α (fun (x : α) => And (Membership.mem.{u1, u1} α (List.{u1} α) (List.instMembershipList.{u1} α) x l) (p x))))
-Case conversion may be inaccurate. Consider using '#align list.exists_mem_cons_iff List.exists_mem_cons_iffₓ'. -/
 theorem exists_mem_cons_iff (p : α → Prop) (a : α) (l : List α) :
     (∃ x ∈ a :: l, p x) ↔ p a ∨ ∃ x ∈ l, p x :=
   Iff.intro or_exists_of_exists_mem_cons fun h =>
@@ -614,12 +596,6 @@ theorem eq_nil_iff_forall_not_mem {l : List α} : l = [] ↔ ∀ a, a ∉ l :=
 #align list.eq_nil_iff_forall_not_mem List.eq_nil_iff_forall_not_mem
 -/
 
-/- warning: list.map_subset -> List.map_subset is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u2}} {l₁ : List.{u1} α} {l₂ : List.{u1} α} (f : α -> β), (HasSubset.Subset.{u1} (List.{u1} α) (List.hasSubset.{u1} α) l₁ l₂) -> (HasSubset.Subset.{u2} (List.{u2} β) (List.hasSubset.{u2} β) (List.map.{u1, u2} α β f l₁) (List.map.{u1, u2} α β f l₂))
-but is expected to have type
-  forall {α : Type.{u2}} {β : Type.{u1}} {l₁ : List.{u2} α} {l₂ : List.{u2} α} (f : α -> β), (HasSubset.Subset.{u2} (List.{u2} α) (List.instHasSubsetList.{u2} α) l₁ l₂) -> (HasSubset.Subset.{u1} (List.{u1} β) (List.instHasSubsetList.{u1} β) (List.map.{u2, u1} α β f l₁) (List.map.{u2, u1} α β f l₂))
-Case conversion may be inaccurate. Consider using '#align list.map_subset List.map_subsetₓ'. -/
 theorem map_subset {l₁ l₂ : List α} (f : α → β) (H : l₁ ⊆ l₂) : map f l₁ ⊆ map f l₂ := fun x => by
   simp only [mem_map, not_and, exists_imp, and_imp] <;> exact fun a h e => ⟨a, H h, e⟩
 #align list.map_subset List.map_subset
@@ -799,12 +775,6 @@ theorem append_left_inj {s₁ s₂ : List α} (t) : s₁ ++ t = s₂ ++ t ↔ s
 #align list.append_left_inj List.append_left_inj
 -/
 
-/- warning: list.map_eq_append_split -> List.map_eq_append_split is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u2}} {f : α -> β} {l : List.{u1} α} {s₁ : List.{u2} β} {s₂ : List.{u2} β}, (Eq.{succ u2} (List.{u2} β) (List.map.{u1, u2} α β f l) (Append.append.{u2} (List.{u2} β) (List.hasAppend.{u2} β) s₁ s₂)) -> (Exists.{succ u1} (List.{u1} α) (fun (l₁ : List.{u1} α) => Exists.{succ u1} (List.{u1} α) (fun (l₂ : List.{u1} α) => And (Eq.{succ u1} (List.{u1} α) l (Append.append.{u1} (List.{u1} α) (List.hasAppend.{u1} α) l₁ l₂)) (And (Eq.{succ u2} (List.{u2} β) (List.map.{u1, u2} α β f l₁) s₁) (Eq.{succ u2} (List.{u2} β) (List.map.{u1, u2} α β f l₂) s₂)))))
-but is expected to have type
-  forall {α : Type.{u2}} {β : Type.{u1}} {f : α -> β} {l : List.{u2} α} {s₁ : List.{u1} β} {s₂ : List.{u1} β}, (Eq.{succ u1} (List.{u1} β) (List.map.{u2, u1} α β f l) (HAppend.hAppend.{u1, u1, u1} (List.{u1} β) (List.{u1} β) (List.{u1} β) (instHAppend.{u1} (List.{u1} β) (List.instAppendList.{u1} β)) s₁ s₂)) -> (Exists.{succ u2} (List.{u2} α) (fun (l₁ : List.{u2} α) => Exists.{succ u2} (List.{u2} α) (fun (l₂ : List.{u2} α) => And (Eq.{succ u2} (List.{u2} α) l (HAppend.hAppend.{u2, u2, u2} (List.{u2} α) (List.{u2} α) (List.{u2} α) (instHAppend.{u2} (List.{u2} α) (List.instAppendList.{u2} α)) l₁ l₂)) (And (Eq.{succ u1} (List.{u1} β) (List.map.{u2, u1} α β f l₁) s₁) (Eq.{succ u1} (List.{u1} β) (List.map.{u2, u1} α β f l₂) s₂)))))
-Case conversion may be inaccurate. Consider using '#align list.map_eq_append_split List.map_eq_append_splitₓ'. -/
 theorem map_eq_append_split {f : α → β} {l : List α} {s₁ s₂ : List β} (h : map f l = s₁ ++ s₂) :
     ∃ l₁ l₂, l = l₁ ++ l₂ ∧ map f l₁ = s₁ ∧ map f l₂ = s₂ :=
   by
@@ -908,12 +878,6 @@ theorem map_replicate (f : α → β) (n a) : map f (replicate n a) = replicate
 #align list.map_replicate List.map_replicate
 -/
 
-/- warning: list.tail_replicate -> List.tail_replicate is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} (n : Nat) (a : α), Eq.{succ u1} (List.{u1} α) (List.tail.{u1} α (List.replicate.{u1} α n a)) (List.replicate.{u1} α (HSub.hSub.{0, 0, 0} Nat Nat Nat (instHSub.{0} Nat Nat.hasSub) n (OfNat.ofNat.{0} Nat 1 (OfNat.mk.{0} Nat 1 (One.one.{0} Nat Nat.hasOne)))) a)
-but is expected to have type
-  forall {α : Type.{u1}} (n : α) (a : Nat), Eq.{succ u1} (List.{u1} α) (List.tail.{u1} α (List.replicate.{u1} α a n)) (List.replicate.{u1} α (HSub.hSub.{0, 0, 0} Nat Nat Nat (instHSub.{0} Nat instSubNat) a (OfNat.ofNat.{0} Nat 1 (instOfNatNat 1))) n)
-Case conversion may be inaccurate. Consider using '#align list.tail_replicate List.tail_replicateₓ'. -/
 @[simp]
 theorem tail_replicate (n) (a : α) : tail (replicate n a) = replicate (n - 1) a := by
   cases n <;> rfl
@@ -964,12 +928,6 @@ theorem replicate_left_inj {a : α} {n m : ℕ} : replicate n a = replicate m a
 /-! ### pure -/
 
 
-/- warning: list.mem_pure -> List.mem_pure is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} (x : α) (y : α), Iff (Membership.Mem.{u1, u1} α (List.{u1} α) (List.hasMem.{u1} α) x (Pure.pure.{u1, u1} List.{u1} (Applicative.toHasPure.{u1, u1} List.{u1} (Monad.toApplicative.{u1, u1} List.{u1} List.monad.{u1})) α y)) (Eq.{succ u1} α x y)
-but is expected to have type
-  forall {α : Type.{u1}} (x : α) (y : α), Iff (Membership.mem.{u1, u1} α (List.{u1} α) (List.instMembershipList.{u1} α) x (Pure.pure.{u1, u1} List.{u1} (Applicative.toPure.{u1, u1} List.{u1} (Monad.toApplicative.{u1, u1} List.{u1} List.instMonadList.{u1})) α y)) (Eq.{succ u1} α x y)
-Case conversion may be inaccurate. Consider using '#align list.mem_pure List.mem_pureₓ'. -/
 @[simp]
 theorem mem_pure {α} (x y : α) : x ∈ (pure y : List α) ↔ x = y := by simp! [pure, List.ret]
 #align list.mem_pure List.mem_pure
@@ -977,12 +935,6 @@ theorem mem_pure {α} (x y : α) : x ∈ (pure y : List α) ↔ x = y := by simp
 /-! ### bind -/
 
 
-/- warning: list.bind_eq_bind -> List.bind_eq_bind is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u1}} (f : α -> (List.{u1} β)) (l : List.{u1} α), Eq.{succ u1} (List.{u1} β) (Bind.bind.{u1, u1} List.{u1} (Monad.toHasBind.{u1, u1} List.{u1} List.monad.{u1}) α β l f) (List.bind.{u1, u1} α β l f)
-but is expected to have type
-  forall {α : Type.{u1}} {β : Type.{u1}} (f : α -> (List.{u1} β)) (l : List.{u1} α), Eq.{succ u1} (List.{u1} β) (Bind.bind.{u1, u1} List.{u1} (Monad.toBind.{u1, u1} List.{u1} List.instMonadList.{u1}) α β l f) (List.bind.{u1, u1} α β l f)
-Case conversion may be inaccurate. Consider using '#align list.bind_eq_bind List.bind_eq_bindₓ'. -/
 @[simp]
 theorem bind_eq_bind {α β} (f : α → List β) (l : List α) : l >>= f = l.bind f :=
   rfl
@@ -1010,22 +962,10 @@ theorem bind_singleton' (l : List α) : (l.bind fun x => [x]) = l :=
 #align list.bind_singleton' List.bind_singleton'
 -/
 
-/- warning: list.map_eq_bind -> List.map_eq_bind is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u2}} (f : α -> β) (l : List.{u1} α), Eq.{succ u2} (List.{u2} β) (List.map.{u1, u2} α β f l) (List.bind.{u1, u2} α β l (fun (x : α) => List.cons.{u2} β (f x) (List.nil.{u2} β)))
-but is expected to have type
-  forall {α : Type.{u2}} {β : Type.{u1}} (f : α -> β) (l : List.{u2} α), Eq.{succ u1} (List.{u1} β) (List.map.{u2, u1} α β f l) (List.bind.{u2, u1} α β l (fun (x : α) => List.cons.{u1} β (f x) (List.nil.{u1} β)))
-Case conversion may be inaccurate. Consider using '#align list.map_eq_bind List.map_eq_bindₓ'. -/
 theorem map_eq_bind {α β} (f : α → β) (l : List α) : map f l = l.bind fun x => [f x] := by trans;
   rw [← bind_singleton' l, bind_map]; rfl
 #align list.map_eq_bind List.map_eq_bind
 
-/- warning: list.bind_assoc -> List.bind_assoc is a dubious translation:
-lean 3 declaration is
-  forall {γ : Type.{u1}} {α : Type.{u2}} {β : Type.{u3}} (l : List.{u2} α) (f : α -> (List.{u3} β)) (g : β -> (List.{u1} γ)), Eq.{succ u1} (List.{u1} γ) (List.bind.{u3, u1} β γ (List.bind.{u2, u3} α β l f) g) (List.bind.{u2, u1} α γ l (fun (x : α) => List.bind.{u3, u1} β γ (f x) g))
-but is expected to have type
-  forall {γ : Type.{u3}} {α : Type.{u2}} {β : Type.{u1}} (l : List.{u2} α) (f : α -> (List.{u1} β)) (g : β -> (List.{u3} γ)), Eq.{succ u3} (List.{u3} γ) (List.bind.{u1, u3} β γ (List.bind.{u2, u1} α β l f) g) (List.bind.{u2, u3} α γ l (fun (x : α) => List.bind.{u1, u3} β γ (f x) g))
-Case conversion may be inaccurate. Consider using '#align list.bind_assoc List.bind_assocₓ'. -/
 theorem bind_assoc {α β} (l : List α) (f : α → List β) (g : β → List γ) :
     (l.bind f).bind g = l.bind fun x => (f x).bind g := by induction l <;> simp [*]
 #align list.bind_assoc List.bind_assoc
@@ -1612,12 +1552,6 @@ theorem nthLe_cons_aux {l : List α} {a : α} {n} (hn : n ≠ 0) (h : n < (a ::
 #align list.nth_le_cons_aux List.nthLe_cons_aux
 -/
 
-/- warning: list.nth_le_cons -> List.nthLe_cons is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {l : List.{u1} α} {a : α} {n : Nat} (hl : LT.lt.{0} Nat Nat.hasLt n (List.length.{u1} α (List.cons.{u1} α a l))), Eq.{succ u1} α (List.nthLe.{u1} α (List.cons.{u1} α a l) n hl) (dite.{succ u1} α (Eq.{1} Nat n (OfNat.ofNat.{0} Nat 0 (OfNat.mk.{0} Nat 0 (Zero.zero.{0} Nat Nat.hasZero)))) (Nat.decidableEq n (OfNat.ofNat.{0} Nat 0 (OfNat.mk.{0} Nat 0 (Zero.zero.{0} Nat Nat.hasZero)))) (fun (hn : Eq.{1} Nat n (OfNat.ofNat.{0} Nat 0 (OfNat.mk.{0} Nat 0 (Zero.zero.{0} Nat Nat.hasZero)))) => a) (fun (hn : Not (Eq.{1} Nat n (OfNat.ofNat.{0} Nat 0 (OfNat.mk.{0} Nat 0 (Zero.zero.{0} Nat Nat.hasZero))))) => List.nthLe.{u1} α l (HSub.hSub.{0, 0, 0} Nat Nat Nat (instHSub.{0} Nat Nat.hasSub) n (OfNat.ofNat.{0} Nat 1 (OfNat.mk.{0} Nat 1 (One.one.{0} Nat Nat.hasOne)))) (List.nthLe_cons_aux.{u1} α l a n hn hl)))
-but is expected to have type
-  forall {α : Type.{u1}} {l : List.{u1} α} {a : α} {n : Nat} (hl : LT.lt.{0} Nat instLTNat n (List.length.{u1} α (List.cons.{u1} α a l))), Eq.{succ u1} α (List.nthLe.{u1} α (List.cons.{u1} α a l) n hl) (dite.{succ u1} α (Eq.{1} Nat n (OfNat.ofNat.{0} Nat 0 (instOfNatNat 0))) (instDecidableEqNat n (OfNat.ofNat.{0} Nat 0 (instOfNatNat 0))) (fun (hn : Eq.{1} Nat n (OfNat.ofNat.{0} Nat 0 (instOfNatNat 0))) => a) (fun (hn : Not (Eq.{1} Nat n (OfNat.ofNat.{0} Nat 0 (instOfNatNat 0)))) => List.nthLe.{u1} α l (HSub.hSub.{0, 0, 0} Nat Nat Nat (instHSub.{0} Nat instSubNat) n (OfNat.ofNat.{0} Nat 1 (instOfNatNat 1))) (List.nthLe_cons_aux.{u1} α l a n hn hl)))
-Case conversion may be inaccurate. Consider using '#align list.nth_le_cons List.nthLe_consₓ'. -/
 theorem nthLe_cons {l : List α} {a : α} {n} (hl) :
     (a :: l).nthLe n hl = if hn : n = 0 then a else l.nthLe (n - 1) (nthLe_cons_aux hn hl) :=
   by
@@ -1655,12 +1589,6 @@ def reverseRecOn {C : List α → Sort _} (l : List α) (H0 : C [])
 #align list.reverse_rec_on List.reverseRecOn
 -/
 
-/- warning: list.bidirectional_rec -> List.bidirectionalRecₓ is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {C : (List.{u1} α) -> Sort.{u2}}, (C (List.nil.{u1} α)) -> (forall (a : α), C (List.cons.{u1} α a (List.nil.{u1} α))) -> (forall (a : α) (l : List.{u1} α) (b : α), (C l) -> (C (List.cons.{u1} α a (Append.append.{u1} (List.{u1} α) (List.hasAppend.{u1} α) l (List.cons.{u1} α b (List.nil.{u1} α)))))) -> (forall (l : List.{u1} α), C l)
-but is expected to have type
-  forall {α : Type.{u2}} {C : (List.{u2} α) -> Sort.{u1}}, (C (List.nil.{u2} α)) -> (forall (a : α), C (List.cons.{u2} α a (List.nil.{u2} α))) -> (forall (a : α) (l : List.{u2} α) (b : α), (C l) -> (C (List.cons.{u2} α a (Append.append.{u2} (List.{u2} α) (List.hasAppend.{u2} α) l (List.cons.{u2} α b (List.nil.{u2} α)))))) -> (forall (l : List.{u2} α), C l)
-Case conversion may be inaccurate. Consider using '#align list.bidirectional_rec List.bidirectionalRecₓₓ'. -/
 /-- Bidirectional induction principle for lists: if a property holds for the empty list, the
 singleton list, and `a :: (l ++ [b])` from `l`, then it holds for all lists. This can be used to
 prove statements about palindromes. The principle is given for a `Sort`-valued predicate, i.e., it
@@ -1771,12 +1699,6 @@ theorem sublist_append_of_sublist_left {l l₁ l₂ : List α} (s : l <+ l₁) :
 #align list.sublist_append_of_sublist_left List.sublist_append_of_sublist_left
 -/
 
-/- warning: list.sublist_append_of_sublist_right -> List.sublist_append_of_sublist_right is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {l : List.{u1} α} {l₁ : List.{u1} α} {l₂ : List.{u1} α}, (List.Sublist.{u1} α l l₂) -> (List.Sublist.{u1} α l (Append.append.{u1} (List.{u1} α) (List.hasAppend.{u1} α) l₁ l₂))
-but is expected to have type
-  forall {α : Type.{u1}} {l : List.{u1} α} {l₁ : List.{u1} α} {l₂ : List.{u1} α}, (List.Sublist.{u1} α l l₁) -> (List.Sublist.{u1} α l (HAppend.hAppend.{u1, u1, u1} (List.{u1} α) (List.{u1} α) (List.{u1} α) (instHAppend.{u1} (List.{u1} α) (List.instAppendList.{u1} α)) l₂ l₁))
-Case conversion may be inaccurate. Consider using '#align list.sublist_append_of_sublist_right List.sublist_append_of_sublist_rightₓ'. -/
 theorem sublist_append_of_sublist_right {l l₁ l₂ : List α} (s : l <+ l₂) : l <+ l₁ ++ l₂ :=
   s.trans <| sublist_append_right _ _
 #align list.sublist_append_of_sublist_right List.sublist_append_of_sublist_right
@@ -1812,12 +1734,6 @@ theorem Sublist.append_right {l₁ l₂ : List α} (h : l₁ <+ l₂) (l) : l₁
 #align list.sublist.append_right List.Sublist.append_right
 -/
 
-/- warning: list.sublist_or_mem_of_sublist -> List.sublist_or_mem_of_sublist is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {l : List.{u1} α} {l₁ : List.{u1} α} {l₂ : List.{u1} α} {a : α}, (List.Sublist.{u1} α l (Append.append.{u1} (List.{u1} α) (List.hasAppend.{u1} α) l₁ (List.cons.{u1} α a l₂))) -> (Or (List.Sublist.{u1} α l (Append.append.{u1} (List.{u1} α) (List.hasAppend.{u1} α) l₁ l₂)) (Membership.Mem.{u1, u1} α (List.{u1} α) (List.hasMem.{u1} α) a l))
-but is expected to have type
-  forall {α : Type.{u1}} {l : List.{u1} α} {l₁ : List.{u1} α} {l₂ : α} {a : List.{u1} α}, (List.Sublist.{u1} α l (HAppend.hAppend.{u1, u1, u1} (List.{u1} α) (List.{u1} α) (List.{u1} α) (instHAppend.{u1} (List.{u1} α) (List.instAppendList.{u1} α)) l₁ (List.cons.{u1} α l₂ a))) -> (Or (List.Sublist.{u1} α l (HAppend.hAppend.{u1, u1, u1} (List.{u1} α) (List.{u1} α) (List.{u1} α) (instHAppend.{u1} (List.{u1} α) (List.instAppendList.{u1} α)) l₁ a)) (Membership.mem.{u1, u1} α (List.{u1} α) (List.instMembershipList.{u1} α) l₂ l))
-Case conversion may be inaccurate. Consider using '#align list.sublist_or_mem_of_sublist List.sublist_or_mem_of_sublistₓ'. -/
 theorem sublist_or_mem_of_sublist {l l₁ l₂ : List α} {a : α} (h : l <+ l₁ ++ a :: l₂) :
     l <+ l₁ ++ l₂ ∨ a ∈ l := by
   induction' l₁ with b l₁ IH generalizing l
@@ -1892,24 +1808,12 @@ theorem sublist_nil_iff_eq_nil {l : List α} : l <+ [] ↔ l = [] :=
 #align list.sublist_nil_iff_eq_nil List.sublist_nil_iff_eq_nil
 -/
 
-/- warning: list.replicate_sublist_replicate -> List.replicate_sublist_replicate is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} (a : α) {m : Nat} {n : Nat}, Iff (List.Sublist.{u1} α (List.replicate.{u1} α m a) (List.replicate.{u1} α n a)) (LE.le.{0} Nat Nat.hasLe m n)
-but is expected to have type
-  forall {α : Type.{u1}} {a : Nat} {m : Nat} (n : α), Iff (List.Sublist.{u1} α (List.replicate.{u1} α a n) (List.replicate.{u1} α m n)) (LE.le.{0} Nat instLENat a m)
-Case conversion may be inaccurate. Consider using '#align list.replicate_sublist_replicate List.replicate_sublist_replicateₓ'. -/
 @[simp]
 theorem replicate_sublist_replicate (a : α) {m n} : replicate m a <+ replicate n a ↔ m ≤ n :=
   ⟨fun h => by simpa only [length_replicate] using h.length_le, fun h => by
     induction h <;> [rfl;simp only [*, replicate_succ, sublist.cons]]⟩
 #align list.replicate_sublist_replicate List.replicate_sublist_replicate
 
-/- warning: list.sublist_replicate_iff -> List.sublist_replicate_iff is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {l : List.{u1} α} {a : α} {n : Nat}, Iff (List.Sublist.{u1} α l (List.replicate.{u1} α n a)) (Exists.{1} Nat (fun (k : Nat) => Exists.{0} (LE.le.{0} Nat Nat.hasLe k n) (fun (H : LE.le.{0} Nat Nat.hasLe k n) => Eq.{succ u1} (List.{u1} α) l (List.replicate.{u1} α k a))))
-but is expected to have type
-  forall {α : Type.{u1}} {l : List.{u1} α} {a : α} {n : Nat}, Iff (List.Sublist.{u1} α l (List.replicate.{u1} α n a)) (Exists.{1} Nat (fun (k : Nat) => And (LE.le.{0} Nat instLENat k n) (Eq.{succ u1} (List.{u1} α) l (List.replicate.{u1} α k a))))
-Case conversion may be inaccurate. Consider using '#align list.sublist_replicate_iff List.sublist_replicate_iffₓ'. -/
 theorem sublist_replicate_iff {l : List α} {a : α} {n : ℕ} :
     l <+ replicate n a ↔ ∃ k ≤ n, l = replicate k a :=
   ⟨fun h =>
@@ -2169,12 +2073,6 @@ theorem get?_injective {α : Type u} {xs : List α} {i j : ℕ} (h₀ : i < xs.l
 #align list.nth_injective List.get?_injective
 -/
 
-/- warning: list.nth_map -> List.get?_map is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u2}} (f : α -> β) (l : List.{u1} α) (n : Nat), Eq.{succ u2} (Option.{u2} β) (List.get?.{u2} β (List.map.{u1, u2} α β f l) n) (Option.map.{u1, u2} α β f (List.get?.{u1} α l n))
-but is expected to have type
-  forall {α : Type.{u2}} {β : Type.{u1}} (f : α -> β) (l : List.{u2} α) (n : Nat), Eq.{succ u1} (Option.{u1} β) (List.get?.{u1} β (List.map.{u2, u1} α β f l) n) (Option.map.{u2, u1} α β f (List.get?.{u2} α l n))
-Case conversion may be inaccurate. Consider using '#align list.nth_map List.get?_mapₓ'. -/
 @[simp]
 theorem get?_map (f : α → β) : ∀ l n, get? (map f l) n = (get? l n).map f
   | [], n => rfl
@@ -2522,12 +2420,6 @@ theorem set_eq_modifyNth (a : α) : ∀ (n) (l : List α), set l n a = modifyNth
 #align list.update_nth_eq_modify_nth List.set_eq_modifyNth
 -/
 
-/- warning: list.modify_nth_eq_update_nth -> List.modifyNth_eq_set is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} (f : α -> α) (n : Nat) (l : List.{u1} α), Eq.{succ u1} (List.{u1} α) (List.modifyNth.{u1} α f n l) (Option.getD.{u1} (List.{u1} α) (Functor.map.{u1, u1} Option.{u1} (Traversable.toFunctor.{u1} Option.{u1} Option.traversable.{u1}) α (List.{u1} α) (fun (a : α) => List.set.{u1} α l n (f a)) (List.get?.{u1} α l n)) l)
-but is expected to have type
-  forall {α : Type.{u1}} (f : α -> α) (n : Nat) (l : List.{u1} α), Eq.{succ u1} (List.{u1} α) (List.modifyNth.{u1} α f n l) (Option.getD.{u1} (List.{u1} α) (Functor.map.{u1, u1} Option.{u1} instFunctorOption.{u1} α (List.{u1} α) (fun (a : α) => List.set.{u1} α l n (f a)) (List.get?.{u1} α l n)) l)
-Case conversion may be inaccurate. Consider using '#align list.modify_nth_eq_update_nth List.modifyNth_eq_setₓ'. -/
 theorem modifyNth_eq_set (f : α → α) :
     ∀ (n) (l : List α), modifyNth f n l = ((fun a => set l n (f a)) <$> get? l n).getD l
   | 0, l => by cases l <;> rfl
@@ -2536,12 +2428,6 @@ theorem modifyNth_eq_set (f : α → α) :
     (congr_arg (cons b) (modify_nth_eq_update_nth n l)).trans <| by cases nth l n <;> rfl
 #align list.modify_nth_eq_update_nth List.modifyNth_eq_set
 
-/- warning: list.nth_modify_nth -> List.get?_modifyNth is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} (f : α -> α) (n : Nat) (l : List.{u1} α) (m : Nat), Eq.{succ u1} (Option.{u1} α) (List.get?.{u1} α (List.modifyNth.{u1} α f n l) m) (Functor.map.{u1, u1} Option.{u1} (Traversable.toFunctor.{u1} Option.{u1} Option.traversable.{u1}) α α (fun (a : α) => ite.{succ u1} α (Eq.{1} Nat n m) (Nat.decidableEq n m) (f a) a) (List.get?.{u1} α l m))
-but is expected to have type
-  forall {α : Type.{u1}} (f : α -> α) (n : Nat) (l : List.{u1} α) (m : Nat), Eq.{succ u1} (Option.{u1} α) (List.get?.{u1} α (List.modifyNth.{u1} α f n l) m) (Functor.map.{u1, u1} Option.{u1} instFunctorOption.{u1} α α (fun (a : α) => ite.{succ u1} α (Eq.{1} Nat n m) (instDecidableEqNat n m) (f a) a) (List.get?.{u1} α l m))
-Case conversion may be inaccurate. Consider using '#align list.nth_modify_nth List.get?_modifyNthₓ'. -/
 theorem get?_modifyNth (f : α → α) :
     ∀ (n) (l : List α) (m),
       get? (modifyNth f n l) m = (fun a => if n = m then f a else a) <$> get? l m
@@ -2578,12 +2464,6 @@ theorem length_set (l : List α) (n) (a : α) : length (set l n a) = length l :=
 #align list.update_nth_length List.length_set
 -/
 
-/- warning: list.nth_modify_nth_eq -> List.get?_modifyNth_eq is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} (f : α -> α) (n : Nat) (l : List.{u1} α), Eq.{succ u1} (Option.{u1} α) (List.get?.{u1} α (List.modifyNth.{u1} α f n l) n) (Functor.map.{u1, u1} Option.{u1} (Traversable.toFunctor.{u1} Option.{u1} Option.traversable.{u1}) α α f (List.get?.{u1} α l n))
-but is expected to have type
-  forall {α : Type.{u1}} (f : α -> α) (n : Nat) (l : List.{u1} α), Eq.{succ u1} (Option.{u1} α) (List.get?.{u1} α (List.modifyNth.{u1} α f n l) n) (Functor.map.{u1, u1} Option.{u1} instFunctorOption.{u1} α α f (List.get?.{u1} α l n))
-Case conversion may be inaccurate. Consider using '#align list.nth_modify_nth_eq List.get?_modifyNth_eqₓ'. -/
 @[simp]
 theorem get?_modifyNth_eq (f : α → α) (n) (l : List α) :
     get? (modifyNth f n l) n = f <$> get? l n := by simp only [nth_modify_nth, if_pos]
@@ -2596,12 +2476,6 @@ theorem get?_modifyNth_ne (f : α → α) {m n} (l : List α) (h : m ≠ n) :
 #align list.nth_modify_nth_ne List.get?_modifyNth_ne
 -/
 
-/- warning: list.nth_update_nth_eq -> List.get?_set_eq is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} (a : α) (n : Nat) (l : List.{u1} α), Eq.{succ u1} (Option.{u1} α) (List.get?.{u1} α (List.set.{u1} α l n a) n) (Functor.map.{u1, u1} Option.{u1} (Traversable.toFunctor.{u1} Option.{u1} Option.traversable.{u1}) α α (fun (_x : α) => a) (List.get?.{u1} α l n))
-but is expected to have type
-  forall {α : Type.{u1}} (a : α) (n : Nat) (l : List.{u1} α), Eq.{succ u1} (Option.{u1} α) (List.get?.{u1} α (List.set.{u1} α l n a) n) (Functor.map.{u1, u1} Option.{u1} instFunctorOption.{u1} α α (fun (_x : α) => a) (List.get?.{u1} α l n))
-Case conversion may be inaccurate. Consider using '#align list.nth_update_nth_eq List.get?_set_eqₓ'. -/
 theorem get?_set_eq (a : α) (n) (l : List α) : get? (set l n a) n = (fun _ => a) <$> get? l n := by
   simp only [update_nth_eq_modify_nth, nth_modify_nth_eq]
 #align list.nth_update_nth_eq List.get?_set_eq
@@ -2807,12 +2681,6 @@ theorem length_insertNth_le_succ (l : List α) (x : α) (n : ℕ) :
 #align list.length_insert_nth_le_succ List.length_insertNth_le_succ
 -/
 
-/- warning: list.nth_le_insert_nth_of_lt -> List.nthLe_insertNth_of_lt is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} (l : List.{u1} α) (x : α) (n : Nat) (k : Nat), (LT.lt.{0} Nat Nat.hasLt k n) -> (forall (hk : LT.lt.{0} Nat Nat.hasLt k (List.length.{u1} α l)) (hk' : optParam.{0} (LT.lt.{0} Nat (Preorder.toHasLt.{0} Nat (PartialOrder.toPreorder.{0} Nat (OrderedCancelAddCommMonoid.toPartialOrder.{0} Nat (StrictOrderedSemiring.toOrderedCancelAddCommMonoid.{0} Nat Nat.strictOrderedSemiring)))) k (List.length.{u1} α (List.insertNth.{u1} α n x l))) (LT.lt.trans_le.{0} Nat (PartialOrder.toPreorder.{0} Nat (OrderedCancelAddCommMonoid.toPartialOrder.{0} Nat (StrictOrderedSemiring.toOrderedCancelAddCommMonoid.{0} Nat Nat.strictOrderedSemiring))) k (List.length.{u1} α l) (List.length.{u1} α (List.insertNth.{u1} α n x l)) hk (List.length_le_length_insertNth.{u1} α l x n))), Eq.{succ u1} α (List.nthLe.{u1} α (List.insertNth.{u1} α n x l) k hk') (List.nthLe.{u1} α l k hk))
-but is expected to have type
-  forall {α : Type.{u1}} (l : List.{u1} α) (x : α) (n : Nat) (k : Nat), (LT.lt.{0} Nat instLTNat k n) -> (forall (hk : LT.lt.{0} Nat instLTNat k (List.length.{u1} α l)) (hk' : optParam.{0} (LT.lt.{0} Nat instLTNat k (List.length.{u1} α (List.insertNth.{u1} α n x l))) (LT.lt.trans_le.{0} Nat (PartialOrder.toPreorder.{0} Nat (StrictOrderedSemiring.toPartialOrder.{0} Nat Nat.strictOrderedSemiring)) k (List.length.{u1} α l) (List.length.{u1} α (List.insertNth.{u1} α n x l)) hk (List.length_le_length_insertNth.{u1} α l x n))), Eq.{succ u1} α (List.nthLe.{u1} α (List.insertNth.{u1} α n x l) k hk') (List.nthLe.{u1} α l k hk))
-Case conversion may be inaccurate. Consider using '#align list.nth_le_insert_nth_of_lt List.nthLe_insertNth_of_ltₓ'. -/
 theorem nthLe_insertNth_of_lt (l : List α) (x : α) (n k : ℕ) (hn : k < n) (hk : k < l.length)
     (hk' : k < (insertNth n x l).length := hk.trans_le (length_le_length_insertNth _ _ _)) :
     (insertNth n x l).nthLe k hk' = l.nthLe k hk :=
@@ -2872,12 +2740,6 @@ end InsertNth
 /-! ### map -/
 
 
-/- warning: list.map_nil -> List.map_nil is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u2}} (f : α -> β), Eq.{succ u2} (List.{u2} β) (List.map.{u1, u2} α β f (List.nil.{u1} α)) (List.nil.{u2} β)
-but is expected to have type
-  forall {α : Type.{u2}} {β : Type.{u1}} {f : α -> β}, Eq.{succ u1} (List.{u1} β) (List.map.{u2, u1} α β f (List.nil.{u2} α)) (List.nil.{u1} β)
-Case conversion may be inaccurate. Consider using '#align list.map_nil List.map_nilₓ'. -/
 @[simp]
 theorem map_nil (f : α → β) : map f [] = [] :=
   rfl
@@ -2958,12 +2820,6 @@ theorem bind_congr {l : List α} {f g : α → List β} (h : ∀ x ∈ l, f x =
 #align list.bind_congr List.bind_congr
 -/
 
-/- warning: list.map_eq_map -> List.map_eq_map is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u1}} (f : α -> β) (l : List.{u1} α), Eq.{succ u1} (List.{u1} β) (Functor.map.{u1, u1} (fun {α : Type.{u1}} => List.{u1} α) (Traversable.toFunctor.{u1} (fun {α : Type.{u1}} => List.{u1} α) List.traversable.{u1}) α β f l) (List.map.{u1, u1} α β f l)
-but is expected to have type
-  forall {α : Type.{u1}} {β : Type.{u1}} (f : α -> β) (l : List.{u1} α), Eq.{succ u1} (List.{u1} β) (Functor.map.{u1, u1} List.{u1} List.instFunctorList.{u1} α β f l) (List.map.{u1, u1} α β f l)
-Case conversion may be inaccurate. Consider using '#align list.map_eq_map List.map_eq_mapₓ'. -/
 @[simp]
 theorem map_eq_map {α β} (f : α → β) (l : List α) : f <$> l = map f l :=
   rfl
@@ -3006,12 +2862,6 @@ theorem map_comp_map (g : β → γ) (f : α → β) : map g ∘ map f = map (g
 #align list.map_comp_map List.map_comp_map
 -/
 
-/- warning: list.map_filter_eq_foldr -> List.map_filter_eq_foldr is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u2}} (f : α -> β) (p : α -> Prop) [_inst_1 : DecidablePred.{succ u1} α p] (as : List.{u1} α), Eq.{succ u2} (List.{u2} β) (List.map.{u1, u2} α β f (List.filterₓ.{u1} α p (fun (a : α) => _inst_1 a) as)) (List.foldr.{u1, u2} α (List.{u2} β) (fun (a : α) (bs : List.{u2} β) => ite.{succ u2} (List.{u2} β) (p a) (_inst_1 a) (List.cons.{u2} β (f a) bs) bs) (List.nil.{u2} β) as)
-but is expected to have type
-  forall {α : Type.{u1}} {β : Type.{u2}} (f : α -> β) (p : α -> Bool) (_inst_1 : List.{u1} α), Eq.{succ u2} (List.{u2} β) (List.map.{u1, u2} α β f (List.filter.{u1} α p _inst_1)) (List.foldr.{u1, u2} α (List.{u2} β) (fun (a : α) (bs : List.{u2} β) => cond.{u2} (List.{u2} β) (p a) (List.cons.{u2} β (f a) bs) bs) (List.nil.{u2} β) _inst_1)
-Case conversion may be inaccurate. Consider using '#align list.map_filter_eq_foldr List.map_filter_eq_foldrₓ'. -/
 theorem map_filter_eq_foldr (f : α → β) (p : α → Prop) [DecidablePred p] (as : List α) :
     map f (filter p as) = foldr (fun a bs => if p a then f a :: bs else bs) [] as := by
   induction as; · rfl; · simp! [*, apply_ite (map f)]
@@ -3135,12 +2985,6 @@ theorem take_left' {l₁ l₂ : List α} {n} (h : length l₁ = n) : take n (l
 #align list.take_left' List.take_left'
 -/
 
-/- warning: list.take_take -> List.take_take is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} (n : Nat) (m : Nat) (l : List.{u1} α), Eq.{succ u1} (List.{u1} α) (List.take.{u1} α n (List.take.{u1} α m l)) (List.take.{u1} α (LinearOrder.min.{0} Nat Nat.linearOrder n m) l)
-but is expected to have type
-  forall {α : Type.{u1}} (n : Nat) (m : Nat) (l : List.{u1} α), Eq.{succ u1} (List.{u1} α) (List.take.{u1} α n (List.take.{u1} α m l)) (List.take.{u1} α (Min.min.{0} Nat instMinNat n m) l)
-Case conversion may be inaccurate. Consider using '#align list.take_take List.take_takeₓ'. -/
 theorem take_take : ∀ (n m) (l : List α), take n (take m l) = take (min n m) l
   | n, 0, l => by rw [min_zero, take_zero, take_nil]
   | 0, m, l => by rw [zero_min, take_zero, take_zero]
@@ -3149,24 +2993,12 @@ theorem take_take : ∀ (n m) (l : List α), take n (take m l) = take (min n m)
     simp only [take, min_succ_succ, take_take n m l] <;> constructor <;> rfl
 #align list.take_take List.take_take
 
-/- warning: list.take_replicate -> List.take_replicate is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} (a : α) (n : Nat) (m : Nat), Eq.{succ u1} (List.{u1} α) (List.take.{u1} α n (List.replicate.{u1} α m a)) (List.replicate.{u1} α (LinearOrder.min.{0} Nat Nat.linearOrder n m) a)
-but is expected to have type
-  forall {α : Type.{u1}} (a : α) (n : Nat) (m : Nat), Eq.{succ u1} (List.{u1} α) (List.take.{u1} α n (List.replicate.{u1} α m a)) (List.replicate.{u1} α (Min.min.{0} Nat instMinNat n m) a)
-Case conversion may be inaccurate. Consider using '#align list.take_replicate List.take_replicateₓ'. -/
 theorem take_replicate (a : α) : ∀ n m : ℕ, take n (replicate m a) = replicate (min n m) a
   | n, 0 => by simp
   | 0, m => by simp
   | succ n, succ m => by simp [min_succ_succ, take_replicate]
 #align list.take_replicate List.take_replicate
 
-/- warning: list.map_take -> List.map_take is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u2}} (f : α -> β) (L : List.{u1} α) (i : Nat), Eq.{succ u2} (List.{u2} β) (List.map.{u1, u2} α β f (List.take.{u1} α i L)) (List.take.{u2} β i (List.map.{u1, u2} α β f L))
-but is expected to have type
-  forall {α : Type.{u2}} {β : Type.{u1}} (f : α -> β) (L : List.{u2} α) (i : Nat), Eq.{succ u1} (List.{u1} β) (List.map.{u2, u1} α β f (List.take.{u2} α i L)) (List.take.{u1} β i (List.map.{u2, u1} α β f L))
-Case conversion may be inaccurate. Consider using '#align list.map_take List.map_takeₓ'. -/
 theorem map_take {α β : Type _} (f : α → β) :
     ∀ (L : List α) (i : ℕ), (L.take i).map f = (L.map f).take i
   | [], i => by simp
@@ -3256,12 +3088,6 @@ theorem take_eq_nil_iff {l : List α} {k : ℕ} : l.take k = [] ↔ l = [] ∨ k
 #align list.take_eq_nil_iff List.take_eq_nil_iff
 -/
 
-/- warning: list.take_eq_take -> List.take_eq_take is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {l : List.{u1} α} {m : Nat} {n : Nat}, Iff (Eq.{succ u1} (List.{u1} α) (List.take.{u1} α m l) (List.take.{u1} α n l)) (Eq.{1} Nat (LinearOrder.min.{0} Nat Nat.linearOrder m (List.length.{u1} α l)) (LinearOrder.min.{0} Nat Nat.linearOrder n (List.length.{u1} α l)))
-but is expected to have type
-  forall {α : Type.{u1}} {l : List.{u1} α} {m : Nat} {n : Nat}, Iff (Eq.{succ u1} (List.{u1} α) (List.take.{u1} α m l) (List.take.{u1} α n l)) (Eq.{1} Nat (Min.min.{0} Nat instMinNat m (List.length.{u1} α l)) (Min.min.{0} Nat instMinNat n (List.length.{u1} α l)))
-Case conversion may be inaccurate. Consider using '#align list.take_eq_take List.take_eq_takeₓ'. -/
 theorem take_eq_take :
     ∀ {l : List α} {m n : ℕ}, l.take m = l.take n ↔ min m l.length = min n l.length
   | [], m, n => by simp
@@ -3456,12 +3282,6 @@ theorem drop_append {l₁ l₂ : List α} (i : ℕ) : drop (l₁.length + i) (l
 #align list.drop_append List.drop_append
 -/
 
-/- warning: list.drop_sizeof_le -> List.drop_sizeOf_le is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} [_inst_1 : SizeOf.{succ u1} α] (l : List.{u1} α) (n : Nat), LE.le.{0} Nat Nat.hasLe (List.sizeof.{u1} α _inst_1 (List.drop.{u1} α n l)) (List.sizeof.{u1} α _inst_1 l)
-but is expected to have type
-  forall {α : Type.{u1}} [_inst_1 : SizeOf.{succ u1} α] (l : List.{u1} α) (n : Nat), LE.le.{0} Nat instLENat (SizeOf.sizeOf.{succ u1} (List.{u1} α) (List._sizeOf_inst.{u1} α _inst_1) (List.drop.{u1} α n l)) (SizeOf.sizeOf.{succ u1} (List.{u1} α) (List._sizeOf_inst.{u1} α _inst_1) l)
-Case conversion may be inaccurate. Consider using '#align list.drop_sizeof_le List.drop_sizeOf_leₓ'. -/
 theorem drop_sizeOf_le [SizeOf α] (l : List α) : ∀ n : ℕ, (l.drop n).sizeOf ≤ l.sizeOf :=
   by
   induction' l with _ _ lih <;> intro n
@@ -3488,12 +3308,6 @@ theorem nthLe_drop (L : List α) {i j : ℕ} (h : i + j < L.length) :
 #align list.nth_le_drop List.nthLe_drop
 -/
 
-/- warning: list.nth_le_drop' -> List.nthLe_drop' is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} (L : List.{u1} α) {i : Nat} {j : Nat} (h : LT.lt.{0} Nat Nat.hasLt j (List.length.{u1} α (List.drop.{u1} α i L))), Eq.{succ u1} α (List.nthLe.{u1} α (List.drop.{u1} α i L) j h) (List.nthLe.{u1} α L (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat Nat.hasAdd) i j) (Iff.mp (LT.lt.{0} Nat (Preorder.toHasLt.{0} Nat (PartialOrder.toPreorder.{0} Nat (SemilatticeInf.toPartialOrder.{0} Nat (Lattice.toSemilatticeInf.{0} Nat (LinearOrder.toLattice.{0} Nat Nat.linearOrder))))) j (HSub.hSub.{0, 0, 0} Nat Nat Nat (instHSub.{0} Nat Nat.hasSub) (List.length.{u1} α L) i)) (LT.lt.{0} Nat (Preorder.toHasLt.{0} Nat (PartialOrder.toPreorder.{0} Nat (SemilatticeInf.toPartialOrder.{0} Nat (Lattice.toSemilatticeInf.{0} Nat (LinearOrder.toLattice.{0} Nat Nat.linearOrder))))) (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat (AddSemigroup.toHasAdd.{0} Nat (AddCommSemigroup.toAddSemigroup.{0} Nat Nat.addCommSemigroup))) i j) (List.length.{u1} α L)) (lt_tsub_iff_left.{0} Nat j (List.length.{u1} α L) i Nat.linearOrder Nat.addCommSemigroup Nat.hasSub Nat.orderedSub) (Eq.subst.{1} Nat (fun (_x : Nat) => LT.lt.{0} Nat (Preorder.toHasLt.{0} Nat (PartialOrder.toPreorder.{0} Nat (SemilatticeInf.toPartialOrder.{0} Nat (Lattice.toSemilatticeInf.{0} Nat (LinearOrder.toLattice.{0} Nat Nat.linearOrder))))) j _x) (List.length.{u1} α (List.drop.{u1} α i L)) (HSub.hSub.{0, 0, 0} Nat Nat Nat (instHSub.{0} Nat Nat.hasSub) (List.length.{u1} α L) i) (List.length_drop.{u1} α i L) h)))
-but is expected to have type
-  forall {α : Type.{u1}} (L : List.{u1} α) {i : Nat} {j : Nat} (h : LT.lt.{0} Nat instLTNat j (List.length.{u1} α (List.drop.{u1} α i L))), Eq.{succ u1} α (List.nthLe.{u1} α (List.drop.{u1} α i L) j h) (List.nthLe.{u1} α L (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat instAddNat) i j) (Iff.mp (LT.lt.{0} Nat (Preorder.toLT.{0} Nat (PartialOrder.toPreorder.{0} Nat (SemilatticeInf.toPartialOrder.{0} Nat (Lattice.toSemilatticeInf.{0} Nat (DistribLattice.toLattice.{0} Nat (instDistribLattice.{0} Nat Nat.linearOrder)))))) j (HSub.hSub.{0, 0, 0} Nat Nat Nat (instHSub.{0} Nat instSubNat) (List.length.{u1} α L) i)) (LT.lt.{0} Nat (Preorder.toLT.{0} Nat (PartialOrder.toPreorder.{0} Nat (SemilatticeInf.toPartialOrder.{0} Nat (Lattice.toSemilatticeInf.{0} Nat (DistribLattice.toLattice.{0} Nat (instDistribLattice.{0} Nat Nat.linearOrder)))))) (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat (AddSemigroup.toAdd.{0} Nat (AddCommSemigroup.toAddSemigroup.{0} Nat Nat.addCommSemigroup))) i j) (List.length.{u1} α L)) (lt_tsub_iff_left.{0} Nat j (List.length.{u1} α L) i Nat.linearOrder Nat.addCommSemigroup instSubNat Nat.instOrderedSubNatInstLENatInstAddNatInstSubNat) (Eq.rec.{0, 1} Nat (List.length.{u1} α (List.drop.{u1} α i L)) (fun (x._@.Mathlib.Data.List.Basic._hyg.24310 : Nat) (h._@.Mathlib.Data.List.Basic._hyg.24311 : Eq.{1} Nat (List.length.{u1} α (List.drop.{u1} α i L)) x._@.Mathlib.Data.List.Basic._hyg.24310) => LT.lt.{0} Nat (Preorder.toLT.{0} Nat (PartialOrder.toPreorder.{0} Nat (SemilatticeInf.toPartialOrder.{0} Nat (Lattice.toSemilatticeInf.{0} Nat (DistribLattice.toLattice.{0} Nat (instDistribLattice.{0} Nat Nat.linearOrder)))))) j x._@.Mathlib.Data.List.Basic._hyg.24310) h (HSub.hSub.{0, 0, 0} Nat Nat Nat (instHSub.{0} Nat instSubNat) (List.length.{u1} α L) i) (List.length_drop.{u1} α i L))))
-Case conversion may be inaccurate. Consider using '#align list.nth_le_drop' List.nthLe_drop'ₓ'. -/
 /-- The `i + j`-th element of a list coincides with the `j`-th element of the list obtained by
 dropping the first `i` elements. Version designed to rewrite from the small list to the big list. -/
 theorem nthLe_drop' (L : List α) {i j : ℕ} (h : j < (L.drop i).length) :
@@ -3534,12 +3348,6 @@ theorem drop_take : ∀ (m : ℕ) (n : ℕ) (l : List α), drop m (take (m + n)
 #align list.drop_take List.drop_take
 -/
 
-/- warning: list.map_drop -> List.map_drop is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u2}} (f : α -> β) (L : List.{u1} α) (i : Nat), Eq.{succ u2} (List.{u2} β) (List.map.{u1, u2} α β f (List.drop.{u1} α i L)) (List.drop.{u2} β i (List.map.{u1, u2} α β f L))
-but is expected to have type
-  forall {α : Type.{u2}} {β : Type.{u1}} (f : α -> β) (L : List.{u2} α) (i : Nat), Eq.{succ u1} (List.{u1} β) (List.map.{u2, u1} α β f (List.drop.{u2} α i L)) (List.drop.{u1} β i (List.map.{u2, u1} α β f L))
-Case conversion may be inaccurate. Consider using '#align list.map_drop List.map_dropₓ'. -/
 theorem map_drop {α β : Type _} (f : α → β) :
     ∀ (L : List α) (i : ℕ), (L.drop i).map f = (L.map f).drop i
   | [], i => by simp
@@ -3697,12 +3505,6 @@ theorem foldr_cons (f : α → β → β) (b : β) (a : α) (l : List α) :
 #align list.foldr_cons List.foldr_cons
 -/
 
-/- warning: list.foldl_append -> List.foldl_append is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u2}} (f : α -> β -> α) (a : α) (l₁ : List.{u2} β) (l₂ : List.{u2} β), Eq.{succ u1} α (List.foldl.{u1, u2} α β f a (Append.append.{u2} (List.{u2} β) (List.hasAppend.{u2} β) l₁ l₂)) (List.foldl.{u1, u2} α β f (List.foldl.{u1, u2} α β f a l₁) l₂)
-but is expected to have type
-  forall {α : Type.{u2}} {β : Type.{u1}} (f : β -> α -> β) (a : β) (l₁ : List.{u2} α) (l₂ : List.{u2} α), Eq.{succ u1} β (List.foldl.{u1, u2} β α f a (HAppend.hAppend.{u2, u2, u2} (List.{u2} α) (List.{u2} α) (List.{u2} α) (instHAppend.{u2} (List.{u2} α) (List.instAppendList.{u2} α)) l₁ l₂)) (List.foldl.{u1, u2} β α f (List.foldl.{u1, u2} β α f a l₁) l₂)
-Case conversion may be inaccurate. Consider using '#align list.foldl_append List.foldl_appendₓ'. -/
 @[simp]
 theorem foldl_append (f : α → β → α) :
     ∀ (a : α) (l₁ l₂ : List β), foldl f a (l₁ ++ l₂) = foldl f (foldl f a l₁) l₂
@@ -3710,12 +3512,6 @@ theorem foldl_append (f : α → β → α) :
   | a, b :: l₁, l₂ => by simp only [cons_append, foldl_cons, foldl_append (f a b) l₁ l₂]
 #align list.foldl_append List.foldl_append
 
-/- warning: list.foldr_append -> List.foldr_append is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u2}} (f : α -> β -> β) (b : β) (l₁ : List.{u1} α) (l₂ : List.{u1} α), Eq.{succ u2} β (List.foldr.{u1, u2} α β f b (Append.append.{u1} (List.{u1} α) (List.hasAppend.{u1} α) l₁ l₂)) (List.foldr.{u1, u2} α β f (List.foldr.{u1, u2} α β f b l₂) l₁)
-but is expected to have type
-  forall {α : Type.{u2}} {β : Type.{u1}} (f : α -> β -> β) (b : β) (l₁ : List.{u2} α) (l₂ : List.{u2} α), Eq.{succ u1} β (List.foldr.{u2, u1} α β f b (HAppend.hAppend.{u2, u2, u2} (List.{u2} α) (List.{u2} α) (List.{u2} α) (instHAppend.{u2} (List.{u2} α) (List.instAppendList.{u2} α)) l₁ l₂)) (List.foldr.{u2, u1} α β f (List.foldr.{u2, u1} α β f b l₂) l₁)
-Case conversion may be inaccurate. Consider using '#align list.foldr_append List.foldr_appendₓ'. -/
 @[simp]
 theorem foldr_append (f : α → β → β) :
     ∀ (b : β) (l₁ l₂ : List α), foldr f b (l₁ ++ l₂) = foldr f (foldr f b l₂) l₁
@@ -3769,23 +3565,11 @@ theorem foldr_join (f : α → β → β) :
 #align list.foldr_join List.foldr_join
 -/
 
-/- warning: list.foldl_reverse -> List.foldl_reverse is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u2}} (f : α -> β -> α) (a : α) (l : List.{u2} β), Eq.{succ u1} α (List.foldl.{u1, u2} α β f a (List.reverse.{u2} β l)) (List.foldr.{u2, u1} β α (fun (x : β) (y : α) => f y x) a l)
-but is expected to have type
-  forall {α : Type.{u2}} {β : Type.{u1}} (f : List.{u2} α) (a : β -> α -> β) (l : β), Eq.{succ u1} β (List.foldl.{u1, u2} β α a l (List.reverse.{u2} α f)) (List.foldr.{u2, u1} α β (fun (x : α) (y : β) => a y x) l f)
-Case conversion may be inaccurate. Consider using '#align list.foldl_reverse List.foldl_reverseₓ'. -/
 theorem foldl_reverse (f : α → β → α) (a : α) (l : List β) :
     foldl f a (reverse l) = foldr (fun x y => f y x) a l := by
   induction l <;> [rfl;simp only [*, reverse_cons, foldl_append, foldl_cons, foldl_nil, foldr]]
 #align list.foldl_reverse List.foldl_reverse
 
-/- warning: list.foldr_reverse -> List.foldr_reverse is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u2}} (f : α -> β -> β) (a : β) (l : List.{u1} α), Eq.{succ u2} β (List.foldr.{u1, u2} α β f a (List.reverse.{u1} α l)) (List.foldl.{u2, u1} β α (fun (x : β) (y : α) => f y x) a l)
-but is expected to have type
-  forall {α : Type.{u2}} {β : Type.{u1}} (f : List.{u2} α) (a : α -> β -> β) (l : β), Eq.{succ u1} β (List.foldr.{u2, u1} α β a l (List.reverse.{u2} α f)) (List.foldl.{u1, u2} β α (fun (x : β) (y : α) => a y x) l f)
-Case conversion may be inaccurate. Consider using '#align list.foldr_reverse List.foldr_reverseₓ'. -/
 theorem foldr_reverse (f : α → β → β) (a : β) (l : List α) :
     foldr f a (reverse l) = foldl (fun x y => f y x) a l :=
   by
@@ -3808,24 +3592,12 @@ theorem reverse_foldl {l : List α} : reverse (foldl (fun t h => h :: t) [] l) =
 #align list.reverse_foldl List.reverse_foldl
 -/
 
-/- warning: list.foldl_map -> List.foldl_map is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u2}} {γ : Type.{u3}} (g : β -> γ) (f : α -> γ -> α) (a : α) (l : List.{u2} β), Eq.{succ u1} α (List.foldl.{u1, u3} α γ f a (List.map.{u2, u3} β γ g l)) (List.foldl.{u1, u2} α β (fun (x : α) (y : β) => f x (g y)) a l)
-but is expected to have type
-  forall {α : Type.{u3}} {β : Type.{u2}} {γ : Type.{u1}} (g : α -> β) (f : γ -> β -> γ) (a : List.{u3} α) (l : γ), Eq.{succ u1} γ (List.foldl.{u1, u2} γ β f l (List.map.{u3, u2} α β g a)) (List.foldl.{u1, u3} γ α (fun (x : γ) (y : α) => f x (g y)) l a)
-Case conversion may be inaccurate. Consider using '#align list.foldl_map List.foldl_mapₓ'. -/
 @[simp]
 theorem foldl_map (g : β → γ) (f : α → γ → α) (a : α) (l : List β) :
     foldl f a (map g l) = foldl (fun x y => f x (g y)) a l := by
   revert a <;> induction l <;> intros <;> [rfl;simp only [*, map, foldl]]
 #align list.foldl_map List.foldl_map
 
-/- warning: list.foldr_map -> List.foldr_map is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u2}} {γ : Type.{u3}} (g : β -> γ) (f : γ -> α -> α) (a : α) (l : List.{u2} β), Eq.{succ u1} α (List.foldr.{u3, u1} γ α f a (List.map.{u2, u3} β γ g l)) (List.foldr.{u2, u1} β α (Function.comp.{succ u2, succ u3, succ u1} β γ (α -> α) f g) a l)
-but is expected to have type
-  forall {α : Type.{u3}} {β : Type.{u2}} {γ : Type.{u1}} (g : α -> β) (f : β -> γ -> γ) (a : List.{u3} α) (l : γ), Eq.{succ u1} γ (List.foldr.{u2, u1} β γ f l (List.map.{u3, u2} α β g a)) (List.foldr.{u3, u1} α γ (fun (x : α) (y : γ) => f (g x) y) l a)
-Case conversion may be inaccurate. Consider using '#align list.foldr_map List.foldr_mapₓ'. -/
 @[simp]
 theorem foldr_map (g : β → γ) (f : γ → α → α) (a : α) (l : List β) :
     foldr f a (map g l) = foldr (f ∘ g) a l := by
@@ -3852,46 +3624,22 @@ theorem foldr_map' {α β : Type u} (g : α → β) (f : α → α → α) (f' :
 #align list.foldr_map' List.foldr_map'
 -/
 
-/- warning: list.foldl_hom -> List.foldl_hom is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u2}} {γ : Type.{u3}} (l : List.{u3} γ) (f : α -> β) (op : α -> γ -> α) (op' : β -> γ -> β) (a : α), (forall (a : α) (x : γ), Eq.{succ u2} β (f (op a x)) (op' (f a) x)) -> (Eq.{succ u2} β (List.foldl.{u2, u3} β γ op' (f a) l) (f (List.foldl.{u1, u3} α γ op a l)))
-but is expected to have type
-  forall {α : Type.{u3}} {β : Type.{u2}} {γ : Type.{u1}} (l : α -> β) (f : α -> γ -> α) (op : β -> γ -> β) (op' : List.{u1} γ) (a : α), (forall (a : α) (x : γ), Eq.{succ u2} β (op (l a) x) (l (f a x))) -> (Eq.{succ u2} β (List.foldl.{u2, u1} β γ op (l a) op') (l (List.foldl.{u3, u1} α γ f a op')))
-Case conversion may be inaccurate. Consider using '#align list.foldl_hom List.foldl_homₓ'. -/
 theorem foldl_hom (l : List γ) (f : α → β) (op : α → γ → α) (op' : β → γ → β) (a : α)
     (h : ∀ a x, f (op a x) = op' (f a) x) : foldl op' (f a) l = f (foldl op a l) :=
   Eq.symm <| by revert a; induction l <;> intros <;> [rfl;simp only [*, foldl]]
 #align list.foldl_hom List.foldl_hom
 
-/- warning: list.foldr_hom -> List.foldr_hom is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u2}} {γ : Type.{u3}} (l : List.{u3} γ) (f : α -> β) (op : γ -> α -> α) (op' : γ -> β -> β) (a : α), (forall (x : γ) (a : α), Eq.{succ u2} β (f (op x a)) (op' x (f a))) -> (Eq.{succ u2} β (List.foldr.{u3, u2} γ β op' (f a) l) (f (List.foldr.{u3, u1} γ α op a l)))
-but is expected to have type
-  forall {α : Type.{u3}} {β : Type.{u2}} {γ : Type.{u1}} (l : α -> β) (f : γ -> α -> α) (op : γ -> β -> β) (op' : List.{u1} γ) (a : α), (forall (x : γ) (a : α), Eq.{succ u2} β (op x (l a)) (l (f x a))) -> (Eq.{succ u2} β (List.foldr.{u1, u2} γ β op (l a) op') (l (List.foldr.{u1, u3} γ α f a op')))
-Case conversion may be inaccurate. Consider using '#align list.foldr_hom List.foldr_homₓ'. -/
 theorem foldr_hom (l : List γ) (f : α → β) (op : γ → α → α) (op' : γ → β → β) (a : α)
     (h : ∀ x a, f (op x a) = op' x (f a)) : foldr op' (f a) l = f (foldr op a l) := by revert a;
   induction l <;> intros <;> [rfl;simp only [*, foldr]]
 #align list.foldr_hom List.foldr_hom
 
-/- warning: list.foldl_hom₂ -> List.foldl_hom₂ is a dubious translation:
-lean 3 declaration is
-  forall {ι : Type.{u4}} {α : Type.{u1}} {β : Type.{u2}} {γ : Type.{u3}} (l : List.{u4} ι) (f : α -> β -> γ) (op₁ : α -> ι -> α) (op₂ : β -> ι -> β) (op₃ : γ -> ι -> γ) (a : α) (b : β), (forall (a : α) (b : β) (i : ι), Eq.{succ u3} γ (f (op₁ a i) (op₂ b i)) (op₃ (f a b) i)) -> (Eq.{succ u3} γ (List.foldl.{u3, u4} γ ι op₃ (f a b) l) (f (List.foldl.{u1, u4} α ι op₁ a l) (List.foldl.{u2, u4} β ι op₂ b l)))
-but is expected to have type
-  forall {ι : Type.{u1}} {α : Type.{u2}} {β : Type.{u3}} {γ : Type.{u4}} (l : List.{u1} ι) (f : α -> β -> γ) (op₁ : α -> ι -> α) (op₂ : β -> ι -> β) (op₃ : γ -> ι -> γ) (a : α) (b : β), (forall (a : α) (b : β) (i : ι), Eq.{succ u4} γ (f (op₁ a i) (op₂ b i)) (op₃ (f a b) i)) -> (Eq.{succ u4} γ (List.foldl.{u4, u1} γ ι op₃ (f a b) l) (f (List.foldl.{u2, u1} α ι op₁ a l) (List.foldl.{u3, u1} β ι op₂ b l)))
-Case conversion may be inaccurate. Consider using '#align list.foldl_hom₂ List.foldl_hom₂ₓ'. -/
 theorem foldl_hom₂ (l : List ι) (f : α → β → γ) (op₁ : α → ι → α) (op₂ : β → ι → β)
     (op₃ : γ → ι → γ) (a : α) (b : β) (h : ∀ a b i, f (op₁ a i) (op₂ b i) = op₃ (f a b) i) :
     foldl op₃ (f a b) l = f (foldl op₁ a l) (foldl op₂ b l) :=
   Eq.symm <| by revert a b; induction l <;> intros <;> [rfl;simp only [*, foldl]]
 #align list.foldl_hom₂ List.foldl_hom₂
 
-/- warning: list.foldr_hom₂ -> List.foldr_hom₂ is a dubious translation:
-lean 3 declaration is
-  forall {ι : Type.{u4}} {α : Type.{u1}} {β : Type.{u2}} {γ : Type.{u3}} (l : List.{u4} ι) (f : α -> β -> γ) (op₁ : ι -> α -> α) (op₂ : ι -> β -> β) (op₃ : ι -> γ -> γ) (a : α) (b : β), (forall (a : α) (b : β) (i : ι), Eq.{succ u3} γ (f (op₁ i a) (op₂ i b)) (op₃ i (f a b))) -> (Eq.{succ u3} γ (List.foldr.{u4, u3} ι γ op₃ (f a b) l) (f (List.foldr.{u4, u1} ι α op₁ a l) (List.foldr.{u4, u2} ι β op₂ b l)))
-but is expected to have type
-  forall {ι : Type.{u1}} {α : Type.{u2}} {β : Type.{u3}} {γ : Type.{u4}} (l : List.{u1} ι) (f : α -> β -> γ) (op₁ : ι -> α -> α) (op₂ : ι -> β -> β) (op₃ : ι -> γ -> γ) (a : α) (b : β), (forall (a : α) (b : β) (i : ι), Eq.{succ u4} γ (f (op₁ i a) (op₂ i b)) (op₃ i (f a b))) -> (Eq.{succ u4} γ (List.foldr.{u1, u4} ι γ op₃ (f a b) l) (f (List.foldr.{u1, u2} ι α op₁ a l) (List.foldr.{u1, u3} ι β op₂ b l)))
-Case conversion may be inaccurate. Consider using '#align list.foldr_hom₂ List.foldr_hom₂ₓ'. -/
 theorem foldr_hom₂ (l : List ι) (f : α → β → γ) (op₁ : ι → α → α) (op₂ : ι → β → β)
     (op₃ : ι → γ → γ) (a : α) (b : β) (h : ∀ a b i, f (op₁ i a) (op₂ i b) = op₃ i (f a b)) :
     foldr op₃ (f a b) l = f (foldr op₁ a l) (foldr op₂ b l) := by revert a;
@@ -3945,24 +3693,12 @@ def foldlRecOn {C : β → Sort _} (l : List α) (op : β → α → β) (b : β
 #align list.foldl_rec_on List.foldlRecOn
 -/
 
-/- warning: list.foldr_rec_on_nil -> List.foldrRecOn_nil is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u2}} {C : β -> Sort.{u3}} (op : α -> β -> β) (b : β) (hb : C b) (hl : forall (b : β), (C b) -> (forall (a : α), (Membership.Mem.{u1, u1} α (List.{u1} α) (List.hasMem.{u1} α) a (List.nil.{u1} α)) -> (C (op a b)))), Eq.{u3} (C (List.foldr.{u1, u2} α β op b (List.nil.{u1} α))) (List.foldrRecOn.{u1, u2, u3} α β (fun (b : β) => C b) (List.nil.{u1} α) op b hb hl) hb
-but is expected to have type
-  forall {α : Type.{u2}} {β : Type.{u3}} {C : β -> Sort.{u1}} (op : α -> β -> β) (b : β) (hb : C b) (hl : forall (b : β), (C b) -> (forall (a : α), (Membership.mem.{u2, u2} α (List.{u2} α) (List.instMembershipList.{u2} α) a (List.nil.{u2} α)) -> (C (op a b)))), Eq.{u1} (C (List.foldr.{u2, u3} α β op b (List.nil.{u2} α))) (List.foldrRecOn.{u2, u3, u1} α β C (List.nil.{u2} α) op b hb hl) hb
-Case conversion may be inaccurate. Consider using '#align list.foldr_rec_on_nil List.foldrRecOn_nilₓ'. -/
 @[simp]
 theorem foldrRecOn_nil {C : β → Sort _} (op : α → β → β) (b) (hb : C b) (hl) :
     foldrRecOn [] op b hb hl = hb :=
   rfl
 #align list.foldr_rec_on_nil List.foldrRecOn_nil
 
-/- warning: list.foldr_rec_on_cons -> List.foldrRecOn_cons is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u2}} {C : β -> Sort.{u3}} (x : α) (l : List.{u1} α) (op : α -> β -> β) (b : β) (hb : C b) (hl : forall (b : β), (C b) -> (forall (a : α), (Membership.Mem.{u1, u1} α (List.{u1} α) (List.hasMem.{u1} α) a (List.cons.{u1} α x l)) -> (C (op a b)))), Eq.{u3} (C (List.foldr.{u1, u2} α β op b (List.cons.{u1} α x l))) (List.foldrRecOn.{u1, u2, u3} α β (fun (b : β) => C b) (List.cons.{u1} α x l) op b hb hl) (hl (List.foldr.{u1, u2} α β op b l) (List.foldrRecOn.{u1, u2, u3} α β C l op b hb (fun (b : β) (hb : C b) (a : α) (ha : Membership.Mem.{u1, u1} α (List.{u1} α) (List.hasMem.{u1} α) a l) => hl b hb a (List.mem_cons_of_mem.{u1} α x a l ha))) x (List.mem_cons_self.{u1} α x l))
-but is expected to have type
-  forall {α : Type.{u2}} {β : Type.{u3}} {C : β -> Sort.{u1}} (x : α) (l : List.{u2} α) (op : α -> β -> β) (b : β) (hb : C b) (hl : forall (b : β), (C b) -> (forall (a : α), (Membership.mem.{u2, u2} α (List.{u2} α) (List.instMembershipList.{u2} α) a (List.cons.{u2} α x l)) -> (C (op a b)))), Eq.{u1} (C (List.foldr.{u2, u3} α β op b (List.cons.{u2} α x l))) (List.foldrRecOn.{u2, u3, u1} α β C (List.cons.{u2} α x l) op b hb hl) (hl (List.foldr.{u2, u3} α β op b l) (List.foldrRecOn.{u2, u3, u1} α β C l op b hb (fun (b : β) (hb : C b) (a : α) (ha : Membership.mem.{u2, u2} α (List.{u2} α) (List.instMembershipList.{u2} α) a l) => hl b hb a (List.mem_cons_of_mem.{u2} α x a l ha))) x (List.mem_cons_self.{u2} α x l))
-Case conversion may be inaccurate. Consider using '#align list.foldr_rec_on_cons List.foldrRecOn_consₓ'. -/
 @[simp]
 theorem foldrRecOn_cons {C : β → Sort _} (x : α) (l : List α) (op : α → β → β) (b) (hb : C b)
     (hl : ∀ (b : β) (hb : C b) (a : α) (ha : a ∈ x :: l), C (op a b)) :
@@ -3972,12 +3708,6 @@ theorem foldrRecOn_cons {C : β → Sort _} (x : α) (l : List α) (op : α →
   rfl
 #align list.foldr_rec_on_cons List.foldrRecOn_cons
 
-/- warning: list.foldl_rec_on_nil -> List.foldlRecOn_nil is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u2}} {C : β -> Sort.{u3}} (op : β -> α -> β) (b : β) (hb : C b) (hl : forall (b : β), (C b) -> (forall (a : α), (Membership.Mem.{u1, u1} α (List.{u1} α) (List.hasMem.{u1} α) a (List.nil.{u1} α)) -> (C (op b a)))), Eq.{u3} (C (List.foldl.{u2, u1} β α op b (List.nil.{u1} α))) (List.foldlRecOn.{u1, u2, u3} α β (fun (b : β) => C b) (List.nil.{u1} α) op b hb hl) hb
-but is expected to have type
-  forall {α : Type.{u2}} {β : Type.{u3}} {C : β -> Sort.{u1}} (op : β -> α -> β) (b : β) (hb : C b) (hl : forall (b : β), (C b) -> (forall (a : α), (Membership.mem.{u2, u2} α (List.{u2} α) (List.instMembershipList.{u2} α) a (List.nil.{u2} α)) -> (C (op b a)))), Eq.{u1} (C (List.foldl.{u3, u2} β α op b (List.nil.{u2} α))) (List.foldlRecOn.{u2, u3, u1} α β C (List.nil.{u2} α) op b hb hl) hb
-Case conversion may be inaccurate. Consider using '#align list.foldl_rec_on_nil List.foldlRecOn_nilₓ'. -/
 @[simp]
 theorem foldlRecOn_nil {C : β → Sort _} (op : β → α → β) (b) (hb : C b) (hl) :
     foldlRecOn [] op b hb hl = hb :=
@@ -4078,11 +3808,6 @@ theorem scanr_nil (f : α → β → β) (b : β) : scanr f b [] = [b] :=
 -/
 
 /- warning: list.scanr_aux_cons clashes with [anonymous] -> [anonymous]
-warning: list.scanr_aux_cons -> [anonymous] is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u2}} (f : α -> β -> β) (b : β) (a : α) (l : List.{u1} α), Eq.{succ u2} (Prod.{u2, u2} β (List.{u2} β)) (List.scanrAux.{u1, u2} α β f b (List.cons.{u1} α a l)) (Prod.mk.{u2, u2} β (List.{u2} β) (List.foldr.{u1, u2} α β f b (List.cons.{u1} α a l)) (List.scanr.{u1, u2} α β f b l))
-but is expected to have type
-  forall {α : Type.{u1}} {β : Type.{u2}}, (Nat -> α -> β) -> Nat -> (List.{u1} α) -> (List.{u2} β)
 Case conversion may be inaccurate. Consider using '#align list.scanr_aux_cons [anonymous]ₓ'. -/
 @[simp]
 theorem [anonymous] (f : α → β → β) (b : β) :
@@ -4233,12 +3958,6 @@ theorem foldlM_nil (f : β → α → m β) {b} : foldlM f b [] = pure b :=
 #align list.mfoldl_nil List.foldlM_nil
 -/
 
-/- warning: list.mfoldr_nil -> List.foldrM_nil is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u2}} {m : Type.{u2} -> Type.{u3}} [_inst_1 : Monad.{u2, u3} m] (f : α -> β -> (m β)) {b : β}, Eq.{succ u3} (m β) (List.foldrM.{u2, u3, u1} (fun {β : Type.{u2}} => m β) _inst_1 β α f b (List.nil.{u1} α)) (Pure.pure.{u2, u3} m (Applicative.toHasPure.{u2, u3} m (Monad.toApplicative.{u2, u3} m _inst_1)) β b)
-but is expected to have type
-  forall {α : Type.{u3} -> Type.{u2}} {β : Type.{u1}} {m : Type.{u3}} [_inst_1 : Monad.{u3, u2} α] (f : β -> m -> (α m)) (b : m), Eq.{succ u2} (α m) (List.foldrM.{u3, u2, u1} α _inst_1 m β f b (List.nil.{u1} β)) (Pure.pure.{u3, u2} α (Applicative.toPure.{u3, u2} α (Monad.toApplicative.{u3, u2} α _inst_1)) m b)
-Case conversion may be inaccurate. Consider using '#align list.mfoldr_nil List.foldrM_nilₓ'. -/
 @[simp]
 theorem foldrM_nil (f : α → β → m β) {b} : foldrM f b [] = pure b :=
   rfl
@@ -4252,23 +3971,11 @@ theorem foldlM_cons {f : β → α → m β} {b a l} :
 #align list.mfoldl_cons List.foldlM_cons
 -/
 
-/- warning: list.mfoldr_cons -> List.foldrM_cons is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u2}} {m : Type.{u2} -> Type.{u3}} [_inst_1 : Monad.{u2, u3} m] {f : α -> β -> (m β)} {b : β} {a : α} {l : List.{u1} α}, Eq.{succ u3} (m β) (List.foldrM.{u2, u3, u1} (fun {β : Type.{u2}} => m β) _inst_1 β α f b (List.cons.{u1} α a l)) (Bind.bind.{u2, u3} m (Monad.toHasBind.{u2, u3} m _inst_1) β β (List.foldrM.{u2, u3, u1} m _inst_1 β α f b l) (f a))
-but is expected to have type
-  forall {α : Type.{u3} -> Type.{u2}} {β : Type.{u1}} {m : Type.{u3}} [_inst_1 : Monad.{u3, u2} α] [f : LawfulMonad.{u3, u2} α _inst_1] (b : β) (a : List.{u1} β) (l : β -> m -> (α m)) (b_1 : m), Eq.{succ u2} (α m) (List.foldrM.{u3, u2, u1} α _inst_1 m β l b_1 (List.cons.{u1} β b a)) (Bind.bind.{u3, u2} α (Monad.toBind.{u3, u2} α _inst_1) m m (List.foldrM.{u3, u2, u1} α _inst_1 m β l b_1 a) (l b))
-Case conversion may be inaccurate. Consider using '#align list.mfoldr_cons List.foldrM_consₓ'. -/
 @[simp]
 theorem foldrM_cons {f : α → β → m β} {b a l} : foldrM f b (a :: l) = foldrM f b l >>= f a :=
   rfl
 #align list.mfoldr_cons List.foldrM_cons
 
-/- warning: list.mfoldr_eq_foldr -> List.foldrM_eq_foldr is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u2}} {m : Type.{u2} -> Type.{u3}} [_inst_1 : Monad.{u2, u3} m] (f : α -> β -> (m β)) (b : β) (l : List.{u1} α), Eq.{succ u3} (m β) (List.foldrM.{u2, u3, u1} (fun {β : Type.{u2}} => m β) _inst_1 β α f b l) (List.foldr.{u1, u3} α (m β) (fun (a : α) (mb : m β) => Bind.bind.{u2, u3} m (Monad.toHasBind.{u2, u3} m _inst_1) β β mb (f a)) (Pure.pure.{u2, u3} m (Applicative.toHasPure.{u2, u3} m (Monad.toApplicative.{u2, u3} m _inst_1)) β b) l)
-but is expected to have type
-  forall {α : Type.{u1}} {β : Type.{u2}} {m : Type.{u2} -> Type.{u3}} [_inst_1 : Monad.{u2, u3} m] [f : LawfulMonad.{u2, u3} m _inst_1] (b : α -> β -> (m β)) (l : β) (l_1 : List.{u1} α), Eq.{succ u3} (m β) (List.foldrM.{u2, u3, u1} m _inst_1 β α b l l_1) (List.foldr.{u1, u3} α (m β) (fun (a : α) (mb : m β) => Bind.bind.{u2, u3} m (Monad.toBind.{u2, u3} m _inst_1) β β mb (b a)) (Pure.pure.{u2, u3} m (Applicative.toPure.{u2, u3} m (Monad.toApplicative.{u2, u3} m _inst_1)) β l) l_1)
-Case conversion may be inaccurate. Consider using '#align list.mfoldr_eq_foldr List.foldrM_eq_foldrₓ'. -/
 theorem foldrM_eq_foldr (f : α → β → m β) (b l) :
     foldrM f b l = foldr (fun a mb => mb >>= f a) (pure b) l := by induction l <;> simp [*]
 #align list.mfoldr_eq_foldr List.foldrM_eq_foldr
@@ -4290,12 +3997,6 @@ theorem foldlM_eq_foldl (f : β → α → m β) (b l) :
 #align list.mfoldl_eq_foldl List.foldlM_eq_foldl
 -/
 
-/- warning: list.mfoldl_append -> List.foldlM_append is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u2}} {m : Type.{u2} -> Type.{u3}} [_inst_1 : Monad.{u2, u3} m] [_inst_2 : LawfulMonad.{u2, u3} m _inst_1] {f : β -> α -> (m β)} {b : β} {l₁ : List.{u1} α} {l₂ : List.{u1} α}, Eq.{succ u3} (m β) (List.foldlM.{u2, u3, u1} (fun {β : Type.{u2}} => m β) _inst_1 β α f b (Append.append.{u1} (List.{u1} α) (List.hasAppend.{u1} α) l₁ l₂)) (Bind.bind.{u2, u3} m (Monad.toHasBind.{u2, u3} m _inst_1) β β (List.foldlM.{u2, u3, u1} m _inst_1 β α f b l₁) (fun (x : β) => List.foldlM.{u2, u3, u1} m _inst_1 β α f x l₂))
-but is expected to have type
-  forall {α : Type.{u3} -> Type.{u2}} {β : Type.{u3}} {m : Type.{u1}} [_inst_1 : Monad.{u3, u2} α] [_inst_2 : LawfulMonad.{u3, u2} α _inst_1] (f : β -> m -> (α β)) (b : β) (l₁ : List.{u1} m) (l₂ : List.{u1} m), Eq.{succ u2} (α β) (List.foldlM.{u3, u2, u1} α _inst_1 β m f b (HAppend.hAppend.{u1, u1, u1} (List.{u1} m) (List.{u1} m) (List.{u1} m) (instHAppend.{u1} (List.{u1} m) (List.instAppendList.{u1} m)) l₁ l₂)) (Bind.bind.{u3, u2} α (Monad.toBind.{u3, u2} α _inst_1) β β (List.foldlM.{u3, u2, u1} α _inst_1 β m f b l₁) (fun (x : β) => List.foldlM.{u3, u2, u1} α _inst_1 β m f x l₂))
-Case conversion may be inaccurate. Consider using '#align list.mfoldl_append List.foldlM_appendₓ'. -/
 @[simp]
 theorem foldlM_append {f : β → α → m β} :
     ∀ {b l₁ l₂}, foldlM f b (l₁ ++ l₂) = foldlM f b l₁ >>= fun x => foldlM f x l₂
@@ -4303,12 +4004,6 @@ theorem foldlM_append {f : β → α → m β} :
   | _, _ :: _, _ => by simp only [cons_append, mfoldl_cons, mfoldl_append, LawfulMonad.bind_assoc]
 #align list.mfoldl_append List.foldlM_append
 
-/- warning: list.mfoldr_append -> List.foldrM_append is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u2}} {m : Type.{u2} -> Type.{u3}} [_inst_1 : Monad.{u2, u3} m] [_inst_2 : LawfulMonad.{u2, u3} m _inst_1] {f : α -> β -> (m β)} {b : β} {l₁ : List.{u1} α} {l₂ : List.{u1} α}, Eq.{succ u3} (m β) (List.foldrM.{u2, u3, u1} (fun {β : Type.{u2}} => m β) _inst_1 β α f b (Append.append.{u1} (List.{u1} α) (List.hasAppend.{u1} α) l₁ l₂)) (Bind.bind.{u2, u3} m (Monad.toHasBind.{u2, u3} m _inst_1) β β (List.foldrM.{u2, u3, u1} m _inst_1 β α f b l₂) (fun (x : β) => List.foldrM.{u2, u3, u1} m _inst_1 β α f x l₁))
-but is expected to have type
-  forall {α : Type.{u3} -> Type.{u2}} {β : Type.{u1}} {m : Type.{u3}} [_inst_1 : Monad.{u3, u2} α] [_inst_2 : LawfulMonad.{u3, u2} α _inst_1] (f : β -> m -> (α m)) (b : m) (l₁ : List.{u1} β) (l₂ : List.{u1} β), Eq.{succ u2} (α m) (List.foldrM.{u3, u2, u1} α _inst_1 m β f b (HAppend.hAppend.{u1, u1, u1} (List.{u1} β) (List.{u1} β) (List.{u1} β) (instHAppend.{u1} (List.{u1} β) (List.instAppendList.{u1} β)) l₁ l₂)) (Bind.bind.{u3, u2} α (Monad.toBind.{u3, u2} α _inst_1) m m (List.foldrM.{u3, u2, u1} α _inst_1 m β f b l₂) (fun (x : m) => List.foldrM.{u3, u2, u1} α _inst_1 m β f x l₁))
-Case conversion may be inaccurate. Consider using '#align list.mfoldr_append List.foldrM_appendₓ'. -/
 @[simp]
 theorem foldrM_append {f : α → β → m β} :
     ∀ {b l₁ l₂}, foldrM f b (l₁ ++ l₂) = foldrM f b l₂ >>= fun x => foldrM f x l₁
@@ -4373,11 +4068,6 @@ theorem splitOnP_nil : [].splitOnP p = [[]] :=
 #align list.split_on_p_nil List.splitOnP_nilₓ
 
 /- warning: list.split_on_p_aux' clashes with [anonymous] -> [anonymous]
-warning: list.split_on_p_aux' -> [anonymous] is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u}} (P : α -> Prop) [_inst_2 : DecidablePred.{succ u} α P], (List.{u} α) -> (List.{u} α) -> (List.{u} (List.{u} α))
-but is expected to have type
-  forall {α : Type.{u}} {P : Type.{v}}, (Nat -> α -> P) -> Nat -> (List.{u} α) -> (List.{v} P)
 Case conversion may be inaccurate. Consider using '#align list.split_on_p_aux' [anonymous]ₓ'. -/
 /-- An auxiliary definition for proving a specification lemma for `split_on_p`.
 
@@ -4390,11 +4080,6 @@ def [anonymous] {α : Type u} (P : α → Prop) [DecidablePred P] : List α →
 #align list.split_on_p_aux' [anonymous]
 
 /- warning: list.split_on_p_aux_eq clashes with [anonymous] -> [anonymous]
-warning: list.split_on_p_aux_eq -> [anonymous] is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u}} (p : α -> Prop) [_inst_1 : DecidablePred.{succ u} α p] (xs : List.{u} α) (ys : List.{u} α), Eq.{succ u} (List.{u} (List.{u} α)) ([anonymous].{u} α p (fun (a : α) => _inst_1 a) xs ys) (List.splitOnPAux.{u} α p (fun (a : α) => _inst_1 a) xs (Append.append.{u} (List.{u} α) (List.hasAppend.{u} α) ys))
-but is expected to have type
-  forall {α : Type.{u}} {p : Type.{v}}, (Nat -> α -> p) -> Nat -> (List.{u} α) -> (List.{v} p)
 Case conversion may be inaccurate. Consider using '#align list.split_on_p_aux_eq [anonymous]ₓ'. -/
 theorem [anonymous] : [anonymous] p xs ys = splitOnPAux p xs ((· ++ ·) ys) :=
   by
@@ -4406,11 +4091,6 @@ theorem [anonymous] : [anonymous] p xs ys = splitOnPAux p xs ((· ++ ·) ys) :=
 #align list.split_on_p_aux_eq [anonymous]
 
 /- warning: list.split_on_p_aux_nil clashes with [anonymous] -> [anonymous]
-warning: list.split_on_p_aux_nil -> [anonymous] is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u}} (p : α -> Prop) [_inst_1 : DecidablePred.{succ u} α p] (xs : List.{u} α), Eq.{succ u} (List.{u} (List.{u} α)) (List.splitOnPAux.{u} α p (fun (a : α) => _inst_1 a) xs (id.{succ u} (List.{u} α))) ([anonymous].{u} α p (fun (a : α) => _inst_1 a) xs (List.nil.{u} α))
-but is expected to have type
-  forall {α : Type.{u}} {p : Type.{v}}, (Nat -> α -> p) -> Nat -> (List.{u} α) -> (List.{v} p)
 Case conversion may be inaccurate. Consider using '#align list.split_on_p_aux_nil [anonymous]ₓ'. -/
 theorem [anonymous] : splitOnPAux p xs id = [anonymous] p xs [] := by rw [split_on_p_aux_eq]; rfl
 #align list.split_on_p_aux_nil [anonymous]
@@ -4432,11 +4112,6 @@ theorem splitOnP_spec (as : List α) :
 #align list.split_on_p_spec List.splitOnP_specₓ
 
 /- warning: list.split_on_p_aux_ne_nil clashes with [anonymous] -> [anonymous]
-warning: list.split_on_p_aux_ne_nil -> [anonymous] is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u}} (p : α -> Prop) [_inst_1 : DecidablePred.{succ u} α p] (xs : List.{u} α) (f : (List.{u} α) -> (List.{u} α)), Ne.{succ u} (List.{u} (List.{u} α)) (List.splitOnPAux.{u} α p (fun (a : α) => _inst_1 a) xs f) (List.nil.{u} (List.{u} α))
-but is expected to have type
-  forall {α : Type.{u}} {p : Type.{v}}, (Nat -> α -> p) -> Nat -> (List.{u} α) -> (List.{v} p)
 Case conversion may be inaccurate. Consider using '#align list.split_on_p_aux_ne_nil [anonymous]ₓ'. -/
 theorem [anonymous] : splitOnPAux p xs f ≠ [] :=
   by
@@ -4445,11 +4120,6 @@ theorem [anonymous] : splitOnPAux p xs f ≠ [] :=
 #align list.split_on_p_aux_ne_nil [anonymous]
 
 /- warning: list.split_on_p_aux_spec clashes with [anonymous] -> [anonymous]
-warning: list.split_on_p_aux_spec -> [anonymous] is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u}} (p : α -> Prop) [_inst_1 : DecidablePred.{succ u} α p] (xs : List.{u} α) (f : (List.{u} α) -> (List.{u} α)), Eq.{succ u} (List.{u} (List.{u} α)) (List.splitOnPAux.{u} α p (fun (a : α) => _inst_1 a) xs f) (List.modifyHead.{u} (List.{u} α) f (List.splitOnP.{u} α p (fun (a : α) => _inst_1 a) xs))
-but is expected to have type
-  forall {α : Type.{u}} {p : Type.{v}}, (Nat -> α -> p) -> Nat -> (List.{u} α) -> (List.{v} p)
 Case conversion may be inaccurate. Consider using '#align list.split_on_p_aux_spec [anonymous]ₓ'. -/
 theorem [anonymous] : splitOnPAux p xs f = (xs.splitOnP p).modifyHead f :=
   by
@@ -4540,12 +4210,6 @@ def attach (l : List α) : List { x // x ∈ l } :=
 #align list.attach List.attach
 -/
 
-/- warning: list.sizeof_lt_sizeof_of_mem -> List.sizeOf_lt_sizeOf_of_mem is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} [_inst_1 : SizeOf.{succ u1} α] {x : α} {l : List.{u1} α}, (Membership.Mem.{u1, u1} α (List.{u1} α) (List.hasMem.{u1} α) x l) -> (LT.lt.{0} Nat Nat.hasLt (SizeOf.sizeOf.{succ u1} α _inst_1 x) (SizeOf.sizeOf.{succ u1} (List.{u1} α) (List.hasSizeof.{u1} α _inst_1) l))
-but is expected to have type
-  forall {α : Type.{u1}} [_inst_1 : SizeOf.{succ u1} α] {x : α} {l : List.{u1} α}, (Membership.mem.{u1, u1} α (List.{u1} α) (List.instMembershipList.{u1} α) x l) -> (LT.lt.{0} Nat instLTNat (SizeOf.sizeOf.{succ u1} α _inst_1 x) (SizeOf.sizeOf.{succ u1} (List.{u1} α) (List._sizeOf_inst.{u1} α _inst_1) l))
-Case conversion may be inaccurate. Consider using '#align list.sizeof_lt_sizeof_of_mem List.sizeOf_lt_sizeOf_of_memₓ'. -/
 theorem sizeOf_lt_sizeOf_of_mem [SizeOf α] {x : α} {l : List α} (hx : x ∈ l) :
     SizeOf.sizeOf x < SizeOf.sizeOf l :=
   by
@@ -4666,12 +4330,6 @@ theorem attach_eq_nil (l : List α) : l.attach = [] ↔ l = [] :=
 #align list.attach_eq_nil List.attach_eq_nil
 -/
 
-/- warning: list.last_pmap -> List.getLast_pmap is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u2}} (p : α -> Prop) (f : forall (a : α), (p a) -> β) (l : List.{u1} α) (hl₁ : forall (a : α), (Membership.Mem.{u1, u1} α (List.{u1} α) (List.hasMem.{u1} α) a l) -> (p a)) (hl₂ : Ne.{succ u1} (List.{u1} α) l (List.nil.{u1} α)), Eq.{succ u2} β (List.getLast.{u2} β (List.pmap.{u1, u2} α β (fun (a : α) => p a) f l hl₁) (mt (Eq.{succ u2} (List.{u2} β) (List.pmap.{u1, u2} α β (fun (a : α) => p a) f l hl₁) (List.nil.{u2} β)) (Eq.{succ u1} (List.{u1} α) l (List.nil.{u1} α)) (Iff.mp (Eq.{succ u2} (List.{u2} β) (List.pmap.{u1, u2} α β (fun (a : α) => p a) f l hl₁) (List.nil.{u2} β)) (Eq.{succ u1} (List.{u1} α) l (List.nil.{u1} α)) (List.pmap_eq_nil.{u1, u2} α β (fun (a : α) => p a) f l hl₁)) hl₂)) (f (List.getLast.{u1} α l hl₂) (hl₁ (List.getLast.{u1} α l hl₂) (List.getLast_mem.{u1} α l hl₂)))
-but is expected to have type
-  forall {α : Type.{u2}} {β : Type.{u1}} (p : α -> Prop) (f : forall (a : α), (p a) -> β) (l : List.{u2} α) (hl₁ : forall (a : α), (Membership.mem.{u2, u2} α (List.{u2} α) (List.instMembershipList.{u2} α) a l) -> (p a)) (hl₂ : Ne.{succ u2} (List.{u2} α) l (List.nil.{u2} α)), Eq.{succ u1} β (List.getLast.{u1} β (List.pmap.{u2, u1} α β (fun (a : α) => p a) f l hl₁) (mt (Eq.{succ u1} (List.{u1} β) (List.pmap.{u2, u1} α β (fun (a : α) => p a) f l hl₁) (List.nil.{u1} β)) (Eq.{succ u2} (List.{u2} α) l (List.nil.{u2} α)) (Iff.mp (Eq.{succ u1} (List.{u1} β) (List.pmap.{u2, u1} α β (fun (a : α) => p a) f l hl₁) (List.nil.{u1} β)) (Eq.{succ u2} (List.{u2} α) l (List.nil.{u2} α)) (List.pmap_eq_nil.{u2, u1} α β (fun (a : α) => p a) f l hl₁)) hl₂)) (f (List.getLast.{u2} α l hl₂) (hl₁ (List.getLast.{u2} α l hl₂) (List.getLast_mem.{u2} α l hl₂)))
-Case conversion may be inaccurate. Consider using '#align list.last_pmap List.getLast_pmapₓ'. -/
 theorem getLast_pmap {α β : Type _} (p : α → Prop) (f : ∀ a, p a → β) (l : List α)
     (hl₁ : ∀ a ∈ l, p a) (hl₂ : l ≠ []) :
     (l.pmap f hl₁).getLast (mt List.pmap_eq_nil.1 hl₂) =
@@ -4710,12 +4368,6 @@ theorem nthLe_pmap {p : α → Prop} (f : ∀ a, p a → β) {l : List α} (h :
 #align list.nth_le_pmap List.nthLe_pmap
 -/
 
-/- warning: list.pmap_append -> List.pmap_append is a dubious translation:
-lean 3 declaration is
-  forall {ι : Type.{u2}} {α : Type.{u1}} {p : ι -> Prop} (f : forall (a : ι), (p a) -> α) (l₁ : List.{u2} ι) (l₂ : List.{u2} ι) (h : forall (a : ι), (Membership.Mem.{u2, u2} ι (List.{u2} ι) (List.hasMem.{u2} ι) a (Append.append.{u2} (List.{u2} ι) (List.hasAppend.{u2} ι) l₁ l₂)) -> (p a)), Eq.{succ u1} (List.{u1} α) (List.pmap.{u2, u1} ι α (fun (a : ι) => p a) f (Append.append.{u2} (List.{u2} ι) (List.hasAppend.{u2} ι) l₁ l₂) h) (Append.append.{u1} (List.{u1} α) (List.hasAppend.{u1} α) (List.pmap.{u2, u1} ι α (fun (a : ι) => p a) f l₁ (fun (a : ι) (ha : Membership.Mem.{u2, u2} ι (List.{u2} ι) (List.hasMem.{u2} ι) a l₁) => h a (List.mem_append_left.{u2} ι a l₁ l₂ ha))) (List.pmap.{u2, u1} ι α (fun (a : ι) => p a) f l₂ (fun (a : ι) (ha : Membership.Mem.{u2, u2} ι (List.{u2} ι) (List.hasMem.{u2} ι) a l₂) => h a (List.mem_append_right.{u2} ι a l₁ l₂ ha))))
-but is expected to have type
-  forall {ι : Type.{u1}} {α : Type.{u2}} {p : ι -> Prop} (f : forall (a : ι), (p a) -> α) (l₁ : List.{u1} ι) (l₂ : List.{u1} ι) (h : forall (a : ι), (Membership.mem.{u1, u1} ι (List.{u1} ι) (List.instMembershipList.{u1} ι) a (HAppend.hAppend.{u1, u1, u1} (List.{u1} ι) (List.{u1} ι) (List.{u1} ι) (instHAppend.{u1} (List.{u1} ι) (List.instAppendList.{u1} ι)) l₁ l₂)) -> (p a)), Eq.{succ u2} (List.{u2} α) (List.pmap.{u1, u2} ι α (fun (a : ι) => p a) f (HAppend.hAppend.{u1, u1, u1} (List.{u1} ι) (List.{u1} ι) (List.{u1} ι) (instHAppend.{u1} (List.{u1} ι) (List.instAppendList.{u1} ι)) l₁ l₂) h) (HAppend.hAppend.{u2, u2, u2} (List.{u2} α) (List.{u2} α) (List.{u2} α) (instHAppend.{u2} (List.{u2} α) (List.instAppendList.{u2} α)) (List.pmap.{u1, u2} ι α (fun (a : ι) => p a) f l₁ (fun (a : ι) (ha : Membership.mem.{u1, u1} ι (List.{u1} ι) (List.instMembershipList.{u1} ι) a l₁) => h a (List.mem_append_left.{u1} ι a l₁ l₂ ha))) (List.pmap.{u1, u2} ι α (fun (a : ι) => p a) f l₂ (fun (a : ι) (ha : Membership.mem.{u1, u1} ι (List.{u1} ι) (List.instMembershipList.{u1} ι) a l₂) => h a (List.mem_append_right.{u1} ι a l₁ l₂ ha))))
-Case conversion may be inaccurate. Consider using '#align list.pmap_append List.pmap_appendₓ'. -/
 theorem pmap_append {p : ι → Prop} (f : ∀ a : ι, p a → α) (l₁ l₂ : List ι)
     (h : ∀ a ∈ l₁ ++ l₂, p a) :
     (l₁ ++ l₂).pmap f h =
@@ -4728,12 +4380,6 @@ theorem pmap_append {p : ι → Prop} (f : ∀ a : ι, p a → α) (l₁ l₂ :
     rw [ih]
 #align list.pmap_append List.pmap_append
 
-/- warning: list.pmap_append' -> List.pmap_append' is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u2}} {p : α -> Prop} (f : forall (a : α), (p a) -> β) (l₁ : List.{u1} α) (l₂ : List.{u1} α) (h₁ : forall (a : α), (Membership.Mem.{u1, u1} α (List.{u1} α) (List.hasMem.{u1} α) a l₁) -> (p a)) (h₂ : forall (a : α), (Membership.Mem.{u1, u1} α (List.{u1} α) (List.hasMem.{u1} α) a l₂) -> (p a)), Eq.{succ u2} (List.{u2} β) (List.pmap.{u1, u2} α β (fun (a : α) => p a) f (Append.append.{u1} (List.{u1} α) (List.hasAppend.{u1} α) l₁ l₂) (fun (a : α) (ha : Membership.Mem.{u1, u1} α (List.{u1} α) (List.hasMem.{u1} α) a (Append.append.{u1} (List.{u1} α) (List.hasAppend.{u1} α) l₁ l₂)) => Or.elim (Membership.Mem.{u1, u1} α (List.{u1} α) (List.hasMem.{u1} α) a l₁) (Membership.Mem.{u1, u1} α (List.{u1} α) (List.hasMem.{u1} α) a l₂) (p a) (Iff.mp (Membership.Mem.{u1, u1} α (List.{u1} α) (List.hasMem.{u1} α) a (Append.append.{u1} (List.{u1} α) (List.hasAppend.{u1} α) l₁ l₂)) (Or (Membership.Mem.{u1, u1} α (List.{u1} α) (List.hasMem.{u1} α) a l₁) (Membership.Mem.{u1, u1} α (List.{u1} α) (List.hasMem.{u1} α) a l₂)) (List.mem_append.{u1} α a l₁ l₂) ha) (h₁ a) (h₂ a))) (Append.append.{u2} (List.{u2} β) (List.hasAppend.{u2} β) (List.pmap.{u1, u2} α β (fun (a : α) => p a) f l₁ h₁) (List.pmap.{u1, u2} α β (fun (a : α) => p a) f l₂ h₂))
-but is expected to have type
-  forall {α : Type.{u2}} {β : Type.{u1}} {p : α -> Prop} (f : forall (a : α), (p a) -> β) (l₁ : List.{u2} α) (l₂ : List.{u2} α) (h₁ : forall (a : α), (Membership.mem.{u2, u2} α (List.{u2} α) (List.instMembershipList.{u2} α) a l₁) -> (p a)) (h₂ : forall (a : α), (Membership.mem.{u2, u2} α (List.{u2} α) (List.instMembershipList.{u2} α) a l₂) -> (p a)), Eq.{succ u1} (List.{u1} β) (List.pmap.{u2, u1} α β (fun (a : α) => p a) f (HAppend.hAppend.{u2, u2, u2} (List.{u2} α) (List.{u2} α) (List.{u2} α) (instHAppend.{u2} (List.{u2} α) (List.instAppendList.{u2} α)) l₁ l₂) (fun (a : α) (ha : Membership.mem.{u2, u2} α (List.{u2} α) (List.instMembershipList.{u2} α) a (HAppend.hAppend.{u2, u2, u2} (List.{u2} α) (List.{u2} α) (List.{u2} α) (instHAppend.{u2} (List.{u2} α) (List.instAppendList.{u2} α)) l₁ l₂)) => Or.elim (Membership.mem.{u2, u2} α (List.{u2} α) (List.instMembershipList.{u2} α) a l₁) (Membership.mem.{u2, u2} α (List.{u2} α) (List.instMembershipList.{u2} α) a l₂) (p a) (Iff.mp (Membership.mem.{u2, u2} α (List.{u2} α) (List.instMembershipList.{u2} α) a (HAppend.hAppend.{u2, u2, u2} (List.{u2} α) (List.{u2} α) (List.{u2} α) (instHAppend.{u2} (List.{u2} α) (List.instAppendList.{u2} α)) l₁ l₂)) (Or (Membership.mem.{u2, u2} α (List.{u2} α) (List.instMembershipList.{u2} α) a l₁) (Membership.mem.{u2, u2} α (List.{u2} α) (List.instMembershipList.{u2} α) a l₂)) (List.mem_append.{u2} α a l₁ l₂) ha) (h₁ a) (h₂ a))) (HAppend.hAppend.{u1, u1, u1} (List.{u1} β) (List.{u1} β) (List.{u1} β) (instHAppend.{u1} (List.{u1} β) (List.instAppendList.{u1} β)) (List.pmap.{u2, u1} α β (fun (a : α) => p a) f l₁ h₁) (List.pmap.{u2, u1} α β (fun (a : α) => p a) f l₂ h₂))
-Case conversion may be inaccurate. Consider using '#align list.pmap_append' List.pmap_append'ₓ'. -/
 theorem pmap_append' {α β : Type _} {p : α → Prop} (f : ∀ a : α, p a → β) (l₁ l₂ : List α)
     (h₁ : ∀ a ∈ l₁, p a) (h₂ : ∀ a ∈ l₂, p a) :
     ((l₁ ++ l₂).pmap f fun a ha => (List.mem_append.1 ha).elim (h₁ a) (h₂ a)) =
@@ -4748,45 +4394,21 @@ section Find
 
 variable {p : α → Prop} [DecidablePred p] {l : List α} {a : α}
 
-/- warning: list.find_nil -> List.find?_nil is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} (p : α -> Prop) [_inst_2 : DecidablePred.{succ u1} α p], Eq.{succ u1} (Option.{u1} α) (List.find?.{u1} α p (fun (a : α) => _inst_2 a) (List.nil.{u1} α)) (Option.none.{u1} α)
-but is expected to have type
-  forall {α : Type.{u1}} (p : α -> Bool), Eq.{succ u1} (Option.{u1} α) (List.find?.{u1} α p (List.nil.{u1} α)) (Option.none.{u1} α)
-Case conversion may be inaccurate. Consider using '#align list.find_nil List.find?_nilₓ'. -/
 @[simp]
 theorem find?_nil (p : α → Prop) [DecidablePred p] : find? p [] = none :=
   rfl
 #align list.find_nil List.find?_nil
 
-/- warning: list.find_cons_of_pos -> List.find?_cons_of_pos is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {p : α -> Prop} [_inst_1 : DecidablePred.{succ u1} α p] {a : α} (l : List.{u1} α), (p a) -> (Eq.{succ u1} (Option.{u1} α) (List.find?.{u1} α p (fun (a : α) => _inst_1 a) (List.cons.{u1} α a l)) (Option.some.{u1} α a))
-but is expected to have type
-  forall {α : Type.{u1}} {p : α -> Bool} {_inst_1 : α} (a : List.{u1} α), (Eq.{1} Bool (p _inst_1) Bool.true) -> (Eq.{succ u1} (Option.{u1} α) (List.find?.{u1} α p (List.cons.{u1} α _inst_1 a)) (Option.some.{u1} α _inst_1))
-Case conversion may be inaccurate. Consider using '#align list.find_cons_of_pos List.find?_cons_of_posₓ'. -/
 @[simp]
 theorem find?_cons_of_pos (l) (h : p a) : find? p (a :: l) = some a :=
   if_pos h
 #align list.find_cons_of_pos List.find?_cons_of_pos
 
-/- warning: list.find_cons_of_neg -> List.find?_cons_of_neg is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {p : α -> Prop} [_inst_1 : DecidablePred.{succ u1} α p] {a : α} (l : List.{u1} α), (Not (p a)) -> (Eq.{succ u1} (Option.{u1} α) (List.find?.{u1} α p (fun (a : α) => _inst_1 a) (List.cons.{u1} α a l)) (List.find?.{u1} α p (fun (a : α) => _inst_1 a) l))
-but is expected to have type
-  forall {α : Type.{u1}} {p : α -> Bool} {_inst_1 : α} (a : List.{u1} α), (Not (Eq.{1} Bool (p _inst_1) Bool.true)) -> (Eq.{succ u1} (Option.{u1} α) (List.find?.{u1} α p (List.cons.{u1} α _inst_1 a)) (List.find?.{u1} α p a))
-Case conversion may be inaccurate. Consider using '#align list.find_cons_of_neg List.find?_cons_of_negₓ'. -/
 @[simp]
 theorem find?_cons_of_neg (l) (h : ¬p a) : find? p (a :: l) = find? p l :=
   if_neg h
 #align list.find_cons_of_neg List.find?_cons_of_neg
 
-/- warning: list.find_eq_none -> List.find?_eq_none is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {p : α -> Prop} [_inst_1 : DecidablePred.{succ u1} α p] {l : List.{u1} α}, Iff (Eq.{succ u1} (Option.{u1} α) (List.find?.{u1} α p (fun (a : α) => _inst_1 a) l) (Option.none.{u1} α)) (forall (x : α), (Membership.Mem.{u1, u1} α (List.{u1} α) (List.hasMem.{u1} α) x l) -> (Not (p x)))
-but is expected to have type
-  forall {α : Type.{u1}} {p : α -> Bool} {_inst_1 : List.{u1} α}, Iff (Eq.{succ u1} (Option.{u1} α) (List.find?.{u1} α p _inst_1) (Option.none.{u1} α)) (forall (x : α), (Membership.mem.{u1, u1} α (List.{u1} α) (List.instMembershipList.{u1} α) x _inst_1) -> (Not (Eq.{1} Bool (p x) Bool.true)))
-Case conversion may be inaccurate. Consider using '#align list.find_eq_none List.find?_eq_noneₓ'. -/
 @[simp]
 theorem find?_eq_none : find? p l = none ↔ ∀ x ∈ l, ¬p x :=
   by
@@ -4797,12 +4419,6 @@ theorem find?_eq_none : find? p l = none ↔ ∀ x ∈ l, ¬p x :=
   · rwa [find_cons_of_neg _ h, iff_true_intro h, true_and_iff]
 #align list.find_eq_none List.find?_eq_none
 
-/- warning: list.find_some -> List.find?_some is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {p : α -> Prop} [_inst_1 : DecidablePred.{succ u1} α p] {l : List.{u1} α} {a : α}, (Eq.{succ u1} (Option.{u1} α) (List.find?.{u1} α p (fun (a : α) => _inst_1 a) l) (Option.some.{u1} α a)) -> (p a)
-but is expected to have type
-  forall {α : Type.{u1}} {p : α -> Bool} {_inst_1 : α} {l : List.{u1} α}, (Eq.{succ u1} (Option.{u1} α) (List.find?.{u1} α p l) (Option.some.{u1} α _inst_1)) -> (Eq.{1} Bool (p _inst_1) Bool.true)
-Case conversion may be inaccurate. Consider using '#align list.find_some List.find?_someₓ'. -/
 theorem find?_some (H : find? p l = some a) : p a :=
   by
   induction' l with b l IH; · contradiction
@@ -4811,12 +4427,6 @@ theorem find?_some (H : find? p l = some a) : p a :=
   · rw [find_cons_of_neg _ h] at H; exact IH H
 #align list.find_some List.find?_some
 
-/- warning: list.find_mem -> List.find?_mem is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {p : α -> Prop} [_inst_1 : DecidablePred.{succ u1} α p] {l : List.{u1} α} {a : α}, (Eq.{succ u1} (Option.{u1} α) (List.find?.{u1} α p (fun (a : α) => _inst_1 a) l) (Option.some.{u1} α a)) -> (Membership.Mem.{u1, u1} α (List.{u1} α) (List.hasMem.{u1} α) a l)
-but is expected to have type
-  forall {α : Type.{u1}} {p : α -> Bool} {_inst_1 : List.{u1} α} {l : α}, (Eq.{succ u1} (Option.{u1} α) (List.find?.{u1} α p _inst_1) (Option.some.{u1} α l)) -> (Membership.mem.{u1, u1} α (List.{u1} α) (List.instMembershipList.{u1} α) l _inst_1)
-Case conversion may be inaccurate. Consider using '#align list.find_mem List.find?_memₓ'. -/
 @[simp]
 theorem find?_mem (H : find? p l = some a) : a ∈ l :=
   by
@@ -4916,46 +4526,22 @@ end Lookmap
 /-! ### filter_map -/
 
 
-/- warning: list.filter_map_nil -> List.filterMap_nil is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u2}} (f : α -> (Option.{u2} β)), Eq.{succ u2} (List.{u2} β) (List.filterMap.{u1, u2} α β f (List.nil.{u1} α)) (List.nil.{u2} β)
-but is expected to have type
-  forall {α : Type.{u2}} {β : Type.{u1}} (f : α -> (Option.{u1} β)), Eq.{succ u1} (List.{u1} β) (List.filterMap.{u2, u1} α β f (List.nil.{u2} α)) (List.nil.{u1} β)
-Case conversion may be inaccurate. Consider using '#align list.filter_map_nil List.filterMap_nilₓ'. -/
 @[simp]
 theorem filterMap_nil (f : α → Option β) : filterMap f [] = [] :=
   rfl
 #align list.filter_map_nil List.filterMap_nil
 
-/- warning: list.filter_map_cons_none -> List.filterMap_cons_none is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u2}} {f : α -> (Option.{u2} β)} (a : α) (l : List.{u1} α), (Eq.{succ u2} (Option.{u2} β) (f a) (Option.none.{u2} β)) -> (Eq.{succ u2} (List.{u2} β) (List.filterMap.{u1, u2} α β f (List.cons.{u1} α a l)) (List.filterMap.{u1, u2} α β f l))
-but is expected to have type
-  forall {α : Type.{u2}} {β : Type.{u1}} {f : α -> (Option.{u1} β)} (a : α) (l : List.{u2} α), (Eq.{succ u1} (Option.{u1} β) (f a) (Option.none.{u1} β)) -> (Eq.{succ u1} (List.{u1} β) (List.filterMap.{u2, u1} α β f (List.cons.{u2} α a l)) (List.filterMap.{u2, u1} α β f l))
-Case conversion may be inaccurate. Consider using '#align list.filter_map_cons_none List.filterMap_cons_noneₓ'. -/
 @[simp]
 theorem filterMap_cons_none {f : α → Option β} (a : α) (l : List α) (h : f a = none) :
     filterMap f (a :: l) = filterMap f l := by simp only [filter_map, h]
 #align list.filter_map_cons_none List.filterMap_cons_none
 
-/- warning: list.filter_map_cons_some -> List.filterMap_cons_some is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u2}} (f : α -> (Option.{u2} β)) (a : α) (l : List.{u1} α) {b : β}, (Eq.{succ u2} (Option.{u2} β) (f a) (Option.some.{u2} β b)) -> (Eq.{succ u2} (List.{u2} β) (List.filterMap.{u1, u2} α β f (List.cons.{u1} α a l)) (List.cons.{u2} β b (List.filterMap.{u1, u2} α β f l)))
-but is expected to have type
-  forall {α : Type.{u2}} {β : Type.{u1}} (f : α -> (Option.{u1} β)) (a : α) (l : List.{u2} α) {b : β}, (Eq.{succ u1} (Option.{u1} β) (f a) (Option.some.{u1} β b)) -> (Eq.{succ u1} (List.{u1} β) (List.filterMap.{u2, u1} α β f (List.cons.{u2} α a l)) (List.cons.{u1} β b (List.filterMap.{u2, u1} α β f l)))
-Case conversion may be inaccurate. Consider using '#align list.filter_map_cons_some List.filterMap_cons_someₓ'. -/
 @[simp]
 theorem filterMap_cons_some (f : α → Option β) (a : α) (l : List α) {b : β} (h : f a = some b) :
     filterMap f (a :: l) = b :: filterMap f l := by
   simp only [filter_map, h] <;> constructor <;> rfl
 #align list.filter_map_cons_some List.filterMap_cons_some
 
-/- warning: list.filter_map_cons -> List.filterMap_cons is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u2}} (f : α -> (Option.{u2} β)) (a : α) (l : List.{u1} α), Eq.{succ u2} (List.{u2} β) (List.filterMap.{u1, u2} α β f (List.cons.{u1} α a l)) (Option.casesOn.{succ u2, u2} β (fun (_x : Option.{u2} β) => List.{u2} β) (f a) (List.filterMap.{u1, u2} α β f l) (fun (b : β) => List.cons.{u2} β b (List.filterMap.{u1, u2} α β f l)))
-but is expected to have type
-  forall {α : Type.{u2}} {β : Type.{u1}} (f : α -> (Option.{u1} β)) (a : α) (l : List.{u2} α), Eq.{succ u1} (List.{u1} β) (List.filterMap.{u2, u1} α β f (List.cons.{u2} α a l)) ([mdata save_info:1 List.filterMap_cons.match_1.{u1, succ u1} β (fun (_x : Option.{u1} β) => List.{u1} β) (f a) (fun (_ : Unit) => List.filterMap.{u2, u1} α β f l) (fun (b : β) => List.cons.{u1} β b (List.filterMap.{u2, u1} α β f l))])
-Case conversion may be inaccurate. Consider using '#align list.filter_map_cons List.filterMap_consₓ'. -/
 theorem filterMap_cons (f : α → Option β) (a : α) (l : List α) :
     filterMap f (a :: l) = Option.casesOn (f a) (filterMap f l) fun b => b :: filterMap f l :=
   by
@@ -4965,12 +4551,6 @@ theorem filterMap_cons (f : α → Option β) (a : α) (l : List α) :
   · rw [filter_map_cons_some _ _ _ Eq]
 #align list.filter_map_cons List.filterMap_cons
 
-/- warning: list.filter_map_append -> List.filterMap_append is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u2}} (l : List.{u1} α) (l' : List.{u1} α) (f : α -> (Option.{u2} β)), Eq.{succ u2} (List.{u2} β) (List.filterMap.{u1, u2} α β f (Append.append.{u1} (List.{u1} α) (List.hasAppend.{u1} α) l l')) (Append.append.{u2} (List.{u2} β) (List.hasAppend.{u2} β) (List.filterMap.{u1, u2} α β f l) (List.filterMap.{u1, u2} α β f l'))
-but is expected to have type
-  forall {α : Type.{u2}} {β : Type.{u1}} (l : List.{u2} α) (l' : List.{u2} α) (f : α -> (Option.{u1} β)), Eq.{succ u1} (List.{u1} β) (List.filterMap.{u2, u1} α β f (HAppend.hAppend.{u2, u2, u2} (List.{u2} α) (List.{u2} α) (List.{u2} α) (instHAppend.{u2} (List.{u2} α) (List.instAppendList.{u2} α)) l l')) (HAppend.hAppend.{u1, u1, u1} (List.{u1} β) (List.{u1} β) (List.{u1} β) (instHAppend.{u1} (List.{u1} β) (List.instAppendList.{u1} β)) (List.filterMap.{u2, u1} α β f l) (List.filterMap.{u2, u1} α β f l'))
-Case conversion may be inaccurate. Consider using '#align list.filter_map_append List.filterMap_appendₓ'. -/
 theorem filterMap_append {α β : Type _} (l l' : List α) (f : α → Option β) :
     filterMap f (l ++ l') = filterMap f l ++ filterMap f l' :=
   by
@@ -4980,12 +4560,6 @@ theorem filterMap_append {α β : Type _} (l l' : List α) (f : α → Option β
     cases f hd <;> simp only [filter_map, hl, cons_append, eq_self_iff_true, and_self_iff]
 #align list.filter_map_append List.filterMap_append
 
-/- warning: list.filter_map_eq_map -> List.filterMap_eq_map is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u2}} (f : α -> β), Eq.{max (succ u1) (succ u2)} ((List.{u1} α) -> (List.{u2} β)) (List.filterMap.{u1, u2} α β (Function.comp.{succ u1, succ u2, succ u2} α β (Option.{u2} β) (Option.some.{u2} β) f)) (List.map.{u1, u2} α β f)
-but is expected to have type
-  forall {α : Type.{u2}} {β : Type.{u1}} (f : α -> β), Eq.{max (succ u2) (succ u1)} ((List.{u2} α) -> (List.{u1} β)) (List.filterMap.{u2, u1} α β (Function.comp.{succ u2, succ u1, succ u1} α β (Option.{u1} β) (Option.some.{u1} β) f)) (List.map.{u2, u1} α β f)
-Case conversion may be inaccurate. Consider using '#align list.filter_map_eq_map List.filterMap_eq_mapₓ'. -/
 theorem filterMap_eq_map (f : α → β) : filterMap (some ∘ f) = map f :=
   by
   funext l
@@ -4993,12 +4567,6 @@ theorem filterMap_eq_map (f : α → β) : filterMap (some ∘ f) = map f :=
   simp only [filter_map_cons_some (some ∘ f) _ _ rfl, IH, map_cons]; constructor <;> rfl
 #align list.filter_map_eq_map List.filterMap_eq_map
 
-/- warning: list.filter_map_eq_filter -> List.filterMap_eq_filter is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} (p : α -> Prop) [_inst_1 : DecidablePred.{succ u1} α p], Eq.{succ u1} ((List.{u1} α) -> (List.{u1} α)) (List.filterMap.{u1, u1} α α (Option.guard.{u1} α p (fun (a : α) => _inst_1 a))) (List.filterₓ.{u1} α p (fun (a : α) => _inst_1 a))
-but is expected to have type
-  forall {α : Type.{u1}} (p : α -> Bool), Eq.{succ u1} ((List.{u1} α) -> (List.{u1} α)) (List.filterMap.{u1, u1} α α (Option.guard.{u1} α (fun (x._@.Std.Data.List.Lemmas._hyg.24241 : α) => Eq.{1} Bool (p x._@.Std.Data.List.Lemmas._hyg.24241) Bool.true) (fun (a : α) => instDecidableEqBool (p a) Bool.true))) (List.filter.{u1} α p)
-Case conversion may be inaccurate. Consider using '#align list.filter_map_eq_filter List.filterMap_eq_filterₓ'. -/
 theorem filterMap_eq_filter (p : α → Prop) [DecidablePred p] :
     filterMap (Option.guard p) = filter p := by
   funext l
@@ -5009,12 +4577,6 @@ theorem filterMap_eq_filter (p : α → Prop) [DecidablePred p] :
   · simp only [filter_map, Option.guard, IH, if_neg pa, filter_cons_of_neg _ pa]
 #align list.filter_map_eq_filter List.filterMap_eq_filter
 
-/- warning: list.filter_map_filter_map -> List.filterMap_filterMap is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u2}} {γ : Type.{u3}} (f : α -> (Option.{u2} β)) (g : β -> (Option.{u3} γ)) (l : List.{u1} α), Eq.{succ u3} (List.{u3} γ) (List.filterMap.{u2, u3} β γ g (List.filterMap.{u1, u2} α β f l)) (List.filterMap.{u1, u3} α γ (fun (x : α) => Option.bind.{u2, u3} β γ (f x) g) l)
-but is expected to have type
-  forall {α : Type.{u3}} {β : Type.{u2}} {γ : Type.{u1}} (f : α -> (Option.{u2} β)) (g : β -> (Option.{u1} γ)) (l : List.{u3} α), Eq.{succ u1} (List.{u1} γ) (List.filterMap.{u2, u1} β γ g (List.filterMap.{u3, u2} α β f l)) (List.filterMap.{u3, u1} α γ (fun (x : α) => Option.bind.{u2, u1} β γ (f x) g) l)
-Case conversion may be inaccurate. Consider using '#align list.filter_map_filter_map List.filterMap_filterMapₓ'. -/
 theorem filterMap_filterMap (f : α → Option β) (g : β → Option γ) (l : List α) :
     filterMap g (filterMap f l) = filterMap (fun x => (f x).bind g) l :=
   by
@@ -5029,45 +4591,21 @@ theorem filterMap_filterMap (f : α → Option β) (g : β → Option γ) (l : L
     simp only [h, h', Option.some_bind']
 #align list.filter_map_filter_map List.filterMap_filterMap
 
-/- warning: list.map_filter_map -> List.map_filterMap is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u2}} {γ : Type.{u3}} (f : α -> (Option.{u2} β)) (g : β -> γ) (l : List.{u1} α), Eq.{succ u3} (List.{u3} γ) (List.map.{u2, u3} β γ g (List.filterMap.{u1, u2} α β f l)) (List.filterMap.{u1, u3} α γ (fun (x : α) => Option.map.{u2, u3} β γ g (f x)) l)
-but is expected to have type
-  forall {α : Type.{u3}} {β : Type.{u2}} {γ : Type.{u1}} (f : α -> (Option.{u2} β)) (g : β -> γ) (l : List.{u3} α), Eq.{succ u1} (List.{u1} γ) (List.map.{u2, u1} β γ g (List.filterMap.{u3, u2} α β f l)) (List.filterMap.{u3, u1} α γ (fun (x : α) => Option.map.{u2, u1} β γ g (f x)) l)
-Case conversion may be inaccurate. Consider using '#align list.map_filter_map List.map_filterMapₓ'. -/
 theorem map_filterMap (f : α → Option β) (g : β → γ) (l : List α) :
     map g (filterMap f l) = filterMap (fun x => (f x).map g) l := by
   rw [← filter_map_eq_map, filter_map_filter_map] <;> rfl
 #align list.map_filter_map List.map_filterMap
 
-/- warning: list.filter_map_map -> List.filterMap_map is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u2}} {γ : Type.{u3}} (f : α -> β) (g : β -> (Option.{u3} γ)) (l : List.{u1} α), Eq.{succ u3} (List.{u3} γ) (List.filterMap.{u2, u3} β γ g (List.map.{u1, u2} α β f l)) (List.filterMap.{u1, u3} α γ (Function.comp.{succ u1, succ u2, succ u3} α β (Option.{u3} γ) g f) l)
-but is expected to have type
-  forall {α : Type.{u3}} {β : Type.{u2}} {γ : Type.{u1}} (f : α -> β) (g : β -> (Option.{u1} γ)) (l : List.{u3} α), Eq.{succ u1} (List.{u1} γ) (List.filterMap.{u2, u1} β γ g (List.map.{u3, u2} α β f l)) (List.filterMap.{u3, u1} α γ (Function.comp.{succ u3, succ u2, succ u1} α β (Option.{u1} γ) g f) l)
-Case conversion may be inaccurate. Consider using '#align list.filter_map_map List.filterMap_mapₓ'. -/
 theorem filterMap_map (f : α → β) (g : β → Option γ) (l : List α) :
     filterMap g (map f l) = filterMap (g ∘ f) l := by
   rw [← filter_map_eq_map, filter_map_filter_map] <;> rfl
 #align list.filter_map_map List.filterMap_map
 
-/- warning: list.filter_filter_map -> List.filter_filterMap is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u2}} (f : α -> (Option.{u2} β)) (p : β -> Prop) [_inst_1 : DecidablePred.{succ u2} β p] (l : List.{u1} α), Eq.{succ u2} (List.{u2} β) (List.filterₓ.{u2} β p (fun (a : β) => _inst_1 a) (List.filterMap.{u1, u2} α β f l)) (List.filterMap.{u1, u2} α β (fun (x : α) => Option.filter.{u2} β p (fun (a : β) => _inst_1 a) (f x)) l)
-but is expected to have type
-  forall {α : Type.{u2}} {β : Type.{u1}} (f : α -> (Option.{u1} β)) (p : β -> Bool) (_inst_1 : List.{u2} α), Eq.{succ u1} (List.{u1} β) (List.filter.{u1} β p (List.filterMap.{u2, u1} α β f _inst_1)) (List.filterMap.{u2, u1} α β (fun (x : α) => Option.filter.{u1} β p (f x)) _inst_1)
-Case conversion may be inaccurate. Consider using '#align list.filter_filter_map List.filter_filterMapₓ'. -/
 theorem filter_filterMap (f : α → Option β) (p : β → Prop) [DecidablePred p] (l : List α) :
     filter p (filterMap f l) = filterMap (fun x => (f x).filterₓ p) l := by
   rw [← filter_map_eq_filter, filter_map_filter_map] <;> rfl
 #align list.filter_filter_map List.filter_filterMap
 
-/- warning: list.filter_map_filter -> List.filterMap_filter is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u2}} (p : α -> Prop) [_inst_1 : DecidablePred.{succ u1} α p] (f : α -> (Option.{u2} β)) (l : List.{u1} α), Eq.{succ u2} (List.{u2} β) (List.filterMap.{u1, u2} α β f (List.filterₓ.{u1} α p (fun (a : α) => _inst_1 a) l)) (List.filterMap.{u1, u2} α β (fun (x : α) => ite.{succ u2} (Option.{u2} β) (p x) (_inst_1 x) (f x) (Option.none.{u2} β)) l)
-but is expected to have type
-  forall {α : Type.{u2}} {β : Type.{u1}} (p : α -> Bool) (_inst_1 : α -> (Option.{u1} β)) (f : List.{u2} α), Eq.{succ u1} (List.{u1} β) (List.filterMap.{u2, u1} α β _inst_1 (List.filter.{u2} α p f)) (List.filterMap.{u2, u1} α β (fun (x : α) => ite.{succ u1} (Option.{u1} β) (Eq.{1} Bool (p x) Bool.true) (instDecidableEqBool (p x) Bool.true) (_inst_1 x) (Option.none.{u1} β)) f)
-Case conversion may be inaccurate. Consider using '#align list.filter_map_filter List.filterMap_filterₓ'. -/
 theorem filterMap_filter (p : α → Prop) [DecidablePred p] (f : α → Option β) (l : List α) :
     filterMap f (filter p l) = filterMap (fun x => if p x then f x else none) l :=
   by
@@ -5086,12 +4624,6 @@ theorem filterMap_some (l : List α) : filterMap some l = l := by
 #align list.filter_map_some List.filterMap_some
 -/
 
-/- warning: list.map_filter_map_some_eq_filter_map_is_some -> List.map_filterMap_some_eq_filter_map_is_some is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u2}} (f : α -> (Option.{u2} β)) (l : List.{u1} α), Eq.{succ u2} (List.{u2} (Option.{u2} β)) (List.map.{u2, u2} β (Option.{u2} β) (Option.some.{u2} β) (List.filterMap.{u1, u2} α β f l)) (List.filterₓ.{u2} (Option.{u2} β) (fun (b : Option.{u2} β) => coeSort.{1, 1} Bool Prop coeSortBool (Option.isSome.{u2} β b)) (fun (a : Option.{u2} β) => Bool.decidableEq (Option.isSome.{u2} β a) Bool.true) (List.map.{u1, u2} α (Option.{u2} β) f l))
-but is expected to have type
-  forall {α : Type.{u2}} {β : Type.{u1}} (f : α -> (Option.{u1} β)) (l : List.{u2} α), Eq.{succ u1} (List.{u1} (Option.{u1} β)) (List.map.{u1, u1} β (Option.{u1} β) (Option.some.{u1} β) (List.filterMap.{u2, u1} α β f l)) (List.filter.{u1} (Option.{u1} β) (fun (a : Option.{u1} β) => Option.isSome.{u1} β a) (List.map.{u2, u1} α (Option.{u1} β) f l))
-Case conversion may be inaccurate. Consider using '#align list.map_filter_map_some_eq_filter_map_is_some List.map_filterMap_some_eq_filter_map_is_someₓ'. -/
 theorem map_filterMap_some_eq_filter_map_is_some (f : α → Option β) (l : List α) :
     (l.filterMap f).map some = (l.map f).filterₓ fun b => b.isSome :=
   by
@@ -5100,12 +4632,6 @@ theorem map_filterMap_some_eq_filter_map_is_some (f : α → Option β) (l : Lis
   · cases h : f x <;> rw [List.filterMap_cons, h] <;> simp [h, ih]
 #align list.map_filter_map_some_eq_filter_map_is_some List.map_filterMap_some_eq_filter_map_is_some
 
-/- warning: list.mem_filter_map -> List.mem_filterMap is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u2}} (f : α -> (Option.{u2} β)) (l : List.{u1} α) {b : β}, Iff (Membership.Mem.{u2, u2} β (List.{u2} β) (List.hasMem.{u2} β) b (List.filterMap.{u1, u2} α β f l)) (Exists.{succ u1} α (fun (a : α) => And (Membership.Mem.{u1, u1} α (List.{u1} α) (List.hasMem.{u1} α) a l) (Eq.{succ u2} (Option.{u2} β) (f a) (Option.some.{u2} β b))))
-but is expected to have type
-  forall {α : Type.{u2}} {β : Type.{u1}} (f : α -> (Option.{u1} β)) (l : List.{u2} α) {b : β}, Iff (Membership.mem.{u1, u1} β (List.{u1} β) (List.instMembershipList.{u1} β) b (List.filterMap.{u2, u1} α β f l)) (Exists.{succ u2} α (fun (a : α) => And (Membership.mem.{u2, u2} α (List.{u2} α) (List.instMembershipList.{u2} α) a l) (Eq.{succ u1} (Option.{u1} β) (f a) (Option.some.{u1} β b))))
-Case conversion may be inaccurate. Consider using '#align list.mem_filter_map List.mem_filterMapₓ'. -/
 @[simp]
 theorem mem_filterMap (f : α → Option β) (l : List α) {b : β} :
     b ∈ filterMap f l ↔ ∃ a, a ∈ l ∧ f a = some b :=
@@ -5122,12 +4648,6 @@ theorem mem_filterMap (f : α → Option β) (l : List α) {b : β} :
       exists_eq_left]
 #align list.mem_filter_map List.mem_filterMap
 
-/- warning: list.filter_map_join -> List.filterMap_join is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u2}} (f : α -> (Option.{u2} β)) (L : List.{u1} (List.{u1} α)), Eq.{succ u2} (List.{u2} β) (List.filterMap.{u1, u2} α β f (List.join.{u1} α L)) (List.join.{u2} β (List.map.{u1, u2} (List.{u1} α) (List.{u2} β) (List.filterMap.{u1, u2} α β f) L))
-but is expected to have type
-  forall {α : Type.{u2}} {β : Type.{u1}} (f : α -> (Option.{u1} β)) (L : List.{u2} (List.{u2} α)), Eq.{succ u1} (List.{u1} β) (List.filterMap.{u2, u1} α β f (List.join.{u2} α L)) (List.join.{u1} β (List.map.{u2, u1} (List.{u2} α) (List.{u1} β) (List.filterMap.{u2, u1} α β f) L))
-Case conversion may be inaccurate. Consider using '#align list.filter_map_join List.filterMap_joinₓ'. -/
 @[simp]
 theorem filterMap_join (f : α → Option β) (L : List (List α)) :
     filterMap f (join L) = join (map (filterMap f) L) :=
@@ -5137,12 +4657,6 @@ theorem filterMap_join (f : α → Option β) (L : List (List α)) :
   · rw [map, join, join, filter_map_append, ih]
 #align list.filter_map_join List.filterMap_join
 
-/- warning: list.map_filter_map_of_inv -> List.map_filterMap_of_inv is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u2}} (f : α -> (Option.{u2} β)) (g : β -> α), (forall (x : α), Eq.{succ u1} (Option.{u1} α) (Option.map.{u2, u1} β α g (f x)) (Option.some.{u1} α x)) -> (forall (l : List.{u1} α), Eq.{succ u1} (List.{u1} α) (List.map.{u2, u1} β α g (List.filterMap.{u1, u2} α β f l)) l)
-but is expected to have type
-  forall {α : Type.{u2}} {β : Type.{u1}} (f : α -> (Option.{u1} β)) (g : β -> α), (forall (x : α), Eq.{succ u2} (Option.{u2} α) (Option.map.{u1, u2} β α g (f x)) (Option.some.{u2} α x)) -> (forall (l : List.{u2} α), Eq.{succ u2} (List.{u2} α) (List.map.{u1, u2} β α g (List.filterMap.{u2, u1} α β f l)) l)
-Case conversion may be inaccurate. Consider using '#align list.map_filter_map_of_inv List.map_filterMap_of_invₓ'. -/
 theorem map_filterMap_of_inv (f : α → Option β) (g : β → α) (H : ∀ x : α, (f x).map g = some x)
     (l : List α) : map g (filterMap f l) = l := by simp only [map_filter_map, H, filter_map_some]
 #align list.map_filter_map_of_inv List.map_filterMap_of_inv
@@ -5152,12 +4666,6 @@ theorem length_filter_le (p : α → Prop) [DecidablePred p] (l : List α) :
   (List.filter_sublist _).length_le
 #align list.length_filter_le List.length_filter_leₓ
 
-/- warning: list.length_filter_map_le -> List.length_filterMap_le is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u2}} (f : α -> (Option.{u2} β)) (l : List.{u1} α), LE.le.{0} Nat Nat.hasLe (List.length.{u2} β (List.filterMap.{u1, u2} α β f l)) (List.length.{u1} α l)
-but is expected to have type
-  forall {α : Type.{u2}} {β : Type.{u1}} (f : α -> (Option.{u1} β)) (l : List.{u2} α), LE.le.{0} Nat instLENat (List.length.{u1} β (List.filterMap.{u2, u1} α β f l)) (List.length.{u2} α l)
-Case conversion may be inaccurate. Consider using '#align list.length_filter_map_le List.length_filterMap_leₓ'. -/
 theorem length_filterMap_le (f : α → Option β) (l : List α) :
     (List.filterMap f l).length ≤ l.length :=
   by
@@ -5165,12 +4673,6 @@ theorem length_filterMap_le (f : α → Option β) (l : List α) :
   apply List.length_filter_le
 #align list.length_filter_map_le List.length_filterMap_le
 
-/- warning: list.sublist.filter_map -> List.Sublist.filterMap is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u2}} (f : α -> (Option.{u2} β)) {l₁ : List.{u1} α} {l₂ : List.{u1} α}, (List.Sublist.{u1} α l₁ l₂) -> (List.Sublist.{u2} β (List.filterMap.{u1, u2} α β f l₁) (List.filterMap.{u1, u2} α β f l₂))
-but is expected to have type
-  forall {α : Type.{u2}} {β : Type.{u1}} {f : List.{u2} α} {l₁ : List.{u2} α} (l₂ : α -> (Option.{u1} β)), (List.Sublist.{u2} α f l₁) -> (List.Sublist.{u1} β (List.filterMap.{u2, u1} α β l₂ f) (List.filterMap.{u2, u1} α β l₂ l₁))
-Case conversion may be inaccurate. Consider using '#align list.sublist.filter_map List.Sublist.filterMapₓ'. -/
 theorem Sublist.filterMap (f : α → Option β) {l₁ l₂ : List α} (s : l₁ <+ l₂) :
     filterMap f l₁ <+ filterMap f l₂ := by
   induction' s with l₁ l₂ a s IH l₁ l₂ a s IH <;> simp only [filter_map] <;> cases' f a with b <;>
@@ -5314,33 +4816,15 @@ section Filter
 
 variable {p : α → Prop} [DecidablePred p]
 
-/- warning: list.filter_singleton -> List.filter_singleton is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {p : α -> Prop} [_inst_1 : DecidablePred.{succ u1} α p] {a : α}, Eq.{succ u1} (List.{u1} α) (List.filterₓ.{u1} α p (fun (a : α) => _inst_1 a) (List.cons.{u1} α a (List.nil.{u1} α))) (ite.{succ u1} (List.{u1} α) (p a) (_inst_1 a) (List.cons.{u1} α a (List.nil.{u1} α)) (List.nil.{u1} α))
-but is expected to have type
-  forall {α : Type.{u1}} {p : α -> Bool} {_inst_1 : α}, Eq.{succ u1} (List.{u1} α) (List.filter.{u1} α p (List.cons.{u1} α _inst_1 (List.nil.{u1} α))) (cond.{u1} (List.{u1} α) (p _inst_1) (List.cons.{u1} α _inst_1 (List.nil.{u1} α)) (List.nil.{u1} α))
-Case conversion may be inaccurate. Consider using '#align list.filter_singleton List.filter_singletonₓ'. -/
 theorem filter_singleton {a : α} : [a].filterₓ p = if p a then [a] else [] :=
   rfl
 #align list.filter_singleton List.filter_singleton
 
-/- warning: list.filter_eq_foldr -> List.filter_eq_foldr is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} (p : α -> Prop) [_inst_2 : DecidablePred.{succ u1} α p] (l : List.{u1} α), Eq.{succ u1} (List.{u1} α) (List.filterₓ.{u1} α p (fun (a : α) => _inst_2 a) l) (List.foldr.{u1, u1} α (List.{u1} α) (fun (a : α) (out : List.{u1} α) => ite.{succ u1} (List.{u1} α) (p a) (_inst_2 a) (List.cons.{u1} α a out) out) (List.nil.{u1} α) l)
-but is expected to have type
-  forall {α : Type.{u1}} (p : α -> Bool) (_inst_2 : List.{u1} α), Eq.{succ u1} (List.{u1} α) (List.filter.{u1} α p _inst_2) (List.foldr.{u1, u1} α (List.{u1} α) (fun (a : α) (out : List.{u1} α) => cond.{u1} (List.{u1} α) (p a) (List.cons.{u1} α a out) out) (List.nil.{u1} α) _inst_2)
-Case conversion may be inaccurate. Consider using '#align list.filter_eq_foldr List.filter_eq_foldrₓ'. -/
 theorem filter_eq_foldr (p : α → Prop) [DecidablePred p] (l : List α) :
     filter p l = foldr (fun a out => if p a then a :: out else out) [] l := by
   induction l <;> simp [*, Filter]
 #align list.filter_eq_foldr List.filter_eq_foldr
 
-/- warning: list.filter_congr' -> List.filter_congr' is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {p : α -> Prop} {q : α -> Prop} [_inst_2 : DecidablePred.{succ u1} α p] [_inst_3 : DecidablePred.{succ u1} α q] {l : List.{u1} α}, (forall (x : α), (Membership.Mem.{u1, u1} α (List.{u1} α) (List.hasMem.{u1} α) x l) -> (Iff (p x) (q x))) -> (Eq.{succ u1} (List.{u1} α) (List.filterₓ.{u1} α p (fun (a : α) => _inst_2 a) l) (List.filterₓ.{u1} α q (fun (a : α) => _inst_3 a) l))
-but is expected to have type
-  forall {α : Type.{u1}} {p : α -> Bool} {q : α -> Bool} {_inst_2 : List.{u1} α}, (forall (x : α), (Membership.mem.{u1, u1} α (List.{u1} α) (List.instMembershipList.{u1} α) x _inst_2) -> (Iff (Eq.{1} Bool (p x) Bool.true) (Eq.{1} Bool (q x) Bool.true))) -> (Eq.{succ u1} (List.{u1} α) (List.filter.{u1} α p _inst_2) (List.filter.{u1} α q _inst_2))
-Case conversion may be inaccurate. Consider using '#align list.filter_congr' List.filter_congr'ₓ'. -/
 theorem filter_congr' {p q : α → Prop} [DecidablePred p] [DecidablePred q] :
     ∀ {l : List α}, (∀ x ∈ l, p x ↔ q x) → filter p l = filter q l
   | [], _ => rfl
@@ -5354,23 +4838,11 @@ theorem filter_congr' {p q : α → Prop} [DecidablePred p] [DecidablePred q] :
       rfl
 #align list.filter_congr' List.filter_congr'
 
-/- warning: list.filter_subset -> List.filter_subset is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {p : α -> Prop} [_inst_1 : DecidablePred.{succ u1} α p] (l : List.{u1} α), HasSubset.Subset.{u1} (List.{u1} α) (List.hasSubset.{u1} α) (List.filterₓ.{u1} α p (fun (a : α) => _inst_1 a) l) l
-but is expected to have type
-  forall {α : Type.{u1}} {p : α -> Bool} (_inst_1 : List.{u1} α), HasSubset.Subset.{u1} (List.{u1} α) (List.instHasSubsetList.{u1} α) (List.filter.{u1} α p _inst_1) _inst_1
-Case conversion may be inaccurate. Consider using '#align list.filter_subset List.filter_subsetₓ'. -/
 @[simp]
 theorem filter_subset (l : List α) : filter p l ⊆ l :=
   (filter_sublist l).Subset
 #align list.filter_subset List.filter_subset
 
-/- warning: list.of_mem_filter -> List.of_mem_filter is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {p : α -> Prop} [_inst_1 : DecidablePred.{succ u1} α p] {a : α} {l : List.{u1} α}, (Membership.Mem.{u1, u1} α (List.{u1} α) (List.hasMem.{u1} α) a (List.filterₓ.{u1} α p (fun (a : α) => _inst_1 a) l)) -> (p a)
-but is expected to have type
-  forall {α : Type.{u1}} {p : α -> Bool} {_inst_1 : α} {a : List.{u1} α}, (Membership.mem.{u1, u1} α (List.{u1} α) (List.instMembershipList.{u1} α) _inst_1 (List.filter.{u1} α p a)) -> (Eq.{1} Bool (p _inst_1) Bool.true)
-Case conversion may be inaccurate. Consider using '#align list.of_mem_filter List.of_mem_filterₓ'. -/
 theorem of_mem_filter {a : α} : ∀ {l}, a ∈ filter p l → p a
   | b :: l, ain =>
     if pb : p b then
@@ -5380,22 +4852,10 @@ theorem of_mem_filter {a : α} : ∀ {l}, a ∈ filter p l → p a
     else by simp only [filter_cons_of_neg _ pb] at ain; exact of_mem_filter ain
 #align list.of_mem_filter List.of_mem_filter
 
-/- warning: list.mem_of_mem_filter -> List.mem_of_mem_filter is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {p : α -> Prop} [_inst_1 : DecidablePred.{succ u1} α p] {a : α} {l : List.{u1} α}, (Membership.Mem.{u1, u1} α (List.{u1} α) (List.hasMem.{u1} α) a (List.filterₓ.{u1} α p (fun (a : α) => _inst_1 a) l)) -> (Membership.Mem.{u1, u1} α (List.{u1} α) (List.hasMem.{u1} α) a l)
-but is expected to have type
-  forall {α : Type.{u1}} {p : α -> Bool} {_inst_1 : α} {a : List.{u1} α}, (Membership.mem.{u1, u1} α (List.{u1} α) (List.instMembershipList.{u1} α) _inst_1 (List.filter.{u1} α p a)) -> (Membership.mem.{u1, u1} α (List.{u1} α) (List.instMembershipList.{u1} α) _inst_1 a)
-Case conversion may be inaccurate. Consider using '#align list.mem_of_mem_filter List.mem_of_mem_filterₓ'. -/
 theorem mem_of_mem_filter {a : α} {l} (h : a ∈ filter p l) : a ∈ l :=
   filter_subset l h
 #align list.mem_of_mem_filter List.mem_of_mem_filter
 
-/- warning: list.mem_filter_of_mem -> List.mem_filter_of_mem is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {p : α -> Prop} [_inst_1 : DecidablePred.{succ u1} α p] {a : α} {l : List.{u1} α}, (Membership.Mem.{u1, u1} α (List.{u1} α) (List.hasMem.{u1} α) a l) -> (p a) -> (Membership.Mem.{u1, u1} α (List.{u1} α) (List.hasMem.{u1} α) a (List.filterₓ.{u1} α p (fun (a : α) => _inst_1 a) l))
-but is expected to have type
-  forall {α : Type.{u1}} {p : α -> Bool} {_inst_1 : α} {a : List.{u1} α}, (Membership.mem.{u1, u1} α (List.{u1} α) (List.instMembershipList.{u1} α) _inst_1 a) -> (Eq.{1} Bool (p _inst_1) Bool.true) -> (Membership.mem.{u1, u1} α (List.{u1} α) (List.instMembershipList.{u1} α) _inst_1 (List.filter.{u1} α p a))
-Case conversion may be inaccurate. Consider using '#align list.mem_filter_of_mem List.mem_filter_of_memₓ'. -/
 theorem mem_filter_of_mem {a : α} : ∀ {l}, a ∈ l → p a → a ∈ filter p l
   | _ :: l, Or.inl rfl, pa => by rw [filter_cons_of_pos _ pa] <;> apply mem_cons_self
   | b :: l, Or.inr ain, pa =>
@@ -5404,23 +4864,11 @@ theorem mem_filter_of_mem {a : α} : ∀ {l}, a ∈ l → p a → a ∈ filter p
     else by rw [filter_cons_of_neg _ pb] <;> apply mem_filter_of_mem ain pa
 #align list.mem_filter_of_mem List.mem_filter_of_mem
 
-/- warning: list.mem_filter -> List.mem_filter is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {p : α -> Prop} [_inst_1 : DecidablePred.{succ u1} α p] {a : α} {l : List.{u1} α}, Iff (Membership.Mem.{u1, u1} α (List.{u1} α) (List.hasMem.{u1} α) a (List.filterₓ.{u1} α p (fun (a : α) => _inst_1 a) l)) (And (Membership.Mem.{u1, u1} α (List.{u1} α) (List.hasMem.{u1} α) a l) (p a))
-but is expected to have type
-  forall {α : Type.{u1}} {p : α} {_inst_1 : α -> Bool} {a : List.{u1} α}, Iff (Membership.mem.{u1, u1} α (List.{u1} α) (List.instMembershipList.{u1} α) p (List.filter.{u1} α _inst_1 a)) (And (Membership.mem.{u1, u1} α (List.{u1} α) (List.instMembershipList.{u1} α) p a) (Eq.{1} Bool (_inst_1 p) Bool.true))
-Case conversion may be inaccurate. Consider using '#align list.mem_filter List.mem_filterₓ'. -/
 @[simp]
 theorem mem_filter {a : α} {l} : a ∈ filter p l ↔ a ∈ l ∧ p a :=
   ⟨fun h => ⟨mem_of_mem_filter h, of_mem_filter h⟩, fun ⟨h₁, h₂⟩ => mem_filter_of_mem h₁ h₂⟩
 #align list.mem_filter List.mem_filter
 
-/- warning: list.monotone_filter_left -> List.monotone_filter_left is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} (p : α -> Prop) [_inst_2 : DecidablePred.{succ u1} α p] {{l : List.{u1} α}} {{l' : List.{u1} α}}, (HasSubset.Subset.{u1} (List.{u1} α) (List.hasSubset.{u1} α) l l') -> (HasSubset.Subset.{u1} (List.{u1} α) (List.hasSubset.{u1} α) (List.filterₓ.{u1} α p (fun (a : α) => _inst_2 a) l) (List.filterₓ.{u1} α p (fun (a : α) => _inst_2 a) l'))
-but is expected to have type
-  forall {α : Type.{u1}} (p : α -> Bool) {{_inst_2 : List.{u1} α}} {{l : List.{u1} α}}, (HasSubset.Subset.{u1} (List.{u1} α) (List.instHasSubsetList.{u1} α) _inst_2 l) -> (HasSubset.Subset.{u1} (List.{u1} α) (List.instHasSubsetList.{u1} α) (List.filter.{u1} α p _inst_2) (List.filter.{u1} α p l))
-Case conversion may be inaccurate. Consider using '#align list.monotone_filter_left List.monotone_filter_leftₓ'. -/
 theorem monotone_filter_left (p : α → Prop) [DecidablePred p] ⦃l l' : List α⦄ (h : l ⊆ l') :
     filter p l ⊆ filter p l' := by
   intro x hx
@@ -5428,12 +4876,6 @@ theorem monotone_filter_left (p : α → Prop) [DecidablePred p] ⦃l l' : List
   exact ⟨h hx.left, hx.right⟩
 #align list.monotone_filter_left List.monotone_filter_left
 
-/- warning: list.filter_eq_self -> List.filter_eq_self is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {p : α -> Prop} [_inst_1 : DecidablePred.{succ u1} α p] {l : List.{u1} α}, Iff (Eq.{succ u1} (List.{u1} α) (List.filterₓ.{u1} α p (fun (a : α) => _inst_1 a) l) l) (forall (a : α), (Membership.Mem.{u1, u1} α (List.{u1} α) (List.hasMem.{u1} α) a l) -> (p a))
-but is expected to have type
-  forall {α : Type.{u1}} {p : α -> Bool} {_inst_1 : List.{u1} α}, Iff (Eq.{succ u1} (List.{u1} α) (List.filter.{u1} α p _inst_1) _inst_1) (forall (a : α), (Membership.mem.{u1, u1} α (List.{u1} α) (List.instMembershipList.{u1} α) a _inst_1) -> (Eq.{1} Bool (p a) Bool.true))
-Case conversion may be inaccurate. Consider using '#align list.filter_eq_self List.filter_eq_selfₓ'. -/
 theorem filter_eq_self {l} : filter p l = l ↔ ∀ a ∈ l, p a :=
   by
   induction' l with a l ih
@@ -5445,44 +4887,20 @@ theorem filter_eq_self {l} : filter p l = l ↔ ∀ a ∈ l, p a :=
     exact mem_cons_self _ _
 #align list.filter_eq_self List.filter_eq_self
 
-/- warning: list.filter_length_eq_length -> List.filter_length_eq_length is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {p : α -> Prop} [_inst_1 : DecidablePred.{succ u1} α p] {l : List.{u1} α}, Iff (Eq.{1} Nat (List.length.{u1} α (List.filterₓ.{u1} α p (fun (a : α) => _inst_1 a) l)) (List.length.{u1} α l)) (forall (a : α), (Membership.Mem.{u1, u1} α (List.{u1} α) (List.hasMem.{u1} α) a l) -> (p a))
-but is expected to have type
-  forall {α : Type.{u1}} {p : α -> Bool} {_inst_1 : List.{u1} α}, Iff (Eq.{1} Nat (List.length.{u1} α (List.filter.{u1} α p _inst_1)) (List.length.{u1} α _inst_1)) (forall (a : α), (Membership.mem.{u1, u1} α (List.{u1} α) (List.instMembershipList.{u1} α) a _inst_1) -> (Eq.{1} Bool (p a) Bool.true))
-Case conversion may be inaccurate. Consider using '#align list.filter_length_eq_length List.filter_length_eq_lengthₓ'. -/
 theorem filter_length_eq_length {l} : (filter p l).length = l.length ↔ ∀ a ∈ l, p a :=
   Iff.trans ⟨l.filter_sublist.eq_of_length, congr_arg List.length⟩ filter_eq_self
 #align list.filter_length_eq_length List.filter_length_eq_length
 
-/- warning: list.filter_eq_nil -> List.filter_eq_nil is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {p : α -> Prop} [_inst_1 : DecidablePred.{succ u1} α p] {l : List.{u1} α}, Iff (Eq.{succ u1} (List.{u1} α) (List.filterₓ.{u1} α p (fun (a : α) => _inst_1 a) l) (List.nil.{u1} α)) (forall (a : α), (Membership.Mem.{u1, u1} α (List.{u1} α) (List.hasMem.{u1} α) a l) -> (Not (p a)))
-but is expected to have type
-  forall {α : Type.{u1}} {p : α -> Bool} {_inst_1 : List.{u1} α}, Iff (Eq.{succ u1} (List.{u1} α) (List.filter.{u1} α p _inst_1) (List.nil.{u1} α)) (forall (a : α), (Membership.mem.{u1, u1} α (List.{u1} α) (List.instMembershipList.{u1} α) a _inst_1) -> (Not (Eq.{1} Bool (p a) Bool.true)))
-Case conversion may be inaccurate. Consider using '#align list.filter_eq_nil List.filter_eq_nilₓ'. -/
 theorem filter_eq_nil {l} : filter p l = [] ↔ ∀ a ∈ l, ¬p a := by
   simp only [eq_nil_iff_forall_not_mem, mem_filter, not_and]
 #align list.filter_eq_nil List.filter_eq_nil
 
 variable (p)
 
-/- warning: list.sublist.filter -> List.Sublist.filter is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} (p : α -> Prop) [_inst_1 : DecidablePred.{succ u1} α p] {l₁ : List.{u1} α} {l₂ : List.{u1} α}, (List.Sublist.{u1} α l₁ l₂) -> (List.Sublist.{u1} α (List.filterₓ.{u1} α p (fun (a : α) => _inst_1 a) l₁) (List.filterₓ.{u1} α p (fun (a : α) => _inst_1 a) l₂))
-but is expected to have type
-  forall {α : Type.{u1}} (p : α -> Bool) {_inst_1 : List.{u1} α} {l₁ : List.{u1} α}, (List.Sublist.{u1} α _inst_1 l₁) -> (List.Sublist.{u1} α (List.filter.{u1} α p _inst_1) (List.filter.{u1} α p l₁))
-Case conversion may be inaccurate. Consider using '#align list.sublist.filter List.Sublist.filterₓ'. -/
 theorem Sublist.filter {l₁ l₂} (s : l₁ <+ l₂) : filter p l₁ <+ filter p l₂ :=
   filterMap_eq_filter p ▸ s.filterMap _
 #align list.sublist.filter List.Sublist.filter
 
-/- warning: list.monotone_filter_right -> List.monotone_filter_right is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} (l : List.{u1} α) {{p : α -> Prop}} {{q : α -> Prop}} [_inst_2 : DecidablePred.{succ u1} α p] [_inst_3 : DecidablePred.{succ u1} α q], (LE.le.{u1} (α -> Prop) (Pi.hasLe.{u1, 0} α (fun (ᾰ : α) => Prop) (fun (i : α) => Prop.le)) p q) -> (List.Sublist.{u1} α (List.filterₓ.{u1} α p (fun (a : α) => _inst_2 a) l) (List.filterₓ.{u1} α q (fun (a : α) => _inst_3 a) l))
-but is expected to have type
-  forall {α : Type.{u1}} (l : List.{u1} α) {{p : α -> Bool}} {{q : α -> Bool}}, (forall (a : α), (Eq.{1} Bool (p a) Bool.true) -> (Eq.{1} Bool (q a) Bool.true)) -> (List.Sublist.{u1} α (List.filter.{u1} α p l) (List.filter.{u1} α q l))
-Case conversion may be inaccurate. Consider using '#align list.monotone_filter_right List.monotone_filter_rightₓ'. -/
 theorem monotone_filter_right (l : List α) ⦃p q : α → Prop⦄ [DecidablePred p] [DecidablePred q]
     (h : p ≤ q) : l.filterₓ p <+ l.filterₓ q :=
   by
@@ -5499,22 +4917,10 @@ theorem monotone_filter_right (l : List α) ⦃p q : α → Prop⦄ [DecidablePr
         exact IH
 #align list.monotone_filter_right List.monotone_filter_right
 
-/- warning: list.map_filter -> List.map_filter is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u2}} (p : α -> Prop) [_inst_1 : DecidablePred.{succ u1} α p] (f : β -> α) (l : List.{u2} β), Eq.{succ u1} (List.{u1} α) (List.filterₓ.{u1} α p (fun (a : α) => _inst_1 a) (List.map.{u2, u1} β α f l)) (List.map.{u2, u1} β α f (List.filterₓ.{u2} β (Function.comp.{succ u2, succ u1, 1} β α Prop p f) (fun (a : β) => _inst_1 (f a)) l))
-but is expected to have type
-  forall {α : Type.{u2}} {β : Type.{u1}} {p : β -> Bool} (_inst_1 : α -> β) (f : List.{u2} α), Eq.{succ u1} (List.{u1} β) (List.filter.{u1} β p (List.map.{u2, u1} α β _inst_1 f)) (List.map.{u2, u1} α β _inst_1 (List.filter.{u2} α (Function.comp.{succ u2, succ u1, 1} α β Bool p _inst_1) f))
-Case conversion may be inaccurate. Consider using '#align list.map_filter List.map_filterₓ'. -/
 theorem map_filter (f : β → α) (l : List β) : filter p (map f l) = map f (filter (p ∘ f) l) := by
   rw [← filter_map_eq_map, filter_filter_map, filter_map_filter] <;> rfl
 #align list.map_filter List.map_filter
 
-/- warning: list.filter_filter -> List.filter_filter is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} (p : α -> Prop) [_inst_1 : DecidablePred.{succ u1} α p] (q : α -> Prop) [_inst_2 : DecidablePred.{succ u1} α q] (l : List.{u1} α), Eq.{succ u1} (List.{u1} α) (List.filterₓ.{u1} α p (fun (a : α) => _inst_1 a) (List.filterₓ.{u1} α q (fun (a : α) => _inst_2 a) l)) (List.filterₓ.{u1} α (fun (a : α) => And (p a) (q a)) (fun (a : α) => And.decidable (p a) (q a) (_inst_1 a) (_inst_2 a)) l)
-but is expected to have type
-  forall {α : Type.{u1}} {p : α -> Bool} (_inst_1 : α -> Bool) (q : List.{u1} α), Eq.{succ u1} (List.{u1} α) (List.filter.{u1} α p (List.filter.{u1} α _inst_1 q)) (List.filter.{u1} α (fun (a : α) => Decidable.decide (And (Eq.{1} Bool (p a) Bool.true) (Eq.{1} Bool (_inst_1 a) Bool.true)) (instDecidableAnd (Eq.{1} Bool (p a) Bool.true) (Eq.{1} Bool (_inst_1 a) Bool.true) (instDecidableEqBool (p a) Bool.true) (instDecidableEqBool (_inst_1 a) Bool.true))) q)
-Case conversion may be inaccurate. Consider using '#align list.filter_filter List.filter_filterₓ'. -/
 @[simp]
 theorem filter_filter (q) [DecidablePred q] :
     ∀ l, filter p (filter q l) = filter (fun a => p a ∧ q a) l
@@ -5525,34 +4931,16 @@ theorem filter_filter (q) [DecidablePred q] :
         eq_self_iff_true]
 #align list.filter_filter List.filter_filter
 
-/- warning: list.filter_true -> List.filter_true is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {h : DecidablePred.{succ u1} α (fun (a : α) => True)} (l : List.{u1} α), Eq.{succ u1} (List.{u1} α) (List.filterₓ.{u1} α (fun (_x : α) => True) h l) l
-but is expected to have type
-  forall {α : Type.{u1}} (h : List.{u1} α), Eq.{succ u1} (List.{u1} α) (List.filter.{u1} α (fun (x._@.Mathlib.Data.List.Basic._hyg.40772 : α) => Bool.true) h) h
-Case conversion may be inaccurate. Consider using '#align list.filter_true List.filter_trueₓ'. -/
 @[simp]
 theorem filter_true {h : DecidablePred fun a : α => True} (l : List α) :
     @filter α (fun _ => True) h l = l := by convert filter_eq_self.2 fun _ _ => trivial
 #align list.filter_true List.filter_true
 
-/- warning: list.filter_false -> List.filter_false is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {h : DecidablePred.{succ u1} α (fun (a : α) => False)} (l : List.{u1} α), Eq.{succ u1} (List.{u1} α) (List.filterₓ.{u1} α (fun (_x : α) => False) h l) (List.nil.{u1} α)
-but is expected to have type
-  forall {α : Type.{u1}} (h : List.{u1} α), Eq.{succ u1} (List.{u1} α) (List.filter.{u1} α (fun (x._@.Mathlib.Data.List.Basic._hyg.40822 : α) => Bool.false) h) (List.nil.{u1} α)
-Case conversion may be inaccurate. Consider using '#align list.filter_false List.filter_falseₓ'. -/
 @[simp]
 theorem filter_false {h : DecidablePred fun a : α => False} (l : List α) :
     @filter α (fun _ => False) h l = [] := by convert filter_eq_nil.2 fun _ _ => id
 #align list.filter_false List.filter_false
 
-/- warning: list.span_eq_take_drop -> List.span_eq_take_drop is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} (p : α -> Prop) [_inst_1 : DecidablePred.{succ u1} α p] (l : List.{u1} α), Eq.{succ u1} (Prod.{u1, u1} (List.{u1} α) (List.{u1} α)) (List.spanₓ.{u1} α p (fun (a : α) => _inst_1 a) l) (Prod.mk.{u1, u1} (List.{u1} α) (List.{u1} α) (List.takeWhile.{u1} α p (fun (a : α) => _inst_1 a) l) (List.dropWhileₓ.{u1} α p (fun (a : α) => _inst_1 a) l))
-but is expected to have type
-  forall {α : Type.{u1}} (p : α -> Bool) (_inst_1 : List.{u1} α), Eq.{succ u1} (Prod.{u1, u1} (List.{u1} α) (List.{u1} α)) (List.span.{u1} α p _inst_1) (Prod.mk.{u1, u1} (List.{u1} α) (List.{u1} α) (List.takeWhile.{u1} α p _inst_1) (List.dropWhile.{u1} α p _inst_1))
-Case conversion may be inaccurate. Consider using '#align list.span_eq_take_drop List.span_eq_take_dropₓ'. -/
 @[simp]
 theorem span_eq_take_drop : ∀ l : List α, span p l = (takeWhile p l, dropWhile p l)
   | [] => rfl
@@ -5561,12 +4949,6 @@ theorem span_eq_take_drop : ∀ l : List α, span p l = (takeWhile p l, dropWhil
     else by simp only [span, take_while, drop_while, if_neg pa]
 #align list.span_eq_take_drop List.span_eq_take_drop
 
-/- warning: list.take_while_append_drop -> List.takeWhile_append_dropWhile is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} (p : α -> Prop) [_inst_1 : DecidablePred.{succ u1} α p] (l : List.{u1} α), Eq.{succ u1} (List.{u1} α) (Append.append.{u1} (List.{u1} α) (List.hasAppend.{u1} α) (List.takeWhile.{u1} α p (fun (a : α) => _inst_1 a) l) (List.dropWhileₓ.{u1} α p (fun (a : α) => _inst_1 a) l)) l
-but is expected to have type
-  forall {α : Type.{u1}} (p : α -> Bool) (_inst_1 : List.{u1} α), Eq.{succ u1} (List.{u1} α) (HAppend.hAppend.{u1, u1, u1} (List.{u1} α) (List.{u1} α) (List.{u1} α) (instHAppend.{u1} (List.{u1} α) (List.instAppendList.{u1} α)) (List.takeWhile.{u1} α p _inst_1) (List.dropWhile.{u1} α p _inst_1)) _inst_1
-Case conversion may be inaccurate. Consider using '#align list.take_while_append_drop List.takeWhile_append_dropWhileₓ'. -/
 @[simp]
 theorem takeWhile_append_dropWhile : ∀ l : List α, takeWhile p l ++ dropWhile p l = l
   | [] => rfl
@@ -5576,12 +4958,6 @@ theorem takeWhile_append_dropWhile : ∀ l : List α, takeWhile p l ++ dropWhile
     else by rw [take_while, drop_while, if_neg pa, if_neg pa, nil_append]
 #align list.take_while_append_drop List.takeWhile_append_dropWhile
 
-/- warning: list.drop_while_nth_le_zero_not -> List.dropWhile_nthLe_zero_not is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} (p : α -> Prop) [_inst_1 : DecidablePred.{succ u1} α p] (l : List.{u1} α) (hl : LT.lt.{0} Nat Nat.hasLt (OfNat.ofNat.{0} Nat 0 (OfNat.mk.{0} Nat 0 (Zero.zero.{0} Nat Nat.hasZero))) (List.length.{u1} α (List.dropWhileₓ.{u1} α p (fun (a : α) => _inst_1 a) l))), Not (p (List.nthLe.{u1} α (List.dropWhileₓ.{u1} α p (fun (a : α) => _inst_1 a) l) (OfNat.ofNat.{0} Nat 0 (OfNat.mk.{0} Nat 0 (Zero.zero.{0} Nat Nat.hasZero))) hl))
-but is expected to have type
-  forall {α : Type.{u1}} (p : α -> Bool) (_inst_1 : List.{u1} α) (l : LT.lt.{0} Nat instLTNat (OfNat.ofNat.{0} Nat 0 (instOfNatNat 0)) (List.length.{u1} α (List.dropWhile.{u1} α p _inst_1))), Not (Eq.{1} Bool (p (List.nthLe.{u1} α (List.dropWhile.{u1} α p _inst_1) (OfNat.ofNat.{0} Nat 0 (instOfNatNat 0)) l)) Bool.true)
-Case conversion may be inaccurate. Consider using '#align list.drop_while_nth_le_zero_not List.dropWhile_nthLe_zero_notₓ'. -/
 theorem dropWhile_nthLe_zero_not (l : List α) (hl : 0 < (l.dropWhileₓ p).length) :
     ¬p ((l.dropWhileₓ p).nthLe 0 hl) :=
   by
@@ -5595,12 +4971,6 @@ theorem dropWhile_nthLe_zero_not (l : List α) (hl : 0 < (l.dropWhileₓ p).leng
 
 variable {p} {l : List α}
 
-/- warning: list.drop_while_eq_nil_iff -> List.dropWhile_eq_nil_iff is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {p : α -> Prop} [_inst_1 : DecidablePred.{succ u1} α p] {l : List.{u1} α}, Iff (Eq.{succ u1} (List.{u1} α) (List.dropWhileₓ.{u1} α p (fun (a : α) => _inst_1 a) l) (List.nil.{u1} α)) (forall (x : α), (Membership.Mem.{u1, u1} α (List.{u1} α) (List.hasMem.{u1} α) x l) -> (p x))
-but is expected to have type
-  forall {α : Type.{u1}} {p : α -> Bool} {_inst_1 : List.{u1} α}, Iff (Eq.{succ u1} (List.{u1} α) (List.dropWhile.{u1} α p _inst_1) (List.nil.{u1} α)) (forall (x : α), (Membership.mem.{u1, u1} α (List.{u1} α) (List.instMembershipList.{u1} α) x _inst_1) -> (Eq.{1} Bool (p x) Bool.true))
-Case conversion may be inaccurate. Consider using '#align list.drop_while_eq_nil_iff List.dropWhile_eq_nil_iffₓ'. -/
 @[simp]
 theorem dropWhile_eq_nil_iff : dropWhile p l = [] ↔ ∀ x ∈ l, p x :=
   by
@@ -5609,12 +4979,6 @@ theorem dropWhile_eq_nil_iff : dropWhile p l = [] ↔ ∀ x ∈ l, p x :=
   · by_cases hp : p x <;> simp [hp, drop_while, IH]
 #align list.drop_while_eq_nil_iff List.dropWhile_eq_nil_iff
 
-/- warning: list.take_while_eq_self_iff -> List.takeWhile_eq_self_iff is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {p : α -> Prop} [_inst_1 : DecidablePred.{succ u1} α p] {l : List.{u1} α}, Iff (Eq.{succ u1} (List.{u1} α) (List.takeWhile.{u1} α p (fun (a : α) => _inst_1 a) l) l) (forall (x : α), (Membership.Mem.{u1, u1} α (List.{u1} α) (List.hasMem.{u1} α) x l) -> (p x))
-but is expected to have type
-  forall {α : Type.{u1}} {p : α -> Bool} {_inst_1 : List.{u1} α}, Iff (Eq.{succ u1} (List.{u1} α) (List.takeWhile.{u1} α p _inst_1) _inst_1) (forall (x : α), (Membership.mem.{u1, u1} α (List.{u1} α) (List.instMembershipList.{u1} α) x _inst_1) -> (Eq.{1} Bool (p x) Bool.true))
-Case conversion may be inaccurate. Consider using '#align list.take_while_eq_self_iff List.takeWhile_eq_self_iffₓ'. -/
 @[simp]
 theorem takeWhile_eq_self_iff : takeWhile p l = l ↔ ∀ x ∈ l, p x :=
   by
@@ -5623,12 +4987,6 @@ theorem takeWhile_eq_self_iff : takeWhile p l = l ↔ ∀ x ∈ l, p x :=
   · by_cases hp : p x <;> simp [hp, take_while, IH]
 #align list.take_while_eq_self_iff List.takeWhile_eq_self_iff
 
-/- warning: list.take_while_eq_nil_iff -> List.takeWhile_eq_nil_iff is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {p : α -> Prop} [_inst_1 : DecidablePred.{succ u1} α p] {l : List.{u1} α}, Iff (Eq.{succ u1} (List.{u1} α) (List.takeWhile.{u1} α p (fun (a : α) => _inst_1 a) l) (List.nil.{u1} α)) (forall (hl : LT.lt.{0} Nat Nat.hasLt (OfNat.ofNat.{0} Nat 0 (OfNat.mk.{0} Nat 0 (Zero.zero.{0} Nat Nat.hasZero))) (List.length.{u1} α l)), Not (p (List.nthLe.{u1} α l (OfNat.ofNat.{0} Nat 0 (OfNat.mk.{0} Nat 0 (Zero.zero.{0} Nat Nat.hasZero))) hl)))
-but is expected to have type
-  forall {α : Type.{u1}} {p : α -> Bool} {_inst_1 : List.{u1} α}, Iff (Eq.{succ u1} (List.{u1} α) (List.takeWhile.{u1} α p _inst_1) (List.nil.{u1} α)) (forall (hl : LT.lt.{0} Nat instLTNat (OfNat.ofNat.{0} Nat 0 (instOfNatNat 0)) (List.length.{u1} α _inst_1)), Not (Eq.{1} Bool (p (List.nthLe.{u1} α _inst_1 (OfNat.ofNat.{0} Nat 0 (instOfNatNat 0)) hl)) Bool.true))
-Case conversion may be inaccurate. Consider using '#align list.take_while_eq_nil_iff List.takeWhile_eq_nil_iffₓ'. -/
 @[simp]
 theorem takeWhile_eq_nil_iff : takeWhile p l = [] ↔ ∀ hl : 0 < l.length, ¬p (l.nthLe 0 hl) :=
   by
@@ -5637,12 +4995,6 @@ theorem takeWhile_eq_nil_iff : takeWhile p l = [] ↔ ∀ hl : 0 < l.length, ¬p
   · by_cases hp : p x <;> simp [hp, take_while, IH]
 #align list.take_while_eq_nil_iff List.takeWhile_eq_nil_iff
 
-/- warning: list.mem_take_while_imp -> List.mem_takeWhile_imp is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {p : α -> Prop} [_inst_1 : DecidablePred.{succ u1} α p] {l : List.{u1} α} {x : α}, (Membership.Mem.{u1, u1} α (List.{u1} α) (List.hasMem.{u1} α) x (List.takeWhile.{u1} α p (fun (a : α) => _inst_1 a) l)) -> (p x)
-but is expected to have type
-  forall {α : Type.{u1}} {p : α -> Bool} {_inst_1 : List.{u1} α} {l : α}, (Membership.mem.{u1, u1} α (List.{u1} α) (List.instMembershipList.{u1} α) l (List.takeWhile.{u1} α p _inst_1)) -> (Eq.{1} Bool (p l) Bool.true)
-Case conversion may be inaccurate. Consider using '#align list.mem_take_while_imp List.mem_takeWhile_impₓ'. -/
 theorem mem_takeWhile_imp {x : α} (hx : x ∈ takeWhile p l) : p x :=
   by
   induction' l with hd tl IH
@@ -5656,12 +5008,6 @@ theorem mem_takeWhile_imp {x : α} (hx : x ∈ takeWhile p l) : p x :=
     · simpa using hx
 #align list.mem_take_while_imp List.mem_takeWhile_imp
 
-/- warning: list.take_while_take_while -> List.takeWhile_takeWhile is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} (p : α -> Prop) (q : α -> Prop) [_inst_2 : DecidablePred.{succ u1} α p] [_inst_3 : DecidablePred.{succ u1} α q] (l : List.{u1} α), Eq.{succ u1} (List.{u1} α) (List.takeWhile.{u1} α p (fun (a : α) => _inst_2 a) (List.takeWhile.{u1} α q (fun (a : α) => _inst_3 a) l)) (List.takeWhile.{u1} α (fun (a : α) => And (p a) (q a)) (fun (a : α) => And.decidable (p a) (q a) (_inst_2 a) (_inst_3 a)) l)
-but is expected to have type
-  forall {α : Type.{u1}} (p : α -> Bool) (q : α -> Bool) (_inst_2 : List.{u1} α), Eq.{succ u1} (List.{u1} α) (List.takeWhile.{u1} α p (List.takeWhile.{u1} α q _inst_2)) (List.takeWhile.{u1} α (fun (a : α) => Decidable.decide (And (Eq.{1} Bool (p a) Bool.true) (Eq.{1} Bool (q a) Bool.true)) (instDecidableAnd (Eq.{1} Bool (p a) Bool.true) (Eq.{1} Bool (q a) Bool.true) (instDecidableEqBool (p a) Bool.true) (instDecidableEqBool (q a) Bool.true))) _inst_2)
-Case conversion may be inaccurate. Consider using '#align list.take_while_take_while List.takeWhile_takeWhileₓ'. -/
 theorem takeWhile_takeWhile (p q : α → Prop) [DecidablePred p] [DecidablePred q] (l : List α) :
     takeWhile p (takeWhile q l) = takeWhile (fun a => p a ∧ q a) l :=
   by
@@ -5670,12 +5016,6 @@ theorem takeWhile_takeWhile (p q : α → Prop) [DecidablePred p] [DecidablePred
   · by_cases hp : p hd <;> by_cases hq : q hd <;> simp [take_while, hp, hq, IH]
 #align list.take_while_take_while List.takeWhile_takeWhile
 
-/- warning: list.take_while_idem -> List.takeWhile_idem is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {p : α -> Prop} [_inst_1 : DecidablePred.{succ u1} α p] {l : List.{u1} α}, Eq.{succ u1} (List.{u1} α) (List.takeWhile.{u1} α p (fun (a : α) => _inst_1 a) (List.takeWhile.{u1} α p (fun (a : α) => _inst_1 a) l)) (List.takeWhile.{u1} α p (fun (a : α) => _inst_1 a) l)
-but is expected to have type
-  forall {α : Type.{u1}} {p : α -> Bool} {_inst_1 : List.{u1} α}, Eq.{succ u1} (List.{u1} α) (List.takeWhile.{u1} α p (List.takeWhile.{u1} α p _inst_1)) (List.takeWhile.{u1} α p _inst_1)
-Case conversion may be inaccurate. Consider using '#align list.take_while_idem List.takeWhile_idemₓ'. -/
 theorem takeWhile_idem : takeWhile p (takeWhile p l) = takeWhile p l := by
   simp_rw [take_while_take_while, and_self_iff]
 #align list.take_while_idem List.takeWhile_idem
@@ -5919,12 +5259,6 @@ theorem erase_comm (a b : α) (l : List α) : (l.eraseₓ a).eraseₓ b = (l.era
     else by simp only [erase_of_not_mem ha, erase_of_not_mem (mt mem_of_mem_erase ha)]
 #align list.erase_comm List.erase_commₓ
 
-/- warning: list.map_erase -> List.map_erase is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u2}} [_inst_1 : DecidableEq.{succ u1} α] [_inst_2 : DecidableEq.{succ u2} β] {f : α -> β}, (Function.Injective.{succ u1, succ u2} α β f) -> (forall {a : α} (l : List.{u1} α), Eq.{succ u2} (List.{u2} β) (List.map.{u1, u2} α β f (List.eraseₓ.{u1} α (fun (a : α) (b : α) => _inst_1 a b) l a)) (List.eraseₓ.{u2} β (fun (a : β) (b : β) => _inst_2 a b) (List.map.{u1, u2} α β f l) (f a)))
-but is expected to have type
-  forall {α : Type.{u1}} {β : Type.{u2}} [_inst_1 : DecidableEq.{succ u1} α] [_inst_2 : DecidableEq.{succ u2} β] {f : α -> β}, (Function.Injective.{succ u1, succ u2} α β f) -> (forall {a : α} (l : List.{u1} α), Eq.{succ u2} (List.{u2} β) (List.map.{u1, u2} α β f (List.erase.{u1} α (instBEq.{u1} α (fun (a : α) (b : α) => _inst_1 a b)) l a)) (List.erase.{u2} β (instBEq.{u2} β (fun (a : β) (b : β) => _inst_2 a b)) (List.map.{u1, u2} α β f l) (f a)))
-Case conversion may be inaccurate. Consider using '#align list.map_erase List.map_eraseₓ'. -/
 theorem map_erase [DecidableEq β] {f : α → β} (finj : Injective f) {a : α} (l : List α) :
     map f (l.eraseₓ a) = (map f l).eraseₓ (f a) :=
   by
@@ -5932,12 +5266,6 @@ theorem map_erase [DecidableEq β] {f : α → β} (finj : Injective f) {a : α}
   simp [erase_eq_erasep, erase_eq_erasep, erasep_map, this]
 #align list.map_erase List.map_erase
 
-/- warning: list.map_foldl_erase -> List.map_foldl_erase is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u2}} [_inst_1 : DecidableEq.{succ u1} α] [_inst_2 : DecidableEq.{succ u2} β] {f : α -> β}, (Function.Injective.{succ u1, succ u2} α β f) -> (forall {l₁ : List.{u1} α} {l₂ : List.{u1} α}, Eq.{succ u2} (List.{u2} β) (List.map.{u1, u2} α β f (List.foldl.{u1, u1} (List.{u1} α) α (List.eraseₓ.{u1} α (fun (a : α) (b : α) => _inst_1 a b)) l₁ l₂)) (List.foldl.{u2, u1} (List.{u2} β) α (fun (l : List.{u2} β) (a : α) => List.eraseₓ.{u2} β (fun (a : β) (b : β) => _inst_2 a b) l (f a)) (List.map.{u1, u2} α β f l₁) l₂))
-but is expected to have type
-  forall {α : Type.{u1}} {β : Type.{u2}} [_inst_1 : DecidableEq.{succ u1} α] [_inst_2 : DecidableEq.{succ u2} β] {f : α -> β}, (Function.Injective.{succ u1, succ u2} α β f) -> (forall {l₁ : List.{u1} α} {l₂ : List.{u1} α}, Eq.{succ u2} (List.{u2} β) (List.map.{u1, u2} α β f (List.foldl.{u1, u1} (List.{u1} α) α (List.erase.{u1} α (instBEq.{u1} α (fun (a : α) (b : α) => _inst_1 a b))) l₁ l₂)) (List.foldl.{u2, u1} (List.{u2} β) α (fun (l : List.{u2} β) (a : α) => List.erase.{u2} β (instBEq.{u2} β (fun (a : β) (b : β) => _inst_2 a b)) l (f a)) (List.map.{u1, u2} α β f l₁) l₂))
-Case conversion may be inaccurate. Consider using '#align list.map_foldl_erase List.map_foldl_eraseₓ'. -/
 theorem map_foldl_erase [DecidableEq β] {f : α → β} (finj : Injective f) {l₁ l₂ : List α} :
     map f (foldl List.erase l₁ l₂) = foldl (fun l a => l.eraseₓ (f a)) (map f l₁) l₂ := by
   induction l₂ generalizing l₁ <;> [rfl;simp only [foldl_cons, map_erase finj, *]]
@@ -5959,24 +5287,12 @@ theorem diff_nil (l : List α) : l.diffₓ [] = l :=
 #align list.diff_nil List.diff_nil
 -/
 
-/- warning: list.diff_cons -> List.diff_cons is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} [_inst_1 : DecidableEq.{succ u1} α] (l₁ : List.{u1} α) (l₂ : List.{u1} α) (a : α), Eq.{succ u1} (List.{u1} α) (List.diffₓ.{u1} α (fun (a : α) (b : α) => _inst_1 a b) l₁ (List.cons.{u1} α a l₂)) (List.diffₓ.{u1} α (fun (a : α) (b : α) => _inst_1 a b) (List.eraseₓ.{u1} α (fun (a : α) (b : α) => _inst_1 a b) l₁ a) l₂)
-but is expected to have type
-  forall {α : Type.{u1}} [_inst_1 : DecidableEq.{succ u1} α] (l₁ : List.{u1} α) (l₂ : List.{u1} α) (a : α), Eq.{succ u1} (List.{u1} α) (List.diff.{u1} α (instBEq.{u1} α (fun (a : α) (b : α) => _inst_1 a b)) l₁ (List.cons.{u1} α a l₂)) (List.diff.{u1} α (instBEq.{u1} α (fun (a : α) (b : α) => _inst_1 a b)) (List.erase.{u1} α (instBEq.{u1} α (fun (a : α) (b : α) => _inst_1 a b)) l₁ a) l₂)
-Case conversion may be inaccurate. Consider using '#align list.diff_cons List.diff_consₓ'. -/
 @[simp]
 theorem diff_cons (l₁ l₂ : List α) (a : α) : l₁.diffₓ (a :: l₂) = (l₁.eraseₓ a).diffₓ l₂ :=
   if h : a ∈ l₁ then by simp only [List.diff, if_pos h]
   else by simp only [List.diff, if_neg h, erase_of_not_mem h]
 #align list.diff_cons List.diff_cons
 
-/- warning: list.diff_cons_right -> List.diff_cons_right is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} [_inst_1 : DecidableEq.{succ u1} α] (l₁ : List.{u1} α) (l₂ : List.{u1} α) (a : α), Eq.{succ u1} (List.{u1} α) (List.diffₓ.{u1} α (fun (a : α) (b : α) => _inst_1 a b) l₁ (List.cons.{u1} α a l₂)) (List.eraseₓ.{u1} α (fun (a : α) (b : α) => _inst_1 a b) (List.diffₓ.{u1} α (fun (a : α) (b : α) => _inst_1 a b) l₁ l₂) a)
-but is expected to have type
-  forall {α : Type.{u1}} [_inst_1 : DecidableEq.{succ u1} α] (l₁ : List.{u1} α) (l₂ : List.{u1} α) (a : α), Eq.{succ u1} (List.{u1} α) (List.diff.{u1} α (instBEq.{u1} α (fun (a : α) (b : α) => _inst_1 a b)) l₁ (List.cons.{u1} α a l₂)) (List.erase.{u1} α (instBEq.{u1} α (fun (a : α) (b : α) => _inst_1 a b)) (List.diff.{u1} α (instBEq.{u1} α (fun (a : α) (b : α) => _inst_1 a b)) l₁ l₂) a)
-Case conversion may be inaccurate. Consider using '#align list.diff_cons_right List.diff_cons_rightₓ'. -/
 theorem diff_cons_right (l₁ l₂ : List α) (a : α) : l₁.diffₓ (a :: l₂) = (l₁.diffₓ l₂).eraseₓ a :=
   by
   induction' l₂ with b l₂ ih generalizing l₁ a
@@ -5984,33 +5300,15 @@ theorem diff_cons_right (l₁ l₂ : List α) (a : α) : l₁.diffₓ (a :: l₂
   · rw [diff_cons, diff_cons, erase_comm, ← diff_cons, ih, ← diff_cons]
 #align list.diff_cons_right List.diff_cons_right
 
-/- warning: list.diff_erase -> List.diff_erase is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} [_inst_1 : DecidableEq.{succ u1} α] (l₁ : List.{u1} α) (l₂ : List.{u1} α) (a : α), Eq.{succ u1} (List.{u1} α) (List.eraseₓ.{u1} α (fun (a : α) (b : α) => _inst_1 a b) (List.diffₓ.{u1} α (fun (a : α) (b : α) => _inst_1 a b) l₁ l₂) a) (List.diffₓ.{u1} α (fun (a : α) (b : α) => _inst_1 a b) (List.eraseₓ.{u1} α (fun (a : α) (b : α) => _inst_1 a b) l₁ a) l₂)
-but is expected to have type
-  forall {α : Type.{u1}} [_inst_1 : DecidableEq.{succ u1} α] (l₁ : List.{u1} α) (l₂ : List.{u1} α) (a : α), Eq.{succ u1} (List.{u1} α) (List.erase.{u1} α (instBEq.{u1} α (fun (a : α) (b : α) => _inst_1 a b)) (List.diff.{u1} α (instBEq.{u1} α (fun (a : α) (b : α) => _inst_1 a b)) l₁ l₂) a) (List.diff.{u1} α (instBEq.{u1} α (fun (a : α) (b : α) => _inst_1 a b)) (List.erase.{u1} α (instBEq.{u1} α (fun (a : α) (b : α) => _inst_1 a b)) l₁ a) l₂)
-Case conversion may be inaccurate. Consider using '#align list.diff_erase List.diff_eraseₓ'. -/
 theorem diff_erase (l₁ l₂ : List α) (a : α) : (l₁.diffₓ l₂).eraseₓ a = (l₁.eraseₓ a).diffₓ l₂ := by
   rw [← diff_cons_right, diff_cons]
 #align list.diff_erase List.diff_erase
 
-/- warning: list.nil_diff -> List.nil_diff is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} [_inst_1 : DecidableEq.{succ u1} α] (l : List.{u1} α), Eq.{succ u1} (List.{u1} α) (List.diffₓ.{u1} α (fun (a : α) (b : α) => _inst_1 a b) (List.nil.{u1} α) l) (List.nil.{u1} α)
-but is expected to have type
-  forall {α : Type.{u1}} [_inst_1 : DecidableEq.{succ u1} α] (l : List.{u1} α), Eq.{succ u1} (List.{u1} α) (List.diff.{u1} α (instBEq.{u1} α (fun (a : α) (b : α) => _inst_1 a b)) (List.nil.{u1} α) l) (List.nil.{u1} α)
-Case conversion may be inaccurate. Consider using '#align list.nil_diff List.nil_diffₓ'. -/
 @[simp]
 theorem nil_diff (l : List α) : [].diffₓ l = [] := by
   induction l <;> [rfl;simp only [*, diff_cons, erase_of_not_mem (not_mem_nil _)]]
 #align list.nil_diff List.nil_diff
 
-/- warning: list.cons_diff -> List.cons_diff is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} [_inst_1 : DecidableEq.{succ u1} α] (a : α) (l₁ : List.{u1} α) (l₂ : List.{u1} α), Eq.{succ u1} (List.{u1} α) (List.diffₓ.{u1} α (fun (a : α) (b : α) => _inst_1 a b) (List.cons.{u1} α a l₁) l₂) (ite.{succ u1} (List.{u1} α) (Membership.Mem.{u1, u1} α (List.{u1} α) (List.hasMem.{u1} α) a l₂) (List.decidableMem.{u1} α (fun (a : α) (b : α) => _inst_1 a b) a l₂) (List.diffₓ.{u1} α (fun (a : α) (b : α) => _inst_1 a b) l₁ (List.eraseₓ.{u1} α (fun (a : α) (b : α) => _inst_1 a b) l₂ a)) (List.cons.{u1} α a (List.diffₓ.{u1} α (fun (a : α) (b : α) => _inst_1 a b) l₁ l₂)))
-but is expected to have type
-  forall {α : Type.{u1}} [_inst_1 : DecidableEq.{succ u1} α] (a : α) (l₁ : List.{u1} α) (l₂ : List.{u1} α), Eq.{succ u1} (List.{u1} α) (List.diff.{u1} α (instBEq.{u1} α (fun (a : α) (b : α) => _inst_1 a b)) (List.cons.{u1} α a l₁) l₂) (ite.{succ u1} (List.{u1} α) (Membership.mem.{u1, u1} α (List.{u1} α) (List.instMembershipList.{u1} α) a l₂) (List.instDecidableMemListInstMembershipList.{u1} α (fun (a : α) (b : α) => _inst_1 a b) a l₂) (List.diff.{u1} α (instBEq.{u1} α (fun (a : α) (b : α) => _inst_1 a b)) l₁ (List.erase.{u1} α (instBEq.{u1} α (fun (a : α) (b : α) => _inst_1 a b)) l₂ a)) (List.cons.{u1} α a (List.diff.{u1} α (instBEq.{u1} α (fun (a : α) (b : α) => _inst_1 a b)) l₁ l₂)))
-Case conversion may be inaccurate. Consider using '#align list.cons_diff List.cons_diffₓ'. -/
 theorem cons_diff (a : α) (l₁ l₂ : List α) :
     (a :: l₁).diffₓ l₂ = if a ∈ l₂ then l₁.diffₓ (l₂.eraseₓ a) else a :: l₁.diffₓ l₂ :=
   by
@@ -6021,66 +5319,30 @@ theorem cons_diff (a : α) (l₁ l₂ : List α) :
     split_ifs with h₂ <;> simp [diff_erase, List.erase, hne, hne.symm]
 #align list.cons_diff List.cons_diff
 
-/- warning: list.cons_diff_of_mem -> List.cons_diff_of_mem is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} [_inst_1 : DecidableEq.{succ u1} α] {a : α} {l₂ : List.{u1} α}, (Membership.Mem.{u1, u1} α (List.{u1} α) (List.hasMem.{u1} α) a l₂) -> (forall (l₁ : List.{u1} α), Eq.{succ u1} (List.{u1} α) (List.diffₓ.{u1} α (fun (a : α) (b : α) => _inst_1 a b) (List.cons.{u1} α a l₁) l₂) (List.diffₓ.{u1} α (fun (a : α) (b : α) => _inst_1 a b) l₁ (List.eraseₓ.{u1} α (fun (a : α) (b : α) => _inst_1 a b) l₂ a)))
-but is expected to have type
-  forall {α : Type.{u1}} [_inst_1 : DecidableEq.{succ u1} α] {a : α} {l₂ : List.{u1} α}, (Membership.mem.{u1, u1} α (List.{u1} α) (List.instMembershipList.{u1} α) a l₂) -> (forall (l₁ : List.{u1} α), Eq.{succ u1} (List.{u1} α) (List.diff.{u1} α (instBEq.{u1} α (fun (a : α) (b : α) => _inst_1 a b)) (List.cons.{u1} α a l₁) l₂) (List.diff.{u1} α (instBEq.{u1} α (fun (a : α) (b : α) => _inst_1 a b)) l₁ (List.erase.{u1} α (instBEq.{u1} α (fun (a : α) (b : α) => _inst_1 a b)) l₂ a)))
-Case conversion may be inaccurate. Consider using '#align list.cons_diff_of_mem List.cons_diff_of_memₓ'. -/
 theorem cons_diff_of_mem {a : α} {l₂ : List α} (h : a ∈ l₂) (l₁ : List α) :
     (a :: l₁).diffₓ l₂ = l₁.diffₓ (l₂.eraseₓ a) := by rw [cons_diff, if_pos h]
 #align list.cons_diff_of_mem List.cons_diff_of_mem
 
-/- warning: list.cons_diff_of_not_mem -> List.cons_diff_of_not_mem is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} [_inst_1 : DecidableEq.{succ u1} α] {a : α} {l₂ : List.{u1} α}, (Not (Membership.Mem.{u1, u1} α (List.{u1} α) (List.hasMem.{u1} α) a l₂)) -> (forall (l₁ : List.{u1} α), Eq.{succ u1} (List.{u1} α) (List.diffₓ.{u1} α (fun (a : α) (b : α) => _inst_1 a b) (List.cons.{u1} α a l₁) l₂) (List.cons.{u1} α a (List.diffₓ.{u1} α (fun (a : α) (b : α) => _inst_1 a b) l₁ l₂)))
-but is expected to have type
-  forall {α : Type.{u1}} [_inst_1 : DecidableEq.{succ u1} α] {a : α} {l₂ : List.{u1} α}, (Not (Membership.mem.{u1, u1} α (List.{u1} α) (List.instMembershipList.{u1} α) a l₂)) -> (forall (l₁ : List.{u1} α), Eq.{succ u1} (List.{u1} α) (List.diff.{u1} α (instBEq.{u1} α (fun (a : α) (b : α) => _inst_1 a b)) (List.cons.{u1} α a l₁) l₂) (List.cons.{u1} α a (List.diff.{u1} α (instBEq.{u1} α (fun (a : α) (b : α) => _inst_1 a b)) l₁ l₂)))
-Case conversion may be inaccurate. Consider using '#align list.cons_diff_of_not_mem List.cons_diff_of_not_memₓ'. -/
 theorem cons_diff_of_not_mem {a : α} {l₂ : List α} (h : a ∉ l₂) (l₁ : List α) :
     (a :: l₁).diffₓ l₂ = a :: l₁.diffₓ l₂ := by rw [cons_diff, if_neg h]
 #align list.cons_diff_of_not_mem List.cons_diff_of_not_mem
 
-/- warning: list.diff_eq_foldl -> List.diff_eq_foldl is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} [_inst_1 : DecidableEq.{succ u1} α] (l₁ : List.{u1} α) (l₂ : List.{u1} α), Eq.{succ u1} (List.{u1} α) (List.diffₓ.{u1} α (fun (a : α) (b : α) => _inst_1 a b) l₁ l₂) (List.foldl.{u1, u1} (List.{u1} α) α (List.eraseₓ.{u1} α (fun (a : α) (b : α) => _inst_1 a b)) l₁ l₂)
-but is expected to have type
-  forall {α : Type.{u1}} [_inst_1 : DecidableEq.{succ u1} α] (l₁ : List.{u1} α) (l₂ : List.{u1} α), Eq.{succ u1} (List.{u1} α) (List.diff.{u1} α (instBEq.{u1} α (fun (a : α) (b : α) => _inst_1 a b)) l₁ l₂) (List.foldl.{u1, u1} (List.{u1} α) α (List.erase.{u1} α (instBEq.{u1} α (fun (a : α) (b : α) => _inst_1 a b))) l₁ l₂)
-Case conversion may be inaccurate. Consider using '#align list.diff_eq_foldl List.diff_eq_foldlₓ'. -/
 theorem diff_eq_foldl : ∀ l₁ l₂ : List α, l₁.diffₓ l₂ = foldl List.erase l₁ l₂
   | l₁, [] => rfl
   | l₁, a :: l₂ => (diff_cons l₁ l₂ a).trans (diff_eq_foldl _ _)
 #align list.diff_eq_foldl List.diff_eq_foldl
 
-/- warning: list.diff_append -> List.diff_append is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} [_inst_1 : DecidableEq.{succ u1} α] (l₁ : List.{u1} α) (l₂ : List.{u1} α) (l₃ : List.{u1} α), Eq.{succ u1} (List.{u1} α) (List.diffₓ.{u1} α (fun (a : α) (b : α) => _inst_1 a b) l₁ (Append.append.{u1} (List.{u1} α) (List.hasAppend.{u1} α) l₂ l₃)) (List.diffₓ.{u1} α (fun (a : α) (b : α) => _inst_1 a b) (List.diffₓ.{u1} α (fun (a : α) (b : α) => _inst_1 a b) l₁ l₂) l₃)
-but is expected to have type
-  forall {α : Type.{u1}} [_inst_1 : DecidableEq.{succ u1} α] (l₁ : List.{u1} α) (l₂ : List.{u1} α) (l₃ : List.{u1} α), Eq.{succ u1} (List.{u1} α) (List.diff.{u1} α (instBEq.{u1} α (fun (a : α) (b : α) => _inst_1 a b)) l₁ (HAppend.hAppend.{u1, u1, u1} (List.{u1} α) (List.{u1} α) (List.{u1} α) (instHAppend.{u1} (List.{u1} α) (List.instAppendList.{u1} α)) l₂ l₃)) (List.diff.{u1} α (instBEq.{u1} α (fun (a : α) (b : α) => _inst_1 a b)) (List.diff.{u1} α (instBEq.{u1} α (fun (a : α) (b : α) => _inst_1 a b)) l₁ l₂) l₃)
-Case conversion may be inaccurate. Consider using '#align list.diff_append List.diff_appendₓ'. -/
 @[simp]
 theorem diff_append (l₁ l₂ l₃ : List α) : l₁.diffₓ (l₂ ++ l₃) = (l₁.diffₓ l₂).diffₓ l₃ := by
   simp only [diff_eq_foldl, foldl_append]
 #align list.diff_append List.diff_append
 
-/- warning: list.map_diff -> List.map_diff is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u2}} [_inst_1 : DecidableEq.{succ u1} α] [_inst_2 : DecidableEq.{succ u2} β] {f : α -> β}, (Function.Injective.{succ u1, succ u2} α β f) -> (forall {l₁ : List.{u1} α} {l₂ : List.{u1} α}, Eq.{succ u2} (List.{u2} β) (List.map.{u1, u2} α β f (List.diffₓ.{u1} α (fun (a : α) (b : α) => _inst_1 a b) l₁ l₂)) (List.diffₓ.{u2} β (fun (a : β) (b : β) => _inst_2 a b) (List.map.{u1, u2} α β f l₁) (List.map.{u1, u2} α β f l₂)))
-but is expected to have type
-  forall {α : Type.{u1}} {β : Type.{u2}} [_inst_1 : DecidableEq.{succ u1} α] [_inst_2 : DecidableEq.{succ u2} β] {f : α -> β}, (Function.Injective.{succ u1, succ u2} α β f) -> (forall {l₁ : List.{u1} α} {l₂ : List.{u1} α}, Eq.{succ u2} (List.{u2} β) (List.map.{u1, u2} α β f (List.diff.{u1} α (instBEq.{u1} α (fun (a : α) (b : α) => _inst_1 a b)) l₁ l₂)) (List.diff.{u2} β (instBEq.{u2} β (fun (a : β) (b : β) => _inst_2 a b)) (List.map.{u1, u2} α β f l₁) (List.map.{u1, u2} α β f l₂)))
-Case conversion may be inaccurate. Consider using '#align list.map_diff List.map_diffₓ'. -/
 @[simp]
 theorem map_diff [DecidableEq β] {f : α → β} (finj : Injective f) {l₁ l₂ : List α} :
     map f (l₁.diffₓ l₂) = (map f l₁).diffₓ (map f l₂) := by
   simp only [diff_eq_foldl, foldl_map, map_foldl_erase finj]
 #align list.map_diff List.map_diff
 
-/- warning: list.diff_sublist -> List.diff_sublist is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} [_inst_1 : DecidableEq.{succ u1} α] (l₁ : List.{u1} α) (l₂ : List.{u1} α), List.Sublist.{u1} α (List.diffₓ.{u1} α (fun (a : α) (b : α) => _inst_1 a b) l₁ l₂) l₁
-but is expected to have type
-  forall {α : Type.{u1}} [_inst_1 : DecidableEq.{succ u1} α] (l₁ : List.{u1} α) (l₂ : List.{u1} α), List.Sublist.{u1} α (List.diff.{u1} α (instBEq.{u1} α (fun (a : α) (b : α) => _inst_1 a b)) l₁ l₂) l₁
-Case conversion may be inaccurate. Consider using '#align list.diff_sublist List.diff_sublistₓ'. -/
 theorem diff_sublist : ∀ l₁ l₂ : List α, l₁.diffₓ l₂ <+ l₁
   | l₁, [] => Sublist.refl _
   | l₁, a :: l₂ =>
@@ -6091,22 +5353,10 @@ theorem diff_sublist : ∀ l₁ l₂ : List α, l₁.diffₓ l₂ <+ l₁
       
 #align list.diff_sublist List.diff_sublist
 
-/- warning: list.diff_subset -> List.diff_subset is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} [_inst_1 : DecidableEq.{succ u1} α] (l₁ : List.{u1} α) (l₂ : List.{u1} α), HasSubset.Subset.{u1} (List.{u1} α) (List.hasSubset.{u1} α) (List.diffₓ.{u1} α (fun (a : α) (b : α) => _inst_1 a b) l₁ l₂) l₁
-but is expected to have type
-  forall {α : Type.{u1}} [_inst_1 : DecidableEq.{succ u1} α] (l₁ : List.{u1} α) (l₂ : List.{u1} α), HasSubset.Subset.{u1} (List.{u1} α) (List.instHasSubsetList.{u1} α) (List.diff.{u1} α (instBEq.{u1} α (fun (a : α) (b : α) => _inst_1 a b)) l₁ l₂) l₁
-Case conversion may be inaccurate. Consider using '#align list.diff_subset List.diff_subsetₓ'. -/
 theorem diff_subset (l₁ l₂ : List α) : l₁.diffₓ l₂ ⊆ l₁ :=
   (diff_sublist _ _).Subset
 #align list.diff_subset List.diff_subset
 
-/- warning: list.mem_diff_of_mem -> List.mem_diff_of_mem is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} [_inst_1 : DecidableEq.{succ u1} α] {a : α} {l₁ : List.{u1} α} {l₂ : List.{u1} α}, (Membership.Mem.{u1, u1} α (List.{u1} α) (List.hasMem.{u1} α) a l₁) -> (Not (Membership.Mem.{u1, u1} α (List.{u1} α) (List.hasMem.{u1} α) a l₂)) -> (Membership.Mem.{u1, u1} α (List.{u1} α) (List.hasMem.{u1} α) a (List.diffₓ.{u1} α (fun (a : α) (b : α) => _inst_1 a b) l₁ l₂))
-but is expected to have type
-  forall {α : Type.{u1}} [_inst_1 : DecidableEq.{succ u1} α] {a : α} {l₁ : List.{u1} α} {l₂ : List.{u1} α}, (Membership.mem.{u1, u1} α (List.{u1} α) (List.instMembershipList.{u1} α) a l₁) -> (Not (Membership.mem.{u1, u1} α (List.{u1} α) (List.instMembershipList.{u1} α) a l₂)) -> (Membership.mem.{u1, u1} α (List.{u1} α) (List.instMembershipList.{u1} α) a (List.diff.{u1} α (instBEq.{u1} α (fun (a : α) (b : α) => _inst_1 a b)) l₁ l₂))
-Case conversion may be inaccurate. Consider using '#align list.mem_diff_of_mem List.mem_diff_of_memₓ'. -/
 theorem mem_diff_of_mem {a : α} : ∀ {l₁ l₂ : List α}, a ∈ l₁ → a ∉ l₂ → a ∈ l₁.diffₓ l₂
   | l₁, [], h₁, h₂ => h₁
   | l₁, b :: l₂, h₁, h₂ => by
@@ -6116,23 +5366,11 @@ theorem mem_diff_of_mem {a : α} : ∀ {l₁ l₂ : List α}, a ∈ l₁ → a 
           (not_mem_of_not_mem_cons h₂)
 #align list.mem_diff_of_mem List.mem_diff_of_mem
 
-/- warning: list.sublist.diff_right -> List.Sublist.diff_right is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} [_inst_1 : DecidableEq.{succ u1} α] {l₁ : List.{u1} α} {l₂ : List.{u1} α} {l₃ : List.{u1} α}, (List.Sublist.{u1} α l₁ l₂) -> (List.Sublist.{u1} α (List.diffₓ.{u1} α (fun (a : α) (b : α) => _inst_1 a b) l₁ l₃) (List.diffₓ.{u1} α (fun (a : α) (b : α) => _inst_1 a b) l₂ l₃))
-but is expected to have type
-  forall {α : Type.{u1}} [_inst_1 : DecidableEq.{succ u1} α] {l₁ : List.{u1} α} {l₂ : List.{u1} α} {l₃ : List.{u1} α}, (List.Sublist.{u1} α l₁ l₂) -> (List.Sublist.{u1} α (List.diff.{u1} α (instBEq.{u1} α (fun (a : α) (b : α) => _inst_1 a b)) l₁ l₃) (List.diff.{u1} α (instBEq.{u1} α (fun (a : α) (b : α) => _inst_1 a b)) l₂ l₃))
-Case conversion may be inaccurate. Consider using '#align list.sublist.diff_right List.Sublist.diff_rightₓ'. -/
 theorem Sublist.diff_right : ∀ {l₁ l₂ l₃ : List α}, l₁ <+ l₂ → l₁.diffₓ l₃ <+ l₂.diffₓ l₃
   | l₁, l₂, [], h => h
   | l₁, l₂, a :: l₃, h => by simp only [diff_cons, (h.erase _).diff_right]
 #align list.sublist.diff_right List.Sublist.diff_right
 
-/- warning: list.erase_diff_erase_sublist_of_sublist -> List.erase_diff_erase_sublist_of_sublist is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} [_inst_1 : DecidableEq.{succ u1} α] {a : α} {l₁ : List.{u1} α} {l₂ : List.{u1} α}, (List.Sublist.{u1} α l₁ l₂) -> (List.Sublist.{u1} α (List.diffₓ.{u1} α (fun (a : α) (b : α) => _inst_1 a b) (List.eraseₓ.{u1} α (fun (a : α) (b : α) => _inst_1 a b) l₂ a) (List.eraseₓ.{u1} α (fun (a : α) (b : α) => _inst_1 a b) l₁ a)) (List.diffₓ.{u1} α (fun (a : α) (b : α) => _inst_1 a b) l₂ l₁))
-but is expected to have type
-  forall {α : Type.{u1}} [_inst_1 : DecidableEq.{succ u1} α] {a : α} {l₁ : List.{u1} α} {l₂ : List.{u1} α}, (List.Sublist.{u1} α l₁ l₂) -> (List.Sublist.{u1} α (List.diff.{u1} α (instBEq.{u1} α (fun (a : α) (b : α) => _inst_1 a b)) (List.erase.{u1} α (instBEq.{u1} α (fun (a : α) (b : α) => _inst_1 a b)) l₂ a) (List.erase.{u1} α (instBEq.{u1} α (fun (a : α) (b : α) => _inst_1 a b)) l₁ a)) (List.diff.{u1} α (instBEq.{u1} α (fun (a : α) (b : α) => _inst_1 a b)) l₂ l₁))
-Case conversion may be inaccurate. Consider using '#align list.erase_diff_erase_sublist_of_sublist List.erase_diff_erase_sublist_of_sublistₓ'. -/
 theorem erase_diff_erase_sublist_of_sublist {a : α} :
     ∀ {l₁ l₂ : List α}, l₁ <+ l₂ → (l₂.eraseₓ a).diffₓ (l₁.eraseₓ a) <+ l₂.diffₓ l₁
   | [], l₂, h => erase_sublist _ _
@@ -6161,12 +5399,6 @@ theorem length_enum : ∀ l : List α, length (enum l) = length l :=
 #align list.length_enum List.length_enum
 -/
 
-/- warning: list.enum_from_nth -> List.enumFrom_get? is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} (n : Nat) (l : List.{u1} α) (m : Nat), Eq.{succ u1} (Option.{u1} (Prod.{0, u1} Nat α)) (List.get?.{u1} (Prod.{0, u1} Nat α) (List.enumFrom.{u1} α n l) m) (Functor.map.{u1, u1} Option.{u1} (Traversable.toFunctor.{u1} Option.{u1} Option.traversable.{u1}) α (Prod.{0, u1} Nat α) (fun (a : α) => Prod.mk.{0, u1} Nat α (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat Nat.hasAdd) n m) a) (List.get?.{u1} α l m))
-but is expected to have type
-  forall {α : Type.{u1}} (n : Nat) (l : List.{u1} α) (m : Nat), Eq.{succ u1} (Option.{u1} (Prod.{0, u1} Nat α)) (List.get?.{u1} (Prod.{0, u1} Nat α) (List.enumFrom.{u1} α n l) m) (Functor.map.{u1, u1} Option.{u1} instFunctorOption.{u1} α (Prod.{0, u1} Nat α) (fun (a : α) => Prod.mk.{0, u1} Nat α (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat instAddNat) n m) a) (List.get?.{u1} α l m))
-Case conversion may be inaccurate. Consider using '#align list.enum_from_nth List.enumFrom_get?ₓ'. -/
 @[simp]
 theorem enumFrom_get? :
     ∀ (n) (l : List α) (m), get? (enumFrom n l) m = (fun a => (n + m, a)) <$> get? l m
@@ -6175,12 +5407,6 @@ theorem enumFrom_get? :
   | n, a :: l, m + 1 => (enum_from_nth (n + 1) l m).trans <| by rw [add_right_comm] <;> rfl
 #align list.enum_from_nth List.enumFrom_get?
 
-/- warning: list.enum_nth -> List.enum_get? is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} (l : List.{u1} α) (n : Nat), Eq.{succ u1} (Option.{u1} (Prod.{0, u1} Nat α)) (List.get?.{u1} (Prod.{0, u1} Nat α) (List.enum.{u1} α l) n) (Functor.map.{u1, u1} Option.{u1} (Traversable.toFunctor.{u1} Option.{u1} Option.traversable.{u1}) α (Prod.{0, u1} Nat α) (fun (a : α) => Prod.mk.{0, u1} Nat α n a) (List.get?.{u1} α l n))
-but is expected to have type
-  forall {α : Type.{u1}} (l : List.{u1} α) (n : Nat), Eq.{succ u1} (Option.{u1} (Prod.{0, u1} Nat α)) (List.get?.{u1} (Prod.{0, u1} Nat α) (List.enum.{u1} α l) n) (Functor.map.{u1, u1} Option.{u1} instFunctorOption.{u1} α (Prod.{0, u1} Nat α) (fun (a : α) => Prod.mk.{0, u1} Nat α n a) (List.get?.{u1} α l n))
-Case conversion may be inaccurate. Consider using '#align list.enum_nth List.enum_get?ₓ'. -/
 @[simp]
 theorem enum_get? : ∀ (l : List α) (n), get? (enum l) n = (fun a => (n, a)) <$> get? l n := by
   simp only [enum, enum_from_nth, zero_add] <;> intros <;> rfl
@@ -6691,22 +5917,12 @@ end ZipRight
 section ToChunks
 
 /- warning: list.to_chunks_nil clashes with [anonymous] -> [anonymous]
-warning: list.to_chunks_nil -> [anonymous] is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u}} (n : Nat), Eq.{succ u} (List.{u} (List.{u} α)) (List.toChunks.{u} α n (List.nil.{u} α)) (List.nil.{u} (List.{u} α))
-but is expected to have type
-  forall {α : Type.{u}} {n : Type.{v}}, (Nat -> α -> n) -> Nat -> (List.{u} α) -> (List.{v} n)
 Case conversion may be inaccurate. Consider using '#align list.to_chunks_nil [anonymous]ₓ'. -/
 @[simp]
 theorem [anonymous] (n) : @toChunks α n [] = [] := by cases n <;> rfl
 #align list.to_chunks_nil [anonymous]
 
 /- warning: list.to_chunks_aux_eq clashes with [anonymous] -> [anonymous]
-warning: list.to_chunks_aux_eq -> [anonymous] is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u}} (n : Nat) (xs : List.{u} α) (i : Nat), Eq.{succ u} (Prod.{u, u} (List.{u} α) (List.{u} (List.{u} α))) (List.toChunksAux.{u} α n xs i) (Prod.mk.{u, u} (List.{u} α) (List.{u} (List.{u} α)) (List.take.{u} α i xs) (List.toChunks.{u} α (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat Nat.hasAdd) n (OfNat.ofNat.{0} Nat 1 (OfNat.mk.{0} Nat 1 (One.one.{0} Nat Nat.hasOne)))) (List.drop.{u} α i xs)))
-but is expected to have type
-  forall {α : Type.{u}} {n : Type.{v}}, (Nat -> α -> n) -> Nat -> (List.{u} α) -> (List.{v} n)
 Case conversion may be inaccurate. Consider using '#align list.to_chunks_aux_eq [anonymous]ₓ'. -/
 theorem [anonymous] (n) : ∀ xs i, @toChunksAux α n xs i = (xs.take i, (xs.drop i).toChunks (n + 1))
   | [], i => by cases i <;> rfl
@@ -6715,11 +5931,6 @@ theorem [anonymous] (n) : ∀ xs i, @toChunksAux α n xs i = (xs.take i, (xs.dro
 #align list.to_chunks_aux_eq [anonymous]
 
 /- warning: list.to_chunks_eq_cons' clashes with [anonymous] -> [anonymous]
-warning: list.to_chunks_eq_cons' -> [anonymous] is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u}} (n : Nat) {xs : List.{u} α}, (Ne.{succ u} (List.{u} α) xs (List.nil.{u} α)) -> (Eq.{succ u} (List.{u} (List.{u} α)) (List.toChunks.{u} α (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat Nat.hasAdd) n (OfNat.ofNat.{0} Nat 1 (OfNat.mk.{0} Nat 1 (One.one.{0} Nat Nat.hasOne)))) xs) (List.cons.{u} (List.{u} α) (List.take.{u} α (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat Nat.hasAdd) n (OfNat.ofNat.{0} Nat 1 (OfNat.mk.{0} Nat 1 (One.one.{0} Nat Nat.hasOne)))) xs) (List.toChunks.{u} α (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat Nat.hasAdd) n (OfNat.ofNat.{0} Nat 1 (OfNat.mk.{0} Nat 1 (One.one.{0} Nat Nat.hasOne)))) (List.drop.{u} α (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat Nat.hasAdd) n (OfNat.ofNat.{0} Nat 1 (OfNat.mk.{0} Nat 1 (One.one.{0} Nat Nat.hasOne)))) xs))))
-but is expected to have type
-  forall {α : Type.{u}} {n : Type.{v}}, (Nat -> α -> n) -> Nat -> (List.{u} α) -> (List.{v} n)
 Case conversion may be inaccurate. Consider using '#align list.to_chunks_eq_cons' [anonymous]ₓ'. -/
 theorem [anonymous] (n) :
     ∀ {xs : List α} (h : xs ≠ []),
@@ -6729,11 +5940,6 @@ theorem [anonymous] (n) :
 #align list.to_chunks_eq_cons' [anonymous]
 
 /- warning: list.to_chunks_eq_cons clashes with [anonymous] -> [anonymous]
-warning: list.to_chunks_eq_cons -> [anonymous] is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u}} {n : Nat} {xs : List.{u} α}, (Ne.{1} Nat n (OfNat.ofNat.{0} Nat 0 (OfNat.mk.{0} Nat 0 (Zero.zero.{0} Nat Nat.hasZero)))) -> (Ne.{succ u} (List.{u} α) xs (List.nil.{u} α)) -> (Eq.{succ u} (List.{u} (List.{u} α)) (List.toChunks.{u} α n xs) (List.cons.{u} (List.{u} α) (List.take.{u} α n xs) (List.toChunks.{u} α n (List.drop.{u} α n xs))))
-but is expected to have type
-  forall {α : Type.{u}} {n : Type.{v}}, (Nat -> α -> n) -> Nat -> (List.{u} α) -> (List.{v} n)
 Case conversion may be inaccurate. Consider using '#align list.to_chunks_eq_cons [anonymous]ₓ'. -/
 theorem [anonymous] :
     ∀ {n} {xs : List α} (n0 : n ≠ 0) (x0 : xs ≠ []),
@@ -6743,11 +5949,6 @@ theorem [anonymous] :
 #align list.to_chunks_eq_cons [anonymous]
 
 /- warning: list.to_chunks_aux_join clashes with [anonymous] -> [anonymous]
-warning: list.to_chunks_aux_join -> [anonymous] is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u}} {n : Nat} {xs : List.{u} α} {i : Nat} {l : List.{u} α} {L : List.{u} (List.{u} α)}, (Eq.{succ u} (Prod.{u, u} (List.{u} α) (List.{u} (List.{u} α))) (List.toChunksAux.{u} α n xs i) (Prod.mk.{u, u} (List.{u} α) (List.{u} (List.{u} α)) l L)) -> (Eq.{succ u} (List.{u} α) (Append.append.{u} (List.{u} α) (List.hasAppend.{u} α) l (List.join.{u} α L)) xs)
-but is expected to have type
-  forall {α : Type.{u}} {n : Type.{v}}, (Nat -> α -> n) -> Nat -> (List.{u} α) -> (List.{v} n)
 Case conversion may be inaccurate. Consider using '#align list.to_chunks_aux_join [anonymous]ₓ'. -/
 theorem [anonymous] {n} : ∀ {xs i l L}, @toChunksAux α n xs i = (l, L) → l ++ L.join = xs
   | [], _, _, _, rfl => rfl
@@ -6759,11 +5960,6 @@ theorem [anonymous] {n} : ∀ {xs i l L}, @toChunksAux α n xs i = (l, L) → l
 #align list.to_chunks_aux_join [anonymous]
 
 /- warning: list.to_chunks_join clashes with [anonymous] -> [anonymous]
-warning: list.to_chunks_join -> [anonymous] is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u}} (n : Nat) (xs : List.{u} α), Eq.{succ u} (List.{u} α) (List.join.{u} α (List.toChunks.{u} α n xs)) xs
-but is expected to have type
-  forall {α : Type.{u}} {n : Type.{v}}, (Nat -> α -> n) -> Nat -> (List.{u} α) -> (List.{v} n)
 Case conversion may be inaccurate. Consider using '#align list.to_chunks_join [anonymous]ₓ'. -/
 @[simp]
 theorem [anonymous] : ∀ n xs, (@toChunks α n xs).join = xs
@@ -6776,11 +5972,6 @@ theorem [anonymous] : ∀ n xs, (@toChunks α n xs).join = xs
 #align list.to_chunks_join [anonymous]
 
 /- warning: list.to_chunks_length_le clashes with [anonymous] -> [anonymous]
-warning: list.to_chunks_length_le -> [anonymous] is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u}} (n : Nat) (xs : List.{u} α), (Ne.{1} Nat n (OfNat.ofNat.{0} Nat 0 (OfNat.mk.{0} Nat 0 (Zero.zero.{0} Nat Nat.hasZero)))) -> (forall (l : List.{u} α), (Membership.Mem.{u, u} (List.{u} α) (List.{u} (List.{u} α)) (List.hasMem.{u} (List.{u} α)) l (List.toChunks.{u} α n xs)) -> (LE.le.{0} Nat Nat.hasLe (List.length.{u} α l) n))
-but is expected to have type
-  forall {α : Type.{u}} {n : Type.{v}}, (Nat -> α -> n) -> Nat -> (List.{u} α) -> (List.{v} n)
 Case conversion may be inaccurate. Consider using '#align list.to_chunks_length_le [anonymous]ₓ'. -/
 theorem [anonymous] : ∀ n xs, n ≠ 0 → ∀ l : List α, l ∈ @toChunks α n xs → l.length ≤ n
   | 0, _, e, _ => (e rfl).elim
@@ -6904,12 +6095,6 @@ theorem dropSlice_eq (xs : List α) (n m : ℕ) : dropSlice n m xs = xs.take n +
 #align list.slice_eq List.dropSlice_eq
 -/
 
-/- warning: list.sizeof_slice_lt -> List.sizeOf_dropSlice_lt is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} [_inst_1 : SizeOf.{succ u1} α] (i : Nat) (j : Nat), (LT.lt.{0} Nat Nat.hasLt (OfNat.ofNat.{0} Nat 0 (OfNat.mk.{0} Nat 0 (Zero.zero.{0} Nat Nat.hasZero))) j) -> (forall (xs : List.{u1} α), (LT.lt.{0} Nat Nat.hasLt i (List.length.{u1} α xs)) -> (LT.lt.{0} Nat Nat.hasLt (SizeOf.sizeOf.{succ u1} (List.{u1} α) (List.hasSizeof.{u1} α _inst_1) (List.dropSlice.{u1} α i j xs)) (SizeOf.sizeOf.{succ u1} (List.{u1} α) (List.hasSizeof.{u1} α _inst_1) xs)))
-but is expected to have type
-  forall {α : Type.{u1}} [_inst_1 : SizeOf.{succ u1} α] (i : Nat) (j : Nat), (LT.lt.{0} Nat instLTNat (OfNat.ofNat.{0} Nat 0 (instOfNatNat 0)) j) -> (forall (xs : List.{u1} α), (LT.lt.{0} Nat instLTNat i (List.length.{u1} α xs)) -> (LT.lt.{0} Nat instLTNat (SizeOf.sizeOf.{succ u1} (List.{u1} α) (List._sizeOf_inst.{u1} α _inst_1) (List.dropSlice.{u1} α i j xs)) (SizeOf.sizeOf.{succ u1} (List.{u1} α) (List._sizeOf_inst.{u1} α _inst_1) xs)))
-Case conversion may be inaccurate. Consider using '#align list.sizeof_slice_lt List.sizeOf_dropSlice_ltₓ'. -/
 theorem sizeOf_dropSlice_lt [SizeOf α] (i j : ℕ) (hj : 0 < j) (xs : List α) (hi : i < xs.length) :
     SizeOf.sizeOf (List.dropSlice i j xs) < SizeOf.sizeOf xs :=
   by
@@ -7056,12 +6241,6 @@ theorem getD_default_eq_getI : l.getD n default = l.getI n :=
   rfl
 #align list.nthd_default_eq_inth List.getD_default_eq_getIₓ
 
-/- warning: list.inth_append -> List.getI_append is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} [_inst_1 : Inhabited.{succ u1} α] (l : List.{u1} α) (l' : List.{u1} α) (n : Nat) (h : LT.lt.{0} Nat Nat.hasLt n (List.length.{u1} α l)), (optParam.{0} (LT.lt.{0} Nat (Preorder.toHasLt.{0} Nat (PartialOrder.toPreorder.{0} Nat (OrderedCancelAddCommMonoid.toPartialOrder.{0} Nat (StrictOrderedSemiring.toOrderedCancelAddCommMonoid.{0} Nat Nat.strictOrderedSemiring)))) n (List.length.{u1} α (Append.append.{u1} (List.{u1} α) (List.hasAppend.{u1} α) l l'))) (LT.lt.trans_le.{0} Nat (PartialOrder.toPreorder.{0} Nat (OrderedCancelAddCommMonoid.toPartialOrder.{0} Nat (StrictOrderedSemiring.toOrderedCancelAddCommMonoid.{0} Nat Nat.strictOrderedSemiring))) n (List.length.{u1} α l) (List.length.{u1} α (Append.append.{u1} (List.{u1} α) (List.hasAppend.{u1} α) l l')) h (Eq.subst.{1} Nat (fun (_x : Nat) => LE.le.{0} Nat (Preorder.toHasLe.{0} Nat (PartialOrder.toPreorder.{0} Nat (OrderedCancelAddCommMonoid.toPartialOrder.{0} Nat (StrictOrderedSemiring.toOrderedCancelAddCommMonoid.{0} Nat Nat.strictOrderedSemiring)))) (List.length.{u1} α l) _x) (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat Nat.hasAdd) (List.length.{u1} α l) (List.length.{u1} α l')) (List.length.{u1} α (Append.append.{u1} (List.{u1} α) (List.hasAppend.{u1} α) l l')) (Eq.symm.{1} Nat (List.length.{u1} α (Append.append.{u1} (List.{u1} α) (List.hasAppend.{u1} α) l l')) (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat Nat.hasAdd) (List.length.{u1} α l) (List.length.{u1} α l')) (List.length_append.{u1} α l l')) (le_self_add.{0} Nat (CanonicallyOrderedCommSemiring.toCanonicallyOrderedAddMonoid.{0} Nat Nat.canonicallyOrderedCommSemiring) (List.length.{u1} α l) (List.length.{u1} α l'))))) -> (Eq.{succ u1} α (List.getI.{u1} α _inst_1 (Append.append.{u1} (List.{u1} α) (List.hasAppend.{u1} α) l l') n) (List.getI.{u1} α _inst_1 l n))
-but is expected to have type
-  forall {α : Type.{u1}} [_inst_1 : Inhabited.{succ u1} α] (l : List.{u1} α) (l' : List.{u1} α) (n : Nat) (h : LT.lt.{0} Nat instLTNat n (List.length.{u1} α l)), (optParam.{0} (LT.lt.{0} Nat instLTNat n (List.length.{u1} α (HAppend.hAppend.{u1, u1, u1} (List.{u1} α) (List.{u1} α) (List.{u1} α) (instHAppend.{u1} (List.{u1} α) (List.instAppendList.{u1} α)) l l'))) (LT.lt.trans_le.{0} Nat (PartialOrder.toPreorder.{0} Nat (StrictOrderedSemiring.toPartialOrder.{0} Nat Nat.strictOrderedSemiring)) n (List.length.{u1} α l) (List.length.{u1} α (HAppend.hAppend.{u1, u1, u1} (List.{u1} α) (List.{u1} α) (List.{u1} α) (instHAppend.{u1} (List.{u1} α) (List.instAppendList.{u1} α)) l l')) h (Eq.rec.{0, 1} Nat (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat instAddNat) (List.length.{u1} α l) (List.length.{u1} α l')) (fun (x._@.Mathlib.Data.List.Basic._hyg.49479 : Nat) (h._@.Mathlib.Data.List.Basic._hyg.49480 : Eq.{1} Nat (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat instAddNat) (List.length.{u1} α l) (List.length.{u1} α l')) x._@.Mathlib.Data.List.Basic._hyg.49479) => LE.le.{0} Nat (Preorder.toLE.{0} Nat (PartialOrder.toPreorder.{0} Nat (StrictOrderedSemiring.toPartialOrder.{0} Nat Nat.strictOrderedSemiring))) (List.length.{u1} α l) x._@.Mathlib.Data.List.Basic._hyg.49479) (le_self_add.{0} Nat (CanonicallyOrderedCommSemiring.toCanonicallyOrderedAddMonoid.{0} Nat Nat.canonicallyOrderedCommSemiring) (List.length.{u1} α l) (List.length.{u1} α l')) (List.length.{u1} α (HAppend.hAppend.{u1, u1, u1} (List.{u1} α) (List.{u1} α) (List.{u1} α) (instHAppend.{u1} (List.{u1} α) (List.instAppendList.{u1} α)) l l')) (Eq.symm.{1} Nat (List.length.{u1} α (HAppend.hAppend.{u1, u1, u1} (List.{u1} α) (List.{u1} α) (List.{u1} α) (instHAppend.{u1} (List.{u1} α) (List.instAppendList.{u1} α)) l l')) (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat instAddNat) (List.length.{u1} α l) (List.length.{u1} α l')) (List.length_append.{u1} α l l'))))) -> (Eq.{succ u1} α (List.getI.{u1} α _inst_1 (HAppend.hAppend.{u1, u1, u1} (List.{u1} α) (List.{u1} α) (List.{u1} α) (instHAppend.{u1} (List.{u1} α) (List.instAppendList.{u1} α)) l l') n) (List.getI.{u1} α _inst_1 l n))
-Case conversion may be inaccurate. Consider using '#align list.inth_append List.getI_appendₓ'. -/
 theorem getI_append (l l' : List α) (n : ℕ) (h : n < l.length)
     (h' : n < (l ++ l').length := h.trans_le ((length_append l l').symm ▸ le_self_add)) :
     (l ++ l').getI n = l.getI n :=
Diff
@@ -102,11 +102,8 @@ theorem singleton_inj {a b : α} : [a] = [b] ↔ a = b :=
 -/
 
 #print List.exists_cons_of_ne_nil /-
-theorem exists_cons_of_ne_nil {l : List α} (h : l ≠ nil) : ∃ b L, l = b :: L :=
-  by
-  induction' l with c l'
-  contradiction
-  use c, l'
+theorem exists_cons_of_ne_nil {l : List α} (h : l ≠ nil) : ∃ b L, l = b :: L := by
+  induction' l with c l'; contradiction; use c, l'
 #align list.exists_cons_of_ne_nil List.exists_cons_of_ne_nil
 -/
 
@@ -223,9 +220,7 @@ theorem mem_map {f : α → β} {b : β} {l : List α} : b ∈ map f l ↔ ∃ a
   by
   -- This proof uses no axioms, that's why it's longer that `induction`; simp [...]
   induction' l with a l ihl
-  · constructor
-    · rintro ⟨_⟩
-    · rintro ⟨a, ⟨_⟩, _⟩
+  · constructor; · rintro ⟨_⟩; · rintro ⟨a, ⟨_⟩, _⟩
   · refine' (or_congr eq_comm ihl).trans _
     constructor
     · rintro (h | ⟨c, hcl, h⟩)
@@ -261,9 +256,7 @@ theorem mem_map_of_injective {f : α → β} (H : Injective f) {a : α} {l : Lis
 @[simp]
 theorem Function.Involutive.exists_mem_and_apply_eq_iff {f : α → α} (hf : Function.Involutive f)
     (x : α) (l : List α) : (∃ y : α, y ∈ l ∧ f y = x) ↔ f x ∈ l :=
-  ⟨by
-    rintro ⟨y, h, rfl⟩
-    rwa [hf y], fun h => ⟨f x, h, hf _⟩⟩
+  ⟨by rintro ⟨y, h, rfl⟩; rwa [hf y], fun h => ⟨f x, h, hf _⟩⟩
 #align function.involutive.exists_mem_and_apply_eq_iff Function.Involutive.exists_mem_and_apply_eq_iff
 -/
 
@@ -421,20 +414,10 @@ theorem exists_of_length_succ {n} : ∀ l : List α, l.length = n + 1 → ∃ h
 theorem length_injective_iff : Injective (List.length : List α → ℕ) ↔ Subsingleton α :=
   by
   constructor
-  · intro h
-    refine' ⟨fun x y => _⟩
-    suffices [x] = [y] by simpa using this
-    apply h
-    rfl
-  · intro hα l1 l2 hl
-    induction l1 generalizing l2 <;> cases l2
-    · rfl
-    · cases hl
-    · cases hl
-    congr
-    exact Subsingleton.elim _ _
-    apply l1_ih
-    simpa using hl
+  · intro h; refine' ⟨fun x y => _⟩; suffices [x] = [y] by simpa using this; apply h; rfl
+  · intro hα l1 l2 hl; induction l1 generalizing l2 <;> cases l2
+    · rfl; · cases hl; · cases hl
+    congr ; exact Subsingleton.elim _ _; apply l1_ih; simpa using hl
 #align list.length_injective_iff List.length_injective_iff
 -/
 
@@ -491,10 +474,8 @@ theorem insert_pos [DecidableEq α] {x : α} {l : List α} (h : x ∈ l) : Inser
 -/
 
 #print List.doubleton_eq /-
-theorem doubleton_eq [DecidableEq α] {x y : α} (h : x ≠ y) : ({x, y} : List α) = [x, y] :=
-  by
-  rw [insert_neg, singleton_eq]
-  rwa [singleton_eq, mem_singleton]
+theorem doubleton_eq [DecidableEq α] {x y : α} (h : x ≠ y) : ({x, y} : List α) = [x, y] := by
+  rw [insert_neg, singleton_eq]; rwa [singleton_eq, mem_singleton]
 #align list.doubleton_eq List.doubleton_eq
 -/
 
@@ -615,11 +596,8 @@ theorem append_subset_of_subset_of_subset {l₁ l₂ l : List α} (l₁subl : l
 theorem append_subset {l₁ l₂ l : List α} : l₁ ++ l₂ ⊆ l ↔ l₁ ⊆ l ∧ l₂ ⊆ l :=
   by
   constructor
-  · intro h
-    simp only [subset_def] at *
-    constructor <;> intros <;> simp [*]
-  · rintro ⟨h1, h2⟩
-    apply append_subset_of_subset_of_subset h1 h2
+  · intro h; simp only [subset_def] at *; constructor <;> intros <;> simp [*]
+  · rintro ⟨h1, h2⟩; apply append_subset_of_subset_of_subset h1 h2
 #align list.append_subset_iff List.append_subset
 -/
 
@@ -721,13 +699,8 @@ theorem append_eq_append_iff {a b c d : List α} :
   induction a generalizing c
   case nil =>
     rw [nil_append]; constructor
-    · rintro rfl
-      left
-      exact ⟨_, rfl, rfl⟩
-    · rintro (⟨a', rfl, rfl⟩ | ⟨a', H, rfl⟩)
-      · rfl
-      · rw [← append_assoc, ← H]
-        rfl
+    · rintro rfl; left; exact ⟨_, rfl, rfl⟩
+    · rintro (⟨a', rfl, rfl⟩ | ⟨a', H, rfl⟩); · rfl; · rw [← append_assoc, ← H]; rfl
   case cons a as ih =>
     cases c
     · simp only [cons_append, nil_append, false_and_iff, exists_false, false_or_iff,
@@ -1043,11 +1016,8 @@ lean 3 declaration is
 but is expected to have type
   forall {α : Type.{u2}} {β : Type.{u1}} (f : α -> β) (l : List.{u2} α), Eq.{succ u1} (List.{u1} β) (List.map.{u2, u1} α β f l) (List.bind.{u2, u1} α β l (fun (x : α) => List.cons.{u1} β (f x) (List.nil.{u1} β)))
 Case conversion may be inaccurate. Consider using '#align list.map_eq_bind List.map_eq_bindₓ'. -/
-theorem map_eq_bind {α β} (f : α → β) (l : List α) : map f l = l.bind fun x => [f x] :=
-  by
-  trans
-  rw [← bind_singleton' l, bind_map]
-  rfl
+theorem map_eq_bind {α β} (f : α → β) (l : List α) : map f l = l.bind fun x => [f x] := by trans;
+  rw [← bind_singleton' l, bind_map]; rfl
 #align list.map_eq_bind List.map_eq_bind
 
 /- warning: list.bind_assoc -> List.bind_assoc is a dubious translation:
@@ -1306,11 +1276,8 @@ theorem length_dropLast : ∀ l : List α, length (dropLast l) = length l - 1
 #print List.getLast_cons /-
 @[simp]
 theorem getLast_cons {a : α} {l : List α} :
-    ∀ h : l ≠ nil, getLast (a :: l) (cons_ne_nil a l) = getLast l h :=
-  by
-  induction l <;> intros
-  contradiction
-  rfl
+    ∀ h : l ≠ nil, getLast (a :: l) (cons_ne_nil a l) = getLast l h := by induction l <;> intros ;
+  contradiction; rfl
 #align list.last_cons List.getLast_cons
 -/
 
@@ -1329,9 +1296,7 @@ theorem getLast_append' (l₁ l₂ : List α) (h : l₂ ≠ []) :
   by
   induction' l₁ with _ _ ih
   · simp
-  · simp only [cons_append]
-    rw [List.getLast_cons]
-    exact ih
+  · simp only [cons_append]; rw [List.getLast_cons]; exact ih
 #align list.last_append List.getLast_append'
 -/
 
@@ -1377,10 +1342,7 @@ theorem getLast_congr {l₁ l₂ : List α} (h₁ : l₁ ≠ []) (h₂ : l₂ 
 theorem getLast_mem : ∀ {l : List α} (h : l ≠ []), getLast l h ∈ l
   | [], h => absurd rfl h
   | [a], h => Or.inl rfl
-  | a :: b :: l, h =>
-    Or.inr <| by
-      rw [last_cons_cons]
-      exact last_mem (cons_ne_nil b l)
+  | a :: b :: l, h => Or.inr <| by rw [last_cons_cons]; exact last_mem (cons_ne_nil b l)
 #align list.last_mem List.getLast_mem
 -/
 
@@ -1431,9 +1393,7 @@ theorem mem_getLast?_eq_getLast : ∀ {l : List α} {x : α}, x ∈ l.getLast? 
 #print List.getLast?_eq_getLast_of_ne_nil /-
 theorem getLast?_eq_getLast_of_ne_nil : ∀ {l : List α} (h : l ≠ []), l.getLast? = some (l.getLast h)
   | [], h => (h rfl).elim
-  | [a], _ => by
-    unfold last
-    unfold last'
+  | [a], _ => by unfold last; unfold last'
   | a :: b :: l, _ => @last'_eq_last_of_ne_nil (b :: l) (cons_ne_nil _ _)
 #align list.last'_eq_last_of_ne_nil List.getLast?_eq_getLast_of_ne_nil
 -/
@@ -1456,9 +1416,7 @@ theorem mem_of_mem_getLast? {l : List α} {a : α} (ha : a ∈ l.getLast?) : a 
 theorem dropLast_append_getLast? : ∀ {l : List α}, ∀ a ∈ l.getLast?, dropLast l ++ [a] = l
   | [], a, ha => (Option.not_mem_none a ha).elim
   | [a], _, rfl => rfl
-  | a :: b :: l, c, hc => by
-    rw [last'] at hc
-    rw [init, cons_append, init_append_last' _ hc]
+  | a :: b :: l, c, hc => by rw [last'] at hc; rw [init, cons_append, init_append_last' _ hc]
 #align list.init_append_last' List.dropLast_append_getLast?
 -/
 
@@ -1499,11 +1457,7 @@ theorem getLast?_append_of_ne_nil (l₁ : List α) :
 
 #print List.getLast?_append /-
 theorem getLast?_append {l₁ l₂ : List α} {x : α} (h : x ∈ l₂.getLast?) : x ∈ (l₁ ++ l₂).getLast? :=
-  by
-  cases l₂
-  · contradiction
-  · rw [List.getLast?_append_cons]
-    exact h
+  by cases l₂; · contradiction; · rw [List.getLast?_append_cons]; exact h
 #align list.last'_append List.getLast?_append
 -/
 
@@ -1536,9 +1490,7 @@ theorem surjective_tail : Surjective (@tail α)
 #print List.eq_cons_of_mem_head? /-
 theorem eq_cons_of_mem_head? {x : α} : ∀ {l : List α}, x ∈ l.head? → l = x :: tail l
   | [], h => (Option.not_mem_none _ h).elim
-  | a :: l, h => by
-    simp only [head', Option.mem_def] at h
-    exact h ▸ rfl
+  | a :: l, h => by simp only [head', Option.mem_def] at h; exact h ▸ rfl
 #align list.eq_cons_of_mem_head' List.eq_cons_of_mem_head?
 -/
 
@@ -1572,19 +1524,13 @@ theorem tail_cons (a : α) (l : List α) : tail (a :: l) = l :=
 #print List.head!_append /-
 @[simp]
 theorem head!_append [Inhabited α] (t : List α) {s : List α} (h : s ≠ []) :
-    headI (s ++ t) = headI s := by
-  induction s
-  contradiction
-  rfl
+    headI (s ++ t) = headI s := by induction s; contradiction; rfl
 #align list.head_append List.head!_append
 -/
 
 #print List.head?_append /-
-theorem head?_append {s t : List α} {x : α} (h : x ∈ s.head?) : x ∈ (s ++ t).head? :=
-  by
-  cases s
-  contradiction
-  exact h
+theorem head?_append {s t : List α} {x : α} (h : x ∈ s.head?) : x ∈ (s ++ t).head? := by cases s;
+  contradiction; exact h
 #align list.head'_append List.head?_append
 -/
 
@@ -1598,19 +1544,14 @@ theorem head?_append_of_ne_nil :
 
 #print List.tail_append_singleton_of_ne_nil /-
 theorem tail_append_singleton_of_ne_nil {a : α} {l : List α} (h : l ≠ nil) :
-    tail (l ++ [a]) = tail l ++ [a] := by
-  induction l
-  contradiction
-  rw [tail, cons_append, tail]
+    tail (l ++ [a]) = tail l ++ [a] := by induction l; contradiction; rw [tail, cons_append, tail]
 #align list.tail_append_singleton_of_ne_nil List.tail_append_singleton_of_ne_nil
 -/
 
 #print List.cons_head?_tail /-
 theorem cons_head?_tail : ∀ {l : List α} {a : α} (h : a ∈ head? l), a :: tail l = l
   | [], a, h => by contradiction
-  | b :: l, a, h => by
-    simp at h
-    simp [h]
+  | b :: l, a, h => by simp at h; simp [h]
 #align list.cons_head'_tail List.cons_head?_tail
 -/
 
@@ -1683,8 +1624,7 @@ theorem nthLe_cons {l : List α} {a : α} {n} (hl) :
   split_ifs
   · simp [nth_le, h]
   cases l
-  · rw [length_singleton, lt_succ_iff, nonpos_iff_eq_zero] at hl
-    contradiction
+  · rw [length_singleton, lt_succ_iff, nonpos_iff_eq_zero] at hl; contradiction
   cases n
   · contradiction
   rfl
@@ -1711,8 +1651,7 @@ def reverseRecOn {C : List α → Sort _} (l : List α) (H0 : C [])
   rw [← reverse_reverse l]
   induction reverse l
   · exact H0
-  · rw [reverse_cons]
-    exact H1 _ _ ih
+  · rw [reverse_cons]; exact H1 _ _ ih
 #align list.reverse_rec_on List.reverseRecOn
 -/
 
@@ -1733,10 +1672,7 @@ def bidirectionalRec {C : List α → Sort _} (H0 : C []) (H1 : ∀ a : α, C [a
   | a :: b :: l => by
     let l' := dropLast (b :: l)
     let b' := getLast (b :: l) (cons_ne_nil _ _)
-    have : length l' < length (a :: b :: l) :=
-      by
-      change _ < length l + 2
-      simp
+    have : length l' < length (a :: b :: l) := by change _ < length l + 2; simp
     rw [← init_append_last (cons_ne_nil b l)]
     have : C l' := bidirectional_rec l'
     exact Hn a l' b' ‹C l'›termination_by' ⟨_, measure_wf List.length⟩
@@ -1885,11 +1821,7 @@ Case conversion may be inaccurate. Consider using '#align list.sublist_or_mem_of
 theorem sublist_or_mem_of_sublist {l l₁ l₂ : List α} {a : α} (h : l <+ l₁ ++ a :: l₂) :
     l <+ l₁ ++ l₂ ∨ a ∈ l := by
   induction' l₁ with b l₁ IH generalizing l
-  · cases h
-    · left
-      exact ‹l <+ l₂›
-    · right
-      apply mem_cons_self
+  · cases h; · left; exact ‹l <+ l₂›; · right; apply mem_cons_self
   · cases' h with _ _ _ h _ _ _ h
     · exact Or.imp_left (sublist_cons_of_sublist _) (IH h)
     · exact (IH h).imp (sublist.cons_cons _) (mem_cons_of_mem _)
@@ -1899,10 +1831,8 @@ theorem sublist_or_mem_of_sublist {l l₁ l₂ : List α} {a : α} (h : l <+ l
 theorem Sublist.reverse {l₁ l₂ : List α} (h : l₁ <+ l₂) : l₁.reverse <+ l₂.reverse :=
   by
   induction' h with _ _ _ _ ih _ _ a _ ih; · rfl
-  · rw [reverse_cons]
-    exact sublist_append_of_sublist_left ih
-  · rw [reverse_cons, reverse_cons]
-    exact ih.append_right [a]
+  · rw [reverse_cons]; exact sublist_append_of_sublist_left ih
+  · rw [reverse_cons, reverse_cons]; exact ih.append_right [a]
 #align list.sublist.reverse List.Sublist.reverse
 -/
 
@@ -1985,9 +1915,7 @@ theorem sublist_replicate_iff {l : List α} {a : α} {n : ℕ} :
   ⟨fun h =>
     ⟨l.length, h.length_le.trans (length_replicate _ _).le,
       eq_replicate_length.mpr fun b hb => eq_of_mem_replicate (h.Subset hb)⟩,
-    by
-    rintro ⟨k, h, rfl⟩
-    exact (replicate_sublist_replicate _).mpr h⟩
+    by rintro ⟨k, h, rfl⟩; exact (replicate_sublist_replicate _).mpr h⟩
 #align list.sublist_replicate_iff List.sublist_replicate_iff
 
 #print List.Sublist.eq_of_length /-
@@ -2076,9 +2004,7 @@ theorem indexOf_eq_length {a : α} {l : List α} : indexOf a l = length l ↔ a
   · exact iff_of_true rfl (not_mem_nil _)
   simp only [length, mem_cons_iff, index_of_cons]; split_ifs
   · exact iff_of_false (by rintro ⟨⟩) fun H => H <| Or.inl h
-  · simp only [h, false_or_iff]
-    rw [← ih]
-    exact succ_inj'
+  · simp only [h, false_or_iff]; rw [← ih]; exact succ_inj'
 #align list.index_of_eq_length List.indexOf_eq_length
 -/
 
@@ -2094,9 +2020,7 @@ theorem indexOf_le_length {a : α} {l : List α} : indexOf a l ≤ length l :=
   by
   induction' l with b l ih; · rfl
   simp only [length, index_of_cons]
-  by_cases h : a = b;
-  · rw [if_pos h]
-    exact Nat.zero_le _
+  by_cases h : a = b; · rw [if_pos h]; exact Nat.zero_le _
   rw [if_neg h]; exact succ_le_succ ih
 #align list.index_of_le_length List.indexOf_le_length
 -/
@@ -2112,8 +2036,7 @@ theorem indexOf_lt_length {a} {l : List α} : indexOf a l < length l ↔ a ∈ l
 theorem indexOf_append_of_mem {a : α} (h : a ∈ l₁) : indexOf a (l₁ ++ l₂) = indexOf a l₁ :=
   by
   induction' l₁ with d₁ t₁ ih
-  · exfalso
-    exact not_mem_nil a h
+  · exfalso; exact not_mem_nil a h
   rw [List.cons_append]
   by_cases hh : a = d₁
   · iterate 2 rw [index_of_cons_eq _ hh]
@@ -2181,11 +2104,9 @@ theorem get?_eq_some' {l : List α} {n a} : get? l n = some a ↔ ∃ h, nthLe l
 theorem get?_eq_none : ∀ {l : List α} {n}, get? l n = none ↔ length l ≤ n :=
   by
   intros ; constructor
-  · intro h
-    by_contra h'
+  · intro h; by_contra h'
     have h₂ : ∃ h, l.nth_le n h = l.nth_le n (lt_of_not_ge h') := ⟨lt_of_not_ge h', rfl⟩
-    rw [← nth_eq_some, h] at h₂
-    cases h₂
+    rw [← nth_eq_some, h] at h₂; cases h₂
   · solve_by_elim [nth_len_le]
 #align list.nth_eq_none_iff List.get?_eq_none
 -/
@@ -2288,9 +2209,7 @@ theorem nthLe_map' (f : α → β) {l n} (H) :
 `hi` gives `i < L.length` and not `i < L'.length`. The lemma `nth_le_of_eq` can be used to make
 such a rewrite, with `rw (nth_le_of_eq h)`. -/
 theorem nthLe_of_eq {L L' : List α} (h : L = L') {i : ℕ} (hi : i < L.length) :
-    nthLe L i hi = nthLe L' i (h ▸ hi) := by
-  congr
-  exact h
+    nthLe L i hi = nthLe L' i (h ▸ hi) := by congr ; exact h
 #align list.nth_le_of_eq List.nthLe_of_eq
 -/
 
@@ -2304,11 +2223,8 @@ theorem nthLe_singleton (a : α) {n : ℕ} (hn : n < 1) : nthLe [a] n hn = a :=
 -/
 
 #print List.nthLe_zero /-
-theorem nthLe_zero [Inhabited α] {L : List α} (h : 0 < L.length) : L.nthLe 0 h = L.headI :=
-  by
-  cases L
-  cases h
-  simp
+theorem nthLe_zero [Inhabited α] {L : List α} (h : 0 < L.length) : L.nthLe 0 h = L.headI := by
+  cases L; cases h; simp
 #align list.nth_le_zero List.nthLe_zero
 -/
 
@@ -2384,18 +2300,13 @@ theorem getLast_eq_nthLe :
   | [a], h => by rw [last_singleton, nth_le_singleton]
   | a :: b :: l, h => by
     rw [last_cons, last_eq_nth_le (b :: l)]
-    rfl
-    exact cons_ne_nil b l
+    rfl; exact cons_ne_nil b l
 #align list.last_eq_nth_le List.getLast_eq_nthLe
 -/
 
 #print List.nthLe_length_sub_one /-
 theorem nthLe_length_sub_one {l : List α} (h : l.length - 1 < l.length) :
-    l.nthLe (l.length - 1) h =
-      l.getLast
-        (by
-          rintro rfl
-          exact Nat.lt_irrefl 0 h) :=
+    l.nthLe (l.length - 1) h = l.getLast (by rintro rfl; exact Nat.lt_irrefl 0 h) :=
   (getLast_eq_nthLe l _).symm
 #align list.nth_le_length_sub_one List.nthLe_length_sub_one
 -/
@@ -2425,17 +2336,9 @@ theorem take_one_drop_eq_of_lt_length' {l : List α} {n : ℕ} (h : n < l.length
   induction' l with x l ih generalizing n
   · cases h
   · by_cases h₁ : l = []
-    · subst h₁
-      rw [nth_le_singleton]
-      simp [lt_succ_iff] at h
-      subst h
-      simp
-    have h₂ := h
-    rw [length_cons, Nat.lt_succ_iff, le_iff_eq_or_lt] at h₂
-    cases n
-    · simp
-    rw [drop, nth_le]
-    apply ih
+    · subst h₁; rw [nth_le_singleton]; simp [lt_succ_iff] at h; subst h; simp
+    have h₂ := h; rw [length_cons, Nat.lt_succ_iff, le_iff_eq_or_lt] at h₂
+    cases n; · simp; rw [drop, nth_le]; apply ih
 #align list.take_one_drop_eq_of_lt_length List.take_one_drop_eq_of_lt_length'
 -/
 
@@ -2460,8 +2363,7 @@ theorem ext_nthLe {l₁ l₂ : List α} (hl : length l₁ = length l₂)
     if h₁ : n < length l₁ then by rw [nth_le_nth, nth_le_nth, h n h₁ (by rwa [← hl])]
     else by
       let h₁ := le_of_not_gt h₁
-      rw [nth_len_le h₁, nth_len_le]
-      rwa [← hl]
+      rw [nth_len_le h₁, nth_len_le]; rwa [← hl]
 #align list.ext_le List.ext_nthLe
 -/
 
@@ -2557,19 +2459,14 @@ theorem eq_cons_of_length_one {l : List α} (h : l.length = 1) :
 -/
 
 #print List.nthLe_eq_iff /-
-theorem nthLe_eq_iff {l : List α} {n : ℕ} {x : α} {h} : l.nthLe n h = x ↔ l.get? n = some x :=
-  by
-  rw [nth_eq_some]
-  tauto
+theorem nthLe_eq_iff {l : List α} {n : ℕ} {x : α} {h} : l.nthLe n h = x ↔ l.get? n = some x := by
+  rw [nth_eq_some]; tauto
 #align list.nth_le_eq_iff List.nthLe_eq_iff
 -/
 
 #print List.some_nthLe_eq /-
-theorem some_nthLe_eq {l : List α} {n : ℕ} {h} : some (l.nthLe n h) = l.get? n :=
-  by
-  symm
-  rw [nth_eq_some]
-  tauto
+theorem some_nthLe_eq {l : List α} {n : ℕ} {h} : some (l.nthLe n h) = l.get? n := by symm;
+  rw [nth_eq_some]; tauto
 #align list.some_nth_le_eq List.some_nthLe_eq
 -/
 
@@ -3083,15 +2980,9 @@ theorem map_tail (f : α → β) (l) : map f (tail l) = tail (map f l) := by cas
 theorem map_injective_iff {f : α → β} : Injective (map f) ↔ Injective f :=
   by
   constructor <;> intro h x y hxy
-  · suffices [x] = [y] by simpa using this
-    apply h
-    simp [hxy]
-  · induction y generalizing x
-    simpa using hxy
-    cases x
-    simpa using hxy
-    simp at hxy
-    simp [y_ih hxy.2, h hxy.1]
+  · suffices [x] = [y] by simpa using this; apply h; simp [hxy]
+  · induction y generalizing x; simpa using hxy
+    cases x; simpa using hxy; simp at hxy; simp [y_ih hxy.2, h hxy.1]
 #align list.map_injective_iff List.map_injective_iff
 -/
 
@@ -3110,9 +3001,7 @@ theorem comp_map (h : β → γ) (g : α → β) (l : List α) : map (h ∘ g) l
 a single `list.map` of composed functions.
 -/
 @[simp]
-theorem map_comp_map (g : β → γ) (f : α → β) : map g ∘ map f = map (g ∘ f) :=
-  by
-  ext l
+theorem map_comp_map (g : β → γ) (f : α → β) : map g ∘ map f = map (g ∘ f) := by ext l;
   rw [comp_map]
 #align list.map_comp_map List.map_comp_map
 -/
@@ -3124,11 +3013,8 @@ but is expected to have type
   forall {α : Type.{u1}} {β : Type.{u2}} (f : α -> β) (p : α -> Bool) (_inst_1 : List.{u1} α), Eq.{succ u2} (List.{u2} β) (List.map.{u1, u2} α β f (List.filter.{u1} α p _inst_1)) (List.foldr.{u1, u2} α (List.{u2} β) (fun (a : α) (bs : List.{u2} β) => cond.{u2} (List.{u2} β) (p a) (List.cons.{u2} β (f a) bs) bs) (List.nil.{u2} β) _inst_1)
 Case conversion may be inaccurate. Consider using '#align list.map_filter_eq_foldr List.map_filter_eq_foldrₓ'. -/
 theorem map_filter_eq_foldr (f : α → β) (p : α → Prop) [DecidablePred p] (as : List α) :
-    map f (filter p as) = foldr (fun a bs => if p a then f a :: bs else bs) [] as :=
-  by
-  induction as
-  · rfl
-  · simp! [*, apply_ite (map f)]
+    map f (filter p as) = foldr (fun a bs => if p a then f a :: bs else bs) [] as := by
+  induction as; · rfl; · simp! [*, apply_ite (map f)]
 #align list.map_filter_eq_foldr List.map_filter_eq_foldr
 
 #print List.getLast_map /-
@@ -3188,9 +3074,7 @@ theorem zipWith_flip (f : α → β → γ) : ∀ as bs, zipWith (flip f) bs as
   | [], [] => rfl
   | [], b :: bs => rfl
   | a :: as, [] => rfl
-  | a :: as, b :: bs => by
-    simp! [map₂_flip]
-    rfl
+  | a :: as, b :: bs => by simp! [map₂_flip]; rfl
 #align list.map₂_flip List.zipWith_flip
 -/
 
@@ -3287,9 +3171,7 @@ theorem map_take {α β : Type _} (f : α → β) :
     ∀ (L : List α) (i : ℕ), (L.take i).map f = (L.map f).take i
   | [], i => by simp
   | L, 0 => by simp
-  | h :: t, n + 1 => by
-    dsimp
-    rw [map_take]
+  | h :: t, n + 1 => by dsimp; rw [map_take]
 #align list.map_take List.map_take
 
 #print List.take_append_eq_append_take /-
@@ -3321,14 +3203,8 @@ theorem take_append {l₁ l₂ : List α} (i : ℕ) : take (l₁.length + i) (l
 /-- The `i`-th element of a list coincides with the `i`-th element of any of its prefixes of
 length `> i`. Version designed to rewrite from the big list to the small list. -/
 theorem nthLe_take (L : List α) {i j : ℕ} (hi : i < L.length) (hj : i < j) :
-    nthLe L i hi =
-      nthLe (L.take j) i
-        (by
-          rw [length_take]
-          exact lt_min hj hi) :=
-  by
-  rw [nth_le_of_eq (take_append_drop j L).symm hi]
-  exact nth_le_append _ _
+    nthLe L i hi = nthLe (L.take j) i (by rw [length_take]; exact lt_min hj hi) := by
+  rw [nth_le_of_eq (take_append_drop j L).symm hi]; exact nth_le_append _ _
 #align list.nth_le_take List.nthLe_take
 -/
 
@@ -3336,9 +3212,7 @@ theorem nthLe_take (L : List α) {i j : ℕ} (hi : i < L.length) (hj : i < j) :
 /-- The `i`-th element of a list coincides with the `i`-th element of any of its prefixes of
 length `> i`. Version designed to rewrite from the small list to the big list. -/
 theorem nthLe_take' (L : List α) {i j : ℕ} (hi : i < (L.take j).length) :
-    nthLe (L.take j) i hi = nthLe L i (lt_of_lt_of_le hi (by simp [le_refl])) :=
-  by
-  simp at hi
+    nthLe (L.take j) i hi = nthLe L i (lt_of_lt_of_le hi (by simp [le_refl])) := by simp at hi;
   rw [nth_le_take L _ hi.1]
 #align list.nth_le_take' List.nthLe_take'
 -/
@@ -3409,8 +3283,7 @@ theorem take_add (l : List α) (m n : ℕ) : l.take (m + n) = l.take m ++ (l.dro
   simp only [take_eq_take, length_take, length_drop]
   generalize l.length = k; by_cases h : m ≤ k
   · simp [min_eq_left_iff.mpr h]
-  · push_neg  at h
-    simp [Nat.sub_eq_zero_of_le (le_of_lt h)]
+  · push_neg  at h; simp [Nat.sub_eq_zero_of_le (le_of_lt h)]
 #align list.take_add List.take_add
 -/
 
@@ -3552,10 +3425,8 @@ theorem drop_length_cons {l : List α} (h : l ≠ []) (a : α) :
   induction' l with y l ih generalizing a
   · cases h rfl
   · simp only [drop, length]
-    by_cases h₁ : l = []
-    · simp [h₁]
-    rw [last_cons h₁]
-    exact ih h₁ y
+    by_cases h₁ : l = []; · simp [h₁]
+    rw [last_cons h₁]; exact ih h₁ y
 #align list.drop_length_cons List.drop_length_cons
 -/
 
@@ -3673,9 +3544,7 @@ theorem map_drop {α β : Type _} (f : α → β) :
     ∀ (L : List α) (i : ℕ), (L.drop i).map f = (L.map f).drop i
   | [], i => by simp
   | L, 0 => by simp
-  | h :: t, n + 1 => by
-    dsimp
-    rw [map_drop]
+  | h :: t, n + 1 => by dsimp; rw [map_drop]
 #align list.map_drop List.map_drop
 
 #print List.modifyNthTail_eq_take_drop /-
@@ -3720,12 +3589,10 @@ theorem reverse_take {α} {xs : List α} (n : ℕ) (h : n ≤ xs.length) :
     rw [show xs_tl.length + 1 - n = succ (xs_tl.length - n) from _, drop]
     · rwa [succ_eq_add_one, ← tsub_add_eq_add_tsub]
     · rwa [length_reverse]
-  · subst h'
-    rw [length, tsub_self, drop]
+  · subst h'; rw [length, tsub_self, drop]
     suffices xs_tl.length + 1 = (xs_tl.reverse ++ [xs_hd]).length by
       rw [this, take_length, reverse_cons]
-    rw [length_append, length_reverse]
-    rfl
+    rw [length_append, length_reverse]; rfl
 #align list.reverse_take List.reverse_take
 -/
 
@@ -3993,9 +3860,7 @@ but is expected to have type
 Case conversion may be inaccurate. Consider using '#align list.foldl_hom List.foldl_homₓ'. -/
 theorem foldl_hom (l : List γ) (f : α → β) (op : α → γ → α) (op' : β → γ → β) (a : α)
     (h : ∀ a x, f (op a x) = op' (f a) x) : foldl op' (f a) l = f (foldl op a l) :=
-  Eq.symm <| by
-    revert a
-    induction l <;> intros <;> [rfl;simp only [*, foldl]]
+  Eq.symm <| by revert a; induction l <;> intros <;> [rfl;simp only [*, foldl]]
 #align list.foldl_hom List.foldl_hom
 
 /- warning: list.foldr_hom -> List.foldr_hom is a dubious translation:
@@ -4005,9 +3870,7 @@ but is expected to have type
   forall {α : Type.{u3}} {β : Type.{u2}} {γ : Type.{u1}} (l : α -> β) (f : γ -> α -> α) (op : γ -> β -> β) (op' : List.{u1} γ) (a : α), (forall (x : γ) (a : α), Eq.{succ u2} β (op x (l a)) (l (f x a))) -> (Eq.{succ u2} β (List.foldr.{u1, u2} γ β op (l a) op') (l (List.foldr.{u1, u3} γ α f a op')))
 Case conversion may be inaccurate. Consider using '#align list.foldr_hom List.foldr_homₓ'. -/
 theorem foldr_hom (l : List γ) (f : α → β) (op : γ → α → α) (op' : γ → β → β) (a : α)
-    (h : ∀ x a, f (op x a) = op' x (f a)) : foldr op' (f a) l = f (foldr op a l) :=
-  by
-  revert a
+    (h : ∀ x a, f (op x a) = op' x (f a)) : foldr op' (f a) l = f (foldr op a l) := by revert a;
   induction l <;> intros <;> [rfl;simp only [*, foldr]]
 #align list.foldr_hom List.foldr_hom
 
@@ -4020,9 +3883,7 @@ Case conversion may be inaccurate. Consider using '#align list.foldl_hom₂ List
 theorem foldl_hom₂ (l : List ι) (f : α → β → γ) (op₁ : α → ι → α) (op₂ : β → ι → β)
     (op₃ : γ → ι → γ) (a : α) (b : β) (h : ∀ a b i, f (op₁ a i) (op₂ b i) = op₃ (f a b) i) :
     foldl op₃ (f a b) l = f (foldl op₁ a l) (foldl op₂ b l) :=
-  Eq.symm <| by
-    revert a b
-    induction l <;> intros <;> [rfl;simp only [*, foldl]]
+  Eq.symm <| by revert a b; induction l <;> intros <;> [rfl;simp only [*, foldl]]
 #align list.foldl_hom₂ List.foldl_hom₂
 
 /- warning: list.foldr_hom₂ -> List.foldr_hom₂ is a dubious translation:
@@ -4033,9 +3894,7 @@ but is expected to have type
 Case conversion may be inaccurate. Consider using '#align list.foldr_hom₂ List.foldr_hom₂ₓ'. -/
 theorem foldr_hom₂ (l : List ι) (f : α → β → γ) (op₁ : ι → α → α) (op₂ : ι → β → β)
     (op₃ : ι → γ → γ) (a : α) (b : β) (h : ∀ a b i, f (op₁ i a) (op₂ i b) = op₃ i (f a b)) :
-    foldr op₃ (f a b) l = f (foldr op₁ a l) (foldr op₂ b l) :=
-  by
-  revert a
+    foldr op₃ (f a b) l = f (foldr op₁ a l) (foldr op₂ b l) := by revert a;
   induction l <;> intros <;> [rfl;simp only [*, foldr]]
 #align list.foldr_hom₂ List.foldr_hom₂
 
@@ -4543,9 +4402,7 @@ theorem [anonymous] : [anonymous] p xs ys = splitOnPAux p xs ((· ++ ·) ys) :=
     simp! only [append_nil, eq_self_iff_true, and_self_iff]
   split_ifs <;> rw [ih]
   · refine' ⟨rfl, rfl⟩
-  · congr
-    ext
-    simp
+  · congr ; ext; simp
 #align list.split_on_p_aux_eq [anonymous]
 
 /- warning: list.split_on_p_aux_nil clashes with [anonymous] -> [anonymous]
@@ -4555,10 +4412,7 @@ lean 3 declaration is
 but is expected to have type
   forall {α : Type.{u}} {p : Type.{v}}, (Nat -> α -> p) -> Nat -> (List.{u} α) -> (List.{v} p)
 Case conversion may be inaccurate. Consider using '#align list.split_on_p_aux_nil [anonymous]ₓ'. -/
-theorem [anonymous] : splitOnPAux p xs id = [anonymous] p xs [] :=
-  by
-  rw [split_on_p_aux_eq]
-  rfl
+theorem [anonymous] : splitOnPAux p xs id = [anonymous] p xs [] := by rw [split_on_p_aux_eq]; rfl
 #align list.split_on_p_aux_nil [anonymous]
 
 /-- The original list `L` can be recovered by joining the lists produced by `split_on_p p L`,
@@ -4572,9 +4426,7 @@ theorem splitOnP_spec (as : List α) :
       join
           (zip_with (· ++ ·) (split_on_p_aux' p as xs) (((as.filter p).map fun x => [x]) ++ [[]])) =
         xs ++ as
-    by
-    rw [this]
-    rfl
+    by rw [this]; rfl
   induction as <;> intro <;> simp! only [split_on_p_aux', append_nil]
   split_ifs <;> simp [zip_with, join, *]
 #align list.split_on_p_spec List.splitOnP_specₓ
@@ -4616,30 +4468,19 @@ theorem splitOnP_ne_nil : xs.splitOnP p ≠ [] :=
 theorem splitOnP_cons (x : α) (xs : List α) :
     (x :: xs).splitOnP p =
       if p x then [] :: xs.splitOnP p else (xs.splitOnP p).modifyHead (cons x) :=
-  by
-  simp only [split_on_p, split_on_p_aux]
-  split_ifs
-  · simp
-  rw [split_on_p_aux_spec]
-  rfl
+  by simp only [split_on_p, split_on_p_aux]; split_ifs; · simp; rw [split_on_p_aux_spec]; rfl
 #align list.split_on_p_cons List.splitOnP_consₓ
 
 /-- If no element satisfies `p` in the list `xs`, then `xs.split_on_p p = [xs]` -/
-theorem splitOnP_eq_single (h : ∀ x ∈ xs, ¬p x) : xs.splitOnP p = [xs] :=
-  by
-  induction' xs with hd tl ih
-  · rfl
-  simp [h hd _, ih fun t ht => h t (Or.inr ht)]
+theorem splitOnP_eq_single (h : ∀ x ∈ xs, ¬p x) : xs.splitOnP p = [xs] := by
+  induction' xs with hd tl ih; · rfl; simp [h hd _, ih fun t ht => h t (Or.inr ht)]
 #align list.split_on_p_eq_single List.splitOnP_eq_singleₓ
 
 /-- When a list of the form `[...xs, sep, ...as]` is split on `p`, the first element is `xs`,
   assuming no element in `xs` satisfies `p` but `sep` does satisfy `p` -/
 theorem splitOnP_first (h : ∀ x ∈ xs, ¬p x) (sep : α) (hsep : p sep) (as : List α) :
-    (xs ++ sep :: as).splitOnP p = xs :: as.splitOnP p :=
-  by
-  induction' xs with hd tl ih
-  · simp [hsep]
-  simp [h hd _, ih fun t ht => h t (Or.inr ht)]
+    (xs ++ sep :: as).splitOnP p = xs :: as.splitOnP p := by induction' xs with hd tl ih;
+  · simp [hsep]; simp [h hd _, ih fun t ht => h t (Or.inr ht)]
 #align list.split_on_p_first List.splitOnP_firstₓ
 
 #print List.intercalate_splitOn /-
@@ -4649,9 +4490,7 @@ theorem intercalate_splitOn (x : α) [DecidableEq α] : [x].intercalate (xs.spli
   simp only [intercalate, split_on]
   induction' xs with hd tl ih; · simp [join]; simp only [split_on_p_cons]
   cases' h' : split_on_p (· = x) tl with hd' tl'; · exact (split_on_p_ne_nil _ tl h').elim
-  rw [h'] at ih; split_ifs;
-  · subst h
-    simp [ih, join]
+  rw [h'] at ih; split_ifs; · subst h; simp [ih, join]
   cases tl' <;> simpa [join] using ih
 #align list.intercalate_split_on List.intercalate_splitOn
 -/
@@ -4666,25 +4505,13 @@ theorem splitOn_intercalate [DecidableEq α] (x : α) (hx : ∀ l ∈ ls, x ∉
   induction' ls with hd tl ih; · contradiction
   cases tl
   · suffices hd.split_on x = [hd] by simpa [join]
-    refine' split_on_p_eq_single _ _ _
-    intro y hy H
-    rw [H] at hy
-    refine' hx hd _ hy
-    simp
+    refine' split_on_p_eq_single _ _ _; intro y hy H; rw [H] at hy
+    refine' hx hd _ hy; simp
   · simp only [intersperse_cons_cons, singleton_append, join]
-    specialize ih _ _
-    · intro l hl
-      apply hx l
-      simp at hl⊢
-      tauto
-    · trivial
+    specialize ih _ _; · intro l hl; apply hx l; simp at hl⊢; tauto; · trivial
     have := split_on_p_first (· = x) hd _ x rfl _
-    · simp only [split_on] at ih⊢
-      rw [this]
-      rw [ih]
-    intro y hy H
-    rw [H] at hy
-    exact hx hd (Or.inl rfl) hy
+    · simp only [split_on] at ih⊢; rw [this]; rw [ih]
+    intro y hy H; rw [H] at hy; exact hx hd (Or.inl rfl) hy
 #align list.split_on_intercalate List.splitOn_intercalate
 -/
 
@@ -4723,8 +4550,7 @@ theorem sizeOf_lt_sizeOf_of_mem [SizeOf α] {x : α} {l : List α} (hx : x ∈ l
     SizeOf.sizeOf x < SizeOf.sizeOf l :=
   by
   induction' l with h t ih <;> cases hx
-  · rw [hx]
-    exact lt_add_of_lt_of_nonneg (lt_one_add _) (Nat.zero_le _)
+  · rw [hx]; exact lt_add_of_lt_of_nonneg (lt_one_add _) (Nat.zero_le _)
   · exact lt_add_of_pos_of_le (zero_lt_one_add _) (le_of_lt (ih hx))
 #align list.sizeof_lt_sizeof_of_mem List.sizeOf_lt_sizeOf_of_mem
 
@@ -4800,8 +4626,7 @@ theorem attach_map_val (l : List α) : l.attach.map Subtype.val = l :=
 theorem mem_attach (l : List α) : ∀ x, x ∈ l.attach
   | ⟨a, h⟩ => by
     have := mem_map.1 (by rw [attach_map_val] <;> exact h) <;>
-      · rcases this with ⟨⟨_, _⟩, m, rfl⟩
-        exact m
+      · rcases this with ⟨⟨_, _⟩, m, rfl⟩; exact m
 #align list.mem_attach List.mem_attach
 -/
 
@@ -4982,11 +4807,8 @@ theorem find?_some (H : find? p l = some a) : p a :=
   by
   induction' l with b l IH; · contradiction
   by_cases h : p b
-  · rw [find_cons_of_pos _ h] at H
-    cases H
-    exact h
-  · rw [find_cons_of_neg _ h] at H
-    exact IH H
+  · rw [find_cons_of_pos _ h] at H; cases H; exact h
+  · rw [find_cons_of_neg _ h] at H; exact IH H
 #align list.find_some List.find?_some
 
 /- warning: list.find_mem -> List.find?_mem is a dubious translation:
@@ -5000,11 +4822,8 @@ theorem find?_mem (H : find? p l = some a) : a ∈ l :=
   by
   induction' l with b l IH; · contradiction
   by_cases h : p b
-  · rw [find_cons_of_pos _ h] at H
-    cases H
-    apply mem_cons_self
-  · rw [find_cons_of_neg _ h] at H
-    exact mem_cons_of_mem _ (IH H)
+  · rw [find_cons_of_pos _ h] at H; cases H; apply mem_cons_self
+  · rw [find_cons_of_neg _ h] at H; exact mem_cons_of_mem _ (IH H)
 #align list.find_mem List.find?_mem
 
 end Find
@@ -5185,7 +5004,7 @@ theorem filterMap_eq_filter (p : α → Prop) [DecidablePred p] :
   funext l
   induction' l with a l IH; · rfl
   by_cases pa : p a
-  · simp only [filter_map, Option.guard, IH, if_pos pa, filter_cons_of_pos _ pa]
+  · simp only [filter_map, Option.guard, IH, if_pos pa, filter_cons_of_pos _ pa];
     constructor <;> rfl
   · simp only [filter_map, Option.guard, IH, if_neg pa, filter_cons_of_neg _ pa]
 #align list.filter_map_eq_filter List.filterMap_eq_filter
@@ -5292,21 +5111,12 @@ theorem mem_filterMap (f : α → Option β) (l : List α) {b : β} :
     b ∈ filterMap f l ↔ ∃ a, a ∈ l ∧ f a = some b :=
   by
   induction' l with a l IH
-  · constructor
-    · intro H
-      cases H
-    · rintro ⟨_, H, _⟩
-      cases H
+  · constructor; · intro H; cases H; · rintro ⟨_, H, _⟩; cases H
   cases' h : f a with b'
-  · have : f a ≠ some b := by
-      rw [h]
-      intro
-      contradiction
+  · have : f a ≠ some b := by rw [h]; intro ; contradiction
     simp only [filter_map_cons_none _ _ h, IH, mem_cons_iff, or_and_right, exists_or,
       exists_eq_left, this, false_or_iff]
-  · have : f a = some b ↔ b = b' := by
-      constructor <;> intro t
-      · rw [t] at h <;> injection h
+  · have : f a = some b ↔ b = b' := by constructor <;> intro t; · rw [t] at h <;> injection h;
       · exact t.symm ▸ h
     simp only [filter_map_cons_some _ _ _ h, IH, mem_cons_iff, or_and_right, exists_or, this,
       exists_eq_left]
@@ -5909,8 +5719,7 @@ theorem exists_of_eraseP {l : List α} {a} (al : a ∈ l) (pa : p a) :
   induction' l with b l IH; · cases al
   by_cases pb : p b
   · exact ⟨b, [], l, forall_mem_nil _, pb, by simp [pb]⟩
-  · rcases al with (rfl | al)
-    · exact pb.elim pa
+  · rcases al with (rfl | al); · exact pb.elim pa
     rcases IH al with ⟨c, l₁, l₂, h₁, h₂, h₃, h₄⟩
     exact ⟨c, b :: l₁, l₂, forall_mem_cons.2 ⟨pb, h₁⟩, h₂, by rw [h₃] <;> rfl, by simp [pb, h₄]⟩
 #align list.exists_of_erasep List.exists_of_erasePₓ
@@ -5922,8 +5731,7 @@ theorem exists_or_eq_self_of_eraseP (p : α → Prop) [DecidablePred p] (l : Lis
   by_cases h : ∃ a ∈ l, p a
   · rcases h with ⟨a, ha, pa⟩
     exact Or.inr (exists_of_erasep ha pa)
-  · simp at h
-    exact Or.inl (erasep_of_forall_not h)
+  · simp at h; exact Or.inl (erasep_of_forall_not h)
 #align list.exists_or_eq_self_of_erasep List.exists_or_eq_self_of_erasePₓ
 
 @[simp]
@@ -5939,8 +5747,7 @@ theorem length_eraseP_add_one {l : List α} {a} (al : a ∈ l) (pa : p a) :
     (l.erasePₓ p).length + 1 = l.length :=
   by
   let ⟨_, l₁, l₂, _, _, h₁, h₂⟩ := exists_of_eraseP al pa
-  rw [h₂, h₁, length_append, length_append]
-  rfl
+  rw [h₂, h₁, length_append, length_append]; rfl
 #align list.length_erasep_add_one List.length_eraseP_add_oneₓ
 
 theorem eraseP_append_left {a : α} (pa : p a) :
@@ -5960,9 +5767,7 @@ theorem eraseP_append_right :
 
 theorem eraseP_sublist (l : List α) : l.erasePₓ p <+ l := by
   rcases exists_or_eq_self_of_erasep p l with (h | ⟨c, l₁, l₂, h₁, h₂, h₃, h₄⟩) <;>
-    [rw [h];·
-      rw [h₄, h₃]
-      simp]
+    [rw [h];· rw [h₄, h₃]; simp]
 #align list.erasep_sublist List.eraseP_sublistₓ
 
 theorem eraseP_subset (l : List α) : l.erasePₓ p ⊆ l :=
@@ -5991,11 +5796,8 @@ theorem mem_eraseP_of_neg {a : α} {l : List α} (pa : ¬p a) : a ∈ l.eraseP
     by
     rcases exists_or_eq_self_of_erasep p l with (h | ⟨c, l₁, l₂, h₁, h₂, h₃, h₄⟩)
     · rwa [h]
-    · rw [h₄]
-      rw [h₃] at al
-      have : a ≠ c := by
-        rintro rfl
-        exact pa.elim h₂
+    · rw [h₄]; rw [h₃] at al
+      have : a ≠ c := by rintro rfl; exact pa.elim h₂
       simpa [this] using al⟩
 #align list.mem_erasep_of_neg List.mem_eraseP_of_negₓ
 
@@ -6043,8 +5845,7 @@ theorem erase_cons_tail {a b : α} (l : List α) (h : b ≠ a) : (b :: l).erase
 
 theorem erase_eq_eraseP (a : α) (l : List α) : l.eraseₓ a = l.erasePₓ (Eq a) :=
   by
-  induction' l with b l
-  · rfl
+  induction' l with b l; · rfl
   by_cases a = b <;> [simp [h];simp [h, Ne.symm h, *]]
 #align list.erase_eq_erasep List.erase_eq_erasePₓ
 
@@ -6416,8 +6217,7 @@ theorem mem_enumFrom {x : α} {i : ℕ} :
     · obtain ⟨hji, hijlen, hmem⟩ := mem_enum_from _ h
       refine' ⟨_, _, _⟩
       · exact le_trans (Nat.le_succ _) hji
-      · convert hijlen using 1
-        ac_rfl
+      · convert hijlen using 1; ac_rfl
       · simp [hmem]
 #align list.mem_enum_from List.mem_enumFrom
 -/
@@ -6545,9 +6345,7 @@ theorem nthLe_enumFrom (l : List α) (n i : ℕ) (hi' : i < (l.enumFrom n).lengt
 #print List.nthLe_enum /-
 theorem nthLe_enum (l : List α) (i : ℕ) (hi' : i < l.enum.length)
     (hi : i < l.length := (by simpa [length_enum] using hi')) :
-    l.enum.nthLe i hi' = (i, l.nthLe i hi) :=
-  by
-  convert nth_le_enum_from _ _ _ hi'
+    l.enum.nthLe i hi' = (i, l.nthLe i hi) := by convert nth_le_enum_from _ _ _ hi';
   exact (zero_add _).symm
 #align list.nth_le_enum List.nthLe_enum
 -/
@@ -6741,12 +6539,8 @@ theorem map₂Left_eq_zipWith :
     ∀ as bs, length as ≤ length bs → map₂Left f as bs = zipWith (fun a b => f a (some b)) as bs
   | [], [], h => by simp!
   | [], b :: bs, h => by simp!
-  | a :: as, [], h => by
-    simp at h
-    contradiction
-  | a :: as, b :: bs, h => by
-    simp at h
-    simp! [*]
+  | a :: as, [], h => by simp at h; contradiction
+  | a :: as, b :: bs, h => by simp at h; simp! [*]
 #align list.map₂_left_eq_map₂ List.map₂Left_eq_zipWith
 -/
 
@@ -6960,8 +6754,7 @@ theorem [anonymous] {n} : ∀ {xs i l L}, @toChunksAux α n xs i = (l, L) → l
   | x :: xs, i, l, L, e => by
     cases i <;>
         [cases' e' : to_chunks_aux n xs n with l L;cases' e' : to_chunks_aux n xs i with l L] <;>
-      · rw [to_chunks_aux, e', to_chunks_aux] at e
-        cases e
+      · rw [to_chunks_aux, e', to_chunks_aux] at e; cases e
         exact (congr_arg (cons x) (to_chunks_aux_join e') : _)
 #align list.to_chunks_aux_join [anonymous]
 
@@ -6993,9 +6786,7 @@ theorem [anonymous] : ∀ n xs, n ≠ 0 → ∀ l : List α, l ∈ @toChunks α
   | 0, _, e, _ => (e rfl).elim
   | n + 1, xs, _, l => by
     refine' (measure_wf length).induction xs _; intro xs IH h
-    by_cases x0 : xs = [];
-    · subst xs
-      cases h
+    by_cases x0 : xs = []; · subst xs; cases h
     rw [to_chunks_eq_cons' _ x0] at h; rcases h with (rfl | h)
     · apply length_take_le
     · refine' IH _ _ h
@@ -7064,10 +6855,7 @@ attribute [to_additive] alternating_prod
 #print List.getLast_reverse /-
 -- `list.alternating_sum`
 theorem getLast_reverse {l : List α} (hl : l.reverse ≠ [])
-    (hl' : 0 < l.length :=
-      (by
-        contrapose! hl
-        simpa [length_eq_zero] using hl)) :
+    (hl' : 0 < l.length := (by contrapose! hl; simpa [length_eq_zero] using hl)) :
     l.reverse.getLast hl = l.nthLe 0 hl' :=
   by
   rw [last_eq_nth_le, nth_le_reverse']
@@ -7130,10 +6918,8 @@ theorem sizeOf_dropSlice_lt [SizeOf α] (i j : ℕ) (hj : 0 < j) (xs : List α)
   case
     cons x xs xs_ih i j h =>
     cases i <;> simp only [-slice_eq, List.dropSlice]
-    · cases j
-      cases h
-      dsimp only [drop]
-      unfold_wf
+    · cases j; cases h
+      dsimp only [drop]; unfold_wf
       apply @lt_of_le_of_lt _ _ _ xs.sizeof
       · clear * -
         induction xs generalizing j <;> unfold_wf
@@ -7143,8 +6929,7 @@ theorem sizeOf_dropSlice_lt [SizeOf α] (i j : ℕ) (hj : 0 < j) (xs : List α)
           trans; apply xs_ih
           simp
       unfold_wf
-    · unfold_wf
-      apply xs_ih _ _ h
+    · unfold_wf; apply xs_ih _ _ h
       apply lt_of_succ_lt_succ hi
 #align list.sizeof_slice_lt List.sizeOf_dropSlice_lt
 
Diff
@@ -931,7 +931,7 @@ theorem subset_singleton_iff {a : α} {L : List α} : L ⊆ [a] ↔ ∃ n, L = r
 #print List.map_replicate /-
 @[simp]
 theorem map_replicate (f : α → β) (n a) : map f (replicate n a) = replicate n (f a) := by
-  induction n <;> [rfl, simp only [*, replicate, map]] <;> constructor <;> rfl
+  induction n <;> [rfl;simp only [*, replicate, map]] <;> constructor <;> rfl
 #align list.map_replicate List.map_replicate
 -/
 
@@ -949,7 +949,7 @@ theorem tail_replicate (n) (a : α) : tail (replicate n a) = replicate (n - 1) a
 #print List.join_replicate_nil /-
 @[simp]
 theorem join_replicate_nil (n : ℕ) : join (replicate n []) = @nil α := by
-  induction n <;> [rfl, simp only [*, replicate, join, append_nil]]
+  induction n <;> [rfl;simp only [*, replicate, join, append_nil]]
 #align list.join_replicate_nil List.join_replicate_nil
 -/
 
@@ -1137,15 +1137,14 @@ attribute [local simp] reverse_core
 @[simp]
 theorem reverse_cons (a : α) (l : List α) : reverse (a :: l) = reverse l ++ [a] :=
   have aux : ∀ l₁ l₂, reverseAux l₁ l₂ ++ [a] = reverseAux l₁ (l₂ ++ [a]) := by
-    intro l₁ <;> induction l₁ <;> intros <;> [rfl, simp only [*, reverse_core, cons_append]]
+    intro l₁ <;> induction l₁ <;> intros <;> [rfl;simp only [*, reverse_core, cons_append]]
   (aux l nil).symm
 #align list.reverse_cons List.reverse_cons
 -/
 
 #print List.reverseAux_eq /-
 theorem reverseAux_eq (l₁ l₂ : List α) : reverseAux l₁ l₂ = reverse l₁ ++ l₂ := by
-  induction l₁ generalizing l₂ <;> [rfl,
-      simp only [*, reverse_core, reverse_cons, append_assoc]] <;>
+  induction l₁ generalizing l₂ <;> [rfl;simp only [*, reverse_core, reverse_cons, append_assoc]] <;>
     rfl
 #align list.reverse_core_eq List.reverseAux_eq
 -/
@@ -1166,8 +1165,9 @@ theorem reverse_singleton (a : α) : reverse [a] = [a] :=
 #print List.reverse_append /-
 @[simp]
 theorem reverse_append (s t : List α) : reverse (s ++ t) = reverse t ++ reverse s := by
-  induction s <;> [rw [nil_append, reverse_nil, append_nil],
-    simp only [*, cons_append, reverse_cons, append_assoc]]
+  induction s <;>
+    [rw [nil_append, reverse_nil,
+      append_nil];simp only [*, cons_append, reverse_cons, append_assoc]]
 #align list.reverse_append List.reverse_append
 -/
 
@@ -1180,7 +1180,7 @@ theorem reverse_concat (l : List α) (a : α) : reverse (concat l a) = a :: reve
 #print List.reverse_reverse /-
 @[simp]
 theorem reverse_reverse (l : List α) : reverse (reverse l) = l := by
-  induction l <;> [rfl, simp only [*, reverse_cons, reverse_append]] <;> rfl
+  induction l <;> [rfl;simp only [*, reverse_cons, reverse_append]] <;> rfl
 #align list.reverse_reverse List.reverse_reverse
 -/
 
@@ -1239,14 +1239,14 @@ theorem concat_eq_reverse_cons (a : α) (l : List α) : concat l a = reverse (a
 #print List.length_reverse /-
 @[simp]
 theorem length_reverse (l : List α) : length (reverse l) = length l := by
-  induction l <;> [rfl, simp only [*, reverse_cons, length_append, length]]
+  induction l <;> [rfl;simp only [*, reverse_cons, length_append, length]]
 #align list.length_reverse List.length_reverse
 -/
 
 #print List.map_reverse /-
 @[simp]
 theorem map_reverse (f : α → β) (l : List α) : map f (reverse l) = reverse (map f l) := by
-  induction l <;> [rfl, simp only [*, map, reverse_cons, map_append]]
+  induction l <;> [rfl;simp only [*, map, reverse_cons, map_append]]
 #align list.map_reverse List.map_reverse
 -/
 
@@ -1260,9 +1260,9 @@ theorem map_reverseAux (f : α → β) (l₁ l₂ : List α) :
 #print List.mem_reverse' /-
 @[simp]
 theorem mem_reverse' {a : α} {l : List α} : a ∈ reverse l ↔ a ∈ l := by
-  induction l <;> [rfl,
-    simp only [*, reverse_cons, mem_append, mem_singleton, mem_cons_iff, not_mem_nil, false_or_iff,
-      or_false_iff, or_comm']]
+  induction l <;>
+    [rfl;simp only [*, reverse_cons, mem_append, mem_singleton, mem_cons_iff, not_mem_nil,
+      false_or_iff, or_false_iff, or_comm']]
 #align list.mem_reverse List.mem_reverse'
 -/
 
@@ -1318,8 +1318,8 @@ theorem getLast_cons {a : α} {l : List α} :
 @[simp]
 theorem getLast_append_singleton {a : α} (l : List α) :
     getLast (l ++ [a]) (append_ne_nil_of_ne_nil_right l _ (cons_ne_nil a _)) = a := by
-  induction l <;> [rfl,
-    simp only [cons_append, last_cons fun H => cons_ne_nil _ _ (append_eq_nil.1 H).2, *]]
+  induction l <;>
+    [rfl;simp only [cons_append, last_cons fun H => cons_ne_nil _ _ (append_eq_nil.1 H).2, *]]
 #align list.last_append_singleton List.getLast_append_singleton
 -/
 
@@ -1971,7 +1971,7 @@ Case conversion may be inaccurate. Consider using '#align list.replicate_sublist
 @[simp]
 theorem replicate_sublist_replicate (a : α) {m n} : replicate m a <+ replicate n a ↔ m ≤ n :=
   ⟨fun h => by simpa only [length_replicate] using h.length_le, fun h => by
-    induction h <;> [rfl, simp only [*, replicate_succ, sublist.cons]]⟩
+    induction h <;> [rfl;simp only [*, replicate_succ, sublist.cons]]⟩
 #align list.replicate_sublist_replicate List.replicate_sublist_replicate
 
 /- warning: list.sublist_replicate_iff -> List.sublist_replicate_iff is a dubious translation:
@@ -3013,7 +3013,7 @@ theorem map_eq_map_iff {f g : α → β} {l : List α} : map f l = map g l ↔ 
 #print List.map_concat /-
 theorem map_concat (f : α → β) (a : α) (l : List α) : map f (concat l a) = concat (map f l) (f a) :=
   by
-  induction l <;> [rfl, simp only [*, concat_eq_append, cons_append, map, map_append]] <;>
+  induction l <;> [rfl;simp only [*, concat_eq_append, cons_append, map, map_append]] <;>
       constructor <;>
     rfl
 #align list.map_concat List.map_concat
@@ -3041,7 +3041,7 @@ theorem eq_nil_of_map_eq_nil {f : α → β} {l : List α} (h : map f l = nil) :
 #print List.map_join /-
 @[simp]
 theorem map_join (f : α → β) (L : List (List α)) : map f (join L) = join (map (map f) L) := by
-  induction L <;> [rfl, simp only [*, join, map, map_append]]
+  induction L <;> [rfl;simp only [*, join, map, map_append]]
 #align list.map_join List.map_join
 -/
 
@@ -3621,7 +3621,7 @@ theorem nthLe_drop (L : List α) {i j : ℕ} (h : i + j < L.length) :
 lean 3 declaration is
   forall {α : Type.{u1}} (L : List.{u1} α) {i : Nat} {j : Nat} (h : LT.lt.{0} Nat Nat.hasLt j (List.length.{u1} α (List.drop.{u1} α i L))), Eq.{succ u1} α (List.nthLe.{u1} α (List.drop.{u1} α i L) j h) (List.nthLe.{u1} α L (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat Nat.hasAdd) i j) (Iff.mp (LT.lt.{0} Nat (Preorder.toHasLt.{0} Nat (PartialOrder.toPreorder.{0} Nat (SemilatticeInf.toPartialOrder.{0} Nat (Lattice.toSemilatticeInf.{0} Nat (LinearOrder.toLattice.{0} Nat Nat.linearOrder))))) j (HSub.hSub.{0, 0, 0} Nat Nat Nat (instHSub.{0} Nat Nat.hasSub) (List.length.{u1} α L) i)) (LT.lt.{0} Nat (Preorder.toHasLt.{0} Nat (PartialOrder.toPreorder.{0} Nat (SemilatticeInf.toPartialOrder.{0} Nat (Lattice.toSemilatticeInf.{0} Nat (LinearOrder.toLattice.{0} Nat Nat.linearOrder))))) (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat (AddSemigroup.toHasAdd.{0} Nat (AddCommSemigroup.toAddSemigroup.{0} Nat Nat.addCommSemigroup))) i j) (List.length.{u1} α L)) (lt_tsub_iff_left.{0} Nat j (List.length.{u1} α L) i Nat.linearOrder Nat.addCommSemigroup Nat.hasSub Nat.orderedSub) (Eq.subst.{1} Nat (fun (_x : Nat) => LT.lt.{0} Nat (Preorder.toHasLt.{0} Nat (PartialOrder.toPreorder.{0} Nat (SemilatticeInf.toPartialOrder.{0} Nat (Lattice.toSemilatticeInf.{0} Nat (LinearOrder.toLattice.{0} Nat Nat.linearOrder))))) j _x) (List.length.{u1} α (List.drop.{u1} α i L)) (HSub.hSub.{0, 0, 0} Nat Nat Nat (instHSub.{0} Nat Nat.hasSub) (List.length.{u1} α L) i) (List.length_drop.{u1} α i L) h)))
 but is expected to have type
-  forall {α : Type.{u1}} (L : List.{u1} α) {i : Nat} {j : Nat} (h : LT.lt.{0} Nat instLTNat j (List.length.{u1} α (List.drop.{u1} α i L))), Eq.{succ u1} α (List.nthLe.{u1} α (List.drop.{u1} α i L) j h) (List.nthLe.{u1} α L (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat instAddNat) i j) (Iff.mp (LT.lt.{0} Nat (Preorder.toLT.{0} Nat (PartialOrder.toPreorder.{0} Nat (SemilatticeInf.toPartialOrder.{0} Nat (Lattice.toSemilatticeInf.{0} Nat (DistribLattice.toLattice.{0} Nat (instDistribLattice.{0} Nat Nat.linearOrder)))))) j (HSub.hSub.{0, 0, 0} Nat Nat Nat (instHSub.{0} Nat instSubNat) (List.length.{u1} α L) i)) (LT.lt.{0} Nat (Preorder.toLT.{0} Nat (PartialOrder.toPreorder.{0} Nat (SemilatticeInf.toPartialOrder.{0} Nat (Lattice.toSemilatticeInf.{0} Nat (DistribLattice.toLattice.{0} Nat (instDistribLattice.{0} Nat Nat.linearOrder)))))) (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat (AddSemigroup.toAdd.{0} Nat (AddCommSemigroup.toAddSemigroup.{0} Nat Nat.addCommSemigroup))) i j) (List.length.{u1} α L)) (lt_tsub_iff_left.{0} Nat j (List.length.{u1} α L) i Nat.linearOrder Nat.addCommSemigroup instSubNat Nat.instOrderedSubNatInstLENatInstAddNatInstSubNat) (Eq.rec.{0, 1} Nat (List.length.{u1} α (List.drop.{u1} α i L)) (fun (x._@.Mathlib.Data.List.Basic._hyg.24309 : Nat) (h._@.Mathlib.Data.List.Basic._hyg.24310 : Eq.{1} Nat (List.length.{u1} α (List.drop.{u1} α i L)) x._@.Mathlib.Data.List.Basic._hyg.24309) => LT.lt.{0} Nat (Preorder.toLT.{0} Nat (PartialOrder.toPreorder.{0} Nat (SemilatticeInf.toPartialOrder.{0} Nat (Lattice.toSemilatticeInf.{0} Nat (DistribLattice.toLattice.{0} Nat (instDistribLattice.{0} Nat Nat.linearOrder)))))) j x._@.Mathlib.Data.List.Basic._hyg.24309) h (HSub.hSub.{0, 0, 0} Nat Nat Nat (instHSub.{0} Nat instSubNat) (List.length.{u1} α L) i) (List.length_drop.{u1} α i L))))
+  forall {α : Type.{u1}} (L : List.{u1} α) {i : Nat} {j : Nat} (h : LT.lt.{0} Nat instLTNat j (List.length.{u1} α (List.drop.{u1} α i L))), Eq.{succ u1} α (List.nthLe.{u1} α (List.drop.{u1} α i L) j h) (List.nthLe.{u1} α L (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat instAddNat) i j) (Iff.mp (LT.lt.{0} Nat (Preorder.toLT.{0} Nat (PartialOrder.toPreorder.{0} Nat (SemilatticeInf.toPartialOrder.{0} Nat (Lattice.toSemilatticeInf.{0} Nat (DistribLattice.toLattice.{0} Nat (instDistribLattice.{0} Nat Nat.linearOrder)))))) j (HSub.hSub.{0, 0, 0} Nat Nat Nat (instHSub.{0} Nat instSubNat) (List.length.{u1} α L) i)) (LT.lt.{0} Nat (Preorder.toLT.{0} Nat (PartialOrder.toPreorder.{0} Nat (SemilatticeInf.toPartialOrder.{0} Nat (Lattice.toSemilatticeInf.{0} Nat (DistribLattice.toLattice.{0} Nat (instDistribLattice.{0} Nat Nat.linearOrder)))))) (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat (AddSemigroup.toAdd.{0} Nat (AddCommSemigroup.toAddSemigroup.{0} Nat Nat.addCommSemigroup))) i j) (List.length.{u1} α L)) (lt_tsub_iff_left.{0} Nat j (List.length.{u1} α L) i Nat.linearOrder Nat.addCommSemigroup instSubNat Nat.instOrderedSubNatInstLENatInstAddNatInstSubNat) (Eq.rec.{0, 1} Nat (List.length.{u1} α (List.drop.{u1} α i L)) (fun (x._@.Mathlib.Data.List.Basic._hyg.24310 : Nat) (h._@.Mathlib.Data.List.Basic._hyg.24311 : Eq.{1} Nat (List.length.{u1} α (List.drop.{u1} α i L)) x._@.Mathlib.Data.List.Basic._hyg.24310) => LT.lt.{0} Nat (Preorder.toLT.{0} Nat (PartialOrder.toPreorder.{0} Nat (SemilatticeInf.toPartialOrder.{0} Nat (Lattice.toSemilatticeInf.{0} Nat (DistribLattice.toLattice.{0} Nat (instDistribLattice.{0} Nat Nat.linearOrder)))))) j x._@.Mathlib.Data.List.Basic._hyg.24310) h (HSub.hSub.{0, 0, 0} Nat Nat Nat (instHSub.{0} Nat instSubNat) (List.length.{u1} α L) i) (List.length_drop.{u1} α i L))))
 Case conversion may be inaccurate. Consider using '#align list.nth_le_drop' List.nthLe_drop'ₓ'. -/
 /-- The `i + j`-th element of a list coincides with the `j`-th element of the list obtained by
 dropping the first `i` elements. Version designed to rewrite from the small list to the big list. -/
@@ -3910,7 +3910,7 @@ but is expected to have type
 Case conversion may be inaccurate. Consider using '#align list.foldl_reverse List.foldl_reverseₓ'. -/
 theorem foldl_reverse (f : α → β → α) (a : α) (l : List β) :
     foldl f a (reverse l) = foldr (fun x y => f y x) a l := by
-  induction l <;> [rfl, simp only [*, reverse_cons, foldl_append, foldl_cons, foldl_nil, foldr]]
+  induction l <;> [rfl;simp only [*, reverse_cons, foldl_append, foldl_cons, foldl_nil, foldr]]
 #align list.foldl_reverse List.foldl_reverse
 
 /- warning: list.foldr_reverse -> List.foldr_reverse is a dubious translation:
@@ -3950,7 +3950,7 @@ Case conversion may be inaccurate. Consider using '#align list.foldl_map List.fo
 @[simp]
 theorem foldl_map (g : β → γ) (f : α → γ → α) (a : α) (l : List β) :
     foldl f a (map g l) = foldl (fun x y => f x (g y)) a l := by
-  revert a <;> induction l <;> intros <;> [rfl, simp only [*, map, foldl]]
+  revert a <;> induction l <;> intros <;> [rfl;simp only [*, map, foldl]]
 #align list.foldl_map List.foldl_map
 
 /- warning: list.foldr_map -> List.foldr_map is a dubious translation:
@@ -3962,7 +3962,7 @@ Case conversion may be inaccurate. Consider using '#align list.foldr_map List.fo
 @[simp]
 theorem foldr_map (g : β → γ) (f : γ → α → α) (a : α) (l : List β) :
     foldr f a (map g l) = foldr (f ∘ g) a l := by
-  revert a <;> induction l <;> intros <;> [rfl, simp only [*, map, foldr]]
+  revert a <;> induction l <;> intros <;> [rfl;simp only [*, map, foldr]]
 #align list.foldr_map List.foldr_map
 
 #print List.foldl_map' /-
@@ -3995,7 +3995,7 @@ theorem foldl_hom (l : List γ) (f : α → β) (op : α → γ → α) (op' : 
     (h : ∀ a x, f (op a x) = op' (f a) x) : foldl op' (f a) l = f (foldl op a l) :=
   Eq.symm <| by
     revert a
-    induction l <;> intros <;> [rfl, simp only [*, foldl]]
+    induction l <;> intros <;> [rfl;simp only [*, foldl]]
 #align list.foldl_hom List.foldl_hom
 
 /- warning: list.foldr_hom -> List.foldr_hom is a dubious translation:
@@ -4008,7 +4008,7 @@ theorem foldr_hom (l : List γ) (f : α → β) (op : γ → α → α) (op' : 
     (h : ∀ x a, f (op x a) = op' x (f a)) : foldr op' (f a) l = f (foldr op a l) :=
   by
   revert a
-  induction l <;> intros <;> [rfl, simp only [*, foldr]]
+  induction l <;> intros <;> [rfl;simp only [*, foldr]]
 #align list.foldr_hom List.foldr_hom
 
 /- warning: list.foldl_hom₂ -> List.foldl_hom₂ is a dubious translation:
@@ -4022,7 +4022,7 @@ theorem foldl_hom₂ (l : List ι) (f : α → β → γ) (op₁ : α → ι →
     foldl op₃ (f a b) l = f (foldl op₁ a l) (foldl op₂ b l) :=
   Eq.symm <| by
     revert a b
-    induction l <;> intros <;> [rfl, simp only [*, foldl]]
+    induction l <;> intros <;> [rfl;simp only [*, foldl]]
 #align list.foldl_hom₂ List.foldl_hom₂
 
 /- warning: list.foldr_hom₂ -> List.foldr_hom₂ is a dubious translation:
@@ -4036,7 +4036,7 @@ theorem foldr_hom₂ (l : List ι) (f : α → β → γ) (op₁ : ι → α →
     foldr op₃ (f a b) l = f (foldr op₁ a l) (foldr op₂ b l) :=
   by
   revert a
-  induction l <;> intros <;> [rfl, simp only [*, foldr]]
+  induction l <;> intros <;> [rfl;simp only [*, foldr]]
 #align list.foldr_hom₂ List.foldr_hom₂
 
 #print List.injective_foldl_comp /-
@@ -4732,7 +4732,7 @@ theorem sizeOf_lt_sizeOf_of_mem [SizeOf α] {x : α} {l : List α} (hx : x ∈ l
 @[simp]
 theorem pmap_eq_map (p : α → Prop) (f : α → β) (l : List α) (H) :
     @pmap _ _ p (fun a _ => f a) l H = map f l := by
-  induction l <;> [rfl, simp only [*, pmap, map]] <;> constructor <;> rfl
+  induction l <;> [rfl;simp only [*, pmap, map]] <;> constructor <;> rfl
 #align list.pmap_eq_map List.pmap_eq_map
 -/
 
@@ -4749,14 +4749,14 @@ theorem pmap_congr {p q : α → Prop} {f : ∀ a, p a → β} {g : ∀ a, q a 
 #print List.map_pmap /-
 theorem map_pmap {p : α → Prop} (g : β → γ) (f : ∀ a, p a → β) (l H) :
     map g (pmap f l H) = pmap (fun a h => g (f a h)) l H := by
-  induction l <;> [rfl, simp only [*, pmap, map]] <;> constructor <;> rfl
+  induction l <;> [rfl;simp only [*, pmap, map]] <;> constructor <;> rfl
 #align list.map_pmap List.map_pmap
 -/
 
 #print List.pmap_map /-
 theorem pmap_map {p : β → Prop} (g : ∀ b, p b → γ) (f : α → β) (l H) :
     pmap g (map f l) H = pmap (fun a h => g (f a) h) l fun a h => H _ (mem_map_of_mem _ h) := by
-  induction l <;> [rfl, simp only [*, pmap, map]] <;> constructor <;> rfl
+  induction l <;> [rfl;simp only [*, pmap, map]] <;> constructor <;> rfl
 #align list.pmap_map List.pmap_map
 -/
 
@@ -4816,7 +4816,7 @@ theorem mem_pmap {p : α → Prop} {f : ∀ a, p a → β} {l H b} :
 #print List.length_pmap /-
 @[simp]
 theorem length_pmap {p : α → Prop} {f : ∀ a, p a → β} {l H} : length (pmap f l H) = length l := by
-  induction l <;> [rfl, simp only [*, pmap, length]]
+  induction l <;> [rfl;simp only [*, pmap, length]]
 #align list.length_pmap List.length_pmap
 -/
 
@@ -5178,7 +5178,7 @@ theorem filterMap_eq_map (f : α → β) : filterMap (some ∘ f) = map f :=
 lean 3 declaration is
   forall {α : Type.{u1}} (p : α -> Prop) [_inst_1 : DecidablePred.{succ u1} α p], Eq.{succ u1} ((List.{u1} α) -> (List.{u1} α)) (List.filterMap.{u1, u1} α α (Option.guard.{u1} α p (fun (a : α) => _inst_1 a))) (List.filterₓ.{u1} α p (fun (a : α) => _inst_1 a))
 but is expected to have type
-  forall {α : Type.{u1}} (p : α -> Bool), Eq.{succ u1} ((List.{u1} α) -> (List.{u1} α)) (List.filterMap.{u1, u1} α α (Option.guard.{u1} α (fun (x._@.Std.Data.List.Lemmas._hyg.24165 : α) => Eq.{1} Bool (p x._@.Std.Data.List.Lemmas._hyg.24165) Bool.true) (fun (a : α) => instDecidableEqBool (p a) Bool.true))) (List.filter.{u1} α p)
+  forall {α : Type.{u1}} (p : α -> Bool), Eq.{succ u1} ((List.{u1} α) -> (List.{u1} α)) (List.filterMap.{u1, u1} α α (Option.guard.{u1} α (fun (x._@.Std.Data.List.Lemmas._hyg.24241 : α) => Eq.{1} Bool (p x._@.Std.Data.List.Lemmas._hyg.24241) Bool.true) (fun (a : α) => instDecidableEqBool (p a) Bool.true))) (List.filter.{u1} α p)
 Case conversion may be inaccurate. Consider using '#align list.filter_map_eq_filter List.filterMap_eq_filterₓ'. -/
 theorem filterMap_eq_filter (p : α → Prop) [DecidablePred p] :
     filterMap (Option.guard p) = filter p := by
@@ -5204,8 +5204,9 @@ theorem filterMap_filterMap (f : α → Option β) (g : β → Option γ) (l : L
   · rw [filter_map_cons_none _ _ h, filter_map_cons_none, IH]
     simp only [h, Option.none_bind']
   rw [filter_map_cons_some _ _ _ h]
-  cases' h' : g b with c <;> [rw [filter_map_cons_none _ _ h', filter_map_cons_none, IH],
-      rw [filter_map_cons_some _ _ _ h', filter_map_cons_some, IH]] <;>
+  cases' h' : g b with c <;>
+      [rw [filter_map_cons_none _ _ h', filter_map_cons_none,
+        IH];rw [filter_map_cons_some _ _ _ h', filter_map_cons_some, IH]] <;>
     simp only [h, h', Option.some_bind']
 #align list.filter_map_filter_map List.filterMap_filterMap
 
@@ -5535,8 +5536,9 @@ theorem filter_congr' {p q : α → Prop} [DecidablePred p] [DecidablePred q] :
   | [], _ => rfl
   | a :: l, h => by
     rw [forall_mem_cons] at h <;> by_cases pa : p a <;>
-          [simp only [filter_cons_of_pos _ pa, filter_cons_of_pos _ (h.1.1 pa), filter_congr' h.2],
-          simp only [filter_cons_of_neg _ pa, filter_cons_of_neg _ (mt h.1.2 pa),
+          [simp only [filter_cons_of_pos _ pa, filter_cons_of_pos _ (h.1.1 pa),
+            filter_congr'
+              h.2];simp only [filter_cons_of_neg _ pa, filter_cons_of_neg _ (mt h.1.2 pa),
             filter_congr' h.2]] <;>
         constructor <;>
       rfl
@@ -5717,7 +5719,7 @@ theorem filter_filter (q) [DecidablePred q] :
 lean 3 declaration is
   forall {α : Type.{u1}} {h : DecidablePred.{succ u1} α (fun (a : α) => True)} (l : List.{u1} α), Eq.{succ u1} (List.{u1} α) (List.filterₓ.{u1} α (fun (_x : α) => True) h l) l
 but is expected to have type
-  forall {α : Type.{u1}} (h : List.{u1} α), Eq.{succ u1} (List.{u1} α) (List.filter.{u1} α (fun (x._@.Mathlib.Data.List.Basic._hyg.41375 : α) => Bool.true) h) h
+  forall {α : Type.{u1}} (h : List.{u1} α), Eq.{succ u1} (List.{u1} α) (List.filter.{u1} α (fun (x._@.Mathlib.Data.List.Basic._hyg.40772 : α) => Bool.true) h) h
 Case conversion may be inaccurate. Consider using '#align list.filter_true List.filter_trueₓ'. -/
 @[simp]
 theorem filter_true {h : DecidablePred fun a : α => True} (l : List α) :
@@ -5728,7 +5730,7 @@ theorem filter_true {h : DecidablePred fun a : α => True} (l : List α) :
 lean 3 declaration is
   forall {α : Type.{u1}} {h : DecidablePred.{succ u1} α (fun (a : α) => False)} (l : List.{u1} α), Eq.{succ u1} (List.{u1} α) (List.filterₓ.{u1} α (fun (_x : α) => False) h l) (List.nil.{u1} α)
 but is expected to have type
-  forall {α : Type.{u1}} (h : List.{u1} α), Eq.{succ u1} (List.{u1} α) (List.filter.{u1} α (fun (x._@.Mathlib.Data.List.Basic._hyg.41425 : α) => Bool.false) h) (List.nil.{u1} α)
+  forall {α : Type.{u1}} (h : List.{u1} α), Eq.{succ u1} (List.{u1} α) (List.filter.{u1} α (fun (x._@.Mathlib.Data.List.Basic._hyg.40822 : α) => Bool.false) h) (List.nil.{u1} α)
 Case conversion may be inaccurate. Consider using '#align list.filter_false List.filter_falseₓ'. -/
 @[simp]
 theorem filter_false {h : DecidablePred fun a : α => False} (l : List α) :
@@ -5749,20 +5751,20 @@ theorem span_eq_take_drop : ∀ l : List α, span p l = (takeWhile p l, dropWhil
     else by simp only [span, take_while, drop_while, if_neg pa]
 #align list.span_eq_take_drop List.span_eq_take_drop
 
-/- warning: list.take_while_append_drop -> List.takeWhile_append_drop is a dubious translation:
+/- warning: list.take_while_append_drop -> List.takeWhile_append_dropWhile is a dubious translation:
 lean 3 declaration is
   forall {α : Type.{u1}} (p : α -> Prop) [_inst_1 : DecidablePred.{succ u1} α p] (l : List.{u1} α), Eq.{succ u1} (List.{u1} α) (Append.append.{u1} (List.{u1} α) (List.hasAppend.{u1} α) (List.takeWhile.{u1} α p (fun (a : α) => _inst_1 a) l) (List.dropWhileₓ.{u1} α p (fun (a : α) => _inst_1 a) l)) l
 but is expected to have type
   forall {α : Type.{u1}} (p : α -> Bool) (_inst_1 : List.{u1} α), Eq.{succ u1} (List.{u1} α) (HAppend.hAppend.{u1, u1, u1} (List.{u1} α) (List.{u1} α) (List.{u1} α) (instHAppend.{u1} (List.{u1} α) (List.instAppendList.{u1} α)) (List.takeWhile.{u1} α p _inst_1) (List.dropWhile.{u1} α p _inst_1)) _inst_1
-Case conversion may be inaccurate. Consider using '#align list.take_while_append_drop List.takeWhile_append_dropₓ'. -/
+Case conversion may be inaccurate. Consider using '#align list.take_while_append_drop List.takeWhile_append_dropWhileₓ'. -/
 @[simp]
-theorem takeWhile_append_drop : ∀ l : List α, takeWhile p l ++ dropWhile p l = l
+theorem takeWhile_append_dropWhile : ∀ l : List α, takeWhile p l ++ dropWhile p l = l
   | [] => rfl
   | a :: l =>
     if pa : p a then by
       rw [take_while, drop_while, if_pos pa, if_pos pa, cons_append, take_while_append_drop l]
     else by rw [take_while, drop_while, if_neg pa, if_neg pa, nil_append]
-#align list.take_while_append_drop List.takeWhile_append_drop
+#align list.take_while_append_drop List.takeWhile_append_dropWhile
 
 /- warning: list.drop_while_nth_le_zero_not -> List.dropWhile_nthLe_zero_not is a dubious translation:
 lean 3 declaration is
@@ -5898,7 +5900,7 @@ theorem eraseP_cons_of_neg {a : α} {l : List α} (h : ¬p a) :
 #align list.erasep_cons_of_neg List.eraseP_cons_of_negₓ
 
 theorem eraseP_of_forall_not {l : List α} (h : ∀ a ∈ l, ¬p a) : l.erasePₓ p = l := by
-  induction' l with _ _ ih <;> [rfl, simp [h _ (Or.inl rfl), ih (forall_mem_of_forall_mem_cons h)]]
+  induction' l with _ _ ih <;> [rfl;simp [h _ (Or.inl rfl), ih (forall_mem_of_forall_mem_cons h)]]
 #align list.erasep_of_forall_not List.eraseP_of_forall_notₓ
 
 theorem exists_of_eraseP {l : List α} {a} (al : a ∈ l) (pa : p a) :
@@ -5957,8 +5959,9 @@ theorem eraseP_append_right :
 #align list.erasep_append_right List.eraseP_append_rightₓ
 
 theorem eraseP_sublist (l : List α) : l.erasePₓ p <+ l := by
-  rcases exists_or_eq_self_of_erasep p l with (h | ⟨c, l₁, l₂, h₁, h₂, h₃, h₄⟩) <;> [rw [h],
-    · rw [h₄, h₃]
+  rcases exists_or_eq_self_of_erasep p l with (h | ⟨c, l₁, l₂, h₁, h₂, h₃, h₄⟩) <;>
+    [rw [h];·
+      rw [h₄, h₃]
       simp]
 #align list.erasep_sublist List.eraseP_sublistₓ
 
@@ -6042,7 +6045,7 @@ theorem erase_eq_eraseP (a : α) (l : List α) : l.eraseₓ a = l.erasePₓ (Eq
   by
   induction' l with b l
   · rfl
-  by_cases a = b <;> [simp [h], simp [h, Ne.symm h, *]]
+  by_cases a = b <;> [simp [h];simp [h, Ne.symm h, *]]
 #align list.erase_eq_erasep List.erase_eq_erasePₓ
 
 @[simp]
@@ -6136,7 +6139,7 @@ but is expected to have type
 Case conversion may be inaccurate. Consider using '#align list.map_foldl_erase List.map_foldl_eraseₓ'. -/
 theorem map_foldl_erase [DecidableEq β] {f : α → β} (finj : Injective f) {l₁ l₂ : List α} :
     map f (foldl List.erase l₁ l₂) = foldl (fun l a => l.eraseₓ (f a)) (map f l₁) l₂ := by
-  induction l₂ generalizing l₁ <;> [rfl, simp only [foldl_cons, map_erase finj, *]]
+  induction l₂ generalizing l₁ <;> [rfl;simp only [foldl_cons, map_erase finj, *]]
 #align list.map_foldl_erase List.map_foldl_erase
 
 end Erase
@@ -6198,7 +6201,7 @@ but is expected to have type
 Case conversion may be inaccurate. Consider using '#align list.nil_diff List.nil_diffₓ'. -/
 @[simp]
 theorem nil_diff (l : List α) : [].diffₓ l = [] := by
-  induction l <;> [rfl, simp only [*, diff_cons, erase_of_not_mem (not_mem_nil _)]]
+  induction l <;> [rfl;simp only [*, diff_cons, erase_of_not_mem (not_mem_nil _)]]
 #align list.nil_diff List.nil_diff
 
 /- warning: list.cons_diff -> List.cons_diff is a dubious translation:
@@ -6955,8 +6958,8 @@ Case conversion may be inaccurate. Consider using '#align list.to_chunks_aux_joi
 theorem [anonymous] {n} : ∀ {xs i l L}, @toChunksAux α n xs i = (l, L) → l ++ L.join = xs
   | [], _, _, _, rfl => rfl
   | x :: xs, i, l, L, e => by
-    cases i <;> [cases' e' : to_chunks_aux n xs n with l L,
-        cases' e' : to_chunks_aux n xs i with l L] <;>
+    cases i <;>
+        [cases' e' : to_chunks_aux n xs n with l L;cases' e' : to_chunks_aux n xs i with l L] <;>
       · rw [to_chunks_aux, e', to_chunks_aux] at e
         cases e
         exact (congr_arg (cons x) (to_chunks_aux_join e') : _)
@@ -7272,7 +7275,7 @@ theorem getD_default_eq_getI : l.getD n default = l.getI n :=
 lean 3 declaration is
   forall {α : Type.{u1}} [_inst_1 : Inhabited.{succ u1} α] (l : List.{u1} α) (l' : List.{u1} α) (n : Nat) (h : LT.lt.{0} Nat Nat.hasLt n (List.length.{u1} α l)), (optParam.{0} (LT.lt.{0} Nat (Preorder.toHasLt.{0} Nat (PartialOrder.toPreorder.{0} Nat (OrderedCancelAddCommMonoid.toPartialOrder.{0} Nat (StrictOrderedSemiring.toOrderedCancelAddCommMonoid.{0} Nat Nat.strictOrderedSemiring)))) n (List.length.{u1} α (Append.append.{u1} (List.{u1} α) (List.hasAppend.{u1} α) l l'))) (LT.lt.trans_le.{0} Nat (PartialOrder.toPreorder.{0} Nat (OrderedCancelAddCommMonoid.toPartialOrder.{0} Nat (StrictOrderedSemiring.toOrderedCancelAddCommMonoid.{0} Nat Nat.strictOrderedSemiring))) n (List.length.{u1} α l) (List.length.{u1} α (Append.append.{u1} (List.{u1} α) (List.hasAppend.{u1} α) l l')) h (Eq.subst.{1} Nat (fun (_x : Nat) => LE.le.{0} Nat (Preorder.toHasLe.{0} Nat (PartialOrder.toPreorder.{0} Nat (OrderedCancelAddCommMonoid.toPartialOrder.{0} Nat (StrictOrderedSemiring.toOrderedCancelAddCommMonoid.{0} Nat Nat.strictOrderedSemiring)))) (List.length.{u1} α l) _x) (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat Nat.hasAdd) (List.length.{u1} α l) (List.length.{u1} α l')) (List.length.{u1} α (Append.append.{u1} (List.{u1} α) (List.hasAppend.{u1} α) l l')) (Eq.symm.{1} Nat (List.length.{u1} α (Append.append.{u1} (List.{u1} α) (List.hasAppend.{u1} α) l l')) (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat Nat.hasAdd) (List.length.{u1} α l) (List.length.{u1} α l')) (List.length_append.{u1} α l l')) (le_self_add.{0} Nat (CanonicallyOrderedCommSemiring.toCanonicallyOrderedAddMonoid.{0} Nat Nat.canonicallyOrderedCommSemiring) (List.length.{u1} α l) (List.length.{u1} α l'))))) -> (Eq.{succ u1} α (List.getI.{u1} α _inst_1 (Append.append.{u1} (List.{u1} α) (List.hasAppend.{u1} α) l l') n) (List.getI.{u1} α _inst_1 l n))
 but is expected to have type
-  forall {α : Type.{u1}} [_inst_1 : Inhabited.{succ u1} α] (l : List.{u1} α) (l' : List.{u1} α) (n : Nat) (h : LT.lt.{0} Nat instLTNat n (List.length.{u1} α l)), (optParam.{0} (LT.lt.{0} Nat instLTNat n (List.length.{u1} α (HAppend.hAppend.{u1, u1, u1} (List.{u1} α) (List.{u1} α) (List.{u1} α) (instHAppend.{u1} (List.{u1} α) (List.instAppendList.{u1} α)) l l'))) (LT.lt.trans_le.{0} Nat (PartialOrder.toPreorder.{0} Nat (StrictOrderedSemiring.toPartialOrder.{0} Nat Nat.strictOrderedSemiring)) n (List.length.{u1} α l) (List.length.{u1} α (HAppend.hAppend.{u1, u1, u1} (List.{u1} α) (List.{u1} α) (List.{u1} α) (instHAppend.{u1} (List.{u1} α) (List.instAppendList.{u1} α)) l l')) h (Eq.rec.{0, 1} Nat (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat instAddNat) (List.length.{u1} α l) (List.length.{u1} α l')) (fun (x._@.Mathlib.Data.List.Basic._hyg.50174 : Nat) (h._@.Mathlib.Data.List.Basic._hyg.50175 : Eq.{1} Nat (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat instAddNat) (List.length.{u1} α l) (List.length.{u1} α l')) x._@.Mathlib.Data.List.Basic._hyg.50174) => LE.le.{0} Nat (Preorder.toLE.{0} Nat (PartialOrder.toPreorder.{0} Nat (StrictOrderedSemiring.toPartialOrder.{0} Nat Nat.strictOrderedSemiring))) (List.length.{u1} α l) x._@.Mathlib.Data.List.Basic._hyg.50174) (le_self_add.{0} Nat (CanonicallyOrderedCommSemiring.toCanonicallyOrderedAddMonoid.{0} Nat Nat.canonicallyOrderedCommSemiring) (List.length.{u1} α l) (List.length.{u1} α l')) (List.length.{u1} α (HAppend.hAppend.{u1, u1, u1} (List.{u1} α) (List.{u1} α) (List.{u1} α) (instHAppend.{u1} (List.{u1} α) (List.instAppendList.{u1} α)) l l')) (Eq.symm.{1} Nat (List.length.{u1} α (HAppend.hAppend.{u1, u1, u1} (List.{u1} α) (List.{u1} α) (List.{u1} α) (instHAppend.{u1} (List.{u1} α) (List.instAppendList.{u1} α)) l l')) (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat instAddNat) (List.length.{u1} α l) (List.length.{u1} α l')) (List.length_append.{u1} α l l'))))) -> (Eq.{succ u1} α (List.getI.{u1} α _inst_1 (HAppend.hAppend.{u1, u1, u1} (List.{u1} α) (List.{u1} α) (List.{u1} α) (instHAppend.{u1} (List.{u1} α) (List.instAppendList.{u1} α)) l l') n) (List.getI.{u1} α _inst_1 l n))
+  forall {α : Type.{u1}} [_inst_1 : Inhabited.{succ u1} α] (l : List.{u1} α) (l' : List.{u1} α) (n : Nat) (h : LT.lt.{0} Nat instLTNat n (List.length.{u1} α l)), (optParam.{0} (LT.lt.{0} Nat instLTNat n (List.length.{u1} α (HAppend.hAppend.{u1, u1, u1} (List.{u1} α) (List.{u1} α) (List.{u1} α) (instHAppend.{u1} (List.{u1} α) (List.instAppendList.{u1} α)) l l'))) (LT.lt.trans_le.{0} Nat (PartialOrder.toPreorder.{0} Nat (StrictOrderedSemiring.toPartialOrder.{0} Nat Nat.strictOrderedSemiring)) n (List.length.{u1} α l) (List.length.{u1} α (HAppend.hAppend.{u1, u1, u1} (List.{u1} α) (List.{u1} α) (List.{u1} α) (instHAppend.{u1} (List.{u1} α) (List.instAppendList.{u1} α)) l l')) h (Eq.rec.{0, 1} Nat (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat instAddNat) (List.length.{u1} α l) (List.length.{u1} α l')) (fun (x._@.Mathlib.Data.List.Basic._hyg.49479 : Nat) (h._@.Mathlib.Data.List.Basic._hyg.49480 : Eq.{1} Nat (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat instAddNat) (List.length.{u1} α l) (List.length.{u1} α l')) x._@.Mathlib.Data.List.Basic._hyg.49479) => LE.le.{0} Nat (Preorder.toLE.{0} Nat (PartialOrder.toPreorder.{0} Nat (StrictOrderedSemiring.toPartialOrder.{0} Nat Nat.strictOrderedSemiring))) (List.length.{u1} α l) x._@.Mathlib.Data.List.Basic._hyg.49479) (le_self_add.{0} Nat (CanonicallyOrderedCommSemiring.toCanonicallyOrderedAddMonoid.{0} Nat Nat.canonicallyOrderedCommSemiring) (List.length.{u1} α l) (List.length.{u1} α l')) (List.length.{u1} α (HAppend.hAppend.{u1, u1, u1} (List.{u1} α) (List.{u1} α) (List.{u1} α) (instHAppend.{u1} (List.{u1} α) (List.instAppendList.{u1} α)) l l')) (Eq.symm.{1} Nat (List.length.{u1} α (HAppend.hAppend.{u1, u1, u1} (List.{u1} α) (List.{u1} α) (List.{u1} α) (instHAppend.{u1} (List.{u1} α) (List.instAppendList.{u1} α)) l l')) (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat instAddNat) (List.length.{u1} α l) (List.length.{u1} α l')) (List.length_append.{u1} α l l'))))) -> (Eq.{succ u1} α (List.getI.{u1} α _inst_1 (HAppend.hAppend.{u1, u1, u1} (List.{u1} α) (List.{u1} α) (List.{u1} α) (instHAppend.{u1} (List.{u1} α) (List.instAppendList.{u1} α)) l l') n) (List.getI.{u1} α _inst_1 l n))
 Case conversion may be inaccurate. Consider using '#align list.inth_append List.getI_appendₓ'. -/
 theorem getI_append (l l' : List α) (n : ℕ) (h : n < l.length)
     (h' : n < (l ++ l').length := h.trans_le ((length_append l l').symm ▸ le_self_add)) :
Diff
@@ -3621,7 +3621,7 @@ theorem nthLe_drop (L : List α) {i j : ℕ} (h : i + j < L.length) :
 lean 3 declaration is
   forall {α : Type.{u1}} (L : List.{u1} α) {i : Nat} {j : Nat} (h : LT.lt.{0} Nat Nat.hasLt j (List.length.{u1} α (List.drop.{u1} α i L))), Eq.{succ u1} α (List.nthLe.{u1} α (List.drop.{u1} α i L) j h) (List.nthLe.{u1} α L (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat Nat.hasAdd) i j) (Iff.mp (LT.lt.{0} Nat (Preorder.toHasLt.{0} Nat (PartialOrder.toPreorder.{0} Nat (SemilatticeInf.toPartialOrder.{0} Nat (Lattice.toSemilatticeInf.{0} Nat (LinearOrder.toLattice.{0} Nat Nat.linearOrder))))) j (HSub.hSub.{0, 0, 0} Nat Nat Nat (instHSub.{0} Nat Nat.hasSub) (List.length.{u1} α L) i)) (LT.lt.{0} Nat (Preorder.toHasLt.{0} Nat (PartialOrder.toPreorder.{0} Nat (SemilatticeInf.toPartialOrder.{0} Nat (Lattice.toSemilatticeInf.{0} Nat (LinearOrder.toLattice.{0} Nat Nat.linearOrder))))) (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat (AddSemigroup.toHasAdd.{0} Nat (AddCommSemigroup.toAddSemigroup.{0} Nat Nat.addCommSemigroup))) i j) (List.length.{u1} α L)) (lt_tsub_iff_left.{0} Nat j (List.length.{u1} α L) i Nat.linearOrder Nat.addCommSemigroup Nat.hasSub Nat.orderedSub) (Eq.subst.{1} Nat (fun (_x : Nat) => LT.lt.{0} Nat (Preorder.toHasLt.{0} Nat (PartialOrder.toPreorder.{0} Nat (SemilatticeInf.toPartialOrder.{0} Nat (Lattice.toSemilatticeInf.{0} Nat (LinearOrder.toLattice.{0} Nat Nat.linearOrder))))) j _x) (List.length.{u1} α (List.drop.{u1} α i L)) (HSub.hSub.{0, 0, 0} Nat Nat Nat (instHSub.{0} Nat Nat.hasSub) (List.length.{u1} α L) i) (List.length_drop.{u1} α i L) h)))
 but is expected to have type
-  forall {α : Type.{u1}} (L : List.{u1} α) {i : Nat} {j : Nat} (h : LT.lt.{0} Nat instLTNat j (List.length.{u1} α (List.drop.{u1} α i L))), Eq.{succ u1} α (List.nthLe.{u1} α (List.drop.{u1} α i L) j h) (List.nthLe.{u1} α L (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat instAddNat) i j) (Iff.mp (LT.lt.{0} Nat (Preorder.toLT.{0} Nat (PartialOrder.toPreorder.{0} Nat (SemilatticeInf.toPartialOrder.{0} Nat (Lattice.toSemilatticeInf.{0} Nat (DistribLattice.toLattice.{0} Nat (instDistribLattice.{0} Nat Nat.linearOrder)))))) j (HSub.hSub.{0, 0, 0} Nat Nat Nat (instHSub.{0} Nat instSubNat) (List.length.{u1} α L) i)) (LT.lt.{0} Nat (Preorder.toLT.{0} Nat (PartialOrder.toPreorder.{0} Nat (SemilatticeInf.toPartialOrder.{0} Nat (Lattice.toSemilatticeInf.{0} Nat (DistribLattice.toLattice.{0} Nat (instDistribLattice.{0} Nat Nat.linearOrder)))))) (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat (AddSemigroup.toAdd.{0} Nat (AddCommSemigroup.toAddSemigroup.{0} Nat Nat.addCommSemigroup))) i j) (List.length.{u1} α L)) (lt_tsub_iff_left.{0} Nat j (List.length.{u1} α L) i Nat.linearOrder Nat.addCommSemigroup instSubNat Nat.instOrderedSubNatInstLENatInstAddNatInstSubNat) (Eq.rec.{0, 1} Nat (List.length.{u1} α (List.drop.{u1} α i L)) (fun (x._@.Mathlib.Data.List.Basic._hyg.24232 : Nat) (h._@.Mathlib.Data.List.Basic._hyg.24233 : Eq.{1} Nat (List.length.{u1} α (List.drop.{u1} α i L)) x._@.Mathlib.Data.List.Basic._hyg.24232) => LT.lt.{0} Nat (Preorder.toLT.{0} Nat (PartialOrder.toPreorder.{0} Nat (SemilatticeInf.toPartialOrder.{0} Nat (Lattice.toSemilatticeInf.{0} Nat (DistribLattice.toLattice.{0} Nat (instDistribLattice.{0} Nat Nat.linearOrder)))))) j x._@.Mathlib.Data.List.Basic._hyg.24232) h (HSub.hSub.{0, 0, 0} Nat Nat Nat (instHSub.{0} Nat instSubNat) (List.length.{u1} α L) i) (List.length_drop.{u1} α i L))))
+  forall {α : Type.{u1}} (L : List.{u1} α) {i : Nat} {j : Nat} (h : LT.lt.{0} Nat instLTNat j (List.length.{u1} α (List.drop.{u1} α i L))), Eq.{succ u1} α (List.nthLe.{u1} α (List.drop.{u1} α i L) j h) (List.nthLe.{u1} α L (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat instAddNat) i j) (Iff.mp (LT.lt.{0} Nat (Preorder.toLT.{0} Nat (PartialOrder.toPreorder.{0} Nat (SemilatticeInf.toPartialOrder.{0} Nat (Lattice.toSemilatticeInf.{0} Nat (DistribLattice.toLattice.{0} Nat (instDistribLattice.{0} Nat Nat.linearOrder)))))) j (HSub.hSub.{0, 0, 0} Nat Nat Nat (instHSub.{0} Nat instSubNat) (List.length.{u1} α L) i)) (LT.lt.{0} Nat (Preorder.toLT.{0} Nat (PartialOrder.toPreorder.{0} Nat (SemilatticeInf.toPartialOrder.{0} Nat (Lattice.toSemilatticeInf.{0} Nat (DistribLattice.toLattice.{0} Nat (instDistribLattice.{0} Nat Nat.linearOrder)))))) (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat (AddSemigroup.toAdd.{0} Nat (AddCommSemigroup.toAddSemigroup.{0} Nat Nat.addCommSemigroup))) i j) (List.length.{u1} α L)) (lt_tsub_iff_left.{0} Nat j (List.length.{u1} α L) i Nat.linearOrder Nat.addCommSemigroup instSubNat Nat.instOrderedSubNatInstLENatInstAddNatInstSubNat) (Eq.rec.{0, 1} Nat (List.length.{u1} α (List.drop.{u1} α i L)) (fun (x._@.Mathlib.Data.List.Basic._hyg.24309 : Nat) (h._@.Mathlib.Data.List.Basic._hyg.24310 : Eq.{1} Nat (List.length.{u1} α (List.drop.{u1} α i L)) x._@.Mathlib.Data.List.Basic._hyg.24309) => LT.lt.{0} Nat (Preorder.toLT.{0} Nat (PartialOrder.toPreorder.{0} Nat (SemilatticeInf.toPartialOrder.{0} Nat (Lattice.toSemilatticeInf.{0} Nat (DistribLattice.toLattice.{0} Nat (instDistribLattice.{0} Nat Nat.linearOrder)))))) j x._@.Mathlib.Data.List.Basic._hyg.24309) h (HSub.hSub.{0, 0, 0} Nat Nat Nat (instHSub.{0} Nat instSubNat) (List.length.{u1} α L) i) (List.length_drop.{u1} α i L))))
 Case conversion may be inaccurate. Consider using '#align list.nth_le_drop' List.nthLe_drop'ₓ'. -/
 /-- The `i + j`-th element of a list coincides with the `j`-th element of the list obtained by
 dropping the first `i` elements. Version designed to rewrite from the small list to the big list. -/
@@ -5717,7 +5717,7 @@ theorem filter_filter (q) [DecidablePred q] :
 lean 3 declaration is
   forall {α : Type.{u1}} {h : DecidablePred.{succ u1} α (fun (a : α) => True)} (l : List.{u1} α), Eq.{succ u1} (List.{u1} α) (List.filterₓ.{u1} α (fun (_x : α) => True) h l) l
 but is expected to have type
-  forall {α : Type.{u1}} (h : List.{u1} α), Eq.{succ u1} (List.{u1} α) (List.filter.{u1} α (fun (x._@.Mathlib.Data.List.Basic._hyg.41262 : α) => Bool.true) h) h
+  forall {α : Type.{u1}} (h : List.{u1} α), Eq.{succ u1} (List.{u1} α) (List.filter.{u1} α (fun (x._@.Mathlib.Data.List.Basic._hyg.41375 : α) => Bool.true) h) h
 Case conversion may be inaccurate. Consider using '#align list.filter_true List.filter_trueₓ'. -/
 @[simp]
 theorem filter_true {h : DecidablePred fun a : α => True} (l : List α) :
@@ -5728,7 +5728,7 @@ theorem filter_true {h : DecidablePred fun a : α => True} (l : List α) :
 lean 3 declaration is
   forall {α : Type.{u1}} {h : DecidablePred.{succ u1} α (fun (a : α) => False)} (l : List.{u1} α), Eq.{succ u1} (List.{u1} α) (List.filterₓ.{u1} α (fun (_x : α) => False) h l) (List.nil.{u1} α)
 but is expected to have type
-  forall {α : Type.{u1}} (h : List.{u1} α), Eq.{succ u1} (List.{u1} α) (List.filter.{u1} α (fun (x._@.Mathlib.Data.List.Basic._hyg.41312 : α) => Bool.false) h) (List.nil.{u1} α)
+  forall {α : Type.{u1}} (h : List.{u1} α), Eq.{succ u1} (List.{u1} α) (List.filter.{u1} α (fun (x._@.Mathlib.Data.List.Basic._hyg.41425 : α) => Bool.false) h) (List.nil.{u1} α)
 Case conversion may be inaccurate. Consider using '#align list.filter_false List.filter_falseₓ'. -/
 @[simp]
 theorem filter_false {h : DecidablePred fun a : α => False} (l : List α) :
@@ -7272,7 +7272,7 @@ theorem getD_default_eq_getI : l.getD n default = l.getI n :=
 lean 3 declaration is
   forall {α : Type.{u1}} [_inst_1 : Inhabited.{succ u1} α] (l : List.{u1} α) (l' : List.{u1} α) (n : Nat) (h : LT.lt.{0} Nat Nat.hasLt n (List.length.{u1} α l)), (optParam.{0} (LT.lt.{0} Nat (Preorder.toHasLt.{0} Nat (PartialOrder.toPreorder.{0} Nat (OrderedCancelAddCommMonoid.toPartialOrder.{0} Nat (StrictOrderedSemiring.toOrderedCancelAddCommMonoid.{0} Nat Nat.strictOrderedSemiring)))) n (List.length.{u1} α (Append.append.{u1} (List.{u1} α) (List.hasAppend.{u1} α) l l'))) (LT.lt.trans_le.{0} Nat (PartialOrder.toPreorder.{0} Nat (OrderedCancelAddCommMonoid.toPartialOrder.{0} Nat (StrictOrderedSemiring.toOrderedCancelAddCommMonoid.{0} Nat Nat.strictOrderedSemiring))) n (List.length.{u1} α l) (List.length.{u1} α (Append.append.{u1} (List.{u1} α) (List.hasAppend.{u1} α) l l')) h (Eq.subst.{1} Nat (fun (_x : Nat) => LE.le.{0} Nat (Preorder.toHasLe.{0} Nat (PartialOrder.toPreorder.{0} Nat (OrderedCancelAddCommMonoid.toPartialOrder.{0} Nat (StrictOrderedSemiring.toOrderedCancelAddCommMonoid.{0} Nat Nat.strictOrderedSemiring)))) (List.length.{u1} α l) _x) (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat Nat.hasAdd) (List.length.{u1} α l) (List.length.{u1} α l')) (List.length.{u1} α (Append.append.{u1} (List.{u1} α) (List.hasAppend.{u1} α) l l')) (Eq.symm.{1} Nat (List.length.{u1} α (Append.append.{u1} (List.{u1} α) (List.hasAppend.{u1} α) l l')) (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat Nat.hasAdd) (List.length.{u1} α l) (List.length.{u1} α l')) (List.length_append.{u1} α l l')) (le_self_add.{0} Nat (CanonicallyOrderedCommSemiring.toCanonicallyOrderedAddMonoid.{0} Nat Nat.canonicallyOrderedCommSemiring) (List.length.{u1} α l) (List.length.{u1} α l'))))) -> (Eq.{succ u1} α (List.getI.{u1} α _inst_1 (Append.append.{u1} (List.{u1} α) (List.hasAppend.{u1} α) l l') n) (List.getI.{u1} α _inst_1 l n))
 but is expected to have type
-  forall {α : Type.{u1}} [_inst_1 : Inhabited.{succ u1} α] (l : List.{u1} α) (l' : List.{u1} α) (n : Nat) (h : LT.lt.{0} Nat instLTNat n (List.length.{u1} α l)), (optParam.{0} (LT.lt.{0} Nat instLTNat n (List.length.{u1} α (HAppend.hAppend.{u1, u1, u1} (List.{u1} α) (List.{u1} α) (List.{u1} α) (instHAppend.{u1} (List.{u1} α) (List.instAppendList.{u1} α)) l l'))) (LT.lt.trans_le.{0} Nat (PartialOrder.toPreorder.{0} Nat (StrictOrderedSemiring.toPartialOrder.{0} Nat Nat.strictOrderedSemiring)) n (List.length.{u1} α l) (List.length.{u1} α (HAppend.hAppend.{u1, u1, u1} (List.{u1} α) (List.{u1} α) (List.{u1} α) (instHAppend.{u1} (List.{u1} α) (List.instAppendList.{u1} α)) l l')) h (Eq.rec.{0, 1} Nat (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat instAddNat) (List.length.{u1} α l) (List.length.{u1} α l')) (fun (x._@.Mathlib.Data.List.Basic._hyg.50042 : Nat) (h._@.Mathlib.Data.List.Basic._hyg.50043 : Eq.{1} Nat (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat instAddNat) (List.length.{u1} α l) (List.length.{u1} α l')) x._@.Mathlib.Data.List.Basic._hyg.50042) => LE.le.{0} Nat (Preorder.toLE.{0} Nat (PartialOrder.toPreorder.{0} Nat (StrictOrderedSemiring.toPartialOrder.{0} Nat Nat.strictOrderedSemiring))) (List.length.{u1} α l) x._@.Mathlib.Data.List.Basic._hyg.50042) (le_self_add.{0} Nat (CanonicallyOrderedCommSemiring.toCanonicallyOrderedAddMonoid.{0} Nat Nat.canonicallyOrderedCommSemiring) (List.length.{u1} α l) (List.length.{u1} α l')) (List.length.{u1} α (HAppend.hAppend.{u1, u1, u1} (List.{u1} α) (List.{u1} α) (List.{u1} α) (instHAppend.{u1} (List.{u1} α) (List.instAppendList.{u1} α)) l l')) (Eq.symm.{1} Nat (List.length.{u1} α (HAppend.hAppend.{u1, u1, u1} (List.{u1} α) (List.{u1} α) (List.{u1} α) (instHAppend.{u1} (List.{u1} α) (List.instAppendList.{u1} α)) l l')) (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat instAddNat) (List.length.{u1} α l) (List.length.{u1} α l')) (List.length_append.{u1} α l l'))))) -> (Eq.{succ u1} α (List.getI.{u1} α _inst_1 (HAppend.hAppend.{u1, u1, u1} (List.{u1} α) (List.{u1} α) (List.{u1} α) (instHAppend.{u1} (List.{u1} α) (List.instAppendList.{u1} α)) l l') n) (List.getI.{u1} α _inst_1 l n))
+  forall {α : Type.{u1}} [_inst_1 : Inhabited.{succ u1} α] (l : List.{u1} α) (l' : List.{u1} α) (n : Nat) (h : LT.lt.{0} Nat instLTNat n (List.length.{u1} α l)), (optParam.{0} (LT.lt.{0} Nat instLTNat n (List.length.{u1} α (HAppend.hAppend.{u1, u1, u1} (List.{u1} α) (List.{u1} α) (List.{u1} α) (instHAppend.{u1} (List.{u1} α) (List.instAppendList.{u1} α)) l l'))) (LT.lt.trans_le.{0} Nat (PartialOrder.toPreorder.{0} Nat (StrictOrderedSemiring.toPartialOrder.{0} Nat Nat.strictOrderedSemiring)) n (List.length.{u1} α l) (List.length.{u1} α (HAppend.hAppend.{u1, u1, u1} (List.{u1} α) (List.{u1} α) (List.{u1} α) (instHAppend.{u1} (List.{u1} α) (List.instAppendList.{u1} α)) l l')) h (Eq.rec.{0, 1} Nat (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat instAddNat) (List.length.{u1} α l) (List.length.{u1} α l')) (fun (x._@.Mathlib.Data.List.Basic._hyg.50174 : Nat) (h._@.Mathlib.Data.List.Basic._hyg.50175 : Eq.{1} Nat (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat instAddNat) (List.length.{u1} α l) (List.length.{u1} α l')) x._@.Mathlib.Data.List.Basic._hyg.50174) => LE.le.{0} Nat (Preorder.toLE.{0} Nat (PartialOrder.toPreorder.{0} Nat (StrictOrderedSemiring.toPartialOrder.{0} Nat Nat.strictOrderedSemiring))) (List.length.{u1} α l) x._@.Mathlib.Data.List.Basic._hyg.50174) (le_self_add.{0} Nat (CanonicallyOrderedCommSemiring.toCanonicallyOrderedAddMonoid.{0} Nat Nat.canonicallyOrderedCommSemiring) (List.length.{u1} α l) (List.length.{u1} α l')) (List.length.{u1} α (HAppend.hAppend.{u1, u1, u1} (List.{u1} α) (List.{u1} α) (List.{u1} α) (instHAppend.{u1} (List.{u1} α) (List.instAppendList.{u1} α)) l l')) (Eq.symm.{1} Nat (List.length.{u1} α (HAppend.hAppend.{u1, u1, u1} (List.{u1} α) (List.{u1} α) (List.{u1} α) (instHAppend.{u1} (List.{u1} α) (List.instAppendList.{u1} α)) l l')) (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat instAddNat) (List.length.{u1} α l) (List.length.{u1} α l')) (List.length_append.{u1} α l l'))))) -> (Eq.{succ u1} α (List.getI.{u1} α _inst_1 (HAppend.hAppend.{u1, u1, u1} (List.{u1} α) (List.{u1} α) (List.{u1} α) (instHAppend.{u1} (List.{u1} α) (List.instAppendList.{u1} α)) l l') n) (List.getI.{u1} α _inst_1 l n))
 Case conversion may be inaccurate. Consider using '#align list.inth_append List.getI_appendₓ'. -/
 theorem getI_append (l l' : List α) (n : ℕ) (h : n < l.length)
     (h' : n < (l ++ l').length := h.trans_le ((length_append l l').symm ▸ le_self_add)) :
Diff
@@ -5178,7 +5178,7 @@ theorem filterMap_eq_map (f : α → β) : filterMap (some ∘ f) = map f :=
 lean 3 declaration is
   forall {α : Type.{u1}} (p : α -> Prop) [_inst_1 : DecidablePred.{succ u1} α p], Eq.{succ u1} ((List.{u1} α) -> (List.{u1} α)) (List.filterMap.{u1, u1} α α (Option.guard.{u1} α p (fun (a : α) => _inst_1 a))) (List.filterₓ.{u1} α p (fun (a : α) => _inst_1 a))
 but is expected to have type
-  forall {α : Type.{u1}} (p : α -> Bool), Eq.{succ u1} ((List.{u1} α) -> (List.{u1} α)) (List.filterMap.{u1, u1} α α (Option.guard.{u1} α (fun (x._@.Std.Data.List.Lemmas._hyg.23896 : α) => Eq.{1} Bool (p x._@.Std.Data.List.Lemmas._hyg.23896) Bool.true) (fun (a : α) => instDecidableEqBool (p a) Bool.true))) (List.filter.{u1} α p)
+  forall {α : Type.{u1}} (p : α -> Bool), Eq.{succ u1} ((List.{u1} α) -> (List.{u1} α)) (List.filterMap.{u1, u1} α α (Option.guard.{u1} α (fun (x._@.Std.Data.List.Lemmas._hyg.24165 : α) => Eq.{1} Bool (p x._@.Std.Data.List.Lemmas._hyg.24165) Bool.true) (fun (a : α) => instDecidableEqBool (p a) Bool.true))) (List.filter.{u1} α p)
 Case conversion may be inaccurate. Consider using '#align list.filter_map_eq_filter List.filterMap_eq_filterₓ'. -/
 theorem filterMap_eq_filter (p : α → Prop) [DecidablePred p] :
     filterMap (Option.guard p) = filter p := by
Diff
@@ -2910,7 +2910,12 @@ theorem length_insertNth_le_succ (l : List α) (x : α) (n : ℕ) :
 #align list.length_insert_nth_le_succ List.length_insertNth_le_succ
 -/
 
-#print List.nthLe_insertNth_of_lt /-
+/- warning: list.nth_le_insert_nth_of_lt -> List.nthLe_insertNth_of_lt is a dubious translation:
+lean 3 declaration is
+  forall {α : Type.{u1}} (l : List.{u1} α) (x : α) (n : Nat) (k : Nat), (LT.lt.{0} Nat Nat.hasLt k n) -> (forall (hk : LT.lt.{0} Nat Nat.hasLt k (List.length.{u1} α l)) (hk' : optParam.{0} (LT.lt.{0} Nat (Preorder.toHasLt.{0} Nat (PartialOrder.toPreorder.{0} Nat (OrderedCancelAddCommMonoid.toPartialOrder.{0} Nat (StrictOrderedSemiring.toOrderedCancelAddCommMonoid.{0} Nat Nat.strictOrderedSemiring)))) k (List.length.{u1} α (List.insertNth.{u1} α n x l))) (LT.lt.trans_le.{0} Nat (PartialOrder.toPreorder.{0} Nat (OrderedCancelAddCommMonoid.toPartialOrder.{0} Nat (StrictOrderedSemiring.toOrderedCancelAddCommMonoid.{0} Nat Nat.strictOrderedSemiring))) k (List.length.{u1} α l) (List.length.{u1} α (List.insertNth.{u1} α n x l)) hk (List.length_le_length_insertNth.{u1} α l x n))), Eq.{succ u1} α (List.nthLe.{u1} α (List.insertNth.{u1} α n x l) k hk') (List.nthLe.{u1} α l k hk))
+but is expected to have type
+  forall {α : Type.{u1}} (l : List.{u1} α) (x : α) (n : Nat) (k : Nat), (LT.lt.{0} Nat instLTNat k n) -> (forall (hk : LT.lt.{0} Nat instLTNat k (List.length.{u1} α l)) (hk' : optParam.{0} (LT.lt.{0} Nat instLTNat k (List.length.{u1} α (List.insertNth.{u1} α n x l))) (LT.lt.trans_le.{0} Nat (PartialOrder.toPreorder.{0} Nat (StrictOrderedSemiring.toPartialOrder.{0} Nat Nat.strictOrderedSemiring)) k (List.length.{u1} α l) (List.length.{u1} α (List.insertNth.{u1} α n x l)) hk (List.length_le_length_insertNth.{u1} α l x n))), Eq.{succ u1} α (List.nthLe.{u1} α (List.insertNth.{u1} α n x l) k hk') (List.nthLe.{u1} α l k hk))
+Case conversion may be inaccurate. Consider using '#align list.nth_le_insert_nth_of_lt List.nthLe_insertNth_of_ltₓ'. -/
 theorem nthLe_insertNth_of_lt (l : List α) (x : α) (n k : ℕ) (hn : k < n) (hk : k < l.length)
     (hk' : k < (insertNth n x l).length := hk.trans_le (length_le_length_insertNth _ _ _)) :
     (insertNth n x l).nthLe k hk' = l.nthLe k hk :=
@@ -2924,7 +2929,6 @@ theorem nthLe_insertNth_of_lt (l : List α) (x : α) (n k : ℕ) (hn : k < n) (h
       · rw [Nat.succ_lt_succ_iff] at hn
         simpa using IH _ _ hn _
 #align list.nth_le_insert_nth_of_lt List.nthLe_insertNth_of_lt
--/
 
 #print List.nthLe_insertNth_self /-
 @[simp]
@@ -3615,7 +3619,7 @@ theorem nthLe_drop (L : List α) {i j : ℕ} (h : i + j < L.length) :
 
 /- warning: list.nth_le_drop' -> List.nthLe_drop' is a dubious translation:
 lean 3 declaration is
-  forall {α : Type.{u1}} (L : List.{u1} α) {i : Nat} {j : Nat} (h : LT.lt.{0} Nat Nat.hasLt j (List.length.{u1} α (List.drop.{u1} α i L))), Eq.{succ u1} α (List.nthLe.{u1} α (List.drop.{u1} α i L) j h) (List.nthLe.{u1} α L (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat Nat.hasAdd) i j) (Iff.mp (LT.lt.{0} Nat (Preorder.toLT.{0} Nat (PartialOrder.toPreorder.{0} Nat (SemilatticeInf.toPartialOrder.{0} Nat (Lattice.toSemilatticeInf.{0} Nat (LinearOrder.toLattice.{0} Nat Nat.linearOrder))))) j (HSub.hSub.{0, 0, 0} Nat Nat Nat (instHSub.{0} Nat Nat.hasSub) (List.length.{u1} α L) i)) (LT.lt.{0} Nat (Preorder.toLT.{0} Nat (PartialOrder.toPreorder.{0} Nat (SemilatticeInf.toPartialOrder.{0} Nat (Lattice.toSemilatticeInf.{0} Nat (LinearOrder.toLattice.{0} Nat Nat.linearOrder))))) (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat (AddSemigroup.toHasAdd.{0} Nat (AddCommSemigroup.toAddSemigroup.{0} Nat Nat.addCommSemigroup))) i j) (List.length.{u1} α L)) (lt_tsub_iff_left.{0} Nat j (List.length.{u1} α L) i Nat.linearOrder Nat.addCommSemigroup Nat.hasSub Nat.orderedSub) (Eq.subst.{1} Nat (fun (_x : Nat) => LT.lt.{0} Nat (Preorder.toLT.{0} Nat (PartialOrder.toPreorder.{0} Nat (SemilatticeInf.toPartialOrder.{0} Nat (Lattice.toSemilatticeInf.{0} Nat (LinearOrder.toLattice.{0} Nat Nat.linearOrder))))) j _x) (List.length.{u1} α (List.drop.{u1} α i L)) (HSub.hSub.{0, 0, 0} Nat Nat Nat (instHSub.{0} Nat Nat.hasSub) (List.length.{u1} α L) i) (List.length_drop.{u1} α i L) h)))
+  forall {α : Type.{u1}} (L : List.{u1} α) {i : Nat} {j : Nat} (h : LT.lt.{0} Nat Nat.hasLt j (List.length.{u1} α (List.drop.{u1} α i L))), Eq.{succ u1} α (List.nthLe.{u1} α (List.drop.{u1} α i L) j h) (List.nthLe.{u1} α L (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat Nat.hasAdd) i j) (Iff.mp (LT.lt.{0} Nat (Preorder.toHasLt.{0} Nat (PartialOrder.toPreorder.{0} Nat (SemilatticeInf.toPartialOrder.{0} Nat (Lattice.toSemilatticeInf.{0} Nat (LinearOrder.toLattice.{0} Nat Nat.linearOrder))))) j (HSub.hSub.{0, 0, 0} Nat Nat Nat (instHSub.{0} Nat Nat.hasSub) (List.length.{u1} α L) i)) (LT.lt.{0} Nat (Preorder.toHasLt.{0} Nat (PartialOrder.toPreorder.{0} Nat (SemilatticeInf.toPartialOrder.{0} Nat (Lattice.toSemilatticeInf.{0} Nat (LinearOrder.toLattice.{0} Nat Nat.linearOrder))))) (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat (AddSemigroup.toHasAdd.{0} Nat (AddCommSemigroup.toAddSemigroup.{0} Nat Nat.addCommSemigroup))) i j) (List.length.{u1} α L)) (lt_tsub_iff_left.{0} Nat j (List.length.{u1} α L) i Nat.linearOrder Nat.addCommSemigroup Nat.hasSub Nat.orderedSub) (Eq.subst.{1} Nat (fun (_x : Nat) => LT.lt.{0} Nat (Preorder.toHasLt.{0} Nat (PartialOrder.toPreorder.{0} Nat (SemilatticeInf.toPartialOrder.{0} Nat (Lattice.toSemilatticeInf.{0} Nat (LinearOrder.toLattice.{0} Nat Nat.linearOrder))))) j _x) (List.length.{u1} α (List.drop.{u1} α i L)) (HSub.hSub.{0, 0, 0} Nat Nat Nat (instHSub.{0} Nat Nat.hasSub) (List.length.{u1} α L) i) (List.length_drop.{u1} α i L) h)))
 but is expected to have type
   forall {α : Type.{u1}} (L : List.{u1} α) {i : Nat} {j : Nat} (h : LT.lt.{0} Nat instLTNat j (List.length.{u1} α (List.drop.{u1} α i L))), Eq.{succ u1} α (List.nthLe.{u1} α (List.drop.{u1} α i L) j h) (List.nthLe.{u1} α L (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat instAddNat) i j) (Iff.mp (LT.lt.{0} Nat (Preorder.toLT.{0} Nat (PartialOrder.toPreorder.{0} Nat (SemilatticeInf.toPartialOrder.{0} Nat (Lattice.toSemilatticeInf.{0} Nat (DistribLattice.toLattice.{0} Nat (instDistribLattice.{0} Nat Nat.linearOrder)))))) j (HSub.hSub.{0, 0, 0} Nat Nat Nat (instHSub.{0} Nat instSubNat) (List.length.{u1} α L) i)) (LT.lt.{0} Nat (Preorder.toLT.{0} Nat (PartialOrder.toPreorder.{0} Nat (SemilatticeInf.toPartialOrder.{0} Nat (Lattice.toSemilatticeInf.{0} Nat (DistribLattice.toLattice.{0} Nat (instDistribLattice.{0} Nat Nat.linearOrder)))))) (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat (AddSemigroup.toAdd.{0} Nat (AddCommSemigroup.toAddSemigroup.{0} Nat Nat.addCommSemigroup))) i j) (List.length.{u1} α L)) (lt_tsub_iff_left.{0} Nat j (List.length.{u1} α L) i Nat.linearOrder Nat.addCommSemigroup instSubNat Nat.instOrderedSubNatInstLENatInstAddNatInstSubNat) (Eq.rec.{0, 1} Nat (List.length.{u1} α (List.drop.{u1} α i L)) (fun (x._@.Mathlib.Data.List.Basic._hyg.24232 : Nat) (h._@.Mathlib.Data.List.Basic._hyg.24233 : Eq.{1} Nat (List.length.{u1} α (List.drop.{u1} α i L)) x._@.Mathlib.Data.List.Basic._hyg.24232) => LT.lt.{0} Nat (Preorder.toLT.{0} Nat (PartialOrder.toPreorder.{0} Nat (SemilatticeInf.toPartialOrder.{0} Nat (Lattice.toSemilatticeInf.{0} Nat (DistribLattice.toLattice.{0} Nat (instDistribLattice.{0} Nat Nat.linearOrder)))))) j x._@.Mathlib.Data.List.Basic._hyg.24232) h (HSub.hSub.{0, 0, 0} Nat Nat Nat (instHSub.{0} Nat instSubNat) (List.length.{u1} α L) i) (List.length_drop.{u1} α i L))))
 Case conversion may be inaccurate. Consider using '#align list.nth_le_drop' List.nthLe_drop'ₓ'. -/
@@ -7264,13 +7268,17 @@ theorem getD_default_eq_getI : l.getD n default = l.getI n :=
   rfl
 #align list.nthd_default_eq_inth List.getD_default_eq_getIₓ
 
-#print List.getI_append /-
+/- warning: list.inth_append -> List.getI_append is a dubious translation:
+lean 3 declaration is
+  forall {α : Type.{u1}} [_inst_1 : Inhabited.{succ u1} α] (l : List.{u1} α) (l' : List.{u1} α) (n : Nat) (h : LT.lt.{0} Nat Nat.hasLt n (List.length.{u1} α l)), (optParam.{0} (LT.lt.{0} Nat (Preorder.toHasLt.{0} Nat (PartialOrder.toPreorder.{0} Nat (OrderedCancelAddCommMonoid.toPartialOrder.{0} Nat (StrictOrderedSemiring.toOrderedCancelAddCommMonoid.{0} Nat Nat.strictOrderedSemiring)))) n (List.length.{u1} α (Append.append.{u1} (List.{u1} α) (List.hasAppend.{u1} α) l l'))) (LT.lt.trans_le.{0} Nat (PartialOrder.toPreorder.{0} Nat (OrderedCancelAddCommMonoid.toPartialOrder.{0} Nat (StrictOrderedSemiring.toOrderedCancelAddCommMonoid.{0} Nat Nat.strictOrderedSemiring))) n (List.length.{u1} α l) (List.length.{u1} α (Append.append.{u1} (List.{u1} α) (List.hasAppend.{u1} α) l l')) h (Eq.subst.{1} Nat (fun (_x : Nat) => LE.le.{0} Nat (Preorder.toHasLe.{0} Nat (PartialOrder.toPreorder.{0} Nat (OrderedCancelAddCommMonoid.toPartialOrder.{0} Nat (StrictOrderedSemiring.toOrderedCancelAddCommMonoid.{0} Nat Nat.strictOrderedSemiring)))) (List.length.{u1} α l) _x) (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat Nat.hasAdd) (List.length.{u1} α l) (List.length.{u1} α l')) (List.length.{u1} α (Append.append.{u1} (List.{u1} α) (List.hasAppend.{u1} α) l l')) (Eq.symm.{1} Nat (List.length.{u1} α (Append.append.{u1} (List.{u1} α) (List.hasAppend.{u1} α) l l')) (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat Nat.hasAdd) (List.length.{u1} α l) (List.length.{u1} α l')) (List.length_append.{u1} α l l')) (le_self_add.{0} Nat (CanonicallyOrderedCommSemiring.toCanonicallyOrderedAddMonoid.{0} Nat Nat.canonicallyOrderedCommSemiring) (List.length.{u1} α l) (List.length.{u1} α l'))))) -> (Eq.{succ u1} α (List.getI.{u1} α _inst_1 (Append.append.{u1} (List.{u1} α) (List.hasAppend.{u1} α) l l') n) (List.getI.{u1} α _inst_1 l n))
+but is expected to have type
+  forall {α : Type.{u1}} [_inst_1 : Inhabited.{succ u1} α] (l : List.{u1} α) (l' : List.{u1} α) (n : Nat) (h : LT.lt.{0} Nat instLTNat n (List.length.{u1} α l)), (optParam.{0} (LT.lt.{0} Nat instLTNat n (List.length.{u1} α (HAppend.hAppend.{u1, u1, u1} (List.{u1} α) (List.{u1} α) (List.{u1} α) (instHAppend.{u1} (List.{u1} α) (List.instAppendList.{u1} α)) l l'))) (LT.lt.trans_le.{0} Nat (PartialOrder.toPreorder.{0} Nat (StrictOrderedSemiring.toPartialOrder.{0} Nat Nat.strictOrderedSemiring)) n (List.length.{u1} α l) (List.length.{u1} α (HAppend.hAppend.{u1, u1, u1} (List.{u1} α) (List.{u1} α) (List.{u1} α) (instHAppend.{u1} (List.{u1} α) (List.instAppendList.{u1} α)) l l')) h (Eq.rec.{0, 1} Nat (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat instAddNat) (List.length.{u1} α l) (List.length.{u1} α l')) (fun (x._@.Mathlib.Data.List.Basic._hyg.50042 : Nat) (h._@.Mathlib.Data.List.Basic._hyg.50043 : Eq.{1} Nat (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat instAddNat) (List.length.{u1} α l) (List.length.{u1} α l')) x._@.Mathlib.Data.List.Basic._hyg.50042) => LE.le.{0} Nat (Preorder.toLE.{0} Nat (PartialOrder.toPreorder.{0} Nat (StrictOrderedSemiring.toPartialOrder.{0} Nat Nat.strictOrderedSemiring))) (List.length.{u1} α l) x._@.Mathlib.Data.List.Basic._hyg.50042) (le_self_add.{0} Nat (CanonicallyOrderedCommSemiring.toCanonicallyOrderedAddMonoid.{0} Nat Nat.canonicallyOrderedCommSemiring) (List.length.{u1} α l) (List.length.{u1} α l')) (List.length.{u1} α (HAppend.hAppend.{u1, u1, u1} (List.{u1} α) (List.{u1} α) (List.{u1} α) (instHAppend.{u1} (List.{u1} α) (List.instAppendList.{u1} α)) l l')) (Eq.symm.{1} Nat (List.length.{u1} α (HAppend.hAppend.{u1, u1, u1} (List.{u1} α) (List.{u1} α) (List.{u1} α) (instHAppend.{u1} (List.{u1} α) (List.instAppendList.{u1} α)) l l')) (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat instAddNat) (List.length.{u1} α l) (List.length.{u1} α l')) (List.length_append.{u1} α l l'))))) -> (Eq.{succ u1} α (List.getI.{u1} α _inst_1 (HAppend.hAppend.{u1, u1, u1} (List.{u1} α) (List.{u1} α) (List.{u1} α) (instHAppend.{u1} (List.{u1} α) (List.instAppendList.{u1} α)) l l') n) (List.getI.{u1} α _inst_1 l n))
+Case conversion may be inaccurate. Consider using '#align list.inth_append List.getI_appendₓ'. -/
 theorem getI_append (l l' : List α) (n : ℕ) (h : n < l.length)
     (h' : n < (l ++ l').length := h.trans_le ((length_append l l').symm ▸ le_self_add)) :
     (l ++ l').getI n = l.getI n :=
   getD_append _ _ _ _ h h'
 #align list.inth_append List.getI_append
--/
 
 #print List.getI_append_right /-
 theorem getI_append_right (l l' : List α) (n : ℕ) (h : l.length ≤ n) :
Diff
@@ -5713,7 +5713,7 @@ theorem filter_filter (q) [DecidablePred q] :
 lean 3 declaration is
   forall {α : Type.{u1}} {h : DecidablePred.{succ u1} α (fun (a : α) => True)} (l : List.{u1} α), Eq.{succ u1} (List.{u1} α) (List.filterₓ.{u1} α (fun (_x : α) => True) h l) l
 but is expected to have type
-  forall {α : Type.{u1}} (h : List.{u1} α), Eq.{succ u1} (List.{u1} α) (List.filter.{u1} α (fun (x._@.Mathlib.Data.List.Basic._hyg.41263 : α) => Bool.true) h) h
+  forall {α : Type.{u1}} (h : List.{u1} α), Eq.{succ u1} (List.{u1} α) (List.filter.{u1} α (fun (x._@.Mathlib.Data.List.Basic._hyg.41262 : α) => Bool.true) h) h
 Case conversion may be inaccurate. Consider using '#align list.filter_true List.filter_trueₓ'. -/
 @[simp]
 theorem filter_true {h : DecidablePred fun a : α => True} (l : List α) :
@@ -5724,7 +5724,7 @@ theorem filter_true {h : DecidablePred fun a : α => True} (l : List α) :
 lean 3 declaration is
   forall {α : Type.{u1}} {h : DecidablePred.{succ u1} α (fun (a : α) => False)} (l : List.{u1} α), Eq.{succ u1} (List.{u1} α) (List.filterₓ.{u1} α (fun (_x : α) => False) h l) (List.nil.{u1} α)
 but is expected to have type
-  forall {α : Type.{u1}} (h : List.{u1} α), Eq.{succ u1} (List.{u1} α) (List.filter.{u1} α (fun (x._@.Mathlib.Data.List.Basic._hyg.41313 : α) => Bool.false) h) (List.nil.{u1} α)
+  forall {α : Type.{u1}} (h : List.{u1} α), Eq.{succ u1} (List.{u1} α) (List.filter.{u1} α (fun (x._@.Mathlib.Data.List.Basic._hyg.41312 : α) => Bool.false) h) (List.nil.{u1} α)
 Case conversion may be inaccurate. Consider using '#align list.filter_false List.filter_falseₓ'. -/
 @[simp]
 theorem filter_false {h : DecidablePred fun a : α => False} (l : List α) :
Diff
@@ -3617,7 +3617,7 @@ theorem nthLe_drop (L : List α) {i j : ℕ} (h : i + j < L.length) :
 lean 3 declaration is
   forall {α : Type.{u1}} (L : List.{u1} α) {i : Nat} {j : Nat} (h : LT.lt.{0} Nat Nat.hasLt j (List.length.{u1} α (List.drop.{u1} α i L))), Eq.{succ u1} α (List.nthLe.{u1} α (List.drop.{u1} α i L) j h) (List.nthLe.{u1} α L (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat Nat.hasAdd) i j) (Iff.mp (LT.lt.{0} Nat (Preorder.toLT.{0} Nat (PartialOrder.toPreorder.{0} Nat (SemilatticeInf.toPartialOrder.{0} Nat (Lattice.toSemilatticeInf.{0} Nat (LinearOrder.toLattice.{0} Nat Nat.linearOrder))))) j (HSub.hSub.{0, 0, 0} Nat Nat Nat (instHSub.{0} Nat Nat.hasSub) (List.length.{u1} α L) i)) (LT.lt.{0} Nat (Preorder.toLT.{0} Nat (PartialOrder.toPreorder.{0} Nat (SemilatticeInf.toPartialOrder.{0} Nat (Lattice.toSemilatticeInf.{0} Nat (LinearOrder.toLattice.{0} Nat Nat.linearOrder))))) (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat (AddSemigroup.toHasAdd.{0} Nat (AddCommSemigroup.toAddSemigroup.{0} Nat Nat.addCommSemigroup))) i j) (List.length.{u1} α L)) (lt_tsub_iff_left.{0} Nat j (List.length.{u1} α L) i Nat.linearOrder Nat.addCommSemigroup Nat.hasSub Nat.orderedSub) (Eq.subst.{1} Nat (fun (_x : Nat) => LT.lt.{0} Nat (Preorder.toLT.{0} Nat (PartialOrder.toPreorder.{0} Nat (SemilatticeInf.toPartialOrder.{0} Nat (Lattice.toSemilatticeInf.{0} Nat (LinearOrder.toLattice.{0} Nat Nat.linearOrder))))) j _x) (List.length.{u1} α (List.drop.{u1} α i L)) (HSub.hSub.{0, 0, 0} Nat Nat Nat (instHSub.{0} Nat Nat.hasSub) (List.length.{u1} α L) i) (List.length_drop.{u1} α i L) h)))
 but is expected to have type
-  forall {α : Type.{u1}} (L : List.{u1} α) {i : Nat} {j : Nat} (h : LT.lt.{0} Nat instLTNat j (List.length.{u1} α (List.drop.{u1} α i L))), Eq.{succ u1} α (List.nthLe.{u1} α (List.drop.{u1} α i L) j h) (List.nthLe.{u1} α L (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat instAddNat) i j) (Iff.mp (LT.lt.{0} Nat (Preorder.toLT.{0} Nat (PartialOrder.toPreorder.{0} Nat (SemilatticeInf.toPartialOrder.{0} Nat (Lattice.toSemilatticeInf.{0} Nat (DistribLattice.toLattice.{0} Nat (instDistribLattice.{0} Nat Nat.linearOrder)))))) j (HSub.hSub.{0, 0, 0} Nat Nat Nat (instHSub.{0} Nat instSubNat) (List.length.{u1} α L) i)) (LT.lt.{0} Nat (Preorder.toLT.{0} Nat (PartialOrder.toPreorder.{0} Nat (SemilatticeInf.toPartialOrder.{0} Nat (Lattice.toSemilatticeInf.{0} Nat (DistribLattice.toLattice.{0} Nat (instDistribLattice.{0} Nat Nat.linearOrder)))))) (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat (AddSemigroup.toAdd.{0} Nat (AddCommSemigroup.toAddSemigroup.{0} Nat Nat.addCommSemigroup))) i j) (List.length.{u1} α L)) (lt_tsub_iff_left.{0} Nat j (List.length.{u1} α L) i Nat.linearOrder Nat.addCommSemigroup instSubNat Nat.instOrderedSubNatInstLENatInstAddNatInstSubNat) (Eq.rec.{0, 1} Nat (List.length.{u1} α (List.drop.{u1} α i L)) (fun (x._@.Mathlib.Data.List.Basic._hyg.24234 : Nat) (h._@.Mathlib.Data.List.Basic._hyg.24235 : Eq.{1} Nat (List.length.{u1} α (List.drop.{u1} α i L)) x._@.Mathlib.Data.List.Basic._hyg.24234) => LT.lt.{0} Nat (Preorder.toLT.{0} Nat (PartialOrder.toPreorder.{0} Nat (SemilatticeInf.toPartialOrder.{0} Nat (Lattice.toSemilatticeInf.{0} Nat (DistribLattice.toLattice.{0} Nat (instDistribLattice.{0} Nat Nat.linearOrder)))))) j x._@.Mathlib.Data.List.Basic._hyg.24234) h (HSub.hSub.{0, 0, 0} Nat Nat Nat (instHSub.{0} Nat instSubNat) (List.length.{u1} α L) i) (List.length_drop.{u1} α i L))))
+  forall {α : Type.{u1}} (L : List.{u1} α) {i : Nat} {j : Nat} (h : LT.lt.{0} Nat instLTNat j (List.length.{u1} α (List.drop.{u1} α i L))), Eq.{succ u1} α (List.nthLe.{u1} α (List.drop.{u1} α i L) j h) (List.nthLe.{u1} α L (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat instAddNat) i j) (Iff.mp (LT.lt.{0} Nat (Preorder.toLT.{0} Nat (PartialOrder.toPreorder.{0} Nat (SemilatticeInf.toPartialOrder.{0} Nat (Lattice.toSemilatticeInf.{0} Nat (DistribLattice.toLattice.{0} Nat (instDistribLattice.{0} Nat Nat.linearOrder)))))) j (HSub.hSub.{0, 0, 0} Nat Nat Nat (instHSub.{0} Nat instSubNat) (List.length.{u1} α L) i)) (LT.lt.{0} Nat (Preorder.toLT.{0} Nat (PartialOrder.toPreorder.{0} Nat (SemilatticeInf.toPartialOrder.{0} Nat (Lattice.toSemilatticeInf.{0} Nat (DistribLattice.toLattice.{0} Nat (instDistribLattice.{0} Nat Nat.linearOrder)))))) (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat (AddSemigroup.toAdd.{0} Nat (AddCommSemigroup.toAddSemigroup.{0} Nat Nat.addCommSemigroup))) i j) (List.length.{u1} α L)) (lt_tsub_iff_left.{0} Nat j (List.length.{u1} α L) i Nat.linearOrder Nat.addCommSemigroup instSubNat Nat.instOrderedSubNatInstLENatInstAddNatInstSubNat) (Eq.rec.{0, 1} Nat (List.length.{u1} α (List.drop.{u1} α i L)) (fun (x._@.Mathlib.Data.List.Basic._hyg.24232 : Nat) (h._@.Mathlib.Data.List.Basic._hyg.24233 : Eq.{1} Nat (List.length.{u1} α (List.drop.{u1} α i L)) x._@.Mathlib.Data.List.Basic._hyg.24232) => LT.lt.{0} Nat (Preorder.toLT.{0} Nat (PartialOrder.toPreorder.{0} Nat (SemilatticeInf.toPartialOrder.{0} Nat (Lattice.toSemilatticeInf.{0} Nat (DistribLattice.toLattice.{0} Nat (instDistribLattice.{0} Nat Nat.linearOrder)))))) j x._@.Mathlib.Data.List.Basic._hyg.24232) h (HSub.hSub.{0, 0, 0} Nat Nat Nat (instHSub.{0} Nat instSubNat) (List.length.{u1} α L) i) (List.length_drop.{u1} α i L))))
 Case conversion may be inaccurate. Consider using '#align list.nth_le_drop' List.nthLe_drop'ₓ'. -/
 /-- The `i + j`-th element of a list coincides with the `j`-th element of the list obtained by
 dropping the first `i` elements. Version designed to rewrite from the small list to the big list. -/
@@ -5713,7 +5713,7 @@ theorem filter_filter (q) [DecidablePred q] :
 lean 3 declaration is
   forall {α : Type.{u1}} {h : DecidablePred.{succ u1} α (fun (a : α) => True)} (l : List.{u1} α), Eq.{succ u1} (List.{u1} α) (List.filterₓ.{u1} α (fun (_x : α) => True) h l) l
 but is expected to have type
-  forall {α : Type.{u1}} (h : List.{u1} α), Eq.{succ u1} (List.{u1} α) (List.filter.{u1} α (fun (x._@.Mathlib.Data.List.Basic._hyg.41267 : α) => Bool.true) h) h
+  forall {α : Type.{u1}} (h : List.{u1} α), Eq.{succ u1} (List.{u1} α) (List.filter.{u1} α (fun (x._@.Mathlib.Data.List.Basic._hyg.41263 : α) => Bool.true) h) h
 Case conversion may be inaccurate. Consider using '#align list.filter_true List.filter_trueₓ'. -/
 @[simp]
 theorem filter_true {h : DecidablePred fun a : α => True} (l : List α) :
@@ -5724,7 +5724,7 @@ theorem filter_true {h : DecidablePred fun a : α => True} (l : List α) :
 lean 3 declaration is
   forall {α : Type.{u1}} {h : DecidablePred.{succ u1} α (fun (a : α) => False)} (l : List.{u1} α), Eq.{succ u1} (List.{u1} α) (List.filterₓ.{u1} α (fun (_x : α) => False) h l) (List.nil.{u1} α)
 but is expected to have type
-  forall {α : Type.{u1}} (h : List.{u1} α), Eq.{succ u1} (List.{u1} α) (List.filter.{u1} α (fun (x._@.Mathlib.Data.List.Basic._hyg.41317 : α) => Bool.false) h) (List.nil.{u1} α)
+  forall {α : Type.{u1}} (h : List.{u1} α), Eq.{succ u1} (List.{u1} α) (List.filter.{u1} α (fun (x._@.Mathlib.Data.List.Basic._hyg.41313 : α) => Bool.false) h) (List.nil.{u1} α)
 Case conversion may be inaccurate. Consider using '#align list.filter_false List.filter_falseₓ'. -/
 @[simp]
 theorem filter_false {h : DecidablePred fun a : α => False} (l : List α) :
Diff
@@ -3615,7 +3615,7 @@ theorem nthLe_drop (L : List α) {i j : ℕ} (h : i + j < L.length) :
 
 /- warning: list.nth_le_drop' -> List.nthLe_drop' is a dubious translation:
 lean 3 declaration is
-  forall {α : Type.{u1}} (L : List.{u1} α) {i : Nat} {j : Nat} (h : LT.lt.{0} Nat Nat.hasLt j (List.length.{u1} α (List.drop.{u1} α i L))), Eq.{succ u1} α (List.nthLe.{u1} α (List.drop.{u1} α i L) j h) (List.nthLe.{u1} α L (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat Nat.hasAdd) i j) (Iff.mp (LT.lt.{0} Nat (Preorder.toLT.{0} Nat (PartialOrder.toPreorder.{0} Nat (SemilatticeInf.toPartialOrder.{0} Nat (Lattice.toSemilatticeInf.{0} Nat (LinearOrder.toLattice.{0} Nat Nat.linearOrder))))) j (HSub.hSub.{0, 0, 0} Nat Nat Nat (instHSub.{0} Nat Nat.hasSub) (List.length.{u1} α L) i)) (LT.lt.{0} Nat (Preorder.toLT.{0} Nat (PartialOrder.toPreorder.{0} Nat (SemilatticeInf.toPartialOrder.{0} Nat (Lattice.toSemilatticeInf.{0} Nat (LinearOrder.toLattice.{0} Nat Nat.linearOrder))))) (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat (AddSemigroup.toHasAdd.{0} Nat (AddCommSemigroup.toAddSemigroup.{0} Nat Nat.addCommSemigroup))) i j) (List.length.{u1} α L)) (lt_tsub_iff_left.{0} Nat j (List.length.{u1} α L) i Nat.linearOrder Nat.addCommSemigroup Nat.hasSub Nat.hasOrderedSub) (Eq.subst.{1} Nat (fun (_x : Nat) => LT.lt.{0} Nat (Preorder.toLT.{0} Nat (PartialOrder.toPreorder.{0} Nat (SemilatticeInf.toPartialOrder.{0} Nat (Lattice.toSemilatticeInf.{0} Nat (LinearOrder.toLattice.{0} Nat Nat.linearOrder))))) j _x) (List.length.{u1} α (List.drop.{u1} α i L)) (HSub.hSub.{0, 0, 0} Nat Nat Nat (instHSub.{0} Nat Nat.hasSub) (List.length.{u1} α L) i) (List.length_drop.{u1} α i L) h)))
+  forall {α : Type.{u1}} (L : List.{u1} α) {i : Nat} {j : Nat} (h : LT.lt.{0} Nat Nat.hasLt j (List.length.{u1} α (List.drop.{u1} α i L))), Eq.{succ u1} α (List.nthLe.{u1} α (List.drop.{u1} α i L) j h) (List.nthLe.{u1} α L (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat Nat.hasAdd) i j) (Iff.mp (LT.lt.{0} Nat (Preorder.toLT.{0} Nat (PartialOrder.toPreorder.{0} Nat (SemilatticeInf.toPartialOrder.{0} Nat (Lattice.toSemilatticeInf.{0} Nat (LinearOrder.toLattice.{0} Nat Nat.linearOrder))))) j (HSub.hSub.{0, 0, 0} Nat Nat Nat (instHSub.{0} Nat Nat.hasSub) (List.length.{u1} α L) i)) (LT.lt.{0} Nat (Preorder.toLT.{0} Nat (PartialOrder.toPreorder.{0} Nat (SemilatticeInf.toPartialOrder.{0} Nat (Lattice.toSemilatticeInf.{0} Nat (LinearOrder.toLattice.{0} Nat Nat.linearOrder))))) (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat (AddSemigroup.toHasAdd.{0} Nat (AddCommSemigroup.toAddSemigroup.{0} Nat Nat.addCommSemigroup))) i j) (List.length.{u1} α L)) (lt_tsub_iff_left.{0} Nat j (List.length.{u1} α L) i Nat.linearOrder Nat.addCommSemigroup Nat.hasSub Nat.orderedSub) (Eq.subst.{1} Nat (fun (_x : Nat) => LT.lt.{0} Nat (Preorder.toLT.{0} Nat (PartialOrder.toPreorder.{0} Nat (SemilatticeInf.toPartialOrder.{0} Nat (Lattice.toSemilatticeInf.{0} Nat (LinearOrder.toLattice.{0} Nat Nat.linearOrder))))) j _x) (List.length.{u1} α (List.drop.{u1} α i L)) (HSub.hSub.{0, 0, 0} Nat Nat Nat (instHSub.{0} Nat Nat.hasSub) (List.length.{u1} α L) i) (List.length_drop.{u1} α i L) h)))
 but is expected to have type
   forall {α : Type.{u1}} (L : List.{u1} α) {i : Nat} {j : Nat} (h : LT.lt.{0} Nat instLTNat j (List.length.{u1} α (List.drop.{u1} α i L))), Eq.{succ u1} α (List.nthLe.{u1} α (List.drop.{u1} α i L) j h) (List.nthLe.{u1} α L (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat instAddNat) i j) (Iff.mp (LT.lt.{0} Nat (Preorder.toLT.{0} Nat (PartialOrder.toPreorder.{0} Nat (SemilatticeInf.toPartialOrder.{0} Nat (Lattice.toSemilatticeInf.{0} Nat (DistribLattice.toLattice.{0} Nat (instDistribLattice.{0} Nat Nat.linearOrder)))))) j (HSub.hSub.{0, 0, 0} Nat Nat Nat (instHSub.{0} Nat instSubNat) (List.length.{u1} α L) i)) (LT.lt.{0} Nat (Preorder.toLT.{0} Nat (PartialOrder.toPreorder.{0} Nat (SemilatticeInf.toPartialOrder.{0} Nat (Lattice.toSemilatticeInf.{0} Nat (DistribLattice.toLattice.{0} Nat (instDistribLattice.{0} Nat Nat.linearOrder)))))) (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat (AddSemigroup.toAdd.{0} Nat (AddCommSemigroup.toAddSemigroup.{0} Nat Nat.addCommSemigroup))) i j) (List.length.{u1} α L)) (lt_tsub_iff_left.{0} Nat j (List.length.{u1} α L) i Nat.linearOrder Nat.addCommSemigroup instSubNat Nat.instOrderedSubNatInstLENatInstAddNatInstSubNat) (Eq.rec.{0, 1} Nat (List.length.{u1} α (List.drop.{u1} α i L)) (fun (x._@.Mathlib.Data.List.Basic._hyg.24234 : Nat) (h._@.Mathlib.Data.List.Basic._hyg.24235 : Eq.{1} Nat (List.length.{u1} α (List.drop.{u1} α i L)) x._@.Mathlib.Data.List.Basic._hyg.24234) => LT.lt.{0} Nat (Preorder.toLT.{0} Nat (PartialOrder.toPreorder.{0} Nat (SemilatticeInf.toPartialOrder.{0} Nat (Lattice.toSemilatticeInf.{0} Nat (DistribLattice.toLattice.{0} Nat (instDistribLattice.{0} Nat Nat.linearOrder)))))) j x._@.Mathlib.Data.List.Basic._hyg.24234) h (HSub.hSub.{0, 0, 0} Nat Nat Nat (instHSub.{0} Nat instSubNat) (List.length.{u1} α L) i) (List.length_drop.{u1} α i L))))
 Case conversion may be inaccurate. Consider using '#align list.nth_le_drop' List.nthLe_drop'ₓ'. -/
Diff
@@ -5174,7 +5174,7 @@ theorem filterMap_eq_map (f : α → β) : filterMap (some ∘ f) = map f :=
 lean 3 declaration is
   forall {α : Type.{u1}} (p : α -> Prop) [_inst_1 : DecidablePred.{succ u1} α p], Eq.{succ u1} ((List.{u1} α) -> (List.{u1} α)) (List.filterMap.{u1, u1} α α (Option.guard.{u1} α p (fun (a : α) => _inst_1 a))) (List.filterₓ.{u1} α p (fun (a : α) => _inst_1 a))
 but is expected to have type
-  forall {α : Type.{u1}} (p : α -> Bool), Eq.{succ u1} ((List.{u1} α) -> (List.{u1} α)) (List.filterMap.{u1, u1} α α (Option.guard.{u1} α (fun (x._@.Std.Data.List.Lemmas._hyg.23784 : α) => Eq.{1} Bool (p x._@.Std.Data.List.Lemmas._hyg.23784) Bool.true) (fun (a : α) => instDecidableEqBool (p a) Bool.true))) (List.filter.{u1} α p)
+  forall {α : Type.{u1}} (p : α -> Bool), Eq.{succ u1} ((List.{u1} α) -> (List.{u1} α)) (List.filterMap.{u1, u1} α α (Option.guard.{u1} α (fun (x._@.Std.Data.List.Lemmas._hyg.23896 : α) => Eq.{1} Bool (p x._@.Std.Data.List.Lemmas._hyg.23896) Bool.true) (fun (a : α) => instDecidableEqBool (p a) Bool.true))) (List.filter.{u1} α p)
 Case conversion may be inaccurate. Consider using '#align list.filter_map_eq_filter List.filterMap_eq_filterₓ'. -/
 theorem filterMap_eq_filter (p : α → Prop) [DecidablePred p] :
     filterMap (Option.guard p) = filter p := by
Diff
@@ -212,9 +212,14 @@ theorem ne_and_not_mem_of_not_mem_cons {a y : α} {l : List α} : a ∉ y :: l 
 #align list.ne_and_not_mem_of_not_mem_cons List.ne_and_not_mem_of_not_mem_cons
 -/
 
-#print List.mem_map' /-
+/- warning: list.mem_map -> List.mem_map is a dubious translation:
+lean 3 declaration is
+  forall {α : Type.{u1}} {β : Type.{u2}} {f : α -> β} {b : β} {l : List.{u1} α}, Iff (Membership.Mem.{u2, u2} β (List.{u2} β) (List.hasMem.{u2} β) b (List.map.{u1, u2} α β f l)) (Exists.{succ u1} α (fun (a : α) => And (Membership.Mem.{u1, u1} α (List.{u1} α) (List.hasMem.{u1} α) a l) (Eq.{succ u2} β (f a) b)))
+but is expected to have type
+  forall {α : Type.{u2}} {β : Type.{u1}} {f : β} {b : α -> β} {l : List.{u2} α}, Iff (Membership.mem.{u1, u1} β (List.{u1} β) (List.instMembershipList.{u1} β) f (List.map.{u2, u1} α β b l)) (Exists.{succ u2} α (fun (a : α) => And (Membership.mem.{u2, u2} α (List.{u2} α) (List.instMembershipList.{u2} α) a l) (Eq.{succ u1} β (b a) f)))
+Case conversion may be inaccurate. Consider using '#align list.mem_map List.mem_mapₓ'. -/
 @[simp]
-theorem mem_map' {f : α → β} {b : β} {l : List α} : b ∈ map f l ↔ ∃ a, a ∈ l ∧ f a = b :=
+theorem mem_map {f : α → β} {b : β} {l : List α} : b ∈ map f l ↔ ∃ a, a ∈ l ∧ f a = b :=
   by
   -- This proof uses no axioms, that's why it's longer that `induction`; simp [...]
   induction' l with a l ihl
@@ -227,21 +232,26 @@ theorem mem_map' {f : α → β} {b : β} {l : List α} : b ∈ map f l ↔ ∃
       exacts[⟨a, Or.inl rfl, h⟩, ⟨c, Or.inr hcl, h⟩]
     · rintro ⟨c, hc | hc, h⟩
       exacts[Or.inl <| (congr_arg f hc.symm).trans h, Or.inr ⟨c, hc, h⟩]
-#align list.mem_map List.mem_map'
--/
+#align list.mem_map List.mem_map
 
+/- warning: list.exists_of_mem_map -> List.exists_of_mem_map is a dubious translation:
+lean 3 declaration is
+  forall {α : Type.{u1}} {β : Type.{u2}} {f : α -> β} {b : β} {l : List.{u1} α}, (Membership.Mem.{u2, u2} β (List.{u2} β) (List.hasMem.{u2} β) b (List.map.{u1, u2} α β f l)) -> (Exists.{succ u1} α (fun (a : α) => And (Membership.Mem.{u1, u1} α (List.{u1} α) (List.hasMem.{u1} α) a l) (Eq.{succ u2} β (f a) b)))
+but is expected to have type
+  forall {α : Type.{u2}} {β : α} {f : Type.{u1}} {b : f -> α} {l : List.{u1} f}, (Membership.mem.{u2, u2} α (List.{u2} α) (List.instMembershipList.{u2} α) β (List.map.{u1, u2} f α b l)) -> (Exists.{succ u1} f (fun (a : f) => And (Membership.mem.{u1, u1} f (List.{u1} f) (List.instMembershipList.{u1} f) a l) (Eq.{succ u2} α (b a) β)))
+Case conversion may be inaccurate. Consider using '#align list.exists_of_mem_map List.exists_of_mem_mapₓ'. -/
 alias mem_map ↔ exists_of_mem_map _
-#align list.exists_of_mem_map List.exists_of_mem_map'
+#align list.exists_of_mem_map List.exists_of_mem_map
 
 theorem mem_map_of_mem (f : α → β) {a : α} {l : List α} (h : a ∈ l) : f a ∈ map f l :=
-  mem_map'.2 ⟨a, h, rfl⟩
+  mem_map.2 ⟨a, h, rfl⟩
 #align list.mem_map_of_mem List.mem_map_of_memₓ
 
 #print List.mem_map_of_injective /-
 theorem mem_map_of_injective {f : α → β} (H : Injective f) {a : α} {l : List α} :
     f a ∈ map f l ↔ a ∈ l :=
   ⟨fun m =>
-    let ⟨a', m', e⟩ := exists_of_mem_map' m
+    let ⟨a', m', e⟩ := exists_of_mem_map m
     H e ▸ m',
     mem_map_of_mem _⟩
 #align list.mem_map_of_injective List.mem_map_of_injective
@@ -304,7 +314,7 @@ theorem mem_join_of_mem {a : α} {L : List (List α)} {l} (lL : l ∈ L) (al : a
 theorem mem_bind {b : β} {l : List α} {f : α → List β} : b ∈ List.bind l f ↔ ∃ a ∈ l, b ∈ f a :=
   Iff.trans mem_join
     ⟨fun ⟨l', h1, h2⟩ =>
-      let ⟨a, al, fa⟩ := exists_of_mem_map' h1
+      let ⟨a, al, fa⟩ := exists_of_mem_map h1
       ⟨a, al, fa.symm ▸ h2⟩,
       fun ⟨a, al, bfa⟩ => ⟨f a, mem_map_of_mem _ al, bfa⟩⟩
 #align list.mem_bind List.mem_bindₓ
@@ -3607,7 +3617,7 @@ theorem nthLe_drop (L : List α) {i j : ℕ} (h : i + j < L.length) :
 lean 3 declaration is
   forall {α : Type.{u1}} (L : List.{u1} α) {i : Nat} {j : Nat} (h : LT.lt.{0} Nat Nat.hasLt j (List.length.{u1} α (List.drop.{u1} α i L))), Eq.{succ u1} α (List.nthLe.{u1} α (List.drop.{u1} α i L) j h) (List.nthLe.{u1} α L (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat Nat.hasAdd) i j) (Iff.mp (LT.lt.{0} Nat (Preorder.toLT.{0} Nat (PartialOrder.toPreorder.{0} Nat (SemilatticeInf.toPartialOrder.{0} Nat (Lattice.toSemilatticeInf.{0} Nat (LinearOrder.toLattice.{0} Nat Nat.linearOrder))))) j (HSub.hSub.{0, 0, 0} Nat Nat Nat (instHSub.{0} Nat Nat.hasSub) (List.length.{u1} α L) i)) (LT.lt.{0} Nat (Preorder.toLT.{0} Nat (PartialOrder.toPreorder.{0} Nat (SemilatticeInf.toPartialOrder.{0} Nat (Lattice.toSemilatticeInf.{0} Nat (LinearOrder.toLattice.{0} Nat Nat.linearOrder))))) (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat (AddSemigroup.toHasAdd.{0} Nat (AddCommSemigroup.toAddSemigroup.{0} Nat Nat.addCommSemigroup))) i j) (List.length.{u1} α L)) (lt_tsub_iff_left.{0} Nat j (List.length.{u1} α L) i Nat.linearOrder Nat.addCommSemigroup Nat.hasSub Nat.hasOrderedSub) (Eq.subst.{1} Nat (fun (_x : Nat) => LT.lt.{0} Nat (Preorder.toLT.{0} Nat (PartialOrder.toPreorder.{0} Nat (SemilatticeInf.toPartialOrder.{0} Nat (Lattice.toSemilatticeInf.{0} Nat (LinearOrder.toLattice.{0} Nat Nat.linearOrder))))) j _x) (List.length.{u1} α (List.drop.{u1} α i L)) (HSub.hSub.{0, 0, 0} Nat Nat Nat (instHSub.{0} Nat Nat.hasSub) (List.length.{u1} α L) i) (List.length_drop.{u1} α i L) h)))
 but is expected to have type
-  forall {α : Type.{u1}} (L : List.{u1} α) {i : Nat} {j : Nat} (h : LT.lt.{0} Nat instLTNat j (List.length.{u1} α (List.drop.{u1} α i L))), Eq.{succ u1} α (List.nthLe.{u1} α (List.drop.{u1} α i L) j h) (List.nthLe.{u1} α L (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat instAddNat) i j) (Iff.mp (LT.lt.{0} Nat (Preorder.toLT.{0} Nat (PartialOrder.toPreorder.{0} Nat (SemilatticeInf.toPartialOrder.{0} Nat (Lattice.toSemilatticeInf.{0} Nat (DistribLattice.toLattice.{0} Nat (instDistribLattice.{0} Nat Nat.linearOrder)))))) j (HSub.hSub.{0, 0, 0} Nat Nat Nat (instHSub.{0} Nat instSubNat) (List.length.{u1} α L) i)) (LT.lt.{0} Nat (Preorder.toLT.{0} Nat (PartialOrder.toPreorder.{0} Nat (SemilatticeInf.toPartialOrder.{0} Nat (Lattice.toSemilatticeInf.{0} Nat (DistribLattice.toLattice.{0} Nat (instDistribLattice.{0} Nat Nat.linearOrder)))))) (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat (AddSemigroup.toAdd.{0} Nat (AddCommSemigroup.toAddSemigroup.{0} Nat Nat.addCommSemigroup))) i j) (List.length.{u1} α L)) (lt_tsub_iff_left.{0} Nat j (List.length.{u1} α L) i Nat.linearOrder Nat.addCommSemigroup instSubNat Nat.instOrderedSubNatInstLENatInstAddNatInstSubNat) (Eq.rec.{0, 1} Nat (List.length.{u1} α (List.drop.{u1} α i L)) (fun (x._@.Mathlib.Data.List.Basic._hyg.25290 : Nat) (h._@.Mathlib.Data.List.Basic._hyg.25291 : Eq.{1} Nat (List.length.{u1} α (List.drop.{u1} α i L)) x._@.Mathlib.Data.List.Basic._hyg.25290) => LT.lt.{0} Nat (Preorder.toLT.{0} Nat (PartialOrder.toPreorder.{0} Nat (SemilatticeInf.toPartialOrder.{0} Nat (Lattice.toSemilatticeInf.{0} Nat (DistribLattice.toLattice.{0} Nat (instDistribLattice.{0} Nat Nat.linearOrder)))))) j x._@.Mathlib.Data.List.Basic._hyg.25290) h (HSub.hSub.{0, 0, 0} Nat Nat Nat (instHSub.{0} Nat instSubNat) (List.length.{u1} α L) i) (List.length_drop.{u1} α i L))))
+  forall {α : Type.{u1}} (L : List.{u1} α) {i : Nat} {j : Nat} (h : LT.lt.{0} Nat instLTNat j (List.length.{u1} α (List.drop.{u1} α i L))), Eq.{succ u1} α (List.nthLe.{u1} α (List.drop.{u1} α i L) j h) (List.nthLe.{u1} α L (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat instAddNat) i j) (Iff.mp (LT.lt.{0} Nat (Preorder.toLT.{0} Nat (PartialOrder.toPreorder.{0} Nat (SemilatticeInf.toPartialOrder.{0} Nat (Lattice.toSemilatticeInf.{0} Nat (DistribLattice.toLattice.{0} Nat (instDistribLattice.{0} Nat Nat.linearOrder)))))) j (HSub.hSub.{0, 0, 0} Nat Nat Nat (instHSub.{0} Nat instSubNat) (List.length.{u1} α L) i)) (LT.lt.{0} Nat (Preorder.toLT.{0} Nat (PartialOrder.toPreorder.{0} Nat (SemilatticeInf.toPartialOrder.{0} Nat (Lattice.toSemilatticeInf.{0} Nat (DistribLattice.toLattice.{0} Nat (instDistribLattice.{0} Nat Nat.linearOrder)))))) (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat (AddSemigroup.toAdd.{0} Nat (AddCommSemigroup.toAddSemigroup.{0} Nat Nat.addCommSemigroup))) i j) (List.length.{u1} α L)) (lt_tsub_iff_left.{0} Nat j (List.length.{u1} α L) i Nat.linearOrder Nat.addCommSemigroup instSubNat Nat.instOrderedSubNatInstLENatInstAddNatInstSubNat) (Eq.rec.{0, 1} Nat (List.length.{u1} α (List.drop.{u1} α i L)) (fun (x._@.Mathlib.Data.List.Basic._hyg.24234 : Nat) (h._@.Mathlib.Data.List.Basic._hyg.24235 : Eq.{1} Nat (List.length.{u1} α (List.drop.{u1} α i L)) x._@.Mathlib.Data.List.Basic._hyg.24234) => LT.lt.{0} Nat (Preorder.toLT.{0} Nat (PartialOrder.toPreorder.{0} Nat (SemilatticeInf.toPartialOrder.{0} Nat (Lattice.toSemilatticeInf.{0} Nat (DistribLattice.toLattice.{0} Nat (instDistribLattice.{0} Nat Nat.linearOrder)))))) j x._@.Mathlib.Data.List.Basic._hyg.24234) h (HSub.hSub.{0, 0, 0} Nat Nat Nat (instHSub.{0} Nat instSubNat) (List.length.{u1} α L) i) (List.length_drop.{u1} α i L))))
 Case conversion may be inaccurate. Consider using '#align list.nth_le_drop' List.nthLe_drop'ₓ'. -/
 /-- The `i + j`-th element of a list coincides with the `j`-th element of the list obtained by
 dropping the first `i` elements. Version designed to rewrite from the small list to the big list. -/
@@ -4962,7 +4972,7 @@ theorem find?_eq_none : find? p l = none ↔ ∀ x ∈ l, ¬p x :=
 lean 3 declaration is
   forall {α : Type.{u1}} {p : α -> Prop} [_inst_1 : DecidablePred.{succ u1} α p] {l : List.{u1} α} {a : α}, (Eq.{succ u1} (Option.{u1} α) (List.find?.{u1} α p (fun (a : α) => _inst_1 a) l) (Option.some.{u1} α a)) -> (p a)
 but is expected to have type
-  forall {α : Type.{u1}} {p : α -> Bool} {_inst_1 : List.{u1} α} {l : α}, (Eq.{succ u1} (Option.{u1} α) (List.find?.{u1} α p _inst_1) (Option.some.{u1} α l)) -> (Eq.{1} Bool (p l) Bool.true)
+  forall {α : Type.{u1}} {p : α -> Bool} {_inst_1 : α} {l : List.{u1} α}, (Eq.{succ u1} (Option.{u1} α) (List.find?.{u1} α p l) (Option.some.{u1} α _inst_1)) -> (Eq.{1} Bool (p _inst_1) Bool.true)
 Case conversion may be inaccurate. Consider using '#align list.find_some List.find?_someₓ'. -/
 theorem find?_some (H : find? p l = some a) : p a :=
   by
@@ -5083,29 +5093,46 @@ end Lookmap
 /-! ### filter_map -/
 
 
-#print List.filterMap_nil /-
+/- warning: list.filter_map_nil -> List.filterMap_nil is a dubious translation:
+lean 3 declaration is
+  forall {α : Type.{u1}} {β : Type.{u2}} (f : α -> (Option.{u2} β)), Eq.{succ u2} (List.{u2} β) (List.filterMap.{u1, u2} α β f (List.nil.{u1} α)) (List.nil.{u2} β)
+but is expected to have type
+  forall {α : Type.{u2}} {β : Type.{u1}} (f : α -> (Option.{u1} β)), Eq.{succ u1} (List.{u1} β) (List.filterMap.{u2, u1} α β f (List.nil.{u2} α)) (List.nil.{u1} β)
+Case conversion may be inaccurate. Consider using '#align list.filter_map_nil List.filterMap_nilₓ'. -/
 @[simp]
 theorem filterMap_nil (f : α → Option β) : filterMap f [] = [] :=
   rfl
 #align list.filter_map_nil List.filterMap_nil
--/
 
-#print List.filterMap_cons_none /-
+/- warning: list.filter_map_cons_none -> List.filterMap_cons_none is a dubious translation:
+lean 3 declaration is
+  forall {α : Type.{u1}} {β : Type.{u2}} {f : α -> (Option.{u2} β)} (a : α) (l : List.{u1} α), (Eq.{succ u2} (Option.{u2} β) (f a) (Option.none.{u2} β)) -> (Eq.{succ u2} (List.{u2} β) (List.filterMap.{u1, u2} α β f (List.cons.{u1} α a l)) (List.filterMap.{u1, u2} α β f l))
+but is expected to have type
+  forall {α : Type.{u2}} {β : Type.{u1}} {f : α -> (Option.{u1} β)} (a : α) (l : List.{u2} α), (Eq.{succ u1} (Option.{u1} β) (f a) (Option.none.{u1} β)) -> (Eq.{succ u1} (List.{u1} β) (List.filterMap.{u2, u1} α β f (List.cons.{u2} α a l)) (List.filterMap.{u2, u1} α β f l))
+Case conversion may be inaccurate. Consider using '#align list.filter_map_cons_none List.filterMap_cons_noneₓ'. -/
 @[simp]
 theorem filterMap_cons_none {f : α → Option β} (a : α) (l : List α) (h : f a = none) :
     filterMap f (a :: l) = filterMap f l := by simp only [filter_map, h]
 #align list.filter_map_cons_none List.filterMap_cons_none
--/
 
-#print List.filterMap_cons_some /-
+/- warning: list.filter_map_cons_some -> List.filterMap_cons_some is a dubious translation:
+lean 3 declaration is
+  forall {α : Type.{u1}} {β : Type.{u2}} (f : α -> (Option.{u2} β)) (a : α) (l : List.{u1} α) {b : β}, (Eq.{succ u2} (Option.{u2} β) (f a) (Option.some.{u2} β b)) -> (Eq.{succ u2} (List.{u2} β) (List.filterMap.{u1, u2} α β f (List.cons.{u1} α a l)) (List.cons.{u2} β b (List.filterMap.{u1, u2} α β f l)))
+but is expected to have type
+  forall {α : Type.{u2}} {β : Type.{u1}} (f : α -> (Option.{u1} β)) (a : α) (l : List.{u2} α) {b : β}, (Eq.{succ u1} (Option.{u1} β) (f a) (Option.some.{u1} β b)) -> (Eq.{succ u1} (List.{u1} β) (List.filterMap.{u2, u1} α β f (List.cons.{u2} α a l)) (List.cons.{u1} β b (List.filterMap.{u2, u1} α β f l)))
+Case conversion may be inaccurate. Consider using '#align list.filter_map_cons_some List.filterMap_cons_someₓ'. -/
 @[simp]
 theorem filterMap_cons_some (f : α → Option β) (a : α) (l : List α) {b : β} (h : f a = some b) :
     filterMap f (a :: l) = b :: filterMap f l := by
   simp only [filter_map, h] <;> constructor <;> rfl
 #align list.filter_map_cons_some List.filterMap_cons_some
--/
 
-#print List.filterMap_cons /-
+/- warning: list.filter_map_cons -> List.filterMap_cons is a dubious translation:
+lean 3 declaration is
+  forall {α : Type.{u1}} {β : Type.{u2}} (f : α -> (Option.{u2} β)) (a : α) (l : List.{u1} α), Eq.{succ u2} (List.{u2} β) (List.filterMap.{u1, u2} α β f (List.cons.{u1} α a l)) (Option.casesOn.{succ u2, u2} β (fun (_x : Option.{u2} β) => List.{u2} β) (f a) (List.filterMap.{u1, u2} α β f l) (fun (b : β) => List.cons.{u2} β b (List.filterMap.{u1, u2} α β f l)))
+but is expected to have type
+  forall {α : Type.{u2}} {β : Type.{u1}} (f : α -> (Option.{u1} β)) (a : α) (l : List.{u2} α), Eq.{succ u1} (List.{u1} β) (List.filterMap.{u2, u1} α β f (List.cons.{u2} α a l)) ([mdata save_info:1 List.filterMap_cons.match_1.{u1, succ u1} β (fun (_x : Option.{u1} β) => List.{u1} β) (f a) (fun (_ : Unit) => List.filterMap.{u2, u1} α β f l) (fun (b : β) => List.cons.{u1} β b (List.filterMap.{u2, u1} α β f l))])
+Case conversion may be inaccurate. Consider using '#align list.filter_map_cons List.filterMap_consₓ'. -/
 theorem filterMap_cons (f : α → Option β) (a : α) (l : List α) :
     filterMap f (a :: l) = Option.casesOn (f a) (filterMap f l) fun b => b :: filterMap f l :=
   by
@@ -5114,7 +5141,6 @@ theorem filterMap_cons (f : α → Option β) (a : α) (l : List α) :
   · rw [filter_map_cons_none _ _ Eq]
   · rw [filter_map_cons_some _ _ _ Eq]
 #align list.filter_map_cons List.filterMap_cons
--/
 
 /- warning: list.filter_map_append -> List.filterMap_append is a dubious translation:
 lean 3 declaration is
@@ -5131,20 +5157,24 @@ theorem filterMap_append {α β : Type _} (l l' : List α) (f : α → Option β
     cases f hd <;> simp only [filter_map, hl, cons_append, eq_self_iff_true, and_self_iff]
 #align list.filter_map_append List.filterMap_append
 
-#print List.filterMap_eq_map /-
+/- warning: list.filter_map_eq_map -> List.filterMap_eq_map is a dubious translation:
+lean 3 declaration is
+  forall {α : Type.{u1}} {β : Type.{u2}} (f : α -> β), Eq.{max (succ u1) (succ u2)} ((List.{u1} α) -> (List.{u2} β)) (List.filterMap.{u1, u2} α β (Function.comp.{succ u1, succ u2, succ u2} α β (Option.{u2} β) (Option.some.{u2} β) f)) (List.map.{u1, u2} α β f)
+but is expected to have type
+  forall {α : Type.{u2}} {β : Type.{u1}} (f : α -> β), Eq.{max (succ u2) (succ u1)} ((List.{u2} α) -> (List.{u1} β)) (List.filterMap.{u2, u1} α β (Function.comp.{succ u2, succ u1, succ u1} α β (Option.{u1} β) (Option.some.{u1} β) f)) (List.map.{u2, u1} α β f)
+Case conversion may be inaccurate. Consider using '#align list.filter_map_eq_map List.filterMap_eq_mapₓ'. -/
 theorem filterMap_eq_map (f : α → β) : filterMap (some ∘ f) = map f :=
   by
   funext l
   induction' l with a l IH; · rfl
   simp only [filter_map_cons_some (some ∘ f) _ _ rfl, IH, map_cons]; constructor <;> rfl
 #align list.filter_map_eq_map List.filterMap_eq_map
--/
 
 /- warning: list.filter_map_eq_filter -> List.filterMap_eq_filter is a dubious translation:
 lean 3 declaration is
   forall {α : Type.{u1}} (p : α -> Prop) [_inst_1 : DecidablePred.{succ u1} α p], Eq.{succ u1} ((List.{u1} α) -> (List.{u1} α)) (List.filterMap.{u1, u1} α α (Option.guard.{u1} α p (fun (a : α) => _inst_1 a))) (List.filterₓ.{u1} α p (fun (a : α) => _inst_1 a))
 but is expected to have type
-  forall {α : Type.{u1}} (p : α -> Bool), Eq.{succ u1} ((List.{u1} α) -> (List.{u1} α)) (List.filterMap.{u1, u1} α α (Option.guard.{u1} α (fun (x._@.Mathlib.Data.List.Basic._hyg.41856 : α) => Eq.{1} Bool (p x._@.Mathlib.Data.List.Basic._hyg.41856) Bool.true) (fun (a : α) => instDecidableEqBool (p a) Bool.true))) (List.filter.{u1} α p)
+  forall {α : Type.{u1}} (p : α -> Bool), Eq.{succ u1} ((List.{u1} α) -> (List.{u1} α)) (List.filterMap.{u1, u1} α α (Option.guard.{u1} α (fun (x._@.Std.Data.List.Lemmas._hyg.23784 : α) => Eq.{1} Bool (p x._@.Std.Data.List.Lemmas._hyg.23784) Bool.true) (fun (a : α) => instDecidableEqBool (p a) Bool.true))) (List.filter.{u1} α p)
 Case conversion may be inaccurate. Consider using '#align list.filter_map_eq_filter List.filterMap_eq_filterₓ'. -/
 theorem filterMap_eq_filter (p : α → Prop) [DecidablePred p] :
     filterMap (Option.guard p) = filter p := by
@@ -5156,7 +5186,12 @@ theorem filterMap_eq_filter (p : α → Prop) [DecidablePred p] :
   · simp only [filter_map, Option.guard, IH, if_neg pa, filter_cons_of_neg _ pa]
 #align list.filter_map_eq_filter List.filterMap_eq_filter
 
-#print List.filterMap_filterMap /-
+/- warning: list.filter_map_filter_map -> List.filterMap_filterMap is a dubious translation:
+lean 3 declaration is
+  forall {α : Type.{u1}} {β : Type.{u2}} {γ : Type.{u3}} (f : α -> (Option.{u2} β)) (g : β -> (Option.{u3} γ)) (l : List.{u1} α), Eq.{succ u3} (List.{u3} γ) (List.filterMap.{u2, u3} β γ g (List.filterMap.{u1, u2} α β f l)) (List.filterMap.{u1, u3} α γ (fun (x : α) => Option.bind.{u2, u3} β γ (f x) g) l)
+but is expected to have type
+  forall {α : Type.{u3}} {β : Type.{u2}} {γ : Type.{u1}} (f : α -> (Option.{u2} β)) (g : β -> (Option.{u1} γ)) (l : List.{u3} α), Eq.{succ u1} (List.{u1} γ) (List.filterMap.{u2, u1} β γ g (List.filterMap.{u3, u2} α β f l)) (List.filterMap.{u3, u1} α γ (fun (x : α) => Option.bind.{u2, u1} β γ (f x) g) l)
+Case conversion may be inaccurate. Consider using '#align list.filter_map_filter_map List.filterMap_filterMapₓ'. -/
 theorem filterMap_filterMap (f : α → Option β) (g : β → Option γ) (l : List α) :
     filterMap g (filterMap f l) = filterMap (fun x => (f x).bind g) l :=
   by
@@ -5169,27 +5204,34 @@ theorem filterMap_filterMap (f : α → Option β) (g : β → Option γ) (l : L
       rw [filter_map_cons_some _ _ _ h', filter_map_cons_some, IH]] <;>
     simp only [h, h', Option.some_bind']
 #align list.filter_map_filter_map List.filterMap_filterMap
--/
 
-#print List.map_filterMap /-
+/- warning: list.map_filter_map -> List.map_filterMap is a dubious translation:
+lean 3 declaration is
+  forall {α : Type.{u1}} {β : Type.{u2}} {γ : Type.{u3}} (f : α -> (Option.{u2} β)) (g : β -> γ) (l : List.{u1} α), Eq.{succ u3} (List.{u3} γ) (List.map.{u2, u3} β γ g (List.filterMap.{u1, u2} α β f l)) (List.filterMap.{u1, u3} α γ (fun (x : α) => Option.map.{u2, u3} β γ g (f x)) l)
+but is expected to have type
+  forall {α : Type.{u3}} {β : Type.{u2}} {γ : Type.{u1}} (f : α -> (Option.{u2} β)) (g : β -> γ) (l : List.{u3} α), Eq.{succ u1} (List.{u1} γ) (List.map.{u2, u1} β γ g (List.filterMap.{u3, u2} α β f l)) (List.filterMap.{u3, u1} α γ (fun (x : α) => Option.map.{u2, u1} β γ g (f x)) l)
+Case conversion may be inaccurate. Consider using '#align list.map_filter_map List.map_filterMapₓ'. -/
 theorem map_filterMap (f : α → Option β) (g : β → γ) (l : List α) :
     map g (filterMap f l) = filterMap (fun x => (f x).map g) l := by
   rw [← filter_map_eq_map, filter_map_filter_map] <;> rfl
 #align list.map_filter_map List.map_filterMap
--/
 
-#print List.filterMap_map /-
+/- warning: list.filter_map_map -> List.filterMap_map is a dubious translation:
+lean 3 declaration is
+  forall {α : Type.{u1}} {β : Type.{u2}} {γ : Type.{u3}} (f : α -> β) (g : β -> (Option.{u3} γ)) (l : List.{u1} α), Eq.{succ u3} (List.{u3} γ) (List.filterMap.{u2, u3} β γ g (List.map.{u1, u2} α β f l)) (List.filterMap.{u1, u3} α γ (Function.comp.{succ u1, succ u2, succ u3} α β (Option.{u3} γ) g f) l)
+but is expected to have type
+  forall {α : Type.{u3}} {β : Type.{u2}} {γ : Type.{u1}} (f : α -> β) (g : β -> (Option.{u1} γ)) (l : List.{u3} α), Eq.{succ u1} (List.{u1} γ) (List.filterMap.{u2, u1} β γ g (List.map.{u3, u2} α β f l)) (List.filterMap.{u3, u1} α γ (Function.comp.{succ u3, succ u2, succ u1} α β (Option.{u1} γ) g f) l)
+Case conversion may be inaccurate. Consider using '#align list.filter_map_map List.filterMap_mapₓ'. -/
 theorem filterMap_map (f : α → β) (g : β → Option γ) (l : List α) :
     filterMap g (map f l) = filterMap (g ∘ f) l := by
   rw [← filter_map_eq_map, filter_map_filter_map] <;> rfl
 #align list.filter_map_map List.filterMap_map
--/
 
 /- warning: list.filter_filter_map -> List.filter_filterMap is a dubious translation:
 lean 3 declaration is
   forall {α : Type.{u1}} {β : Type.{u2}} (f : α -> (Option.{u2} β)) (p : β -> Prop) [_inst_1 : DecidablePred.{succ u2} β p] (l : List.{u1} α), Eq.{succ u2} (List.{u2} β) (List.filterₓ.{u2} β p (fun (a : β) => _inst_1 a) (List.filterMap.{u1, u2} α β f l)) (List.filterMap.{u1, u2} α β (fun (x : α) => Option.filter.{u2} β p (fun (a : β) => _inst_1 a) (f x)) l)
 but is expected to have type
-  forall {α : Type.{u1}} {β : Type.{u2}} (f : α -> (Option.{u2} β)) (p : β -> Bool) (_inst_1 : List.{u1} α), Eq.{succ u2} (List.{u2} β) (List.filter.{u2} β p (List.filterMap.{u1, u2} α β f _inst_1)) (List.filterMap.{u1, u2} α β (fun (x : α) => Option.filter.{u2} β p (f x)) _inst_1)
+  forall {α : Type.{u2}} {β : Type.{u1}} (f : α -> (Option.{u1} β)) (p : β -> Bool) (_inst_1 : List.{u2} α), Eq.{succ u1} (List.{u1} β) (List.filter.{u1} β p (List.filterMap.{u2, u1} α β f _inst_1)) (List.filterMap.{u2, u1} α β (fun (x : α) => Option.filter.{u1} β p (f x)) _inst_1)
 Case conversion may be inaccurate. Consider using '#align list.filter_filter_map List.filter_filterMapₓ'. -/
 theorem filter_filterMap (f : α → Option β) (p : β → Prop) [DecidablePred p] (l : List α) :
     filter p (filterMap f l) = filterMap (fun x => (f x).filterₓ p) l := by
@@ -5200,7 +5242,7 @@ theorem filter_filterMap (f : α → Option β) (p : β → Prop) [DecidablePred
 lean 3 declaration is
   forall {α : Type.{u1}} {β : Type.{u2}} (p : α -> Prop) [_inst_1 : DecidablePred.{succ u1} α p] (f : α -> (Option.{u2} β)) (l : List.{u1} α), Eq.{succ u2} (List.{u2} β) (List.filterMap.{u1, u2} α β f (List.filterₓ.{u1} α p (fun (a : α) => _inst_1 a) l)) (List.filterMap.{u1, u2} α β (fun (x : α) => ite.{succ u2} (Option.{u2} β) (p x) (_inst_1 x) (f x) (Option.none.{u2} β)) l)
 but is expected to have type
-  forall {α : Type.{u1}} {β : Type.{u2}} (p : α -> Bool) (_inst_1 : α -> (Option.{u2} β)) (f : List.{u1} α), Eq.{succ u2} (List.{u2} β) (List.filterMap.{u1, u2} α β _inst_1 (List.filter.{u1} α p f)) (List.filterMap.{u1, u2} α β (fun (x : α) => ite.{succ u2} (Option.{u2} β) (Eq.{1} Bool (p x) Bool.true) (instDecidableEqBool (p x) Bool.true) (_inst_1 x) (Option.none.{u2} β)) f)
+  forall {α : Type.{u2}} {β : Type.{u1}} (p : α -> Bool) (_inst_1 : α -> (Option.{u1} β)) (f : List.{u2} α), Eq.{succ u1} (List.{u1} β) (List.filterMap.{u2, u1} α β _inst_1 (List.filter.{u2} α p f)) (List.filterMap.{u2, u1} α β (fun (x : α) => ite.{succ u1} (Option.{u1} β) (Eq.{1} Bool (p x) Bool.true) (instDecidableEqBool (p x) Bool.true) (_inst_1 x) (Option.none.{u1} β)) f)
 Case conversion may be inaccurate. Consider using '#align list.filter_map_filter List.filterMap_filterₓ'. -/
 theorem filterMap_filter (p : α → Prop) [DecidablePred p] (f : α → Option β) (l : List α) :
     filterMap f (filter p l) = filterMap (fun x => if p x then f x else none) l :=
@@ -5224,7 +5266,7 @@ theorem filterMap_some (l : List α) : filterMap some l = l := by
 lean 3 declaration is
   forall {α : Type.{u1}} {β : Type.{u2}} (f : α -> (Option.{u2} β)) (l : List.{u1} α), Eq.{succ u2} (List.{u2} (Option.{u2} β)) (List.map.{u2, u2} β (Option.{u2} β) (Option.some.{u2} β) (List.filterMap.{u1, u2} α β f l)) (List.filterₓ.{u2} (Option.{u2} β) (fun (b : Option.{u2} β) => coeSort.{1, 1} Bool Prop coeSortBool (Option.isSome.{u2} β b)) (fun (a : Option.{u2} β) => Bool.decidableEq (Option.isSome.{u2} β a) Bool.true) (List.map.{u1, u2} α (Option.{u2} β) f l))
 but is expected to have type
-  forall {α : Type.{u1}} {β : Type.{u2}} (f : α -> (Option.{u2} β)) (l : List.{u1} α), Eq.{succ u2} (List.{u2} (Option.{u2} β)) (List.map.{u2, u2} β (Option.{u2} β) (Option.some.{u2} β) (List.filterMap.{u1, u2} α β f l)) (List.filter.{u2} (Option.{u2} β) (fun (a : Option.{u2} β) => Option.isSome.{u2} β a) (List.map.{u1, u2} α (Option.{u2} β) f l))
+  forall {α : Type.{u2}} {β : Type.{u1}} (f : α -> (Option.{u1} β)) (l : List.{u2} α), Eq.{succ u1} (List.{u1} (Option.{u1} β)) (List.map.{u1, u1} β (Option.{u1} β) (Option.some.{u1} β) (List.filterMap.{u2, u1} α β f l)) (List.filter.{u1} (Option.{u1} β) (fun (a : Option.{u1} β) => Option.isSome.{u1} β a) (List.map.{u2, u1} α (Option.{u1} β) f l))
 Case conversion may be inaccurate. Consider using '#align list.map_filter_map_some_eq_filter_map_is_some List.map_filterMap_some_eq_filter_map_is_someₓ'. -/
 theorem map_filterMap_some_eq_filter_map_is_some (f : α → Option β) (l : List α) :
     (l.filterMap f).map some = (l.map f).filterₓ fun b => b.isSome :=
@@ -5234,7 +5276,12 @@ theorem map_filterMap_some_eq_filter_map_is_some (f : α → Option β) (l : Lis
   · cases h : f x <;> rw [List.filterMap_cons, h] <;> simp [h, ih]
 #align list.map_filter_map_some_eq_filter_map_is_some List.map_filterMap_some_eq_filter_map_is_some
 
-#print List.mem_filterMap /-
+/- warning: list.mem_filter_map -> List.mem_filterMap is a dubious translation:
+lean 3 declaration is
+  forall {α : Type.{u1}} {β : Type.{u2}} (f : α -> (Option.{u2} β)) (l : List.{u1} α) {b : β}, Iff (Membership.Mem.{u2, u2} β (List.{u2} β) (List.hasMem.{u2} β) b (List.filterMap.{u1, u2} α β f l)) (Exists.{succ u1} α (fun (a : α) => And (Membership.Mem.{u1, u1} α (List.{u1} α) (List.hasMem.{u1} α) a l) (Eq.{succ u2} (Option.{u2} β) (f a) (Option.some.{u2} β b))))
+but is expected to have type
+  forall {α : Type.{u2}} {β : Type.{u1}} (f : α -> (Option.{u1} β)) (l : List.{u2} α) {b : β}, Iff (Membership.mem.{u1, u1} β (List.{u1} β) (List.instMembershipList.{u1} β) b (List.filterMap.{u2, u1} α β f l)) (Exists.{succ u2} α (fun (a : α) => And (Membership.mem.{u2, u2} α (List.{u2} α) (List.instMembershipList.{u2} α) a l) (Eq.{succ u1} (Option.{u1} β) (f a) (Option.some.{u1} β b))))
+Case conversion may be inaccurate. Consider using '#align list.mem_filter_map List.mem_filterMapₓ'. -/
 @[simp]
 theorem mem_filterMap (f : α → Option β) (l : List α) {b : β} :
     b ∈ filterMap f l ↔ ∃ a, a ∈ l ∧ f a = some b :=
@@ -5259,9 +5306,13 @@ theorem mem_filterMap (f : α → Option β) (l : List α) {b : β} :
     simp only [filter_map_cons_some _ _ _ h, IH, mem_cons_iff, or_and_right, exists_or, this,
       exists_eq_left]
 #align list.mem_filter_map List.mem_filterMap
--/
 
-#print List.filterMap_join /-
+/- warning: list.filter_map_join -> List.filterMap_join is a dubious translation:
+lean 3 declaration is
+  forall {α : Type.{u1}} {β : Type.{u2}} (f : α -> (Option.{u2} β)) (L : List.{u1} (List.{u1} α)), Eq.{succ u2} (List.{u2} β) (List.filterMap.{u1, u2} α β f (List.join.{u1} α L)) (List.join.{u2} β (List.map.{u1, u2} (List.{u1} α) (List.{u2} β) (List.filterMap.{u1, u2} α β f) L))
+but is expected to have type
+  forall {α : Type.{u2}} {β : Type.{u1}} (f : α -> (Option.{u1} β)) (L : List.{u2} (List.{u2} α)), Eq.{succ u1} (List.{u1} β) (List.filterMap.{u2, u1} α β f (List.join.{u2} α L)) (List.join.{u1} β (List.map.{u2, u1} (List.{u2} α) (List.{u1} β) (List.filterMap.{u2, u1} α β f) L))
+Case conversion may be inaccurate. Consider using '#align list.filter_map_join List.filterMap_joinₓ'. -/
 @[simp]
 theorem filterMap_join (f : α → Option β) (L : List (List α)) :
     filterMap f (join L) = join (map (filterMap f) L) :=
@@ -5270,35 +5321,46 @@ theorem filterMap_join (f : α → Option β) (L : List (List α)) :
   · rfl
   · rw [map, join, join, filter_map_append, ih]
 #align list.filter_map_join List.filterMap_join
--/
 
-#print List.map_filterMap_of_inv /-
+/- warning: list.map_filter_map_of_inv -> List.map_filterMap_of_inv is a dubious translation:
+lean 3 declaration is
+  forall {α : Type.{u1}} {β : Type.{u2}} (f : α -> (Option.{u2} β)) (g : β -> α), (forall (x : α), Eq.{succ u1} (Option.{u1} α) (Option.map.{u2, u1} β α g (f x)) (Option.some.{u1} α x)) -> (forall (l : List.{u1} α), Eq.{succ u1} (List.{u1} α) (List.map.{u2, u1} β α g (List.filterMap.{u1, u2} α β f l)) l)
+but is expected to have type
+  forall {α : Type.{u2}} {β : Type.{u1}} (f : α -> (Option.{u1} β)) (g : β -> α), (forall (x : α), Eq.{succ u2} (Option.{u2} α) (Option.map.{u1, u2} β α g (f x)) (Option.some.{u2} α x)) -> (forall (l : List.{u2} α), Eq.{succ u2} (List.{u2} α) (List.map.{u1, u2} β α g (List.filterMap.{u2, u1} α β f l)) l)
+Case conversion may be inaccurate. Consider using '#align list.map_filter_map_of_inv List.map_filterMap_of_invₓ'. -/
 theorem map_filterMap_of_inv (f : α → Option β) (g : β → α) (H : ∀ x : α, (f x).map g = some x)
     (l : List α) : map g (filterMap f l) = l := by simp only [map_filter_map, H, filter_map_some]
 #align list.map_filter_map_of_inv List.map_filterMap_of_inv
--/
 
 theorem length_filter_le (p : α → Prop) [DecidablePred p] (l : List α) :
     (l.filterₓ p).length ≤ l.length :=
   (List.filter_sublist _).length_le
 #align list.length_filter_le List.length_filter_leₓ
 
-#print List.length_filterMap_le /-
+/- warning: list.length_filter_map_le -> List.length_filterMap_le is a dubious translation:
+lean 3 declaration is
+  forall {α : Type.{u1}} {β : Type.{u2}} (f : α -> (Option.{u2} β)) (l : List.{u1} α), LE.le.{0} Nat Nat.hasLe (List.length.{u2} β (List.filterMap.{u1, u2} α β f l)) (List.length.{u1} α l)
+but is expected to have type
+  forall {α : Type.{u2}} {β : Type.{u1}} (f : α -> (Option.{u1} β)) (l : List.{u2} α), LE.le.{0} Nat instLENat (List.length.{u1} β (List.filterMap.{u2, u1} α β f l)) (List.length.{u2} α l)
+Case conversion may be inaccurate. Consider using '#align list.length_filter_map_le List.length_filterMap_leₓ'. -/
 theorem length_filterMap_le (f : α → Option β) (l : List α) :
     (List.filterMap f l).length ≤ l.length :=
   by
   rw [← List.length_map some, List.map_filterMap_some_eq_filter_map_is_some, ← List.length_map f]
   apply List.length_filter_le
 #align list.length_filter_map_le List.length_filterMap_le
--/
 
-#print List.Sublist.filterMap /-
+/- warning: list.sublist.filter_map -> List.Sublist.filterMap is a dubious translation:
+lean 3 declaration is
+  forall {α : Type.{u1}} {β : Type.{u2}} (f : α -> (Option.{u2} β)) {l₁ : List.{u1} α} {l₂ : List.{u1} α}, (List.Sublist.{u1} α l₁ l₂) -> (List.Sublist.{u2} β (List.filterMap.{u1, u2} α β f l₁) (List.filterMap.{u1, u2} α β f l₂))
+but is expected to have type
+  forall {α : Type.{u2}} {β : Type.{u1}} {f : List.{u2} α} {l₁ : List.{u2} α} (l₂ : α -> (Option.{u1} β)), (List.Sublist.{u2} α f l₁) -> (List.Sublist.{u1} β (List.filterMap.{u2, u1} α β l₂ f) (List.filterMap.{u2, u1} α β l₂ l₁))
+Case conversion may be inaccurate. Consider using '#align list.sublist.filter_map List.Sublist.filterMapₓ'. -/
 theorem Sublist.filterMap (f : α → Option β) {l₁ l₂ : List α} (s : l₁ <+ l₂) :
     filterMap f l₁ <+ filterMap f l₂ := by
   induction' s with l₁ l₂ a s IH l₁ l₂ a s IH <;> simp only [filter_map] <;> cases' f a with b <;>
     simp only [filter_map, IH, sublist.cons, sublist.cons2]
 #align list.sublist.filter_map List.Sublist.filterMap
--/
 
 #print List.Sublist.map /-
 theorem Sublist.map (f : α → β) {l₁ l₂ : List α} (s : l₁ <+ l₂) : map f l₁ <+ map f l₂ :=
@@ -5625,7 +5687,7 @@ theorem monotone_filter_right (l : List α) ⦃p q : α → Prop⦄ [DecidablePr
 lean 3 declaration is
   forall {α : Type.{u1}} {β : Type.{u2}} (p : α -> Prop) [_inst_1 : DecidablePred.{succ u1} α p] (f : β -> α) (l : List.{u2} β), Eq.{succ u1} (List.{u1} α) (List.filterₓ.{u1} α p (fun (a : α) => _inst_1 a) (List.map.{u2, u1} β α f l)) (List.map.{u2, u1} β α f (List.filterₓ.{u2} β (Function.comp.{succ u2, succ u1, 1} β α Prop p f) (fun (a : β) => _inst_1 (f a)) l))
 but is expected to have type
-  forall {α : Type.{u1}} {β : Type.{u2}} (p : α -> Bool) (_inst_1 : β -> α) (f : List.{u2} β), Eq.{succ u1} (List.{u1} α) (List.filter.{u1} α p (List.map.{u2, u1} β α _inst_1 f)) (List.map.{u2, u1} β α _inst_1 (List.filter.{u2} β (Function.comp.{succ u2, succ u1, 1} β α Bool p _inst_1) f))
+  forall {α : Type.{u2}} {β : Type.{u1}} {p : β -> Bool} (_inst_1 : α -> β) (f : List.{u2} α), Eq.{succ u1} (List.{u1} β) (List.filter.{u1} β p (List.map.{u2, u1} α β _inst_1 f)) (List.map.{u2, u1} α β _inst_1 (List.filter.{u2} α (Function.comp.{succ u2, succ u1, 1} α β Bool p _inst_1) f))
 Case conversion may be inaccurate. Consider using '#align list.map_filter List.map_filterₓ'. -/
 theorem map_filter (f : β → α) (l : List β) : filter p (map f l) = map f (filter (p ∘ f) l) := by
   rw [← filter_map_eq_map, filter_filter_map, filter_map_filter] <;> rfl
@@ -5635,7 +5697,7 @@ theorem map_filter (f : β → α) (l : List β) : filter p (map f l) = map f (f
 lean 3 declaration is
   forall {α : Type.{u1}} (p : α -> Prop) [_inst_1 : DecidablePred.{succ u1} α p] (q : α -> Prop) [_inst_2 : DecidablePred.{succ u1} α q] (l : List.{u1} α), Eq.{succ u1} (List.{u1} α) (List.filterₓ.{u1} α p (fun (a : α) => _inst_1 a) (List.filterₓ.{u1} α q (fun (a : α) => _inst_2 a) l)) (List.filterₓ.{u1} α (fun (a : α) => And (p a) (q a)) (fun (a : α) => And.decidable (p a) (q a) (_inst_1 a) (_inst_2 a)) l)
 but is expected to have type
-  forall {α : Type.{u1}} (p : α -> Bool) (_inst_1 : α -> Bool) (q : List.{u1} α), Eq.{succ u1} (List.{u1} α) (List.filter.{u1} α p (List.filter.{u1} α _inst_1 q)) (List.filter.{u1} α (fun (a : α) => Decidable.decide (And (Eq.{1} Bool (p a) Bool.true) (Eq.{1} Bool (_inst_1 a) Bool.true)) (instDecidableAnd (Eq.{1} Bool (p a) Bool.true) (Eq.{1} Bool (_inst_1 a) Bool.true) (instDecidableEqBool (p a) Bool.true) (instDecidableEqBool (_inst_1 a) Bool.true))) q)
+  forall {α : Type.{u1}} {p : α -> Bool} (_inst_1 : α -> Bool) (q : List.{u1} α), Eq.{succ u1} (List.{u1} α) (List.filter.{u1} α p (List.filter.{u1} α _inst_1 q)) (List.filter.{u1} α (fun (a : α) => Decidable.decide (And (Eq.{1} Bool (p a) Bool.true) (Eq.{1} Bool (_inst_1 a) Bool.true)) (instDecidableAnd (Eq.{1} Bool (p a) Bool.true) (Eq.{1} Bool (_inst_1 a) Bool.true) (instDecidableEqBool (p a) Bool.true) (instDecidableEqBool (_inst_1 a) Bool.true))) q)
 Case conversion may be inaccurate. Consider using '#align list.filter_filter List.filter_filterₓ'. -/
 @[simp]
 theorem filter_filter (q) [DecidablePred q] :
@@ -5651,7 +5713,7 @@ theorem filter_filter (q) [DecidablePred q] :
 lean 3 declaration is
   forall {α : Type.{u1}} {h : DecidablePred.{succ u1} α (fun (a : α) => True)} (l : List.{u1} α), Eq.{succ u1} (List.{u1} α) (List.filterₓ.{u1} α (fun (_x : α) => True) h l) l
 but is expected to have type
-  forall {α : Type.{u1}} (h : List.{u1} α), Eq.{succ u1} (List.{u1} α) (List.filter.{u1} α (fun (x._@.Mathlib.Data.List.Basic._hyg.45961 : α) => Bool.true) h) h
+  forall {α : Type.{u1}} (h : List.{u1} α), Eq.{succ u1} (List.{u1} α) (List.filter.{u1} α (fun (x._@.Mathlib.Data.List.Basic._hyg.41267 : α) => Bool.true) h) h
 Case conversion may be inaccurate. Consider using '#align list.filter_true List.filter_trueₓ'. -/
 @[simp]
 theorem filter_true {h : DecidablePred fun a : α => True} (l : List α) :
@@ -5662,7 +5724,7 @@ theorem filter_true {h : DecidablePred fun a : α => True} (l : List α) :
 lean 3 declaration is
   forall {α : Type.{u1}} {h : DecidablePred.{succ u1} α (fun (a : α) => False)} (l : List.{u1} α), Eq.{succ u1} (List.{u1} α) (List.filterₓ.{u1} α (fun (_x : α) => False) h l) (List.nil.{u1} α)
 but is expected to have type
-  forall {α : Type.{u1}} (h : List.{u1} α), Eq.{succ u1} (List.{u1} α) (List.filter.{u1} α (fun (x._@.Mathlib.Data.List.Basic._hyg.46011 : α) => Bool.false) h) (List.nil.{u1} α)
+  forall {α : Type.{u1}} (h : List.{u1} α), Eq.{succ u1} (List.{u1} α) (List.filter.{u1} α (fun (x._@.Mathlib.Data.List.Basic._hyg.41317 : α) => Bool.false) h) (List.nil.{u1} α)
 Case conversion may be inaccurate. Consider using '#align list.filter_false List.filter_falseₓ'. -/
 @[simp]
 theorem filter_false {h : DecidablePred fun a : α => False} (l : List α) :
Diff
@@ -3607,7 +3607,7 @@ theorem nthLe_drop (L : List α) {i j : ℕ} (h : i + j < L.length) :
 lean 3 declaration is
   forall {α : Type.{u1}} (L : List.{u1} α) {i : Nat} {j : Nat} (h : LT.lt.{0} Nat Nat.hasLt j (List.length.{u1} α (List.drop.{u1} α i L))), Eq.{succ u1} α (List.nthLe.{u1} α (List.drop.{u1} α i L) j h) (List.nthLe.{u1} α L (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat Nat.hasAdd) i j) (Iff.mp (LT.lt.{0} Nat (Preorder.toLT.{0} Nat (PartialOrder.toPreorder.{0} Nat (SemilatticeInf.toPartialOrder.{0} Nat (Lattice.toSemilatticeInf.{0} Nat (LinearOrder.toLattice.{0} Nat Nat.linearOrder))))) j (HSub.hSub.{0, 0, 0} Nat Nat Nat (instHSub.{0} Nat Nat.hasSub) (List.length.{u1} α L) i)) (LT.lt.{0} Nat (Preorder.toLT.{0} Nat (PartialOrder.toPreorder.{0} Nat (SemilatticeInf.toPartialOrder.{0} Nat (Lattice.toSemilatticeInf.{0} Nat (LinearOrder.toLattice.{0} Nat Nat.linearOrder))))) (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat (AddSemigroup.toHasAdd.{0} Nat (AddCommSemigroup.toAddSemigroup.{0} Nat Nat.addCommSemigroup))) i j) (List.length.{u1} α L)) (lt_tsub_iff_left.{0} Nat j (List.length.{u1} α L) i Nat.linearOrder Nat.addCommSemigroup Nat.hasSub Nat.hasOrderedSub) (Eq.subst.{1} Nat (fun (_x : Nat) => LT.lt.{0} Nat (Preorder.toLT.{0} Nat (PartialOrder.toPreorder.{0} Nat (SemilatticeInf.toPartialOrder.{0} Nat (Lattice.toSemilatticeInf.{0} Nat (LinearOrder.toLattice.{0} Nat Nat.linearOrder))))) j _x) (List.length.{u1} α (List.drop.{u1} α i L)) (HSub.hSub.{0, 0, 0} Nat Nat Nat (instHSub.{0} Nat Nat.hasSub) (List.length.{u1} α L) i) (List.length_drop.{u1} α i L) h)))
 but is expected to have type
-  forall {α : Type.{u1}} (L : List.{u1} α) {i : Nat} {j : Nat} (h : LT.lt.{0} Nat instLTNat j (List.length.{u1} α (List.drop.{u1} α i L))), Eq.{succ u1} α (List.nthLe.{u1} α (List.drop.{u1} α i L) j h) (List.nthLe.{u1} α L (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat instAddNat) i j) (Iff.mp (LT.lt.{0} Nat (Preorder.toLT.{0} Nat (PartialOrder.toPreorder.{0} Nat (SemilatticeInf.toPartialOrder.{0} Nat (Lattice.toSemilatticeInf.{0} Nat (DistribLattice.toLattice.{0} Nat (instDistribLattice.{0} Nat Nat.linearOrder)))))) j (HSub.hSub.{0, 0, 0} Nat Nat Nat (instHSub.{0} Nat instSubNat) (List.length.{u1} α L) i)) (LT.lt.{0} Nat (Preorder.toLT.{0} Nat (PartialOrder.toPreorder.{0} Nat (SemilatticeInf.toPartialOrder.{0} Nat (Lattice.toSemilatticeInf.{0} Nat (DistribLattice.toLattice.{0} Nat (instDistribLattice.{0} Nat Nat.linearOrder)))))) (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat (AddSemigroup.toAdd.{0} Nat (AddCommSemigroup.toAddSemigroup.{0} Nat Nat.addCommSemigroup))) i j) (List.length.{u1} α L)) (lt_tsub_iff_left.{0} Nat j (List.length.{u1} α L) i Nat.linearOrder Nat.addCommSemigroup instSubNat Nat.instOrderedSubNatInstLENatInstAddNatInstSubNat) (Eq.rec.{0, 1} Nat (List.length.{u1} α (List.drop.{u1} α i L)) (fun (x._@.Mathlib.Data.List.Basic._hyg.25683 : Nat) (h._@.Mathlib.Data.List.Basic._hyg.25684 : Eq.{1} Nat (List.length.{u1} α (List.drop.{u1} α i L)) x._@.Mathlib.Data.List.Basic._hyg.25683) => LT.lt.{0} Nat (Preorder.toLT.{0} Nat (PartialOrder.toPreorder.{0} Nat (SemilatticeInf.toPartialOrder.{0} Nat (Lattice.toSemilatticeInf.{0} Nat (DistribLattice.toLattice.{0} Nat (instDistribLattice.{0} Nat Nat.linearOrder)))))) j x._@.Mathlib.Data.List.Basic._hyg.25683) h (HSub.hSub.{0, 0, 0} Nat Nat Nat (instHSub.{0} Nat instSubNat) (List.length.{u1} α L) i) (List.length_drop.{u1} α i L))))
+  forall {α : Type.{u1}} (L : List.{u1} α) {i : Nat} {j : Nat} (h : LT.lt.{0} Nat instLTNat j (List.length.{u1} α (List.drop.{u1} α i L))), Eq.{succ u1} α (List.nthLe.{u1} α (List.drop.{u1} α i L) j h) (List.nthLe.{u1} α L (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat instAddNat) i j) (Iff.mp (LT.lt.{0} Nat (Preorder.toLT.{0} Nat (PartialOrder.toPreorder.{0} Nat (SemilatticeInf.toPartialOrder.{0} Nat (Lattice.toSemilatticeInf.{0} Nat (DistribLattice.toLattice.{0} Nat (instDistribLattice.{0} Nat Nat.linearOrder)))))) j (HSub.hSub.{0, 0, 0} Nat Nat Nat (instHSub.{0} Nat instSubNat) (List.length.{u1} α L) i)) (LT.lt.{0} Nat (Preorder.toLT.{0} Nat (PartialOrder.toPreorder.{0} Nat (SemilatticeInf.toPartialOrder.{0} Nat (Lattice.toSemilatticeInf.{0} Nat (DistribLattice.toLattice.{0} Nat (instDistribLattice.{0} Nat Nat.linearOrder)))))) (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat (AddSemigroup.toAdd.{0} Nat (AddCommSemigroup.toAddSemigroup.{0} Nat Nat.addCommSemigroup))) i j) (List.length.{u1} α L)) (lt_tsub_iff_left.{0} Nat j (List.length.{u1} α L) i Nat.linearOrder Nat.addCommSemigroup instSubNat Nat.instOrderedSubNatInstLENatInstAddNatInstSubNat) (Eq.rec.{0, 1} Nat (List.length.{u1} α (List.drop.{u1} α i L)) (fun (x._@.Mathlib.Data.List.Basic._hyg.25290 : Nat) (h._@.Mathlib.Data.List.Basic._hyg.25291 : Eq.{1} Nat (List.length.{u1} α (List.drop.{u1} α i L)) x._@.Mathlib.Data.List.Basic._hyg.25290) => LT.lt.{0} Nat (Preorder.toLT.{0} Nat (PartialOrder.toPreorder.{0} Nat (SemilatticeInf.toPartialOrder.{0} Nat (Lattice.toSemilatticeInf.{0} Nat (DistribLattice.toLattice.{0} Nat (instDistribLattice.{0} Nat Nat.linearOrder)))))) j x._@.Mathlib.Data.List.Basic._hyg.25290) h (HSub.hSub.{0, 0, 0} Nat Nat Nat (instHSub.{0} Nat instSubNat) (List.length.{u1} α L) i) (List.length_drop.{u1} α i L))))
 Case conversion may be inaccurate. Consider using '#align list.nth_le_drop' List.nthLe_drop'ₓ'. -/
 /-- The `i + j`-th element of a list coincides with the `j`-th element of the list obtained by
 dropping the first `i` elements. Version designed to rewrite from the small list to the big list. -/
@@ -5144,7 +5144,7 @@ theorem filterMap_eq_map (f : α → β) : filterMap (some ∘ f) = map f :=
 lean 3 declaration is
   forall {α : Type.{u1}} (p : α -> Prop) [_inst_1 : DecidablePred.{succ u1} α p], Eq.{succ u1} ((List.{u1} α) -> (List.{u1} α)) (List.filterMap.{u1, u1} α α (Option.guard.{u1} α p (fun (a : α) => _inst_1 a))) (List.filterₓ.{u1} α p (fun (a : α) => _inst_1 a))
 but is expected to have type
-  forall {α : Type.{u1}} (p : α -> Bool), Eq.{succ u1} ((List.{u1} α) -> (List.{u1} α)) (List.filterMap.{u1, u1} α α (Option.guard.{u1} α (fun (x._@.Mathlib.Data.List.Basic._hyg.42249 : α) => Eq.{1} Bool (p x._@.Mathlib.Data.List.Basic._hyg.42249) Bool.true) (fun (a : α) => instDecidableEqBool (p a) Bool.true))) (List.filter.{u1} α p)
+  forall {α : Type.{u1}} (p : α -> Bool), Eq.{succ u1} ((List.{u1} α) -> (List.{u1} α)) (List.filterMap.{u1, u1} α α (Option.guard.{u1} α (fun (x._@.Mathlib.Data.List.Basic._hyg.41856 : α) => Eq.{1} Bool (p x._@.Mathlib.Data.List.Basic._hyg.41856) Bool.true) (fun (a : α) => instDecidableEqBool (p a) Bool.true))) (List.filter.{u1} α p)
 Case conversion may be inaccurate. Consider using '#align list.filter_map_eq_filter List.filterMap_eq_filterₓ'. -/
 theorem filterMap_eq_filter (p : α → Prop) [DecidablePred p] :
     filterMap (Option.guard p) = filter p := by
@@ -5651,7 +5651,7 @@ theorem filter_filter (q) [DecidablePred q] :
 lean 3 declaration is
   forall {α : Type.{u1}} {h : DecidablePred.{succ u1} α (fun (a : α) => True)} (l : List.{u1} α), Eq.{succ u1} (List.{u1} α) (List.filterₓ.{u1} α (fun (_x : α) => True) h l) l
 but is expected to have type
-  forall {α : Type.{u1}} (h : List.{u1} α), Eq.{succ u1} (List.{u1} α) (List.filter.{u1} α (fun (x._@.Mathlib.Data.List.Basic._hyg.46354 : α) => Bool.true) h) h
+  forall {α : Type.{u1}} (h : List.{u1} α), Eq.{succ u1} (List.{u1} α) (List.filter.{u1} α (fun (x._@.Mathlib.Data.List.Basic._hyg.45961 : α) => Bool.true) h) h
 Case conversion may be inaccurate. Consider using '#align list.filter_true List.filter_trueₓ'. -/
 @[simp]
 theorem filter_true {h : DecidablePred fun a : α => True} (l : List α) :
@@ -5662,7 +5662,7 @@ theorem filter_true {h : DecidablePred fun a : α => True} (l : List α) :
 lean 3 declaration is
   forall {α : Type.{u1}} {h : DecidablePred.{succ u1} α (fun (a : α) => False)} (l : List.{u1} α), Eq.{succ u1} (List.{u1} α) (List.filterₓ.{u1} α (fun (_x : α) => False) h l) (List.nil.{u1} α)
 but is expected to have type
-  forall {α : Type.{u1}} (h : List.{u1} α), Eq.{succ u1} (List.{u1} α) (List.filter.{u1} α (fun (x._@.Mathlib.Data.List.Basic._hyg.46404 : α) => Bool.false) h) (List.nil.{u1} α)
+  forall {α : Type.{u1}} (h : List.{u1} α), Eq.{succ u1} (List.{u1} α) (List.filter.{u1} α (fun (x._@.Mathlib.Data.List.Basic._hyg.46011 : α) => Bool.false) h) (List.nil.{u1} α)
 Case conversion may be inaccurate. Consider using '#align list.filter_false List.filter_falseₓ'. -/
 @[simp]
 theorem filter_false {h : DecidablePred fun a : α => False} (l : List α) :
Diff
@@ -3607,7 +3607,7 @@ theorem nthLe_drop (L : List α) {i j : ℕ} (h : i + j < L.length) :
 lean 3 declaration is
   forall {α : Type.{u1}} (L : List.{u1} α) {i : Nat} {j : Nat} (h : LT.lt.{0} Nat Nat.hasLt j (List.length.{u1} α (List.drop.{u1} α i L))), Eq.{succ u1} α (List.nthLe.{u1} α (List.drop.{u1} α i L) j h) (List.nthLe.{u1} α L (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat Nat.hasAdd) i j) (Iff.mp (LT.lt.{0} Nat (Preorder.toLT.{0} Nat (PartialOrder.toPreorder.{0} Nat (SemilatticeInf.toPartialOrder.{0} Nat (Lattice.toSemilatticeInf.{0} Nat (LinearOrder.toLattice.{0} Nat Nat.linearOrder))))) j (HSub.hSub.{0, 0, 0} Nat Nat Nat (instHSub.{0} Nat Nat.hasSub) (List.length.{u1} α L) i)) (LT.lt.{0} Nat (Preorder.toLT.{0} Nat (PartialOrder.toPreorder.{0} Nat (SemilatticeInf.toPartialOrder.{0} Nat (Lattice.toSemilatticeInf.{0} Nat (LinearOrder.toLattice.{0} Nat Nat.linearOrder))))) (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat (AddSemigroup.toHasAdd.{0} Nat (AddCommSemigroup.toAddSemigroup.{0} Nat Nat.addCommSemigroup))) i j) (List.length.{u1} α L)) (lt_tsub_iff_left.{0} Nat j (List.length.{u1} α L) i Nat.linearOrder Nat.addCommSemigroup Nat.hasSub Nat.hasOrderedSub) (Eq.subst.{1} Nat (fun (_x : Nat) => LT.lt.{0} Nat (Preorder.toLT.{0} Nat (PartialOrder.toPreorder.{0} Nat (SemilatticeInf.toPartialOrder.{0} Nat (Lattice.toSemilatticeInf.{0} Nat (LinearOrder.toLattice.{0} Nat Nat.linearOrder))))) j _x) (List.length.{u1} α (List.drop.{u1} α i L)) (HSub.hSub.{0, 0, 0} Nat Nat Nat (instHSub.{0} Nat Nat.hasSub) (List.length.{u1} α L) i) (List.length_drop.{u1} α i L) h)))
 but is expected to have type
-  forall {α : Type.{u1}} (L : List.{u1} α) {i : Nat} {j : Nat} (h : LT.lt.{0} Nat instLTNat j (List.length.{u1} α (List.drop.{u1} α i L))), Eq.{succ u1} α (List.nthLe.{u1} α (List.drop.{u1} α i L) j h) (List.nthLe.{u1} α L (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat instAddNat) i j) (Iff.mp (LT.lt.{0} Nat (Preorder.toLT.{0} Nat (PartialOrder.toPreorder.{0} Nat (SemilatticeInf.toPartialOrder.{0} Nat (Lattice.toSemilatticeInf.{0} Nat (DistribLattice.toLattice.{0} Nat (instDistribLattice.{0} Nat Nat.linearOrder)))))) j (HSub.hSub.{0, 0, 0} Nat Nat Nat (instHSub.{0} Nat instSubNat) (List.length.{u1} α L) i)) (LT.lt.{0} Nat (Preorder.toLT.{0} Nat (PartialOrder.toPreorder.{0} Nat (SemilatticeInf.toPartialOrder.{0} Nat (Lattice.toSemilatticeInf.{0} Nat (DistribLattice.toLattice.{0} Nat (instDistribLattice.{0} Nat Nat.linearOrder)))))) (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat (AddSemigroup.toAdd.{0} Nat (AddCommSemigroup.toAddSemigroup.{0} Nat Nat.addCommSemigroup))) i j) (List.length.{u1} α L)) (lt_tsub_iff_left.{0} Nat j (List.length.{u1} α L) i Nat.linearOrder Nat.addCommSemigroup instSubNat Nat.instOrderedSubNatInstLENatInstAddNatInstSubNat) (Eq.rec.{0, 1} Nat (List.length.{u1} α (List.drop.{u1} α i L)) (fun (x._@.Mathlib.Data.List.Basic._hyg.25563 : Nat) (h._@.Mathlib.Data.List.Basic._hyg.25564 : Eq.{1} Nat (List.length.{u1} α (List.drop.{u1} α i L)) x._@.Mathlib.Data.List.Basic._hyg.25563) => LT.lt.{0} Nat (Preorder.toLT.{0} Nat (PartialOrder.toPreorder.{0} Nat (SemilatticeInf.toPartialOrder.{0} Nat (Lattice.toSemilatticeInf.{0} Nat (DistribLattice.toLattice.{0} Nat (instDistribLattice.{0} Nat Nat.linearOrder)))))) j x._@.Mathlib.Data.List.Basic._hyg.25563) h (HSub.hSub.{0, 0, 0} Nat Nat Nat (instHSub.{0} Nat instSubNat) (List.length.{u1} α L) i) (List.length_drop.{u1} α i L))))
+  forall {α : Type.{u1}} (L : List.{u1} α) {i : Nat} {j : Nat} (h : LT.lt.{0} Nat instLTNat j (List.length.{u1} α (List.drop.{u1} α i L))), Eq.{succ u1} α (List.nthLe.{u1} α (List.drop.{u1} α i L) j h) (List.nthLe.{u1} α L (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat instAddNat) i j) (Iff.mp (LT.lt.{0} Nat (Preorder.toLT.{0} Nat (PartialOrder.toPreorder.{0} Nat (SemilatticeInf.toPartialOrder.{0} Nat (Lattice.toSemilatticeInf.{0} Nat (DistribLattice.toLattice.{0} Nat (instDistribLattice.{0} Nat Nat.linearOrder)))))) j (HSub.hSub.{0, 0, 0} Nat Nat Nat (instHSub.{0} Nat instSubNat) (List.length.{u1} α L) i)) (LT.lt.{0} Nat (Preorder.toLT.{0} Nat (PartialOrder.toPreorder.{0} Nat (SemilatticeInf.toPartialOrder.{0} Nat (Lattice.toSemilatticeInf.{0} Nat (DistribLattice.toLattice.{0} Nat (instDistribLattice.{0} Nat Nat.linearOrder)))))) (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat (AddSemigroup.toAdd.{0} Nat (AddCommSemigroup.toAddSemigroup.{0} Nat Nat.addCommSemigroup))) i j) (List.length.{u1} α L)) (lt_tsub_iff_left.{0} Nat j (List.length.{u1} α L) i Nat.linearOrder Nat.addCommSemigroup instSubNat Nat.instOrderedSubNatInstLENatInstAddNatInstSubNat) (Eq.rec.{0, 1} Nat (List.length.{u1} α (List.drop.{u1} α i L)) (fun (x._@.Mathlib.Data.List.Basic._hyg.25683 : Nat) (h._@.Mathlib.Data.List.Basic._hyg.25684 : Eq.{1} Nat (List.length.{u1} α (List.drop.{u1} α i L)) x._@.Mathlib.Data.List.Basic._hyg.25683) => LT.lt.{0} Nat (Preorder.toLT.{0} Nat (PartialOrder.toPreorder.{0} Nat (SemilatticeInf.toPartialOrder.{0} Nat (Lattice.toSemilatticeInf.{0} Nat (DistribLattice.toLattice.{0} Nat (instDistribLattice.{0} Nat Nat.linearOrder)))))) j x._@.Mathlib.Data.List.Basic._hyg.25683) h (HSub.hSub.{0, 0, 0} Nat Nat Nat (instHSub.{0} Nat instSubNat) (List.length.{u1} α L) i) (List.length_drop.{u1} α i L))))
 Case conversion may be inaccurate. Consider using '#align list.nth_le_drop' List.nthLe_drop'ₓ'. -/
 /-- The `i + j`-th element of a list coincides with the `j`-th element of the list obtained by
 dropping the first `i` elements. Version designed to rewrite from the small list to the big list. -/
@@ -5144,7 +5144,7 @@ theorem filterMap_eq_map (f : α → β) : filterMap (some ∘ f) = map f :=
 lean 3 declaration is
   forall {α : Type.{u1}} (p : α -> Prop) [_inst_1 : DecidablePred.{succ u1} α p], Eq.{succ u1} ((List.{u1} α) -> (List.{u1} α)) (List.filterMap.{u1, u1} α α (Option.guard.{u1} α p (fun (a : α) => _inst_1 a))) (List.filterₓ.{u1} α p (fun (a : α) => _inst_1 a))
 but is expected to have type
-  forall {α : Type.{u1}} (p : α -> Bool), Eq.{succ u1} ((List.{u1} α) -> (List.{u1} α)) (List.filterMap.{u1, u1} α α (Option.guard.{u1} α (fun (x._@.Mathlib.Data.List.Basic._hyg.42129 : α) => Eq.{1} Bool (p x._@.Mathlib.Data.List.Basic._hyg.42129) Bool.true) (fun (a : α) => instDecidableEqBool (p a) Bool.true))) (List.filter.{u1} α p)
+  forall {α : Type.{u1}} (p : α -> Bool), Eq.{succ u1} ((List.{u1} α) -> (List.{u1} α)) (List.filterMap.{u1, u1} α α (Option.guard.{u1} α (fun (x._@.Mathlib.Data.List.Basic._hyg.42249 : α) => Eq.{1} Bool (p x._@.Mathlib.Data.List.Basic._hyg.42249) Bool.true) (fun (a : α) => instDecidableEqBool (p a) Bool.true))) (List.filter.{u1} α p)
 Case conversion may be inaccurate. Consider using '#align list.filter_map_eq_filter List.filterMap_eq_filterₓ'. -/
 theorem filterMap_eq_filter (p : α → Prop) [DecidablePred p] :
     filterMap (Option.guard p) = filter p := by
@@ -5651,7 +5651,7 @@ theorem filter_filter (q) [DecidablePred q] :
 lean 3 declaration is
   forall {α : Type.{u1}} {h : DecidablePred.{succ u1} α (fun (a : α) => True)} (l : List.{u1} α), Eq.{succ u1} (List.{u1} α) (List.filterₓ.{u1} α (fun (_x : α) => True) h l) l
 but is expected to have type
-  forall {α : Type.{u1}} (h : List.{u1} α), Eq.{succ u1} (List.{u1} α) (List.filter.{u1} α (fun (x._@.Mathlib.Data.List.Basic._hyg.46234 : α) => Bool.true) h) h
+  forall {α : Type.{u1}} (h : List.{u1} α), Eq.{succ u1} (List.{u1} α) (List.filter.{u1} α (fun (x._@.Mathlib.Data.List.Basic._hyg.46354 : α) => Bool.true) h) h
 Case conversion may be inaccurate. Consider using '#align list.filter_true List.filter_trueₓ'. -/
 @[simp]
 theorem filter_true {h : DecidablePred fun a : α => True} (l : List α) :
@@ -5662,7 +5662,7 @@ theorem filter_true {h : DecidablePred fun a : α => True} (l : List α) :
 lean 3 declaration is
   forall {α : Type.{u1}} {h : DecidablePred.{succ u1} α (fun (a : α) => False)} (l : List.{u1} α), Eq.{succ u1} (List.{u1} α) (List.filterₓ.{u1} α (fun (_x : α) => False) h l) (List.nil.{u1} α)
 but is expected to have type
-  forall {α : Type.{u1}} (h : List.{u1} α), Eq.{succ u1} (List.{u1} α) (List.filter.{u1} α (fun (x._@.Mathlib.Data.List.Basic._hyg.46284 : α) => Bool.false) h) (List.nil.{u1} α)
+  forall {α : Type.{u1}} (h : List.{u1} α), Eq.{succ u1} (List.{u1} α) (List.filter.{u1} α (fun (x._@.Mathlib.Data.List.Basic._hyg.46404 : α) => Bool.false) h) (List.nil.{u1} α)
 Case conversion may be inaccurate. Consider using '#align list.filter_false List.filter_falseₓ'. -/
 @[simp]
 theorem filter_false {h : DecidablePred fun a : α => False} (l : List α) :
Diff
@@ -5144,7 +5144,7 @@ theorem filterMap_eq_map (f : α → β) : filterMap (some ∘ f) = map f :=
 lean 3 declaration is
   forall {α : Type.{u1}} (p : α -> Prop) [_inst_1 : DecidablePred.{succ u1} α p], Eq.{succ u1} ((List.{u1} α) -> (List.{u1} α)) (List.filterMap.{u1, u1} α α (Option.guard.{u1} α p (fun (a : α) => _inst_1 a))) (List.filterₓ.{u1} α p (fun (a : α) => _inst_1 a))
 but is expected to have type
-  forall {α : Type.{u1}} (p : α -> Bool), Eq.{succ u1} ((List.{u1} α) -> (List.{u1} α)) (List.filterMap.{u1, u1} α α (Option.guard.{u1} α (fun (x._@.Mathlib.Data.List.Basic._hyg.42127 : α) => Eq.{1} Bool (p x._@.Mathlib.Data.List.Basic._hyg.42127) Bool.true) (fun (a : α) => instDecidableEqBool (p a) Bool.true))) (List.filter.{u1} α p)
+  forall {α : Type.{u1}} (p : α -> Bool), Eq.{succ u1} ((List.{u1} α) -> (List.{u1} α)) (List.filterMap.{u1, u1} α α (Option.guard.{u1} α (fun (x._@.Mathlib.Data.List.Basic._hyg.42129 : α) => Eq.{1} Bool (p x._@.Mathlib.Data.List.Basic._hyg.42129) Bool.true) (fun (a : α) => instDecidableEqBool (p a) Bool.true))) (List.filter.{u1} α p)
 Case conversion may be inaccurate. Consider using '#align list.filter_map_eq_filter List.filterMap_eq_filterₓ'. -/
 theorem filterMap_eq_filter (p : α → Prop) [DecidablePred p] :
     filterMap (Option.guard p) = filter p := by
@@ -5651,7 +5651,7 @@ theorem filter_filter (q) [DecidablePred q] :
 lean 3 declaration is
   forall {α : Type.{u1}} {h : DecidablePred.{succ u1} α (fun (a : α) => True)} (l : List.{u1} α), Eq.{succ u1} (List.{u1} α) (List.filterₓ.{u1} α (fun (_x : α) => True) h l) l
 but is expected to have type
-  forall {α : Type.{u1}} (h : List.{u1} α), Eq.{succ u1} (List.{u1} α) (List.filter.{u1} α (fun (x._@.Mathlib.Data.List.Basic._hyg.46232 : α) => Bool.true) h) h
+  forall {α : Type.{u1}} (h : List.{u1} α), Eq.{succ u1} (List.{u1} α) (List.filter.{u1} α (fun (x._@.Mathlib.Data.List.Basic._hyg.46234 : α) => Bool.true) h) h
 Case conversion may be inaccurate. Consider using '#align list.filter_true List.filter_trueₓ'. -/
 @[simp]
 theorem filter_true {h : DecidablePred fun a : α => True} (l : List α) :
@@ -5662,7 +5662,7 @@ theorem filter_true {h : DecidablePred fun a : α => True} (l : List α) :
 lean 3 declaration is
   forall {α : Type.{u1}} {h : DecidablePred.{succ u1} α (fun (a : α) => False)} (l : List.{u1} α), Eq.{succ u1} (List.{u1} α) (List.filterₓ.{u1} α (fun (_x : α) => False) h l) (List.nil.{u1} α)
 but is expected to have type
-  forall {α : Type.{u1}} (h : List.{u1} α), Eq.{succ u1} (List.{u1} α) (List.filter.{u1} α (fun (x._@.Mathlib.Data.List.Basic._hyg.46282 : α) => Bool.false) h) (List.nil.{u1} α)
+  forall {α : Type.{u1}} (h : List.{u1} α), Eq.{succ u1} (List.{u1} α) (List.filter.{u1} α (fun (x._@.Mathlib.Data.List.Basic._hyg.46284 : α) => Bool.false) h) (List.nil.{u1} α)
 Case conversion may be inaccurate. Consider using '#align list.filter_false List.filter_falseₓ'. -/
 @[simp]
 theorem filter_false {h : DecidablePred fun a : α => False} (l : List α) :
Diff
@@ -3607,7 +3607,7 @@ theorem nthLe_drop (L : List α) {i j : ℕ} (h : i + j < L.length) :
 lean 3 declaration is
   forall {α : Type.{u1}} (L : List.{u1} α) {i : Nat} {j : Nat} (h : LT.lt.{0} Nat Nat.hasLt j (List.length.{u1} α (List.drop.{u1} α i L))), Eq.{succ u1} α (List.nthLe.{u1} α (List.drop.{u1} α i L) j h) (List.nthLe.{u1} α L (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat Nat.hasAdd) i j) (Iff.mp (LT.lt.{0} Nat (Preorder.toLT.{0} Nat (PartialOrder.toPreorder.{0} Nat (SemilatticeInf.toPartialOrder.{0} Nat (Lattice.toSemilatticeInf.{0} Nat (LinearOrder.toLattice.{0} Nat Nat.linearOrder))))) j (HSub.hSub.{0, 0, 0} Nat Nat Nat (instHSub.{0} Nat Nat.hasSub) (List.length.{u1} α L) i)) (LT.lt.{0} Nat (Preorder.toLT.{0} Nat (PartialOrder.toPreorder.{0} Nat (SemilatticeInf.toPartialOrder.{0} Nat (Lattice.toSemilatticeInf.{0} Nat (LinearOrder.toLattice.{0} Nat Nat.linearOrder))))) (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat (AddSemigroup.toHasAdd.{0} Nat (AddCommSemigroup.toAddSemigroup.{0} Nat Nat.addCommSemigroup))) i j) (List.length.{u1} α L)) (lt_tsub_iff_left.{0} Nat j (List.length.{u1} α L) i Nat.linearOrder Nat.addCommSemigroup Nat.hasSub Nat.hasOrderedSub) (Eq.subst.{1} Nat (fun (_x : Nat) => LT.lt.{0} Nat (Preorder.toLT.{0} Nat (PartialOrder.toPreorder.{0} Nat (SemilatticeInf.toPartialOrder.{0} Nat (Lattice.toSemilatticeInf.{0} Nat (LinearOrder.toLattice.{0} Nat Nat.linearOrder))))) j _x) (List.length.{u1} α (List.drop.{u1} α i L)) (HSub.hSub.{0, 0, 0} Nat Nat Nat (instHSub.{0} Nat Nat.hasSub) (List.length.{u1} α L) i) (List.length_drop.{u1} α i L) h)))
 but is expected to have type
-  forall {α : Type.{u1}} (L : List.{u1} α) {i : Nat} {j : Nat} (h : LT.lt.{0} Nat instLTNat j (List.length.{u1} α (List.drop.{u1} α i L))), Eq.{succ u1} α (List.nthLe.{u1} α (List.drop.{u1} α i L) j h) (List.nthLe.{u1} α L (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat instAddNat) i j) (Iff.mp (LT.lt.{0} Nat (Preorder.toLT.{0} Nat (PartialOrder.toPreorder.{0} Nat (SemilatticeInf.toPartialOrder.{0} Nat (Lattice.toSemilatticeInf.{0} Nat (DistribLattice.toLattice.{0} Nat (instDistribLattice.{0} Nat Nat.linearOrder)))))) j (HSub.hSub.{0, 0, 0} Nat Nat Nat (instHSub.{0} Nat instSubNat) (List.length.{u1} α L) i)) (LT.lt.{0} Nat (Preorder.toLT.{0} Nat (PartialOrder.toPreorder.{0} Nat (SemilatticeInf.toPartialOrder.{0} Nat (Lattice.toSemilatticeInf.{0} Nat (DistribLattice.toLattice.{0} Nat (instDistribLattice.{0} Nat Nat.linearOrder)))))) (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat (AddSemigroup.toAdd.{0} Nat (AddCommSemigroup.toAddSemigroup.{0} Nat Nat.addCommSemigroup))) i j) (List.length.{u1} α L)) (lt_tsub_iff_left.{0} Nat j (List.length.{u1} α L) i Nat.linearOrder Nat.addCommSemigroup instSubNat Nat.instOrderedSubNatInstLENatInstAddNatInstSubNat) (Eq.rec.{0, 1} Nat (List.length.{u1} α (List.drop.{u1} α i L)) (fun (x._@.Mathlib.Data.List.Basic._hyg.25569 : Nat) (h._@.Mathlib.Data.List.Basic._hyg.25570 : Eq.{1} Nat (List.length.{u1} α (List.drop.{u1} α i L)) x._@.Mathlib.Data.List.Basic._hyg.25569) => LT.lt.{0} Nat (Preorder.toLT.{0} Nat (PartialOrder.toPreorder.{0} Nat (SemilatticeInf.toPartialOrder.{0} Nat (Lattice.toSemilatticeInf.{0} Nat (DistribLattice.toLattice.{0} Nat (instDistribLattice.{0} Nat Nat.linearOrder)))))) j x._@.Mathlib.Data.List.Basic._hyg.25569) h (HSub.hSub.{0, 0, 0} Nat Nat Nat (instHSub.{0} Nat instSubNat) (List.length.{u1} α L) i) (List.length_drop.{u1} α i L))))
+  forall {α : Type.{u1}} (L : List.{u1} α) {i : Nat} {j : Nat} (h : LT.lt.{0} Nat instLTNat j (List.length.{u1} α (List.drop.{u1} α i L))), Eq.{succ u1} α (List.nthLe.{u1} α (List.drop.{u1} α i L) j h) (List.nthLe.{u1} α L (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat instAddNat) i j) (Iff.mp (LT.lt.{0} Nat (Preorder.toLT.{0} Nat (PartialOrder.toPreorder.{0} Nat (SemilatticeInf.toPartialOrder.{0} Nat (Lattice.toSemilatticeInf.{0} Nat (DistribLattice.toLattice.{0} Nat (instDistribLattice.{0} Nat Nat.linearOrder)))))) j (HSub.hSub.{0, 0, 0} Nat Nat Nat (instHSub.{0} Nat instSubNat) (List.length.{u1} α L) i)) (LT.lt.{0} Nat (Preorder.toLT.{0} Nat (PartialOrder.toPreorder.{0} Nat (SemilatticeInf.toPartialOrder.{0} Nat (Lattice.toSemilatticeInf.{0} Nat (DistribLattice.toLattice.{0} Nat (instDistribLattice.{0} Nat Nat.linearOrder)))))) (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat (AddSemigroup.toAdd.{0} Nat (AddCommSemigroup.toAddSemigroup.{0} Nat Nat.addCommSemigroup))) i j) (List.length.{u1} α L)) (lt_tsub_iff_left.{0} Nat j (List.length.{u1} α L) i Nat.linearOrder Nat.addCommSemigroup instSubNat Nat.instOrderedSubNatInstLENatInstAddNatInstSubNat) (Eq.rec.{0, 1} Nat (List.length.{u1} α (List.drop.{u1} α i L)) (fun (x._@.Mathlib.Data.List.Basic._hyg.25563 : Nat) (h._@.Mathlib.Data.List.Basic._hyg.25564 : Eq.{1} Nat (List.length.{u1} α (List.drop.{u1} α i L)) x._@.Mathlib.Data.List.Basic._hyg.25563) => LT.lt.{0} Nat (Preorder.toLT.{0} Nat (PartialOrder.toPreorder.{0} Nat (SemilatticeInf.toPartialOrder.{0} Nat (Lattice.toSemilatticeInf.{0} Nat (DistribLattice.toLattice.{0} Nat (instDistribLattice.{0} Nat Nat.linearOrder)))))) j x._@.Mathlib.Data.List.Basic._hyg.25563) h (HSub.hSub.{0, 0, 0} Nat Nat Nat (instHSub.{0} Nat instSubNat) (List.length.{u1} α L) i) (List.length_drop.{u1} α i L))))
 Case conversion may be inaccurate. Consider using '#align list.nth_le_drop' List.nthLe_drop'ₓ'. -/
 /-- The `i + j`-th element of a list coincides with the `j`-th element of the list obtained by
 dropping the first `i` elements. Version designed to rewrite from the small list to the big list. -/
@@ -5144,7 +5144,7 @@ theorem filterMap_eq_map (f : α → β) : filterMap (some ∘ f) = map f :=
 lean 3 declaration is
   forall {α : Type.{u1}} (p : α -> Prop) [_inst_1 : DecidablePred.{succ u1} α p], Eq.{succ u1} ((List.{u1} α) -> (List.{u1} α)) (List.filterMap.{u1, u1} α α (Option.guard.{u1} α p (fun (a : α) => _inst_1 a))) (List.filterₓ.{u1} α p (fun (a : α) => _inst_1 a))
 but is expected to have type
-  forall {α : Type.{u1}} (p : α -> Bool), Eq.{succ u1} ((List.{u1} α) -> (List.{u1} α)) (List.filterMap.{u1, u1} α α (Option.guard.{u1} α (fun (x._@.Mathlib.Data.List.Basic._hyg.42145 : α) => Eq.{1} Bool (p x._@.Mathlib.Data.List.Basic._hyg.42145) Bool.true) (fun (a : α) => instDecidableEqBool (p a) Bool.true))) (List.filter.{u1} α p)
+  forall {α : Type.{u1}} (p : α -> Bool), Eq.{succ u1} ((List.{u1} α) -> (List.{u1} α)) (List.filterMap.{u1, u1} α α (Option.guard.{u1} α (fun (x._@.Mathlib.Data.List.Basic._hyg.42127 : α) => Eq.{1} Bool (p x._@.Mathlib.Data.List.Basic._hyg.42127) Bool.true) (fun (a : α) => instDecidableEqBool (p a) Bool.true))) (List.filter.{u1} α p)
 Case conversion may be inaccurate. Consider using '#align list.filter_map_eq_filter List.filterMap_eq_filterₓ'. -/
 theorem filterMap_eq_filter (p : α → Prop) [DecidablePred p] :
     filterMap (Option.guard p) = filter p := by
@@ -5651,7 +5651,7 @@ theorem filter_filter (q) [DecidablePred q] :
 lean 3 declaration is
   forall {α : Type.{u1}} {h : DecidablePred.{succ u1} α (fun (a : α) => True)} (l : List.{u1} α), Eq.{succ u1} (List.{u1} α) (List.filterₓ.{u1} α (fun (_x : α) => True) h l) l
 but is expected to have type
-  forall {α : Type.{u1}} (h : List.{u1} α), Eq.{succ u1} (List.{u1} α) (List.filter.{u1} α (fun (x._@.Mathlib.Data.List.Basic._hyg.46252 : α) => Bool.true) h) h
+  forall {α : Type.{u1}} (h : List.{u1} α), Eq.{succ u1} (List.{u1} α) (List.filter.{u1} α (fun (x._@.Mathlib.Data.List.Basic._hyg.46232 : α) => Bool.true) h) h
 Case conversion may be inaccurate. Consider using '#align list.filter_true List.filter_trueₓ'. -/
 @[simp]
 theorem filter_true {h : DecidablePred fun a : α => True} (l : List α) :
@@ -5662,7 +5662,7 @@ theorem filter_true {h : DecidablePred fun a : α => True} (l : List α) :
 lean 3 declaration is
   forall {α : Type.{u1}} {h : DecidablePred.{succ u1} α (fun (a : α) => False)} (l : List.{u1} α), Eq.{succ u1} (List.{u1} α) (List.filterₓ.{u1} α (fun (_x : α) => False) h l) (List.nil.{u1} α)
 but is expected to have type
-  forall {α : Type.{u1}} (h : List.{u1} α), Eq.{succ u1} (List.{u1} α) (List.filter.{u1} α (fun (x._@.Mathlib.Data.List.Basic._hyg.46302 : α) => Bool.false) h) (List.nil.{u1} α)
+  forall {α : Type.{u1}} (h : List.{u1} α), Eq.{succ u1} (List.{u1} α) (List.filter.{u1} α (fun (x._@.Mathlib.Data.List.Basic._hyg.46282 : α) => Bool.false) h) (List.nil.{u1} α)
 Case conversion may be inaccurate. Consider using '#align list.filter_false List.filter_falseₓ'. -/
 @[simp]
 theorem filter_false {h : DecidablePred fun a : α => False} (l : List α) :
@@ -6432,16 +6432,21 @@ theorem map_fst_add_enum_eq_enumFrom (l : List α) (n : ℕ) :
 #align list.map_fst_add_enum_eq_enum_from List.map_fst_add_enum_eq_enumFrom
 -/
 
+#print List.enumFrom_cons' /-
 theorem enumFrom_cons' (n : ℕ) (x : α) (xs : List α) :
     enumFrom n (x :: xs) = (n, x) :: (enumFrom n xs).map (Prod.map Nat.succ id) := by
   rw [enum_from_cons, add_comm, ← map_fst_add_enum_from_eq_enum_from]
 #align list.enum_from_cons' List.enumFrom_cons'
+-/
 
+#print List.enum_cons' /-
 theorem enum_cons' (x : α) (xs : List α) :
     enum (x :: xs) = (0, x) :: (enum xs).map (Prod.map Nat.succ id) :=
   enumFrom_cons' _ _ _
 #align list.enum_cons' List.enum_cons'
+-/
 
+#print List.enumFrom_map /-
 theorem enumFrom_map (n : ℕ) (l : List α) (f : α → β) :
     enumFrom n (l.map f) = (enumFrom n l).map (Prod.map id f) :=
   by
@@ -6450,10 +6455,13 @@ theorem enumFrom_map (n : ℕ) (l : List α) (f : α → β) :
   · rw [map_cons, enum_from_cons', enum_from_cons', map_cons, map_map, IH, map_map]
     rfl
 #align list.enum_from_map List.enumFrom_map
+-/
 
+#print List.enum_map /-
 theorem enum_map (l : List α) (f : α → β) : (l.map f).enum = l.enum.map (Prod.map id f) :=
   enumFrom_map _ _ _
 #align list.enum_map List.enum_map
+-/
 
 #print List.nthLe_enumFrom /-
 theorem nthLe_enumFrom (l : List α) (n i : ℕ) (hi' : i < (l.enumFrom n).length)
Diff
@@ -3607,7 +3607,7 @@ theorem nthLe_drop (L : List α) {i j : ℕ} (h : i + j < L.length) :
 lean 3 declaration is
   forall {α : Type.{u1}} (L : List.{u1} α) {i : Nat} {j : Nat} (h : LT.lt.{0} Nat Nat.hasLt j (List.length.{u1} α (List.drop.{u1} α i L))), Eq.{succ u1} α (List.nthLe.{u1} α (List.drop.{u1} α i L) j h) (List.nthLe.{u1} α L (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat Nat.hasAdd) i j) (Iff.mp (LT.lt.{0} Nat (Preorder.toLT.{0} Nat (PartialOrder.toPreorder.{0} Nat (SemilatticeInf.toPartialOrder.{0} Nat (Lattice.toSemilatticeInf.{0} Nat (LinearOrder.toLattice.{0} Nat Nat.linearOrder))))) j (HSub.hSub.{0, 0, 0} Nat Nat Nat (instHSub.{0} Nat Nat.hasSub) (List.length.{u1} α L) i)) (LT.lt.{0} Nat (Preorder.toLT.{0} Nat (PartialOrder.toPreorder.{0} Nat (SemilatticeInf.toPartialOrder.{0} Nat (Lattice.toSemilatticeInf.{0} Nat (LinearOrder.toLattice.{0} Nat Nat.linearOrder))))) (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat (AddSemigroup.toHasAdd.{0} Nat (AddCommSemigroup.toAddSemigroup.{0} Nat Nat.addCommSemigroup))) i j) (List.length.{u1} α L)) (lt_tsub_iff_left.{0} Nat j (List.length.{u1} α L) i Nat.linearOrder Nat.addCommSemigroup Nat.hasSub Nat.hasOrderedSub) (Eq.subst.{1} Nat (fun (_x : Nat) => LT.lt.{0} Nat (Preorder.toLT.{0} Nat (PartialOrder.toPreorder.{0} Nat (SemilatticeInf.toPartialOrder.{0} Nat (Lattice.toSemilatticeInf.{0} Nat (LinearOrder.toLattice.{0} Nat Nat.linearOrder))))) j _x) (List.length.{u1} α (List.drop.{u1} α i L)) (HSub.hSub.{0, 0, 0} Nat Nat Nat (instHSub.{0} Nat Nat.hasSub) (List.length.{u1} α L) i) (List.length_drop.{u1} α i L) h)))
 but is expected to have type
-  forall {α : Type.{u1}} (L : List.{u1} α) {i : Nat} {j : Nat} (h : LT.lt.{0} Nat instLTNat j (List.length.{u1} α (List.drop.{u1} α i L))), Eq.{succ u1} α (List.nthLe.{u1} α (List.drop.{u1} α i L) j h) (List.nthLe.{u1} α L (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat instAddNat) i j) (Iff.mp (LT.lt.{0} Nat (Preorder.toLT.{0} Nat (PartialOrder.toPreorder.{0} Nat (SemilatticeInf.toPartialOrder.{0} Nat (Lattice.toSemilatticeInf.{0} Nat (DistribLattice.toLattice.{0} Nat (instDistribLattice.{0} Nat Nat.linearOrder)))))) j (HSub.hSub.{0, 0, 0} Nat Nat Nat (instHSub.{0} Nat instSubNat) (List.length.{u1} α L) i)) (LT.lt.{0} Nat (Preorder.toLT.{0} Nat (PartialOrder.toPreorder.{0} Nat (SemilatticeInf.toPartialOrder.{0} Nat (Lattice.toSemilatticeInf.{0} Nat (DistribLattice.toLattice.{0} Nat (instDistribLattice.{0} Nat Nat.linearOrder)))))) (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat (AddSemigroup.toAdd.{0} Nat (AddCommSemigroup.toAddSemigroup.{0} Nat Nat.addCommSemigroup))) i j) (List.length.{u1} α L)) (lt_tsub_iff_left.{0} Nat j (List.length.{u1} α L) i Nat.linearOrder Nat.addCommSemigroup instSubNat Nat.instOrderedSubNatInstLENatInstAddNatInstSubNat) (Eq.rec.{0, 1} Nat (List.length.{u1} α (List.drop.{u1} α i L)) (fun (x._@.Mathlib.Data.List.Basic._hyg.25580 : Nat) (h._@.Mathlib.Data.List.Basic._hyg.25581 : Eq.{1} Nat (List.length.{u1} α (List.drop.{u1} α i L)) x._@.Mathlib.Data.List.Basic._hyg.25580) => LT.lt.{0} Nat (Preorder.toLT.{0} Nat (PartialOrder.toPreorder.{0} Nat (SemilatticeInf.toPartialOrder.{0} Nat (Lattice.toSemilatticeInf.{0} Nat (DistribLattice.toLattice.{0} Nat (instDistribLattice.{0} Nat Nat.linearOrder)))))) j x._@.Mathlib.Data.List.Basic._hyg.25580) h (HSub.hSub.{0, 0, 0} Nat Nat Nat (instHSub.{0} Nat instSubNat) (List.length.{u1} α L) i) (List.length_drop.{u1} α i L))))
+  forall {α : Type.{u1}} (L : List.{u1} α) {i : Nat} {j : Nat} (h : LT.lt.{0} Nat instLTNat j (List.length.{u1} α (List.drop.{u1} α i L))), Eq.{succ u1} α (List.nthLe.{u1} α (List.drop.{u1} α i L) j h) (List.nthLe.{u1} α L (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat instAddNat) i j) (Iff.mp (LT.lt.{0} Nat (Preorder.toLT.{0} Nat (PartialOrder.toPreorder.{0} Nat (SemilatticeInf.toPartialOrder.{0} Nat (Lattice.toSemilatticeInf.{0} Nat (DistribLattice.toLattice.{0} Nat (instDistribLattice.{0} Nat Nat.linearOrder)))))) j (HSub.hSub.{0, 0, 0} Nat Nat Nat (instHSub.{0} Nat instSubNat) (List.length.{u1} α L) i)) (LT.lt.{0} Nat (Preorder.toLT.{0} Nat (PartialOrder.toPreorder.{0} Nat (SemilatticeInf.toPartialOrder.{0} Nat (Lattice.toSemilatticeInf.{0} Nat (DistribLattice.toLattice.{0} Nat (instDistribLattice.{0} Nat Nat.linearOrder)))))) (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat (AddSemigroup.toAdd.{0} Nat (AddCommSemigroup.toAddSemigroup.{0} Nat Nat.addCommSemigroup))) i j) (List.length.{u1} α L)) (lt_tsub_iff_left.{0} Nat j (List.length.{u1} α L) i Nat.linearOrder Nat.addCommSemigroup instSubNat Nat.instOrderedSubNatInstLENatInstAddNatInstSubNat) (Eq.rec.{0, 1} Nat (List.length.{u1} α (List.drop.{u1} α i L)) (fun (x._@.Mathlib.Data.List.Basic._hyg.25569 : Nat) (h._@.Mathlib.Data.List.Basic._hyg.25570 : Eq.{1} Nat (List.length.{u1} α (List.drop.{u1} α i L)) x._@.Mathlib.Data.List.Basic._hyg.25569) => LT.lt.{0} Nat (Preorder.toLT.{0} Nat (PartialOrder.toPreorder.{0} Nat (SemilatticeInf.toPartialOrder.{0} Nat (Lattice.toSemilatticeInf.{0} Nat (DistribLattice.toLattice.{0} Nat (instDistribLattice.{0} Nat Nat.linearOrder)))))) j x._@.Mathlib.Data.List.Basic._hyg.25569) h (HSub.hSub.{0, 0, 0} Nat Nat Nat (instHSub.{0} Nat instSubNat) (List.length.{u1} α L) i) (List.length_drop.{u1} α i L))))
 Case conversion may be inaccurate. Consider using '#align list.nth_le_drop' List.nthLe_drop'ₓ'. -/
 /-- The `i + j`-th element of a list coincides with the `j`-th element of the list obtained by
 dropping the first `i` elements. Version designed to rewrite from the small list to the big list. -/
@@ -5144,7 +5144,7 @@ theorem filterMap_eq_map (f : α → β) : filterMap (some ∘ f) = map f :=
 lean 3 declaration is
   forall {α : Type.{u1}} (p : α -> Prop) [_inst_1 : DecidablePred.{succ u1} α p], Eq.{succ u1} ((List.{u1} α) -> (List.{u1} α)) (List.filterMap.{u1, u1} α α (Option.guard.{u1} α p (fun (a : α) => _inst_1 a))) (List.filterₓ.{u1} α p (fun (a : α) => _inst_1 a))
 but is expected to have type
-  forall {α : Type.{u1}} (p : α -> Bool), Eq.{succ u1} ((List.{u1} α) -> (List.{u1} α)) (List.filterMap.{u1, u1} α α (Option.guard.{u1} α (fun (x._@.Mathlib.Data.List.Basic._hyg.42156 : α) => Eq.{1} Bool (p x._@.Mathlib.Data.List.Basic._hyg.42156) Bool.true) (fun (a : α) => instDecidableEqBool (p a) Bool.true))) (List.filter.{u1} α p)
+  forall {α : Type.{u1}} (p : α -> Bool), Eq.{succ u1} ((List.{u1} α) -> (List.{u1} α)) (List.filterMap.{u1, u1} α α (Option.guard.{u1} α (fun (x._@.Mathlib.Data.List.Basic._hyg.42145 : α) => Eq.{1} Bool (p x._@.Mathlib.Data.List.Basic._hyg.42145) Bool.true) (fun (a : α) => instDecidableEqBool (p a) Bool.true))) (List.filter.{u1} α p)
 Case conversion may be inaccurate. Consider using '#align list.filter_map_eq_filter List.filterMap_eq_filterₓ'. -/
 theorem filterMap_eq_filter (p : α → Prop) [DecidablePred p] :
     filterMap (Option.guard p) = filter p := by
@@ -5651,7 +5651,7 @@ theorem filter_filter (q) [DecidablePred q] :
 lean 3 declaration is
   forall {α : Type.{u1}} {h : DecidablePred.{succ u1} α (fun (a : α) => True)} (l : List.{u1} α), Eq.{succ u1} (List.{u1} α) (List.filterₓ.{u1} α (fun (_x : α) => True) h l) l
 but is expected to have type
-  forall {α : Type.{u1}} (h : List.{u1} α), Eq.{succ u1} (List.{u1} α) (List.filter.{u1} α (fun (x._@.Mathlib.Data.List.Basic._hyg.46263 : α) => Bool.true) h) h
+  forall {α : Type.{u1}} (h : List.{u1} α), Eq.{succ u1} (List.{u1} α) (List.filter.{u1} α (fun (x._@.Mathlib.Data.List.Basic._hyg.46252 : α) => Bool.true) h) h
 Case conversion may be inaccurate. Consider using '#align list.filter_true List.filter_trueₓ'. -/
 @[simp]
 theorem filter_true {h : DecidablePred fun a : α => True} (l : List α) :
@@ -5662,7 +5662,7 @@ theorem filter_true {h : DecidablePred fun a : α => True} (l : List α) :
 lean 3 declaration is
   forall {α : Type.{u1}} {h : DecidablePred.{succ u1} α (fun (a : α) => False)} (l : List.{u1} α), Eq.{succ u1} (List.{u1} α) (List.filterₓ.{u1} α (fun (_x : α) => False) h l) (List.nil.{u1} α)
 but is expected to have type
-  forall {α : Type.{u1}} (h : List.{u1} α), Eq.{succ u1} (List.{u1} α) (List.filter.{u1} α (fun (x._@.Mathlib.Data.List.Basic._hyg.46313 : α) => Bool.false) h) (List.nil.{u1} α)
+  forall {α : Type.{u1}} (h : List.{u1} α), Eq.{succ u1} (List.{u1} α) (List.filter.{u1} α (fun (x._@.Mathlib.Data.List.Basic._hyg.46302 : α) => Bool.false) h) (List.nil.{u1} α)
 Case conversion may be inaccurate. Consider using '#align list.filter_false List.filter_falseₓ'. -/
 @[simp]
 theorem filter_false {h : DecidablePred fun a : α => False} (l : List α) :
Diff
@@ -3633,7 +3633,7 @@ theorem drop_drop (n : ℕ) : ∀ (m) (l : List α), drop n (drop m l) = drop (n
   | m + 1, a :: l =>
     calc
       drop n (drop (m + 1) (a :: l)) = drop n (drop m l) := rfl
-      _ = drop (n + m) l := drop_drop m l
+      _ = drop (n + m) l := (drop_drop m l)
       _ = drop (n + (m + 1)) (a :: l) := rfl
       
 #align list.drop_drop List.drop_drop
@@ -6216,7 +6216,7 @@ theorem diff_sublist : ∀ l₁ l₂ : List α, l₁.diffₓ l₂ <+ l₁
   | l₁, a :: l₂ =>
     calc
       l₁.diffₓ (a :: l₂) = (l₁.eraseₓ a).diffₓ l₂ := diff_cons _ _ _
-      _ <+ l₁.eraseₓ a := diff_sublist _ _
+      _ <+ l₁.eraseₓ a := (diff_sublist _ _)
       _ <+ l₁ := List.erase_sublist _ _
       
 #align list.diff_sublist List.diff_sublist
Diff
@@ -4,7 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE.
 Authors: Parikshit Khanna, Jeremy Avigad, Leonardo de Moura, Floris van Doorn, Mario Carneiro
 
 ! This file was ported from Lean 3 source module data.list.basic
-! leanprover-community/mathlib commit 1447cae870f372074e480de1acbeb51de0077698
+! leanprover-community/mathlib commit 9da1b3534b65d9661eb8f42443598a92bbb49211
 ! Please do not edit these lines, except to modify the commit id
 ! if you have ported upstream changes.
 -/
@@ -6432,6 +6432,29 @@ theorem map_fst_add_enum_eq_enumFrom (l : List α) (n : ℕ) :
 #align list.map_fst_add_enum_eq_enum_from List.map_fst_add_enum_eq_enumFrom
 -/
 
+theorem enumFrom_cons' (n : ℕ) (x : α) (xs : List α) :
+    enumFrom n (x :: xs) = (n, x) :: (enumFrom n xs).map (Prod.map Nat.succ id) := by
+  rw [enum_from_cons, add_comm, ← map_fst_add_enum_from_eq_enum_from]
+#align list.enum_from_cons' List.enumFrom_cons'
+
+theorem enum_cons' (x : α) (xs : List α) :
+    enum (x :: xs) = (0, x) :: (enum xs).map (Prod.map Nat.succ id) :=
+  enumFrom_cons' _ _ _
+#align list.enum_cons' List.enum_cons'
+
+theorem enumFrom_map (n : ℕ) (l : List α) (f : α → β) :
+    enumFrom n (l.map f) = (enumFrom n l).map (Prod.map id f) :=
+  by
+  induction' l with hd tl IH
+  · rfl
+  · rw [map_cons, enum_from_cons', enum_from_cons', map_cons, map_map, IH, map_map]
+    rfl
+#align list.enum_from_map List.enumFrom_map
+
+theorem enum_map (l : List α) (f : α → β) : (l.map f).enum = l.enum.map (Prod.map id f) :=
+  enumFrom_map _ _ _
+#align list.enum_map List.enum_map
+
 #print List.nthLe_enumFrom /-
 theorem nthLe_enumFrom (l : List α) (n i : ℕ) (hi' : i < (l.enumFrom n).length)
     (hi : i < l.length := (by simpa [length_enum_from] using hi')) :

Changes in mathlib4

mathlib3
mathlib4
chore(List): delete old, unused, deprecated theorems (#9607)

These theorems have been deprecated for at least a year, and are unused.

Co-authored-by: Michael Rothgang <rothgami@math.hu-berlin.de> Co-authored-by: Scott Morrison <scott.morrison@gmail.com> Co-authored-by: Yury G. Kudryashov <urkud@urkud.name>

Diff
@@ -862,10 +862,12 @@ theorem tail_append_of_ne_nil (l l' : List α) (h : l ≠ []) : (l ++ l').tail =
 
 theorem get_eq_iff {l : List α} {n : Fin l.length} {x : α} : l.get n = x ↔ l.get? n.1 = some x := by
   simp [get?_eq_some]
+#align list.nth_le_eq_iff List.get_eq_iff
 
 theorem get_eq_get? (l : List α) (i : Fin l.length) :
     l.get i = (l.get? i).get (by simp [get?_eq_get]) := by
   simp [get_eq_iff]
+#align list.some_nth_le_eq List.get?_eq_get
 
 section deprecated
 set_option linter.deprecated false -- TODO(Mario): make replacements for theorems in this section
@@ -1224,10 +1226,7 @@ theorem nthLe_get? {l : List α} {n} (h) : get? l n = some (nthLe l n h) := get?
 theorem get?_length (l : List α) : l.get? l.length = none := get?_len_le le_rfl
 #align list.nth_length List.get?_length
 
-@[deprecated get?_eq_some] -- 2023-01-05
-theorem get?_eq_some' {l : List α} {n a} : get? l n = some a ↔ ∃ h, nthLe l n h = a := get?_eq_some
-#align list.nth_eq_some List.get?_eq_some'
-
+#align list.nth_eq_some List.get?_eq_some
 #align list.nth_eq_none_iff List.get?_eq_none
 #align list.nth_of_mem List.get?_of_mem
 
@@ -1302,10 +1301,7 @@ theorem nthLe_zero [Inhabited α] {L : List α} (h : 0 < L.length) : List.nthLe
   simp [nthLe]
 #align list.nth_le_zero List.nthLe_zero
 
-@[deprecated get_append] -- 2023-01-05
-theorem nthLe_append {l₁ l₂ : List α} {n : ℕ} (hn₁) (hn₂) :
-    (l₁ ++ l₂).nthLe n hn₁ = l₁.nthLe n hn₂ := get_append _ hn₂
-#align list.nth_le_append List.nthLe_append
+#align list.nth_le_append List.get_append
 
 @[deprecated get_append_right'] -- 2023-01-05
 theorem nthLe_append_right {l₁ l₂ : List α} {n : ℕ} (h₁ : l₁.length ≤ n) (h₂) :
@@ -1314,30 +1310,16 @@ theorem nthLe_append_right {l₁ l₂ : List α} {n : ℕ} (h₁ : l₁.length 
 #align list.nth_le_append_right_aux List.get_append_right_aux
 #align list.nth_le_append_right List.nthLe_append_right
 
-@[deprecated get_replicate] -- 2023-01-05
-theorem nthLe_replicate (a : α) {n m : ℕ} (h : m < (replicate n a).length) :
-    (replicate n a).nthLe m h = a := get_replicate ..
-#align list.nth_le_replicate List.nthLe_replicate
-
+#align list.nth_le_replicate List.get_replicate
 #align list.nth_append List.get?_append
 #align list.nth_append_right List.get?_append_right
-
-@[deprecated getLast_eq_get] -- 2023-01-05
-theorem getLast_eq_nthLe (l : List α) (h : l ≠ []) :
-    getLast l h = l.nthLe (l.length - 1) (have := length_pos_of_ne_nil h; by omega) :=
-  getLast_eq_get ..
-#align list.last_eq_nth_le List.getLast_eq_nthLe
+#align list.last_eq_nth_le List.getLast_eq_get
 
 theorem get_length_sub_one {l : List α} (h : l.length - 1 < l.length) :
     l.get ⟨l.length - 1, h⟩ = l.getLast (by rintro rfl; exact Nat.lt_irrefl 0 h) :=
   (getLast_eq_get l _).symm
 
-@[deprecated get_length_sub_one] -- 2023-01-05
-theorem nthLe_length_sub_one {l : List α} (h : l.length - 1 < l.length) :
-    l.nthLe (l.length - 1) h = l.getLast (by rintro rfl; exact Nat.lt_irrefl 0 h) :=
-  get_length_sub_one _
-#align list.nth_le_length_sub_one List.nthLe_length_sub_one
-
+#align list.nth_le_length_sub_one List.get_length_sub_one
 #align list.nth_concat_length List.get?_concat_length
 
 @[deprecated get_cons_length] -- 2023-01-05
@@ -1466,16 +1448,6 @@ theorem eq_cons_of_length_one {l : List α} (h : l.length = 1) :
   omega
 #align list.eq_cons_of_length_one List.eq_cons_of_length_one
 
-@[deprecated get_eq_iff] -- 2023-01-05
-theorem nthLe_eq_iff {l : List α} {n : ℕ} {x : α} {h} : l.nthLe n h = x ↔ l.get? n = some x :=
-  get_eq_iff
-#align list.nth_le_eq_iff List.nthLe_eq_iff
-
-@[deprecated get?_eq_get] -- 2023-01-05
-theorem some_nthLe_eq {l : List α} {n : ℕ} {h} : some (l.nthLe n h) = l.get? n :=
-  (get?_eq_get _).symm
-#align list.some_nth_le_eq List.some_nthLe_eq
-
 end deprecated
 
 theorem modifyNthTail_modifyNthTail {f g : List α → List α} (m : ℕ) :
@@ -1545,27 +1517,16 @@ theorem length_modifyNth (f : α → α) : ∀ n l, length (modifyNth f n l) = l
 #align list.update_nth_succ List.set_succ
 #align list.update_nth_comm List.set_comm
 
-@[simp, deprecated get_set_eq] -- 2023-01-05
-theorem nthLe_set_eq (l : List α) (i : ℕ) (a : α) (h : i < (l.set i a).length) :
-    (l.set i a).nthLe i h = a := get_set_eq ..
-#align list.nth_le_update_nth_eq List.nthLe_set_eq
-
+#align list.nth_le_update_nth_eq List.get_set_eq
 @[simp]
 theorem get_set_of_ne {l : List α} {i j : ℕ} (h : i ≠ j) (a : α)
     (hj : j < (l.set i a).length) :
     (l.set i a).get ⟨j, hj⟩ = l.get ⟨j, by simpa using hj⟩ := by
   rw [← Option.some_inj, ← List.get?_eq_get, List.get?_set_ne _ _ h, List.get?_eq_get]
 
-@[simp, deprecated get_set_of_ne] -- 2023-01-05
-theorem nthLe_set_of_ne {l : List α} {i j : ℕ} (h : i ≠ j) (a : α)
-    (hj : j < (l.set i a).length) :
-    (l.set i a).nthLe j hj = l.nthLe j (by simpa using hj) :=
-  get_set_of_ne h _ hj
-#align list.nth_le_update_nth_of_ne List.nthLe_set_of_ne
-
+#align list.nth_le_update_nth_of_ne List.get_set_of_ne
 #align list.mem_or_eq_of_mem_update_nth List.mem_or_eq_of_mem_set
 
-
 /-! ### map -/
 
 #align list.map_nil List.map_nil
@@ -1781,25 +1742,8 @@ theorem take_cons (n) (a : α) (l : List α) : take (succ n) (a :: l) = a :: tak
 #align list.take_append_eq_append_take List.take_append_eq_append_take
 #align list.take_append_of_le_length List.take_append_of_le_length
 #align list.take_append List.take_append
-
-set_option linter.deprecated false in
-/-- The `i`-th element of a list coincides with the `i`-th element of any of its prefixes of
-length `> i`. Version designed to rewrite from the big list to the small list. -/
-@[deprecated get_take] -- 2023-01-05
-theorem nthLe_take (L : List α) {i j : ℕ} (hi : i < L.length) (hj : i < j) :
-    nthLe L i hi = nthLe (L.take j) i (length_take .. ▸ lt_min hj hi) :=
-  get_take _ hi hj
-#align list.nth_le_take List.nthLe_take
-
-set_option linter.deprecated false in
-/-- The `i`-th element of a list coincides with the `i`-th element of any of its prefixes of
-length `> i`. Version designed to rewrite from the small list to the big list. -/
-@[deprecated get_take'] -- 2023-01-05
-theorem nthLe_take' (L : List α) {i j : ℕ} (hi : i < (L.take j).length) :
-    nthLe (L.take j) i hi = nthLe L i (lt_of_lt_of_le hi (by simp only [length_take]; omega)) :=
-  get_take' _
-#align list.nth_le_take' List.nthLe_take'
-
+#align list.nth_le_take List.get_take
+#align list.nth_le_take' List.get_take'
 #align list.nth_take List.get?_take
 #align list.nth_take_of_succ List.nth_take_of_succ
 #align list.take_succ List.take_succ
@@ -1822,11 +1766,7 @@ theorem cons_get_drop_succ {l : List α} {n} :
     l.get n :: l.drop (n.1 + 1) = l.drop n.1 :=
   (drop_eq_get_cons n.2).symm
 
-@[deprecated cons_get_drop_succ] -- 2023-01-05
-theorem cons_nthLe_drop_succ {l : List α} {n : ℕ} (hn : n < l.length) :
-    l.nthLe n hn :: l.drop (n + 1) = l.drop n := cons_get_drop_succ
-#align list.cons_nth_le_drop_succ List.cons_nthLe_drop_succ
-
+#align list.cons_nth_le_drop_succ List.cons_get_drop_succ
 #align list.drop_nil List.drop_nil
 #align list.drop_one List.drop_one
 #align list.drop_add List.drop_add
@@ -1839,24 +1779,8 @@ theorem cons_nthLe_drop_succ {l : List α} {n : ℕ} (hn : n < l.length) :
 #align list.drop_append_of_le_length List.drop_append_of_le_length
 #align list.drop_append List.drop_append
 #align list.drop_sizeof_le List.drop_sizeOf_le
-
-set_option linter.deprecated false in
-/-- The `i + j`-th element of a list coincides with the `j`-th element of the list obtained by
-dropping the first `i` elements. Version designed to rewrite from the big list to the small list. -/
-@[deprecated get_drop] -- 2023-01-05
-theorem nthLe_drop (L : List α) {i j : ℕ} (h : i + j < L.length) :
-    nthLe L (i + j) h = nthLe (L.drop i) j (by rw [length_drop]; omega) := get_drop ..
-#align list.nth_le_drop List.nthLe_drop
-
-set_option linter.deprecated false in
-/-- The `i + j`-th element of a list coincides with the `j`-th element of the list obtained by
-dropping the first `i` elements. Version designed to rewrite from the small list to the big list. -/
-@[deprecated get_drop'] -- 2023-01-05
-theorem nthLe_drop' (L : List α) {i j : ℕ} (h : j < (L.drop i).length) :
-    nthLe (L.drop i) j h = nthLe L (i + j) (have := length_drop i L; by omega) :=
-  get_drop' ..
-#align list.nth_le_drop' List.nthLe_drop'
-
+#align list.nth_le_drop List.get_drop
+#align list.nth_le_drop' List.get_drop'
 #align list.nth_drop List.get?_drop
 #align list.drop_drop List.drop_drop
 #align list.drop_take List.drop_take
@@ -3640,7 +3564,6 @@ theorem get_attach (L : List α) (i) :
     (L.attach.get i).1 = (L.attach.map Subtype.val).get ⟨i, by simpa using i.2⟩ :=
       by rw [get_map]
     _ = L.get { val := i, isLt := _ } := by congr 2 <;> simp
-
 #align list.nth_le_attach List.get_attach
 
 @[simp 1100]
chore: adapt to multiple goal linter 1 (#12338)

A PR accompanying #12339.

Zulip discussion

Diff
@@ -618,8 +618,8 @@ theorem isEmpty_iff_eq_nil {l : List α} : l.isEmpty ↔ l = [] := by cases l <;
 theorem getLast_cons {a : α} {l : List α} :
     ∀ h : l ≠ nil, getLast (a :: l) (cons_ne_nil a l) = getLast l h := by
   induction l <;> intros
-  contradiction
-  rfl
+  · contradiction
+  · rfl
 #align list.last_cons List.getLast_cons
 
 theorem getLast_append_singleton {a : α} (l : List α) :
@@ -802,11 +802,16 @@ theorem mem_of_mem_head? {x : α} {l : List α} (h : x ∈ l.head?) : x ∈ l :=
 
 @[simp]
 theorem head!_append [Inhabited α] (t : List α) {s : List α} (h : s ≠ []) :
-    head! (s ++ t) = head! s := by induction s; contradiction; rfl
+    head! (s ++ t) = head! s := by
+  induction s
+  · contradiction
+  · rfl
 #align list.head_append List.head!_append
 
 theorem head?_append {s t : List α} {x : α} (h : x ∈ s.head?) : x ∈ (s ++ t).head? := by
-  cases s; contradiction; exact h
+  cases s
+  · contradiction
+  · exact h
 #align list.head'_append List.head?_append
 
 theorem head?_append_of_ne_nil :
@@ -816,7 +821,9 @@ theorem head?_append_of_ne_nil :
 
 theorem tail_append_singleton_of_ne_nil {a : α} {l : List α} (h : l ≠ nil) :
     tail (l ++ [a]) = tail l ++ [a] := by
-  induction l; contradiction; rw [tail, cons_append, tail]
+  induction l
+  · contradiction
+  · rw [tail, cons_append, tail]
 #align list.tail_append_singleton_of_ne_nil List.tail_append_singleton_of_ne_nil
 
 theorem cons_head?_tail : ∀ {l : List α} {a : α}, a ∈ head? l → a :: tail l = l
@@ -991,7 +998,6 @@ theorem bidirectionalRec_cons_append {motive : List α → Sort*}
   | nil => rfl
   | cons x xs =>
   simp only [List.cons_append]
-  congr
   dsimp only [← List.cons_append]
   suffices ∀ (ys init : List α) (hinit : init = ys) (last : α) (hlast : last = b),
       (cons_append a init last
feat(List/Basic): add get_eq_get? (#12304)

Should it be get_eq_get?, get_eq_get?_get, or get_eq_get_get??

Diff
@@ -853,6 +853,13 @@ theorem tail_append_of_ne_nil (l l' : List α) (h : l ≠ []) : (l ++ l').tail =
   · simp
 #align list.tail_append_of_ne_nil List.tail_append_of_ne_nil
 
+theorem get_eq_iff {l : List α} {n : Fin l.length} {x : α} : l.get n = x ↔ l.get? n.1 = some x := by
+  simp [get?_eq_some]
+
+theorem get_eq_get? (l : List α) (i : Fin l.length) :
+    l.get i = (l.get? i).get (by simp [get?_eq_get]) := by
+  simp [get_eq_iff]
+
 section deprecated
 set_option linter.deprecated false -- TODO(Mario): make replacements for theorems in this section
 
@@ -1453,10 +1460,6 @@ theorem eq_cons_of_length_one {l : List α} (h : l.length = 1) :
   omega
 #align list.eq_cons_of_length_one List.eq_cons_of_length_one
 
-theorem get_eq_iff {l : List α} {n : Fin l.length} {x : α} : l.get n = x ↔ l.get? n.1 = some x := by
-  rw [get?_eq_some]
-  simp [n.2]
-
 @[deprecated get_eq_iff] -- 2023-01-05
 theorem nthLe_eq_iff {l : List α} {n : ℕ} {x : α} {h} : l.nthLe n h = x ↔ l.get? n = some x :=
   get_eq_iff
feat(List): add lemmas about Sublist (#12326)
  • Move tail_sublist to Basic
  • Rename sublist_of_cons_sublist_cons to Sublist.of_cons_cos
  • Rename cons_sublist_cons_iff to cons_sublist_cons
  • Add Sublist.tail, drop_sublist_drop_left, Sublist.drop
  • Protect some lemmas
Diff
@@ -1026,13 +1026,25 @@ theorem sublist_cons_of_sublist (a : α) (h : l₁ <+ l₂) : l₁ <+ a :: l₂
 #align list.sublist_append_of_sublist_left List.sublist_append_of_sublist_left
 #align list.sublist_append_of_sublist_right List.sublist_append_of_sublist_right
 
-theorem sublist_of_cons_sublist_cons {l₁ l₂ : List α} : ∀ {a : α}, a :: l₁ <+ a :: l₂ → l₁ <+ l₂
-  | _, Sublist.cons _ s => sublist_of_cons_sublist s
-  | _, Sublist.cons₂ _ s => s
-#align list.sublist_of_cons_sublist_cons List.sublist_of_cons_sublist_cons
+theorem tail_sublist : ∀ l : List α, tail l <+ l
+  | [] => .slnil
+  | a::l => sublist_cons a l
+#align list.tail_sublist List.tail_sublist
 
-theorem cons_sublist_cons_iff {l₁ l₂ : List α} {a : α} : a :: l₁ <+ a :: l₂ ↔ l₁ <+ l₂ :=
-  ⟨sublist_of_cons_sublist_cons, Sublist.cons_cons _⟩
+@[gcongr] protected theorem Sublist.tail : ∀ {l₁ l₂ : List α}, l₁ <+ l₂ → tail l₁ <+ tail l₂
+  | _, _, slnil => .slnil
+  | _, _, Sublist.cons _ h => (tail_sublist _).trans h
+  | _, _, Sublist.cons₂ _ h => h
+
+theorem Sublist.of_cons_cons {l₁ l₂ : List α} {a b : α} (h : a :: l₁ <+ b :: l₂) : l₁ <+ l₂ :=
+  h.tail
+#align list.sublist_of_cons_sublist_cons List.Sublist.of_cons_cons
+
+@[deprecated] -- 2024-04-07
+theorem sublist_of_cons_sublist_cons {a} (h : a :: l₁ <+ a :: l₂) : l₁ <+ l₂ := h.of_cons_cons
+
+attribute [simp] cons_sublist_cons
+@[deprecated] alias cons_sublist_cons_iff := cons_sublist_cons -- 2024-04-07
 #align list.cons_sublist_cons_iff List.cons_sublist_cons_iff
 
 #align list.append_sublist_append_left List.append_sublist_append_left
chore(Data/List): add dates to all deprecated lemmas (#12337)

Most of them go back to the port.

Diff
@@ -102,8 +102,7 @@ theorem _root_.Decidable.List.eq_or_ne_mem_of_mem [DecidableEq α]
 lemma mem_pair {a b c : α} : a ∈ [b, c] ↔ a = b ∨ a = c := by
   rw [mem_cons, mem_singleton]
 
--- 2024-03-23
-@[deprecated] alias mem_split := append_of_mem
+@[deprecated] alias mem_split := append_of_mem -- 2024-03-23
 #align list.mem_split List.append_of_mem
 
 #align list.mem_of_ne_of_mem List.mem_of_ne_of_mem
@@ -355,12 +354,10 @@ theorem append_eq_has_append {L₁ L₂ : List α} : List.append L₁ L₂ = L
 -- Porting note: in Std
 #align list.nil_eq_append_iff List.nil_eq_append
 
--- 2024-03-24
-@[deprecated] alias append_eq_cons_iff := append_eq_cons
+@[deprecated] alias append_eq_cons_iff := append_eq_cons -- 2024-03-24
 #align list.append_eq_cons_iff List.append_eq_cons
 
--- 2024-03-24
-@[deprecated] alias cons_eq_append_iff := cons_eq_append
+@[deprecated] alias cons_eq_append_iff := cons_eq_append -- 2024-03-24
 #align list.cons_eq_append_iff List.cons_eq_append
 
 #align list.append_eq_append_iff List.append_eq_append_iff
@@ -1187,12 +1184,12 @@ end IndexOf
 section deprecated
 set_option linter.deprecated false
 
-@[deprecated get_of_mem]
+@[deprecated get_of_mem] -- 2023-01-05
 theorem nthLe_of_mem {a} {l : List α} (h : a ∈ l) : ∃ n h, nthLe l n h = a :=
   let ⟨i, h⟩ := get_of_mem h; ⟨i.1, i.2, h⟩
 #align list.nth_le_of_mem List.nthLe_of_mem
 
-@[deprecated get?_eq_get]
+@[deprecated get?_eq_get] -- 2023-01-05
 theorem nthLe_get? {l : List α} {n} (h) : get? l n = some (nthLe l n h) := get?_eq_get _
 #align list.nth_le_nth List.nthLe_get?
 
@@ -1202,20 +1199,20 @@ theorem nthLe_get? {l : List α} {n} (h) : get? l n = some (nthLe l n h) := get?
 theorem get?_length (l : List α) : l.get? l.length = none := get?_len_le le_rfl
 #align list.nth_length List.get?_length
 
-@[deprecated get?_eq_some]
+@[deprecated get?_eq_some] -- 2023-01-05
 theorem get?_eq_some' {l : List α} {n a} : get? l n = some a ↔ ∃ h, nthLe l n h = a := get?_eq_some
 #align list.nth_eq_some List.get?_eq_some'
 
 #align list.nth_eq_none_iff List.get?_eq_none
 #align list.nth_of_mem List.get?_of_mem
 
-@[deprecated get_mem]
+@[deprecated get_mem] -- 2023-01-05
 theorem nthLe_mem (l : List α) (n h) : nthLe l n h ∈ l := get_mem ..
 #align list.nth_le_mem List.nthLe_mem
 
 #align list.nth_mem List.get?_mem
 
-@[deprecated mem_iff_get]
+@[deprecated mem_iff_get] -- 2023-01-05
 theorem mem_iff_nthLe {a} {l : List α} : a ∈ l ↔ ∃ n h, nthLe l n h = a :=
   mem_iff_get.trans ⟨fun ⟨⟨n, h⟩, e⟩ => ⟨n, h, e⟩, fun ⟨n, h, e⟩ => ⟨⟨n, h⟩, e⟩⟩
 #align list.mem_iff_nth_le List.mem_iff_nthLe
@@ -1241,7 +1238,7 @@ theorem get?_injective {α : Type u} {xs : List α} {i j : ℕ} (h₀ : i < xs.l
 
 #align list.nth_map List.get?_map
 
-@[deprecated get_map]
+@[deprecated get_map] -- 2023-01-05
 theorem nthLe_map (f : α → β) {l n} (H1 H2) : nthLe (map f l) n H1 = f (nthLe l n H2) := get_map ..
 #align list.nth_le_map List.nthLe_map
 
@@ -1250,13 +1247,13 @@ theorem get_map_rev (f : α → β) {l n} :
     f (get l n) = get (map f l) ⟨n.1, (l.length_map f).symm ▸ n.2⟩ := Eq.symm (get_map _)
 
 /-- A version of `nthLe_map` that can be used for rewriting. -/
-@[deprecated get_map_rev]
+@[deprecated get_map_rev] -- 2023-01-05
 theorem nthLe_map_rev (f : α → β) {l n} (H) :
     f (nthLe l n H) = nthLe (map f l) n ((l.length_map f).symm ▸ H) :=
   (nthLe_map f _ _).symm
 #align list.nth_le_map_rev List.nthLe_map_rev
 
-@[simp, deprecated get_map]
+@[simp, deprecated get_map] -- 2023-01-05
 theorem nthLe_map' (f : α → β) {l n} (H) :
     nthLe (map f l) n H = f (nthLe l n (l.length_map f ▸ H)) := nthLe_map f _ _
 #align list.nth_le_map' List.nthLe_map'
@@ -1264,35 +1261,35 @@ theorem nthLe_map' (f : α → β) {l n} (H) :
 /-- If one has `nthLe 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 lemma `nth_le_of_eq` can be used to make
 such a rewrite, with `rw (nth_le_of_eq h)`. -/
-@[deprecated get_of_eq]
+@[deprecated get_of_eq] -- 2023-01-05
 theorem nthLe_of_eq {L L' : List α} (h : L = L') {i : ℕ} (hi : i < L.length) :
     nthLe L i hi = nthLe L' i (h ▸ hi) := by congr
 #align list.nth_le_of_eq List.nthLe_of_eq
 
-@[simp, deprecated get_singleton]
+@[simp, deprecated get_singleton] -- 2023-01-05
 theorem nthLe_singleton (a : α) {n : ℕ} (hn : n < 1) : nthLe [a] n hn = a := get_singleton ..
 #align list.nth_le_singleton List.nthLe_singleton
 
-@[deprecated] -- FIXME: replacement -- it's not `get_zero` and it's not `get?_zero`
+@[deprecated] -- 2023-01-05 -- FIXME: replacement -- it's not `get_zero` and it's not `get?_zero`
 theorem nthLe_zero [Inhabited α] {L : List α} (h : 0 < L.length) : List.nthLe L 0 h = L.head! := by
   cases L
   cases h
   simp [nthLe]
 #align list.nth_le_zero List.nthLe_zero
 
-@[deprecated get_append]
+@[deprecated get_append] -- 2023-01-05
 theorem nthLe_append {l₁ l₂ : List α} {n : ℕ} (hn₁) (hn₂) :
     (l₁ ++ l₂).nthLe n hn₁ = l₁.nthLe n hn₂ := get_append _ hn₂
 #align list.nth_le_append List.nthLe_append
 
-@[deprecated get_append_right']
+@[deprecated get_append_right'] -- 2023-01-05
 theorem nthLe_append_right {l₁ l₂ : List α} {n : ℕ} (h₁ : l₁.length ≤ n) (h₂) :
     (l₁ ++ l₂).nthLe n h₂ = l₂.nthLe (n - l₁.length) (get_append_right_aux h₁ h₂) :=
   get_append_right' h₁ h₂
 #align list.nth_le_append_right_aux List.get_append_right_aux
 #align list.nth_le_append_right List.nthLe_append_right
 
-@[deprecated get_replicate]
+@[deprecated get_replicate] -- 2023-01-05
 theorem nthLe_replicate (a : α) {n m : ℕ} (h : m < (replicate n a).length) :
     (replicate n a).nthLe m h = a := get_replicate ..
 #align list.nth_le_replicate List.nthLe_replicate
@@ -1300,7 +1297,7 @@ theorem nthLe_replicate (a : α) {n m : ℕ} (h : m < (replicate n a).length) :
 #align list.nth_append List.get?_append
 #align list.nth_append_right List.get?_append_right
 
-@[deprecated getLast_eq_get]
+@[deprecated getLast_eq_get] -- 2023-01-05
 theorem getLast_eq_nthLe (l : List α) (h : l ≠ []) :
     getLast l h = l.nthLe (l.length - 1) (have := length_pos_of_ne_nil h; by omega) :=
   getLast_eq_get ..
@@ -1310,7 +1307,7 @@ theorem get_length_sub_one {l : List α} (h : l.length - 1 < l.length) :
     l.get ⟨l.length - 1, h⟩ = l.getLast (by rintro rfl; exact Nat.lt_irrefl 0 h) :=
   (getLast_eq_get l _).symm
 
-@[deprecated get_length_sub_one]
+@[deprecated get_length_sub_one] -- 2023-01-05
 theorem nthLe_length_sub_one {l : List α} (h : l.length - 1 < l.length) :
     l.nthLe (l.length - 1) h = l.getLast (by rintro rfl; exact Nat.lt_irrefl 0 h) :=
   get_length_sub_one _
@@ -1318,7 +1315,7 @@ theorem nthLe_length_sub_one {l : List α} (h : l.length - 1 < l.length) :
 
 #align list.nth_concat_length List.get?_concat_length
 
-@[deprecated get_cons_length]
+@[deprecated get_cons_length] -- 2023-01-05
 theorem nthLe_cons_length : ∀ (x : α) (xs : List α) (n : ℕ) (h : n = xs.length),
     (x :: xs).nthLe n (by simp [h]) = (x :: xs).getLast (cons_ne_nil x xs) := get_cons_length
 #align list.nth_le_cons_length List.nthLe_cons_length
@@ -1357,7 +1354,7 @@ theorem ext_get?_iff' {l₁ l₂ : List α} : l₁ = l₂ ↔
     ∀ n < max l₁.length l₂.length, l₁.get? n = l₂.get? n :=
   ⟨by rintro rfl _ _; rfl, ext_get?'⟩
 
-@[deprecated ext_get]
+@[deprecated ext_get] -- 2023-01-05
 theorem ext_nthLe {l₁ l₂ : List α} (hl : length l₁ = length l₂)
     (h : ∀ n h₁ h₂, nthLe l₁ n h₁ = nthLe l₂ n h₂) : l₁ = l₂ :=
   ext_get hl h
@@ -1369,7 +1366,7 @@ theorem indexOf_get [DecidableEq α] {a : α} : ∀ {l : List α} (h), get l ⟨
     by_cases h' : b = a <;>
     simp only [h', if_pos, if_false, indexOf_cons, get, @indexOf_get _ _ l, cond_eq_if, beq_iff_eq]
 
-@[simp, deprecated indexOf_get]
+@[simp, deprecated indexOf_get] -- 2023-01-05
 theorem indexOf_nthLe [DecidableEq α] {a : α} : ∀ {l : List α} (h), nthLe l (indexOf a l) h = a :=
   indexOf_get
 #align list.index_of_nth_le List.indexOf_nthLe
@@ -1379,7 +1376,7 @@ theorem indexOf_get? [DecidableEq α] {a : α} {l : List α} (h : a ∈ l) :
     get? l (indexOf a l) = some a := by rw [nthLe_get?, indexOf_nthLe (indexOf_lt_length.2 h)]
 #align list.index_of_nth List.indexOf_get?
 
-@[deprecated]
+@[deprecated] -- 2023-01-05
 theorem get_reverse_aux₁ :
     ∀ (l r : List α) (i h1 h2), get (reverseAux l r) ⟨i + length l, h1⟩ = get r ⟨i, h2⟩
   | [], r, i => fun h1 _ => rfl
@@ -1417,7 +1414,7 @@ theorem get_reverse_aux₂ :
     get (reverse l) ⟨length l - 1 - i, h1⟩ = get l ⟨i, h2⟩ :=
   get_reverse_aux₂ _ _ _ _ _
 
-@[simp, deprecated get_reverse]
+@[simp, deprecated get_reverse] -- 2023-01-05
 theorem nthLe_reverse (l : List α) (i : Nat) (h1 h2) :
     nthLe (reverse l) (length l - 1 - i) h1 = nthLe l i h2 :=
   get_reverse ..
@@ -1434,7 +1431,7 @@ theorem get_reverse' (l : List α) (n) (hn') :
     l.reverse.get n = l.get ⟨l.length - 1 - n, hn'⟩ := nthLe_reverse' ..
 
 -- FIXME: prove it the other way around
-attribute [deprecated get_reverse'] nthLe_reverse'
+attribute [deprecated get_reverse'] nthLe_reverse' -- 2023-01-05
 
 theorem eq_cons_of_length_one {l : List α} (h : l.length = 1) :
     l = [l.nthLe 0 (by omega)] := by
@@ -1448,12 +1445,12 @@ theorem get_eq_iff {l : List α} {n : Fin l.length} {x : α} : l.get n = x ↔ l
   rw [get?_eq_some]
   simp [n.2]
 
-@[deprecated get_eq_iff]
+@[deprecated get_eq_iff] -- 2023-01-05
 theorem nthLe_eq_iff {l : List α} {n : ℕ} {x : α} {h} : l.nthLe n h = x ↔ l.get? n = some x :=
   get_eq_iff
 #align list.nth_le_eq_iff List.nthLe_eq_iff
 
-@[deprecated get?_eq_get]
+@[deprecated get?_eq_get] -- 2023-01-05
 theorem some_nthLe_eq {l : List α} {n : ℕ} {h} : some (l.nthLe n h) = l.get? n :=
   (get?_eq_get _).symm
 #align list.some_nth_le_eq List.some_nthLe_eq
@@ -1527,7 +1524,7 @@ theorem length_modifyNth (f : α → α) : ∀ n l, length (modifyNth f n l) = l
 #align list.update_nth_succ List.set_succ
 #align list.update_nth_comm List.set_comm
 
-@[simp, deprecated get_set_eq]
+@[simp, deprecated get_set_eq] -- 2023-01-05
 theorem nthLe_set_eq (l : List α) (i : ℕ) (a : α) (h : i < (l.set i a).length) :
     (l.set i a).nthLe i h = a := get_set_eq ..
 #align list.nth_le_update_nth_eq List.nthLe_set_eq
@@ -1538,7 +1535,7 @@ theorem get_set_of_ne {l : List α} {i j : ℕ} (h : i ≠ j) (a : α)
     (l.set i a).get ⟨j, hj⟩ = l.get ⟨j, by simpa using hj⟩ := by
   rw [← Option.some_inj, ← List.get?_eq_get, List.get?_set_ne _ _ h, List.get?_eq_get]
 
-@[simp, deprecated get_set_of_ne]
+@[simp, deprecated get_set_of_ne] -- 2023-01-05
 theorem nthLe_set_of_ne {l : List α} {i j : ℕ} (h : i ≠ j) (a : α)
     (hj : j < (l.set i a).length) :
     (l.set i a).nthLe j hj = l.nthLe j (by simpa using hj) :=
@@ -1767,7 +1764,7 @@ theorem take_cons (n) (a : α) (l : List α) : take (succ n) (a :: l) = a :: tak
 set_option linter.deprecated false in
 /-- The `i`-th element of a list coincides with the `i`-th element of any of its prefixes of
 length `> i`. Version designed to rewrite from the big list to the small list. -/
-@[deprecated get_take]
+@[deprecated get_take] -- 2023-01-05
 theorem nthLe_take (L : List α) {i j : ℕ} (hi : i < L.length) (hj : i < j) :
     nthLe L i hi = nthLe (L.take j) i (length_take .. ▸ lt_min hj hi) :=
   get_take _ hi hj
@@ -1776,7 +1773,7 @@ theorem nthLe_take (L : List α) {i j : ℕ} (hi : i < L.length) (hj : i < j) :
 set_option linter.deprecated false in
 /-- The `i`-th element of a list coincides with the `i`-th element of any of its prefixes of
 length `> i`. Version designed to rewrite from the small list to the big list. -/
-@[deprecated get_take']
+@[deprecated get_take'] -- 2023-01-05
 theorem nthLe_take' (L : List α) {i j : ℕ} (hi : i < (L.take j).length) :
     nthLe (L.take j) i hi = nthLe L i (lt_of_lt_of_le hi (by simp only [length_take]; omega)) :=
   get_take' _
@@ -1804,7 +1801,7 @@ theorem cons_get_drop_succ {l : List α} {n} :
     l.get n :: l.drop (n.1 + 1) = l.drop n.1 :=
   (drop_eq_get_cons n.2).symm
 
-@[deprecated cons_get_drop_succ]
+@[deprecated cons_get_drop_succ] -- 2023-01-05
 theorem cons_nthLe_drop_succ {l : List α} {n : ℕ} (hn : n < l.length) :
     l.nthLe n hn :: l.drop (n + 1) = l.drop n := cons_get_drop_succ
 #align list.cons_nth_le_drop_succ List.cons_nthLe_drop_succ
@@ -1825,7 +1822,7 @@ theorem cons_nthLe_drop_succ {l : List α} {n : ℕ} (hn : n < l.length) :
 set_option linter.deprecated false in
 /-- The `i + j`-th element of a list coincides with the `j`-th element of the list obtained by
 dropping the first `i` elements. Version designed to rewrite from the big list to the small list. -/
-@[deprecated get_drop]
+@[deprecated get_drop] -- 2023-01-05
 theorem nthLe_drop (L : List α) {i j : ℕ} (h : i + j < L.length) :
     nthLe L (i + j) h = nthLe (L.drop i) j (by rw [length_drop]; omega) := get_drop ..
 #align list.nth_le_drop List.nthLe_drop
@@ -1833,7 +1830,7 @@ theorem nthLe_drop (L : List α) {i j : ℕ} (h : i + j < L.length) :
 set_option linter.deprecated false in
 /-- The `i + j`-th element of a list coincides with the `j`-th element of the list obtained by
 dropping the first `i` elements. Version designed to rewrite from the small list to the big list. -/
-@[deprecated get_drop']
+@[deprecated get_drop'] -- 2023-01-05
 theorem nthLe_drop' (L : List α) {i j : ℕ} (h : j < (L.drop i).length) :
     nthLe (L.drop i) j h = nthLe L (i + j) (have := length_drop i L; by omega) :=
   get_drop' ..
@@ -2155,7 +2152,7 @@ theorem get_zero_scanl {h : 0 < (scanl f b l).length} : (scanl f b l).get ⟨0,
   · simp only [get, scanl_cons, singleton_append]
 
 set_option linter.deprecated false in
-@[simp, deprecated get_zero_scanl]
+@[simp, deprecated get_zero_scanl] -- 2023-01-05
 theorem nthLe_zero_scanl {h : 0 < (scanl f b l).length} : (scanl f b l).nthLe 0 h = b :=
   get_zero_scanl
 #align list.nth_le_zero_scanl List.nthLe_zero_scanl
@@ -2199,7 +2196,7 @@ theorem get_succ_scanl {i : ℕ} {h : i + 1 < (scanl f b l).length} :
   nthLe_succ_scanl
 
 -- FIXME: we should do the proof the other way around
-attribute [deprecated get_succ_scanl] nthLe_succ_scanl
+attribute [deprecated get_succ_scanl] nthLe_succ_scanl -- 2023-01-05
 
 end Scanl
 
@@ -2716,7 +2713,7 @@ theorem get_pmap {p : α → Prop} (f : ∀ a, p a → β) {l : List α} (h : 
     · simp [hl]
 
 set_option linter.deprecated false in
-@[deprecated get_pmap]
+@[deprecated get_pmap] -- 2023-01-05
 theorem nthLe_pmap {p : α → Prop} (f : ∀ a, p a → β) {l : List α} (h : ∀ a ∈ l, p a) {n : ℕ}
     (hn : n < (pmap f l h).length) :
     nthLe (pmap f l h) n hn =
@@ -3609,7 +3606,7 @@ theorem getLast_reverse {l : List α} (hl : l.reverse ≠ [])
 #align list.last_reverse List.getLast_reverse
 
 set_option linter.deprecated false in
-@[deprecated]
+@[deprecated] -- 2023-01-05
 theorem ilast'_mem : ∀ a l, @ilast' α a l ∈ a :: l
   | a, [] => by simp [ilast']
   | a, b :: l => by rw [mem_cons]; exact Or.inr (ilast'_mem b l)
chore(Data/List/Basic): remove some long-deprecated unused lemmas (#12367)
Diff
@@ -3623,11 +3623,7 @@ theorem get_attach (L : List α) (i) :
       by rw [get_map]
     _ = L.get { val := i, isLt := _ } := by congr 2 <;> simp
 
-set_option linter.deprecated false in
-@[simp, deprecated get_attach]
-theorem nthLe_attach (L : List α) (i) (H : i < L.attach.length) :
-    (L.attach.nthLe i H).1 = L.nthLe i (length_attach L ▸ H) := get_attach ..
-#align list.nth_le_attach List.nthLe_attach
+#align list.nth_le_attach List.get_attach
 
 @[simp 1100]
 theorem mem_map_swap (x : α) (y : β) (xs : List (α × β)) :
chore(List): drop primed deprecated lemmas (#12307)

Cherry-picked from #9607

Co-authored-by: @semorrison

Diff
@@ -307,14 +307,8 @@ instance : IsTrans (List α) Subset where
   trans := fun _ _ _ => List.Subset.trans
 
 #align list.subset_def List.subset_def
-
 #align list.subset_append_of_subset_left List.subset_append_of_subset_left
-
-@[deprecated subset_append_of_subset_right]
-theorem subset_append_of_subset_right' (l l₁ l₂ : List α) : l ⊆ l₂ → l ⊆ l₁ ++ l₂ :=
-  subset_append_of_subset_right _
-#align list.subset_append_of_subset_right List.subset_append_of_subset_right'
-
+#align list.subset_append_of_subset_right List.subset_append_of_subset_right
 #align list.cons_subset List.cons_subset
 
 theorem cons_subset_of_subset_of_mem {a : α} {l m : List α}
@@ -515,21 +509,12 @@ theorem bind_eq_bind {α β} (f : α → List β) (l : List α) : l >>= f = l.bi
 #align list.concat_nil List.concat_nil
 #align list.concat_cons List.concat_cons
 
-@[deprecated concat_eq_append]
-theorem concat_eq_append' (a : α) (l : List α) : concat l a = l ++ [a] :=
-  concat_eq_append l a
-#align list.concat_eq_append List.concat_eq_append'
-
+#align list.concat_eq_append List.concat_eq_append
 #align list.init_eq_of_concat_eq List.init_eq_of_concat_eq
 #align list.last_eq_of_concat_eq List.last_eq_of_concat_eq
 #align list.concat_ne_nil List.concat_ne_nil
 #align list.concat_append List.concat_append
-
-@[deprecated length_concat]
-theorem length_concat' (a : α) (l : List α) : length (concat l a) = succ (length l) := by
-  simp only [concat_eq_append, length_append, length]
-#align list.length_concat List.length_concat'
-
+#align list.length_concat List.length_concat
 #align list.append_concat List.append_concat
 
 /-! ### reverse -/
@@ -1342,11 +1327,7 @@ 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_get_cons h, take, take]
 
-@[deprecated take_one_drop_eq_of_lt_length]
-theorem take_one_drop_eq_of_lt_length' {l : List α} {n : ℕ} (h : n < l.length) :
-    (l.drop n).take 1 = [l.nthLe n h] := take_one_drop_eq_of_lt_length h
-#align list.take_one_drop_eq_of_lt_length List.take_one_drop_eq_of_lt_length'
-
+#align list.take_one_drop_eq_of_lt_length List.take_one_drop_eq_of_lt_length
 #align list.ext List.ext
 
 -- TODO one may rename ext in the standard library, and it is also not clear
chore: update Std (#12210)

Co-authored-by: Scott Morrison <scott.morrison@gmail.com>

Diff
@@ -2646,13 +2646,13 @@ theorem pmap_map {p : β → Prop} (g : ∀ b, p b → γ) (f : α → β) (l H)
 
 theorem pmap_eq_map_attach {p : α → Prop} (f : ∀ a, p a → β) (l H) :
     pmap f l H = l.attach.map fun x => f x.1 (H _ x.2) := by
-  rw [attach, map_pmap]; exact pmap_congr l fun _ _ _ _ => rfl
+  rw [attach, attachWith, map_pmap]; exact pmap_congr l fun _ _ _ _ => rfl
 #align list.pmap_eq_map_attach List.pmap_eq_map_attach
 
 -- @[simp] -- Porting note (#10959): lean 4 simp can't rewrite with this
 theorem attach_map_coe' (l : List α) (f : α → β) :
     (l.attach.map fun (i : {i // i ∈ l}) => f i) = l.map f := by
-  rw [attach, map_pmap]; exact pmap_eq_map _ _ _ _
+  rw [attach, attachWith, map_pmap]; exact pmap_eq_map _ _ _ _
 #align list.attach_map_coe' List.attach_map_coe'
 
 theorem attach_map_val' (l : List α) (f : α → β) : (l.attach.map fun i => f i.val) = l.map f :=
chore: deprecate redundant theorems append_eq_cons_iff and cons_eq_append_iff (#11630)

These theorems already exist in Std: https://github.com/leanprover/std4/blob/e5306c3b0edefe722370b7387ee9bcd4631d6c17/Std/Data/List/Lemmas.lean#L150-L157

Diff
@@ -361,17 +361,13 @@ theorem append_eq_has_append {L₁ L₂ : List α} : List.append L₁ L₂ = L
 -- Porting note: in Std
 #align list.nil_eq_append_iff List.nil_eq_append
 
-theorem append_eq_cons_iff {a b c : List α} {x : α} :
-    a ++ b = x :: c ↔ a = [] ∧ b = x :: c ∨ ∃ a', a = x :: a' ∧ c = a' ++ b := by
-  cases a <;>
-    simp only [and_assoc, @eq_comm _ c, nil_append, cons_append, cons.injEq, true_and_iff,
-      false_and_iff, exists_false, false_or_iff, or_false_iff, exists_and_left, exists_eq_left']
-#align list.append_eq_cons_iff List.append_eq_cons_iff
-
-theorem cons_eq_append_iff {a b c : List α} {x : α} :
-    (x :: c : List α) = a ++ b ↔ a = [] ∧ b = x :: c ∨ ∃ a', a = x :: a' ∧ c = a' ++ b := by
-  rw [eq_comm, append_eq_cons_iff]
-#align list.cons_eq_append_iff List.cons_eq_append_iff
+-- 2024-03-24
+@[deprecated] alias append_eq_cons_iff := append_eq_cons
+#align list.append_eq_cons_iff List.append_eq_cons
+
+-- 2024-03-24
+@[deprecated] alias cons_eq_append_iff := cons_eq_append
+#align list.cons_eq_append_iff List.cons_eq_append
 
 #align list.append_eq_append_iff List.append_eq_append_iff
 
chore(Data/List/Enum): move from Basic (#11697)
Diff
@@ -3296,156 +3296,6 @@ theorem erase_diff_erase_sublist_of_sublist {a : α} :
 
 end Diff
 
-/-! ### enum -/
-
-#align list.length_enum_from List.enumFrom_length
-#align list.length_enum List.enum_length
-
-@[simp]
-theorem enumFrom_get? :
-    ∀ (n) (l : List α) (m), get? (enumFrom n l) m = (fun a => (n + m, a)) <$> get? l m
-  | n, [], m => rfl
-  | n, a :: l, 0 => rfl
-  | n, a :: l, m + 1 => (enumFrom_get? (n + 1) l m).trans <| by rw [Nat.add_right_comm]; rfl
-#align list.enum_from_nth List.enumFrom_get?
-
-@[simp]
-theorem enum_get? : ∀ (l : List α) (n), get? (enum l) n = (fun a => (n, a)) <$> get? l n := by
-  simp only [enum, enumFrom_get?, Nat.zero_add]; intros; trivial
-#align list.enum_nth List.enum_get?
-
-@[simp]
-theorem enumFrom_map_snd : ∀ (n) (l : List α), map Prod.snd (enumFrom n l) = l
-  | _, [] => rfl
-  | _, _ :: _ => congr_arg (cons _) (enumFrom_map_snd _ _)
-#align list.enum_from_map_snd List.enumFrom_map_snd
-
-@[simp]
-theorem enum_map_snd : ∀ l : List α, map Prod.snd (enum l) = l :=
-  enumFrom_map_snd _
-#align list.enum_map_snd List.enum_map_snd
-
-theorem mem_enumFrom {x : α} {i : ℕ} :
-    ∀ {j : ℕ} (xs : List α), (i, x) ∈ xs.enumFrom j → j ≤ i ∧ i < j + xs.length ∧ x ∈ xs
-  | j, [] => by simp [enumFrom]
-  | j, y :: ys => by
-    suffices
-      i = j ∧ x = y ∨ (i, x) ∈ enumFrom (j + 1) ys →
-        j ≤ i ∧ i < j + (length ys + 1) ∧ (x = y ∨ x ∈ ys)
-      by simpa [enumFrom, mem_enumFrom ys]
-    rintro (h | h)
-    · refine' ⟨le_of_eq h.1.symm, h.1 ▸ _, Or.inl h.2⟩
-      apply Nat.lt_add_of_pos_right; simp
-    · have ⟨hji, hijlen, hmem⟩ := mem_enumFrom _ h
-      refine' ⟨_, _, _⟩
-      · exact le_trans (Nat.le_succ _) hji
-      · convert hijlen using 1
-        omega
-      · simp [hmem]
-#align list.mem_enum_from List.mem_enumFrom
-
-@[simp]
-theorem enum_nil : enum ([] : List α) = [] :=
-  rfl
-#align list.enum_nil List.enum_nil
-
-#align list.enum_from_nil List.enumFrom_nil
-
-#align list.enum_from_cons List.enumFrom_cons
-
-@[simp]
-theorem enum_cons (x : α) (xs : List α) : enum (x :: xs) = (0, x) :: enumFrom 1 xs :=
-  rfl
-#align list.enum_cons List.enum_cons
-
-@[simp]
-theorem enumFrom_singleton (x : α) (n : ℕ) : enumFrom n [x] = [(n, x)] :=
-  rfl
-#align list.enum_from_singleton List.enumFrom_singleton
-
-@[simp]
-theorem enum_singleton (x : α) : enum [x] = [(0, x)] :=
-  rfl
-#align list.enum_singleton List.enum_singleton
-
-theorem enumFrom_append (xs ys : List α) (n : ℕ) :
-    enumFrom n (xs ++ ys) = enumFrom n xs ++ enumFrom (n + xs.length) ys := by
-  induction' xs with x xs IH generalizing ys n
-  · simp
-  · rw [cons_append, enumFrom_cons, IH, ← cons_append, ← enumFrom_cons, length, Nat.add_right_comm,
-      Nat.add_assoc]
-#align list.enum_from_append List.enumFrom_append
-
-theorem enum_append (xs ys : List α) : enum (xs ++ ys) = enum xs ++ enumFrom xs.length ys := by
-  simp [enum, enumFrom_append]
-#align list.enum_append List.enum_append
-
-theorem map_fst_add_enumFrom_eq_enumFrom (l : List α) (n k : ℕ) :
-    map (Prod.map (· + n) id) (enumFrom k l) = enumFrom (n + k) l := by
-  induction l generalizing n k <;> [rfl; simp_all [Nat.add_assoc, Nat.add_comm k]]
-#align list.map_fst_add_enum_from_eq_enum_from List.map_fst_add_enumFrom_eq_enumFrom
-
-theorem map_fst_add_enum_eq_enumFrom (l : List α) (n : ℕ) :
-    map (Prod.map (· + n) id) (enum l) = enumFrom n l :=
-  map_fst_add_enumFrom_eq_enumFrom l _ _
-#align list.map_fst_add_enum_eq_enum_from List.map_fst_add_enum_eq_enumFrom
-
-theorem enumFrom_cons' (n : ℕ) (x : α) (xs : List α) :
-    enumFrom n (x :: xs) = (n, x) :: (enumFrom n xs).map (Prod.map Nat.succ id) := by
-  rw [enumFrom_cons, Nat.add_comm, ← map_fst_add_enumFrom_eq_enumFrom]
-#align list.enum_from_cons' List.enumFrom_cons'
-
-theorem enum_cons' (x : α) (xs : List α) :
-    enum (x :: xs) = (0, x) :: (enum xs).map (Prod.map Nat.succ id) :=
-  enumFrom_cons' _ _ _
-#align list.enum_cons' List.enum_cons'
-
-theorem enumFrom_map (n : ℕ) (l : List α) (f : α → β) :
-    enumFrom n (l.map f) = (enumFrom n l).map (Prod.map id f) := by
-  induction' l with hd tl IH
-  · rfl
-  · rw [map_cons, enumFrom_cons', enumFrom_cons', map_cons, map_map, IH, map_map]
-    rfl
-#align list.enum_from_map List.enumFrom_map
-
-theorem enum_map (l : List α) (f : α → β) : (l.map f).enum = l.enum.map (Prod.map id f) :=
-  enumFrom_map _ _ _
-#align list.enum_map List.enum_map
-
-theorem get_enumFrom (l : List α) (n) (i : Fin (l.enumFrom n).length)
-    (hi : i.1 < l.length := (by simpa using i.2)) :
-    (l.enumFrom n).get i = (n + i, l.get ⟨i, hi⟩) := by
-  rw [← Option.some_inj, ← get?_eq_get]
-  simp [enumFrom_get?, get?_eq_get hi]
-
-set_option linter.deprecated false in
-@[deprecated get_enumFrom]
-theorem nthLe_enumFrom (l : List α) (n i : ℕ) (hi' : i < (l.enumFrom n).length)
-    (hi : i < l.length := (by simpa using hi')) :
-    (l.enumFrom n).nthLe i hi' = (n + i, l.nthLe i hi) :=
-  get_enumFrom ..
-#align list.nth_le_enum_from List.nthLe_enumFrom
-
-theorem get_enum (l : List α) (i : Fin l.enum.length)
-    (hi : i < l.length := (by simpa using i.2)) :
-    l.enum.get i = (i.1, l.get ⟨i, hi⟩) := by
-  convert get_enumFrom _ _ i
-  exact (Nat.zero_add _).symm
-
-set_option linter.deprecated false in
-@[deprecated get_enum]
-theorem nthLe_enum (l : List α) (i : ℕ) (hi' : i < l.enum.length)
-    (hi : i < l.length := (by simpa using hi')) :
-    l.enum.nthLe i hi' = (i, l.nthLe i hi) := get_enum ..
-#align list.nth_le_enum List.nthLe_enum
-
-@[simp]
-theorem enumFrom_eq_nil {n : ℕ} {l : List α} : List.enumFrom n l = [] ↔ l = [] := by
-  cases l <;> simp
-
-@[simp]
-theorem enum_eq_nil {l : List α} : List.enum l = [] ↔ l = [] := enumFrom_eq_nil
-
 section Choose
 
 variable (p : α → Prop) [DecidablePred p] (l : List α)
chore: avoid id.def (adaptation for nightly-2024-03-27) (#11829)

Co-authored-by: Ruben Van de Velde <65514131+Ruben-VandeVelde@users.noreply.github.com>

Diff
@@ -3027,7 +3027,7 @@ lemma filter_attach (l : List α) (p : α → Bool) :
     (l.attach.filter fun x => p x : List {x // x ∈ l}) =
       (l.filter p).attach.map (Subtype.map id fun x => mem_of_mem_filter) :=
   map_injective_iff.2 Subtype.coe_injective <| by
-    simp_rw [map_map, (· ∘ ·), Subtype.map, id.def, ← Function.comp_apply (g := Subtype.val),
+    simp_rw [map_map, (· ∘ ·), Subtype.map, id, ← Function.comp_apply (g := Subtype.val),
       ← map_filter, attach_map_val]
 #align list.filter_attach List.filter_attach
 
chore(List/Basic): golf some proofs (#11996)
Diff
@@ -1042,8 +1042,7 @@ theorem Sublist.cons_cons {l₁ l₂ : List α} (a : α) (s : l₁ <+ l₂) : a
 #align list.sublist_append_left List.sublist_append_left
 #align list.sublist_append_right List.sublist_append_right
 
-theorem sublist_cons_of_sublist (a : α) {l₁ l₂ : List α} : l₁ <+ l₂ → l₁ <+ a :: l₂ :=
-  Sublist.cons _
+theorem sublist_cons_of_sublist (a : α) (h : l₁ <+ l₂) : l₁ <+ a :: l₂ := h.cons _
 #align list.sublist_cons_of_sublist List.sublist_cons_of_sublist
 
 #align list.sublist_append_of_sublist_left List.sublist_append_of_sublist_left
@@ -1105,8 +1104,7 @@ instance decidableSublist [DecidableEq α] : ∀ l₁ l₂ : List α, Decidable
   | _ :: _, [] => isFalse fun h => List.noConfusion <| eq_nil_of_sublist_nil h
   | a :: l₁, b :: l₂ =>
     if h : a = b then
-      @decidable_of_decidable_of_iff _ _ (decidableSublist l₁ l₂) <|
-        h ▸ ⟨Sublist.cons_cons _, sublist_of_cons_sublist_cons⟩
+      @decidable_of_decidable_of_iff _ _ (decidableSublist l₁ l₂) <| h ▸ cons_sublist_cons.symm
     else
       @decidable_of_decidable_of_iff _ _ (decidableSublist (a :: l₁) l₂)
         ⟨sublist_cons_of_sublist _, fun s =>
@@ -1346,20 +1344,7 @@ theorem nthLe_cons_length : ∀ (x : α) (xs : List α) (n : ℕ) (h : n = xs.le
 
 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
-  induction' l with x l ih generalizing n
-  · cases h
-  · by_cases h₁ : l = []
-    · subst h₁
-      rw [get_singleton]
-      simp only [length_cons, length_nil, Nat.lt_succ_iff, le_zero_eq] at h
-      subst h
-      simp
-    have h₂ := h
-    rw [length_cons, Nat.lt_succ_iff, le_iff_eq_or_lt] at h₂
-    cases n
-    · simp [get]
-    rw [drop, get]
-    apply ih
+  rw [drop_eq_get_cons h, take, take]
 
 @[deprecated take_one_drop_eq_of_lt_length]
 theorem take_one_drop_eq_of_lt_length' {l : List α} {n : ℕ} (h : n < l.length) :
@@ -1836,17 +1821,11 @@ theorem nthLe_take' (L : List α) {i j : ℕ} (hi : i < (L.take j).length) :
 
 @[simp]
 theorem drop_tail (l : List α) (n : ℕ) : l.tail.drop n = l.drop (n + 1) := by
-  induction' l <;> simp
+  rw [drop_add, drop_one]
 
 theorem cons_get_drop_succ {l : List α} {n} :
-    l.get n :: l.drop (n.1 + 1) = l.drop n.1 := by
-  induction' l with hd tl hl
-  · exact absurd n.1.zero_le (not_le_of_lt (nomatch n))
-  · match n with
-    | ⟨0, _⟩ => simp [get]
-    | ⟨n+1, hn⟩ =>
-      simp only [Nat.succ_lt_succ_iff, List.length] at hn
-      simpa [List.get, List.drop] using hl
+    l.get n :: l.drop (n.1 + 1) = l.drop n.1 :=
+  (drop_eq_get_cons n.2).symm
 
 @[deprecated cons_get_drop_succ]
 theorem cons_nthLe_drop_succ {l : List α} {n : ℕ} (hn : n < l.length) :
@@ -1871,11 +1850,7 @@ set_option linter.deprecated false in
 dropping the first `i` elements. Version designed to rewrite from the big list to the small list. -/
 @[deprecated get_drop]
 theorem nthLe_drop (L : List α) {i j : ℕ} (h : i + j < L.length) :
-    nthLe L (i + j) h = nthLe (L.drop i) j (by
-      have A : i < L.length := lt_of_le_of_lt (Nat.le.intro rfl) h
-      rw [(take_append_drop i L).symm] at h
-      simp_all only [take_append_drop, length_drop, gt_iff_lt]
-      omega) := get_drop ..
+    nthLe L (i + j) h = nthLe (L.drop i) j (by rw [length_drop]; omega) := get_drop ..
 #align list.nth_le_drop List.nthLe_drop
 
 set_option linter.deprecated false in
chore: remove more bex and ball from lemma names (#11615)

Follow-up to #10816.

Remaining places containing such lemmas are

  • Option.bex_ne_none and Option.ball_ne_none: defined in Lean core
  • Nat.decidableBallLT and Nat.decidableBallLE: defined in Lean core
  • bef_def is still used in a number of places and could be renamed
  • BAll.imp_{left,right}, BEx.imp_{left,right}, BEx.intro and BEx.elim

I only audited the first ~150 lemmas mentioning "ball"; too many lemmas named after Metric.ball/openBall/closedBall.

Co-authored-by: Yaël Dillies <yael.dillies@gmail.com>

Diff
@@ -274,8 +274,6 @@ theorem forall_mem_of_forall_mem_cons {p : α → Prop} {a : α} {l : List α} (
 
 #align list.forall_mem_append List.forall_mem_append
 
-theorem not_exists_mem_nil (p : α → Prop) : ¬∃ x ∈ @nil α, p x :=
-  nofun
 #align list.not_exists_mem_nil List.not_exists_mem_nilₓ -- bExists change
 
 -- Porting note: bExists in Lean3 and And in Lean4
feat: list lemmas (#11626)

Add some general purpose lemmas on lists. The new ext_get?' is intermediate between ext and ext_get, and for consistent naming add an alias ext_get? for ext.

Co-authored-by: sven-manthe <147848313+sven-manthe@users.noreply.github.com>

Diff
@@ -397,6 +397,18 @@ theorem cons_eq_append_iff {a b c : List α} {x : α} :
 @[deprecated] alias append_right_cancel := append_cancel_right -- deprecated since 2024-01-18
 #align list.append_right_cancel List.append_cancel_right
 
+@[simp] theorem append_left_eq_self {x y : List α} : x ++ y = y ↔ x = [] := by
+  rw [← append_left_inj (s₁ := x), nil_append]
+
+@[simp] theorem self_eq_append_left {x y : List α} : y = x ++ y ↔ x = [] := by
+  rw [eq_comm, append_left_eq_self]
+
+@[simp] theorem append_right_eq_self {x y : List α} : x ++ y = x ↔ y = [] := by
+  rw [← append_right_inj (t₁ := y), append_nil]
+
+@[simp] theorem self_eq_append_right {x y : List α} : x = x ++ y ↔ y = [] := by
+  rw [eq_comm, append_right_eq_self]
+
 theorem append_right_injective (s : List α) : Injective fun t ↦ s ++ t :=
   fun _ _ ↦ append_cancel_left
 #align list.append_right_injective List.append_right_injective
@@ -487,6 +499,9 @@ theorem replicate_left_injective (a : α) : Injective (replicate · a) :=
   (replicate_left_injective a).eq_iff
 #align list.replicate_left_inj List.replicate_left_inj
 
+@[simp] theorem head_replicate (n : ℕ) (a : α) (h) : head (replicate n a) h = a := by
+  cases n <;> simp at h ⊢
+
 /-! ### pure -/
 
 theorem mem_pure {α} (x y : α) : x ∈ (pure y : List α) ↔ x = y := by simp
@@ -540,6 +555,9 @@ theorem reverse_cons' (a : α) (l : List α) : reverse (a :: l) = concat (revers
   simp only [reverse_cons, concat_eq_append]
 #align list.reverse_cons' List.reverse_cons'
 
+theorem reverse_concat' (l : List α) (a : α) : (l ++ [a]).reverse = a :: l.reverse := by
+  rw [reverse_append]; rfl
+
 -- Porting note (#10618): simp can prove this
 -- @[simp]
 theorem reverse_singleton (a : α) : reverse [a] = [a] :=
@@ -771,6 +789,9 @@ theorem getLast?_append {l₁ l₂ : List α} {x : α} (h : x ∈ l₂.getLast?)
 
 /-! ### head(!?) and tail -/
 
+@[simp] theorem head_cons_tail (x : List α) (h : x ≠ []) : x.head h :: x.tail = x := by
+  cases x <;> simp at h ⊢
+
 theorem head!_eq_head? [Inhabited α] (l : List α) : head! l = (head? l).iget := by cases l <;> rfl
 #align list.head_eq_head' List.head!_eq_head?
 
@@ -1349,6 +1370,33 @@ theorem take_one_drop_eq_of_lt_length' {l : List α} {n : ℕ} (h : n < l.length
 
 #align list.ext List.ext
 
+-- TODO one may rename ext in the standard library, and it is also not clear
+-- which of ext_get?, ext_get?', ext_get should be @[ext], if any
+alias ext_get? := ext
+
+theorem ext_get?' {l₁ l₂ : List α} (h' : ∀ n < max l₁.length l₂.length, l₁.get? n = l₂.get? n) :
+    l₁ = l₂ := by
+  apply ext
+  intro n
+  rcases Nat.lt_or_ge n <| max l₁.length l₂.length with hn | hn
+  · exact h' n hn
+  · simp_all [Nat.max_le, get?_eq_none.mpr]
+
+theorem ext_get?_iff {l₁ l₂ : List α} : l₁ = l₂ ↔ ∀ n, l₁.get? n = l₂.get? n :=
+  ⟨by rintro rfl _; rfl, ext_get?⟩
+
+theorem ext_get_iff {l₁ l₂ : List α} :
+    l₁ = l₂ ↔ l₁.length = l₂.length ∧ ∀ n h₁ h₂, get l₁ ⟨n, h₁⟩ = get l₂ ⟨n, h₂⟩ := by
+  constructor
+  · rintro rfl
+    exact ⟨rfl, fun _ _ _ ↦ rfl⟩
+  · intro ⟨h₁, h₂⟩
+    exact ext_get h₁ h₂
+
+theorem ext_get?_iff' {l₁ l₂ : List α} : l₁ = l₂ ↔
+    ∀ n < max l₁.length l₂.length, l₁.get? n = l₂.get? n :=
+  ⟨by rintro rfl _ _; rfl, ext_get?'⟩
+
 @[deprecated ext_get]
 theorem ext_nthLe {l₁ l₂ : List α} (hl : length l₁ = length l₂)
     (h : ∀ n h₁ h₂, nthLe l₁ n h₁ = nthLe l₂ n h₂) : l₁ = l₂ :=
chore(Data/List): Use Std lemmas (#11711)

Make use of Nat-specific lemmas from Std rather than the general ones provided by mathlib. Also reverse the dependency between Multiset.Nodup/Multiset.dedup and Multiset.sum since only the latter needs algebra. Also rename Algebra.BigOperators.Multiset.Abs to Algebra.BigOperators.Multiset.Order and move some lemmas from Algebra.BigOperators.Multiset.Basic to it.

The ultimate goal here is to carve out Data, Algebra and Order sublibraries.

Diff
@@ -3,18 +3,17 @@ Copyright (c) 2014 Parikshit Khanna. All rights reserved.
 Released under Apache 2.0 license as described in the file LICENSE.
 Authors: Parikshit Khanna, Jeremy Avigad, Leonardo de Moura, Floris van Doorn, Mario Carneiro
 -/
-import Mathlib.Init.Data.List.Instances
-import Mathlib.Init.Data.Bool.Lemmas
-import Mathlib.Init.Data.List.Lemmas
-import Mathlib.Data.Nat.Defs
-import Mathlib.Data.Nat.Basic
 import Mathlib.Data.Bool.Basic
+import Mathlib.Data.Nat.Defs
 import Mathlib.Data.Option.Basic
 import Mathlib.Data.List.Defs
+import Mathlib.Init.Data.List.Basic
+import Mathlib.Init.Data.List.Instances
+import Mathlib.Init.Data.List.Lemmas
+import Mathlib.Logic.Unique
 import Mathlib.Order.Basic
 import Std.Data.List.Lemmas
 import Mathlib.Tactic.Common
-import Mathlib.Init.Data.List.Basic
 
 #align_import data.list.basic from "leanprover-community/mathlib"@"65a1391a0106c9204fe45bc73a039f056558cb83"
 
@@ -22,12 +21,14 @@ import Mathlib.Init.Data.List.Basic
 # Basic properties of lists
 -/
 
+assert_not_exists Set.range
+assert_not_exists GroupWithZero
+assert_not_exists Ring
+
 open Function
 
 open Nat hiding one_pos
 
-assert_not_exists Set.range
-
 namespace List
 
 universe u v w
@@ -435,7 +436,7 @@ theorem eq_replicate_length {a : α} : ∀ {l : List α}, l = replicate l.length
 #align list.eq_replicate List.eq_replicate
 
 theorem replicate_add (m n) (a : α) : replicate (m + n) a = replicate m a ++ replicate n a := by
-  induction m <;> simp [*, zero_add, succ_add, replicate]
+  induction m <;> simp [*, succ_add, replicate]
 #align list.replicate_add List.replicate_add
 
 theorem replicate_succ' (n) (a : α) : replicate (n + 1) a = replicate n a ++ [a] :=
@@ -1176,7 +1177,7 @@ theorem indexOf_append_of_mem {a : α} (h : a ∈ l₁) : indexOf a (l₁ ++ l
 theorem indexOf_append_of_not_mem {a : α} (h : a ∉ l₁) :
     indexOf a (l₁ ++ l₂) = l₁.length + indexOf a l₂ := by
   induction' l₁ with d₁ t₁ ih
-  · rw [List.nil_append, List.length, zero_add]
+  · rw [List.nil_append, List.length, Nat.zero_add]
   rw [List.cons_append, indexOf_cons_ne _ (ne_of_not_mem_cons h).symm, List.length,
     ih (not_mem_of_not_mem_cons h), Nat.succ_add]
 #align list.index_of_append_of_not_mem List.indexOf_append_of_not_mem
@@ -1395,14 +1396,11 @@ theorem get_reverse_aux₂ :
   | [], r, i, h1, h2 => absurd h2 (Nat.not_lt_zero _)
   | a :: l, r, 0, h1, _ => by
     have aux := get_reverse_aux₁ l (a :: r) 0
-    rw [zero_add] at aux
+    rw [Nat.zero_add] at aux
     exact aux _ (zero_lt_succ _)
   | a :: l, r, i + 1, h1, h2 => by
     have aux := get_reverse_aux₂ l (a :: r) i
-    have heq :=
-      calc
-        length (a :: l) - 1 - (i + 1) = length l - (1 + i) := by rw [add_comm]; rfl
-        _ = length l - 1 - i := by omega
+    have heq : length (a :: l) - 1 - (i + 1) = length l - 1 - i := by rw [length]; omega
     rw [← heq] at aux
     apply aux
 #align list.nth_le_reverse_aux2 List.get_reverse_aux₂
@@ -1468,7 +1466,7 @@ theorem modifyNthTail_modifyNthTail_le {f g : List α → List α} (m n : ℕ) (
     (l.modifyNthTail f n).modifyNthTail g m =
       l.modifyNthTail (fun l => (f l).modifyNthTail g (m - n)) n := by
   rcases Nat.exists_eq_add_of_le h with ⟨m, rfl⟩
-  rw [add_comm, modifyNthTail_modifyNthTail, Nat.add_sub_cancel]
+  rw [Nat.add_comm, modifyNthTail_modifyNthTail, Nat.add_sub_cancel]
 #align list.modify_nth_tail_modify_nth_tail_le List.modifyNthTail_modifyNthTail_le
 
 theorem modifyNthTail_modifyNthTail_same {f g : List α → List α} (n : ℕ) (l : List α) :
@@ -2188,11 +2186,11 @@ theorem nthLe_succ_scanl {i : ℕ} {h : i + 1 < (scanl f b l).length} :
     · simp [scanl_cons, singleton_append, nthLe_zero_scanl, nthLe_cons]
   | succ i hi =>
     cases l
-    · simp only [length, zero_add] at h
+    · simp only [length] at h
       exact absurd h (by omega)
     · simp_rw [scanl_cons]
       rw [nthLe_append_right]
-      · simp only [length, zero_add 1, succ_add_sub_one, hi]; rfl
+      · simp only [length, Nat.zero_add 1, succ_add_sub_one, hi]; rfl
       · simp only [length_singleton]; omega
 #align list.nth_le_succ_scanl List.nthLe_succ_scanl
 
@@ -3292,7 +3290,7 @@ theorem enumFrom_get? :
 
 @[simp]
 theorem enum_get? : ∀ (l : List α) (n), get? (enum l) n = (fun a => (n, a)) <$> get? l n := by
-  simp only [enum, enumFrom_get?, zero_add]; intros; trivial
+  simp only [enum, enumFrom_get?, Nat.zero_add]; intros; trivial
 #align list.enum_nth List.enum_get?
 
 @[simp]
@@ -3354,7 +3352,7 @@ theorem enumFrom_append (xs ys : List α) (n : ℕ) :
   induction' xs with x xs IH generalizing ys n
   · simp
   · rw [cons_append, enumFrom_cons, IH, ← cons_append, ← enumFrom_cons, length, Nat.add_right_comm,
-      add_assoc]
+      Nat.add_assoc]
 #align list.enum_from_append List.enumFrom_append
 
 theorem enum_append (xs ys : List α) : enum (xs ++ ys) = enum xs ++ enumFrom xs.length ys := by
@@ -3363,7 +3361,7 @@ theorem enum_append (xs ys : List α) : enum (xs ++ ys) = enum xs ++ enumFrom xs
 
 theorem map_fst_add_enumFrom_eq_enumFrom (l : List α) (n k : ℕ) :
     map (Prod.map (· + n) id) (enumFrom k l) = enumFrom (n + k) l := by
-  induction l generalizing n k <;> [rfl; simp_all [add_assoc, add_comm k]]
+  induction l generalizing n k <;> [rfl; simp_all [Nat.add_assoc, Nat.add_comm k]]
 #align list.map_fst_add_enum_from_eq_enum_from List.map_fst_add_enumFrom_eq_enumFrom
 
 theorem map_fst_add_enum_eq_enumFrom (l : List α) (n : ℕ) :
@@ -3373,7 +3371,7 @@ theorem map_fst_add_enum_eq_enumFrom (l : List α) (n : ℕ) :
 
 theorem enumFrom_cons' (n : ℕ) (x : α) (xs : List α) :
     enumFrom n (x :: xs) = (n, x) :: (enumFrom n xs).map (Prod.map Nat.succ id) := by
-  rw [enumFrom_cons, add_comm, ← map_fst_add_enumFrom_eq_enumFrom]
+  rw [enumFrom_cons, Nat.add_comm, ← map_fst_add_enumFrom_eq_enumFrom]
 #align list.enum_from_cons' List.enumFrom_cons'
 
 theorem enum_cons' (x : α) (xs : List α) :
@@ -3411,7 +3409,7 @@ theorem get_enum (l : List α) (i : Fin l.enum.length)
     (hi : i < l.length := (by simpa using i.2)) :
     l.enum.get i = (i.1, l.get ⟨i, hi⟩) := by
   convert get_enumFrom _ _ i
-  exact (zero_add _).symm
+  exact (Nat.zero_add _).symm
 
 set_option linter.deprecated false in
 @[deprecated get_enum]
chore(List/ReduceOption): move from Basic.lean (#11662)

Also rename List.IsPrefix.filter_map to List.IsPrefix.filterMap and protect some theorems in the List.IsPrefix namespace.

Diff
@@ -2917,96 +2917,6 @@ theorem Sublist.map (f : α → β) {l₁ l₂ : List α} (s : l₁ <+ l₂) : m
   filterMap_eq_map f ▸ s.filterMap _
 #align list.sublist.map List.Sublist.map
 
-/-! ### reduceOption -/
-
-@[simp]
-theorem reduceOption_cons_of_some (x : α) (l : List (Option α)) :
-    reduceOption (some x :: l) = x :: l.reduceOption := by
-  simp only [reduceOption, filterMap, id.def, eq_self_iff_true, and_self_iff]
-#align list.reduce_option_cons_of_some List.reduceOption_cons_of_some
-
-@[simp]
-theorem reduceOption_cons_of_none (l : List (Option α)) :
-    reduceOption (none :: l) = l.reduceOption := by simp only [reduceOption, filterMap, id.def]
-#align list.reduce_option_cons_of_none List.reduceOption_cons_of_none
-
-@[simp]
-theorem reduceOption_nil : @reduceOption α [] = [] :=
-  rfl
-#align list.reduce_option_nil List.reduceOption_nil
-
-@[simp]
-theorem reduceOption_map {l : List (Option α)} {f : α → β} :
-    reduceOption (map (Option.map f) l) = map f (reduceOption l) := by
-  induction' l with hd tl hl
-  · simp only [reduceOption_nil, map_nil]
-  · cases hd <;>
-      simpa [true_and_iff, Option.map_some', map, eq_self_iff_true,
-        reduceOption_cons_of_some] using hl
-#align list.reduce_option_map List.reduceOption_map
-
-theorem reduceOption_append (l l' : List (Option α)) :
-    (l ++ l').reduceOption = l.reduceOption ++ l'.reduceOption :=
-  filterMap_append l l' id
-#align list.reduce_option_append List.reduceOption_append
-
-theorem reduceOption_length_le (l : List (Option α)) : l.reduceOption.length ≤ l.length := by
-  induction' l with hd tl hl
-  · simp [reduceOption_nil, length]
-  · cases hd
-    · exact Nat.le_succ_of_le hl
-    · simpa only [length, Nat.add_le_add_iff_right, reduceOption_cons_of_some] using hl
-#align list.reduce_option_length_le List.reduceOption_length_le
-
-theorem reduceOption_length_eq_iff {l : List (Option α)} :
-    l.reduceOption.length = l.length ↔ ∀ x ∈ l, Option.isSome x := by
-  induction' l with hd tl hl
-  · simp only [forall_const, reduceOption_nil, not_mem_nil, forall_prop_of_false, eq_self_iff_true,
-      length, not_false_iff]
-  · cases hd
-    · simp only [mem_cons, forall_eq_or_imp, Bool.coe_sort_false, false_and_iff,
-        reduceOption_cons_of_none, length, Option.isSome_none, iff_false_iff]
-      intro H
-      have := reduceOption_length_le tl
-      rw [H] at this
-      exact absurd (Nat.lt_succ_self _) (not_lt_of_le this)
-    · simp only [length, mem_cons, forall_eq_or_imp, Option.isSome_some, ← hl, reduceOption,
-        true_and]
-      omega
-#align list.reduce_option_length_eq_iff List.reduceOption_length_eq_iff
-
-theorem reduceOption_length_lt_iff {l : List (Option α)} :
-    l.reduceOption.length < l.length ↔ none ∈ l := by
-  rw [(reduceOption_length_le l).lt_iff_ne, Ne, reduceOption_length_eq_iff]
-  induction l <;> simp [*]
-  rw [@eq_comm _ none, ← Option.not_isSome_iff_eq_none, Decidable.imp_iff_not_or]
-#align list.reduce_option_length_lt_iff List.reduceOption_length_lt_iff
-
-theorem reduceOption_singleton (x : Option α) : [x].reduceOption = x.toList := by cases x <;> rfl
-#align list.reduce_option_singleton List.reduceOption_singleton
-
-theorem reduceOption_concat (l : List (Option α)) (x : Option α) :
-    (l.concat x).reduceOption = l.reduceOption ++ x.toList := by
-  induction' l with hd tl hl generalizing x
-  · cases x <;> simp [Option.toList]
-  · simp only [concat_eq_append, reduceOption_append] at hl
-    cases hd <;> simp [hl, reduceOption_append]
-#align list.reduce_option_concat List.reduceOption_concat
-
-theorem reduceOption_concat_of_some (l : List (Option α)) (x : α) :
-    (l.concat (some x)).reduceOption = l.reduceOption.concat x := by
-  simp only [reduceOption_nil, concat_eq_append, reduceOption_append, reduceOption_cons_of_some]
-#align list.reduce_option_concat_of_some List.reduceOption_concat_of_some
-
-theorem reduceOption_mem_iff {l : List (Option α)} {x : α} : x ∈ l.reduceOption ↔ some x ∈ l := by
-  simp only [reduceOption, id.def, mem_filterMap, exists_eq_right]
-#align list.reduce_option_mem_iff List.reduceOption_mem_iff
-
-theorem reduceOption_get?_iff {l : List (Option α)} {x : α} :
-    (∃ i, l.get? i = some (some x)) ↔ ∃ i, l.reduceOption.get? i = some x := by
-  rw [← mem_iff_get?, ← mem_iff_get?, reduceOption_mem_iff]
-#align list.reduce_option_nth_iff List.reduceOption_get?_iff
-
 /-! ### filter -/
 
 section Filter
chore(List): deprecate List.ret (#11651)

Use List.pure from Lean core instead.

Diff
@@ -14,6 +14,7 @@ import Mathlib.Data.List.Defs
 import Mathlib.Order.Basic
 import Std.Data.List.Lemmas
 import Mathlib.Tactic.Common
+import Mathlib.Init.Data.List.Basic
 
 #align_import data.list.basic from "leanprover-community/mathlib"@"65a1391a0106c9204fe45bc73a039f056558cb83"
 
@@ -487,9 +488,7 @@ theorem replicate_left_injective (a : α) : Injective (replicate · a) :=
 
 /-! ### pure -/
 
-@[simp]
-theorem mem_pure {α} (x y : α) : x ∈ (pure y : List α) ↔ x = y :=
-  show x ∈ [y] ↔ x = y by simp
+theorem mem_pure {α} (x y : α) : x ∈ (pure y : List α) ↔ x = y := by simp
 #align list.mem_pure List.mem_pure
 
 /-! ### bind -/
@@ -1585,12 +1584,14 @@ theorem map_join (f : α → β) (L : List (List α)) : map f (join L) = join (m
   induction L <;> [rfl; simp only [*, join, map, map_append]]
 #align list.map_join List.map_join
 
-theorem bind_ret_eq_map (f : α → β) (l : List α) : l.bind (List.ret ∘ f) = map f l := by
-  unfold List.bind
-  induction l <;>
-    simp (config := { unfoldPartialApp := true })
-      [map, join, List.ret, cons_append, nil_append, *] at *
-#align list.bind_ret_eq_map List.bind_ret_eq_map
+theorem bind_pure_eq_map (f : α → β) (l : List α) : l.bind (pure ∘ f) = map f l :=
+  .symm <| map_eq_bind ..
+#align list.bind_ret_eq_map List.bind_pure_eq_map
+
+set_option linter.deprecated false in
+@[deprecated bind_pure_eq_map] -- 2024-03-24
+theorem bind_ret_eq_map (f : α → β) (l : List α) : l.bind (List.ret ∘ f) = map f l :=
+  bind_pure_eq_map f l
 
 theorem bind_congr {l : List α} {f g : α → List β} (h : ∀ x ∈ l, f x = g x) :
     List.bind l f = List.bind l g :=
@@ -3452,10 +3453,7 @@ theorem enum_append (xs ys : List α) : enum (xs ++ ys) = enum xs ++ enumFrom xs
 
 theorem map_fst_add_enumFrom_eq_enumFrom (l : List α) (n k : ℕ) :
     map (Prod.map (· + n) id) (enumFrom k l) = enumFrom (n + k) l := by
-  induction' l with hd tl IH generalizing n k
-  · simp [enumFrom]
-  · simp only [enumFrom, map, zero_add, Prod.map_mk, id.def, eq_self_iff_true, true_and_iff]
-    simp [IH, add_comm n k, add_assoc, Nat.add_left_comm]
+  induction l generalizing n k <;> [rfl; simp_all [add_assoc, add_comm k]]
 #align list.map_fst_add_enum_from_eq_enum_from List.map_fst_add_enumFrom_eq_enumFrom
 
 theorem map_fst_add_enum_eq_enumFrom (l : List α) (n : ℕ) :
chore(List/Basic): golf disjoint_{p,}map (#11680)

Golf List.disjoint_map and List.disjoint_pmap

Diff
@@ -3918,31 +3918,22 @@ section Disjoint
 
 variable {α β : Type*}
 
-/-- The images of disjoint lists under an injective map are disjoint -/
-theorem disjoint_map {f : α → β} {s t : List α} (hf : Function.Injective f)
-    (h : Disjoint s t) : Disjoint (s.map f) (t.map f) := by
-  simp only [Disjoint]
-  intro b hbs hbt
-  rw [mem_map] at hbs hbt
-  obtain ⟨a, ha, rfl⟩ := hbs
-  apply h ha
-  obtain ⟨a', ha', ha''⟩ := hbt
-  rw [hf ha''.symm]; exact ha'
-
 /-- The images of disjoint lists under a partially defined map are disjoint -/
 theorem disjoint_pmap {p : α → Prop} {f : ∀ a : α, p a → β} {s t : List α}
     (hs : ∀ a ∈ s, p a) (ht : ∀ a ∈ t, p a)
     (hf : ∀ (a a' : α) (ha : p a) (ha' : p a'), f a ha = f a' ha' → a = a')
     (h : Disjoint s t) :
     Disjoint (s.pmap f hs) (t.pmap f ht) := by
-  simp only [Disjoint]
-  intro b hbs hbt
-  rw [mem_pmap] at hbs hbt
-  obtain ⟨a, ha, rfl⟩ := hbs
+  simp only [Disjoint, mem_pmap]
+  rintro b ⟨a, ha, rfl⟩ ⟨a', ha', ha''⟩
   apply h ha
-  obtain ⟨a', ha', ha''⟩ := hbt
-  rw [hf a a' (hs a ha) (ht a' ha') ha''.symm]
-  exact ha'
+  rwa [hf a a' (hs a ha) (ht a' ha') ha''.symm]
+
+/-- The images of disjoint lists under an injective map are disjoint -/
+theorem disjoint_map {f : α → β} {s t : List α} (hf : Function.Injective f)
+    (h : Disjoint s t) : Disjoint (s.map f) (t.map f) := by
+  rw [← pmap_eq_map _ _ _ (fun _ _ ↦ trivial), ← pmap_eq_map _ _ _ (fun _ _ ↦ trivial)]
+  exact disjoint_pmap _ _ (fun _ _ _ _ h' ↦ hf h') h
 
 end Disjoint
 
chore(List/Basic): use mem_filter to golf 2 proofs (#11652)
Diff
@@ -3031,25 +3031,15 @@ theorem filter_subset (l : List α) : filter p l ⊆ l :=
   (filter_sublist l).subset
 #align list.filter_subset List.filter_subset
 
-theorem of_mem_filter {a : α} : ∀ {l}, a ∈ filter p l → p a
-  | b :: l, ain =>
-    if pb : p b then
-      have : a ∈ b :: filter p l := by simpa only [filter_cons_of_pos _ pb] using ain
-      Or.elim (eq_or_mem_of_mem_cons this) (fun h : a = b => by rw [← h] at pb; exact pb)
-        fun h : a ∈ filter p l => of_mem_filter h
-    else by simp only [filter_cons_of_neg _ pb] at ain; exact of_mem_filter ain
+theorem of_mem_filter {a : α} {l} (h : a ∈ filter p l) : p a := (mem_filter.1 h).2
 #align list.of_mem_filter List.of_mem_filter
 
 theorem mem_of_mem_filter {a : α} {l} (h : a ∈ filter p l) : a ∈ l :=
   filter_subset l h
 #align list.mem_of_mem_filter List.mem_of_mem_filter
 
-theorem mem_filter_of_mem {a : α} : ∀ {l}, a ∈ l → p a → a ∈ filter p l
-  | x :: l, h, h1 => by
-    rcases mem_cons.1 h with rfl | h
-    · simp [filter, h1]
-    · rw [filter]
-      cases p x <;> simp [mem_filter_of_mem h h1]
+theorem mem_filter_of_mem {a : α} {l} (h₁ : a ∈ l) (h₂ : p a) : a ∈ filter p l :=
+  mem_filter.2 ⟨h₁, h₂⟩
 #align list.mem_filter_of_mem List.mem_filter_of_mem
 
 #align list.mem_filter List.mem_filter
chore: make List.mem_split an alias of List.append_of_mem (#11060)

List.mem_split duplicates List.append_of_mem from Std: https://github.com/leanprover/std4/blob/a756b7d643ae5dcd7bf314e99f8e493e5d81b9ed/Std/Data/List/Lemmas.lean#L94-L96

This PR makes it an alias.

Co-authored-by: Yaël Dillies <yael.dillies@gmail.com>

Diff
@@ -100,12 +100,9 @@ theorem _root_.Decidable.List.eq_or_ne_mem_of_mem [DecidableEq α]
 lemma mem_pair {a b c : α} : a ∈ [b, c] ↔ a = b ∨ a = c := by
   rw [mem_cons, mem_singleton]
 
-theorem mem_split {a : α} {l : List α} (h : a ∈ l) : ∃ s t : List α, l = s ++ a :: t := by
-  induction' l with b l ih; {cases h}; rcases h with (_ | ⟨_, h⟩)
-  · exact ⟨[], l, rfl⟩
-  · rcases ih h with ⟨s, t, rfl⟩
-    exact ⟨b :: s, t, rfl⟩
-#align list.mem_split List.mem_split
+-- 2024-03-23
+@[deprecated] alias mem_split := append_of_mem
+#align list.mem_split List.append_of_mem
 
 #align list.mem_of_ne_of_mem List.mem_of_ne_of_mem
 
chore: bump Std (#11576)

Co-authored-by: Scott Morrison <scott.morrison@gmail.com>

Diff
@@ -1750,75 +1750,16 @@ theorem take_cons (n) (a : α) (l : List α) : take (succ n) (a :: l) = a :: tak
 #align list.take_cons List.take_cons
 
 #align list.take_length List.take_length
-
-theorem take_all_of_le : ∀ {n} {l : List α}, length l ≤ n → take n l = l
-  | 0, [], _ => rfl
-  | 0, a :: l, h => absurd h (not_le_of_gt (zero_lt_succ _))
-  | n + 1, [], _ => rfl
-  | n + 1, a :: l, h => by
-    change a :: take n l = a :: l
-    rw [take_all_of_le (le_of_succ_le_succ h)]
 #align list.take_all_of_le List.take_all_of_le
-
-@[simp]
-theorem take_left : ∀ l₁ l₂ : List α, take (length l₁) (l₁ ++ l₂) = l₁
-  | [], _ => rfl
-  | a :: l₁, l₂ => congr_arg (cons a) (take_left l₁ l₂)
 #align list.take_left List.take_left
-
-theorem take_left' {l₁ l₂ : List α} {n} (h : length l₁ = n) : take n (l₁ ++ l₂) = l₁ := by
-  rw [← h]; apply take_left
 #align list.take_left' List.take_left'
-
-theorem take_take : ∀ (n m) (l : List α), take n (take m l) = take (min n m) l
-  | n, 0, l => by rw [Nat.min_zero, take_zero, take_nil]
-  | 0, m, l => by rw [Nat.zero_min, take_zero, take_zero]
-  | succ n, succ m, nil => by simp only [take_nil]
-  | succ n, succ m, a :: l => by
-    simp only [take, succ_min_succ, take_take n m l]
 #align list.take_take List.take_take
-
-theorem take_replicate (a : α) : ∀ n m : ℕ, take n (replicate m a) = replicate (min n m) a
-  | n, 0 => by simp
-  | 0, m => by simp
-  | succ n, succ m => by simp [succ_min_succ, take_replicate]
 #align list.take_replicate List.take_replicate
-
-theorem map_take {α β : Type*} (f : α → β) :
-    ∀ (L : List α) (i : ℕ), (L.take i).map f = (L.map f).take i
-  | [], i => by simp
-  | _, 0 => by simp
-  | h :: t, n + 1 => by dsimp; rw [map_take f t n]
 #align list.map_take List.map_take
-
-/-- Taking the first `n` elements in `l₁ ++ l₂` is the same as appending the first `n` elements
-of `l₁` to the first `n - l₁.length` elements of `l₂`. -/
-theorem take_append_eq_append_take {l₁ l₂ : List α} {n : ℕ} :
-    take n (l₁ ++ l₂) = take n l₁ ++ take (n - l₁.length) l₂ := by
-  induction l₁ generalizing n; {simp}
-  cases n <;> simp [*]
 #align list.take_append_eq_append_take List.take_append_eq_append_take
-
-theorem take_append_of_le_length {l₁ l₂ : List α} {n : ℕ} (h : n ≤ l₁.length) :
-    (l₁ ++ l₂).take n = l₁.take n := by
-  simp [take_append_eq_append_take, Nat.sub_eq_zero_iff_le.mpr h]
 #align list.take_append_of_le_length List.take_append_of_le_length
-
-/-- Taking the first `l₁.length + i` elements in `l₁ ++ l₂` is the same as appending the first
-`i` elements of `l₂` to `l₁`. -/
-theorem take_append {l₁ l₂ : List α} (i : ℕ) :
-    take (l₁.length + i) (l₁ ++ l₂) = l₁ ++ take i l₂ := by
-  rw [take_append_eq_append_take, take_all_of_le (by omega), append_cancel_left_eq]
-  congr
-  omega
 #align list.take_append List.take_append
 
-/-- The `i`-th element of a list coincides with the `i`-th element of any of its prefixes of
-length `> i`. Version designed to rewrite from the big list to the small list. -/
-theorem get_take (L : List α) {i j : ℕ} (hi : i < L.length) (hj : i < j) :
-    get L ⟨i, hi⟩ = get (L.take j) ⟨i, length_take .. ▸ lt_min hj hi⟩ :=
-  get_of_eq (take_append_drop j L).symm _ ▸ get_append ..
-
 set_option linter.deprecated false in
 /-- The `i`-th element of a list coincides with the `i`-th element of any of its prefixes of
 length `> i`. Version designed to rewrite from the big list to the small list. -/
@@ -1828,15 +1769,6 @@ theorem nthLe_take (L : List α) {i j : ℕ} (hi : i < L.length) (hj : i < j) :
   get_take _ hi hj
 #align list.nth_le_take List.nthLe_take
 
-/-- The `i`-th element of a list coincides with the `i`-th element of any of its prefixes of
-length `> i`. Version designed to rewrite from the small list to the big list. -/
-theorem get_take' (L : List α) {j i} :
-    get (L.take j) i = get L ⟨i.1, lt_of_lt_of_le i.2 (by simp only [length_take]; omega)⟩ := by
-  let ⟨i, hi⟩ := i
-  simp only [length_take] at hi
-  rw [get_take L]
-  dsimp
-  omega
 set_option linter.deprecated false in
 /-- The `i`-th element of a list coincides with the `i`-th element of any of its prefixes of
 length `> i`. Version designed to rewrite from the small list to the big list. -/
@@ -1846,106 +1778,18 @@ theorem nthLe_take' (L : List α) {i j : ℕ} (hi : i < (L.take j).length) :
   get_take' _
 #align list.nth_le_take' List.nthLe_take'
 
-theorem get?_take {l : List α} {n m : ℕ} (h : m < n) : (l.take n).get? m = l.get? m := by
-  induction' n with n hn generalizing l m
-  · simp only [Nat.zero_eq] at h
-    exact absurd h (not_lt_of_le m.zero_le)
-  · cases' l with hd tl
-    · simp only [take_nil]
-    · cases m
-      · simp only [get?, take]
-      · simpa only using hn (Nat.lt_of_succ_lt_succ h)
 #align list.nth_take List.get?_take
-
-@[simp]
-theorem nth_take_of_succ {l : List α} {n : ℕ} : (l.take (n + 1)).get? n = l.get? n :=
-  get?_take (Nat.lt_succ_self n)
 #align list.nth_take_of_succ List.nth_take_of_succ
-
-theorem take_succ {l : List α} {n : ℕ} : l.take (n + 1) = l.take n ++ (l.get? n).toList := by
-  induction' l with hd tl hl generalizing n
-  · simp only [Option.toList, get?, take_nil, append_nil]
-  · cases n
-    · simp only [Option.toList, get?, eq_self_iff_true, and_self_iff, take, nil_append]
-    · simp only [hl, cons_append, get?, eq_self_iff_true, and_self_iff, take]
 #align list.take_succ List.take_succ
-
-@[simp]
-theorem take_eq_nil_iff {l : List α} {k : ℕ} : l.take k = [] ↔ l = [] ∨ k = 0 := by
-  cases l <;> cases k <;> simp [Nat.succ_ne_zero]
 #align list.take_eq_nil_iff List.take_eq_nil_iff
-
-theorem take_eq_take :
-    ∀ {l : List α} {m n : ℕ}, l.take m = l.take n ↔ min m l.length = min n l.length
-  | [], m, n => by simp
-  | _ :: xs, 0, 0 => by simp
-  | x :: xs, m + 1, 0 => by simp; omega
-  | x :: xs, 0, n + 1 => by simp; omega
-  | x :: xs, m + 1, n + 1 => by simp [Nat.succ_min_succ, take_eq_take]
 #align list.take_eq_take List.take_eq_take
-
-theorem take_add (l : List α) (m n : ℕ) : l.take (m + n) = l.take m ++ (l.drop m).take n := by
-  convert_to take (m + n) (take m l ++ drop m l) = take m l ++ take n (drop m l)
-  · rw [take_append_drop]
-  rw [take_append_eq_append_take, take_all_of_le, append_right_inj]
-  · simp only [take_eq_take, length_take, length_drop]
-    generalize l.length = k; by_cases h : m ≤ k
-    · omega
-    · push_neg at h
-      simp [Nat.sub_eq_zero_of_le (le_of_lt h)]
-  · trans m
-    · apply length_take_le
-    · omega
 #align list.take_add List.take_add
-
-theorem dropLast_eq_take (l : List α) : l.dropLast = l.take l.length.pred := by
-  cases' l with x l
-  · simp [dropLast]
-  · induction' l with hd tl hl generalizing x
-    · simp [dropLast]
-    · simp [dropLast, hl]
 #align list.init_eq_take List.dropLast_eq_take
-
-theorem dropLast_take {n : ℕ} {l : List α} (h : n < l.length) :
-    (l.take n).dropLast = l.take n.pred := by
-  simp only [dropLast_eq_take, length_take, pred_eq_sub_one, take_take]
-  congr
-  omega
 #align list.init_take List.dropLast_take
-
-theorem dropLast_cons_of_ne_nil {α : Type*} {x : α}
-    {l : List α} (h : l ≠ []) : (x :: l).dropLast = x :: l.dropLast := by simp [h, dropLast]
 #align list.init_cons_of_ne_nil List.dropLast_cons_of_ne_nil
-
-@[simp]
-theorem dropLast_append_of_ne_nil {α : Type*} {l : List α} :
-    ∀ (l' : List α) (_ : l ≠ []), (l' ++ l).dropLast = l' ++ l.dropLast
-  | [], _ => by simp only [nil_append]
-  | a :: l', h => by
-    rw [cons_append, dropLast, dropLast_append_of_ne_nil l' h, cons_append]
-    simp [h]
 #align list.init_append_of_ne_nil List.dropLast_append_of_ne_nil
-
 #align list.drop_eq_nil_of_le List.drop_eq_nil_of_le
-
-theorem drop_eq_nil_iff_le {l : List α} {k : ℕ} : l.drop k = [] ↔ l.length ≤ k := by
-  refine' ⟨fun h => _, drop_eq_nil_of_le⟩
-  induction' k with k hk generalizing l
-  · simp only [drop] at h
-    simp [h]
-  · cases l
-    · simp
-    · simp only [drop] at h
-      simpa [Nat.succ_le_succ_iff] using hk h
 #align list.drop_eq_nil_iff_le List.drop_eq_nil_iff_le
-
-@[simp]
-theorem tail_drop (l : List α) (n : ℕ) : (l.drop n).tail = l.drop (n + 1) := by
-  induction' l with hd tl hl generalizing n
-  · simp
-  · cases n
-    · simp
-    · simp [hl]
 #align list.tail_drop List.tail_drop
 
 @[simp]
@@ -1973,60 +1817,13 @@ theorem cons_nthLe_drop_succ {l : List α} {n : ℕ} (hn : n < l.length) :
 #align list.drop_left List.drop_left
 #align list.drop_left' List.drop_left'
 #align list.drop_eq_nth_le_cons List.drop_eq_get_consₓ -- nth_le vs get
-
 #align list.drop_length List.drop_length
-
-theorem drop_length_cons {l : List α} (h : l ≠ []) (a : α) :
-    (a :: l).drop l.length = [l.getLast h] := by
-  induction' l with y l ih generalizing a
-  · cases h rfl
-  · simp only [drop, length]
-    by_cases h₁ : l = []
-    · simp [h₁]
-    rw [getLast_cons h₁]
-    exact ih h₁ y
 #align list.drop_length_cons List.drop_length_cons
-
 #align list.drop_append_eq_append_drop List.drop_append_eq_append_drop
-
 #align list.drop_append_of_le_length List.drop_append_of_le_length
-
-/-- Dropping the elements up to `l₁.length + i` in `l₁ + l₂` is the same as dropping the elements
-up to `i` in `l₂`. -/
-theorem drop_append {l₁ l₂ : List α} (i : ℕ) : drop (l₁.length + i) (l₁ ++ l₂) = drop i l₂ := by
-  rw [drop_append_eq_append_drop, drop_eq_nil_of_le]
-  · simp only [nil_append]
-    congr
-    omega
-  · omega
 #align list.drop_append List.drop_append
-
-theorem drop_sizeOf_le [SizeOf α] (l : List α) : ∀ n : ℕ, sizeOf (l.drop n) ≤ sizeOf l := by
-  induction' l with _ _ lih <;> intro n
-  · rw [drop_nil]
-  · induction' n with n
-    · rfl
-    · specialize lih n
-      simp_all only [cons.sizeOf_spec, drop_succ_cons]
-      omega
 #align list.drop_sizeof_le List.drop_sizeOf_le
 
-set_option linter.deprecated false in -- FIXME
-/-- The `i + j`-th element of a list coincides with the `j`-th element of the list obtained by
-dropping the first `i` elements. Version designed to rewrite from the big list to the small list. -/
-theorem get_drop (L : List α) {i j : ℕ} (h : i + j < L.length) :
-    get L ⟨i + j, h⟩ = get (L.drop i) ⟨j, by
-      have A : i < L.length := lt_of_le_of_lt (Nat.le.intro rfl) h
-      rw [(take_append_drop i L).symm] at h
-      simp_all only [take_append_drop, length_drop, gt_iff_lt]
-      omega⟩ := by
-  rw [← nthLe_eq, ← nthLe_eq]
-  rw [nthLe_of_eq (take_append_drop i L).symm h, nthLe_append_right]
-  congr
-  all_goals
-    simp only [length_take]
-    omega
-
 set_option linter.deprecated false in
 /-- The `i + j`-th element of a list coincides with the `j`-th element of the list obtained by
 dropping the first `i` elements. Version designed to rewrite from the big list to the small list. -/
@@ -2039,12 +1836,6 @@ theorem nthLe_drop (L : List α) {i j : ℕ} (h : i + j < L.length) :
       omega) := get_drop ..
 #align list.nth_le_drop List.nthLe_drop
 
-/-- The `i + j`-th element of a list coincides with the `j`-th element of the list obtained by
-dropping the first `i` elements. Version designed to rewrite from the small list to the big list. -/
-theorem get_drop' (L : List α) {i j} :
-    get (L.drop i) j = get L ⟨i + j, have := length_drop i L; by omega⟩ := by
-  rw [get_drop]
-
 set_option linter.deprecated false in
 /-- The `i + j`-th element of a list coincides with the `j`-th element of the list obtained by
 dropping the first `i` elements. Version designed to rewrite from the small list to the big list. -/
@@ -2054,45 +1845,10 @@ theorem nthLe_drop' (L : List α) {i j : ℕ} (h : j < (L.drop i).length) :
   get_drop' ..
 #align list.nth_le_drop' List.nthLe_drop'
 
-theorem get?_drop (L : List α) (i j : ℕ) : get? (L.drop i) j = get? L (i + j) := by
-  ext
-  simp only [get?_eq_some, get_drop', Option.mem_def]
-  constructor <;> exact fun ⟨h, ha⟩ => ⟨by simp_all only [length_drop, exists_prop]; omega, ha⟩
 #align list.nth_drop List.get?_drop
-
-@[simp]
-theorem drop_drop (n : ℕ) : ∀ (m) (l : List α), drop n (drop m l) = drop (n + m) l
-  | m, [] => by simp
-  | 0, l => by simp
-  | m + 1, a :: l =>
-    calc
-      drop n (drop (m + 1) (a :: l)) = drop n (drop m l) := rfl
-      _ = drop (n + m) l := drop_drop n m l
-      _ = drop (n + (m + 1)) (a :: l) := rfl
 #align list.drop_drop List.drop_drop
-
-theorem drop_take : ∀ (m : ℕ) (n : ℕ) (l : List α), drop m (take (m + n) l) = take n (drop m l)
-  | 0, n, _ => by simp
-  | m + 1, n, nil => by simp
-  | m + 1, n, _ :: l => by
-    have h : m + 1 + n = m + n + 1 := by omega
-    simpa [take_cons, h] using drop_take m n l
 #align list.drop_take List.drop_take
-
-theorem map_drop {α β : Type*} (f : α → β) :
-    ∀ (L : List α) (i : ℕ), (L.drop i).map f = (L.map f).drop i
-  | [], i => by simp
-  | L, 0 => by simp
-  | h :: t, n + 1 => by
-    dsimp
-    rw [map_drop f t]
 #align list.map_drop List.map_drop
-
-theorem modifyNthTail_eq_take_drop (f : List α → List α) (H : f [] = []) :
-    ∀ n l, modifyNthTail f n l = take n l ++ f (drop n l)
-  | 0, _ => rfl
-  | _ + 1, [] => H.symm
-  | n + 1, b :: l => congr_arg (cons b) (modifyNthTail_eq_take_drop f H n l)
 #align list.modify_nth_tail_eq_take_drop List.modifyNthTail_eq_take_drop
 
 @[simp]
@@ -2107,42 +1863,10 @@ theorem modifyNth_zero_cons (f : α → α) (a : α) (l : List α) :
 theorem modifyNth_succ_cons (f : α → α) (n : ℕ) (a : α) (l : List α) :
     modifyNth f (n + 1) (a :: l) = a :: modifyNth f n l := rfl
 
-theorem modifyNth_eq_take_drop (f : α → α) :
-    ∀ n l, modifyNth f n l = take n l ++ modifyHead f (drop n l) :=
-  modifyNthTail_eq_take_drop _ rfl
 #align list.modify_nth_eq_take_drop List.modifyNth_eq_take_drop
-
-theorem modifyNth_eq_take_cons_drop (f : α → α) {n l} (h) :
-    modifyNth f n l = take n l ++ f (get l ⟨n, h⟩) :: drop (n + 1) l := by
-  rw [modifyNth_eq_take_drop, drop_eq_get_cons h]; rfl
 #align list.modify_nth_eq_take_cons_drop List.modifyNth_eq_take_cons_drop
-
-theorem set_eq_take_cons_drop (a : α) {n l} (h : n < length l) :
-    set l n a = take n l ++ a :: drop (n + 1) l := by
-  rw [set_eq_modifyNth, modifyNth_eq_take_cons_drop _ h]
 #align list.update_nth_eq_take_cons_drop List.set_eq_take_cons_drop
-
-theorem reverse_take {α} {xs : List α} (n : ℕ) (h : n ≤ xs.length) :
-    xs.reverse.take n = (xs.drop (xs.length - n)).reverse := by
-  induction' xs with xs_hd xs_tl xs_ih generalizing n <;>
-    simp only [reverse_nil, reverse_cons, take_nil, length, Nat.zero_sub, drop_nil]
-  cases' h.lt_or_eq_dec with h' h'
-  · replace h' := le_of_succ_le_succ h'
-    rw [take_append_of_le_length, xs_ih _ h']
-    rw [show xs_tl.length + 1 - n = succ (xs_tl.length - n) from _, drop]
-    · omega
-    · rwa [length_reverse]
-  · subst h'
-    rw [length, Nat.sub_self, drop]
-    suffices xs_tl.length + 1 = (xs_tl.reverse ++ [xs_hd]).length by
-      rw [this, take_length, reverse_cons]
-    rw [length_append, length_reverse]
-    rfl
 #align list.reverse_take List.reverse_take
-
-@[simp]
-theorem set_eq_nil (l : List α) (n : ℕ) (a : α) : l.set n a = [] ↔ l = [] := by
-  cases l <;> cases n <;> simp only [set]
 #align list.update_nth_eq_nil List.set_eq_nil
 
 section TakeI
chore: split insertNth lemmas from List.Basic (#11542)

Removes the insertNth section of this long file to its own new file. This section seems to be completely independent of the rest of the file, so this is a fairly easy split to make.

Diff
@@ -1545,177 +1545,6 @@ theorem nthLe_set_of_ne {l : List α} {i j : ℕ} (h : i ≠ j) (a : α)
 
 #align list.mem_or_eq_of_mem_update_nth List.mem_or_eq_of_mem_set
 
-section InsertNth
-
-variable {a : α}
-
-@[simp]
-theorem insertNth_zero (s : List α) (x : α) : insertNth 0 x s = x :: s :=
-  rfl
-#align list.insert_nth_zero List.insertNth_zero
-
-@[simp]
-theorem insertNth_succ_nil (n : ℕ) (a : α) : insertNth (n + 1) a [] = [] :=
-  rfl
-#align list.insert_nth_succ_nil List.insertNth_succ_nil
-
-@[simp]
-theorem insertNth_succ_cons (s : List α) (hd x : α) (n : ℕ) :
-    insertNth (n + 1) x (hd :: s) = hd :: insertNth n x s :=
-  rfl
-#align list.insert_nth_succ_cons List.insertNth_succ_cons
-
-theorem length_insertNth : ∀ n as, n ≤ length as → length (insertNth n a as) = length as + 1
-  | 0, _, _ => rfl
-  | _ + 1, [], h => (Nat.not_succ_le_zero _ h).elim
-  | n + 1, _ :: as, h => congr_arg Nat.succ <| length_insertNth n as (Nat.le_of_succ_le_succ h)
-#align list.length_insert_nth List.length_insertNth
-
-theorem removeNth_insertNth (n : ℕ) (l : List α) : (l.insertNth n a).removeNth n = l := by
-  rw [removeNth_eq_nth_tail, insertNth, modifyNthTail_modifyNthTail_same]
-  exact modifyNthTail_id _ _
-#align list.remove_nth_insert_nth List.removeNth_insertNth
-
-theorem insertNth_removeNth_of_ge :
-    ∀ n m as,
-      n < length as → n ≤ m → insertNth m a (as.removeNth n) = (as.insertNth (m + 1) a).removeNth n
-  | 0, 0, [], has, _ => (lt_irrefl _ has).elim
-  | 0, 0, _ :: as, _, _ => by simp [removeNth, insertNth]
-  | 0, m + 1, a :: as, _, _ => rfl
-  | n + 1, m + 1, a :: as, has, hmn =>
-    congr_arg (cons a) <|
-      insertNth_removeNth_of_ge n m as (Nat.lt_of_succ_lt_succ has) (Nat.le_of_succ_le_succ hmn)
-#align list.insert_nth_remove_nth_of_ge List.insertNth_removeNth_of_ge
-
-theorem insertNth_removeNth_of_le :
-    ∀ n m as,
-      n < length as → m ≤ n → insertNth m a (as.removeNth n) = (as.insertNth m a).removeNth (n + 1)
-  | _, 0, _ :: _, _, _ => rfl
-  | n + 1, m + 1, a :: as, has, hmn =>
-    congr_arg (cons a) <|
-      insertNth_removeNth_of_le n m as (Nat.lt_of_succ_lt_succ has) (Nat.le_of_succ_le_succ hmn)
-#align list.insert_nth_remove_nth_of_le List.insertNth_removeNth_of_le
-
-theorem insertNth_comm (a b : α) :
-    ∀ (i j : ℕ) (l : List α) (_ : i ≤ j) (_ : j ≤ length l),
-      (l.insertNth i a).insertNth (j + 1) b = (l.insertNth j b).insertNth i a
-  | 0, j, l => by simp [insertNth]
-  | i + 1, 0, l => fun h => (Nat.not_lt_zero _ h).elim
-  | i + 1, j + 1, [] => by simp
-  | i + 1, j + 1, c :: l => fun h₀ h₁ => by
-    simp only [insertNth_succ_cons, cons.injEq, true_and]
-    exact insertNth_comm a b i j l (Nat.le_of_succ_le_succ h₀) (Nat.le_of_succ_le_succ h₁)
-#align list.insert_nth_comm List.insertNth_comm
-
-theorem mem_insertNth {a b : α} :
-    ∀ {n : ℕ} {l : List α} (_ : n ≤ l.length), a ∈ l.insertNth n b ↔ a = b ∨ a ∈ l
-  | 0, as, _ => by simp
-  | n + 1, [], h => (Nat.not_succ_le_zero _ h).elim
-  | n + 1, a' :: as, h => by
-    rw [List.insertNth_succ_cons, mem_cons, mem_insertNth (Nat.le_of_succ_le_succ h),
-      ← or_assoc, @or_comm (a = a'), or_assoc, mem_cons]
-#align list.mem_insert_nth List.mem_insertNth
-
-theorem insertNth_of_length_lt (l : List α) (x : α) (n : ℕ) (h : l.length < n) :
-    insertNth n x l = l := by
-  induction' l with hd tl IH generalizing n
-  · cases n
-    · simp at h
-    · simp
-  · cases n
-    · simp at h
-    · simp only [Nat.succ_lt_succ_iff, length] at h
-      simpa using IH _ h
-#align list.insert_nth_of_length_lt List.insertNth_of_length_lt
-
-@[simp]
-theorem insertNth_length_self (l : List α) (x : α) : insertNth l.length x l = l ++ [x] := by
-  induction' l with hd tl IH
-  · simp
-  · simpa using IH
-#align list.insert_nth_length_self List.insertNth_length_self
-
-theorem length_le_length_insertNth (l : List α) (x : α) (n : ℕ) :
-    l.length ≤ (insertNth n x l).length := by
-  rcases le_or_lt n l.length with hn | hn
-  · rw [length_insertNth _ _ hn]
-    exact (Nat.lt_succ_self _).le
-  · rw [insertNth_of_length_lt _ _ _ hn]
-#align list.length_le_length_insert_nth List.length_le_length_insertNth
-
-theorem length_insertNth_le_succ (l : List α) (x : α) (n : ℕ) :
-    (insertNth n x l).length ≤ l.length + 1 := by
-  rcases le_or_lt n l.length with hn | hn
-  · rw [length_insertNth _ _ hn]
-  · rw [insertNth_of_length_lt _ _ _ hn]
-    exact (Nat.lt_succ_self _).le
-#align list.length_insert_nth_le_succ List.length_insertNth_le_succ
-
-theorem get_insertNth_of_lt (l : List α) (x : α) (n k : ℕ) (hn : k < n) (hk : k < l.length)
-    (hk' : k < (insertNth n x l).length := hk.trans_le (length_le_length_insertNth _ _ _)) :
-    (insertNth n x l).get ⟨k, hk'⟩ = l.get ⟨k, hk⟩ := by
-  induction' n with n IH generalizing k l
-  · simp at hn
-  · cases' l with hd tl
-    · simp
-    · cases k
-      · simp [get]
-      · rw [Nat.succ_lt_succ_iff] at hn
-        simpa using IH _ _ hn _
-
-@[deprecated get_insertNth_of_lt]
-theorem nthLe_insertNth_of_lt : ∀ (l : List α) (x : α) (n k : ℕ), k < n → ∀ (hk : k < l.length)
-    (hk' : k < (insertNth n x l).length := hk.trans_le (length_le_length_insertNth _ _ _)),
-    (insertNth n x l).nthLe k hk' = l.nthLe k hk := @get_insertNth_of_lt _
-#align list.nth_le_insert_nth_of_lt List.nthLe_insertNth_of_lt
-
-@[simp]
-theorem get_insertNth_self (l : List α) (x : α) (n : ℕ) (hn : n ≤ l.length)
-    (hn' : n < (insertNth n x l).length := (by rwa [length_insertNth _ _ hn, Nat.lt_succ_iff])) :
-    (insertNth n x l).get ⟨n, hn'⟩ = x := by
-  induction' l with hd tl IH generalizing n
-  · simp only [length] at hn
-    cases hn
-    simp only [insertNth_zero, get_singleton]
-  · cases n
-    · simp
-    · simp only [Nat.succ_le_succ_iff, length] at hn
-      simpa using IH _ hn
-
-@[simp, deprecated get_insertNth_self]
-theorem nthLe_insertNth_self (l : List α) (x : α) (n : ℕ) (hn : n ≤ l.length)
-    (hn' : n < (insertNth n x l).length := (by rwa [length_insertNth _ _ hn, Nat.lt_succ_iff])) :
-    (insertNth n x l).nthLe n hn' = x := get_insertNth_self _ _ _ hn
-#align list.nth_le_insert_nth_self List.nthLe_insertNth_self
-
-theorem get_insertNth_add_succ (l : List α) (x : α) (n k : ℕ) (hk' : n + k < l.length)
-    (hk : n + k + 1 < (insertNth n x l).length := (by
-      rwa [length_insertNth _ _ (by omega), Nat.succ_lt_succ_iff])):
-    (insertNth n x l).get ⟨n + k + 1, hk⟩ = get l ⟨n + k, hk'⟩ := by
-  induction' l with hd tl IH generalizing n k
-  · simp at hk'
-  · cases n
-    · simp
-    · simpa [succ_add] using IH _ _ _
-
-set_option linter.deprecated false in
-@[deprecated get_insertNth_add_succ]
-theorem nthLe_insertNth_add_succ : ∀ (l : List α) (x : α) (n k : ℕ) (hk' : n + k < l.length)
-    (hk : n + k + 1 < (insertNth n x l).length := (by
-      rwa [length_insertNth _ _ (by omega), Nat.succ_lt_succ_iff])),
-    (insertNth n x l).nthLe (n + k + 1) hk = nthLe l (n + k) hk' :=
-  @get_insertNth_add_succ _
-#align list.nth_le_insert_nth_add_succ List.nthLe_insertNth_add_succ
-
-set_option linter.unnecessarySimpa false in
-theorem insertNth_injective (n : ℕ) (x : α) : Function.Injective (insertNth n x) := by
-  induction' n with n IH
-  · have : insertNth 0 x = cons x := funext fun _ => rfl
-    simp [this]
-  · rintro (_ | ⟨a, as⟩) (_ | ⟨b, bs⟩) h <;> simpa [IH.eq_iff] using h
-#align list.insert_nth_injective List.insertNth_injective
-
-end InsertNth
 
 /-! ### map -/
 
chore: simplify some proofs for the 2024-03-16 nightly (#11547)

Some small changes to adapt to the 2024-03-16 nightly that can land in advance.

Diff
@@ -1603,7 +1603,7 @@ theorem insertNth_comm (a b : α) :
   | i + 1, 0, l => fun h => (Nat.not_lt_zero _ h).elim
   | i + 1, j + 1, [] => by simp
   | i + 1, j + 1, c :: l => fun h₀ h₁ => by
-    simp only [insertNth_succ_cons, insertNth._eq_1, cons.injEq, true_and]
+    simp only [insertNth_succ_cons, cons.injEq, true_and]
     exact insertNth_comm a b i j l (Nat.le_of_succ_le_succ h₀) (Nat.le_of_succ_le_succ h₁)
 #align list.insert_nth_comm List.insertNth_comm
 
feat: lemmas about List.reverseRecOn (#11257)

This renames the arguments to the eliminators to be more ergonomic when using the induction tactic.

I also changed the definition in an attempt to make the proof easier.

Diff
@@ -905,41 +905,106 @@ theorem modifyHead_modifyHead (l : List α) (f g : α → α) :
 for `l ++ [a]` if it holds for `l`, then it holds for all lists. The principle is given for
 a `Sort`-valued predicate, i.e., it can also be used to construct data. -/
 @[elab_as_elim]
-def reverseRecOn {C : List α → Sort*} (l : List α) (H0 : C [])
-    (H1 : ∀ (l : List α) (a : α), C l → C (l ++ [a])) : C l := by
-  rw [← reverse_reverse l]
-  match h:(reverse l) with
-  | [] => exact H0
+def reverseRecOn {motive : List α → Sort*} (l : List α) (nil : motive [])
+    (append_singleton : ∀ (l : List α) (a : α), motive l → motive (l ++ [a])) : motive l :=
+  match h : reverse l with
+  | [] => cast (congr_arg motive <| by simpa using congr(reverse $h.symm)) <|
+      nil
   | head :: tail =>
     have : tail.length < l.length := by
       rw [← length_reverse l, h, length_cons]
       simp [Nat.lt_succ]
-    let ih := reverseRecOn (reverse tail) H0 H1
-    rw [reverse_cons]
-    exact H1 _ _ ih
+    cast (congr_arg motive <| by simpa using congr(reverse $h.symm)) <|
+      append_singleton _ head <| reverseRecOn (reverse tail) nil append_singleton
 termination_by l.length
 #align list.reverse_rec_on List.reverseRecOn
 
+@[simp]
+theorem reverseRecOn_nil {motive : List α → Sort*} (nil : motive [])
+    (append_singleton : ∀ (l : List α) (a : α), motive l → motive (l ++ [a])) :
+    reverseRecOn [] nil append_singleton = nil := rfl
+
+-- `unusedHavesSuffices` is getting confused by the unfolding of `reverseRecOn`
+@[simp, nolint unusedHavesSuffices]
+theorem reverseRecOn_concat {motive : List α → Sort*} (x : α) (xs : List α) (nil : motive [])
+    (append_singleton : ∀ (l : List α) (a : α), motive l → motive (l ++ [a])) :
+    reverseRecOn (motive := motive) (xs ++ [x]) nil append_singleton =
+      append_singleton _ _ (reverseRecOn (motive := motive) xs nil append_singleton) := by
+  suffices ∀ ys (h : reverse (reverse xs) = ys),
+      reverseRecOn (motive := motive) (xs ++ [x]) nil append_singleton =
+        cast (by simp [(reverse_reverse _).symm.trans h])
+          (append_singleton _ x (reverseRecOn (motive := motive) ys nil append_singleton)) by
+    exact this _ (reverse_reverse xs)
+  intros ys hy
+  conv_lhs => unfold reverseRecOn
+  split
+  next h => simp at h
+  next heq =>
+    revert heq
+    simp only [reverse_append, reverse_cons, reverse_nil, nil_append, singleton_append, cons.injEq]
+    rintro ⟨rfl, rfl⟩
+    subst ys
+    rfl
+
 /-- Bidirectional induction principle for lists: if a property holds for the empty list, the
 singleton list, and `a :: (l ++ [b])` from `l`, then it holds for all lists. This can be used to
 prove statements about palindromes. The principle is given for a `Sort`-valued predicate, i.e., it
 can also be used to construct data. -/
-def bidirectionalRec {C : List α → Sort*} (H0 : C []) (H1 : ∀ a : α, C [a])
-    (Hn : ∀ (a : α) (l : List α) (b : α), C l → C (a :: (l ++ [b]))) : ∀ l, C l
-  | [] => H0
-  | [a] => H1 a
-  | a :: b :: l => by
+@[elab_as_elim]
+def bidirectionalRec {motive : List α → Sort*} (nil : motive []) (singleton : ∀ a : α, motive [a])
+    (cons_append : ∀ (a : α) (l : List α) (b : α), motive l → motive (a :: (l ++ [b]))) :
+    ∀ l, motive l
+  | [] => nil
+  | [a] => singleton a
+  | a :: b :: l =>
     let l' := dropLast (b :: l)
     let b' := getLast (b :: l) (cons_ne_nil _ _)
-    rw [← dropLast_append_getLast (cons_ne_nil b l)]
-    have : C l' := bidirectionalRec H0 H1 Hn l'
-    exact Hn a l' b' this
+    cast (by rw [← dropLast_append_getLast (cons_ne_nil b l)]) <|
+      cons_append a l' b' (bidirectionalRec nil singleton cons_append l')
 termination_by l => l.length
 #align list.bidirectional_rec List.bidirectionalRecₓ -- universe order
 
+@[simp]
+theorem bidirectionalRec_nil {motive : List α → Sort*}
+    (nil : motive []) (singleton : ∀ a : α, motive [a])
+    (cons_append : ∀ (a : α) (l : List α) (b : α), motive l → motive (a :: (l ++ [b]))) :
+    bidirectionalRec nil singleton cons_append [] = nil :=
+  rfl
+
+@[simp]
+theorem bidirectionalRec_singleton {motive : List α → Sort*}
+    (nil : motive []) (singleton : ∀ a : α, motive [a])
+    (cons_append : ∀ (a : α) (l : List α) (b : α), motive l → motive (a :: (l ++ [b]))) (a : α):
+    bidirectionalRec nil singleton cons_append [a] = singleton a :=
+  rfl
+
+@[simp]
+theorem bidirectionalRec_cons_append {motive : List α → Sort*}
+    (nil : motive []) (singleton : ∀ a : α, motive [a])
+    (cons_append : ∀ (a : α) (l : List α) (b : α), motive l → motive (a :: (l ++ [b])))
+    (a : α) (l : List α) (b : α) :
+    bidirectionalRec nil singleton cons_append (a :: (l ++ [b])) =
+      cons_append a l b (bidirectionalRec nil singleton cons_append l) := by
+  conv_lhs => unfold bidirectionalRec
+  cases l with
+  | nil => rfl
+  | cons x xs =>
+  simp only [List.cons_append]
+  congr
+  dsimp only [← List.cons_append]
+  suffices ∀ (ys init : List α) (hinit : init = ys) (last : α) (hlast : last = b),
+      (cons_append a init last
+        (bidirectionalRec nil singleton cons_append init)) =
+      cast (congr_arg motive <| by simp [hinit, hlast])
+        (cons_append a ys b (bidirectionalRec nil singleton cons_append ys)) by
+    rw [this (x :: xs) _ (by rw [dropLast_append_cons, dropLast_single, append_nil]) _ (by simp)]
+    simp
+  rintro ys init rfl last rfl
+  rfl
+
 /-- Like `bidirectionalRec`, but with the list parameter placed first. -/
 @[elab_as_elim]
-def bidirectionalRecOn {C : List α → Sort*} (l : List α) (H0 : C []) (H1 : ∀ a : α, C [a])
+abbrev bidirectionalRecOn {C : List α → Sort*} (l : List α) (H0 : C []) (H1 : ∀ a : α, C [a])
     (Hn : ∀ (a : α) (l : List α) (b : α), C l → C (a :: (l ++ [b]))) : C l :=
   bidirectionalRec H0 H1 Hn l
 #align list.bidirectional_rec_on List.bidirectionalRecOn
chore(Mathlib/Data/List/Basic): minimize imports (#11497)

Use Nat specialized theorems, and omega, where necessary to avoid needing to import the abstract ordered algebra hierarchy for basic results about List.

Import graph between Mathlib.Order.Basic and Mathlib.Data.List.Basic:

Co-authored-by: Scott Morrison <scott.morrison@gmail.com>

Diff
@@ -4,12 +4,16 @@ Released under Apache 2.0 license as described in the file LICENSE.
 Authors: Parikshit Khanna, Jeremy Avigad, Leonardo de Moura, Floris van Doorn, Mario Carneiro
 -/
 import Mathlib.Init.Data.List.Instances
-import Mathlib.Data.Nat.Order.Basic
+import Mathlib.Init.Data.Bool.Lemmas
+import Mathlib.Init.Data.List.Lemmas
+import Mathlib.Data.Nat.Defs
+import Mathlib.Data.Nat.Basic
+import Mathlib.Data.Bool.Basic
+import Mathlib.Data.Option.Basic
 import Mathlib.Data.List.Defs
+import Mathlib.Order.Basic
 import Std.Data.List.Lemmas
 import Mathlib.Tactic.Common
-import Mathlib.Init.Data.Bool.Lemmas
-import Mathlib.Init.Data.List.Lemmas
 
 #align_import data.list.basic from "leanprover-community/mathlib"@"65a1391a0106c9204fe45bc73a039f056558cb83"
 
@@ -859,7 +863,7 @@ section deprecated
 set_option linter.deprecated false -- TODO(Mario): make replacements for theorems in this section
 
 @[simp] theorem nthLe_tail (l : List α) (i) (h : i < l.tail.length)
-    (h' : i + 1 < l.length := (by simpa [← lt_tsub_iff_right] using h)) :
+    (h' : i + 1 < l.length := (by simp only [length_tail] at h; omega)) :
     l.tail.nthLe i h = l.nthLe (i + 1) h' := by
   cases l <;> [cases h; rfl]
 #align list.nth_le_tail List.nthLe_tail
@@ -868,8 +872,7 @@ theorem nthLe_cons_aux {l : List α} {a : α} {n} (hn : n ≠ 0) (h : n < (a ::
     n - 1 < l.length := by
   contrapose! h
   rw [length_cons]
-  convert succ_le_succ h
-  exact (Nat.succ_pred_eq_of_pos hn.bot_lt).symm
+  omega
 #align list.nth_le_cons_aux List.nthLe_cons_aux
 
 theorem nthLe_cons {l : List α} {a : α} {n} (hl) :
@@ -877,8 +880,8 @@ theorem nthLe_cons {l : List α} {a : α} {n} (hl) :
   split_ifs with h
   · simp [nthLe, h]
   cases l
-  · rw [length_singleton, Nat.lt_succ_iff, nonpos_iff_eq_zero] at hl
-    contradiction
+  · rw [length_singleton, Nat.lt_succ_iff] at hl
+    omega
   cases n
   · contradiction
   rfl
@@ -1239,7 +1242,7 @@ theorem nthLe_replicate (a : α) {n m : ℕ} (h : m < (replicate n a).length) :
 
 @[deprecated getLast_eq_get]
 theorem getLast_eq_nthLe (l : List α) (h : l ≠ []) :
-    getLast l h = l.nthLe (l.length - 1) (Nat.sub_lt (length_pos_of_ne_nil h) one_pos) :=
+    getLast l h = l.nthLe (l.length - 1) (have := length_pos_of_ne_nil h; by omega) :=
   getLast_eq_get ..
 #align list.last_eq_nth_le List.getLast_eq_nthLe
 
@@ -1267,7 +1270,7 @@ theorem take_one_drop_eq_of_lt_length {l : List α} {n : ℕ} (h : n < l.length)
   · by_cases h₁ : l = []
     · subst h₁
       rw [get_singleton]
-      simp only [length_singleton, Nat.lt_succ_iff, nonpos_iff_eq_zero] at h
+      simp only [length_cons, length_nil, Nat.lt_succ_iff, le_zero_eq] at h
       subst h
       simp
     have h₂ := h
@@ -1311,7 +1314,7 @@ theorem get_reverse_aux₁ :
     ∀ (l r : List α) (i h1 h2), get (reverseAux l r) ⟨i + length l, h1⟩ = get r ⟨i, h2⟩
   | [], r, i => fun h1 _ => rfl
   | a :: l, r, i => by
-    rw [show i + length (a :: l) = i + 1 + length l from add_right_comm i (length l) 1]
+    rw [show i + length (a :: l) = i + 1 + length l from Nat.add_right_comm i (length l) 1]
     exact fun h1 h2 => get_reverse_aux₁ l (a :: r) (i + 1) h1 (succ_lt_succ h2)
 #align list.nth_le_reverse_aux1 List.get_reverse_aux₁
 
@@ -1338,7 +1341,7 @@ theorem get_reverse_aux₂ :
     have heq :=
       calc
         length (a :: l) - 1 - (i + 1) = length l - (1 + i) := by rw [add_comm]; rfl
-        _ = length l - 1 - i := by rw [← tsub_add_eq_tsub_tsub]
+        _ = length l - 1 - i := by omega
     rw [← heq] at aux
     apply aux
 #align list.nth_le_reverse_aux2 List.get_reverse_aux₂
@@ -1367,11 +1370,11 @@ theorem get_reverse' (l : List α) (n) (hn') :
 attribute [deprecated get_reverse'] nthLe_reverse'
 
 theorem eq_cons_of_length_one {l : List α} (h : l.length = 1) :
-    l = [l.nthLe 0 (h.symm ▸ zero_lt_one)] := by
+    l = [l.nthLe 0 (by omega)] := by
   refine' ext_get (by convert h) fun n h₁ h₂ => _
   simp only [get_singleton]
   congr
-  exact eq_bot_iff.mpr (Nat.lt_succ_iff.mp h₂)
+  omega
 #align list.eq_cons_of_length_one List.eq_cons_of_length_one
 
 theorem get_eq_iff {l : List α} {n : Fin l.length} {x : α} : l.get n = x ↔ l.get? n.1 = some x := by
@@ -1403,13 +1406,13 @@ theorem modifyNthTail_modifyNthTail_le {f g : List α → List α} (m n : ℕ) (
     (h : n ≤ m) :
     (l.modifyNthTail f n).modifyNthTail g m =
       l.modifyNthTail (fun l => (f l).modifyNthTail g (m - n)) n := by
-  rcases exists_add_of_le h with ⟨m, rfl⟩
-  rw [@add_tsub_cancel_left, add_comm, modifyNthTail_modifyNthTail]
+  rcases Nat.exists_eq_add_of_le h with ⟨m, rfl⟩
+  rw [add_comm, modifyNthTail_modifyNthTail, Nat.add_sub_cancel]
 #align list.modify_nth_tail_modify_nth_tail_le List.modifyNthTail_modifyNthTail_le
 
 theorem modifyNthTail_modifyNthTail_same {f g : List α → List α} (n : ℕ) (l : List α) :
     (l.modifyNthTail f n).modifyNthTail g n = l.modifyNthTail (g ∘ f) n := by
-  rw [modifyNthTail_modifyNthTail_le n n l (le_refl n), tsub_self]; rfl
+  rw [modifyNthTail_modifyNthTail_le n n l (le_refl n), Nat.sub_self]; rfl
 #align list.modify_nth_tail_modify_nth_tail_same List.modifyNthTail_modifyNthTail_same
 
 #align list.modify_nth_tail_id List.modifyNthTail_id
@@ -1606,7 +1609,7 @@ theorem get_insertNth_self (l : List α) (x : α) (n : ℕ) (hn : n ≤ l.length
     (hn' : n < (insertNth n x l).length := (by rwa [length_insertNth _ _ hn, Nat.lt_succ_iff])) :
     (insertNth n x l).get ⟨n, hn'⟩ = x := by
   induction' l with hd tl IH generalizing n
-  · simp only [length, nonpos_iff_eq_zero] at hn
+  · simp only [length] at hn
     cases hn
     simp only [insertNth_zero, get_singleton]
   · cases n
@@ -1622,7 +1625,7 @@ theorem nthLe_insertNth_self (l : List α) (x : α) (n : ℕ) (hn : n ≤ l.leng
 
 theorem get_insertNth_add_succ (l : List α) (x : α) (n k : ℕ) (hk' : n + k < l.length)
     (hk : n + k + 1 < (insertNth n x l).length := (by
-      rwa [length_insertNth _ _ (le_self_add.trans hk'.le), Nat.succ_lt_succ_iff])):
+      rwa [length_insertNth _ _ (by omega), Nat.succ_lt_succ_iff])):
     (insertNth n x l).get ⟨n + k + 1, hk⟩ = get l ⟨n + k, hk'⟩ := by
   induction' l with hd tl IH generalizing n k
   · simp at hk'
@@ -1634,7 +1637,7 @@ set_option linter.deprecated false in
 @[deprecated get_insertNth_add_succ]
 theorem nthLe_insertNth_add_succ : ∀ (l : List α) (x : α) (n k : ℕ) (hk' : n + k < l.length)
     (hk : n + k + 1 < (insertNth n x l).length := (by
-      rwa [length_insertNth _ _ (le_self_add.trans hk'.le), Nat.succ_lt_succ_iff])),
+      rwa [length_insertNth _ _ (by omega), Nat.succ_lt_succ_iff])),
     (insertNth n x l).nthLe (n + k + 1) hk = nthLe l (n + k) hk' :=
   @get_insertNth_add_succ _
 #align list.nth_le_insert_nth_add_succ List.nthLe_insertNth_add_succ
@@ -1874,8 +1877,8 @@ theorem take_left' {l₁ l₂ : List α} {n} (h : length l₁ = n) : take n (l
 #align list.take_left' List.take_left'
 
 theorem take_take : ∀ (n m) (l : List α), take n (take m l) = take (min n m) l
-  | n, 0, l => by rw [min_zero, take_zero, take_nil]
-  | 0, m, l => by rw [zero_min, take_zero, take_zero]
+  | n, 0, l => by rw [Nat.min_zero, take_zero, take_nil]
+  | 0, m, l => by rw [Nat.zero_min, take_zero, take_zero]
   | succ n, succ m, nil => by simp only [take_nil]
   | succ n, succ m, a :: l => by
     simp only [take, succ_min_succ, take_take n m l]
@@ -1903,13 +1906,17 @@ theorem take_append_eq_append_take {l₁ l₂ : List α} {n : ℕ} :
 #align list.take_append_eq_append_take List.take_append_eq_append_take
 
 theorem take_append_of_le_length {l₁ l₂ : List α} {n : ℕ} (h : n ≤ l₁.length) :
-    (l₁ ++ l₂).take n = l₁.take n := by simp [take_append_eq_append_take, tsub_eq_zero_iff_le.mpr h]
+    (l₁ ++ l₂).take n = l₁.take n := by
+  simp [take_append_eq_append_take, Nat.sub_eq_zero_iff_le.mpr h]
 #align list.take_append_of_le_length List.take_append_of_le_length
 
 /-- Taking the first `l₁.length + i` elements in `l₁ ++ l₂` is the same as appending the first
 `i` elements of `l₂` to `l₁`. -/
-theorem take_append {l₁ l₂ : List α} (i : ℕ) : take (l₁.length + i) (l₁ ++ l₂) = l₁ ++ take i l₂ :=
-  by simp [take_append_eq_append_take, take_all_of_le le_self_add]
+theorem take_append {l₁ l₂ : List α} (i : ℕ) :
+    take (l₁.length + i) (l₁ ++ l₂) = l₁ ++ take i l₂ := by
+  rw [take_append_eq_append_take, take_all_of_le (by omega), append_cancel_left_eq]
+  congr
+  omega
 #align list.take_append List.take_append
 
 /-- The `i`-th element of a list coincides with the `i`-th element of any of its prefixes of
@@ -1930,15 +1937,19 @@ theorem nthLe_take (L : List α) {i j : ℕ} (hi : i < L.length) (hj : i < j) :
 /-- The `i`-th element of a list coincides with the `i`-th element of any of its prefixes of
 length `> i`. Version designed to rewrite from the small list to the big list. -/
 theorem get_take' (L : List α) {j i} :
-    get (L.take j) i = get L ⟨i.1, lt_of_lt_of_le i.2 (by simp [le_refl])⟩ := by
-  let ⟨i, hi⟩ := i; simp only [length_take, lt_min_iff] at hi; rw [get_take L _ hi.1]
-
+    get (L.take j) i = get L ⟨i.1, lt_of_lt_of_le i.2 (by simp only [length_take]; omega)⟩ := by
+  let ⟨i, hi⟩ := i
+  simp only [length_take] at hi
+  rw [get_take L]
+  dsimp
+  omega
 set_option linter.deprecated false in
 /-- The `i`-th element of a list coincides with the `i`-th element of any of its prefixes of
 length `> i`. Version designed to rewrite from the small list to the big list. -/
 @[deprecated get_take']
 theorem nthLe_take' (L : List α) {i j : ℕ} (hi : i < (L.take j).length) :
-    nthLe (L.take j) i hi = nthLe L i (lt_of_lt_of_le hi (by simp [le_refl])) := get_take' _
+    nthLe (L.take j) i hi = nthLe L i (lt_of_lt_of_le hi (by simp only [length_take]; omega)) :=
+  get_take' _
 #align list.nth_le_take' List.nthLe_take'
 
 theorem get?_take {l : List α} {n m : ℕ} (h : m < n) : (l.take n).get? m = l.get? m := by
@@ -1974,8 +1985,8 @@ theorem take_eq_take :
     ∀ {l : List α} {m n : ℕ}, l.take m = l.take n ↔ min m l.length = min n l.length
   | [], m, n => by simp
   | _ :: xs, 0, 0 => by simp
-  | x :: xs, m + 1, 0 => by simp
-  | x :: xs, 0, n + 1 => by simp [@eq_comm ℕ 0]
+  | x :: xs, m + 1, 0 => by simp; omega
+  | x :: xs, 0, n + 1 => by simp; omega
   | x :: xs, m + 1, n + 1 => by simp [Nat.succ_min_succ, take_eq_take]
 #align list.take_eq_take List.take_eq_take
 
@@ -1985,12 +1996,12 @@ theorem take_add (l : List α) (m n : ℕ) : l.take (m + n) = l.take m ++ (l.dro
   rw [take_append_eq_append_take, take_all_of_le, append_right_inj]
   · simp only [take_eq_take, length_take, length_drop]
     generalize l.length = k; by_cases h : m ≤ k
-    · simp [min_eq_left_iff.mpr h]
+    · omega
     · push_neg at h
       simp [Nat.sub_eq_zero_of_le (le_of_lt h)]
   · trans m
     · apply length_take_le
-    · simp
+    · omega
 #align list.take_add List.take_add
 
 theorem dropLast_eq_take (l : List α) : l.dropLast = l.take l.length.pred := by
@@ -2003,7 +2014,9 @@ theorem dropLast_eq_take (l : List α) : l.dropLast = l.take l.length.pred := by
 
 theorem dropLast_take {n : ℕ} {l : List α} (h : n < l.length) :
     (l.take n).dropLast = l.take n.pred := by
-  simp [dropLast_eq_take, min_eq_left_of_lt h, take_take, pred_le]
+  simp only [dropLast_eq_take, length_take, pred_eq_sub_one, take_take]
+  congr
+  omega
 #align list.init_take List.dropLast_take
 
 theorem dropLast_cons_of_ne_nil {α : Type*} {x : α}
@@ -2087,7 +2100,11 @@ theorem drop_length_cons {l : List α} (h : l ≠ []) (a : α) :
 /-- Dropping the elements up to `l₁.length + i` in `l₁ + l₂` is the same as dropping the elements
 up to `i` in `l₂`. -/
 theorem drop_append {l₁ l₂ : List α} (i : ℕ) : drop (l₁.length + i) (l₁ ++ l₂) = drop i l₂ := by
-  rw [drop_append_eq_append_drop, drop_eq_nil_of_le] <;> simp
+  rw [drop_append_eq_append_drop, drop_eq_nil_of_le]
+  · simp only [nil_append]
+    congr
+    omega
+  · omega
 #align list.drop_append List.drop_append
 
 theorem drop_sizeOf_le [SizeOf α] (l : List α) : ∀ n : ℕ, sizeOf (l.drop n) ≤ sizeOf l := by
@@ -2095,7 +2112,9 @@ theorem drop_sizeOf_le [SizeOf α] (l : List α) : ∀ n : ℕ, sizeOf (l.drop n
   · rw [drop_nil]
   · induction' n with n
     · rfl
-    · exact Trans.trans (lih _) le_add_self
+    · specialize lih n
+      simp_all only [cons.sizeOf_spec, drop_succ_cons]
+      omega
 #align list.drop_sizeof_le List.drop_sizeOf_le
 
 set_option linter.deprecated false in -- FIXME
@@ -2105,11 +2124,14 @@ theorem get_drop (L : List α) {i j : ℕ} (h : i + j < L.length) :
     get L ⟨i + j, h⟩ = get (L.drop i) ⟨j, by
       have A : i < L.length := lt_of_le_of_lt (Nat.le.intro rfl) h
       rw [(take_append_drop i L).symm] at h
-      simpa only [le_of_lt A, min_eq_left, add_lt_add_iff_left, length_take,
-        length_append] using h⟩ := by
+      simp_all only [take_append_drop, length_drop, gt_iff_lt]
+      omega⟩ := by
   rw [← nthLe_eq, ← nthLe_eq]
-  rw [nthLe_of_eq (take_append_drop i L).symm h, nthLe_append_right] <;>
-  simp [min_eq_left (show i ≤ length L from le_trans (by simp) (le_of_lt h))]
+  rw [nthLe_of_eq (take_append_drop i L).symm h, nthLe_append_right]
+  congr
+  all_goals
+    simp only [length_take]
+    omega
 
 set_option linter.deprecated false in
 /-- The `i + j`-th element of a list coincides with the `j`-th element of the list obtained by
@@ -2119,14 +2141,14 @@ theorem nthLe_drop (L : List α) {i j : ℕ} (h : i + j < L.length) :
     nthLe L (i + j) h = nthLe (L.drop i) j (by
       have A : i < L.length := lt_of_le_of_lt (Nat.le.intro rfl) h
       rw [(take_append_drop i L).symm] at h
-      simpa only [le_of_lt A, min_eq_left, add_lt_add_iff_left, length_take,
-        length_append] using h) := get_drop ..
+      simp_all only [take_append_drop, length_drop, gt_iff_lt]
+      omega) := get_drop ..
 #align list.nth_le_drop List.nthLe_drop
 
 /-- The `i + j`-th element of a list coincides with the `j`-th element of the list obtained by
 dropping the first `i` elements. Version designed to rewrite from the small list to the big list. -/
 theorem get_drop' (L : List α) {i j} :
-    get (L.drop i) j = get L ⟨i + j, lt_tsub_iff_left.mp (length_drop i L ▸ j.2)⟩ := by
+    get (L.drop i) j = get L ⟨i + j, have := length_drop i L; by omega⟩ := by
   rw [get_drop]
 
 set_option linter.deprecated false in
@@ -2134,14 +2156,14 @@ set_option linter.deprecated false in
 dropping the first `i` elements. Version designed to rewrite from the small list to the big list. -/
 @[deprecated get_drop']
 theorem nthLe_drop' (L : List α) {i j : ℕ} (h : j < (L.drop i).length) :
-    nthLe (L.drop i) j h = nthLe L (i + j) (lt_tsub_iff_left.mp (length_drop i L ▸ h)) :=
+    nthLe (L.drop i) j h = nthLe L (i + j) (have := length_drop i L; by omega) :=
   get_drop' ..
 #align list.nth_le_drop' List.nthLe_drop'
 
 theorem get?_drop (L : List α) (i j : ℕ) : get? (L.drop i) j = get? L (i + j) := by
   ext
   simp only [get?_eq_some, get_drop', Option.mem_def]
-  constructor <;> exact fun ⟨h, ha⟩ => ⟨by simpa [lt_tsub_iff_left] using h, ha⟩
+  constructor <;> exact fun ⟨h, ha⟩ => ⟨by simp_all only [length_drop, exists_prop]; omega, ha⟩
 #align list.nth_drop List.get?_drop
 
 @[simp]
@@ -2159,7 +2181,7 @@ theorem drop_take : ∀ (m : ℕ) (n : ℕ) (l : List α), drop m (take (m + n)
   | 0, n, _ => by simp
   | m + 1, n, nil => by simp
   | m + 1, n, _ :: l => by
-    have h : m + 1 + n = m + n + 1 := by ac_rfl
+    have h : m + 1 + n = m + n + 1 := by omega
     simpa [take_cons, h] using drop_take m n l
 #align list.drop_take List.drop_take
 
@@ -2209,15 +2231,15 @@ theorem set_eq_take_cons_drop (a : α) {n l} (h : n < length l) :
 theorem reverse_take {α} {xs : List α} (n : ℕ) (h : n ≤ xs.length) :
     xs.reverse.take n = (xs.drop (xs.length - n)).reverse := by
   induction' xs with xs_hd xs_tl xs_ih generalizing n <;>
-    simp only [reverse_cons, drop, reverse_nil, zero_tsub, length, take_nil]
+    simp only [reverse_nil, reverse_cons, take_nil, length, Nat.zero_sub, drop_nil]
   cases' h.lt_or_eq_dec with h' h'
   · replace h' := le_of_succ_le_succ h'
     rw [take_append_of_le_length, xs_ih _ h']
     rw [show xs_tl.length + 1 - n = succ (xs_tl.length - n) from _, drop]
-    · rwa [succ_eq_add_one, ← @tsub_add_eq_add_tsub]
+    · omega
     · rwa [length_reverse]
   · subst h'
-    rw [length, tsub_self, drop]
+    rw [length, Nat.sub_self, drop]
     suffices xs_tl.length + 1 = (xs_tl.reverse ++ [xs_hd]).length by
       rw [this, take_length, reverse_cons]
     rw [length_append, length_reverse]
@@ -2550,12 +2572,12 @@ theorem nthLe_succ_scanl {i : ℕ} {h : i + 1 < (scanl f b l).length} :
     · simp [scanl_cons, singleton_append, nthLe_zero_scanl, nthLe_cons]
   | succ i hi =>
     cases l
-    · simp only [length, add_lt_iff_neg_right, scanl_nil] at h
-      exact absurd h (not_lt_of_lt Nat.succ_pos')
+    · simp only [length, zero_add] at h
+      exact absurd h (by omega)
     · simp_rw [scanl_cons]
       rw [nthLe_append_right]
       · simp only [length, zero_add 1, succ_add_sub_one, hi]; rfl
-      · simp only [length, Nat.zero_le, le_add_iff_nonneg_left]
+      · simp only [length_singleton]; omega
 #align list.nth_le_succ_scanl List.nthLe_succ_scanl
 
 theorem get_succ_scanl {i : ℕ} {h : i + 1 < (scanl f b l).length} :
@@ -2764,10 +2786,10 @@ where
           rw [length, succ_eq_add_one] at h
           rw [splitAt.go, take, drop, append_cons, Array.toList_eq, ← Array.push_data,
             ← Array.toList_eq]
-          exact ih _ _ <| lt_of_add_lt_add_right h
+          exact ih _ _ <| (by omega)
     · induction n generalizing xs acc with
       | zero =>
-        rw [zero_eq, not_lt, nonpos_iff_eq_zero] at h
+        replace h : xs.length = 0 := by rw [zero_eq] at h; omega
         rw [eq_nil_of_length_eq_zero h, splitAt.go]
       | succ _ ih =>
         cases xs with
@@ -2963,9 +2985,9 @@ end ModifyLast
 theorem sizeOf_lt_sizeOf_of_mem [SizeOf α] {x : α} {l : List α} (hx : x ∈ l) :
     SizeOf.sizeOf x < SizeOf.sizeOf l := by
   induction' l with h t ih <;> cases hx <;> rw [cons.sizeOf_spec]
-  · exact lt_add_of_lt_of_nonneg (lt_one_add _) (Nat.zero_le _)
-  · refine lt_add_of_pos_of_le ?_ (le_of_lt (ih ‹_›))
-    rw [add_comm]; exact succ_pos _
+  · omega
+  · specialize ih ‹_›
+    omega
 #align list.sizeof_lt_sizeof_of_mem List.sizeOf_lt_sizeOf_of_mem
 
 @[simp]
@@ -3317,7 +3339,7 @@ theorem reduceOption_length_le (l : List (Option α)) : l.reduceOption.length 
   · simp [reduceOption_nil, length]
   · cases hd
     · exact Nat.le_succ_of_le hl
-    · simpa only [length, add_le_add_iff_right, reduceOption_cons_of_some] using hl
+    · simpa only [length, Nat.add_le_add_iff_right, reduceOption_cons_of_some] using hl
 #align list.reduce_option_length_le List.reduceOption_length_le
 
 theorem reduceOption_length_eq_iff {l : List (Option α)} :
@@ -3332,8 +3354,9 @@ theorem reduceOption_length_eq_iff {l : List (Option α)} :
       have := reduceOption_length_le tl
       rw [H] at this
       exact absurd (Nat.lt_succ_self _) (not_lt_of_le this)
-    · simp only [length, add_left_inj, find?, mem_cons, forall_eq_or_imp, Option.isSome_some,
-        ← hl, reduceOption, true_and]
+    · simp only [length, mem_cons, forall_eq_or_imp, Option.isSome_some, ← hl, reduceOption,
+        true_and]
+      omega
 #align list.reduce_option_length_eq_iff List.reduceOption_length_eq_iff
 
 theorem reduceOption_length_lt_iff {l : List (Option α)} :
@@ -3748,7 +3771,7 @@ theorem enumFrom_get? :
     ∀ (n) (l : List α) (m), get? (enumFrom n l) m = (fun a => (n + m, a)) <$> get? l m
   | n, [], m => rfl
   | n, a :: l, 0 => rfl
-  | n, a :: l, m + 1 => (enumFrom_get? (n + 1) l m).trans <| by rw [add_right_comm]; rfl
+  | n, a :: l, m + 1 => (enumFrom_get? (n + 1) l m).trans <| by rw [Nat.add_right_comm]; rfl
 #align list.enum_from_nth List.enumFrom_get?
 
 @[simp]
@@ -3782,7 +3805,7 @@ theorem mem_enumFrom {x : α} {i : ℕ} :
       refine' ⟨_, _, _⟩
       · exact le_trans (Nat.le_succ _) hji
       · convert hijlen using 1
-        ac_rfl
+        omega
       · simp [hmem]
 #align list.mem_enum_from List.mem_enumFrom
 
@@ -3814,7 +3837,7 @@ theorem enumFrom_append (xs ys : List α) (n : ℕ) :
     enumFrom n (xs ++ ys) = enumFrom n xs ++ enumFrom (n + xs.length) ys := by
   induction' xs with x xs IH generalizing ys n
   · simp
-  · rw [cons_append, enumFrom_cons, IH, ← cons_append, ← enumFrom_cons, length, add_right_comm,
+  · rw [cons_append, enumFrom_cons, IH, ← cons_append, ← enumFrom_cons, length, Nat.add_right_comm,
       add_assoc]
 #align list.enum_from_append List.enumFrom_append
 
@@ -3827,7 +3850,7 @@ theorem map_fst_add_enumFrom_eq_enumFrom (l : List α) (n k : ℕ) :
   induction' l with hd tl IH generalizing n k
   · simp [enumFrom]
   · simp only [enumFrom, map, zero_add, Prod.map_mk, id.def, eq_self_iff_true, true_and_iff]
-    simp [IH, add_comm n k, add_assoc, add_left_comm]
+    simp [IH, add_comm n k, add_assoc, Nat.add_left_comm]
 #align list.map_fst_add_enum_from_eq_enum_from List.map_fst_add_enumFrom_eq_enumFrom
 
 theorem map_fst_add_enum_eq_enumFrom (l : List α) (n : ℕ) :
@@ -4280,8 +4303,8 @@ theorem sizeOf_dropSlice_lt [SizeOf α] (i j : ℕ) (hj : 0 < j) (xs : List α)
           · simp only [drop, cons.sizeOf_spec]
             rw [← Nat.zero_add (sizeOf (drop _ xs_tl))]
             exact Nat.add_le_add (Nat.zero_le _) (drop_sizeOf_le xs_tl _)
-        · simp
-    · simp only [cons.sizeOf_spec, add_lt_add_iff_left]
+        · simp only [cons.sizeOf_spec]; omega
+    · simp only [cons.sizeOf_spec, Nat.add_lt_add_iff_left]
       apply xs_ih _ j hj
       apply lt_of_succ_lt_succ hi
 #align list.sizeof_slice_lt List.sizeOf_dropSlice_lt
@@ -4319,3 +4342,5 @@ theorem disjoint_pmap {p : α → Prop} {f : ∀ a : α, p a → β} {s t : List
 end Disjoint
 
 end List
+
+assert_not_exists Lattice
chore(*): remove empty lines between variable statements (#11418)

Empty lines were removed by executing the following Python script twice

import os
import re


# Loop through each file in the repository
for dir_path, dirs, files in os.walk('.'):
  for filename in files:
    if filename.endswith('.lean'):
      file_path = os.path.join(dir_path, filename)

      # Open the file and read its contents
      with open(file_path, 'r') as file:
        content = file.read()

      # Use a regular expression to replace sequences of "variable" lines separated by empty lines
      # with sequences without empty lines
      modified_content = re.sub(r'(variable.*\n)\n(variable(?! .* in))', r'\1\2', content)

      # Write the modified content back to the file
      with open(file_path, 'w') as file:
        file.write(modified_content)
Diff
@@ -2615,7 +2615,6 @@ end FoldlEqFoldr
 section FoldlEqFoldlr'
 
 variable {f : α → β → α}
-
 variable (hf : ∀ a b c, f (f a b) c = f (f a c) b)
 
 theorem foldl_eq_of_comm' : ∀ a b l, foldl f a (b :: l) = f (foldl f a l) b
@@ -2633,7 +2632,6 @@ end FoldlEqFoldlr'
 section FoldlEqFoldlr'
 
 variable {f : α → β → β}
-
 variable (hf : ∀ a b c, f a (f b c) = f b (f a c))
 
 theorem foldr_eq_of_comm' : ∀ a b l, foldr f a (b :: l) = foldr f (f b a) l
chore: resolve a few porting notes of "original proof fails". (#11388)
Diff
@@ -861,10 +861,7 @@ set_option linter.deprecated false -- TODO(Mario): make replacements for theorem
 @[simp] theorem nthLe_tail (l : List α) (i) (h : i < l.tail.length)
     (h' : i + 1 < l.length := (by simpa [← lt_tsub_iff_right] using h)) :
     l.tail.nthLe i h = l.nthLe (i + 1) h' := by
-  -- Porting note: cases l <;> [cases h; rfl] fails
-  cases l
-  · cases h
-  · rfl
+  cases l <;> [cases h; rfl]
 #align list.nth_le_tail List.nthLe_tail
 
 theorem nthLe_cons_aux {l : List α} {a : α} {n} (hn : n ≠ 0) (h : n < (a :: l).length) :
@@ -1625,9 +1622,7 @@ theorem nthLe_insertNth_self (l : List α) (x : α) (n : ℕ) (hn : n ≤ l.leng
 
 theorem get_insertNth_add_succ (l : List α) (x : α) (n k : ℕ) (hk' : n + k < l.length)
     (hk : n + k + 1 < (insertNth n x l).length := (by
-      -- Porting note: the original proof fails
-      -- rwa [length_insertNth _ _ (le_self_add.trans hk'.le), Nat.succ_lt_succ_iff]
-      rw [length_insertNth _ _ (le_self_add.trans hk'.le)]; exact Nat.succ_lt_succ_iff.2 hk')) :
+      rwa [length_insertNth _ _ (le_self_add.trans hk'.le), Nat.succ_lt_succ_iff])):
     (insertNth n x l).get ⟨n + k + 1, hk⟩ = get l ⟨n + k, hk'⟩ := by
   induction' l with hd tl IH generalizing n k
   · simp at hk'
@@ -1639,9 +1634,7 @@ set_option linter.deprecated false in
 @[deprecated get_insertNth_add_succ]
 theorem nthLe_insertNth_add_succ : ∀ (l : List α) (x : α) (n k : ℕ) (hk' : n + k < l.length)
     (hk : n + k + 1 < (insertNth n x l).length := (by
-      -- Porting note: the original proof fails
-      -- rwa [length_insertNth _ _ (le_self_add.trans hk'.le), Nat.succ_lt_succ_iff]
-      rw [length_insertNth _ _ (le_self_add.trans hk'.le)]; exact Nat.succ_lt_succ_iff.2 hk')),
+      rwa [length_insertNth _ _ (le_self_add.trans hk'.le), Nat.succ_lt_succ_iff])),
     (insertNth n x l).nthLe (n + k + 1) hk = nthLe l (n + k) hk' :=
   @get_insertNth_add_succ _
 #align list.nth_le_insert_nth_add_succ List.nthLe_insertNth_add_succ
chore: squeeze some non-terminal simps (#11247)

This PR accompanies #11246, squeezing some non-terminal simps highlighted by the linter until I decided to stop!

Diff
@@ -1938,7 +1938,7 @@ theorem nthLe_take (L : List α) {i j : ℕ} (hi : i < L.length) (hj : i < j) :
 length `> i`. Version designed to rewrite from the small list to the big list. -/
 theorem get_take' (L : List α) {j i} :
     get (L.take j) i = get L ⟨i.1, lt_of_lt_of_le i.2 (by simp [le_refl])⟩ := by
-  let ⟨i, hi⟩ := i; simp at hi; rw [get_take L _ hi.1]
+  let ⟨i, hi⟩ := i; simp only [length_take, lt_min_iff] at hi; rw [get_take L _ hi.1]
 
 set_option linter.deprecated false in
 /-- The `i`-th element of a list coincides with the `i`-th element of any of its prefixes of
@@ -3220,7 +3220,7 @@ theorem lookmap_map_eq (g : α → β) (h : ∀ (a), ∀ b ∈ f a, g a = g b) :
   | [] => rfl
   | a :: l => by
     cases' h' : f a with b
-    · simp [h']; exact lookmap_map_eq _ h l
+    · simpa [h'] using lookmap_map_eq _ h l
     · simp [lookmap_cons_some _ _ h', h _ _ h']
 #align list.lookmap_map_eq List.lookmap_map_eq
 
@@ -4207,7 +4207,10 @@ theorem forall_iff_forall_mem : ∀ {l : List α}, Forall p l ↔ ∀ x ∈ l, p
 
 theorem Forall.imp (h : ∀ x, p x → q x) : ∀ {l : List α}, Forall p l → Forall q l
   | [] => id
-  | x :: l => by simp; rw [← and_imp]; exact And.imp (h x) (Forall.imp h)
+  | x :: l => by
+    simp only [forall_cons, and_imp]
+    rw [← and_imp]
+    exact And.imp (h x) (Forall.imp h)
 #align list.all₂.imp List.Forall.imp
 
 @[simp]
@@ -4283,11 +4286,11 @@ theorem sizeOf_dropSlice_lt [SizeOf α] (i j : ℕ) (hj : 0 < j) (xs : List α)
         | cons _ xs_tl =>
           cases n
           · simp
-          · simp [drop]
+          · simp only [drop, cons.sizeOf_spec]
             rw [← Nat.zero_add (sizeOf (drop _ xs_tl))]
             exact Nat.add_le_add (Nat.zero_le _) (drop_sizeOf_le xs_tl _)
         · simp
-    · simp
+    · simp only [cons.sizeOf_spec, add_lt_add_iff_left]
       apply xs_ih _ j hj
       apply lt_of_succ_lt_succ hi
 #align list.sizeof_slice_lt List.sizeOf_dropSlice_lt
chore: move Mathlib to v4.7.0-rc1 (#11162)

This is a very large PR, but it has been reviewed piecemeal already in PRs to the bump/v4.7.0 branch as we update to intermediate nightlies.

Co-authored-by: Scott Morrison <scott.morrison@gmail.com> Co-authored-by: Kyle Miller <kmill31415@gmail.com> Co-authored-by: damiano <adomani@gmail.com>

Diff
@@ -58,7 +58,6 @@ instance : Std.Associative (α := List α) Append.append where
 #align list.cons_injective List.cons_injective
 
 #align list.cons_inj List.cons_inj
-
 #align list.cons_eq_cons List.cons_eq_cons
 
 theorem singleton_injective : Injective fun a : α => [a] := fun _ _ h => (cons_eq_cons.1 h).1
@@ -273,7 +272,7 @@ theorem forall_mem_of_forall_mem_cons {p : α → Prop} {a : α} {l : List α} (
 #align list.forall_mem_append List.forall_mem_append
 
 theorem not_exists_mem_nil (p : α → Prop) : ¬∃ x ∈ @nil α, p x :=
-  fun.
+  nofun
 #align list.not_exists_mem_nil List.not_exists_mem_nilₓ -- bExists change
 
 -- Porting note: bExists in Lean3 and And in Lean4
@@ -1431,7 +1430,7 @@ theorem modifyNth_eq_set (f : α → α) :
   | 0, l => by cases l <;> rfl
   | n + 1, [] => rfl
   | n + 1, b :: l =>
-    (congr_arg (cons b) (modifyNth_eq_set f n l)).trans <| by cases get? l n <;> rfl
+    (congr_arg (cons b) (modifyNth_eq_set f n l)).trans <| by cases h : get? l n <;> simp [h]
 #align list.modify_nth_eq_update_nth List.modifyNth_eq_set
 
 #align list.nth_modify_nth List.get?_modifyNth
@@ -1704,7 +1703,6 @@ theorem bind_ret_eq_map (f : α → β) (l : List α) : l.bind (List.ret ∘ f)
   induction l <;>
     simp (config := { unfoldPartialApp := true })
       [map, join, List.ret, cons_append, nil_append, *] at *
-  assumption
 #align list.bind_ret_eq_map List.bind_ret_eq_map
 
 theorem bind_congr {l : List α} {f g : α → List β} (h : ∀ x ∈ l, f x = g x) :
@@ -3352,7 +3350,6 @@ theorem reduceOption_length_lt_iff {l : List (Option α)} :
   rw [(reduceOption_length_le l).lt_iff_ne, Ne, reduceOption_length_eq_iff]
   induction l <;> simp [*]
   rw [@eq_comm _ none, ← Option.not_isSome_iff_eq_none, Decidable.imp_iff_not_or]
-  simp [Option.isNone_iff_eq_none]
 #align list.reduce_option_length_lt_iff List.reduceOption_length_lt_iff
 
 theorem reduceOption_singleton (x : Option α) : [x].reduceOption = x.toList := by cases x <;> rfl
style: homogenise porting notes (#11145)

Homogenises porting notes via capitalisation and addition of whitespace.

It makes the following changes:

  • converts "--porting note" into "-- Porting note";
  • converts "porting note" into "Porting note".
Diff
@@ -2720,7 +2720,7 @@ theorem foldlM_eq_foldl (f : β → α → m β) (b l) :
 -- Porting note: now in std
 #align list.mfoldl_append List.foldlM_append
 
---Porting note: now in std
+-- Porting note: now in std
 #align list.mfoldr_append List.foldrM_append
 
 end FoldlMFoldrM
@@ -3020,7 +3020,7 @@ theorem attach_map_val' (l : List α) (f : α → β) : (l.attach.map fun i => f
 @[simp]
 theorem attach_map_val (l : List α) : l.attach.map Subtype.val = l :=
   (attach_map_coe' _ _).trans l.map_id
--- porting note: coe is expanded eagerly, so "attach_map_coe" would have the same syntactic form.
+-- Porting note: coe is expanded eagerly, so "attach_map_coe" would have the same syntactic form.
 #align list.attach_map_coe List.attach_map_val
 #align list.attach_map_val List.attach_map_val
 
@@ -3476,7 +3476,7 @@ lemma filter_attach' (l : List α) (p : {a // a ∈ l} → Bool) [DecidableEq α
   simp [(· ∘ ·), map_filter' _ Subtype.coe_injective]
 #align list.filter_attach' List.filter_attach'
 
--- porting note: `Lean.Internal.coeM` forces us to type-ascript `{x // x ∈ l}`
+-- Porting note: `Lean.Internal.coeM` forces us to type-ascript `{x // x ∈ l}`
 lemma filter_attach (l : List α) (p : α → Bool) :
     (l.attach.filter fun x => p x : List {x // x ∈ l}) =
       (l.filter p).attach.map (Subtype.map id fun x => mem_of_mem_filter) :=
@@ -3523,7 +3523,7 @@ theorem dropWhile_nthLe_zero_not (l : List α) (hl : 0 < (l.dropWhile p).length)
     by_cases hp : p hd
     · simp [hp, IH]
     · simp [hp, nthLe_cons]
--- porting note: How did the Lean 3 proof work,
+-- Porting note: How did the Lean 3 proof work,
 -- without mentioning nthLe_cons?
 -- Same question for takeWhile_eq_nil_iff below
 #align list.drop_while_nth_le_zero_not List.dropWhile_nthLe_zero_not
feat: Add norm_iteratedFDeriv_prod_le using Sym (#10022)

add (iterated) deriv for prod

  • Add HasFDerivAt + variants for Finset.prod (and ContinuousMultilinearMap.mkPiAlgebra)
  • Add missing iteratedFDerivWithin equivalents for zero, const (resolves a todo in Analysis.Calculus.ContDiff.Basic)
  • Add iteratedFDeriv[Within]_sum for symmetry
  • Add a couple of convenience lemmas for Sym and Finset.{prod,sum}
Diff
@@ -3672,6 +3672,27 @@ theorem map_foldl_erase [DecidableEq β] {f : α → β} (finj : Injective f) {l
   induction l₂ generalizing l₁ <;> [rfl; simp only [foldl_cons, map_erase finj, *]]
 #align list.map_foldl_erase List.map_foldl_erase
 
+theorem erase_get [DecidableEq ι] {l : List ι} (i : Fin l.length) :
+    Perm (l.erase (l.get i)) (l.eraseIdx ↑i) := by
+  induction l with
+  | nil => simp
+  | cons a l IH =>
+    cases i using Fin.cases with
+    | zero => simp
+    | succ i =>
+      by_cases ha : a = l.get i
+      · simpa [ha] using .trans (perm_cons_erase (l.get_mem i i.isLt)) (.cons _ (IH i))
+      · simpa [ha] using IH i
+
+theorem eraseIdx_eq_take_drop_succ {l : List ι} {i : ℕ} :
+    l.eraseIdx i = l.take i ++ l.drop i.succ := by
+  induction l generalizing i with
+  | nil => simp
+  | cons a l IH =>
+    cases i with
+    | zero => simp
+    | succ i => simp [IH]
+
 end Erase
 
 /-! ### diff -/
chore: classify simp cannot prove porting notes (#10960)

Classifies by adding issue number #10959 porting notes claiming anything semantically equivalent to:

  • "simp cannot prove this"
  • "simp used to be able to close this goal"
  • "simp can't handle this"
  • "simp used to work here"
Diff
@@ -3007,7 +3007,7 @@ theorem pmap_eq_map_attach {p : α → Prop} (f : ∀ a, p a → β) (l H) :
   rw [attach, map_pmap]; exact pmap_congr l fun _ _ _ _ => rfl
 #align list.pmap_eq_map_attach List.pmap_eq_map_attach
 
--- @[simp] -- Porting note: lean 4 simp can't rewrite with this
+-- @[simp] -- Porting note (#10959): lean 4 simp can't rewrite with this
 theorem attach_map_coe' (l : List α) (f : α → β) :
     (l.attach.map fun (i : {i // i ∈ l}) => f i) = l.map f := by
   rw [attach, map_pmap]; exact pmap_eq_map _ _ _ _
chore: bump dependencies (#10954)

Co-authored-by: Scott Morrison <scott.morrison@gmail.com> Co-authored-by: Riccardo Brasca <riccardo.brasca@gmail.com>

Diff
@@ -3663,8 +3663,8 @@ variable [DecidableEq α]
 
 theorem map_erase [DecidableEq β] {f : α → β} (finj : Injective f) {a : α} (l : List α) :
     map f (l.erase a) = (map f l).erase (f a) := by
-  have this : Eq a = Eq (f a) ∘ f := by ext b; simp [finj.eq_iff]
-  simp [erase_eq_eraseP, erase_eq_eraseP, eraseP_map, this]; rfl
+  have this : (a == ·) = (f a == f ·) := by ext b; simp [beq_eq_decide, finj.eq_iff]
+  rw [erase_eq_eraseP, erase_eq_eraseP, eraseP_map, this]; rfl
 #align list.map_erase List.map_erase
 
 theorem map_foldl_erase [DecidableEq β] {f : α → β} (finj : Injective f) {l₁ l₂ : List α} :
@@ -3720,7 +3720,7 @@ theorem erase_diff_erase_sublist_of_sublist {a : α} :
   | b :: l₁, l₂, h =>
     if heq : b = a then by simp only [heq, erase_cons_head, diff_cons]; rfl
     else by
-      simp only [erase_cons_head b l₁, erase_cons_tail l₁ heq,
+      simp only [erase_cons_head b l₁, erase_cons_tail l₁ (not_beq_of_ne heq),
         diff_cons ((List.erase l₂ a)) (List.erase l₁ a) b, diff_cons l₂ l₁ b, erase_comm a b l₂]
       have h' := h.erase b
       rw [erase_cons_head] at h'
chore: classify simp can do this porting notes (#10619)

Classify by adding issue number (#10618) to porting notes claiming anything semantically equivalent to simp can prove this or simp can simplify this.

Diff
@@ -540,7 +540,7 @@ theorem reverse_cons' (a : α) (l : List α) : reverse (a :: l) = concat (revers
   simp only [reverse_cons, concat_eq_append]
 #align list.reverse_cons' List.reverse_cons'
 
--- Porting note: simp can prove this
+-- Porting note (#10618): simp can prove this
 -- @[simp]
 theorem reverse_singleton (a : α) : reverse [a] = [a] :=
   rfl
@@ -651,7 +651,7 @@ theorem getLast_concat' {a : α} (l : List α) : getLast (concat l a) (concat_ne
 theorem getLast_singleton' (a : α) : getLast [a] (cons_ne_nil a []) = a := rfl
 #align list.last_singleton List.getLast_singleton'
 
--- Porting note: simp can prove this
+-- Porting note (#10618): simp can prove this
 -- @[simp]
 theorem getLast_cons_cons (a₁ a₂ : α) (l : List α) :
     getLast (a₁ :: a₂ :: l) (cons_ne_nil _ _) = getLast (a₂ :: l) (cons_ne_nil a₂ l) :=
@@ -2369,7 +2369,7 @@ theorem foldr_join (f : α → β → β) :
 
 #align list.foldr_reverse List.foldr_reverse
 
--- Porting note: simp can prove this
+-- Porting note (#10618): simp can prove this
 -- @[simp]
 theorem foldr_eta : ∀ l : List α, foldr cons [] l = l :=
   by simp only [foldr_self_append, append_nil, forall_const]
@@ -3928,7 +3928,7 @@ theorem map₂Right'_nil_right : map₂Right' f as [] = ([], as) :=
   rfl
 #align list.map₂_right'_nil_right List.map₂Right'_nil_right
 
--- Porting note: simp can prove this
+-- Porting note (#10618): simp can prove this
 -- @[simp]
 theorem map₂Right'_nil_cons : map₂Right' f [] (b :: bs) = (f none b :: bs.map (f none), []) :=
   rfl
@@ -3960,7 +3960,7 @@ theorem zipLeft'_nil_left : zipLeft' ([] : List α) bs = ([], bs) :=
   rfl
 #align list.zip_left'_nil_left List.zipLeft'_nil_left
 
--- Porting note: simp can prove this
+-- Porting note (#10618): simp can prove this
 -- @[simp]
 theorem zipLeft'_cons_nil :
     zipLeft' (a :: as) ([] : List β) = ((a, none) :: as.map fun a => (a, none), []) :=
@@ -3993,7 +3993,7 @@ theorem zipRight'_nil_right : zipRight' as ([] : List β) = ([], as) :=
   rfl
 #align list.zip_right'_nil_right List.zipRight'_nil_right
 
--- Porting note: simp can prove this
+-- Porting note (#10618): simp can prove this
 -- @[simp]
 theorem zipRight'_nil_cons :
     zipRight' ([] : List α) (b :: bs) = ((none, b) :: bs.map fun b => (none, b), []) :=
@@ -4056,7 +4056,7 @@ theorem map₂Right_nil_right : map₂Right f as [] = [] :=
   rfl
 #align list.map₂_right_nil_right List.map₂Right_nil_right
 
--- Porting note: simp can prove this
+-- Porting note (#10618): simp can prove this
 -- @[simp]
 theorem map₂Right_nil_cons : map₂Right f [] (b :: bs) = f none b :: bs.map (f none) :=
   rfl
@@ -4096,7 +4096,7 @@ theorem zipLeft_nil_left : zipLeft ([] : List α) bs = [] :=
   rfl
 #align list.zip_left_nil_left List.zipLeft_nil_left
 
--- Porting note: simp can prove this
+-- Porting note (#10618): simp can prove this
 -- @[simp]
 theorem zipLeft_cons_nil :
     zipLeft (a :: as) ([] : List β) = (a, none) :: as.map fun a => (a, none) :=
@@ -4137,7 +4137,7 @@ theorem zipRight_nil_right : zipRight as ([] : List β) = [] :=
   rfl
 #align list.zip_right_nil_right List.zipRight_nil_right
 
--- Porting note: simp can prove this
+-- Porting note (#10618): simp can prove this
 -- @[simp]
 theorem zipRight_nil_cons :
     zipRight ([] : List α) (b :: bs) = (none, b) :: bs.map fun b => (none, b) :=
chore: Split off getD/getI lemmas from Data.List.Basic (#10337)

Splits off some lemmas from the end of this file, reducing the size of what is currently the longest file in mathlib.

Diff
@@ -4274,158 +4274,6 @@ theorem sizeOf_dropSlice_lt [SizeOf α] (i j : ℕ) (hj : 0 < j) (xs : List α)
       apply lt_of_succ_lt_succ hi
 #align list.sizeof_slice_lt List.sizeOf_dropSlice_lt
 
-/-! ### getD and getI -/
-
-section getD
-
-variable (l : List α) (x : α) (xs : List α) (d : α) (n : ℕ)
-
-@[simp]
-theorem getD_nil : getD [] n d = d :=
-  rfl
-#align list.nthd_nil List.getD_nilₓ -- argument order
-
-@[simp]
-theorem getD_cons_zero : getD (x :: xs) 0 d = x :=
-  rfl
-#align list.nthd_cons_zero List.getD_cons_zeroₓ -- argument order
-
-@[simp]
-theorem getD_cons_succ : getD (x :: xs) (n + 1) d = getD xs n d :=
-  rfl
-#align list.nthd_cons_succ List.getD_cons_succₓ -- argument order
-
-theorem getD_eq_get {n : ℕ} (hn : n < l.length) : l.getD n d = l.get ⟨n, hn⟩ := by
-  induction l generalizing n with
-  | nil => exact absurd hn (not_lt_of_ge (Nat.zero_le _))
-  | cons head tail ih =>
-    cases n
-    · exact getD_cons_zero _ _ _
-    · exact ih _
-
-@[simp]
-theorem getD_map {n : ℕ} (f : α → β) : (map f l).getD n (f d) = f (l.getD n d) := by
-  induction l generalizing n with
-  | nil => rfl
-  | cons head tail ih =>
-    cases n
-    · rfl
-    · simp [ih]
-
-set_option linter.deprecated false in
-@[deprecated getD_eq_get]
-theorem getD_eq_nthLe {n : ℕ} (hn : n < l.length) : l.getD n d = l.nthLe n hn :=
-  getD_eq_get ..
-#align list.nthd_eq_nth_le List.getD_eq_nthLeₓ -- argument order
-
-theorem getD_eq_default {n : ℕ} (hn : l.length ≤ n) : l.getD n d = d := by
-  induction l generalizing n with
-  | nil => exact getD_nil _ _
-  | cons head tail ih =>
-    cases n
-    · refine' absurd (Nat.zero_lt_succ _) (not_lt_of_ge hn)
-    · exact ih (Nat.le_of_succ_le_succ hn)
-#align list.nthd_eq_default List.getD_eq_defaultₓ -- argument order
-
-/-- An empty list can always be decidably checked for the presence of an element.
-Not an instance because it would clash with `DecidableEq α`. -/
-def decidableGetDNilNe {α} (a : α) : DecidablePred fun i : ℕ => getD ([] : List α) i a ≠ a :=
-  fun _ => isFalse fun H => H (getD_nil _ _)
-#align list.decidable_nthd_nil_ne List.decidableGetDNilNeₓ -- argument order
-
-@[simp]
-theorem getD_singleton_default_eq (n : ℕ) : [d].getD n d = d := by cases n <;> simp
-#align list.nthd_singleton_default_eq List.getD_singleton_default_eqₓ -- argument order
-
-@[simp]
-theorem getD_replicate_default_eq (r n : ℕ) : (replicate r d).getD n d = d := by
-  induction r generalizing n with
-  | zero => simp
-  | succ n ih => cases n <;> simp [ih]
-#align list.nthd_replicate_default_eq List.getD_replicate_default_eqₓ -- argument order
-
-theorem getD_append (l l' : List α) (d : α) (n : ℕ) (h : n < l.length)
-    (h' : n < (l ++ l').length := h.trans_le ((length_append l l').symm ▸ le_self_add)) :
-    (l ++ l').getD n d = l.getD n d := by
-  rw [getD_eq_get _ _ h', get_append _ h, getD_eq_get]
-#align list.nthd_append List.getD_appendₓ -- argument order
-
-theorem getD_append_right (l l' : List α) (d : α) (n : ℕ) (h : l.length ≤ n) :
-    (l ++ l').getD n d = l'.getD (n - l.length) d := by
-  cases lt_or_le n (l ++ l').length with
-  | inl h' =>
-    rw [getD_eq_get (l ++ l') d h', get_append_right, getD_eq_get]
-    · rw [length_append] at h'
-      exact Nat.sub_lt_left_of_lt_add h h'
-    · exact not_lt_of_le h
-  | inr h' =>
-    rw [getD_eq_default _ _ h', getD_eq_default]
-    rwa [le_tsub_iff_left h, ← length_append]
-#align list.nthd_append_right List.getD_append_rightₓ -- argument order
-
-theorem getD_eq_getD_get? (n : ℕ) : l.getD n d = (l.get? n).getD d := by
-  cases lt_or_le n l.length with
-  | inl h => rw [getD_eq_get _ _ h, get?_eq_get h, Option.getD_some]
-  | inr h => rw [getD_eq_default _ _ h, get?_eq_none.mpr h, Option.getD_none]
-#align list.nthd_eq_get_or_else_nth List.getD_eq_getD_get?ₓ -- argument order
-
-end getD
-
-section getI
-
-variable [Inhabited α] (l : List α) (x : α) (xs : List α) (n : ℕ)
-
-@[simp]
-theorem getI_nil : getI ([] : List α) n = default :=
-  rfl
-#align list.inth_nil List.getI_nil
-
-@[simp]
-theorem getI_cons_zero : getI (x :: xs) 0 = x :=
-  rfl
-#align list.inth_cons_zero List.getI_cons_zero
-
-@[simp]
-theorem getI_cons_succ : getI (x :: xs) (n + 1) = getI xs n :=
-  rfl
-#align list.inth_cons_succ List.getI_cons_succ
-
-theorem getI_eq_get {n : ℕ} (hn : n < l.length) : l.getI n = l.get ⟨n, hn⟩ :=
-  getD_eq_get ..
-
-@[deprecated getI_eq_get]
-theorem getI_eq_nthLe {n : ℕ} (hn : n < l.length) : l.getI n = l.nthLe n hn :=
-  getI_eq_get ..
-#align list.inth_eq_nth_le List.getI_eq_nthLe
-
-theorem getI_eq_default {n : ℕ} (hn : l.length ≤ n) : l.getI n = default :=
-  getD_eq_default _ _ hn
-#align list.inth_eq_default List.getI_eq_default
-
-theorem getD_default_eq_getI {n : ℕ} : l.getD n default = l.getI n :=
-  rfl
-#align list.nthd_default_eq_inth List.getD_default_eq_getIₓ -- new argument `n`
-
-theorem getI_append (l l' : List α) (n : ℕ) (h : n < l.length)
-    (h' : n < (l ++ l').length := h.trans_le ((length_append l l').symm ▸ le_self_add)) :
-    (l ++ l').getI n = l.getI n :=
-  getD_append _ _ _ _ h h'
-#align list.inth_append List.getI_append
-
-theorem getI_append_right (l l' : List α) (n : ℕ) (h : l.length ≤ n) :
-    (l ++ l').getI n = l'.getI (n - l.length) :=
-  getD_append_right _ _ _ _ h
-#align list.inth_append_right List.getI_append_right
-
-theorem getI_eq_iget_get? (n : ℕ) : l.getI n = (l.get? n).iget := by
-  rw [← getD_default_eq_getI, getD_eq_getD_get?, Option.getD_default_eq_iget]
-#align list.inth_eq_iget_nth List.getI_eq_iget_get?
-
-theorem getI_zero_eq_headI : l.getI 0 = l.headI := by cases l <;> rfl
-#align list.inth_zero_eq_head List.getI_zero_eq_headI
-
-end getI
-
 section Disjoint
 
 variable {α β : Type*}
chore: bump dependencies (#10446)

Co-authored-by: Scott Morrison <scott.morrison@gmail.com>

Diff
@@ -59,8 +59,6 @@ instance : Std.Associative (α := List α) Append.append where
 
 #align list.cons_inj List.cons_inj
 
-theorem cons_eq_cons {a b : α} {l l' : List α} : a :: l = b :: l' ↔ a = b ∧ l = l' :=
-  ⟨List.cons.inj, fun h => h.1 ▸ h.2 ▸ rfl⟩
 #align list.cons_eq_cons List.cons_eq_cons
 
 theorem singleton_injective : Injective fun a : α => [a] := fun _ _ h => (cons_eq_cons.1 h).1
@@ -505,12 +503,7 @@ theorem bind_eq_bind {α β} (f : α → List β) (l : List α) : l >>= f = l.bi
 
 /-! ### concat -/
 
-theorem concat_nil (a : α) : concat [] a = [a] :=
-  rfl
 #align list.concat_nil List.concat_nil
-
-theorem concat_cons (a b : α) (l : List α) : concat (a :: l) b = a :: concat l b :=
-  rfl
 #align list.concat_cons List.concat_cons
 
 @[deprecated concat_eq_append]
@@ -518,22 +511,9 @@ theorem concat_eq_append' (a : α) (l : List α) : concat l a = l ++ [a] :=
   concat_eq_append l a
 #align list.concat_eq_append List.concat_eq_append'
 
-theorem init_eq_of_concat_eq {a : α} {l₁ l₂ : List α} : concat l₁ a = concat l₂ a → l₁ = l₂ := by
-  intro h
-  rw [concat_eq_append, concat_eq_append] at h
-  exact append_cancel_right h
 #align list.init_eq_of_concat_eq List.init_eq_of_concat_eq
-
-theorem last_eq_of_concat_eq {a b : α} {l : List α} : concat l a = concat l b → a = b := by
-  intro h
-  rw [concat_eq_append, concat_eq_append] at h
-  exact head_eq_of_cons_eq (append_cancel_left h)
 #align list.last_eq_of_concat_eq List.last_eq_of_concat_eq
-
-theorem concat_ne_nil (a : α) (l : List α) : concat l a ≠ [] := by simp
 #align list.concat_ne_nil List.concat_ne_nil
-
-theorem concat_append (a : α) (l₁ l₂ : List α) : concat l₁ a ++ l₂ = l₁ ++ a :: l₂ := by simp
 #align list.concat_append List.concat_append
 
 @[deprecated length_concat]
@@ -541,7 +521,6 @@ theorem length_concat' (a : α) (l : List α) : length (concat l a) = succ (leng
   simp only [concat_eq_append, length_append, length]
 #align list.length_concat List.length_concat'
 
-theorem append_concat (a : α) (l₁ l₂ : List α) : l₁ ++ concat l₂ a = concat (l₁ ++ l₂) a := by simp
 #align list.append_concat List.append_concat
 
 /-! ### reverse -/
feat: add lemmas to simplify List.modifyNth (#10318)

Adds three lemmas, I don't think any of them are in the library anywhere already.

Diff
@@ -2209,6 +2209,18 @@ theorem modifyNthTail_eq_take_drop (f : List α → List α) (H : f [] = []) :
   | n + 1, b :: l => congr_arg (cons b) (modifyNthTail_eq_take_drop f H n l)
 #align list.modify_nth_tail_eq_take_drop List.modifyNthTail_eq_take_drop
 
+@[simp]
+theorem modifyNth_nil (f : α → α) (n : ℕ) :
+    modifyNth f n [] = [] := by cases n <;> rfl
+
+@[simp]
+theorem modifyNth_zero_cons (f : α → α) (a : α) (l : List α) :
+    modifyNth f 0 (a :: l) = f a :: l := rfl
+
+@[simp]
+theorem modifyNth_succ_cons (f : α → α) (n : ℕ) (a : α) (l : List α) :
+    modifyNth f (n + 1) (a :: l) = a :: modifyNth f n l := rfl
+
 theorem modifyNth_eq_take_drop (f : α → α) :
     ∀ n l, modifyNth f n l = take n l ++ modifyHead f (drop n l) :=
   modifyNthTail_eq_take_drop _ rfl
chore: bump dependencies (#10315)

Co-authored-by: Scott Morrison <scott.morrison@gmail.com>

Diff
@@ -902,7 +902,7 @@ theorem nthLe_cons {l : List α} {a : α} {n} (hl) :
   split_ifs with h
   · simp [nthLe, h]
   cases l
-  · rw [length_singleton, lt_succ_iff, nonpos_iff_eq_zero] at hl
+  · rw [length_singleton, Nat.lt_succ_iff, nonpos_iff_eq_zero] at hl
     contradiction
   cases n
   · contradiction
@@ -1292,7 +1292,7 @@ theorem take_one_drop_eq_of_lt_length {l : List α} {n : ℕ} (h : n < l.length)
   · by_cases h₁ : l = []
     · subst h₁
       rw [get_singleton]
-      simp only [length_singleton, lt_succ_iff, nonpos_iff_eq_zero] at h
+      simp only [length_singleton, Nat.lt_succ_iff, nonpos_iff_eq_zero] at h
       subst h
       simp
     have h₂ := h
chore: move to v4.6.0-rc1, merging adaptations from bump/v4.6.0 (#10176)

Co-authored-by: Scott Morrison <scott.morrison@gmail.com> Co-authored-by: Eric Wieser <wieser.eric@gmail.com> Co-authored-by: Joachim Breitner <mail@joachim-breitner.de>

Diff
@@ -41,14 +41,12 @@ instance uniqueOfIsEmpty [IsEmpty α] : Unique (List α) :=
       | a :: _ => isEmptyElim a }
 #align list.unique_of_is_empty List.uniqueOfIsEmpty
 
-instance : IsLeftId (List α) Append.append [] :=
-  ⟨nil_append⟩
+instance : Std.LawfulIdentity (α := List α) Append.append [] where
+  left_id := nil_append
+  right_id := append_nil
 
-instance : IsRightId (List α) Append.append [] :=
-  ⟨append_nil⟩
-
-instance : IsAssociative (List α) Append.append :=
-  ⟨append_assoc⟩
+instance : Std.Associative (α := List α) Append.append where
+  assoc := append_assoc
 
 #align list.cons_ne_nil List.cons_ne_nil
 #align list.cons_ne_self List.cons_ne_self
@@ -941,7 +939,7 @@ def reverseRecOn {C : List α → Sort*} (l : List α) (H0 : C [])
     let ih := reverseRecOn (reverse tail) H0 H1
     rw [reverse_cons]
     exact H1 _ _ ih
-termination_by _ _ l _ _ => l.length
+termination_by l.length
 #align list.reverse_rec_on List.reverseRecOn
 
 /-- Bidirectional induction principle for lists: if a property holds for the empty list, the
@@ -958,7 +956,7 @@ def bidirectionalRec {C : List α → Sort*} (H0 : C []) (H1 : ∀ a : α, C [a]
     rw [← dropLast_append_getLast (cons_ne_nil b l)]
     have : C l' := bidirectionalRec H0 H1 Hn l'
     exact Hn a l' b' this
-termination_by _ l => l.length
+termination_by l => l.length
 #align list.bidirectional_rec List.bidirectionalRecₓ -- universe order
 
 /-- Like `bidirectionalRec`, but with the list parameter placed first. -/
@@ -2665,7 +2663,7 @@ end FoldlEqFoldlr'
 
 section
 
-variable {op : α → α → α} [ha : IsAssociative α op] [hc : IsCommutative α op]
+variable {op : α → α → α} [ha : Std.Associative op] [hc : Std.Commutative op]
 
 /-- Notation for `op a b`. -/
 local notation a " ⋆ " b => op a b
@@ -4240,6 +4238,7 @@ theorem get_attach (L : List α) (i) :
       by rw [get_map]
     _ = L.get { val := i, isLt := _ } := by congr 2 <;> simp
 
+set_option linter.deprecated false in
 @[simp, deprecated get_attach]
 theorem nthLe_attach (L : List α) (i) (H : i < L.attach.length) :
     (L.attach.nthLe i H).1 = L.nthLe i (length_attach L ▸ H) := get_attach ..
feat: List.append_cons_inj_of_not_mem (#6856)

Co-authored-by: Yury G. Kudryashov <urkud@urkud.name>

Diff
@@ -2491,6 +2491,21 @@ theorem foldlRecOn_nil {C : β → Sort*} (op : β → α → β) (b) (hb : C b)
   rfl
 #align list.foldl_rec_on_nil List.foldlRecOn_nil
 
+/-- Consider two lists `l₁` and `l₂` with designated elements `a₁` and `a₂` somewhere in them:
+`l₁ = x₁ ++ [a₁] ++ z₁` and `l₂ = x₂ ++ [a₂] ++ z₂`.
+Assume the designated element `a₂` is present in neither `x₁` nor `z₁`.
+We conclude that the lists are equal (`l₁ = l₂`) if and only if their respective parts are equal
+(`x₁ = x₂ ∧ a₁ = a₂ ∧ z₁ = z₂`). -/
+lemma append_cons_inj_of_not_mem {x₁ x₂ z₁ z₂ : List α} {a₁ a₂ : α}
+    (notin_x : a₂ ∉ x₁) (notin_z : a₂ ∉ z₁) :
+    x₁ ++ a₁ :: z₁ = x₂ ++ a₂ :: z₂ ↔ x₁ = x₂ ∧ a₁ = a₂ ∧ z₁ = z₂ := by
+  constructor
+  · simp only [append_eq_append_iff, cons_eq_append, cons_eq_cons]
+    rintro (⟨c, rfl, ⟨rfl, rfl, rfl⟩ | ⟨d, rfl, rfl⟩⟩ |
+      ⟨c, rfl, ⟨rfl, rfl, rfl⟩ | ⟨d, rfl, rfl⟩⟩) <;> simp_all
+  · rintro ⟨rfl, rfl, rfl⟩
+    rfl
+
 section Scanl
 
 variable {f : β → α → β} {b : β} {a : α} {l : List α}
chore: reduce imports (#9830)

This uses the improved shake script from #9772 to reduce imports across mathlib. The corresponding noshake.json file has been added to #9772.

Co-authored-by: Mario Carneiro <di.gama@gmail.com>

Diff
@@ -6,9 +6,10 @@ Authors: Parikshit Khanna, Jeremy Avigad, Leonardo de Moura, Floris van Doorn, M
 import Mathlib.Init.Data.List.Instances
 import Mathlib.Data.Nat.Order.Basic
 import Mathlib.Data.List.Defs
-import Mathlib.Init.Core
 import Std.Data.List.Lemmas
 import Mathlib.Tactic.Common
+import Mathlib.Init.Data.Bool.Lemmas
+import Mathlib.Init.Data.List.Lemmas
 
 #align_import data.list.basic from "leanprover-community/mathlib"@"65a1391a0106c9204fe45bc73a039f056558cb83"
 
chore: remove duplicates about List.append (#9376)

Replace duplicates in Mathlib with theorems in Lean core.

  • List.append_left_cancelList.append_cancel_left
  • List.append_right_cancelList.append_cancel_right
Diff
@@ -392,22 +392,20 @@ theorem cons_eq_append_iff {a b c : List α} {x : α} :
 
 #align list.append_inj_left' List.append_inj_left'ₓ -- implicits order
 
-theorem append_left_cancel {s t₁ t₂ : List α} (h : s ++ t₁ = s ++ t₂) : t₁ = t₂ :=
-  (append_right_inj _).1 h
-#align list.append_left_cancel List.append_left_cancel
+@[deprecated] alias append_left_cancel := append_cancel_left -- deprecated since 2024-01-18
+#align list.append_left_cancel List.append_cancel_left
 
-theorem append_right_cancel {s₁ s₂ t : List α} (h : s₁ ++ t = s₂ ++ t) : s₁ = s₂ :=
-  (append_left_inj _).1 h
-#align list.append_right_cancel List.append_right_cancel
+@[deprecated] alias append_right_cancel := append_cancel_right -- deprecated since 2024-01-18
+#align list.append_right_cancel List.append_cancel_right
 
 theorem append_right_injective (s : List α) : Injective fun t ↦ s ++ t :=
-  fun _ _ ↦ append_left_cancel
+  fun _ _ ↦ append_cancel_left
 #align list.append_right_injective List.append_right_injective
 
 #align list.append_right_inj List.append_right_inj
 
 theorem append_left_injective (t : List α) : Injective fun s ↦ s ++ t :=
-  fun _ _ ↦ append_right_cancel
+  fun _ _ ↦ append_cancel_right
 #align list.append_left_injective List.append_left_injective
 
 #align list.append_left_inj List.append_left_inj
@@ -524,13 +522,13 @@ theorem concat_eq_append' (a : α) (l : List α) : concat l a = l ++ [a] :=
 theorem init_eq_of_concat_eq {a : α} {l₁ l₂ : List α} : concat l₁ a = concat l₂ a → l₁ = l₂ := by
   intro h
   rw [concat_eq_append, concat_eq_append] at h
-  exact append_right_cancel h
+  exact append_cancel_right h
 #align list.init_eq_of_concat_eq List.init_eq_of_concat_eq
 
 theorem last_eq_of_concat_eq {a b : α} {l : List α} : concat l a = concat l b → a = b := by
   intro h
   rw [concat_eq_append, concat_eq_append] at h
-  exact head_eq_of_cons_eq (append_left_cancel h)
+  exact head_eq_of_cons_eq (append_cancel_left h)
 #align list.last_eq_of_concat_eq List.last_eq_of_concat_eq
 
 theorem concat_ne_nil (a : α) (l : List α) : concat l a ≠ [] := by simp
chore: bump Std dependency up to leanprover/std4#511 (#9609)

Co-authored-by: Scott Morrison <scott.morrison@gmail.com>

Diff
@@ -695,13 +695,6 @@ theorem getLast_congr {l₁ l₂ : List α} (h₁ : l₁ ≠ []) (h₂ : l₂ 
     getLast l₁ h₁ = getLast l₂ h₂ := by subst l₁; rfl
 #align list.last_congr List.getLast_congr
 
-theorem getLast_mem : ∀ {l : List α} (h : l ≠ []), getLast l h ∈ l
-  | [], h => absurd rfl h
-  | [a], _ => by simp only [getLast, mem_singleton]
-  | a :: b :: l, h =>
-    List.mem_cons.2 <| Or.inr <| by
-        rw [getLast_cons_cons]
-        exact getLast_mem (cons_ne_nil b l)
 #align list.last_mem List.getLast_mem
 
 theorem getLast_replicate_succ (m : ℕ) (a : α) :
@@ -712,11 +705,6 @@ theorem getLast_replicate_succ (m : ℕ) (a : α) :
 
 /-! ### getLast? -/
 
--- Porting note: New lemma, since definition of getLast? is slightly different.
-@[simp]
-theorem getLast?_singleton (a : α) :
-    getLast? [a] = a := rfl
-
 -- Porting note: Moved earlier in file, for use in subsequent lemmas.
 @[simp]
 theorem getLast?_cons_cons (a b : α) (l : List α) :
@@ -4223,6 +4211,8 @@ theorem getLast_reverse {l : List α} (hl : l.reverse ≠ [])
   · simpa using hl'
 #align list.last_reverse List.getLast_reverse
 
+set_option linter.deprecated false in
+@[deprecated]
 theorem ilast'_mem : ∀ a l, @ilast' α a l ∈ a :: l
   | a, [] => by simp [ilast']
   | a, b :: l => by rw [mem_cons]; exact Or.inr (ilast'_mem b l)
chore(*): use ∃ x ∈ s, _ instead of ∃ (x) (_ : x ∈ s), _ (#9184)

Search for [∀∃].*(_ and manually replace some occurrences with more readable versions. In case of , the new expressions are defeq to the old ones. In case of , they differ by exists_prop.

In some rare cases, golf proofs that needed fixing.

Diff
@@ -2458,7 +2458,7 @@ for the seed element `b : β` and for all incremental `op : α → β → β`
 performed on the elements `(a : α) ∈ l`. The principle is given for
 a `Sort`-valued predicate, i.e., it can also be used to construct data. -/
 def foldrRecOn {C : β → Sort*} (l : List α) (op : α → β → β) (b : β) (hb : C b)
-    (hl : ∀ (b : β) (_ : C b) (a : α) (_ : a ∈ l), C (op a b)) : C (foldr op b l) := by
+    (hl : ∀ b, C b → ∀ a ∈ l, C (op a b)) : C (foldr op b l) := by
   induction l with
   | nil => exact hb
   | cons hd tl IH =>
@@ -2473,7 +2473,7 @@ for the seed element `b : β` and for all incremental `op : β → α → β`
 performed on the elements `(a : α) ∈ l`. The principle is given for
 a `Sort`-valued predicate, i.e., it can also be used to construct data. -/
 def foldlRecOn {C : β → Sort*} (l : List α) (op : β → α → β) (b : β) (hb : C b)
-    (hl : ∀ (b : β) (_ : C b) (a : α) (_ : a ∈ l), C (op b a)) : C (foldl op b l) := by
+    (hl : ∀ b, C b → ∀ a ∈ l, C (op b a)) : C (foldl op b l) := by
   induction l generalizing b with
   | nil => exact hb
   | cons hd tl IH =>
@@ -2491,7 +2491,7 @@ theorem foldrRecOn_nil {C : β → Sort*} (op : α → β → β) (b) (hb : C b)
 
 @[simp]
 theorem foldrRecOn_cons {C : β → Sort*} (x : α) (l : List α) (op : α → β → β) (b) (hb : C b)
-    (hl : ∀ (b : β) (_ : C b) (a : α) (_ : a ∈ x :: l), C (op a b)) :
+    (hl : ∀ b, C b → ∀ a ∈ x :: l, C (op a b)) :
     foldrRecOn (x :: l) op b hb hl =
       hl _ (foldrRecOn l op b hb fun b hb a ha => hl b hb a (mem_cons_of_mem _ ha)) x
         (mem_cons_self _ _) :=
chore: remove uses of cases' (#9171)

I literally went through and regex'd some uses of cases', replacing them with rcases; this is meant to be a low effort PR as I hope that tools can do this in the future.

rcases is an easier replacement than cases, though with better tools we could in future do a second pass converting simple rcases added here (and existing ones) to cases.

Diff
@@ -1609,7 +1609,7 @@ theorem insertNth_length_self (l : List α) (x : α) : insertNth l.length x l =
 
 theorem length_le_length_insertNth (l : List α) (x : α) (n : ℕ) :
     l.length ≤ (insertNth n x l).length := by
-  cases' le_or_lt n l.length with hn hn
+  rcases le_or_lt n l.length with hn | hn
   · rw [length_insertNth _ _ hn]
     exact (Nat.lt_succ_self _).le
   · rw [insertNth_of_length_lt _ _ _ hn]
@@ -1617,7 +1617,7 @@ theorem length_le_length_insertNth (l : List α) (x : α) (n : ℕ) :
 
 theorem length_insertNth_le_succ (l : List α) (x : α) (n : ℕ) :
     (insertNth n x l).length ≤ l.length + 1 := by
-  cases' le_or_lt n l.length with hn hn
+  rcases le_or_lt n l.length with hn | hn
   · rw [length_insertNth _ _ hn]
   · rw [insertNth_of_length_lt _ _ _ hn]
     exact (Nat.lt_succ_self _).le
chore: bump Std to leanprover/std4#277 (#9172)

Co-authored-by: Scott Morrison <scott.morrison@gmail.com>

Diff
@@ -2106,31 +2106,10 @@ theorem cons_nthLe_drop_succ {l : List α} {n : ℕ} (hn : n < l.length) :
 #align list.cons_nth_le_drop_succ List.cons_nthLe_drop_succ
 
 #align list.drop_nil List.drop_nil
-
-@[simp]
-theorem drop_one : ∀ l : List α, drop 1 l = tail l
-  | [] | _ :: _ => rfl
 #align list.drop_one List.drop_one
-
-theorem drop_add : ∀ (m n) (l : List α), drop (m + n) l = drop m (drop n l)
-  | _, 0, _ => rfl
-  | _, _ + 1, [] => drop_nil.symm
-  | m, n + 1, _ :: _ => drop_add m n _
 #align list.drop_add List.drop_add
-
-@[simp]
-theorem drop_left : ∀ l₁ l₂ : List α, drop (length l₁) (l₁ ++ l₂) = l₂
-  | [], _ => rfl
-  | _ :: l₁, l₂ => drop_left l₁ l₂
 #align list.drop_left List.drop_left
-
-theorem drop_left' {l₁ l₂ : List α} {n} (h : length l₁ = n) : drop n (l₁ ++ l₂) = l₂ := by
-  rw [← h]; apply drop_left
 #align list.drop_left' List.drop_left'
-
-theorem drop_eq_get_cons : ∀ {n} {l : List α} (h), drop n l = get l ⟨n, h⟩ :: drop (n + 1) l
-  | 0, _ :: _, _ => rfl
-  | n + 1, _ :: _, _ => @drop_eq_get_cons n _ _
 #align list.drop_eq_nth_le_cons List.drop_eq_get_consₓ -- nth_le vs get
 
 #align list.drop_length List.drop_length
chore: bump Std to match leanprover/std4#438 (#9157)

Co-authored-by: Scott Morrison <scott.morrison@gmail.com> Co-authored-by: Mario Carneiro <di.gama@gmail.com>

Diff
@@ -1077,10 +1077,6 @@ section IndexOf
 
 variable [DecidableEq α]
 
--- Porting note: simp can prove this
--- @[simp]
-theorem indexOf_nil (a : α) : indexOf a [] = 0 :=
-  rfl
 #align list.index_of_nil List.indexOf_nil
 
 /-
@@ -1111,18 +1107,16 @@ theorem indexOf_cons_ne {a b : α} (l : List α) : b ≠ a → indexOf a (b :: l
   | h => by simp only [indexOf, findIdx_cons, Bool.cond_eq_ite, beq_iff_eq, h, ite_false]
 #align list.index_of_cons_ne List.indexOf_cons_ne
 
--- rfl
-theorem indexOf_cons (a b : α) (l : List α) :
-    indexOf a (b :: l) = if b = a then 0 else succ (indexOf a l) := by
-  simp only [indexOf, findIdx_cons, Bool.cond_eq_ite, beq_iff_eq]
 #align list.index_of_cons List.indexOf_cons
 
 theorem indexOf_eq_length {a : α} {l : List α} : indexOf a l = length l ↔ a ∉ l := by
   induction' l with b l ih
   · exact iff_of_true rfl (not_mem_nil _)
-  simp only [length, mem_cons, indexOf_cons, eq_comm]; split_ifs with h
-  · exact iff_of_false (by rintro ⟨⟩) fun H => H <| Or.inl h
-  · simp only [h, false_or_iff]
+  simp only [length, mem_cons, indexOf_cons, eq_comm]
+  rw [cond_eq_if]
+  split_ifs with h <;> simp at h
+  · exact iff_of_false (by rintro ⟨⟩) fun H => H <| Or.inl h.symm
+  · simp only [Ne.symm h, false_or_iff]
     rw [← ih]
     exact succ_inj'
 #align list.index_of_eq_length List.indexOf_eq_length
@@ -1134,7 +1128,7 @@ theorem indexOf_of_not_mem {l : List α} {a : α} : a ∉ l → indexOf a l = le
 
 theorem indexOf_le_length {a : α} {l : List α} : indexOf a l ≤ length l := by
   induction' l with b l ih; · rfl
-  simp only [length, indexOf_cons]
+  simp only [length, indexOf_cons, cond_eq_if, beq_iff_eq]
   by_cases h : b = a
   · rw [if_pos h]; exact Nat.zero_le _
   · rw [if_neg h]; exact succ_le_succ ih
@@ -1340,7 +1334,7 @@ theorem ext_nthLe {l₁ l₂ : List α} (hl : length l₁ = length l₂)
 theorem indexOf_get [DecidableEq α] {a : α} : ∀ {l : List α} (h), get l ⟨indexOf a l, h⟩ = a
   | b :: l, h => by
     by_cases h' : b = a <;>
-      simp only [h', if_pos, if_false, indexOf_cons, get, @indexOf_get _ _ l]
+    simp only [h', if_pos, if_false, indexOf_cons, get, @indexOf_get _ _ l, cond_eq_if, beq_iff_eq]
 
 @[simp, deprecated indexOf_get]
 theorem indexOf_nthLe [DecidableEq α] {a : α} : ∀ {l : List α} (h), nthLe l (indexOf a l) h = a :=
chore: bump Std dependency to leanprover/std4#432 (#9094)

This covers these changes in Std: https://github.com/leanprover/std4/compare/6b4cf96c89e53cfcd73350bbcd90333a051ff4f0...[9dd24a34](https://github.com/leanprover-community/mathlib/commit/9dd24a3493cceefa2bede383f21e4ef548990b68)

  • Int.ofNat_natAbs_eq_of_nonneg has become Int.natAbs_of_nonneg (and one argument has become implicit)
  • List.map_id'' and List.map_id' have exchanged names. (Yay naming things using primes!)
  • Some meta functions have moved to Std and can be deleted here.

Co-authored-by: Scott Morrison <scott.morrison@gmail.com>

Diff
@@ -1726,14 +1726,11 @@ theorem map_concat (f : α → β) (a : α) (l : List α) :
   induction l <;> [rfl; simp only [*, concat_eq_append, cons_append, map, map_append]]
 #align list.map_concat List.map_concat
 
-@[simp]
-theorem map_id'' (l : List α) : map (fun x => x) l = l :=
-  map_id _
-#align list.map_id'' List.map_id''
+#align list.map_id'' List.map_id'
 
-theorem map_id' {f : α → α} (h : ∀ x, f x = x) (l : List α) : map f l = l := by
+theorem map_id'' {f : α → α} (h : ∀ x, f x = x) (l : List α) : map f l = l := by
   simp [show f = id from funext h]
-#align list.map_id' List.map_id'
+#align list.map_id' List.map_id''
 
 theorem eq_nil_of_map_eq_nil {f : α → β} {l : List α} (h : map f l = nil) : l = nil :=
   eq_nil_of_length_eq_zero <| by rw [← length_map l f, h]; rfl
chore: Remove nonterminal simp at (#7795)

Removes nonterminal uses of simp at. Replaces most of these with instances of simp? ... says.

Co-authored-by: Scott Morrison <scott.morrison@gmail.com> Co-authored-by: Mario Carneiro <di.gama@gmail.com>

Diff
@@ -861,7 +861,7 @@ theorem tail_append_singleton_of_ne_nil {a : α} {l : List α} (h : l ≠ nil) :
 theorem cons_head?_tail : ∀ {l : List α} {a : α}, a ∈ head? l → a :: tail l = l
   | [], a, h => by contradiction
   | b :: l, a, h => by
-    simp at h
+    simp? at h says simp only [head?_cons, Option.mem_def, Option.some.injEq] at h
     simp [h]
 #align list.cons_head'_tail List.cons_head?_tail
 
@@ -1313,7 +1313,7 @@ theorem take_one_drop_eq_of_lt_length {l : List α} {n : ℕ} (h : n < l.length)
   · by_cases h₁ : l = []
     · subst h₁
       rw [get_singleton]
-      simp [lt_succ_iff] at h
+      simp only [length_singleton, lt_succ_iff, nonpos_iff_eq_zero] at h
       subst h
       simp
     have h₂ := h
@@ -2943,7 +2943,7 @@ theorem splitOn_intercalate [DecidableEq α] (x : α) (hx : ∀ l ∈ ls, x ∉
     specialize ih _ _
     · intro l hl
       apply hx l
-      simp at hl ⊢
+      simp only [mem_cons] at hl ⊢
       exact Or.inr hl
     · exact List.noConfusion
     have := splitOnP_first (· == x) hd ?h x (beq_self_eq_true _)
@@ -4074,7 +4074,7 @@ theorem map₂Left_eq_zipWith :
   | a :: as, [], h => by
     simp at h
   | a :: as, b :: bs, h => by
-    simp [Nat.succ_le_succ_iff] at h
+    simp only [length_cons, succ_le_succ_iff] at h
     simp [h, map₂Left_eq_zipWith]
 #align list.map₂_left_eq_map₂ List.map₂Left_eq_zipWith
 
chore: bump Std to match leanprover/std4#448 (#9044)

Co-authored-by: Scott Morrison <scott.morrison@gmail.com> Co-authored-by: Mario Carneiro <di.gama@gmail.com>

Diff
@@ -247,12 +247,13 @@ theorem singleton_eq (x : α) : ({x} : List α) = [x] :=
   rfl
 #align list.singleton_eq List.singleton_eq
 
-theorem insert_neg [DecidableEq α] {x : α} {l : List α} (h : x ∉ l) : Insert.insert x l = x :: l :=
-  if_neg h
+theorem insert_neg [DecidableEq α] {x : α} {l : List α} (h : x ∉ l) :
+    Insert.insert x l = x :: l :=
+  insert_of_not_mem h
 #align list.insert_neg List.insert_neg
 
 theorem insert_pos [DecidableEq α] {x : α} {l : List α} (h : x ∈ l) : Insert.insert x l = l :=
-  if_pos h
+  insert_of_mem h
 #align list.insert_pos List.insert_pos
 
 theorem doubleton_eq [DecidableEq α] {x y : α} (h : x ≠ y) : ({x, y} : List α) = [x, y] := by
chore: update Std dependency to match leanprover/std4#397 (#9039)

Co-authored-by: Scott Morrison <scott.morrison@gmail.com> Co-authored-by: Mario Carneiro <di.gama@gmail.com>

Diff
@@ -1100,26 +1100,26 @@ theorem indexOf_cons_self (a : α) (l : List α) : indexOf a (a :: l) = 0 := by
 #align list.index_of_cons_self List.indexOf_cons_self
 
 -- fun e => if_pos e
-theorem indexOf_cons_eq {a b : α} (l : List α) : a = b → indexOf a (b :: l) = 0
-  | e => by rw [e]; exact indexOf_cons_self b l
+theorem indexOf_cons_eq {a b : α} (l : List α) : b = a → indexOf a (b :: l) = 0
+  | e => by rw [← e]; exact indexOf_cons_self b l
 #align list.index_of_cons_eq List.indexOf_cons_eq
 
 -- fun n => if_neg n
 @[simp]
-theorem indexOf_cons_ne {a b : α} (l : List α) : a ≠ b → indexOf a (b :: l) = succ (indexOf a l)
+theorem indexOf_cons_ne {a b : α} (l : List α) : b ≠ a → indexOf a (b :: l) = succ (indexOf a l)
   | h => by simp only [indexOf, findIdx_cons, Bool.cond_eq_ite, beq_iff_eq, h, ite_false]
 #align list.index_of_cons_ne List.indexOf_cons_ne
 
 -- rfl
 theorem indexOf_cons (a b : α) (l : List α) :
-    indexOf a (b :: l) = if a = b then 0 else succ (indexOf a l) := by
+    indexOf a (b :: l) = if b = a then 0 else succ (indexOf a l) := by
   simp only [indexOf, findIdx_cons, Bool.cond_eq_ite, beq_iff_eq]
 #align list.index_of_cons List.indexOf_cons
 
 theorem indexOf_eq_length {a : α} {l : List α} : indexOf a l = length l ↔ a ∉ l := by
   induction' l with b l ih
   · exact iff_of_true rfl (not_mem_nil _)
-  simp only [length, mem_cons, indexOf_cons]; split_ifs with h
+  simp only [length, mem_cons, indexOf_cons, eq_comm]; split_ifs with h
   · exact iff_of_false (by rintro ⟨⟩) fun H => H <| Or.inl h
   · simp only [h, false_or_iff]
     rw [← ih]
@@ -1134,7 +1134,7 @@ theorem indexOf_of_not_mem {l : List α} {a : α} : a ∉ l → indexOf a l = le
 theorem indexOf_le_length {a : α} {l : List α} : indexOf a l ≤ length l := by
   induction' l with b l ih; · rfl
   simp only [length, indexOf_cons]
-  by_cases h : a = b
+  by_cases h : b = a
   · rw [if_pos h]; exact Nat.zero_le _
   · rw [if_neg h]; exact succ_le_succ ih
 #align list.index_of_le_length List.indexOf_le_length
@@ -1149,16 +1149,16 @@ theorem indexOf_append_of_mem {a : α} (h : a ∈ l₁) : indexOf a (l₁ ++ l
   · exfalso
     exact not_mem_nil a h
   rw [List.cons_append]
-  by_cases hh : a = d₁
+  by_cases hh : d₁ = a
   · iterate 2 rw [indexOf_cons_eq _ hh]
-  rw [indexOf_cons_ne _ hh, indexOf_cons_ne _ hh, ih (mem_of_ne_of_mem hh h)]
+  rw [indexOf_cons_ne _ hh, indexOf_cons_ne _ hh, ih (mem_of_ne_of_mem (Ne.symm hh) h)]
 #align list.index_of_append_of_mem List.indexOf_append_of_mem
 
 theorem indexOf_append_of_not_mem {a : α} (h : a ∉ l₁) :
     indexOf a (l₁ ++ l₂) = l₁.length + indexOf a l₂ := by
   induction' l₁ with d₁ t₁ ih
   · rw [List.nil_append, List.length, zero_add]
-  rw [List.cons_append, indexOf_cons_ne _ (ne_of_not_mem_cons h), List.length,
+  rw [List.cons_append, indexOf_cons_ne _ (ne_of_not_mem_cons h).symm, List.length,
     ih (not_mem_of_not_mem_cons h), Nat.succ_add]
 #align list.index_of_append_of_not_mem List.indexOf_append_of_not_mem
 
@@ -1338,7 +1338,7 @@ theorem ext_nthLe {l₁ l₂ : List α} (hl : length l₁ = length l₂)
 @[simp]
 theorem indexOf_get [DecidableEq α] {a : α} : ∀ {l : List α} (h), get l ⟨indexOf a l, h⟩ = a
   | b :: l, h => by
-    by_cases h' : a = b <;>
+    by_cases h' : b = a <;>
       simp only [h', if_pos, if_false, indexOf_cons, get, @indexOf_get _ _ l]
 
 @[simp, deprecated indexOf_get]
chore: bump Std dependency up to leanprover/std4#445 (#9043)

I think this one should merge cleanly, after which we have some work to do for #9039

Co-authored-by: Scott Morrison <scott.morrison@gmail.com>

Diff
@@ -600,10 +600,7 @@ theorem reverse_eq_iff {l l' : List α} : l.reverse = l' ↔ l = l'.reverse :=
   reverse_involutive.eq_iff
 #align list.reverse_eq_iff List.reverse_eq_iff
 
-@[simp]
-theorem reverse_eq_nil {l : List α} : reverse l = [] ↔ l = [] :=
-  @reverse_inj _ l []
-#align list.reverse_eq_nil List.reverse_eq_nil
+#align list.reverse_eq_nil List.reverse_eq_nil_iff
 
 theorem concat_eq_reverse_cons (a : α) (l : List α) : concat l a = reverse (a :: reverse l) := by
   simp only [concat_eq_append, reverse_cons, reverse_reverse]
chore: reduce imports of Data.List.Defs (#8635)

Currently Data.List.Defs depends on Algebra.Group.Defs, rather unnecessarily.

(This then prevents importing Data.List.Defs into Tactic.Common, without breaking various assert_not_exists statements.)

Co-authored-by: Scott Morrison <scott.morrison@gmail.com> Co-authored-by: thorimur <68410468+thorimur@users.noreply.github.com>

Diff
@@ -4243,15 +4243,6 @@ instance (p : α → Prop) [DecidablePred p] : DecidablePred (Forall p) := fun _
 
 end Forall
 
-/-! ### Retroattributes
-
-The list definitions happen earlier than `to_additive`, so here we tag the few multiplicative
-definitions that couldn't be tagged earlier.
--/
-
-attribute [to_additive existing] List.prod -- `List.sum`
-attribute [to_additive existing] alternatingProd -- `List.alternatingSum`
-
 /-! ### Miscellaneous lemmas -/
 
 theorem getLast_reverse {l : List α} (hl : l.reverse ≠ [])
feat: Finsets and multisets are graded (#8892)

Characterise IsAtom, IsCoatom, Covby in Set α, Multiset α, Finset α and deduce that Multiset α, Finset α are graded orders.

Note I am moving some existing characterisations to here because it makes sense thematically, but I could be convinced otherwise.

Diff
@@ -1037,6 +1037,9 @@ theorem eq_nil_of_sublist_nil {l : List α} (s : l <+ []) : l = [] :=
 alias sublist_nil_iff_eq_nil := sublist_nil
 #align list.sublist_nil_iff_eq_nil List.sublist_nil_iff_eq_nil
 
+@[simp] lemma sublist_singleton {l : List α} {a : α} : l <+ [a] ↔ l = [] ∨ l = [a] := by
+  constructor <;> rintro (_ | _) <;> aesop
+
 #align list.replicate_sublist_replicate List.replicate_sublist_replicate
 
 theorem sublist_replicate_iff {l : List α} {a : α} {n : ℕ} :
chore: tidy various files (#8823)
Diff
@@ -4474,7 +4474,7 @@ section Disjoint
 
 variable {α β : Type*}
 
-/-- The images of disjoint maps under a map are disjoint -/
+/-- The images of disjoint lists under an injective map are disjoint -/
 theorem disjoint_map {f : α → β} {s t : List α} (hf : Function.Injective f)
     (h : Disjoint s t) : Disjoint (s.map f) (t.map f) := by
   simp only [Disjoint]
chore: tidy various files (#8818)
Diff
@@ -4396,7 +4396,7 @@ theorem getD_append (l l' : List α) (d : α) (n : ℕ) (h : n < l.length)
 
 theorem getD_append_right (l l' : List α) (d : α) (n : ℕ) (h : l.length ≤ n) :
     (l ++ l').getD n d = l'.getD (n - l.length) d := by
-  cases lt_or_le n (l ++l').length with
+  cases lt_or_le n (l ++ l').length with
   | inl h' =>
     rw [getD_eq_get (l ++ l') d h', get_append_right, getD_eq_get]
     · rw [length_append] at h'
chore: space after (#8178)

Co-authored-by: Moritz Firsching <firsching@google.com>

Diff
@@ -2540,7 +2540,7 @@ variable {f : β → α → β} {b : β} {a : α} {l : List α}
 theorem length_scanl : ∀ a l, length (scanl f a l) = l.length + 1
   | a, [] => rfl
   | a, x :: l => by
-    rw [scanl, length_cons, length_cons, ←succ_eq_add_one, congr_arg succ]
+    rw [scanl, length_cons, length_cons, ← succ_eq_add_one, congr_arg succ]
     exact length_scanl _ _
 #align list.length_scanl List.length_scanl
 
@@ -2752,7 +2752,7 @@ theorem foldlM_eq_foldl (f : β → α → m β) (b l) :
     by simp [← h (pure b)]
   induction l with
   | nil => intro; simp
-  | cons _ _ l_ih => intro; simp only [List.foldlM, foldl, ←l_ih, functor_norm]
+  | cons _ _ l_ih => intro; simp only [List.foldlM, foldl, ← l_ih, functor_norm]
 #align list.mfoldl_eq_foldl List.foldlM_eq_foldl
 
 -- Porting note: now in std
@@ -2811,8 +2811,8 @@ where
         | nil => contradiction
         | cons hd tl =>
           rw [length, succ_eq_add_one] at h
-          rw [splitAt.go, take, drop, append_cons, Array.toList_eq, ←Array.push_data,
-            ←Array.toList_eq]
+          rw [splitAt.go, take, drop, append_cons, Array.toList_eq, ← Array.push_data,
+            ← Array.toList_eq]
           exact ih _ _ <| lt_of_add_lt_add_right h
     · induction n generalizing xs acc with
       | zero =>
@@ -2994,7 +2994,7 @@ theorem modifyLast_append (f : α → α) (l₁ l₂ : List α) (_ : l₂ ≠ []
     cases tl with
     | nil => exact modifyLast_append_one _ hd _
     | cons hd' tl' =>
-      rw [append_cons, ←nil_append (hd :: hd' :: tl'), append_cons [], nil_append,
+      rw [append_cons, ← nil_append (hd :: hd' :: tl'), append_cons [], nil_append,
         modifyLast_append _ (l₁ ++ [hd]) (hd' :: tl') _, modifyLast_append _ [hd] (hd' :: tl') _,
         append_assoc]
       all_goals { exact cons_ne_nil _ _ }
@@ -3519,8 +3519,8 @@ lemma filter_attach (l : List α) (p : α → Bool) :
     (l.attach.filter fun x => p x : List {x // x ∈ l}) =
       (l.filter p).attach.map (Subtype.map id fun x => mem_of_mem_filter) :=
   map_injective_iff.2 Subtype.coe_injective <| by
-    simp_rw [map_map, (· ∘ ·), Subtype.map, id.def, ←Function.comp_apply (g := Subtype.val),
-      ←map_filter, attach_map_val]
+    simp_rw [map_map, (· ∘ ·), Subtype.map, id.def, ← Function.comp_apply (g := Subtype.val),
+      ← map_filter, attach_map_val]
 #align list.filter_attach List.filter_attach
 
 #align list.filter_filter List.filter_filter
@@ -4227,7 +4227,7 @@ theorem forall_iff_forall_mem : ∀ {l : List α}, Forall p l ↔ ∀ x ∈ l, p
 
 theorem Forall.imp (h : ∀ x, p x → q x) : ∀ {l : List α}, Forall p l → Forall q l
   | [] => id
-  | x :: l => by simp; rw [←and_imp]; exact And.imp (h x) (Forall.imp h)
+  | x :: l => by simp; rw [← and_imp]; exact And.imp (h x) (Forall.imp h)
 #align list.all₂.imp List.Forall.imp
 
 @[simp]
@@ -4310,7 +4310,7 @@ theorem sizeOf_dropSlice_lt [SizeOf α] (i j : ℕ) (hj : 0 < j) (xs : List α)
           cases n
           · simp
           · simp [drop]
-            rw [←Nat.zero_add (sizeOf (drop _ xs_tl))]
+            rw [← Nat.zero_add (sizeOf (drop _ xs_tl))]
             exact Nat.add_le_add (Nat.zero_le _) (drop_sizeOf_le xs_tl _)
         · simp
     · simp
feat(Data/List/Basic): bijectivity of List.map (#8642)

This adds Function.{LeftInverse,RightInverse,Involutive,Surjective,Bijective}.list_map, and corresponding iff lemmas.

List.map_injective_iff already existed, but has been golfed. The rest are new.

Diff
@@ -1765,20 +1765,6 @@ theorem map_eq_map {α β} (f : α → β) (l : List α) : f <$> l = map f l :=
 theorem map_tail (f : α → β) (l) : map f (tail l) = tail (map f l) := by cases l <;> rfl
 #align list.map_tail List.map_tail
 
-@[simp]
-theorem map_injective_iff {f : α → β} : Injective (map f) ↔ Injective f := by
-  constructor <;> intro h x y hxy
-  · suffices [x] = [y] by simpa using this
-    apply h
-    simp [hxy]
-  · induction' y with yh yt y_ih generalizing x
-    · simpa using hxy
-    cases x
-    · simp at hxy
-    · simp only [map, cons.injEq] at hxy
-      simp [y_ih hxy.2, h hxy.1]
-#align list.map_injective_iff List.map_injective_iff
-
 /-- A single `List.map` of a composition of functions is equal to
 composing a `List.map` with another `List.map`, fully applied.
 This is the reverse direction of `List.map_map`.
@@ -1795,6 +1781,68 @@ theorem map_comp_map (g : β → γ) (f : α → β) : map g ∘ map f = map (g
   ext l; rw [comp_map, Function.comp_apply]
 #align list.map_comp_map List.map_comp_map
 
+section map_bijectivity
+
+theorem _root_.Function.LeftInverse.list_map {f : α → β} {g : β → α} (h : LeftInverse f g) :
+    LeftInverse (map f) (map g)
+  | [] => by simp_rw [map_nil]
+  | x :: xs => by simp_rw [map_cons, h x, h.list_map xs]
+
+nonrec theorem _root_.Function.RightInverse.list_map {f : α → β} {g : β → α}
+    (h : RightInverse f g) : RightInverse (map f) (map g) :=
+  h.list_map
+
+nonrec theorem _root_.Function.Involutive.list_map {f : α → α}
+    (h : Involutive f) : Involutive (map f) :=
+  Function.LeftInverse.list_map h
+
+@[simp]
+theorem map_leftInverse_iff {f : α → β} {g : β → α} :
+    LeftInverse (map f) (map g) ↔ LeftInverse f g :=
+  ⟨fun h x => by injection h [x], (·.list_map)⟩
+
+@[simp]
+theorem map_rightInverse_iff {f : α → β} {g : β → α} :
+    RightInverse (map f) (map g) ↔ RightInverse f g := map_leftInverse_iff
+
+@[simp]
+theorem map_involutive_iff {f : α → α} :
+    Involutive (map f) ↔ Involutive f := map_leftInverse_iff
+
+theorem _root_.Function.Injective.list_map {f : α → β} (h : Injective f) :
+    Injective (map f)
+  | [], [], _ => rfl
+  | x :: xs, y :: ys, hxy => by
+    injection hxy with hxy hxys
+    rw [h hxy, h.list_map hxys]
+
+@[simp]
+theorem map_injective_iff {f : α → β} : Injective (map f) ↔ Injective f := by
+  refine ⟨fun h x y hxy => ?_, (·.list_map)⟩
+  suffices [x] = [y] by simpa using this
+  apply h
+  simp [hxy]
+#align list.map_injective_iff List.map_injective_iff
+
+theorem _root_.Function.Surjective.list_map {f : α → β} (h : Surjective f) :
+    Surjective (map f) :=
+  let ⟨_, h⟩ := h.hasRightInverse; h.list_map.surjective
+
+@[simp]
+theorem map_surjective_iff {f : α → β} : Surjective (map f) ↔ Surjective f := by
+  refine ⟨fun h x => ?_, (·.list_map)⟩
+  let ⟨[y], hxy⟩ := h [x]
+  exact ⟨_, List.singleton_injective hxy⟩
+
+theorem _root_.Function.Bijective.list_map {f : α → β} (h : Bijective f) : Bijective (map f) :=
+  ⟨h.1.list_map, h.2.list_map⟩
+
+@[simp]
+theorem map_bijective_iff {f : α → β} : Bijective (map f) ↔ Bijective f := by
+  simp_rw [Function.Bijective, map_injective_iff, map_surjective_iff]
+
+end map_bijectivity
+
 theorem map_filter_eq_foldr (f : α → β) (p : α → Bool) (as : List α) :
     map f (filter p as) = foldr (fun a bs => bif p a then f a :: bs else bs) [] as := by
   induction' as with head tail
feat: add List.enum_eq_nil and List.mapIdx_eq_nil (#8493)

Adds List.enum_eq_nil and List.mapIdx_eq_nil. These are analogous to List.map_eq_nil.

Diff
@@ -3865,6 +3865,13 @@ theorem nthLe_enum (l : List α) (i : ℕ) (hi' : i < l.enum.length)
     l.enum.nthLe i hi' = (i, l.nthLe i hi) := get_enum ..
 #align list.nth_le_enum List.nthLe_enum
 
+@[simp]
+theorem enumFrom_eq_nil {n : ℕ} {l : List α} : List.enumFrom n l = [] ↔ l = [] := by
+  cases l <;> simp
+
+@[simp]
+theorem enum_eq_nil {l : List α} : List.enum l = [] ↔ l = [] := enumFrom_eq_nil
+
 section Choose
 
 variable (p : α → Prop) [DecidablePred p] (l : List α)
chore: bump std4 (#8548)
Diff
@@ -642,13 +642,6 @@ theorem isEmpty_iff_eq_nil {l : List α} : l.isEmpty ↔ l = [] := by cases l <;
 
 /-! ### dropLast -/
 
-@[simp]
-theorem length_dropLast : ∀ l : List α, length l.dropLast = length l - 1
-  | [] | [_] => rfl
-  | a::b::l => by
-    rw [dropLast, length_cons, length_cons, length_dropLast (b::l), succ_sub_one, length_cons,
-      succ_sub_one]
-    simp
 #align list.length_init List.length_dropLast
 
 /-! ### getLast -/
chore: restore simpler code in foldrRecOn and foldlRecOn (#8508)

#1720 made List.rec computable and therefore made it possible to restore the simpler versions of foldrRecOn and foldlRecOn.

Diff
@@ -2441,56 +2441,30 @@ theorem injective_foldl_comp {α : Type*} {l : List (α → α)} {f : α → α}
     apply hl _ (List.mem_cons_self _ _)
 #align list.injective_foldl_comp List.injective_foldl_comp
 
-/- Porting note: couldn't do induction proof because "code generator does not support recursor
-  'List.rec' yet". Earlier proof:
-
-  induction l with
-  | nil => exact hb
-  | cons hd tl IH =>
-    refine' hl _ _ hd (mem_cons_self hd tl)
-    refine' IH _
-    intro y hy x hx
-    exact hl y hy x (mem_cons_of_mem hd hx)
--/
 /-- Induction principle for values produced by a `foldr`: if a property holds
 for the seed element `b : β` and for all incremental `op : α → β → β`
 performed on the elements `(a : α) ∈ l`. The principle is given for
 a `Sort`-valued predicate, i.e., it can also be used to construct data. -/
 def foldrRecOn {C : β → Sort*} (l : List α) (op : α → β → β) (b : β) (hb : C b)
     (hl : ∀ (b : β) (_ : C b) (a : α) (_ : a ∈ l), C (op a b)) : C (foldr op b l) := by
-  cases l with
+  induction l with
   | nil => exact hb
-  | cons hd tl =>
-    have IH : ((b : β) → C b → (a : α) → a ∈ tl → C (op a b)) → C (foldr op b tl) :=
-      foldrRecOn _ _ _ hb
+  | cons hd tl IH =>
     refine' hl _ _ hd (mem_cons_self hd tl)
     refine' IH _
     intro y hy x hx
     exact hl y hy x (mem_cons_of_mem hd hx)
 #align list.foldr_rec_on List.foldrRecOn
 
-/- Porting note: couldn't do induction proof because "code generator does not support recursor
-  'List.rec' yet". Earlier proof:
-
-  induction l generalizing b with
-  | nil => exact hb
-  | cons hd tl IH =>
-    refine' IH _ _ _
-    · exact hl b hb hd (mem_cons_self hd tl)
-    · intro y hy x hx
-      exact hl y hy x (mem_cons_of_mem hd hx)
--/
 /-- Induction principle for values produced by a `foldl`: if a property holds
 for the seed element `b : β` and for all incremental `op : β → α → β`
 performed on the elements `(a : α) ∈ l`. The principle is given for
 a `Sort`-valued predicate, i.e., it can also be used to construct data. -/
 def foldlRecOn {C : β → Sort*} (l : List α) (op : β → α → β) (b : β) (hb : C b)
     (hl : ∀ (b : β) (_ : C b) (a : α) (_ : a ∈ l), C (op b a)) : C (foldl op b l) := by
-  cases l with
+  induction l generalizing b with
   | nil => exact hb
-  | cons hd tl =>
-    have IH : (b : β) → C b → ((b : β) → C b → (a : α) → a ∈ tl → C (op b a)) → C (foldl op b tl) :=
-      foldlRecOn _ _
+  | cons hd tl IH =>
     refine' IH _ _ _
     · exact hl b hb hd (mem_cons_self hd tl)
     · intro y hy x hx
chore: bump to v4.3.0-rc2 (#8366)

PR contents

This is the supremum of

along with some minor fixes from failures on nightly-testing as Mathlib master is merged into it.

Note that some PRs for changes that are already compatible with the current toolchain and will be necessary have already been split out: #8380.

I am hopeful that in future we will be able to progressively merge adaptation PRs into a bump/v4.X.0 branch, so we never end up with a "big merge" like this. However one of these adaptation PRs (#8056) predates my new scheme for combined CI, and it wasn't possible to keep that PR viable in the meantime.

Lean PRs involved in this bump

In particular this includes adjustments for the Lean PRs

leanprover/lean4#2778

We can get rid of all the

local macro_rules | `($x ^ $y) => `(HPow.hPow $x $y) -- Porting note: See issue [lean4#2220](https://github.com/leanprover/lean4/pull/2220)

macros across Mathlib (and in any projects that want to write natural number powers of reals).

leanprover/lean4#2722

Changes the default behaviour of simp to (config := {decide := false}). This makes simp (and consequentially norm_num) less powerful, but also more consistent, and less likely to blow up in long failures. This requires a variety of changes: changing some previously by simp or norm_num to decide or rfl, or adding (config := {decide := true}).

leanprover/lean4#2783

This changed the behaviour of simp so that simp [f] will only unfold "fully applied" occurrences of f. The old behaviour can be recovered with simp (config := { unfoldPartialApp := true }). We may in future add a syntax for this, e.g. simp [!f]; please provide feedback! In the meantime, we have made the following changes:

  • switching to using explicit lemmas that have the intended level of application
  • (config := { unfoldPartialApp := true }) in some places, to recover the old behaviour
  • Using @[eqns] to manually adjust the equation lemmas for a particular definition, recovering the old behaviour just for that definition. See #8371, where we do this for Function.comp and Function.flip.

This change in Lean may require further changes down the line (e.g. adding the !f syntax, and/or upstreaming the special treatment for Function.comp and Function.flip, and/or removing this special treatment). Please keep an open and skeptical mind about these changes!

Co-authored-by: leanprover-community-mathlib4-bot <leanprover-community-mathlib4-bot@users.noreply.github.com> Co-authored-by: Scott Morrison <scott.morrison@gmail.com> Co-authored-by: Eric Wieser <wieser.eric@gmail.com> Co-authored-by: Mauricio Collares <mauricio@collares.org>

Diff
@@ -1752,7 +1752,9 @@ theorem map_join (f : α → β) (L : List (List α)) : map f (join L) = join (m
 
 theorem bind_ret_eq_map (f : α → β) (l : List α) : l.bind (List.ret ∘ f) = map f l := by
   unfold List.bind
-  induction l <;> simp [map, join, List.ret, cons_append, nil_append, *] at *
+  induction l <;>
+    simp (config := { unfoldPartialApp := true })
+      [map, join, List.ret, cons_append, nil_append, *] at *
   assumption
 #align list.bind_ret_eq_map List.bind_ret_eq_map
 
@@ -2576,7 +2578,7 @@ theorem nthLe_succ_scanl {i : ℕ} {h : i + 1 < (scanl f b l).length} :
   induction i generalizing b l with
   | zero =>
     cases l
-    · simp only [length, zero_add, scanl_nil] at h
+    · simp only [length, zero_eq, lt_self_iff_false] at h
     · simp [scanl_cons, singleton_append, nthLe_zero_scanl, nthLe_cons]
   | succ i hi =>
     cases l
@@ -3334,7 +3336,7 @@ theorem reduceOption_map {l : List (Option α)} {f : α → β} :
     reduceOption (map (Option.map f) l) = map f (reduceOption l) := by
   induction' l with hd tl hl
   · simp only [reduceOption_nil, map_nil]
-  ·cases hd <;>
+  · cases hd <;>
       simpa [true_and_iff, Option.map_some', map, eq_self_iff_true,
         reduceOption_cons_of_some] using hl
 #align list.reduce_option_map List.reduceOption_map
@@ -3346,7 +3348,7 @@ theorem reduceOption_append (l l' : List (Option α)) :
 
 theorem reduceOption_length_le (l : List (Option α)) : l.reduceOption.length ≤ l.length := by
   induction' l with hd tl hl
-  · simp only [reduceOption_nil, length]
+  · simp [reduceOption_nil, length]
   · cases hd
     · exact Nat.le_succ_of_le hl
     · simpa only [length, add_le_add_iff_right, reduceOption_cons_of_some] using hl
chore: remove upstreamed lemmas (#8432)

Co-authored-by: Scott Morrison <scott.morrison@gmail.com>

Diff
@@ -3752,14 +3752,8 @@ end Diff
 
 /-! ### enum -/
 
-theorem length_enumFrom : ∀ (n) (l : List α), length (enumFrom n l) = length l
-  | _, [] => rfl
-  | _, _ :: _ => congr_arg Nat.succ (length_enumFrom _ _)
-#align list.length_enum_from List.length_enumFrom
-
-theorem length_enum : ∀ l : List α, length (enum l) = length l :=
-  length_enumFrom _
-#align list.length_enum List.length_enum
+#align list.length_enum_from List.enumFrom_length
+#align list.length_enum List.enum_length
 
 @[simp]
 theorem enumFrom_get? :
@@ -3876,7 +3870,7 @@ theorem enum_map (l : List α) (f : α → β) : (l.map f).enum = l.enum.map (Pr
 #align list.enum_map List.enum_map
 
 theorem get_enumFrom (l : List α) (n) (i : Fin (l.enumFrom n).length)
-    (hi : i.1 < l.length := (by simpa [length_enumFrom] using i.2)) :
+    (hi : i.1 < l.length := (by simpa using i.2)) :
     (l.enumFrom n).get i = (n + i, l.get ⟨i, hi⟩) := by
   rw [← Option.some_inj, ← get?_eq_get]
   simp [enumFrom_get?, get?_eq_get hi]
@@ -3884,13 +3878,13 @@ theorem get_enumFrom (l : List α) (n) (i : Fin (l.enumFrom n).length)
 set_option linter.deprecated false in
 @[deprecated get_enumFrom]
 theorem nthLe_enumFrom (l : List α) (n i : ℕ) (hi' : i < (l.enumFrom n).length)
-    (hi : i < l.length := (by simpa [length_enumFrom] using hi')) :
+    (hi : i < l.length := (by simpa using hi')) :
     (l.enumFrom n).nthLe i hi' = (n + i, l.nthLe i hi) :=
   get_enumFrom ..
 #align list.nth_le_enum_from List.nthLe_enumFrom
 
 theorem get_enum (l : List α) (i : Fin l.enum.length)
-    (hi : i < l.length := (by simpa [length_enum] using i.2)) :
+    (hi : i < l.length := (by simpa using i.2)) :
     l.enum.get i = (i.1, l.get ⟨i, hi⟩) := by
   convert get_enumFrom _ _ i
   exact (zero_add _).symm
@@ -3898,7 +3892,7 @@ theorem get_enum (l : List α) (i : Fin l.enum.length)
 set_option linter.deprecated false in
 @[deprecated get_enum]
 theorem nthLe_enum (l : List α) (i : ℕ) (hi' : i < l.enum.length)
-    (hi : i < l.length := (by simpa [length_enum] using hi')) :
+    (hi : i < l.length := (by simpa using hi')) :
     l.enum.nthLe i hi' = (i, l.nthLe i hi) := get_enum ..
 #align list.nth_le_enum List.nthLe_enum
 
Diff
@@ -10,7 +10,7 @@ import Mathlib.Init.Core
 import Std.Data.List.Lemmas
 import Mathlib.Tactic.Common
 
-#align_import data.list.basic from "leanprover-community/mathlib"@"9da1b3534b65d9661eb8f42443598a92bbb49211"
+#align_import data.list.basic from "leanprover-community/mathlib"@"65a1391a0106c9204fe45bc73a039f056558cb83"
 
 /-!
 # Basic properties of lists
@@ -2989,6 +2989,9 @@ end ModifyLast
 #align list.pmap List.pmap
 #align list.attach List.attach
 
+@[simp] lemma attach_nil : ([] : List α).attach = [] := rfl
+#align list.attach_nil List.attach_nil
+
 theorem sizeOf_lt_sizeOf_of_mem [SizeOf α] {x : α} {l : List α} (hx : x ∈ l) :
     SizeOf.sizeOf x < SizeOf.sizeOf l := by
   induction' l with h t ih <;> cases hx <;> rw [cons.sizeOf_spec]
@@ -3480,8 +3483,35 @@ theorem monotone_filter_right (l : List α) ⦃p q : α → Bool⦄
 
 #align list.map_filter List.map_filter
 
+lemma map_filter' {f : α → β} (hf : Injective f) (l : List α)
+    [DecidablePred fun b => ∃ a, p a ∧ f a = b] :
+    (l.filter p).map f = (l.map f).filter fun b => ∃ a, p a ∧ f a = b := by
+  simp [(· ∘ ·), map_filter, hf.eq_iff]
+#align list.map_filter' List.map_filter'
+
+lemma filter_attach' (l : List α) (p : {a // a ∈ l} → Bool) [DecidableEq α] :
+    l.attach.filter p =
+      (l.filter fun x => ∃ h, p ⟨x, h⟩).attach.map (Subtype.map id fun x => mem_of_mem_filter) := by
+  classical
+  refine' map_injective_iff.2 Subtype.coe_injective _
+  simp [(· ∘ ·), map_filter' _ Subtype.coe_injective]
+#align list.filter_attach' List.filter_attach'
+
+-- porting note: `Lean.Internal.coeM` forces us to type-ascript `{x // x ∈ l}`
+lemma filter_attach (l : List α) (p : α → Bool) :
+    (l.attach.filter fun x => p x : List {x // x ∈ l}) =
+      (l.filter p).attach.map (Subtype.map id fun x => mem_of_mem_filter) :=
+  map_injective_iff.2 Subtype.coe_injective <| by
+    simp_rw [map_map, (· ∘ ·), Subtype.map, id.def, ←Function.comp_apply (g := Subtype.val),
+      ←map_filter, attach_map_val]
+#align list.filter_attach List.filter_attach
+
 #align list.filter_filter List.filter_filter
 
+lemma filter_comm (q) (l : List α) : filter p (filter q l) = filter q (filter p l) := by
+  simp [and_comm]
+#align list.filter_comm List.filter_comm
+
 @[simp]
 theorem filter_true (l : List α) :
     filter (fun _ => true) l = l := by induction l <;> simp [*, filter]
feat: patch for std4#196 (more min/max lemmas for Nat) (#8074)

Co-authored-by: Scott Morrison <scott.morrison@gmail.com>

Diff
@@ -1888,13 +1888,13 @@ theorem take_take : ∀ (n m) (l : List α), take n (take m l) = take (min n m)
   | 0, m, l => by rw [zero_min, take_zero, take_zero]
   | succ n, succ m, nil => by simp only [take_nil]
   | succ n, succ m, a :: l => by
-    simp only [take, min_succ_succ, take_take n m l]
+    simp only [take, succ_min_succ, take_take n m l]
 #align list.take_take List.take_take
 
 theorem take_replicate (a : α) : ∀ n m : ℕ, take n (replicate m a) = replicate (min n m) a
   | n, 0 => by simp
   | 0, m => by simp
-  | succ n, succ m => by simp [min_succ_succ, take_replicate]
+  | succ n, succ m => by simp [succ_min_succ, take_replicate]
 #align list.take_replicate List.take_replicate
 
 theorem map_take {α β : Type*} (f : α → β) :
@@ -1986,7 +1986,7 @@ theorem take_eq_take :
   | _ :: xs, 0, 0 => by simp
   | x :: xs, m + 1, 0 => by simp
   | x :: xs, 0, n + 1 => by simp [@eq_comm ℕ 0]
-  | x :: xs, m + 1, n + 1 => by simp [Nat.min_succ_succ, take_eq_take]
+  | x :: xs, m + 1, n + 1 => by simp [Nat.succ_min_succ, take_eq_take]
 #align list.take_eq_take List.take_eq_take
 
 theorem take_add (l : List α) (m n : ℕ) : l.take (m + n) = l.take m ++ (l.drop m).take n := by
feat (GroupTheory.Perm.Cycle.PossibleTypes) : cycleTypes of perm (#7433)

Characterize the possible types of permutations: given m : Multiset ℕ, there are permutations in Equiv.Perm α with cycleType m if and only if m.sumis at most Fintype.card α and the members of m are at least 2.

This result will be used in later PR which computes the cardinality of conjugacy classes in Equiv.Perm α and alternatingGroup α

Co-authored-by: Antoine Chambert-Loir <antoine.chambert-loir@math.univ-paris-diderot.fr>

Diff
@@ -4422,4 +4422,36 @@ theorem getI_zero_eq_headI : l.getI 0 = l.headI := by cases l <;> rfl
 
 end getI
 
+section Disjoint
+
+variable {α β : Type*}
+
+/-- The images of disjoint maps under a map are disjoint -/
+theorem disjoint_map {f : α → β} {s t : List α} (hf : Function.Injective f)
+    (h : Disjoint s t) : Disjoint (s.map f) (t.map f) := by
+  simp only [Disjoint]
+  intro b hbs hbt
+  rw [mem_map] at hbs hbt
+  obtain ⟨a, ha, rfl⟩ := hbs
+  apply h ha
+  obtain ⟨a', ha', ha''⟩ := hbt
+  rw [hf ha''.symm]; exact ha'
+
+/-- The images of disjoint lists under a partially defined map are disjoint -/
+theorem disjoint_pmap {p : α → Prop} {f : ∀ a : α, p a → β} {s t : List α}
+    (hs : ∀ a ∈ s, p a) (ht : ∀ a ∈ t, p a)
+    (hf : ∀ (a a' : α) (ha : p a) (ha' : p a'), f a ha = f a' ha' → a = a')
+    (h : Disjoint s t) :
+    Disjoint (s.pmap f hs) (t.pmap f ht) := by
+  simp only [Disjoint]
+  intro b hbs hbt
+  rw [mem_pmap] at hbs hbt
+  obtain ⟨a, ha, rfl⟩ := hbs
+  apply h ha
+  obtain ⟨a', ha', ha''⟩ := hbt
+  rw [hf a a' (hs a ha) (ht a' ha') ha''.symm]
+  exact ha'
+
+end Disjoint
+
 end List
chore: fix whitespace typos (#7950)
Diff
@@ -237,7 +237,7 @@ instance instSingletonList : Singleton α (List α) := ⟨fun x => [x]⟩
 instance [DecidableEq α] : Insert α (List α) := ⟨List.insert⟩
 
 -- ADHOC Porting note: instance from Lean3 core
-instance [DecidableEq α]: IsLawfulSingleton α (List α) :=
+instance [DecidableEq α] : IsLawfulSingleton α (List α) :=
   { insert_emptyc_eq := fun x =>
       show (if x ∈ ([] : List α) then [] else [x]) = [x] from if_neg (not_mem_nil _) }
 
refactor: List.All₂ to List.Forall (#7797)

This renames List.All₂ to List.Forall, because the is highly confusing when it usually means “two lists”, and we had users on Zulip not find List.Forall because of that (https://leanprover.zulipchat.com/#narrow/stream/217875-Is-there-code-for-X.3F/topic/Is.20there.20List.2EForall.E2.82.82.2C.20but.20for.20one.20list.3F.20.28In.20library.20Std.29/near/397551365)

Co-authored-by: Mario Carneiro <di.gama@gmail.com>

Diff
@@ -4160,37 +4160,37 @@ end ZipRight
 #noalign list.to_chunks_join
 #noalign list.to_chunks_length_le
 
-/-! ### all₂ -/
+/-! ### Forall -/
 
-section All₂
+section Forall
 
 variable {p q : α → Prop} {l : List α}
 
 @[simp]
-theorem all₂_cons (p : α → Prop) (x : α) : ∀ l : List α, All₂ p (x :: l) ↔ p x ∧ All₂ p l
+theorem forall_cons (p : α → Prop) (x : α) : ∀ l : List α, Forall p (x :: l) ↔ p x ∧ Forall p l
   | [] => (and_true_iff _).symm
   | _ :: _ => Iff.rfl
-#align list.all₂_cons List.all₂_cons
+#align list.all₂_cons List.forall_cons
 
-theorem all₂_iff_forall : ∀ {l : List α}, All₂ p l ↔ ∀ x ∈ l, p x
+theorem forall_iff_forall_mem : ∀ {l : List α}, Forall p l ↔ ∀ x ∈ l, p x
   | [] => (iff_true_intro <| forall_mem_nil _).symm
-  | x :: l => by rw [forall_mem_cons, all₂_cons, all₂_iff_forall]
-#align list.all₂_iff_forall List.all₂_iff_forall
+  | x :: l => by rw [forall_mem_cons, forall_cons, forall_iff_forall_mem]
+#align list.all₂_iff_forall List.forall_iff_forall_mem
 
-theorem All₂.imp (h : ∀ x, p x → q x) : ∀ {l : List α}, All₂ p l → All₂ q l
+theorem Forall.imp (h : ∀ x, p x → q x) : ∀ {l : List α}, Forall p l → Forall q l
   | [] => id
-  | x :: l => by simp; rw [←and_imp]; exact And.imp (h x) (All₂.imp h)
-#align list.all₂.imp List.All₂.imp
+  | x :: l => by simp; rw [←and_imp]; exact And.imp (h x) (Forall.imp h)
+#align list.all₂.imp List.Forall.imp
 
 @[simp]
-theorem all₂_map_iff {p : β → Prop} (f : α → β) : All₂ p (l.map f) ↔ All₂ (p ∘ f) l := by
+theorem forall_map_iff {p : β → Prop} (f : α → β) : Forall p (l.map f) ↔ Forall (p ∘ f) l := by
   induction l <;> simp [*]
-#align list.all₂_map_iff List.all₂_map_iff
+#align list.all₂_map_iff List.forall_map_iff
 
-instance (p : α → Prop) [DecidablePred p] : DecidablePred (All₂ p) := fun _ =>
-  decidable_of_iff' _ all₂_iff_forall
+instance (p : α → Prop) [DecidablePred p] : DecidablePred (Forall p) := fun _ =>
+  decidable_of_iff' _ forall_iff_forall_mem
 
-end All₂
+end Forall
 
 /-! ### Retroattributes
 
chore: remove nonterminal simp (#7580)

Removes nonterminal simps on lines looking like simp [...]

Diff
@@ -1587,7 +1587,7 @@ theorem insertNth_comm (a b : α) :
   | i + 1, 0, l => fun h => (Nat.not_lt_zero _ h).elim
   | i + 1, j + 1, [] => by simp
   | i + 1, j + 1, c :: l => fun h₀ h₁ => by
-    simp [insertNth]
+    simp only [insertNth_succ_cons, insertNth._eq_1, cons.injEq, true_and]
     exact insertNth_comm a b i j l (Nat.le_of_succ_le_succ h₀) (Nat.le_of_succ_le_succ h₁)
 #align list.insert_nth_comm List.insertNth_comm
 
chore: bump std (#7694)

Some deleted lemmas have been upstreamed to Std.

Note that the statements of List.zipWith_map_left (and _right) have been changed, requiring slight changes here.

Co-authored-by: Scott Morrison <scott.morrison@gmail.com> Co-authored-by: sgouezel <sebastien.gouezel@univ-rennes1.fr>

Diff
@@ -1100,25 +1100,6 @@ theorem indexOf_nil (a : α) : indexOf a [] = 0 :=
   The ported versions of the earlier proofs are given in comments.
 -/
 
--- Porting note: these lemmas recover the Lean 3 definition of `findIdx`
-@[simp] theorem findIdx_nil {α : Type*} (p : α → Bool) :
-  [].findIdx p = 0 := rfl
-
-theorem findIdx_cons (p : α → Bool) (b : α) (l : List α) :
-    (b :: l).findIdx p = bif p b then 0 else (l.findIdx p) + 1 := by
-    cases H : p b with
-      | true => simp [H, findIdx, findIdx.go]
-      | false => simp [H, findIdx, findIdx.go, findIdx_go_succ]
-  where
-    findIdx_go_succ (p : α → Bool) (l : List α) (n : ℕ) :
-        List.findIdx.go p l (n + 1) = (List.findIdx.go p l n) + 1 := by
-      cases l with
-      | nil => unfold List.findIdx.go; exact Nat.succ_eq_add_one n
-      | cons head tail =>
-        unfold List.findIdx.go
-        cases p head <;> simp only [cond_false, cond_true]
-        exact findIdx_go_succ p tail (n + 1)
-
 -- indexOf_cons_eq _ rfl
 @[simp]
 theorem indexOf_cons_self (a : α) (l : List α) : indexOf a (a :: l) = 0 := by
feat: add lemma List.getD_map (#7307)

Adds a lemma, analogous to Option.getD_map, but for List.

Also fixes a few nearby lemmas to use induction/cases instead of induction'/cases'

Co-authored-by: GitHub Copilot

Diff
@@ -4311,11 +4311,21 @@ theorem getD_cons_succ : getD (x :: xs) (n + 1) d = getD xs n d :=
 #align list.nthd_cons_succ List.getD_cons_succₓ -- argument order
 
 theorem getD_eq_get {n : ℕ} (hn : n < l.length) : l.getD n d = l.get ⟨n, hn⟩ := by
-  induction' l with hd tl IH generalizing n
-  · exact absurd hn (not_lt_of_ge (Nat.zero_le _))
-  · cases n
+  induction l generalizing n with
+  | nil => exact absurd hn (not_lt_of_ge (Nat.zero_le _))
+  | cons head tail ih =>
+    cases n
     · exact getD_cons_zero _ _ _
-    · exact IH _
+    · exact ih _
+
+@[simp]
+theorem getD_map {n : ℕ} (f : α → β) : (map f l).getD n (f d) = f (l.getD n d) := by
+  induction l generalizing n with
+  | nil => rfl
+  | cons head tail ih =>
+    cases n
+    · rfl
+    · simp [ih]
 
 set_option linter.deprecated false in
 @[deprecated getD_eq_get]
@@ -4324,11 +4334,12 @@ theorem getD_eq_nthLe {n : ℕ} (hn : n < l.length) : l.getD n d = l.nthLe n hn
 #align list.nthd_eq_nth_le List.getD_eq_nthLeₓ -- argument order
 
 theorem getD_eq_default {n : ℕ} (hn : l.length ≤ n) : l.getD n d = d := by
-  induction' l with hd tl IH generalizing n
-  · exact getD_nil _ _
-  · cases n
+  induction l generalizing n with
+  | nil => exact getD_nil _ _
+  | cons head tail ih =>
+    cases n
     · refine' absurd (Nat.zero_lt_succ _) (not_lt_of_ge hn)
-    · exact IH (Nat.le_of_succ_le_succ hn)
+    · exact ih (Nat.le_of_succ_le_succ hn)
 #align list.nthd_eq_default List.getD_eq_defaultₓ -- argument order
 
 /-- An empty list can always be decidably checked for the presence of an element.
@@ -4343,9 +4354,9 @@ theorem getD_singleton_default_eq (n : ℕ) : [d].getD n d = d := by cases n <;>
 
 @[simp]
 theorem getD_replicate_default_eq (r n : ℕ) : (replicate r d).getD n d = d := by
-  induction' r with r IH generalizing n
-  · simp
-  · cases n <;> simp [IH]
+  induction r generalizing n with
+  | zero => simp
+  | succ n ih => cases n <;> simp [ih]
 #align list.nthd_replicate_default_eq List.getD_replicate_default_eqₓ -- argument order
 
 theorem getD_append (l l' : List α) (d : α) (n : ℕ) (h : n < l.length)
@@ -4356,19 +4367,21 @@ theorem getD_append (l l' : List α) (d : α) (n : ℕ) (h : n < l.length)
 
 theorem getD_append_right (l l' : List α) (d : α) (n : ℕ) (h : l.length ≤ n) :
     (l ++ l').getD n d = l'.getD (n - l.length) d := by
-  cases' lt_or_le n (l ++l').length with h' h'
-  · rw [getD_eq_get (l ++ l') d h', get_append_right, getD_eq_get]
+  cases lt_or_le n (l ++l').length with
+  | inl h' =>
+    rw [getD_eq_get (l ++ l') d h', get_append_right, getD_eq_get]
     · rw [length_append] at h'
       exact Nat.sub_lt_left_of_lt_add h h'
     · exact not_lt_of_le h
-  · rw [getD_eq_default _ _ h', getD_eq_default]
+  | inr h' =>
+    rw [getD_eq_default _ _ h', getD_eq_default]
     rwa [le_tsub_iff_left h, ← length_append]
 #align list.nthd_append_right List.getD_append_rightₓ -- argument order
 
 theorem getD_eq_getD_get? (n : ℕ) : l.getD n d = (l.get? n).getD d := by
-  cases' lt_or_le n l.length with h h
-  · rw [getD_eq_get _ _ h, get?_eq_get h, Option.getD_some]
-  · rw [getD_eq_default _ _ h, get?_eq_none.mpr h, Option.getD_none]
+  cases lt_or_le n l.length with
+  | inl h => rw [getD_eq_get _ _ h, get?_eq_get h, Option.getD_some]
+  | inr h => rw [getD_eq_default _ _ h, get?_eq_none.mpr h, Option.getD_none]
 #align list.nthd_eq_get_or_else_nth List.getD_eq_getD_get?ₓ -- argument order
 
 end getD
chore: cleanup some spaces (#7484)

Purely cosmetic PR.

Diff
@@ -1242,7 +1242,7 @@ theorem get?_injective {α : Type u} {xs : List α} {i j : ℕ} (h₀ : i < xs.l
     case succ.succ =>
       congr; cases h₁
       apply tail_ih <;> solve_by_elim [lt_of_succ_lt_succ]
-    all_goals ( dsimp at h₂; cases' h₁ with _ _ h h')
+    all_goals (dsimp at h₂; cases' h₁ with _ _ h h')
     · cases (h x (mem_iff_get?.mpr ⟨_, h₂.symm⟩) rfl)
     · cases (h x (mem_iff_get?.mpr ⟨_, h₂⟩) rfl)
 #align list.nth_injective List.get?_injective
feat: some lemmas about List and ZMod (#7424)

Co-authored-by: Alex J Best <alex.j.best@gmail.com>

Diff
@@ -2061,6 +2061,7 @@ theorem drop_eq_nil_iff_le {l : List α} {k : ℕ} : l.drop k = [] ↔ l.length
       simpa [Nat.succ_le_succ_iff] using hk h
 #align list.drop_eq_nil_iff_le List.drop_eq_nil_iff_le
 
+@[simp]
 theorem tail_drop (l : List α) (n : ℕ) : (l.drop n).tail = l.drop (n + 1) := by
   induction' l with hd tl hl generalizing n
   · simp
@@ -2069,6 +2070,10 @@ theorem tail_drop (l : List α) (n : ℕ) : (l.drop n).tail = l.drop (n + 1) :=
     · simp [hl]
 #align list.tail_drop List.tail_drop
 
+@[simp]
+theorem drop_tail (l : List α) (n : ℕ) : l.tail.drop n = l.drop (n + 1) := by
+  induction' l <;> simp
+
 theorem cons_get_drop_succ {l : List α} {n} :
     l.get n :: l.drop (n.1 + 1) = l.drop n.1 := by
   induction' l with hd tl hl
feat: add some List.takeWhile lemmas (#7397)

Co-authored-by: Scott Morrison <scott@tqft.net>

Diff
@@ -3542,20 +3542,36 @@ theorem dropWhile_eq_nil_iff : dropWhile p l = [] ↔ ∀ x ∈ l, p x := by
   · by_cases hp : p x <;> simp [hp, dropWhile, IH]
 #align list.drop_while_eq_nil_iff List.dropWhile_eq_nil_iff
 
+@[simp] theorem takeWhile_nil : List.takeWhile p [] = [] := rfl
+
+theorem takeWhile_cons {x : α} :
+    List.takeWhile p (x :: l) = (match p x with
+      | true  => x :: takeWhile p l
+      | false => []) :=
+  rfl
+
+theorem takeWhile_cons_of_pos {x : α} (h : p x) :
+    List.takeWhile p (x :: l) = x :: takeWhile p l := by
+  simp [takeWhile_cons, h]
+
+theorem takeWhile_cons_of_neg {x : α} (h : ¬ p x) :
+    List.takeWhile p (x :: l) = [] := by
+  simp [takeWhile_cons, h]
+
 @[simp]
 theorem takeWhile_eq_self_iff : takeWhile p l = l ↔ ∀ x ∈ l, p x := by
   induction' l with x xs IH
-  · simp [takeWhile]
-  · by_cases hp : p x <;> simp [hp, takeWhile, IH]
+  · simp
+  · by_cases hp : p x <;> simp [hp, takeWhile_cons, IH]
 #align list.take_while_eq_self_iff List.takeWhile_eq_self_iff
 
 @[simp]
 theorem takeWhile_eq_nil_iff : takeWhile p l = [] ↔ ∀ hl : 0 < l.length, ¬p (l.nthLe 0 hl) := by
   induction' l with x xs IH
-  · simp [takeWhile, true_iff]
+  · simp only [takeWhile_nil, Bool.not_eq_true, true_iff]
     intro h
     simp at h
-  · by_cases hp : p x <;> simp [hp, takeWhile, IH, nthLe_cons]
+  · by_cases hp : p x <;> simp [hp, takeWhile_cons, IH, nthLe_cons]
 #align list.take_while_eq_nil_iff List.takeWhile_eq_nil_iff
 
 theorem mem_takeWhile_imp {x : α} (hx : x ∈ takeWhile p l) : p x := by
@@ -3572,7 +3588,7 @@ theorem mem_takeWhile_imp {x : α} (hx : x ∈ takeWhile p l) : p x := by
 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 hd tl IH
-  · simp [takeWhile]
+  · simp
   · by_cases hp : p hd <;> by_cases hq : q hd <;> simp [takeWhile, hp, hq, IH]
 #align list.take_while_take_while List.takeWhile_takeWhile
 
chore: exactly 4 spaces in theorems (#7328)

Co-authored-by: Moritz Firsching <firsching@google.com>

Diff
@@ -320,7 +320,7 @@ theorem subset_append_of_subset_right' (l l₁ l₂ : List α) : l ⊆ l₂ →
 #align list.cons_subset List.cons_subset
 
 theorem cons_subset_of_subset_of_mem {a : α} {l m : List α}
-  (ainm : a ∈ m) (lsubm : l ⊆ m) : a::l ⊆ m :=
+    (ainm : a ∈ m) (lsubm : l ⊆ m) : a::l ⊆ m :=
   cons_subset.2 ⟨ainm, lsubm⟩
 #align list.cons_subset_of_subset_of_mem List.cons_subset_of_subset_of_mem
 
chore: bump to std#260 (#7134)

Co-authored-by: Scott Morrison <scott.morrison@gmail.com> Co-authored-by: Alex Keizer <alex@keizer.dev>

Diff
@@ -651,10 +651,6 @@ theorem length_dropLast : ∀ l : List α, length l.dropLast = length l - 1
     simp
 #align list.length_init List.length_dropLast
 
--- Porting note: `rw [dropLast]` in Lean4 generates a goal `(b::l) ≠ []`
--- so we use this lemma instead
-theorem dropLast_cons_cons (a b : α) (l : List α) : dropLast (a::b::l) = a::dropLast (b::l) := rfl
-
 /-! ### getLast -/
 
 @[simp]
@@ -699,7 +695,7 @@ theorem dropLast_append_getLast : ∀ {l : List α} (h : l ≠ []), dropLast l +
   | [], h => absurd rfl h
   | [a], h => rfl
   | a :: b :: l, h => by
-    rw [dropLast_cons_cons, cons_append, getLast_cons (cons_ne_nil _ _)]
+    rw [dropLast_cons₂, cons_append, getLast_cons (cons_ne_nil _ _)]
     congr
     exact dropLast_append_getLast (cons_ne_nil b l)
 #align list.init_append_last List.dropLast_append_getLast
@@ -782,7 +778,7 @@ theorem dropLast_append_getLast? : ∀ {l : List α}, ∀ a ∈ l.getLast?, drop
   | [a], _, rfl => rfl
   | a :: b :: l, c, hc => by
     rw [getLast?_cons_cons] at hc
-    rw [dropLast_cons_cons, cons_append, dropLast_append_getLast? _ hc]
+    rw [dropLast_cons₂, cons_append, dropLast_append_getLast? _ hc]
 #align list.init_append_last' List.dropLast_append_getLast?
 
 theorem getLastI_eq_getLast? [Inhabited α] : ∀ l : List α, l.getLastI = l.getLast?.iget
@@ -1877,9 +1873,6 @@ theorem zipWith_flip (f : α → β → γ) : ∀ as bs, zipWith (flip f) bs as
 
 /-! ### take, drop -/
 
-@[simp]
-theorem take_zero (l : List α) : take 0 l = [] :=
-  rfl
 #align list.take_zero List.take_zero
 
 #align list.take_nil List.take_nil
@@ -2043,7 +2036,7 @@ theorem dropLast_take {n : ℕ} {l : List α} (h : n < l.length) :
 #align list.init_take List.dropLast_take
 
 theorem dropLast_cons_of_ne_nil {α : Type*} {x : α}
-    {l : List α} (h : l ≠ []) : (x :: l).dropLast = x :: l.dropLast := by simp [h]
+    {l : List α} (h : l ≠ []) : (x :: l).dropLast = x :: l.dropLast := by simp [h, dropLast]
 #align list.init_cons_of_ne_nil List.dropLast_cons_of_ne_nil
 
 @[simp]
@@ -2343,26 +2336,9 @@ theorem foldr_ext (f g : α → β → β) (b : β) {l : List α} (H : ∀ a ∈
   simp only [foldr, ih H.2, H.1]
 #align list.foldr_ext List.foldr_ext
 
-@[simp]
-theorem foldl_nil (f : α → β → α) (a : α) : foldl f a [] = a :=
-  rfl
 #align list.foldl_nil List.foldl_nil
-
-@[simp]
-theorem foldl_cons (f : α → β → α) (a : α) (b : β) (l : List β) :
-    foldl f a (b :: l) = foldl f (f a b) l :=
-  rfl
 #align list.foldl_cons List.foldl_cons
-
-@[simp]
-theorem foldr_nil (f : α → β → β) (b : β) : foldr f b [] = b :=
-  rfl
 #align list.foldr_nil List.foldr_nil
-
-@[simp]
-theorem foldr_cons (f : α → β → β) (b : β) (a : α) (l : List α) :
-    foldr f b (a :: l) = f a (foldr f b l) :=
-  rfl
 #align list.foldr_cons List.foldr_cons
 
 #align list.foldl_append List.foldl_append
@@ -2748,18 +2724,9 @@ section FoldlMFoldrM
 
 variable {m : Type v → Type w} [Monad m]
 
-@[simp]
-theorem foldlM_nil (f : β → α → m β) {b} : List.foldlM f b [] = pure b :=
-  rfl
 #align list.mfoldl_nil List.foldlM_nil
-
 -- Porting note: now in std
 #align list.mfoldr_nil List.foldrM_nil
-
-@[simp]
-theorem foldlM_cons {f : β → α → m β} {b a l} :
-    List.foldlM f b (a :: l) = f b a >>= fun b' => List.foldlM f b' l :=
-  rfl
 #align list.mfoldl_cons List.foldlM_cons
 
 /- Porting note: now in std; now assumes an instance of `LawfulMonad m`, so we make everything
@@ -2795,9 +2762,6 @@ end FoldlMFoldrM
 
 /-! ### intersperse -/
 
-@[simp]
-theorem intersperse_nil {α : Type u} (a : α) : intersperse a [] = [] :=
-  rfl
 #align list.intersperse_nil List.intersperse_nil
 
 @[simp]
@@ -3195,18 +3159,13 @@ section find?
 
 variable {p : α → Bool} {l : List α} {a : α}
 
-@[simp]
-theorem find?_nil (p : α → Bool) : find? p [] = none :=
-  rfl
 #align list.find_nil List.find?_nil
 
--- Porting note: List.find? is given @[simp] in Std.Data.List.Init.Lemmas
 -- @[simp]
 -- Later porting note (at time of this lemma moving to Std): removing attribute `nolint simpNF`
 attribute [simp 1100] find?_cons_of_pos
 #align list.find_cons_of_pos List.find?_cons_of_pos
 
--- Porting note: List.find? is given @[simp] in Std.Data.List.Init.Lemmas
 -- @[simp]
 -- Later porting note (at time of this lemma moving to Std): removing attribute `nolint simpNF`
 attribute [simp 1100] find?_cons_of_neg
@@ -3818,15 +3777,8 @@ theorem enum_nil : enum ([] : List α) = [] :=
   rfl
 #align list.enum_nil List.enum_nil
 
-@[simp]
-theorem enumFrom_nil (n : ℕ) : enumFrom n ([] : List α) = [] :=
-  rfl
 #align list.enum_from_nil List.enumFrom_nil
 
-@[simp]
-theorem enumFrom_cons (x : α) (xs : List α) (n : ℕ) :
-    enumFrom n (x :: xs) = (n, x) :: enumFrom (n + 1) xs :=
-  rfl
 #align list.enum_from_cons List.enumFrom_cons
 
 @[simp]
chore: tidy various files (#7343)
Diff
@@ -321,12 +321,12 @@ theorem subset_append_of_subset_right' (l l₁ l₂ : List α) : l ⊆ l₂ →
 
 theorem cons_subset_of_subset_of_mem {a : α} {l m : List α}
   (ainm : a ∈ m) (lsubm : l ⊆ m) : a::l ⊆ m :=
-cons_subset.2 ⟨ainm, lsubm⟩
+  cons_subset.2 ⟨ainm, lsubm⟩
 #align list.cons_subset_of_subset_of_mem List.cons_subset_of_subset_of_mem
 
 theorem append_subset_of_subset_of_subset {l₁ l₂ l : List α} (l₁subl : l₁ ⊆ l) (l₂subl : l₂ ⊆ l) :
     l₁ ++ l₂ ⊆ l :=
-fun _ h ↦ (mem_append.1 h).elim (@l₁subl _) (@l₂subl _)
+  fun _ h ↦ (mem_append.1 h).elim (@l₁subl _) (@l₂subl _)
 #align list.append_subset_of_subset_of_subset List.append_subset_of_subset_of_subset
 
 -- Porting note: in Std
chore: only four spaces for subsequent lines (#7286)

Co-authored-by: Moritz Firsching <firsching@google.com>

Diff
@@ -325,7 +325,7 @@ cons_subset.2 ⟨ainm, lsubm⟩
 #align list.cons_subset_of_subset_of_mem List.cons_subset_of_subset_of_mem
 
 theorem append_subset_of_subset_of_subset {l₁ l₂ l : List α} (l₁subl : l₁ ⊆ l) (l₂subl : l₂ ⊆ l) :
-  l₁ ++ l₂ ⊆ l :=
+    l₁ ++ l₂ ⊆ l :=
 fun _ h ↦ (mem_append.1 h).elim (@l₁subl _) (@l₂subl _)
 #align list.append_subset_of_subset_of_subset List.append_subset_of_subset_of_subset
 
@@ -3549,7 +3549,7 @@ theorem filter_false (l : List α) :
 
 /- Porting note: need a helper theorem for span.loop. -/
 theorem span.loop_eq_take_drop :
-  ∀ l₁ l₂ : List α, span.loop p l₁ l₂ = (l₂.reverse ++ takeWhile p l₁, dropWhile p l₁)
+    ∀ l₁ l₂ : List α, span.loop p l₁ l₂ = (l₂.reverse ++ takeWhile p l₁, dropWhile p l₁)
   | [], l₂ => by simp [span.loop, takeWhile, dropWhile]
   | (a :: l), l₂ => by
     cases hp : p a <;> simp [hp, span.loop, span.loop_eq_take_drop, takeWhile, dropWhile]
chore: update to std4#100 (#6743)

Std bump patch for https://github.com/leanprover/std4/pull/100

Co-authored-by: Scott Morrison <scott.morrison@gmail.com>

Diff
@@ -2132,17 +2132,8 @@ theorem drop_length_cons {l : List α} (h : l ≠ []) (a : α) :
     exact ih h₁ y
 #align list.drop_length_cons List.drop_length_cons
 
-/-- 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. -/
-theorem drop_append_eq_append_drop {l₁ l₂ : List α} {n : ℕ} :
-    drop n (l₁ ++ l₂) = drop n l₁ ++ drop (n - l₁.length) l₂ := by
-  induction l₁ generalizing n; · simp
-  cases n <;> simp [*]
 #align list.drop_append_eq_append_drop List.drop_append_eq_append_drop
 
-theorem drop_append_of_le_length {l₁ l₂ : List α} {n : ℕ} (h : n ≤ l₁.length) :
-    (l₁ ++ l₂).drop n = l₁.drop n ++ l₂ := by
-  simp [drop_append_eq_append_drop, tsub_eq_zero_iff_le.mpr h]
 #align list.drop_append_of_le_length List.drop_append_of_le_length
 
 /-- Dropping the elements up to `l₁.length + i` in `l₁ + l₂` is the same as dropping the elements
chore: avoid lean3 style have/suffices (#6964)

Many proofs use the "stream of consciousness" style from Lean 3, rather than have ... := or suffices ... from/by.

This PR updates a fraction of these to the preferred Lean 4 style.

I think a good goal would be to delete the "deferred" versions of have, suffices, and let at the bottom of Mathlib.Tactic.Have

(Anyone who would like to contribute more cleanup is welcome to push directly to this branch.)

Co-authored-by: Scott Morrison <scott.morrison@gmail.com>

Diff
@@ -2788,7 +2788,7 @@ theorem foldlM_eq_foldl (f : β → α → m β) (b l) :
     List.foldlM f b l = foldl (fun mb a => mb >>= fun b => f b a) (pure b) l := by
   suffices h :
     ∀ mb : m β, (mb >>= fun b => List.foldlM f b l) = foldl (fun mb a => mb >>= fun b => f b a) mb l
-  · simp [← h (pure b)]
+    by simp [← h (pure b)]
   induction l with
   | nil => intro; simp
   | cons _ _ l_ih => intro; simp only [List.foldlM, foldl, ←l_ih, functor_norm]
chore: delay import of Tactic.Common (#7000)

I know that this is contrary to what we've done previously, but:

  • I'm trying to upstream a great many tactics from Mathlib to Std (essentially, everything that non-mathematicians want too).
  • This makes it much easier for me to see what is going on, and understand the import requirements (particularly for the "big" tactics norm_num / ring / linarith)
  • It's actually not as bad as it looks here, because as these tactics move up to Std they will start disappearing again from explicit imports, but Mathlib can happily import all of Std.

(Oh

Co-authored-by: Scott Morrison <scott.morrison@gmail.com>

Diff
@@ -8,6 +8,7 @@ import Mathlib.Data.Nat.Order.Basic
 import Mathlib.Data.List.Defs
 import Mathlib.Init.Core
 import Std.Data.List.Lemmas
+import Mathlib.Tactic.Common
 
 #align_import data.list.basic from "leanprover-community/mathlib"@"9da1b3534b65d9661eb8f42443598a92bbb49211"
 
feat: List.head_mem (#6801)
Diff
@@ -822,12 +822,12 @@ theorem getLast?_append {l₁ l₂ : List α} {x : α} (h : x ∈ l₂.getLast?)
 theorem head!_eq_head? [Inhabited α] (l : List α) : head! l = (head? l).iget := by cases l <;> rfl
 #align list.head_eq_head' List.head!_eq_head?
 
-theorem surjective_head [Inhabited α] : Surjective (@head! α _) := fun x => ⟨[x], rfl⟩
-#align list.surjective_head List.surjective_head
+theorem surjective_head! [Inhabited α] : Surjective (@head! α _) := fun x => ⟨[x], rfl⟩
+#align list.surjective_head List.surjective_head!
 
-theorem surjective_head' : Surjective (@head? α) :=
+theorem surjective_head? : Surjective (@head? α) :=
   Option.forall.2 ⟨⟨[], rfl⟩, fun x => ⟨[x], rfl⟩⟩
-#align list.surjective_head' List.surjective_head'
+#align list.surjective_head' List.surjective_head?
 
 theorem surjective_tail : Surjective (@tail α)
   | [] => ⟨[], rfl⟩
@@ -891,6 +891,9 @@ theorem head!_mem_self [Inhabited α] {l : List α} (h : l ≠ nil) : l.head! 
   rwa [cons_head!_tail h] at h'
 #align list.head_mem_self List.head!_mem_self
 
+theorem head_mem {l : List α} : ∀ (h : l ≠ nil), l.head h ∈ l := by
+  cases l <;> simp
+
 @[simp]
 theorem head?_map (f : α → β) (l) : head? (map f l) = (head? l).map f := by cases l <;> rfl
 #align list.head'_map List.head?_map
feat(Data/List/Basic): mem_doubleton (#6756)
Diff
@@ -23,9 +23,9 @@ assert_not_exists Set.range
 
 namespace List
 
-universe u v w x
+universe u v w
 
-variable {ι : Type*} {α : Type u} {β : Type v} {γ : Type w} {δ : Type x} {l₁ l₂ : List α}
+variable {ι : Type*} {α : Type u} {β : Type v} {γ : Type w} {l₁ l₂ : List α}
 
 -- Porting note: Delete this attribute
 -- attribute [inline] List.head!
@@ -96,6 +96,9 @@ theorem _root_.Decidable.List.eq_or_ne_mem_of_mem [DecidableEq α]
 
 #align list.ne_nil_of_mem List.ne_nil_of_mem
 
+lemma mem_pair {a b c : α} : a ∈ [b, c] ↔ a = b ∨ a = c := by
+  rw [mem_cons, mem_singleton]
+
 theorem mem_split {a : α} {l : List α} (h : a ∈ l) : ∃ s t : List α, l = s ++ a :: t := by
   induction' l with b l ih; {cases h}; rcases h with (_ | ⟨_, h⟩)
   · exact ⟨[], l, rfl⟩
feat: patch for new alias command (#6172)
Diff
@@ -177,7 +177,7 @@ theorem map_bind (g : β → List γ) (f : α → β) :
 
 #align list.length_pos_iff_exists_mem List.length_pos_iff_exists_mem
 
-alias length_pos ↔ ne_nil_of_length_pos length_pos_of_ne_nil
+alias ⟨ne_nil_of_length_pos, length_pos_of_ne_nil⟩ := length_pos
 #align list.ne_nil_of_length_pos List.ne_nil_of_length_pos
 #align list.length_pos_of_ne_nil List.length_pos_of_ne_nil
 
@@ -328,7 +328,7 @@ fun _ h ↦ (mem_append.1 h).elim (@l₁subl _) (@l₂subl _)
 -- Porting note: in Std
 #align list.append_subset_iff List.append_subset
 
-alias subset_nil ↔ eq_nil_of_subset_nil _
+alias ⟨eq_nil_of_subset_nil, _⟩ := subset_nil
 #align list.eq_nil_of_subset_nil List.eq_nil_of_subset_nil
 
 #align list.eq_nil_iff_forall_not_mem List.eq_nil_iff_forall_not_mem
@@ -1038,7 +1038,7 @@ theorem eq_nil_of_sublist_nil {l : List α} (s : l <+ []) : l = [] :=
 #align list.eq_nil_of_sublist_nil List.eq_nil_of_sublist_nil
 
 -- Porting note: this lemma seems to have been renamed on the occasion of its move to Std4
-alias sublist_nil ← sublist_nil_iff_eq_nil
+alias sublist_nil_iff_eq_nil := sublist_nil
 #align list.sublist_nil_iff_eq_nil List.sublist_nil_iff_eq_nil
 
 #align list.replicate_sublist_replicate List.replicate_sublist_replicate
feat(Data/List/Basic): remove bind_append (#6599)

This removes bind_append, since an identical append_bind is already in std.

Co-authored-by: Moritz Firsching <firsching@google.com>

Diff
@@ -499,11 +499,7 @@ theorem bind_eq_bind {α β} (f : α → List β) (l : List α) : l >>= f = l.bi
   rfl
 #align list.bind_eq_bind List.bind_eq_bind
 
--- TODO: duplicate of a lemma in core
-theorem bind_append (f : α → List β) (l₁ l₂ : List α) :
-    (l₁ ++ l₂).bind f = l₁.bind f ++ l₂.bind f :=
-  append_bind _ _ _
-#align list.bind_append List.bind_append
+#align list.bind_append List.append_bind
 
 /-! ### concat -/
 
chore: adjust priorities of mem_map lemmas (#6327)

The mem_map lemmas were inconsistently either not simp lemmas at all, simp lemmas, or simp lemmas with a lowered priority.

This PR makes them uniformly low priority simp lemmas, and adds a few simp attributes to "better" simp lemmas instead. (However these lemmas are themselves quite inconsistent across different algebraic structures, and I haven't attempted to add missing ones.)

Co-authored-by: Scott Morrison <scott.morrison@gmail.com>

Diff
@@ -119,6 +119,10 @@ theorem mem_split {a : α} {l : List α} (h : a ∈ l) : ∃ s t : List α, l =
 
 #align list.mem_map_of_mem List.mem_map_of_memₓ -- implicits order
 
+-- The simpNF linter says that the LHS can be simplified via `List.mem_map`.
+-- However this is a higher priority lemma.
+-- https://github.com/leanprover/std4/issues/207
+@[simp 1100, nolint simpNF]
 theorem mem_map_of_injective {f : α → β} (H : Injective f) {a : α} {l : List α} :
     f a ∈ map f l ↔ a ∈ l :=
   ⟨fun m => let ⟨_, m', e⟩ := exists_of_mem_map m; H e ▸ m', mem_map_of_mem _⟩
chore: banish Type _ and Sort _ (#6499)

We remove all possible occurences of Type _ and Sort _ in favor of Type* and Sort*.

This has nice performance benefits.

Diff
@@ -25,7 +25,7 @@ namespace List
 
 universe u v w x
 
-variable {ι : Type _} {α : Type u} {β : Type v} {γ : Type w} {δ : Type x} {l₁ l₂ : List α}
+variable {ι : Type*} {α : Type u} {β : Type v} {γ : Type w} {δ : Type x} {l₁ l₂ : List α}
 
 -- Porting note: Delete this attribute
 -- attribute [inline] List.head!
@@ -948,7 +948,7 @@ theorem modifyHead_modifyHead (l : List α) (f g : α → α) :
 for `l ++ [a]` if it holds for `l`, then it holds for all lists. The principle is given for
 a `Sort`-valued predicate, i.e., it can also be used to construct data. -/
 @[elab_as_elim]
-def reverseRecOn {C : List α → Sort _} (l : List α) (H0 : C [])
+def reverseRecOn {C : List α → Sort*} (l : List α) (H0 : C [])
     (H1 : ∀ (l : List α) (a : α), C l → C (l ++ [a])) : C l := by
   rw [← reverse_reverse l]
   match h:(reverse l) with
@@ -967,7 +967,7 @@ termination_by _ _ l _ _ => l.length
 singleton list, and `a :: (l ++ [b])` from `l`, then it holds for all lists. This can be used to
 prove statements about palindromes. The principle is given for a `Sort`-valued predicate, i.e., it
 can also be used to construct data. -/
-def bidirectionalRec {C : List α → Sort _} (H0 : C []) (H1 : ∀ a : α, C [a])
+def bidirectionalRec {C : List α → Sort*} (H0 : C []) (H1 : ∀ a : α, C [a])
     (Hn : ∀ (a : α) (l : List α) (b : α), C l → C (a :: (l ++ [b]))) : ∀ l, C l
   | [] => H0
   | [a] => H1 a
@@ -982,7 +982,7 @@ termination_by _ l => l.length
 
 /-- Like `bidirectionalRec`, but with the list parameter placed first. -/
 @[elab_as_elim]
-def bidirectionalRecOn {C : List α → Sort _} (l : List α) (H0 : C []) (H1 : ∀ a : α, C [a])
+def bidirectionalRecOn {C : List α → Sort*} (l : List α) (H0 : C []) (H1 : ∀ a : α, C [a])
     (Hn : ∀ (a : α) (l : List α) (b : α), C l → C (a :: (l ++ [b]))) : C l :=
   bidirectionalRec H0 H1 Hn l
 #align list.bidirectional_rec_on List.bidirectionalRecOn
@@ -1098,7 +1098,7 @@ theorem indexOf_nil (a : α) : indexOf a [] = 0 :=
 -/
 
 -- Porting note: these lemmas recover the Lean 3 definition of `findIdx`
-@[simp] theorem findIdx_nil {α : Type _} (p : α → Bool) :
+@[simp] theorem findIdx_nil {α : Type*} (p : α → Bool) :
   [].findIdx p = 0 := rfl
 
 theorem findIdx_cons (p : α → Bool) (b : α) (l : List α) :
@@ -1916,7 +1916,7 @@ theorem take_replicate (a : α) : ∀ n m : ℕ, take n (replicate m a) = replic
   | succ n, succ m => by simp [min_succ_succ, take_replicate]
 #align list.take_replicate List.take_replicate
 
-theorem map_take {α β : Type _} (f : α → β) :
+theorem map_take {α β : Type*} (f : α → β) :
     ∀ (L : List α) (i : ℕ), (L.take i).map f = (L.map f).take i
   | [], i => by simp
   | _, 0 => by simp
@@ -2035,12 +2035,12 @@ theorem dropLast_take {n : ℕ} {l : List α} (h : n < l.length) :
   simp [dropLast_eq_take, min_eq_left_of_lt h, take_take, pred_le]
 #align list.init_take List.dropLast_take
 
-theorem dropLast_cons_of_ne_nil {α : Type _} {x : α}
+theorem dropLast_cons_of_ne_nil {α : Type*} {x : α}
     {l : List α} (h : l ≠ []) : (x :: l).dropLast = x :: l.dropLast := by simp [h]
 #align list.init_cons_of_ne_nil List.dropLast_cons_of_ne_nil
 
 @[simp]
-theorem dropLast_append_of_ne_nil {α : Type _} {l : List α} :
+theorem dropLast_append_of_ne_nil {α : Type*} {l : List α} :
     ∀ (l' : List α) (_ : l ≠ []), (l' ++ l).dropLast = l' ++ l.dropLast
   | [], _ => by simp only [nil_append]
   | a :: l', h => by
@@ -2217,7 +2217,7 @@ theorem drop_take : ∀ (m : ℕ) (n : ℕ) (l : List α), drop m (take (m + n)
     simpa [take_cons, h] using drop_take m n l
 #align list.drop_take List.drop_take
 
-theorem map_drop {α β : Type _} (f : α → β) :
+theorem map_drop {α β : Type*} (f : α → β) :
     ∀ (L : List α) (i : ℕ), (L.drop i).map f = (L.map f).drop i
   | [], i => by simp
   | L, 0 => by simp
@@ -2469,7 +2469,7 @@ theorem foldr_hom₂ (l : List ι) (f : α → β → γ) (op₁ : ι → α →
   induction l <;> intros <;> [rfl; simp only [*, foldr]]
 #align list.foldr_hom₂ List.foldr_hom₂
 
-theorem injective_foldl_comp {α : Type _} {l : List (α → α)} {f : α → α}
+theorem injective_foldl_comp {α : Type*} {l : List (α → α)} {f : α → α}
     (hl : ∀ f ∈ l, Function.Injective f) (hf : Function.Injective f) :
     Function.Injective (@List.foldl (α → α) (α → α) Function.comp f l) := by
   induction' l with lh lt l_ih generalizing f
@@ -2494,7 +2494,7 @@ theorem injective_foldl_comp {α : Type _} {l : List (α → α)} {f : α → α
 for the seed element `b : β` and for all incremental `op : α → β → β`
 performed on the elements `(a : α) ∈ l`. The principle is given for
 a `Sort`-valued predicate, i.e., it can also be used to construct data. -/
-def foldrRecOn {C : β → Sort _} (l : List α) (op : α → β → β) (b : β) (hb : C b)
+def foldrRecOn {C : β → Sort*} (l : List α) (op : α → β → β) (b : β) (hb : C b)
     (hl : ∀ (b : β) (_ : C b) (a : α) (_ : a ∈ l), C (op a b)) : C (foldr op b l) := by
   cases l with
   | nil => exact hb
@@ -2522,7 +2522,7 @@ def foldrRecOn {C : β → Sort _} (l : List α) (op : α → β → β) (b : β
 for the seed element `b : β` and for all incremental `op : β → α → β`
 performed on the elements `(a : α) ∈ l`. The principle is given for
 a `Sort`-valued predicate, i.e., it can also be used to construct data. -/
-def foldlRecOn {C : β → Sort _} (l : List α) (op : β → α → β) (b : β) (hb : C b)
+def foldlRecOn {C : β → Sort*} (l : List α) (op : β → α → β) (b : β) (hb : C b)
     (hl : ∀ (b : β) (_ : C b) (a : α) (_ : a ∈ l), C (op b a)) : C (foldl op b l) := by
   cases l with
   | nil => exact hb
@@ -2536,13 +2536,13 @@ def foldlRecOn {C : β → Sort _} (l : List α) (op : β → α → β) (b : β
 #align list.foldl_rec_on List.foldlRecOn
 
 @[simp]
-theorem foldrRecOn_nil {C : β → Sort _} (op : α → β → β) (b) (hb : C b) (hl) :
+theorem foldrRecOn_nil {C : β → Sort*} (op : α → β → β) (b) (hb : C b) (hl) :
     foldrRecOn [] op b hb hl = hb :=
   rfl
 #align list.foldr_rec_on_nil List.foldrRecOn_nil
 
 @[simp]
-theorem foldrRecOn_cons {C : β → Sort _} (x : α) (l : List α) (op : α → β → β) (b) (hb : C b)
+theorem foldrRecOn_cons {C : β → Sort*} (x : α) (l : List α) (op : α → β → β) (b) (hb : C b)
     (hl : ∀ (b : β) (_ : C b) (a : α) (_ : a ∈ x :: l), C (op a b)) :
     foldrRecOn (x :: l) op b hb hl =
       hl _ (foldrRecOn l op b hb fun b hb a ha => hl b hb a (mem_cons_of_mem _ ha)) x
@@ -2551,7 +2551,7 @@ theorem foldrRecOn_cons {C : β → Sort _} (x : α) (l : List α) (op : α →
 #align list.foldr_rec_on_cons List.foldrRecOn_cons
 
 @[simp]
-theorem foldlRecOn_nil {C : β → Sort _} (op : β → α → β) (b) (hb : C b) (hl) :
+theorem foldlRecOn_nil {C : β → Sort*} (op : β → α → β) (b) (hb : C b) (hl) :
     foldlRecOn [] op b hb hl = hb :=
   rfl
 #align list.foldl_rec_on_nil List.foldlRecOn_nil
@@ -3128,7 +3128,7 @@ theorem attach_eq_nil (l : List α) : l.attach = [] ↔ l = [] :=
   pmap_eq_nil
 #align list.attach_eq_nil List.attach_eq_nil
 
-theorem getLast_pmap {α β : Type _} (p : α → Prop) (f : ∀ a, p a → β) (l : List α)
+theorem getLast_pmap {α β : Type*} (p : α → Prop) (f : ∀ a, p a → β) (l : List α)
     (hl₁ : ∀ a ∈ l, p a) (hl₂ : l ≠ []) :
     (l.pmap f hl₁).getLast (mt List.pmap_eq_nil.1 hl₂) =
       f (l.getLast hl₂) (hl₁ _ (List.getLast_mem hl₂)) := by
@@ -3184,7 +3184,7 @@ theorem pmap_append {p : ι → Prop} (f : ∀ a : ι, p a → α) (l₁ l₂ :
     rw [ih]
 #align list.pmap_append List.pmap_append
 
-theorem pmap_append' {α β : Type _} {p : α → Prop} (f : ∀ a : α, p a → β) (l₁ l₂ : List α)
+theorem pmap_append' {α β : Type*} {p : α → Prop} (f : ∀ a : α, p a → β) (l₁ l₂ : List α)
     (h₁ : ∀ a ∈ l₁, p a) (h₂ : ∀ a ∈ l₂, p a) :
     ((l₁ ++ l₂).pmap f fun a ha => (List.mem_append.1 ha).elim (h₁ a) (h₂ a)) =
       l₁.pmap f h₁ ++ l₂.pmap f h₂ :=
chore: ensure all instances referred to directly have explicit names (#6423)

Per https://github.com/leanprover/lean4/issues/2343, we are going to need to change the automatic generation of instance names, as they become too long.

This PR ensures that everywhere in Mathlib that refers to an instance by name, that name is given explicitly, rather than being automatically generated.

There are four exceptions, which are now commented, with links to https://github.com/leanprover/lean4/issues/2343.

This was implemented by running Mathlib against a modified Lean that appended _ᾰ to all automatically generated names, and fixing everything.

Co-authored-by: Scott Morrison <scott.morrison@gmail.com>

Diff
@@ -222,7 +222,7 @@ theorem length_eq_three {l : List α} : l.length = 3 ↔ ∃ a b c, l = [a, b, c
 /-! ### set-theoretic notation of lists -/
 
 -- ADHOC Porting note: instance from Lean3 core
-instance : Singleton α (List α) := ⟨fun x => [x]⟩
+instance instSingletonList : Singleton α (List α) := ⟨fun x => [x]⟩
 #align list.has_singleton List.instSingletonList
 
 -- ADHOC Porting note: instance from Lean3 core
feat: port Init.Data.List.Lemmas (#6243)
Diff
@@ -92,10 +92,6 @@ theorem _root_.Decidable.List.eq_or_ne_mem_of_mem [DecidableEq α]
 
 #align list.eq_or_ne_mem_of_mem List.eq_or_ne_mem_of_mem
 
--- porting note: from init.data.list.lemmas
-alias mem_cons ↔ eq_or_mem_of_mem_cons _
-#align list.eq_or_mem_of_mem_cons List.eq_or_mem_of_mem_cons
-
 #align list.not_mem_append List.not_mem_append
 
 #align list.ne_nil_of_mem List.ne_nil_of_mem
@@ -221,11 +217,6 @@ theorem length_eq_three {l : List α} : l.length = 3 ↔ ∃ a b c, l = [a, b, c
   ⟨fun _ => let [a, b, c] := l; ⟨a, b, c, rfl⟩, fun ⟨_, _, _, e⟩ => e ▸ rfl⟩
 #align list.length_eq_three List.length_eq_three
 
--- Porting note: Lean 3 core library had the name length_le_of_sublist
--- and data.list.basic the command `alias length_le_of_sublist ← sublist.length_le`,
--- but Std has the name Sublist.length_le instead.
-alias Sublist.length_le ← length_le_of_sublist
-#align list.length_le_of_sublist List.length_le_of_sublist
 #align list.sublist.length_le List.Sublist.length_le
 
 /-! ### set-theoretic notation of lists -/
@@ -3321,18 +3312,6 @@ theorem length_lookmap (l : List α) : length (l.lookmap f) = length l := by
 end Lookmap
 
 /-! ### filter -/
--- Porting note: These lemmas are from Lean3 core
-
-#align list.filter_nil List.filter_nil
-
-#align list.filter_cons_of_pos List.filter_cons_of_pos
-
-#align list.filter_cons_of_neg List.filter_cons_of_neg
-
-#align list.filter_append List.filter_append
-
-#align list.filter_sublist List.filter_sublist
-
 /-! ### filterMap -/
 
 #align list.filter_map_nil List.filterMap_nil
chore: move some List aligns to a better location (#6056)
Diff
@@ -416,15 +416,19 @@ theorem append_left_injective (t : List α) : Injective fun s ↦ s ++ t :=
 
 /-! ### replicate -/
 
-attribute [simp] replicate_succ
-#align list.replicate_succ List.replicate_succ
-
 @[simp] lemma replicate_zero (a : α) : replicate 0 a = [] := rfl
 #align list.replicate_zero List.replicate_zero
 
+attribute [simp] replicate_succ
+#align list.replicate_succ List.replicate_succ
+
 lemma replicate_one (a : α) : replicate 1 a = [a] := rfl
 #align list.replicate_one List.replicate_one
 
+#align list.length_replicate List.length_replicate
+#align list.mem_replicate List.mem_replicate
+#align list.eq_of_mem_replicate List.eq_of_mem_replicate
+
 theorem eq_replicate_length {a : α} : ∀ {l : List α}, l = replicate l.length a ↔ ∀ b ∈ l, b = a
   | [] => by simp
   | (b :: l) => by simp [eq_replicate_length]
chore: bump to nightly-2023-07-15 (#5992)

Various adaptations to changes when Fin API was moved to Std. One notable change is that many lemmas are now stated in terms of i ≠ 0 (for i : Fin n) rather then i.1 ≠ 0, and as a consequence many Fin.vne_of_ne applications have been added or removed, mostly removed.

Co-authored-by: Scott Morrison <scott.morrison@gmail.com> Co-authored-by: Wojciech Nawrocki <wjnawrocki@protonmail.com> Co-authored-by: Eric Wieser <wieser.eric@gmail.com>

Diff
@@ -625,16 +625,12 @@ theorem map_reverseAux (f : α → β) (l₁ l₂ : List α) :
   simp only [reverseAux_eq, map_append, map_reverse]
 #align list.map_reverse_core List.map_reverseAux
 
--- Porting TODO: Fix statement of `mem_reverse` in Std to match Lean3,
--- then deprecate/remove this one
-theorem mem_reverse' {a : α} {l : List α} : a ∈ reverse l ↔ a ∈ l :=
-  List.mem_reverse _ _
-#align list.mem_reverse List.mem_reverse'
+#align list.mem_reverse List.mem_reverse
 
 @[simp] theorem reverse_replicate (n) (a : α) : reverse (replicate n a) = replicate n a :=
   eq_replicate.2
     ⟨by rw [length_reverse, length_replicate],
-     fun b h => eq_of_mem_replicate (mem_reverse'.1 h)⟩
+     fun b h => eq_of_mem_replicate (mem_reverse.1 h)⟩
 #align list.reverse_replicate List.reverse_replicate
 
 /-! ### empty -/
@@ -1884,9 +1880,6 @@ theorem take_zero (l : List α) : take 0 l = [] :=
   rfl
 #align list.take_zero List.take_zero
 
-@[simp]
-theorem take_nil : ∀ n, take n [] = ([] : List α)
-  | 0 | _ + 1 => rfl
 #align list.take_nil List.take_nil
 
 theorem take_cons (n) (a : α) (l : List α) : take (succ n) (a :: l) = a :: take n l :=
chore: script to replace headers with #align_import statements (#5979)

Open in Gitpod

Co-authored-by: Eric Wieser <wieser.eric@gmail.com> Co-authored-by: Scott Morrison <scott.morrison@gmail.com>

Diff
@@ -2,11 +2,6 @@
 Copyright (c) 2014 Parikshit Khanna. All rights reserved.
 Released under Apache 2.0 license as described in the file LICENSE.
 Authors: Parikshit Khanna, Jeremy Avigad, Leonardo de Moura, Floris van Doorn, Mario Carneiro
-
-! This file was ported from Lean 3 source module data.list.basic
-! leanprover-community/mathlib commit 9da1b3534b65d9661eb8f42443598a92bbb49211
-! Please do not edit these lines, except to modify the commit id
-! if you have ported upstream changes.
 -/
 import Mathlib.Init.Data.List.Instances
 import Mathlib.Data.Nat.Order.Basic
@@ -14,6 +9,8 @@ import Mathlib.Data.List.Defs
 import Mathlib.Init.Core
 import Std.Data.List.Lemmas
 
+#align_import data.list.basic from "leanprover-community/mathlib"@"9da1b3534b65d9661eb8f42443598a92bbb49211"
+
 /-!
 # Basic properties of lists
 -/
chore: cleanup whitespace (#5988)

Grepping for [^ .:{-] [^ :] and reviewing the results. Once I started I couldn't stop. :-)

Co-authored-by: Scott Morrison <scott.morrison@gmail.com>

Diff
@@ -3567,7 +3567,7 @@ theorem monotone_filter_right (l : List α) ⦃p q : α → Bool⦄
 #align list.filter_filter List.filter_filter
 
 @[simp]
-theorem filter_true  (l : List α) :
+theorem filter_true (l : List α) :
     filter (fun _ => true) l = l := by induction l <;> simp [*, filter]
 #align list.filter_true List.filter_true
 
chore: remove a few superfluous semicolons (#5880)

Alongside any necessary spacing/flow changes to accommodate their removal.

Diff
@@ -1169,10 +1169,9 @@ theorem indexOf_of_not_mem {l : List α} {a : α} : a ∉ l → indexOf a l = le
 theorem indexOf_le_length {a : α} {l : List α} : indexOf a l ≤ length l := by
   induction' l with b l ih; · rfl
   simp only [length, indexOf_cons]
-  by_cases h : a = b;
-  · rw [if_pos h]
-    exact Nat.zero_le _
-  rw [if_neg h]; exact succ_le_succ ih
+  by_cases h : a = b
+  · rw [if_pos h]; exact Nat.zero_le _
+  · rw [if_neg h]; exact succ_le_succ ih
 #align list.index_of_le_length List.indexOf_le_length
 
 theorem indexOf_lt_length {a} {l : List α} : indexOf a l < length l ↔ a ∈ l :=
@@ -2969,7 +2968,7 @@ theorem intercalate_splitOn (x : α) [DecidableEq α] : [x].intercalate (xs.spli
   cases' h' : splitOnP (· == x) tl with hd' tl'; · exact (splitOnP_ne_nil _ tl h').elim
   rw [h'] at ih
   rw [splitOnP_cons]
-  split_ifs with h;
+  split_ifs with h
   · rw [beq_iff_eq] at h
     subst h
     simp [ih, join, h']
@@ -3113,9 +3112,9 @@ theorem attach_map_val (l : List α) : l.attach.map Subtype.val = l :=
 @[simp]
 theorem mem_attach (l : List α) : ∀ x, x ∈ l.attach
   | ⟨a, h⟩ => by
-    have := mem_map.1 (by rw [attach_map_val] <;> exact h);
-      · rcases this with ⟨⟨_, _⟩, m, rfl⟩
-        exact m
+    have := mem_map.1 (by rw [attach_map_val] <;> exact h)
+    rcases this with ⟨⟨_, _⟩, m, rfl⟩
+    exact m
 #align list.mem_attach List.mem_attach
 
 @[simp]
refactor(Init.Data.List.Instances): sync to Mathlib 3 (#5751)
Diff
@@ -8,7 +8,7 @@ Authors: Parikshit Khanna, Jeremy Avigad, Leonardo de Moura, Floris van Doorn, M
 ! Please do not edit these lines, except to modify the commit id
 ! if you have ported upstream changes.
 -/
-import Mathlib.Init.Data.List.Basic
+import Mathlib.Init.Data.List.Instances
 import Mathlib.Data.Nat.Order.Basic
 import Mathlib.Data.List.Defs
 import Mathlib.Init.Core
@@ -491,35 +491,6 @@ theorem replicate_left_injective (a : α) : Injective (replicate · a) :=
 
 /-! ### pure -/
 
--- ADHOC Porting note: TODO this is from Lean3 core, so doesn't belong here
-instance : Monad List := { pure := @List.ret, bind := @List.bind, map := @List.map }
-
--- Porting note: simp can prove this
--- @[simp]
-theorem bind_singleton (f : α → List β) (x : α) : [x].bind f = f x :=
-  append_nil (f x)
-#align list.bind_singleton List.bind_singleton
-
-@[simp] theorem bind_singleton' (l : List α) : (l.bind fun x => [x]) = l := by
-  induction l <;> simp [*]
-#align list.bind_singleton' List.bind_singleton'
-
-theorem map_eq_bind {α β} (f : α → β) (l : List α) : map f l = l.bind fun x => [f x] := by
-  simp_rw [←map_singleton]
-  rw [← bind_singleton' l, bind_map, bind_singleton']
-#align list.map_eq_bind List.map_eq_bind
-
-theorem bind_assoc {α β} (l : List α) (f : α → List β) (g : β → List γ) :
-    (l.bind f).bind g = l.bind fun x => (f x).bind g := by induction l <;> simp [*]
-#align list.bind_assoc List.bind_assoc
-
--- ADHOC Porting note: TODO this is from Lean3 core, so doesn't belong here
-instance : LawfulMonad List := LawfulMonad.mk'
-  (id_map := map_id)
-  (pure_bind := fun _ _ => List.append_nil _)
-  (bind_assoc := List.bind_assoc)
-  (bind_pure_comp := fun _ _ => (map_eq_bind _ _).symm)
-
 @[simp]
 theorem mem_pure {α} (x y : α) : x ∈ (pure y : List α) ↔ x = y :=
   show x ∈ [y] ↔ x = y by simp
feat: add List.foldl_concat and List.foldr.concat (#5733)

These are special versions of List.fold[lr]_append in case a single element list is appended.

Co-authored-by: Chris Hughes <33847686+ChrisHughes24@users.noreply.github.com>

Diff
@@ -2416,6 +2416,16 @@ theorem foldr_cons (f : α → β → β) (b : β) (a : α) (l : List α) :
 
 #align list.foldr_append List.foldr_append
 
+theorem foldl_concat
+    (f : β → α → β) (b : β) (x : α) (xs : List α) :
+    List.foldl f b (xs ++ [x]) = f (List.foldl f b xs) x := by
+  simp only [List.foldl_append, List.foldl]
+
+theorem foldr_concat
+    (f : α → β → β) (b : β) (x : α) (xs : List α) :
+    List.foldr f b (xs ++ [x]) = (List.foldr f (f x b) xs) := by
+  simp only [List.foldr_append, List.foldr]
+
 theorem foldl_fixed' {f : α → β → α} {a : α} (hf : ∀ b, f a b = a) : ∀ l : List β, foldl f a l = a
   | [] => rfl
   | b :: l => by rw [foldl_cons, hf b, foldl_fixed' hf l]
chore: fix focusing dots (#5708)

This PR is the result of running

find . -type f -name "*.lean" -exec sed -i -E 's/^( +)\. /\1· /' {} \;
find . -type f -name "*.lean" -exec sed -i -E 'N;s/^( +·)\n +(.*)$/\1 \2/;P;D' {} \;

which firstly replaces . focusing dots with · and secondly removes isolated instances of such dots, unifying them with the following line. A new rule is placed in the style linter to verify this.

Diff
@@ -3181,8 +3181,8 @@ theorem get?_pmap {p : α → Prop} (f : ∀ a, p a → β) {l : List α} (h : 
   induction' l with hd tl hl generalizing n
   · simp
   · cases' n with n
-    . simp
-    . simp [hl]
+    · simp
+    · simp [hl]
 #align list.nth_pmap List.get?_pmap
 
 theorem get_pmap {p : α → Prop} (f : ∀ a, p a → β) {l : List α} (h : ∀ a ∈ l, p a) {n : ℕ}
@@ -3543,8 +3543,8 @@ theorem mem_of_mem_filter {a : α} {l} (h : a ∈ filter p l) : a ∈ l :=
 theorem mem_filter_of_mem {a : α} : ∀ {l}, a ∈ l → p a → a ∈ filter p l
   | x :: l, h, h1 => by
     rcases mem_cons.1 h with rfl | h
-    . simp [filter, h1]
-    . rw [filter]
+    · simp [filter, h1]
+    · rw [filter]
       cases p x <;> simp [mem_filter_of_mem h h1]
 #align list.mem_filter_of_mem List.mem_filter_of_mem
 
chore: remove legacy termination_by' (#5426)

This adds a couple of WellFoundedRelation instances, like for example WellFoundedRelation (WithBot Nat). Longer-term, we should probably add a WellFoundedOrder class for types with a well-founded less-than relation and a [WellFoundOrder α] : WellFoundedRelation α instance (or maybe just [LT α] [IsWellFounded fun a b : α => a < b] : WellFoundedRelation α).

Diff
@@ -1018,7 +1018,7 @@ def bidirectionalRec {C : List α → Sort _} (H0 : C []) (H1 : ∀ a : α, C [a
     rw [← dropLast_append_getLast (cons_ne_nil b l)]
     have : C l' := bidirectionalRec H0 H1 Hn l'
     exact Hn a l' b' this
-termination_by' measure List.length
+termination_by _ l => l.length
 #align list.bidirectional_rec List.bidirectionalRecₓ -- universe order
 
 /-- Like `bidirectionalRec`, but with the list parameter placed first. -/
chore: clean up spacing around at and goals (#5387)

Changes are of the form

  • some_tactic at h⊢ -> some_tactic at h ⊢
  • some_tactic at h -> some_tactic at h
Diff
@@ -2060,7 +2060,7 @@ theorem take_add (l : List α) (m n : ℕ) : l.take (m + n) = l.take m ++ (l.dro
   · simp only [take_eq_take, length_take, length_drop]
     generalize l.length = k; by_cases h : m ≤ k
     · simp [min_eq_left_iff.mpr h]
-    · push_neg  at h
+    · push_neg at h
       simp [Nat.sub_eq_zero_of_le (le_of_lt h)]
   · trans m
     · apply length_take_le
@@ -3012,7 +3012,7 @@ theorem splitOn_intercalate [DecidableEq α] (x : α) (hx : ∀ l ∈ ls, x ∉
     specialize ih _ _
     · intro l hl
       apply hx l
-      simp at hl⊢
+      simp at hl ⊢
       exact Or.inr hl
     · exact List.noConfusion
     have := splitOnP_first (· == x) hd ?h x (beq_self_eq_true _)
@@ -3020,7 +3020,7 @@ theorem splitOn_intercalate [DecidableEq α] (x : α) (hx : ∀ l ∈ ls, x ∉
       intro y hy H
       rw [eq_of_beq H] at hy
       exact hx hd (.head _) hy
-    simp only [splitOn] at ih⊢
+    simp only [splitOn] at ih ⊢
     rw [this, ih]
 #align list.split_on_intercalate List.splitOn_intercalate
 
@@ -3553,7 +3553,7 @@ theorem mem_filter_of_mem {a : α} : ∀ {l}, a ∈ l → p a → a ∈ filter p
 theorem monotone_filter_left (p : α → Bool) ⦃l l' : List α⦄ (h : l ⊆ l') :
     filter p l ⊆ filter p l' := by
   intro x hx
-  rw [mem_filter] at hx⊢
+  rw [mem_filter] at hx ⊢
   exact ⟨h hx.left, hx.right⟩
 #align list.monotone_filter_left List.monotone_filter_left
 
chore: formatting issues (#4947)

Co-authored-by: Scott Morrison <scott.morrison@anu.edu.au> Co-authored-by: Parcly Taxel <reddeloostw@gmail.com>

Diff
@@ -404,13 +404,13 @@ theorem append_right_cancel {s₁ s₂ t : List α} (h : s₁ ++ t = s₂ ++ t)
 #align list.append_right_cancel List.append_right_cancel
 
 theorem append_right_injective (s : List α) : Injective fun t ↦ s ++ t :=
-fun _ _ ↦ append_left_cancel
+  fun _ _ ↦ append_left_cancel
 #align list.append_right_injective List.append_right_injective
 
 #align list.append_right_inj List.append_right_inj
 
 theorem append_left_injective (t : List α) : Injective fun s ↦ s ++ t :=
-fun _ _ ↦ append_right_cancel
+  fun _ _ ↦ append_right_cancel
 #align list.append_left_injective List.append_left_injective
 
 #align list.append_left_inj List.append_left_inj
@@ -3031,7 +3031,7 @@ end SplitAtOn
 
 section ModifyLast
 
-theorem modifyLast.go_append_one (f : α → α) (a : α) (tl : List α) (r : Array α):
+theorem modifyLast.go_append_one (f : α → α) (a : α) (tl : List α) (r : Array α) :
     modifyLast.go f (tl ++ [a]) r = (r.toListAppend <| modifyLast.go f (tl ++ [a]) #[]) := by
   cases tl with
   | nil =>
@@ -3139,7 +3139,7 @@ theorem mem_attach (l : List α) : ∀ x, x ∈ l.attach
 
 @[simp]
 theorem mem_pmap {p : α → Prop} {f : ∀ a, p a → β} {l H b} :
-    b ∈ pmap f l H ↔ ∃ (a : _)(h : a ∈ l), f a (H a h) = b := by
+    b ∈ pmap f l H ↔ ∃ (a : _) (h : a ∈ l), f a (H a h) = b := by
   simp only [pmap_eq_map_attach, mem_map, mem_attach, true_and_iff, Subtype.exists, eq_comm]
 #align list.mem_pmap List.mem_pmap
 
chore: bump to nightly-2023-05-31 (#4530)

Co-authored-by: Scott Morrison <scott.morrison@gmail.com> Co-authored-by: Mario Carneiro <di.gama@gmail.com> Co-authored-by: Floris van Doorn <fpvdoorn@gmail.com> Co-authored-by: Jeremy Tan Jie Rui <reddeloostw@gmail.com> Co-authored-by: Alex J Best <alex.j.best@gmail.com>

Diff
@@ -3073,20 +3073,7 @@ end ModifyLast
 
 /-! ### map for partial functions -/
 
-/-- Partial map. If `f : Π a, p a → β` is a partial function defined on
-  `a : α` satisfying `p`, then `pmap f l h` is essentially the same as `map f l`
-  but is defined only when all members of `l` satisfy `p`, using the proof
-  to apply `f`. -/
-@[simp]
-def pmap {p : α → Prop} (f : ∀ a, p a → β) : ∀ l : List α, (∀ a ∈ l, p a) → List β
-  | [], _ => []
-  | a :: l, H => f a (forall_mem_cons.1 H).1 :: pmap f l (forall_mem_cons.1 H).2
 #align list.pmap List.pmap
-
-/-- "Attach" the proof that the elements of `l` are in `l` to produce a new list
-  with the same elements but in the type `{x // x ∈ l}`. -/
-def attach (l : List α) : List { x // x ∈ l } :=
-  pmap Subtype.mk l fun _ => id
 #align list.attach List.attach
 
 theorem sizeOf_lt_sizeOf_of_mem [SizeOf α] {x : α} {l : List α} (hx : x ∈ l) :
chore: fix typos (#4518)

I ran codespell Mathlib and got tired halfway through the suggestions.

Diff
@@ -2853,7 +2853,7 @@ theorem intersperse_cons_cons {α : Type u} (a b c : α) (tl : List α) :
 section SplitAtOn
 
 /- Porting note: the new version of `splitOnP` uses a `Bool`-valued predicate instead of a
-  `Prop`-valued one. All downstream defintions have been updated to match. -/
+  `Prop`-valued one. All downstream definitions have been updated to match. -/
 
 variable (p : α → Bool) (xs ys : List α) (ls : List (List α)) (f : List α → List α)
 
feat: assert_not_exists (#4245)
Diff
@@ -22,8 +22,7 @@ open Function
 
 open Nat hiding one_pos
 
--- Porting note: missing impl
--- assert_not_exists Set.range
+assert_not_exists Set.range
 
 namespace List
 
chore: update std 05-22 (#4248)

The main breaking change is that tac <;> [t1, t2] is now written tac <;> [t1; t2], to avoid clashing with tactics like cases and use that take comma-separated lists.

Diff
@@ -456,7 +456,7 @@ theorem subset_singleton_iff {a : α} {L : List α} : L ⊆ [a] ↔ ∃ n, L = r
 
 @[simp] theorem map_replicate (f : α → β) (n) (a : α) :
     map f (replicate n a) = replicate n (f a) := by
-  induction n <;> [rfl, simp only [*, replicate, map]]
+  induction n <;> [rfl; simp only [*, replicate, map]]
 #align list.map_replicate List.map_replicate
 
 @[simp] theorem tail_replicate (a : α) (n) :
@@ -464,7 +464,7 @@ theorem subset_singleton_iff {a : α} {L : List α} : L ⊆ [a] ↔ ∃ n, L = r
 #align list.tail_replicate List.tail_replicate
 
 @[simp] theorem join_replicate_nil (n : ℕ) : join (replicate n []) = @nil α := by
-  induction n <;> [rfl, simp only [*, replicate, join, append_nil]]
+  induction n <;> [rfl; simp only [*, replicate, join, append_nil]]
 #align list.join_replicate_nil List.join_replicate_nil
 
 theorem replicate_right_injective {n : ℕ} (hn : n ≠ 0) : Injective (@replicate α n) :=
@@ -946,7 +946,7 @@ set_option linter.deprecated false -- TODO(Mario): make replacements for theorem
 @[simp] theorem nthLe_tail (l : List α) (i) (h : i < l.tail.length)
     (h' : i + 1 < l.length := (by simpa [← lt_tsub_iff_right] using h)) :
     l.tail.nthLe i h = l.nthLe (i + 1) h' := by
-  -- Porting note: cases l <;> [cases h, rfl] fails
+  -- Porting note: cases l <;> [cases h; rfl] fails
   cases l
   · cases h
   · rfl
@@ -1788,7 +1788,7 @@ theorem map_eq_map_iff {f g : α → β} {l : List α} : map f l = map g l ↔ 
 
 theorem map_concat (f : α → β) (a : α) (l : List α) :
     map f (concat l a) = concat (map f l) (f a) := by
-  induction l <;> [rfl, simp only [*, concat_eq_append, cons_append, map, map_append]]
+  induction l <;> [rfl; simp only [*, concat_eq_append, cons_append, map, map_append]]
 #align list.map_concat List.map_concat
 
 @[simp]
@@ -1806,7 +1806,7 @@ theorem eq_nil_of_map_eq_nil {f : α → β} {l : List α} (h : map f l = nil) :
 
 @[simp]
 theorem map_join (f : α → β) (L : List (List α)) : map f (join L) = join (map (map f) L) := by
-  induction L <;> [rfl, simp only [*, join, map, map_append]]
+  induction L <;> [rfl; simp only [*, join, map, map_append]]
 #align list.map_join List.map_join
 
 theorem bind_ret_eq_map (f : α → β) (l : List α) : l.bind (List.ret ∘ f) = map f l := by
@@ -2495,14 +2495,14 @@ theorem foldl_hom₂ (l : List ι) (f : α → β → γ) (op₁ : α → ι →
     foldl op₃ (f a b) l = f (foldl op₁ a l) (foldl op₂ b l) :=
   Eq.symm <| by
     revert a b
-    induction l <;> intros <;> [rfl, simp only [*, foldl]]
+    induction l <;> intros <;> [rfl; simp only [*, foldl]]
 #align list.foldl_hom₂ List.foldl_hom₂
 
 theorem foldr_hom₂ (l : List ι) (f : α → β → γ) (op₁ : ι → α → α) (op₂ : ι → β → β)
     (op₃ : ι → γ → γ) (a : α) (b : β) (h : ∀ a b i, f (op₁ i a) (op₂ i b) = op₃ i (f a b)) :
     foldr op₃ (f a b) l = f (foldr op₁ a l) (foldr op₂ b l) := by
   revert a
-  induction l <;> intros <;> [rfl, simp only [*, foldr]]
+  induction l <;> intros <;> [rfl; simp only [*, foldr]]
 #align list.foldr_hom₂ List.foldr_hom₂
 
 theorem injective_foldl_comp {α : Type _} {l : List (α → α)} {f : α → α}
@@ -2918,60 +2918,27 @@ theorem splitOnP_nil : [].splitOnP p = [[]] :=
 #noalign list.split_on_p_aux_eq
 #noalign list.split_on_p_aux_nil
 
-theorem splitOnP.go_append (xs : List α) (acc : Array α) (r : Array (List α)) :
-    splitOnP.go p xs acc r = r.toListAppend (splitOnP.go p xs acc #[]) := by
-  cases xs with
-  | nil => rfl
-  | cons a as =>
-    simp only [go]
-    by_cases h : p a
-    · simp only [h, cond_true]
-      rw [go_append as, go_append as _ (Array.push #[] (Array.toList acc))]
-      simp only [Array.toListAppend_eq, Array.push_data]
-      rw [Array.data_toArray, nil_append, append_assoc]
-    · simp only [eq_false_of_ne_true h, cond_false]
-      exact go_append as _ _
-
-theorem splitOnP.go_acc (xs : List α) (acc : Array α) :
-    splitOnP.go p xs acc #[] = modifyHead (acc.toListAppend) (splitOnP.go p xs #[] #[]) := by
-  cases xs with
-  | nil => rfl
-  | cons hd tl =>
-    simp only [go]
-    by_cases h : p hd
-    · simp only [h, cond_true]
-      rw [go_append, go_append _ _ _ (Array.push #[] (Array.toList #[]))]
-      rfl
-    · simp only [eq_false_of_ne_true h, cond_false]
-      rw [go_acc tl, go_acc tl (Array.push #[] hd), modifyHead_modifyHead]
-      change modifyHead (fun a ↦ Array.toListAppend (Array.push acc hd) a) _ =
-        modifyHead (fun a ↦ Array.toListAppend acc <| Array.toListAppend (Array.push #[] hd) a) _
-      simp only [Array.toListAppend_eq, Array.push_data, Array.data_toArray, nil_append,
-        append_assoc]
+theorem splitOnP.go_ne_nil (xs acc : List α) : splitOnP.go p xs acc ≠ [] := by
+  induction xs generalizing acc <;> simp [go]; split <;> simp [*]
 
-theorem splitOnP_ne_nil (xs : List α) : xs.splitOnP p ≠ [] := by
-  cases xs with
-  | nil => exact cons_ne_nil [] []
-  | cons hd tl =>
-    rw [splitOnP, splitOnP.go]
-    by_cases h : p hd
-    · rw [h, cond_true, splitOnP.go_append]
-      exact append_ne_nil_of_ne_nil_left [[]] _ (cons_ne_nil [] [])
-    · rw [eq_false_of_ne_true h, cond_false, splitOnP.go_acc, ←splitOnP]
-      exact modifyHead_ne_nil_of_ne_nil (splitOnP_ne_nil tl)
-where
-  modifyHead_ne_nil_of_ne_nil {α} {f} {l : List α} (_ : l ≠ []) : modifyHead f l ≠ [] := by
-    cases l with | nil => contradiction | cons => rw [modifyHead]; exact cons_ne_nil _ _
+theorem splitOnP.go_acc (xs acc : List α) :
+    splitOnP.go p xs acc = modifyHead (acc.reverse ++ ·) (splitOnP p xs) := by
+  induction xs generalizing acc with
+  | nil => simp only [go, modifyHead, splitOnP_nil, append_nil]
+  | cons hd tl ih =>
+    simp only [splitOnP, go]; split
+    · simp only [modifyHead, reverse_nil, append_nil]
+    · rw [ih [hd], modifyHead_modifyHead, ih]
+      congr; funext x; simp only [reverse_cons, append_assoc]; rfl
+
+theorem splitOnP_ne_nil (xs : List α) : xs.splitOnP p ≠ [] := splitOnP.go_ne_nil _ _ _
 #align list.split_on_p_ne_nil List.splitOnP_ne_nilₓ
 
 @[simp]
 theorem splitOnP_cons (x : α) (xs : List α) :
     (x :: xs).splitOnP p =
       if p x then [] :: xs.splitOnP p else (xs.splitOnP p).modifyHead (cons x) := by
-  rw [splitOnP, splitOnP.go]
-  by_cases h : p x
-  · rw [if_pos h, h, cond_true, splitOnP.go_append, splitOnP]; rfl
-  · rw [if_neg h, eq_false_of_ne_true h, cond_false, splitOnP.go_acc, splitOnP]; congr 1
+  rw [splitOnP, splitOnP.go]; split <;> [rfl; simp [splitOnP.go_acc]]
 #align list.split_on_p_cons List.splitOnP_consₓ
 
 /-- The original list `L` can be recovered by joining the lists produced by `splitOnP p L`,
@@ -3134,7 +3101,7 @@ theorem sizeOf_lt_sizeOf_of_mem [SizeOf α] {x : α} {l : List α} (hx : x ∈ l
 @[simp]
 theorem pmap_eq_map (p : α → Prop) (f : α → β) (l : List α) (H) :
     @pmap _ _ p (fun a _ => f a) l H = map f l := by
-  induction l <;> [rfl, simp only [*, pmap, map]]
+  induction l <;> [rfl; simp only [*, pmap, map]]
 #align list.pmap_eq_map List.pmap_eq_map
 
 theorem pmap_congr {p q : α → Prop} {f : ∀ a, p a → β} {g : ∀ a, q a → β} (l : List α) {H₁ H₂}
@@ -3146,12 +3113,12 @@ theorem pmap_congr {p q : α → Prop} {f : ∀ a, p a → β} {g : ∀ a, q a 
 
 theorem map_pmap {p : α → Prop} (g : β → γ) (f : ∀ a, p a → β) (l H) :
     map g (pmap f l H) = pmap (fun a h => g (f a h)) l H := by
-  induction l <;> [rfl, simp only [*, pmap, map]]
+  induction l <;> [rfl; simp only [*, pmap, map]]
 #align list.map_pmap List.map_pmap
 
 theorem pmap_map {p : β → Prop} (g : ∀ b, p b → γ) (f : α → β) (l H) :
     pmap g (map f l) H = pmap (fun a h => g (f a) h) l fun a h => H _ (mem_map_of_mem _ h) := by
-  induction l <;> [rfl, simp only [*, pmap, map]]
+  induction l <;> [rfl; simp only [*, pmap, map]]
 #align list.pmap_map List.pmap_map
 
 theorem pmap_eq_map_attach {p : α → Prop} (f : ∀ a, p a → β) (l H) :
@@ -3192,7 +3159,7 @@ theorem mem_pmap {p : α → Prop} {f : ∀ a, p a → β} {l H b} :
 
 @[simp]
 theorem length_pmap {p : α → Prop} {f : ∀ a, p a → β} {l H} : length (pmap f l H) = length l := by
-  induction l <;> [rfl, simp only [*, pmap, length]]
+  induction l <;> [rfl; simp only [*, pmap, length]]
 #align list.length_pmap List.length_pmap
 
 @[simp]
@@ -3646,22 +3613,16 @@ theorem filter_false (l : List α) :
 /- Porting note: need a helper theorem for span.loop. -/
 theorem span.loop_eq_take_drop :
   ∀ l₁ l₂ : List α, span.loop p l₁ l₂ = (l₂.reverse ++ takeWhile p l₁, dropWhile p l₁)
-  | [], l₂ => by simp [span.loop]
-  | (a :: l), l₂ => by cases hp : p a <;> simp [hp, span.loop, span.loop_eq_take_drop]
+  | [], l₂ => by simp [span.loop, takeWhile, dropWhile]
+  | (a :: l), l₂ => by
+    cases hp : p a <;> simp [hp, span.loop, span.loop_eq_take_drop, takeWhile, dropWhile]
 
 @[simp]
 theorem span_eq_take_drop (l : List α) : span p l = (takeWhile p l, dropWhile p l) := by
   simpa using span.loop_eq_take_drop p l []
 #align list.span_eq_take_drop List.span_eq_take_drop
 
-@[simp]
-theorem takeWhile_append_drop : ∀ l : List α, takeWhile p l ++ dropWhile p l = l
-  | [] => rfl
-  | a :: l =>
-    if pa : p a then by
-      simp [takeWhile, dropWhile, pa, cons_append, takeWhile_append_drop l]
-    else by simp [takeWhile, dropWhile, pa, nil_append]
-#align list.take_while_append_drop List.takeWhile_append_drop
+#align list.take_while_append_drop List.takeWhile_append_dropWhile
 
 theorem dropWhile_nthLe_zero_not (l : List α) (hl : 0 < (l.dropWhile p).length) :
     ¬p ((l.dropWhile p).nthLe 0 hl) := by
@@ -3702,9 +3663,8 @@ theorem takeWhile_eq_nil_iff : takeWhile p l = [] ↔ ∀ hl : 0 < l.length, ¬p
 #align list.take_while_eq_nil_iff List.takeWhile_eq_nil_iff
 
 theorem mem_takeWhile_imp {x : α} (hx : x ∈ takeWhile p l) : p x := by
-  induction' l with hd tl IH
-  · simp at hx
-  · simp only [takeWhile] at hx
+  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
@@ -3802,7 +3762,7 @@ theorem map_erase [DecidableEq β] {f : α → β} (finj : Injective f) {a : α}
 
 theorem map_foldl_erase [DecidableEq β] {f : α → β} (finj : Injective f) {l₁ l₂ : List α} :
     map f (foldl List.erase l₁ l₂) = foldl (fun l a => l.erase (f a)) (map f l₁) l₂ := by
-  induction l₂ generalizing l₁ <;> [rfl, simp only [foldl_cons, map_erase finj, *]]
+  induction l₂ generalizing l₁ <;> [rfl; simp only [foldl_cons, map_erase finj, *]]
 #align list.map_foldl_erase List.map_foldl_erase
 
 end Erase
chore: reenable eta, bump to nightly 2023-05-16 (#3414)

Now that leanprover/lean4#2210 has been merged, this PR:

  • removes all the set_option synthInstance.etaExperiment true commands (and some etaExperiment% term elaborators)
  • removes many but not quite all set_option maxHeartbeats commands
  • makes various other changes required to cope with leanprover/lean4#2210.

Co-authored-by: Scott Morrison <scott.morrison@anu.edu.au> Co-authored-by: Scott Morrison <scott.morrison@gmail.com> Co-authored-by: Matthew Ballard <matt@mrb.email>

Diff
@@ -3230,7 +3230,6 @@ theorem get?_pmap {p : α → Prop} (f : ∀ a, p a → β) {l : List α} (h : 
   · cases' n with n
     . simp
     . simp [hl]
-      dsimp
 #align list.nth_pmap List.get?_pmap
 
 theorem get_pmap {p : α → Prop} (f : ∀ a, p a → β) {l : List α} (h : ∀ a ∈ l, p a) {n : ℕ}
chore: fix #align lines (#3640)

This PR fixes two things:

  • Most align statements for definitions and theorems and instances that are separated by two newlines from the relevant declaration (s/\n\n#align/\n#align). This is often seen in the mathport output after ending calc blocks.
  • All remaining more-than-one-line #align statements. (This was needed for a script I wrote for #3630.)
Diff
@@ -1173,14 +1173,12 @@ theorem indexOf_cons_eq {a b : α} (l : List α) : a = b → indexOf a (b :: l)
 @[simp]
 theorem indexOf_cons_ne {a b : α} (l : List α) : a ≠ b → indexOf a (b :: l) = succ (indexOf a l)
   | h => by simp only [indexOf, findIdx_cons, Bool.cond_eq_ite, beq_iff_eq, h, ite_false]
-
 #align list.index_of_cons_ne List.indexOf_cons_ne
 
 -- rfl
 theorem indexOf_cons (a b : α) (l : List α) :
     indexOf a (b :: l) = if a = b then 0 else succ (indexOf a l) := by
   simp only [indexOf, findIdx_cons, Bool.cond_eq_ite, beq_iff_eq]
-
 #align list.index_of_cons List.indexOf_cons
 
 theorem indexOf_eq_length {a : α} {l : List α} : indexOf a l = length l ↔ a ∉ l := by
@@ -2767,7 +2765,6 @@ theorem foldl_assoc : ∀ {l : List α} {a₁ a₂}, (l <*> a₁ ⋆ a₂) = a
     calc
       ((a :: l) <*> a₁ ⋆ a₂) = l <*> a₁ ⋆ a₂ ⋆ a := by simp only [foldl_cons, ha.assoc]
       _ = a₁ ⋆ (a :: l) <*> a₂ := by rw [foldl_assoc, foldl_cons]
-
 #align list.foldl_assoc List.foldl_assoc
 
 theorem foldl_op_eq_op_foldr_assoc :
@@ -3597,7 +3594,6 @@ theorem mem_filter_of_mem {a : α} : ∀ {l}, a ∈ l → p a → a ∈ filter p
     . simp [filter, h1]
     . rw [filter]
       cases p x <;> simp [mem_filter_of_mem h h1]
-
 #align list.mem_filter_of_mem List.mem_filter_of_mem
 
 #align list.mem_filter List.mem_filter
chore: bump Std (#3113)

Notably incorporates https://github.com/leanprover/std4/pull/98 and https://github.com/leanprover/std4/pull/109.

https://github.com/leanprover/std4/pull/98 moves a number of lemmas from Mathlib to Std, so the bump requires deleting them in Mathlib. I did check on each lemma whether its attributes were kept in the move (and gave attribute markings in Mathlib if they were not present in Std), but a reviewer may wish to re-check.

List.mem_map changed statement from b ∈ l.map f ↔ ∃ a, a ∈ l ∧ b = f a to b ∈ l.map f ↔ ∃ a, a ∈ l ∧ f a = b. Similarly for List.exists_of_mem_map. This was a deliberate change, so I have simply adjusted proofs (many become simpler, which supports the change). I also deleted List.mem_map', List.exists_of_mem_map', which were temporary versions in Mathlib while waiting for this change (replacing their uses with the unprimed versions).

Also, the lemma sublist_nil_iff_eq_nil seems to have been renamed to sublist_nil during the move, so I added an alias for the old name.

(another issue fixed during review by @digama0) List.Sublist.filter had an argument change from explicit to implicit. This appears to have been an oversight (cc @JamesGallicchio). I have temporarily introduced List.Sublist.filter' with the argument explicit, and replaced Mathlib uses of Sublist.filter with Sublist.filter'. Later we can fix the argument in Std, and then delete List.Sublist.filter'.

Diff
@@ -100,8 +100,6 @@ theorem _root_.Decidable.List.eq_or_ne_mem_of_mem [DecidableEq α]
 alias mem_cons ↔ eq_or_mem_of_mem_cons _
 #align list.eq_or_mem_of_mem_cons List.eq_or_mem_of_mem_cons
 
-theorem not_mem_append {a : α} {s t : List α} (h₁ : a ∉ s) (h₂ : a ∉ t) : a ∉ s ++ t :=
-mt mem_append.1 $ not_or.mpr ⟨h₁, h₂⟩
 #align list.not_mem_append List.not_mem_append
 
 #align list.ne_nil_of_mem List.ne_nil_of_mem
@@ -113,34 +111,19 @@ theorem mem_split {a : α} {l : List α} (h : a ∈ l) : ∃ s t : List α, l =
     exact ⟨b :: s, t, rfl⟩
 #align list.mem_split List.mem_split
 
-theorem mem_of_ne_of_mem {a y : α} {l : List α} (h₁ : a ≠ y) (h₂ : a ∈ y :: l) : a ∈ l :=
-Or.elim (eq_or_mem_of_mem_cons h₂) (fun e ↦ absurd e h₁) (fun r ↦ r)
 #align list.mem_of_ne_of_mem List.mem_of_ne_of_mem
 
-theorem ne_of_not_mem_cons {a b : α} {l : List α} : (a ∉ b::l) → a ≠ b :=
-fun nin aeqb ↦ absurd (aeqb ▸ Mem.head ..) nin
 #align list.ne_of_not_mem_cons List.ne_of_not_mem_cons
 
-theorem not_mem_of_not_mem_cons {a b : α} {l : List α} : (a ∉ b::l) → a ∉ l :=
-fun nin nainl ↦ absurd (Mem.tail _ nainl) nin
 #align list.not_mem_of_not_mem_cons List.not_mem_of_not_mem_cons
 
-theorem not_mem_cons_of_ne_of_not_mem {a y : α} {l : List α} : a ≠ y → (a ∉ l) → (a ∉ y::l) :=
-fun p1 p2 Pain ↦ absurd (eq_or_mem_of_mem_cons Pain) (not_or.mpr ⟨p1, p2⟩)
 #align list.not_mem_cons_of_ne_of_not_mem List.not_mem_cons_of_ne_of_not_mem
 
-theorem ne_and_not_mem_of_not_mem_cons {a y : α} {l : List α} : (a ∉ y::l) → a ≠ y ∧ a ∉ l :=
-fun p ↦ ⟨ne_of_not_mem_cons p, not_mem_of_not_mem_cons p⟩
 #align list.ne_and_not_mem_of_not_mem_cons List.ne_and_not_mem_of_not_mem_cons
 
--- Porting TODO: fix `List.mem_map` in Std to this statement.
-@[simp]
-theorem mem_map' {f : α → β} {b : β} {l : List α} : b ∈ map f l ↔ ∃ a, a ∈ l ∧ f a = b := by
-  simp only [List.mem_map, eq_comm]
-#align list.mem_map List.mem_map'
+#align list.mem_map List.mem_map
 
-alias mem_map' ↔ exists_of_mem_map' _
-#align list.exists_of_mem_map List.exists_of_mem_map'
+#align list.exists_of_mem_map List.exists_of_mem_map
 
 #align list.mem_map_of_mem List.mem_map_of_memₓ -- implicits order
 
@@ -156,7 +139,7 @@ theorem _root_.Function.Involutive.exists_mem_and_apply_eq_iff {f : α → α}
 #align function.involutive.exists_mem_and_apply_eq_iff Function.Involutive.exists_mem_and_apply_eq_iff
 
 theorem mem_map_of_involutive {f : α → α} (hf : Involutive f) {a : α} {l : List α} :
-    a ∈ map f l ↔ f a ∈ l := by rw [mem_map', hf.exists_mem_and_apply_eq_iff]
+    a ∈ map f l ↔ f a ∈ l := by rw [mem_map, hf.exists_mem_and_apply_eq_iff]
 #align list.mem_map_of_involutive List.mem_map_of_involutive
 
 #align list.forall_mem_map_iff List.forall_mem_map_iffₓ -- universe order
@@ -451,12 +434,8 @@ theorem eq_replicate_length {a : α} : ∀ {l : List α}, l = replicate l.length
   | (b :: l) => by simp [eq_replicate_length]
 #align list.eq_replicate_length List.eq_replicate_length
 
-alias eq_replicate_length ↔ _ eq_replicate_of_mem
 #align list.eq_replicate_of_mem List.eq_replicate_of_mem
 
-theorem eq_replicate {a : α} {n} {l} : l = replicate n a ↔ length l = n ∧ ∀ b ∈ l, b = a :=
-  ⟨fun h => h.symm ▸ ⟨length_replicate _ _, fun _ => eq_of_mem_replicate⟩, fun ⟨e, al⟩ =>
-    e ▸ eq_replicate_of_mem al⟩
 #align list.eq_replicate List.eq_replicate
 
 theorem replicate_add (m n) (a : α) : replicate (m + n) a = replicate m a ++ replicate n a := by
@@ -1094,27 +1073,16 @@ theorem cons_sublist_cons_iff {l₁ l₂ : List α} {a : α} : a :: l₁ <+ a ::
 #align list.sublist.append List.Sublist.append
 #align list.sublist.subset List.Sublist.subset
 
-@[simp]
-theorem singleton_sublist {a : α} {l} : [a] <+ l ↔ a ∈ l :=
-  ⟨fun h => h.subset (mem_singleton_self _), fun h =>
-    let ⟨_, _, e⟩ := mem_split h
-    e.symm ▸ ((nil_sublist _).cons_cons _).trans (sublist_append_right _ _)⟩
 #align list.singleton_sublist List.singleton_sublist
 
 theorem eq_nil_of_sublist_nil {l : List α} (s : l <+ []) : l = [] :=
   eq_nil_of_subset_nil <| s.subset
 #align list.eq_nil_of_sublist_nil List.eq_nil_of_sublist_nil
 
-@[simp]
-theorem sublist_nil_iff_eq_nil {l : List α} : l <+ [] ↔ l = [] :=
-  ⟨eq_nil_of_sublist_nil, fun H => H ▸ Sublist.refl _⟩
+-- Porting note: this lemma seems to have been renamed on the occasion of its move to Std4
+alias sublist_nil ← sublist_nil_iff_eq_nil
 #align list.sublist_nil_iff_eq_nil List.sublist_nil_iff_eq_nil
 
-@[simp]
-theorem replicate_sublist_replicate {m n} (a : α) :
-    replicate m a <+ replicate n a ↔ m ≤ n :=
-  ⟨fun h => by simpa only [length_replicate] using h.length_le, fun h => by
-    induction h <;> [rfl, simp only [*, replicate_succ, Sublist.cons]]⟩
 #align list.replicate_sublist_replicate List.replicate_sublist_replicate
 
 theorem sublist_replicate_iff {l : List α} {a : α} {n : ℕ} :
@@ -1125,16 +1093,8 @@ theorem sublist_replicate_iff {l : List α} {a : α} {n : ℕ} :
     by rintro ⟨k, h, rfl⟩; exact (replicate_sublist_replicate _).mpr h⟩
 #align list.sublist_replicate_iff List.sublist_replicate_iff
 
-theorem Sublist.eq_of_length : ∀ {l₁ l₂ : List α}, l₁ <+ l₂ → length l₁ = length l₂ → l₁ = l₂
-  | _, _, Sublist.slnil, _ => rfl
-  | _, _, Sublist.cons a s, h => by
-    cases s.length_le.not_lt (by rw [h]; apply lt_succ_self)
-  | _, _, Sublist.cons₂ a s, h => by
-    rw [length, length] at h; injection h with h; rw [s.eq_of_length h]
 #align list.sublist.eq_of_length List.Sublist.eq_of_length
 
-theorem Sublist.eq_of_length_le (s : l₁ <+ l₂) (h : length l₂ ≤ length l₁) : l₁ = l₂ :=
-  s.eq_of_length <| s.length_le.antisymm h
 #align list.sublist.eq_of_length_le List.Sublist.eq_of_length_le
 
 theorem Sublist.antisymm (s₁ : l₁ <+ l₂) (s₂ : l₂ <+ l₁) : l₁ = l₂ :=
@@ -3330,35 +3290,19 @@ theorem find?_nil (p : α → Bool) : find? p [] = none :=
 
 -- Porting note: List.find? is given @[simp] in Std.Data.List.Init.Lemmas
 -- @[simp]
-@[simp 1100, nolint simpNF]
-theorem find?_cons_of_pos (l) (h : p a) : find? p (a :: l) = some a :=
-  by simp [find?, h]
+-- Later porting note (at time of this lemma moving to Std): removing attribute `nolint simpNF`
+attribute [simp 1100] find?_cons_of_pos
 #align list.find_cons_of_pos List.find?_cons_of_pos
 
 -- Porting note: List.find? is given @[simp] in Std.Data.List.Init.Lemmas
 -- @[simp]
-@[simp 1100, nolint simpNF]
-theorem find?_cons_of_neg (l) (h : ¬p a) : find? p (a :: l) = find? p l :=
-  by simp [find?, h]
+-- Later porting note (at time of this lemma moving to Std): removing attribute `nolint simpNF`
+attribute [simp 1100] find?_cons_of_neg
 #align list.find_cons_of_neg List.find?_cons_of_neg
 
-@[simp]
-theorem find?_eq_none : find? p l = none ↔ ∀ x ∈ l, ¬p x := by
-  induction' l with a l IH
-  · exact iff_of_true rfl (forall_mem_nil _)
-  rw [forall_mem_cons]; by_cases h : p a
-  · simp only [find?_cons_of_pos _ h, h, not_true, false_and_iff]
-  · rwa [find?_cons_of_neg _ h, iff_true_intro h, true_and_iff]
+attribute [simp] find?_eq_none
 #align list.find_eq_none List.find?_eq_none
 
-theorem find?_some (H : find? p l = some a) : p a := by
-  induction' l with b l IH; · contradiction
-  by_cases h : p b
-  · rw [find?_cons_of_pos _ h] at H
-    cases H
-    exact h
-  · rw [find?_cons_of_neg _ h] at H
-    exact IH H
 #align list.find_some List.find?_some
 
 @[simp]
@@ -3456,191 +3400,63 @@ end Lookmap
 /-! ### filter -/
 -- Porting note: These lemmas are from Lean3 core
 
-@[simp] theorem filter_nil (p : α → Bool) : filter p [] = [] := rfl
 #align list.filter_nil List.filter_nil
 
-@[simp] theorem filter_cons_of_pos {p : α → Bool} {a : α} :
-   ∀ l, p a → filter p (a::l) = a :: filter p l :=
-fun l pa => by rw [filter, pa]
 #align list.filter_cons_of_pos List.filter_cons_of_pos
 
-@[simp] theorem filter_cons_of_neg {p : α → Bool} {a : α} :
-  ∀ l, ¬ p a → filter p (a::l) = filter p l :=
-fun l pa => by rw [filter, eq_false_of_ne_true pa]
 #align list.filter_cons_of_neg List.filter_cons_of_neg
 
-@[simp] theorem filter_append {p : α → Bool} :
-  ∀ (l₁ l₂ : List α), filter p (l₁++l₂) = filter p l₁ ++ filter p l₂
-| [],    l₂ => rfl
-| a::l₁, l₂ => by rw [cons_append, filter, filter]; cases p a <;> dsimp <;> rw [filter_append l₁]
 #align list.filter_append List.filter_append
 
-@[simp] theorem filter_sublist {p : α → Bool} :
-    ∀ (l : List α), filter p l <+ l
-| []     => Sublist.slnil
-| (a::l) => by
-  rw [filter]
-  cases p a
-  . exact Sublist.cons _ (filter_sublist l)
-  . exact Sublist.cons₂ _ (filter_sublist l)
 #align list.filter_sublist List.filter_sublist
 
 /-! ### filterMap -/
 
-@[simp]
-theorem filterMap_nil (f : α → Option β) : filterMap f [] = [] :=
-  rfl
 #align list.filter_map_nil List.filterMap_nil
 
 -- Porting note: List.filterMap is given @[simp] in Std.Data.List.Init.Lemmas
 -- @[simp]
-@[simp 1100, nolint simpNF]
-theorem filterMap_cons_none {f : α → Option β} (a : α) (l : List α) (h : f a = none) :
-    filterMap f (a :: l) = filterMap f l := by simp only [filterMap, h]
+-- Later porting note (at time of this lemma moving to Std): removing attribute `nolint simpNF`
+attribute [simp 1100] filterMap_cons_none
 #align list.filter_map_cons_none List.filterMap_cons_none
 
 -- @[simp]
-@[simp 1100, nolint simpNF]
-theorem filterMap_cons_some (f : α → Option β) (a : α) (l : List α) {b : β} (h : f a = some b) :
-    filterMap f (a :: l) = b :: filterMap f l := by
-  simp only [filterMap, h]
+-- Later porting note (at time of this lemma moving to Std): removing attribute `nolint simpNF`
+attribute [simp 1100] filterMap_cons_some
 #align list.filter_map_cons_some List.filterMap_cons_some
 
-theorem filterMap_cons (f : α → Option β) (a : α) (l : List α) :
-    filterMap f (a :: l) = Option.casesOn (f a) (filterMap f l) fun b => b :: filterMap f l := by
-  generalize eq : f a = b
-  cases b
-  · rw [filterMap_cons_none _ _ eq]
-  · rw [filterMap_cons_some _ _ _ eq]
 #align list.filter_map_cons List.filterMap_cons
 
-theorem filterMap_append {α β : Type _} (l l' : List α) (f : α → Option β) :
-    filterMap f (l ++ l') = filterMap f l ++ filterMap f l' := by
-  induction' l with hd tl hl generalizing l'
-  · simp
-  · rw [cons_append, filterMap, filterMap]
-    cases f hd <;> simp only [filterMap, hl, cons_append, eq_self_iff_true, and_self_iff]
 #align list.filter_map_append List.filterMap_append
 
-theorem filterMap_eq_map (f : α → β) : filterMap (some ∘ f) = map f := by
-  funext l
-  induction' l with a l IH; · rfl
-  simp only [filterMap_cons_some (some ∘ f) _ _ rfl, IH, map_cons]
 #align list.filter_map_eq_map List.filterMap_eq_map
 
-theorem filterMap_eq_filter (p : α → Bool) :
-    filterMap (Option.guard (p ·)) = filter p := by
-  funext l
-  induction' l with a l IH; · rfl
-  by_cases pa : p a
-  · simp only [filterMap, Option.guard, pa, ite_true, filter, decide_True, ← IH]
-  · simp only [filterMap, Option.guard, pa, ite_false, filter, decide_False, ← IH]
 #align list.filter_map_eq_filter List.filterMap_eq_filter
 
-theorem filterMap_filterMap (f : α → Option β) (g : β → Option γ) (l : List α) :
-    filterMap g (filterMap f l) = filterMap (fun x => (f x).bind g) l := by
-  induction' l with a l IH; · rfl
-  cases' h : f a with b
-  · rw [filterMap_cons_none _ _ h, filterMap_cons_none, IH]
-    simp only [h, Option.none_bind']
-  rw [filterMap_cons_some _ _ _ h]
-  cases' h' : g b with c <;> [rw [filterMap_cons_none _ _ h', filterMap_cons_none, IH],
-      rw [filterMap_cons_some _ _ _ h', filterMap_cons_some, IH]] <;>
-    simp only [h, h', Option.some_bind']
 #align list.filter_map_filter_map List.filterMap_filterMap
 
-theorem map_filterMap (f : α → Option β) (g : β → γ) (l : List α) :
-    map g (filterMap f l) = filterMap (fun x => (f x).map g) l := by
-  simp only [← filterMap_eq_map, filterMap_filterMap, Option.map_eq_bind]
 #align list.map_filter_map List.map_filterMap
 
-theorem filterMap_map (f : α → β) (g : β → Option γ) (l : List α) :
-    filterMap g (map f l) = filterMap (g ∘ f) l := by
-  rw [← filterMap_eq_map, filterMap_filterMap]; rfl
 #align list.filter_map_map List.filterMap_map
 
-theorem filter_filterMap (f : α → Option β) (p : β → Bool) (l : List α) :
-    filter p (filterMap f l) = filterMap (fun x => (f x).filter p) l := by
-  rw [← filterMap_eq_filter, filterMap_filterMap]
-  congr
-  funext x
-  cases f x <;> simp [Option.filter, Option.guard]
 #align list.filter_filter_map List.filter_filterMap
 
-theorem filterMap_filter (p : α → Bool) (f : α → Option β) (l : List α) :
-    filterMap f (filter p l) = filterMap (fun x => if p x then f x else none) l := by
-  rw [← filterMap_eq_filter, filterMap_filterMap]; congr
-  funext x
-  by_cases h : p x <;> simp [Option.guard, h]
 #align list.filter_map_filter List.filterMap_filter
 
-@[simp]
-theorem filterMap_some (l : List α) : filterMap some l = l := by
-  erw [filterMap_eq_map]; apply map_id
 #align list.filter_map_some List.filterMap_some
 
-theorem map_filterMap_some_eq_filter_map_is_some (f : α → Option β) (l : List α) :
-    (l.filterMap f).map some = (l.map f).filter fun b => b.isSome := by
-  induction' l with x xs ih
-  · rfl
-  · cases h : f x <;> rw [List.filterMap_cons, h] <;> simp [h, ih]
 #align list.map_filter_map_some_eq_filter_map_is_some List.map_filterMap_some_eq_filter_map_is_some
 
-@[simp]
-theorem mem_filterMap (f : α → Option β) (l : List α) {b : β} :
-    b ∈ filterMap f l ↔ ∃ a, a ∈ l ∧ f a = some b := by
-  induction' l with a l IH
-  · constructor
-    · intro H
-      cases H
-    · rintro ⟨_, H, _⟩
-      cases H
-  cases' h : f a with b'
-  · have : f a ≠ some b := by
-      rw [h]
-      intro
-      contradiction
-    simp only [filterMap_cons_none _ _ h, IH, mem_cons, or_and_right, exists_or,
-      exists_eq_left, this, false_or_iff]
-  · have : f a = some b ↔ b = b' := by
-      constructor <;> intro t
-      · rw [t] at h; injection h
-      · exact t.symm ▸ h
-    simp only [filterMap_cons_some _ _ _ h, IH, mem_cons, or_and_right, exists_or, this,
-      exists_eq_left]
 #align list.mem_filter_map List.mem_filterMap
 
-@[simp]
-theorem filterMap_join (f : α → Option β) (L : List (List α)) :
-    filterMap f (join L) = join (map (filterMap f) L) := by
-  induction' L with hd tl ih
-  · rfl
-  · rw [map, join, join, filterMap_append, ih]
 #align list.filter_map_join List.filterMap_join
 
-theorem map_filterMap_of_inv (f : α → Option β) (g : β → α) (H : ∀ x : α, (f x).map g = some x)
-    (l : List α) : map g (filterMap f l) = l := by simp only [map_filterMap, H, filterMap_some]
 #align list.map_filter_map_of_inv List.map_filterMap_of_inv
 
-theorem length_filter_le (p : α → Bool) (l : List α) :
-    (l.filter p).length ≤ l.length :=
-  (List.filter_sublist _).length_le
 #align list.length_filter_le List.length_filter_leₓ
 
-theorem length_filterMap_le (f : α → Option β) (l : List α) :
-    (List.filterMap f l).length ≤ l.length := by
-  rw [←List.length_map _ some, List.map_filterMap_some_eq_filter_map_is_some, ←List.length_map _ f]
-  apply List.length_filter_le
 #align list.length_filter_map_le List.length_filterMap_le
 
-theorem Sublist.filterMap (f : α → Option β) {l₁ l₂ : List α} (s : l₁ <+ l₂) :
-    filterMap f l₁ <+ filterMap f l₂ := by
-  induction' s with l₁ l₂ a s IH l₁ l₂ a s IH
-  . simp
-  . rw [filterMap]
-    cases f a <;> simp [IH, Sublist.cons]
-  . rw [filterMap, filterMap]
-    cases f a <;> simp [IH, Sublist.cons₂]
 #align list.sublist.filter_map List.Sublist.filterMap
 
 theorem Sublist.map (f : α → β) {l₁ l₂ : List α} (s : l₁ <+ l₂) : map f l₁ <+ map f l₂ :=
@@ -3755,14 +3571,6 @@ theorem filter_eq_foldr (p : α → Bool) (l : List α) :
   induction l <;> simp [*, filter]; rfl
 #align list.filter_eq_foldr List.filter_eq_foldr
 
-theorem filter_congr' {p q : α → Bool} :
-    ∀ {l : List α}, (∀ x ∈ l, p x ↔ q x) → filter p l = filter q l
-  | [], _ => rfl
-  | a :: l, h => by
-    rw [forall_mem_cons] at h; by_cases pa : p a <;>
-      [simp only [filter_cons_of_pos _ pa, filter_cons_of_pos _ (h.1.1 pa), filter_congr' h.2],
-      simp only [filter_cons_of_neg _ pa, filter_cons_of_neg _ (mt h.1.2 pa),
-        filter_congr' h.2]]
 #align list.filter_congr' List.filter_congr'
 
 @[simp]
@@ -3801,32 +3609,14 @@ theorem monotone_filter_left (p : α → Bool) ⦃l l' : List α⦄ (h : l ⊆ l
   exact ⟨h hx.left, hx.right⟩
 #align list.monotone_filter_left List.monotone_filter_left
 
-theorem filter_eq_self {l} : filter p l = l ↔ ∀ a ∈ l, p a := by
-  induction' l with a l ih
-  · exact iff_of_true rfl (forall_mem_nil _)
-  rw [forall_mem_cons]
-  by_cases h : p a
-  · rw [filter_cons_of_pos _ h, cons_inj, ih, and_iff_right h]
-  · refine' iff_of_false (fun hl => h <| of_mem_filter (_ : a ∈ filter p (a :: l))) (mt And.left h)
-    rw [hl]
-    exact mem_cons_self _ _
 #align list.filter_eq_self List.filter_eq_self
 
-theorem filter_length_eq_length {l} : (filter p l).length = l.length ↔ ∀ a ∈ l, p a :=
-  Iff.trans ⟨l.filter_sublist.eq_of_length, congr_arg List.length⟩ filter_eq_self
 #align list.filter_length_eq_length List.filter_length_eq_length
 
-theorem filter_eq_nil {l} : filter p l = [] ↔ ∀ a ∈ l, ¬p a := by
-  simp only [eq_nil_iff_forall_not_mem, mem_filter, not_and]
 #align list.filter_eq_nil List.filter_eq_nil
 
 variable (p)
 
-theorem Sublist.filter {l₁ l₂} (s : l₁ <+ l₂) : filter p l₁ <+ filter p l₂ := by
-  have := filterMap_eq_filter (fun a => p a)
-  simp only [Bool.decide_coe] at this
-  rw [← this]
-  apply s.filterMap
 #align list.sublist.filter List.Sublist.filter
 
 theorem monotone_filter_right (l : List α) ⦃p q : α → Bool⦄
@@ -3844,18 +3634,8 @@ theorem monotone_filter_right (l : List α) ⦃p q : α → Bool⦄
         exact IH
 #align list.monotone_filter_right List.monotone_filter_right
 
-theorem map_filter (f : β → α) (l : List β) : filter p (map f l) = map f (filter (p ∘ f) l) := by
-  rw [← filterMap_eq_map, filter_filterMap, filterMap_filter]; rfl
 #align list.map_filter List.map_filter
 
-@[simp]
-theorem filter_filter (q) :
-    ∀ l, filter p (filter q l) = filter (fun a => p a ∧ q a) l
-  | [] => rfl
-  | a :: l => by
-    by_cases hp : p a <;> by_cases hq : q a <;>
-      simp only [hp, hq, filter, if_true, if_false, true_and_iff, false_and_iff, filter_filter _ l,
-        eq_self_iff_true, decide_True, decide_False]
 #align list.filter_filter List.filter_filter
 
 @[simp]
@@ -4013,8 +3793,6 @@ variable [DecidableEq α]
 #align list.erase_sublist List.erase_sublistₓ -- DecidableEq -> BEq
 #align list.erase_subset List.erase_subsetₓ -- DecidableEq -> BEq
 
-theorem Sublist.erase (a : α) {l₁ l₂ : List α} (h : l₁ <+ l₂) : l₁.erase a <+ l₂.erase a := by
-  simp [erase_eq_eraseP]; exact Sublist.eraseP h
 #align list.sublist.erase List.Sublist.eraseₓ -- DecidableEq -> BEq
 
 #align list.mem_of_mem_erase List.mem_of_mem_eraseₓ -- DecidableEq -> BEq
@@ -4040,57 +3818,24 @@ section Diff
 
 variable [DecidableEq α]
 
-@[simp]
-theorem diff_nil (l : List α) : l.diff [] = l :=
-  rfl
 #align list.diff_nil List.diff_nil
 
-@[simp]
-theorem diff_cons (l₁ l₂ : List α) (a : α) : l₁.diff (a :: l₂) = (l₁.erase a).diff l₂ :=
-  if h : elem a l₁ then by simp only [List.diff, if_pos h]
-  else by simp only [List.diff, if_neg h, erase_of_not_mem (mt elem_eq_true_of_mem h)]
 #align list.diff_cons List.diff_cons
 
-theorem diff_cons_right (l₁ l₂ : List α) (a : α) : l₁.diff (a :: l₂) = (l₁.diff l₂).erase a := by
-  induction' l₂ with b l₂ ih generalizing l₁ a
-  · simp_rw [diff_cons, diff_nil]
-  · rw [diff_cons, diff_cons, erase_comm, ← diff_cons, ih, ← diff_cons]
 #align list.diff_cons_right List.diff_cons_right
 
-theorem diff_erase (l₁ l₂ : List α) (a : α) : (l₁.diff l₂).erase a = (l₁.erase a).diff l₂ := by
-  rw [← diff_cons_right, diff_cons]
 #align list.diff_erase List.diff_erase
 
-@[simp]
-theorem nil_diff (l : List α) : [].diff l = [] := by
-  induction l <;> [rfl, simp only [*, diff_cons, erase_of_not_mem (not_mem_nil _)]]
 #align list.nil_diff List.nil_diff
 
-theorem cons_diff (a : α) (l₁ l₂ : List α) :
-    (a :: l₁).diff l₂ = if a ∈ l₂ then l₁.diff (l₂.erase a) else a :: l₁.diff l₂ := by
-  induction' l₂ with b l₂ ih; · rfl
-  rcases eq_or_ne a b with (rfl | hne)
-  · simp
-  · simp only [mem_cons, *, false_or_iff, diff_cons_right]
-    split_ifs with h₂ <;> simp [diff_erase, List.erase, mt eq_of_beq hne, mt eq_of_beq hne.symm]
 #align list.cons_diff List.cons_diff
 
-theorem cons_diff_of_mem {a : α} {l₂ : List α} (h : a ∈ l₂) (l₁ : List α) :
-    (a :: l₁).diff l₂ = l₁.diff (l₂.erase a) := by rw [cons_diff, if_pos h]
 #align list.cons_diff_of_mem List.cons_diff_of_mem
 
-theorem cons_diff_of_not_mem {a : α} {l₂ : List α} (h : a ∉ l₂) (l₁ : List α) :
-    (a :: l₁).diff l₂ = a :: l₁.diff l₂ := by rw [cons_diff, if_neg h]
 #align list.cons_diff_of_not_mem List.cons_diff_of_not_mem
 
-theorem diff_eq_foldl : ∀ l₁ l₂ : List α, l₁.diff l₂ = foldl List.erase l₁ l₂
-  | _, [] => rfl
-  | l₁, a :: l₂ => (diff_cons l₁ l₂ a).trans (diff_eq_foldl _ _)
 #align list.diff_eq_foldl List.diff_eq_foldl
 
-@[simp]
-theorem diff_append (l₁ l₂ l₃ : List α) : l₁.diff (l₂ ++ l₃) = (l₁.diff l₂).diff l₃ := by
-  simp only [diff_eq_foldl, foldl_append]
 #align list.diff_append List.diff_append
 
 @[simp]
@@ -4099,31 +3844,12 @@ theorem map_diff [DecidableEq β] {f : α → β} (finj : Injective f) {l₁ l
   simp only [diff_eq_foldl, foldl_map, map_foldl_erase finj]
 #align list.map_diff List.map_diff
 
-theorem diff_sublist : ∀ l₁ l₂ : List α, l₁.diff l₂ <+ l₁
-  | _, [] => Sublist.refl _
-  | l₁, a :: l₂ =>
-    calc
-      l₁.diff (a :: l₂) = (l₁.erase a).diff l₂ := diff_cons _ _ _
-      _ <+ l₁.erase a := diff_sublist _ _
-      _ <+ l₁ := List.erase_sublist _ _
 #align list.diff_sublist List.diff_sublist
 
-theorem diff_subset (l₁ l₂ : List α) : l₁.diff l₂ ⊆ l₁ :=
-  (diff_sublist _ _).subset
 #align list.diff_subset List.diff_subset
 
-theorem mem_diff_of_mem {a : α} : ∀ {l₁ l₂ : List α}, a ∈ l₁ → a ∉ l₂ → a ∈ l₁.diff l₂
-  | _, [], h₁, _ => h₁
-  | l₁, b :: l₂, h₁, h₂ => by
-    rw [diff_cons] ;
-      exact
-        mem_diff_of_mem ((mem_erase_of_ne (ne_of_not_mem_cons h₂)).2 h₁)
-          (not_mem_of_not_mem_cons h₂)
 #align list.mem_diff_of_mem List.mem_diff_of_mem
 
-theorem Sublist.diff_right : ∀ {l₁ l₂ l₃ : List α}, l₁ <+ l₂ → l₁.diff l₃ <+ l₂.diff l₃
-  | _,  _, [], h => h
-  | l₁, l₂, a :: l₃, h => by simp only [diff_cons, (h.erase _).diff_right]
 #align list.sublist.diff_right List.Sublist.diff_right
 
 theorem erase_diff_erase_sublist_of_sublist {a : α} :
feat: port/Computability.Primrec (#2360)

Co-authored-by: prakol16 <prakol16@users.noreply.github.com>

Diff
@@ -1179,10 +1179,29 @@ theorem indexOf_nil (a : α) : indexOf a [] = 0 :=
   The ported versions of the earlier proofs are given in comments.
 -/
 
+-- Porting note: these lemmas recover the Lean 3 definition of `findIdx`
+@[simp] theorem findIdx_nil {α : Type _} (p : α → Bool) :
+  [].findIdx p = 0 := rfl
+
+theorem findIdx_cons (p : α → Bool) (b : α) (l : List α) :
+    (b :: l).findIdx p = bif p b then 0 else (l.findIdx p) + 1 := by
+    cases H : p b with
+      | true => simp [H, findIdx, findIdx.go]
+      | false => simp [H, findIdx, findIdx.go, findIdx_go_succ]
+  where
+    findIdx_go_succ (p : α → Bool) (l : List α) (n : ℕ) :
+        List.findIdx.go p l (n + 1) = (List.findIdx.go p l n) + 1 := by
+      cases l with
+      | nil => unfold List.findIdx.go; exact Nat.succ_eq_add_one n
+      | cons head tail =>
+        unfold List.findIdx.go
+        cases p head <;> simp only [cond_false, cond_true]
+        exact findIdx_go_succ p tail (n + 1)
+
 -- indexOf_cons_eq _ rfl
 @[simp]
 theorem indexOf_cons_self (a : α) (l : List α) : indexOf a (a :: l) = 0 := by
-  rw [indexOf, findIdx, findIdx.go, beq_self_eq_true, cond]
+  rw [indexOf, findIdx_cons, beq_self_eq_true, cond]
 #align list.index_of_cons_self List.indexOf_cons_self
 
 -- fun e => if_pos e
@@ -1193,36 +1212,15 @@ theorem indexOf_cons_eq {a b : α} (l : List α) : a = b → indexOf a (b :: l)
 -- fun n => if_neg n
 @[simp]
 theorem indexOf_cons_ne {a b : α} (l : List α) : a ≠ b → indexOf a (b :: l) = succ (indexOf a l)
-  | n => by
-    cases l with
-    | nil => rw [indexOf, findIdx, findIdx.go, beq_false_of_ne n, cond, ←succ_eq_add_one]; rfl
-    | cons head tail =>
-      by_cases h : a = head
-      · rw [indexOf_cons_eq tail h, indexOf, findIdx, findIdx.go, beq_false_of_ne n, cond, h,
-          findIdx.go, beq_self_eq_true head, cond]
-      · rw [indexOf, findIdx, findIdx, findIdx.go, beq_false_of_ne, cond, findIdx.go,
-          beq_false_of_ne h, cond_false]
-        change _ = succ (cond (a == head) _ _)
-        rw [beq_false_of_ne h, cond_false]
-        simp only [findIdx_go_succ (fun x ↦ a == x) tail _]
-        exact n
-where
-  findIdx_go_succ (p : α → Bool) (l : List α) (n : ℕ) :
-      findIdx.go p l (n + 1) = succ (findIdx.go p l n) := by
-    cases l with
-    | nil => unfold findIdx.go; exact succ_eq_add_one n
-    | cons head tail =>
-      unfold findIdx.go
-      cases p head <;> simp only [cond]
-      · exact findIdx_go_succ p tail (n + 1)
+  | h => by simp only [indexOf, findIdx_cons, Bool.cond_eq_ite, beq_iff_eq, h, ite_false]
+
 #align list.index_of_cons_ne List.indexOf_cons_ne
 
 -- rfl
 theorem indexOf_cons (a b : α) (l : List α) :
     indexOf a (b :: l) = if a = b then 0 else succ (indexOf a l) := by
-  cases l <;> by_cases h : a = b
-  case pos | pos => rw [if_pos h]; exact indexOf_cons_eq _ h
-  case neg | neg => rw [if_neg h]; exact indexOf_cons_ne _ h
+  simp only [indexOf, findIdx_cons, Bool.cond_eq_ite, beq_iff_eq]
+
 #align list.index_of_cons List.indexOf_cons
 
 theorem indexOf_eq_length {a : α} {l : List α} : indexOf a l = length l ↔ a ∉ l := by
feat: forward-port leanprover-community/mathlib#18489 (#2469)

Co-authored-by: Jon Eugster <eugster.jon@gmail.com>

Diff
@@ -4,7 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE.
 Authors: Parikshit Khanna, Jeremy Avigad, Leonardo de Moura, Floris van Doorn, Mario Carneiro
 
 ! This file was ported from Lean 3 source module data.list.basic
-! leanprover-community/mathlib commit 1447cae870f372074e480de1acbeb51de0077698
+! leanprover-community/mathlib commit 9da1b3534b65d9661eb8f42443598a92bbb49211
 ! Please do not edit these lines, except to modify the commit id
 ! if you have ported upstream changes.
 -/
@@ -4253,6 +4253,28 @@ theorem map_fst_add_enum_eq_enumFrom (l : List α) (n : ℕ) :
   map_fst_add_enumFrom_eq_enumFrom l _ _
 #align list.map_fst_add_enum_eq_enum_from List.map_fst_add_enum_eq_enumFrom
 
+theorem enumFrom_cons' (n : ℕ) (x : α) (xs : List α) :
+    enumFrom n (x :: xs) = (n, x) :: (enumFrom n xs).map (Prod.map Nat.succ id) := by
+  rw [enumFrom_cons, add_comm, ← map_fst_add_enumFrom_eq_enumFrom]
+#align list.enum_from_cons' List.enumFrom_cons'
+
+theorem enum_cons' (x : α) (xs : List α) :
+    enum (x :: xs) = (0, x) :: (enum xs).map (Prod.map Nat.succ id) :=
+  enumFrom_cons' _ _ _
+#align list.enum_cons' List.enum_cons'
+
+theorem enumFrom_map (n : ℕ) (l : List α) (f : α → β) :
+    enumFrom n (l.map f) = (enumFrom n l).map (Prod.map id f) := by
+  induction' l with hd tl IH
+  · rfl
+  · rw [map_cons, enumFrom_cons', enumFrom_cons', map_cons, map_map, IH, map_map]
+    rfl
+#align list.enum_from_map List.enumFrom_map
+
+theorem enum_map (l : List α) (f : α → β) : (l.map f).enum = l.enum.map (Prod.map id f) :=
+  enumFrom_map _ _ _
+#align list.enum_map List.enum_map
+
 theorem get_enumFrom (l : List α) (n) (i : Fin (l.enumFrom n).length)
     (hi : i.1 < l.length := (by simpa [length_enumFrom] using i.2)) :
     (l.enumFrom n).get i = (n + i, l.get ⟨i, hi⟩) := by
chore: add missing hypothesis names to by_cases (#2679)
Diff
@@ -1197,7 +1197,7 @@ theorem indexOf_cons_ne {a b : α} (l : List α) : a ≠ b → indexOf a (b :: l
     cases l with
     | nil => rw [indexOf, findIdx, findIdx.go, beq_false_of_ne n, cond, ←succ_eq_add_one]; rfl
     | cons head tail =>
-      by_cases a = head
+      by_cases h : a = head
       · rw [indexOf_cons_eq tail h, indexOf, findIdx, findIdx.go, beq_false_of_ne n, cond, h,
           findIdx.go, beq_self_eq_true head, cond]
       · rw [indexOf, findIdx, findIdx, findIdx.go, beq_false_of_ne, cond, findIdx.go,
@@ -1220,7 +1220,7 @@ where
 -- rfl
 theorem indexOf_cons (a b : α) (l : List α) :
     indexOf a (b :: l) = if a = b then 0 else succ (indexOf a l) := by
-  cases l <;> by_cases a = b
+  cases l <;> by_cases h : a = b
   case pos | pos => rw [if_pos h]; exact indexOf_cons_eq _ h
   case neg | neg => rw [if_neg h]; exact indexOf_cons_ne _ h
 #align list.index_of_cons List.indexOf_cons
@@ -2910,7 +2910,7 @@ variable (p : α → Bool) (xs ys : List α) (ls : List (List α)) (f : List α
 
 @[simp]
 theorem splitAt_eq_take_drop (n : ℕ) (l : List α) : splitAt n l = (take n l, drop n l) := by
-  by_cases n < l.length <;> rw [splitAt, go_eq_take_drop]
+  by_cases h : n < l.length <;> rw [splitAt, go_eq_take_drop]
   · rw [if_pos h]; rfl
   · rw [if_neg h, take_all_of_le <| le_of_not_lt h, drop_eq_nil_of_le <| le_of_not_lt h]
 where
@@ -2969,7 +2969,7 @@ theorem splitOnP.go_append (xs : List α) (acc : Array α) (r : Array (List α))
   | nil => rfl
   | cons a as =>
     simp only [go]
-    by_cases p a
+    by_cases h : p a
     · simp only [h, cond_true]
       rw [go_append as, go_append as _ (Array.push #[] (Array.toList acc))]
       simp only [Array.toListAppend_eq, Array.push_data]
@@ -2983,7 +2983,7 @@ theorem splitOnP.go_acc (xs : List α) (acc : Array α) :
   | nil => rfl
   | cons hd tl =>
     simp only [go]
-    by_cases p hd
+    by_cases h : p hd
     · simp only [h, cond_true]
       rw [go_append, go_append _ _ _ (Array.push #[] (Array.toList #[]))]
       rfl
@@ -2999,7 +2999,7 @@ theorem splitOnP_ne_nil (xs : List α) : xs.splitOnP p ≠ [] := by
   | nil => exact cons_ne_nil [] []
   | cons hd tl =>
     rw [splitOnP, splitOnP.go]
-    by_cases p hd
+    by_cases h : p hd
     · rw [h, cond_true, splitOnP.go_append]
       exact append_ne_nil_of_ne_nil_left [[]] _ (cons_ne_nil [] [])
     · rw [eq_false_of_ne_true h, cond_false, splitOnP.go_acc, ←splitOnP]
@@ -3014,7 +3014,7 @@ theorem splitOnP_cons (x : α) (xs : List α) :
     (x :: xs).splitOnP p =
       if p x then [] :: xs.splitOnP p else (xs.splitOnP p).modifyHead (cons x) := by
   rw [splitOnP, splitOnP.go]
-  by_cases p x
+  by_cases h : p x
   · rw [if_pos h, h, cond_true, splitOnP.go_append, splitOnP]; rfl
   · rw [if_neg h, eq_false_of_ne_true h, cond_false, splitOnP.go_acc, splitOnP]; congr 1
 #align list.split_on_p_cons List.splitOnP_consₓ
@@ -3027,7 +3027,7 @@ theorem splitOnP_spec (as : List α) :
   | nil => rfl
   | cons a as' ih =>
     rw [splitOnP_cons, filter]
-    by_cases p a
+    by_cases h : p a
     · rw [if_pos h, h, map, cons_append, zipWith, nil_append, join, cons_append, cons_inj]
       exact ih
     · rw [if_neg h, eq_false_of_ne_true h, join_zipWith (splitOnP_ne_nil _ _)
@@ -3806,7 +3806,8 @@ theorem monotone_filter_left (p : α → Bool) ⦃l l' : List α⦄ (h : l ⊆ l
 theorem filter_eq_self {l} : filter p l = l ↔ ∀ a ∈ l, p a := by
   induction' l with a l ih
   · exact iff_of_true rfl (forall_mem_nil _)
-  rw [forall_mem_cons]; by_cases p a
+  rw [forall_mem_cons]
+  by_cases h : p a
   · rw [filter_cons_of_pos _ h, cons_inj, ih, and_iff_right h]
   · refine' iff_of_false (fun hl => h <| of_mem_filter (_ : a ∈ filter p (a :: l))) (mt And.left h)
     rw [hl]
chore: address some porting notes mentioning congr (#2595)

Switch to using congr! instead, which is analogous to mathlib 3's congr'.

Diff
@@ -1827,11 +1827,7 @@ theorem map_eq_map_iff {f g : α → β} {l : List α} : map f l = map g l ↔ 
   refine' ⟨_, map_congr⟩; intro h x hx
   rw [mem_iff_get] at hx; rcases hx with ⟨n, hn, rfl⟩
   rw [get_map_rev f, get_map_rev g]
-  -- Porting note: with `nthLe` instead of `get` the remainder of the proof is simply `congr`
-  generalize_proofs h₁ h₂
-  generalize map f l = x, map g l = y at *
-  cases h
-  congr
+  congr!
 #align list.map_eq_map_iff List.map_eq_map_iff
 
 theorem map_concat (f : α → β) (a : α) (l : List α) :
feat: add to_additive linter checking whether additive decl exists (#1881)
  • Force the user to specify whether the additive declaration already exists.
  • Will raise a linter error if the user specified it wrongly
  • Requested on Zulip
Diff
@@ -4609,8 +4609,8 @@ The list definitions happen earlier than `to_additive`, so here we tag the few m
 definitions that couldn't be tagged earlier.
 -/
 
-attribute [to_additive] List.prod -- `List.sum`
-attribute [to_additive] alternatingProd -- `List.alternatingSum`
+attribute [to_additive existing] List.prod -- `List.sum`
+attribute [to_additive existing] alternatingProd -- `List.alternatingSum`
 
 /-! ### Miscellaneous lemmas -/
 
Diff
@@ -4,7 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE.
 Authors: Parikshit Khanna, Jeremy Avigad, Leonardo de Moura, Floris van Doorn, Mario Carneiro
 
 ! This file was ported from Lean 3 source module data.list.basic
-! leanprover-community/mathlib commit cf9386b56953fb40904843af98b7a80757bbe7f9
+! leanprover-community/mathlib commit 1447cae870f372074e480de1acbeb51de0077698
 ! Please do not edit these lines, except to modify the commit id
 ! if you have ported upstream changes.
 -/
chore: tidy various files (#2251)
Diff
@@ -527,9 +527,8 @@ theorem bind_singleton (f : α → List β) (x : α) : [x].bind f = f x :=
 #align list.bind_singleton' List.bind_singleton'
 
 theorem map_eq_bind {α β} (f : α → β) (l : List α) : map f l = l.bind fun x => [f x] := by
-  trans
-  rw [← bind_singleton' l, bind_map]
-  rfl
+  simp_rw [←map_singleton]
+  rw [← bind_singleton' l, bind_map, bind_singleton']
 #align list.map_eq_bind List.map_eq_bind
 
 theorem bind_assoc {α β} (l : List α) (f : α → List β) (g : β → List γ) :
@@ -717,9 +716,7 @@ theorem dropLast_cons_cons (a b : α) (l : List α) : dropLast (a::b::l) = a::dr
 
 /-! ### getLast -/
 
--- Porting note: TODO: After https://github.com/leanprover/std4/pull/75, change to:
--- @[simp]
-@[simp 1100, nolint simpNF]
+@[simp]
 theorem getLast_cons {a : α} {l : List α} :
     ∀ h : l ≠ nil, getLast (a :: l) (cons_ne_nil a l) = getLast l h := by
   induction l <;> intros
@@ -746,9 +743,7 @@ theorem getLast_concat' {a : α} (l : List α) : getLast (concat l a) (concat_ne
   getLast_concat ..
 #align list.last_concat List.getLast_concat'
 
--- Porting note: TODO: After https://github.com/leanprover/std4/pull/75, change to:
--- @[simp]
-@[simp 1100, nolint simpNF]
+@[simp]
 theorem getLast_singleton' (a : α) : getLast [a] (cons_ne_nil a []) = a := rfl
 #align list.last_singleton List.getLast_singleton'
 
@@ -790,15 +785,13 @@ theorem getLast_replicate_succ (m : ℕ) (a : α) :
 /-! ### getLast? -/
 
 -- Porting note: New lemma, since definition of getLast? is slightly different.
--- Porting note: TODO: After https://github.com/leanprover/std4/pull/75, change to:
--- @[simp]
-@[simp 1100, nolint simpNF] theorem getLast?_singleton (a : α) :
+@[simp]
+theorem getLast?_singleton (a : α) :
     getLast? [a] = a := rfl
 
 -- Porting note: Moved earlier in file, for use in subsequent lemmas.
--- Porting note: TODO: After https://github.com/leanprover/std4/pull/75, change to:
--- @[simp]
-@[simp 1100, nolint simpNF] theorem getLast?_cons_cons (a b : α) (l : List α) :
+@[simp]
+theorem getLast?_cons_cons (a b : α) (l : List α) :
     getLast? (a :: b :: l) = getLast? (b :: l) := rfl
 
 @[simp]
@@ -975,7 +968,9 @@ set_option linter.deprecated false -- TODO(Mario): make replacements for theorem
     (h' : i + 1 < l.length := (by simpa [← lt_tsub_iff_right] using h)) :
     l.tail.nthLe i h = l.nthLe (i + 1) h' := by
   -- Porting note: cases l <;> [cases h, rfl] fails
-  cases l; {cases h}; rfl
+  cases l
+  · cases h
+  · rfl
 #align list.nth_le_tail List.nthLe_tail
 
 theorem nthLe_cons_aux {l : List α} {a : α} {n} (hn : n ≠ 0) (h : n < (a :: l).length) :
@@ -1761,7 +1756,7 @@ theorem nthLe_insertNth_of_lt : ∀ (l : List α) (x : α) (n k : ℕ), k < n 
     (insertNth n x l).nthLe k hk' = l.nthLe k hk := @get_insertNth_of_lt _
 #align list.nth_le_insert_nth_of_lt List.nthLe_insertNth_of_lt
 
-@[simp, nolint simpNF] -- Porting note: bug in linter, see std4#78
+@[simp]
 theorem get_insertNth_self (l : List α) (x : α) (n : ℕ) (hn : n ≤ l.length)
     (hn' : n < (insertNth n x l).length := (by rwa [length_insertNth _ _ hn, Nat.lt_succ_iff])) :
     (insertNth n x l).get ⟨n, hn'⟩ = x := by
@@ -1774,7 +1769,7 @@ theorem get_insertNth_self (l : List α) (x : α) (n : ℕ) (hn : n ≤ l.length
     · simp only [Nat.succ_le_succ_iff, length] at hn
       simpa using IH _ hn
 
-@[simp, deprecated get_insertNth_self, nolint simpNF] -- Porting note: bug in linter, see std4#78
+@[simp, deprecated get_insertNth_self]
 theorem nthLe_insertNth_self (l : List α) (x : α) (n : ℕ) (hn : n ≤ l.length)
     (hn' : n < (insertNth n x l).length := (by rwa [length_insertNth _ _ hn, Nat.lt_succ_iff])) :
     (insertNth n x l).nthLe n hn' = x := get_insertNth_self _ _ _ hn
@@ -1889,27 +1884,27 @@ theorem map_injective_iff {f : α → β} : Injective (map f) ↔ Injective f :=
     apply h
     simp [hxy]
   · induction' y with yh yt y_ih generalizing x
-    simpa using hxy
+    · simpa using hxy
     cases x
-    simp at hxy
-    simp at hxy
-    simp [y_ih hxy.2, h hxy.1]
+    · simp at hxy
+    · simp only [map, cons.injEq] at hxy
+      simp [y_ih hxy.2, h hxy.1]
 #align list.map_injective_iff List.map_injective_iff
 
-/-- A single `list.map` of a composition of functions is equal to
-composing a `list.map` with another `list.map`, fully applied.
-This is the reverse direction of `list.map_map`.
+/-- A single `List.map` of a composition of functions is equal to
+composing a `List.map` with another `List.map`, fully applied.
+This is the reverse direction of `List.map_map`.
 -/
 theorem comp_map (h : β → γ) (g : α → β) (l : List α) : map (h ∘ g) l = map h (map g l) :=
   (map_map _ _ _).symm
 #align list.comp_map List.comp_map
 
-/-- Composing a `list.map` with another `list.map` is equal to
-a single `list.map` of composed functions.
+/-- Composing a `List.map` with another `List.map` is equal to
+a single `List.map` of composed functions.
 -/
 @[simp]
 theorem map_comp_map (g : β → γ) (f : α → β) : map g ∘ map f = map (g ∘ f) := by
-  ext l; rw [comp_map]; rfl
+  ext l; rw [comp_map, Function.comp_apply]
 #align list.map_comp_map List.map_comp_map
 
 theorem map_filter_eq_foldr (f : α → β) (p : α → Bool) (as : List α) :
@@ -2645,7 +2640,6 @@ theorem foldlRecOn_nil {C : β → Sort _} (op : β → α → β) (b) (hb : C b
   rfl
 #align list.foldl_rec_on_nil List.foldlRecOn_nil
 
--- scanl
 section Scanl
 
 variable {f : β → α → β} {b : β} {a : α} {l : List α}
@@ -3116,7 +3110,7 @@ theorem splitOn_intercalate [DecidableEq α] (x : α) (hx : ∀ l ∈ ls, x ∉
 end SplitAtOn
 
 /- Porting note: new; here tentatively -/
-/-! ### ModifyLast -/
+/-! ### modifyLast -/
 
 section ModifyLast
 
@@ -4312,7 +4306,7 @@ end Choose
 section Map₂Left'
 
 -- The definitional equalities for `map₂Left'` can already be used by the
--- simplifie because `map₂Left'` is marked `@[simp]`.
+-- simplifier because `map₂Left'` is marked `@[simp]`.
 @[simp]
 theorem map₂Left'_nil_right (f : α → Option β → γ) (as) :
     map₂Left' f as [] = (as.map fun a => f a none, []) := by cases as <;> rfl
@@ -4615,8 +4609,8 @@ The list definitions happen earlier than `to_additive`, so here we tag the few m
 definitions that couldn't be tagged earlier.
 -/
 
-attribute [to_additive] List.prod -- `list.sum`
-attribute [to_additive] alternatingProd -- `list.alternatingSum`
+attribute [to_additive] List.prod -- `List.sum`
+attribute [to_additive] alternatingProd -- `List.alternatingSum`
 
 /-! ### Miscellaneous lemmas -/
 
chore: bump to leanprover/lean4:nightly-2023-02-10 (#2188)
Diff
@@ -1564,7 +1564,7 @@ theorem modifyNthTail_modifyNthTail_le {f g : List α → List α} (m n : ℕ) (
     (l.modifyNthTail f n).modifyNthTail g m =
       l.modifyNthTail (fun l => (f l).modifyNthTail g (m - n)) n := by
   rcases exists_add_of_le h with ⟨m, rfl⟩
-  rw [add_tsub_cancel_left, add_comm, modifyNthTail_modifyNthTail]
+  rw [@add_tsub_cancel_left, add_comm, modifyNthTail_modifyNthTail]
 #align list.modify_nth_tail_modify_nth_tail_le List.modifyNthTail_modifyNthTail_le
 
 theorem modifyNthTail_modifyNthTail_same {f g : List α → List α} (n : ℕ) (l : List α) :
@@ -2355,7 +2355,7 @@ theorem reverse_take {α} {xs : List α} (n : ℕ) (h : n ≤ xs.length) :
   · replace h' := le_of_succ_le_succ h'
     rw [take_append_of_le_length, xs_ih _ h']
     rw [show xs_tl.length + 1 - n = succ (xs_tl.length - n) from _, drop]
-    · rwa [succ_eq_add_one, ← tsub_add_eq_add_tsub]
+    · rwa [succ_eq_add_one, ← @tsub_add_eq_add_tsub]
     · rwa [length_reverse]
   · subst h'
     rw [length, tsub_self, drop]
chore: add #align statements for Core and Std (#1966)
Diff
@@ -18,8 +18,6 @@ import Std.Data.List.Lemmas
 # Basic properties of lists
 -/
 
-#align list.mem_cons_iff List.mem_cons
-
 open Function
 
 open Nat hiding one_pos
@@ -696,9 +694,6 @@ theorem mem_reverse' {a : α} {l : List α} : a ∈ reverse l ↔ a ∈ l :=
 
 /-! ### empty -/
 
--- Porting note: Definition from Lean3 core, so should be moved
-#align list.empty List.isEmpty
-
 -- Porting note: this does not work as desired
 -- attribute [simp] List.isEmpty
 
@@ -1064,8 +1059,6 @@ def bidirectionalRecOn {C : List α → Sort _} (l : List α) (H0 : C []) (H1 :
 
 attribute [refl] List.Sublist.refl
 
-#align list.sublist.cons2 List.Sublist.cons₂
-
 #align list.nil_sublist List.nil_sublist
 #align list.sublist.refl List.Sublist.refl
 #align list.sublist.trans List.Sublist.trans
chore: fix casing errors per naming scheme (#1670)
Diff
@@ -4737,7 +4737,7 @@ theorem getD_eq_default {n : ℕ} (hn : l.length ≤ n) : l.getD n d = d := by
 #align list.nthd_eq_default List.getD_eq_defaultₓ -- argument order
 
 /-- An empty list can always be decidably checked for the presence of an element.
-Not an instance because it would clash with `decidable_eq α`. -/
+Not an instance because it would clash with `DecidableEq α`. -/
 def decidableGetDNilNe {α} (a : α) : DecidablePred fun i : ℕ => getD ([] : List α) i a ≠ a :=
   fun _ => isFalse fun H => H (getD_nil _ _)
 #align list.decidable_nthd_nil_ne List.decidableGetDNilNeₓ -- argument order
Feat: add List.perm_replicate_append_replicate (#1509)

This is a forward-port of leanprover-community/mathlib#18126

Also golf a proof.

Diff
@@ -329,6 +329,9 @@ theorem exists_mem_cons_iff (p : α → Prop) (a : α) (l : List α) :
 
 /-! ### list subset -/
 
+instance : IsTrans (List α) Subset where
+  trans := fun _ _ _ => List.Subset.trans
+
 #align list.subset_def List.subset_def
 
 #align list.subset_append_of_subset_left List.subset_append_of_subset_left
chore: fix most phantom #aligns (#1794)
Diff
@@ -742,7 +742,7 @@ theorem getLast_append' (l₁ l₂ : List α) (h : l₂ ≠ []) :
   · simp only [cons_append]
     rw [List.getLast_cons]
     exact ih
-#align list.getLast_append List.getLast_append'
+#align list.last_append List.getLast_append'
 
 theorem getLast_concat' {a : α} (l : List α) : getLast (concat l a) (concat_ne_nil a l) = a :=
   getLast_concat ..
@@ -4460,7 +4460,7 @@ variable (f : Option α → β → γ) (a : α) (as : List α) (b : β) (bs : Li
 
 @[simp]
 theorem map₂Right_nil_left : map₂Right f [] bs = bs.map (f none) := by cases bs <;> rfl
-#align list.mapmap₂Right₂_right_nil_left List.map₂Right_nil_left
+#align list.map₂_right_nil_left List.map₂Right_nil_left
 
 @[simp]
 theorem map₂Right_nil_right : map₂Right f as [] = [] :=
chore: the style linter shouldn't complain about long #align lines (#1643)
Diff
@@ -155,9 +155,7 @@ theorem mem_map_of_injective {f : α → β} (H : Injective f) {a : α} {l : Lis
 theorem _root_.Function.Involutive.exists_mem_and_apply_eq_iff {f : α → α}
     (hf : Function.Involutive f) (x : α) (l : List α) : (∃ y : α, y ∈ l ∧ f y = x) ↔ f x ∈ l :=
   ⟨by rintro ⟨y, h, rfl⟩; rwa [hf y], fun h => ⟨f x, h, hf _⟩⟩
-#align
-  function.involutive.exists_mem_and_apply_eq_iff
-  Function.Involutive.exists_mem_and_apply_eq_iff
+#align function.involutive.exists_mem_and_apply_eq_iff Function.Involutive.exists_mem_and_apply_eq_iff
 
 theorem mem_map_of_involutive {f : α → α} (hf : Involutive f) {a : α} {l : List α} :
     a ∈ map f l ↔ f a ∈ l := by rw [mem_map', hf.exists_mem_and_apply_eq_iff]
Refactor: drop List.repeat (#1579)

Mathlib 3 migrated to list.replicate in leanprover-community/mathlib#18127 (merged) and leanprover-community/mathlib#18181 (awaiting review).

Diff
@@ -436,163 +436,81 @@ fun _ _ ↦ append_right_cancel
 
 #align list.map_eq_append_split List.map_eq_append_split
 
--- porting note: TODO: #align list.repeat List.replicate & theorems below?
-/-! ### repeat -/
+/-! ### replicate -/
 
 attribute [simp] replicate_succ
+#align list.replicate_succ List.replicate_succ
 
-theorem eq_replicate_of_mem {a : α} :
-    ∀ {l : List α}, (∀ b ∈ l, b = a) → l = List.replicate l.length a
-  | [], _ => rfl
-  | b :: l, H => by
-    rw [length_cons, List.replicate]
-    cases' forall_mem_cons.1 H with H₁ H₂
-    conv_lhs => rw [H₁, eq_replicate_of_mem H₂]
+@[simp] lemma replicate_zero (a : α) : replicate 0 a = [] := rfl
+#align list.replicate_zero List.replicate_zero
+
+lemma replicate_one (a : α) : replicate 1 a = [a] := rfl
+#align list.replicate_one List.replicate_one
 
-theorem eq_replicate' {a : α} {l : List α} : l = List.replicate l.length a ↔ ∀ b ∈ l, b = a :=
-  ⟨fun h => h.symm ▸ fun _ => eq_of_mem_replicate, eq_replicate_of_mem⟩
+theorem eq_replicate_length {a : α} : ∀ {l : List α}, l = replicate l.length a ↔ ∀ b ∈ l, b = a
+  | [] => by simp
+  | (b :: l) => by simp [eq_replicate_length]
+#align list.eq_replicate_length List.eq_replicate_length
+
+alias eq_replicate_length ↔ _ eq_replicate_of_mem
+#align list.eq_replicate_of_mem List.eq_replicate_of_mem
 
-theorem eq_replicate {a : α} {n} {l : List α} :
-    l = List.replicate n a ↔ length l = n ∧ ∀ b ∈ l, b = a :=
+theorem eq_replicate {a : α} {n} {l} : l = replicate n a ↔ length l = n ∧ ∀ b ∈ l, b = a :=
   ⟨fun h => h.symm ▸ ⟨length_replicate _ _, fun _ => eq_of_mem_replicate⟩, fun ⟨e, al⟩ =>
     e ▸ eq_replicate_of_mem al⟩
+#align list.eq_replicate List.eq_replicate
+
+theorem replicate_add (m n) (a : α) : replicate (m + n) a = replicate m a ++ replicate n a := by
+  induction m <;> simp [*, zero_add, succ_add, replicate]
+#align list.replicate_add List.replicate_add
 
-theorem replicate_add (a : α) (m n) :
-    List.replicate (m + n) a = List.replicate m a ++ List.replicate n a := by
-  induction m <;> simp [*, zero_add, succ_add, List.replicate]
+theorem replicate_succ' (n) (a : α) : replicate (n + 1) a = replicate n a ++ [a] :=
+  replicate_add n 1 a
+#align list.replicate_succ' List.replicate_succ'
 
-theorem replicate_subset_singleton (a : α) (n) : List.replicate n a ⊆ [a] := fun _ h =>
+theorem replicate_subset_singleton (n) (a : α) : replicate n a ⊆ [a] := fun _ h =>
   mem_singleton.2 (eq_of_mem_replicate h)
+#align list.replicate_subset_singleton List.replicate_subset_singleton
 
-theorem subset_singleton_iff {a : α} : ∀ L : List α, L ⊆ [a] ↔ ∃ n, L = List.replicate n a
-  | [] => ⟨fun _ => ⟨0, by simp⟩, by simp⟩
-  | h :: L => by
-    refine' ⟨fun h => _, fun ⟨k, hk⟩ => by simp [hk, replicate_subset_singleton]⟩
-    rw [cons_subset] at h
-    obtain ⟨n, rfl⟩ := (subset_singleton_iff L).mp h.2
-    exact ⟨n.succ, by simp [mem_singleton.mp h.1]⟩
+theorem subset_singleton_iff {a : α} {L : List α} : L ⊆ [a] ↔ ∃ n, L = replicate n a := by
+  simp only [eq_replicate, subset_def, mem_singleton, exists_eq_left']
+#align list.subset_singleton_iff List.subset_singleton_iff
 
-@[simp] theorem map_replicate (f : α → β) (a : α) (n) :
-    map f (List.replicate n a) = List.replicate n (f a) := by
-  induction n <;> [rfl, simp only [*, List.replicate, map]]
+@[simp] theorem map_replicate (f : α → β) (n) (a : α) :
+    map f (replicate n a) = replicate n (f a) := by
+  induction n <;> [rfl, simp only [*, replicate, map]]
+#align list.map_replicate List.map_replicate
 
 @[simp] theorem tail_replicate (a : α) (n) :
-    tail (List.replicate n a) = List.replicate n.pred a := by cases n <;> rfl
+    tail (replicate n a) = replicate (n - 1) a := by cases n <;> rfl
+#align list.tail_replicate List.tail_replicate
 
-@[simp] theorem join_replicate_nil (n : ℕ) : join (List.replicate n []) = @nil α := by
-  induction n <;> [rfl, simp only [*, List.replicate, join, append_nil]]
+@[simp] theorem join_replicate_nil (n : ℕ) : join (replicate n []) = @nil α := by
+  induction n <;> [rfl, simp only [*, replicate, join, append_nil]]
+#align list.join_replicate_nil List.join_replicate_nil
 
-theorem replicate_left_injective {n : ℕ} (hn : n ≠ 0) :
-    Function.Injective (@List.replicate α n ·) :=
+theorem replicate_right_injective {n : ℕ} (hn : n ≠ 0) : Injective (@replicate α n) :=
   fun _ _ h => (eq_replicate.1 h).2 _ <| mem_replicate.2 ⟨hn, rfl⟩
+#align list.replicate_right_injective List.replicate_right_injective
 
-theorem replicate_left_inj {a b : α} {n : ℕ} (hn : n ≠ 0) :
-    List.replicate n a = List.replicate n b ↔ a = b :=
-  (replicate_left_injective hn).eq_iff
+theorem replicate_right_inj {a b : α} {n : ℕ} (hn : n ≠ 0) :
+    replicate n a = replicate n b ↔ a = b :=
+  (replicate_right_injective hn).eq_iff
+#align list.replicate_right_inj List.replicate_right_inj
 
-@[simp] theorem replicate_left_inj' {a b : α} : ∀ {n},
-    List.replicate n a = List.replicate n b ↔ n = 0 ∨ a = b
+@[simp] theorem replicate_right_inj' {a b : α} : ∀ {n},
+    replicate n a = replicate n b ↔ n = 0 ∨ a = b
   | 0 => by simp
-  | n + 1 => (replicate_left_inj n.succ_ne_zero).trans <| by simp [n.succ_ne_zero, false_or_iff]
-
-theorem replicate_right_injective (a : α) : Function.Injective (List.replicate · a) :=
-  Function.LeftInverse.injective (length_replicate · a)
-
-@[simp]
-theorem replicate_right_inj {a : α} {n m : ℕ} :
-    List.replicate n a = List.replicate m a ↔ n = m :=
-  (replicate_right_injective a).eq_iff
-
-section deprecated
-set_option linter.deprecated false
-
--- Porting note: From Lean3 Core
-@[deprecated length_replicate]
-lemma length_repeat (a : α) (n : ℕ) : length (List.repeat a n) = n := length_replicate ..
-#align list.length_repeat List.length_repeat
-
-@[deprecated replicate_succ]
-theorem repeat_succ (a : α) (n) : List.repeat a (n + 1) = a :: List.repeat a n :=
-  rfl
-#align list.repeat_succ List.repeat_succ
-
-@[deprecated mem_replicate]
-theorem mem_repeat {a b : α} {n} : b ∈ List.repeat a n ↔ n ≠ 0 ∧ b = a := mem_replicate
-#align list.mem_repeat List.mem_repeat
-
-@[deprecated eq_of_mem_replicate]
-theorem eq_of_mem_repeat {a b : α} {n} (h : b ∈ List.repeat a n) : b = a := eq_of_mem_replicate h
-#align list.eq_of_mem_repeat List.eq_of_mem_repeat
-
-@[deprecated eq_replicate_of_mem]
-theorem eq_repeat_of_mem {a : α} {l : List α} : (∀ b ∈ l, b = a) → l = List.repeat a l.length :=
-  eq_replicate_of_mem
-#align list.eq_repeat_of_mem List.eq_repeat_of_mem
-
-@[deprecated eq_replicate']
-theorem eq_repeat' {a : α} {l : List α} : l = List.repeat a l.length ↔ ∀ b ∈ l, b = a :=
-  eq_replicate'
-#align list.eq_repeat' List.eq_repeat'
-
-@[deprecated eq_replicate]
-theorem eq_repeat {a : α} {n} {l : List α} : l = List.repeat a n ↔ length l = n ∧ ∀ b ∈ l, b = a :=
-  eq_replicate
-#align list.eq_repeat List.eq_repeat
+  | n + 1 => (replicate_right_inj n.succ_ne_zero).trans <| by simp only [n.succ_ne_zero, false_or]
+#align list.replicate_right_inj' List.replicate_right_inj'
 
-@[deprecated replicate_add]
-theorem repeat_add (a : α) (m n) : List.repeat a (m + n) = List.repeat a m ++ List.repeat a n :=
-  replicate_add ..
-#align list.repeat_add List.repeat_add
+theorem replicate_left_injective (a : α) : Injective (replicate · a) :=
+  LeftInverse.injective (length_replicate · a)
+#align list.replicate_left_injective List.replicate_left_injective
 
-@[deprecated replicate_subset_singleton]
-theorem repeat_subset_singleton (a : α) (n) : List.repeat a n ⊆ [a] :=
-  replicate_subset_singleton ..
-#align list.repeat_subset_singleton List.repeat_subset_singleton
-
-#align list.subset_singleton_iff List.subset_singleton_iff
-
-@[deprecated map_replicate]
-theorem map_repeat (f : α → β) (a : α) (n) : map f (List.repeat a n) = List.repeat (f a) n :=
-  map_replicate ..
-#align list.map_repeat List.map_repeat
-
-@[deprecated tail_replicate]
-theorem tail_repeat (a : α) (n) : tail (List.repeat a n) = List.repeat a n.pred :=
-  tail_replicate ..
-#align list.tail_repeat List.tail_repeat
-
-@[deprecated join_replicate_nil]
-theorem join_repeat_nil (n : ℕ) : join (List.repeat [] n) = @nil α :=
-  join_replicate_nil ..
-#align list.join_repeat_nil List.join_repeat_nil
-
-@[deprecated replicate_left_injective]
-theorem repeat_left_injective {n : ℕ} (hn : n ≠ 0) :
-    Function.Injective fun a : α => List.repeat a n := replicate_left_injective hn
-#align list.repeat_left_injective List.repeat_left_injective
-
-@[deprecated replicate_left_inj]
-theorem repeat_left_inj {a b : α} {n : ℕ} (hn : n ≠ 0) :
-    List.repeat a n = List.repeat b n ↔ a = b :=
-  replicate_left_inj hn
-#align list.repeat_left_inj List.repeat_left_inj
-
-@[deprecated replicate_left_inj']
-theorem repeat_left_inj' {a b : α} {n} : List.repeat a n = List.repeat b n ↔ n = 0 ∨ a = b :=
-  replicate_left_inj'
-#align list.repeat_left_inj' List.repeat_left_inj'
-
-@[deprecated replicate_right_injective]
-theorem repeat_right_injective (a : α) : Function.Injective (List.repeat a) :=
-  replicate_right_injective ..
-#align list.repeat_right_injective List.repeat_right_injective
-
-@[deprecated replicate_right_inj]
-theorem repeat_right_inj {a : α} {n m : ℕ} : List.repeat a n = List.repeat a m ↔ n = m :=
-  replicate_right_inj ..
-#align list.repeat_right_inj List.repeat_right_inj
-
-end deprecated
+@[simp] theorem replicate_left_inj {a : α} {n m : ℕ} : replicate n a = replicate m a ↔ n = m :=
+  (replicate_left_injective a).eq_iff
+#align list.replicate_left_inj List.replicate_left_inj
 
 /-! ### pure -/
 
@@ -769,16 +687,11 @@ theorem mem_reverse' {a : α} {l : List α} : a ∈ reverse l ↔ a ∈ l :=
   List.mem_reverse _ _
 #align list.mem_reverse List.mem_reverse'
 
-@[simp] theorem reverse_replicate (n) (a : α) : reverse (List.replicate n a) = List.replicate n a :=
+@[simp] theorem reverse_replicate (n) (a : α) : reverse (replicate n a) = replicate n a :=
   eq_replicate.2
-    ⟨by simp only [length_reverse, length_replicate],
+    ⟨by rw [length_reverse, length_replicate],
      fun b h => eq_of_mem_replicate (mem_reverse'.1 h)⟩
-
-set_option linter.deprecated false in
-@[deprecated reverse_replicate]
-theorem reverse_repeat (a : α) (n) : reverse (List.repeat a n) = List.repeat a n :=
-  reverse_replicate ..
-#align list.reverse_repeat List.reverse_repeat
+#align list.reverse_replicate List.reverse_replicate
 
 /-! ### empty -/
 
@@ -872,20 +785,11 @@ theorem getLast_mem : ∀ {l : List α} (h : l ≠ []), getLast l h ∈ l
         exact getLast_mem (cons_ne_nil b l)
 #align list.last_mem List.getLast_mem
 
-theorem getLast_replicate_succ (m a : ℕ) :
-    (List.replicate m.succ a).getLast (ne_nil_of_length_eq_succ
-      (show (List.replicate m.succ a).length = m.succ by rw [length_replicate])) = a := by
-  induction' m with k IH
-  · simp
-  · simpa only [replicate_succ, getLast]
-
-set_option linter.deprecated false in
-@[deprecated getLast_replicate_succ]
-theorem getLast_repeat_succ (a m : ℕ) :
-    (List.repeat a m.succ).getLast (ne_nil_of_length_eq_succ
-      (show (List.repeat a m.succ).length = m.succ by rw [length_repeat])) = a :=
-  getLast_replicate_succ ..
-#align list.last_repeat_succ List.getLast_repeat_succ
+theorem getLast_replicate_succ (m : ℕ) (a : α) :
+    (replicate (m + 1) a).getLast (ne_nil_of_length_eq_succ (length_replicate _ _)) = a := by
+  simp only [replicate_succ']
+  exact getLast_append_singleton _
+#align list.last_replicate_succ List.getLast_replicate_succ
 
 /-! ### getLast? -/
 
@@ -1219,28 +1123,18 @@ theorem sublist_nil_iff_eq_nil {l : List α} : l <+ [] ↔ l = [] :=
 
 @[simp]
 theorem replicate_sublist_replicate {m n} (a : α) :
-    List.replicate m a <+ List.replicate n a ↔ m ≤ n :=
+    replicate m a <+ replicate n a ↔ m ≤ n :=
   ⟨fun h => by simpa only [length_replicate] using h.length_le, fun h => by
     induction h <;> [rfl, simp only [*, replicate_succ, Sublist.cons]]⟩
-
-set_option linter.deprecated false in
-@[deprecated replicate_sublist_replicate]
-theorem repeat_sublist_repeat (a : α) {m n} : List.repeat a m <+ List.repeat a n ↔ m ≤ n :=
-  replicate_sublist_replicate _
-#align list.repeat_sublist_repeat List.repeat_sublist_repeat
+#align list.replicate_sublist_replicate List.replicate_sublist_replicate
 
 theorem sublist_replicate_iff {l : List α} {a : α} {n : ℕ} :
-    l <+ List.replicate n a ↔ ∃ k ≤ n, l = List.replicate k a :=
+    l <+ replicate n a ↔ ∃ k ≤ n, l = replicate k a :=
   ⟨fun h =>
-    ⟨l.length, h.length_le.trans (length_replicate _ _).le,
-      eq_replicate.mpr ⟨rfl, fun b hb => List.eq_of_mem_replicate (h.subset hb)⟩⟩,
+    ⟨l.length, h.length_le.trans_eq (length_replicate _ _),
+      eq_replicate_length.mpr fun b hb => eq_of_mem_replicate (h.subset hb)⟩,
     by rintro ⟨k, h, rfl⟩; exact (replicate_sublist_replicate _).mpr h⟩
-
-set_option linter.deprecated false in
-@[deprecated sublist_replicate_iff]
-theorem sublist_repeat_iff {l : List α} {a : α} {n : ℕ} :
-    l <+ List.repeat a n ↔ ∃ k ≤ n, l = List.repeat a k := sublist_replicate_iff
-#align list.sublist_repeat_iff List.sublist_repeat_iff
+#align list.sublist_replicate_iff List.sublist_replicate_iff
 
 theorem Sublist.eq_of_length : ∀ {l₁ l₂ : List α}, l₁ <+ l₂ → length l₁ = length l₂ → l₁ = l₂
   | _, _, Sublist.slnil, _ => rfl
@@ -1502,9 +1396,9 @@ theorem nthLe_append_right {l₁ l₂ : List α} {n : ℕ} (h₁ : l₁.length 
 #align list.nth_le_append_right List.nthLe_append_right
 
 @[deprecated get_replicate]
-theorem nthLe_repeat (a : α) {n m : ℕ} (h : m < (List.repeat a n).length) :
-    (List.repeat a n).nthLe m h = a := get_replicate ..
-#align list.nth_le_repeat List.nthLe_repeat
+theorem nthLe_replicate (a : α) {n m : ℕ} (h : m < (replicate n a).length) :
+    (replicate n a).nthLe m h = a := get_replicate ..
+#align list.nth_le_replicate List.nthLe_replicate
 
 #align list.nth_append List.get?_append
 #align list.nth_append_right List.get?_append_right
@@ -2042,32 +1936,19 @@ theorem getLast_map (f : α → β) {l : List α} (hl : l ≠ []) :
 #align list.last_map List.getLast_map
 
 theorem map_eq_replicate_iff {l : List α} {f : α → β} {b : β} :
-    l.map f = List.replicate l.length b ↔ ∀ x ∈ l, f x = b := by
-  induction' l with x l' ih
-  · simp only [List.replicate, length, not_mem_nil, IsEmpty.forall_iff, imp_true_iff, map_nil,
-      eq_self_iff_true]
-  · simp only [map, List.replicate, add_eq, add_zero, cons.injEq, mem_cons,
-      forall_eq_or_imp, and_congr_right_iff]
-    exact fun _ => ih
-
-set_option linter.deprecated false in
-@[deprecated map_eq_replicate_iff]
-theorem map_eq_repeat_iff {l : List α} {f : α → β} {b : β} :
-    l.map f = List.repeat b l.length ↔ ∀ x ∈ l, f x = b :=
-  map_eq_replicate_iff
-#align list.map_eq_repeat_iff List.map_eq_repeat_iff
+    l.map f = replicate l.length b ↔ ∀ x ∈ l, f x = b := by
+  simp [eq_replicate]
+#align list.map_eq_replicate_iff List.map_eq_replicate_iff
 
-@[simp]
-theorem map_const (l : List α) (b : β) : map (Function.const α b) l = List.replicate l.length b :=
+@[simp] theorem map_const (l : List α) (b : β) : map (const α b) l = replicate l.length b :=
   map_eq_replicate_iff.mpr fun _ _ => rfl
+#align list.map_const List.map_const
 
-set_option linter.deprecated false in
-@[deprecated map_const]
-theorem map_const' (l : List α) (b : β) : map (Function.const α b) l = List.repeat b l.length :=
-  map_eq_replicate_iff.mpr fun _ _ => rfl
-#align list.map_const List.map_const'
+@[simp] theorem map_const' (l : List α) (b : β) : map (fun _ => b) l = replicate l.length b :=
+  map_const l b
+#align list.map_const' List.map_const'
 
-theorem eq_of_mem_map_const {b₁ b₂ : β} {l : List α} (h : b₁ ∈ map (Function.const α b₂) l) :
+theorem eq_of_mem_map_const {b₁ b₂ : β} {l : List α} (h : b₁ ∈ map (const α b₂) l) :
     b₁ = b₂ := by rw [map_const] at h; exact eq_of_mem_replicate h
 #align list.eq_of_mem_map_const List.eq_of_mem_map_const
 
@@ -2134,16 +2015,11 @@ theorem take_take : ∀ (n m) (l : List α), take n (take m l) = take (min n m)
     simp only [take, min_succ_succ, take_take n m l]
 #align list.take_take List.take_take
 
-theorem take_replicate (a : α) : ∀ n m : ℕ, take n (List.replicate m a) = List.replicate (min n m) a
+theorem take_replicate (a : α) : ∀ n m : ℕ, take n (replicate m a) = replicate (min n m) a
   | n, 0 => by simp
   | 0, m => by simp
   | succ n, succ m => by simp [min_succ_succ, take_replicate]
-
-set_option linter.deprecated false in
-@[deprecated take_replicate]
-theorem take_repeat (a : α) (n m : ℕ) : take n (List.repeat a m) = List.repeat a (min n m) :=
-  take_replicate ..
-#align list.take_repeat List.take_repeat
+#align list.take_replicate List.take_replicate
 
 theorem map_take {α β : Type _} (f : α → β) :
     ∀ (L : List α) (i : ℕ), (L.take i).map f = (L.map f).take i
@@ -4874,7 +4750,7 @@ theorem getD_replicate_default_eq (r n : ℕ) : (replicate r d).getD n d = d :=
   induction' r with r IH generalizing n
   · simp
   · cases n <;> simp [IH]
-#align list.nthd_repeat_default_eq List.getD_replicate_default_eqₓ -- argument order
+#align list.nthd_replicate_default_eq List.getD_replicate_default_eqₓ -- argument order
 
 theorem getD_append (l l' : List α) (d : α) (n : ℕ) (h : n < l.length)
     (h' : n < (l ++ l').length := h.trans_le ((length_append l l').symm ▸ le_self_add)) :
chore: drop use of trivial in use (#1153)

After filling an existential, use will resolve the remaining goals if they are "easy". Before this PR this was done by trying trivial. I have downgraded to with_reducible rfl. This means use will no longer solve goals which are

  • definitional equalities which require the unfolding of non-reducible definitions
  • tactics other than rfl which are called by trivial (notably decide, which can get slow)

Note that this brings use closer to the mathlib3 version: there it tried the trivial' tactic, which again only looked at definitional equality up to reducible definitions, and whose kitchen-sink did not include decide.

See discussion: https://leanprover.zulipchat.com/#narrow/stream/287929-mathlib4/topic/use

Diff
@@ -924,6 +924,7 @@ theorem mem_getLast?_eq_getLast : ∀ {l : List α} {x : α}, x ∈ l.getLast? 
     rw [getLast?_cons_cons] at hx
     rcases mem_getLast?_eq_getLast hx with ⟨_, h₂⟩
     use cons_ne_nil _ _
+    assumption
 #align list.mem_last'_eq_last List.mem_getLast?_eq_getLast
 
 theorem getLast?_eq_getLast_of_ne_nil : ∀ {l : List α} (h : l ≠ []), l.getLast? = some (l.getLast h)
chore: rename getI_zero_eq_head! to getI_zero_eq_headI (#1415)

it doesn't really make sense for List.getI 0 = List.head! when the latter panics.

Co-authored-by: Calvin Lee <calvins.lee@utah.edu>

Diff
@@ -4950,8 +4950,8 @@ theorem getI_eq_iget_get? (n : ℕ) : l.getI n = (l.get? n).iget := by
   rw [← getD_default_eq_getI, getD_eq_getD_get?, Option.getD_default_eq_iget]
 #align list.inth_eq_iget_nth List.getI_eq_iget_get?
 
-theorem getI_zero_eq_head! : l.getI 0 = l.head! := by cases l <;> rfl
-#align list.inth_zero_eq_head List.getI_zero_eq_head!
+theorem getI_zero_eq_headI : l.getI 0 = l.headI := by cases l <;> rfl
+#align list.inth_zero_eq_head List.getI_zero_eq_headI
 
 end getI
 
chore: fix some names in Data.List.Basic (#1421)
Diff
@@ -2754,25 +2754,25 @@ def foldlRecOn {C : β → Sort _} (l : List α) (op : β → α → β) (b : β
 #align list.foldl_rec_on List.foldlRecOn
 
 @[simp]
-theorem foldr_rec_on_nil {C : β → Sort _} (op : α → β → β) (b) (hb : C b) (hl) :
+theorem foldrRecOn_nil {C : β → Sort _} (op : α → β → β) (b) (hb : C b) (hl) :
     foldrRecOn [] op b hb hl = hb :=
   rfl
-#align list.foldr_rec_on_nil List.foldr_rec_on_nil
+#align list.foldr_rec_on_nil List.foldrRecOn_nil
 
 @[simp]
-theorem foldr_rec_on_cons {C : β → Sort _} (x : α) (l : List α) (op : α → β → β) (b) (hb : C b)
+theorem foldrRecOn_cons {C : β → Sort _} (x : α) (l : List α) (op : α → β → β) (b) (hb : C b)
     (hl : ∀ (b : β) (_ : C b) (a : α) (_ : a ∈ x :: l), C (op a b)) :
     foldrRecOn (x :: l) op b hb hl =
       hl _ (foldrRecOn l op b hb fun b hb a ha => hl b hb a (mem_cons_of_mem _ ha)) x
         (mem_cons_self _ _) :=
   rfl
-#align list.foldr_rec_on_cons List.foldr_rec_on_cons
+#align list.foldr_rec_on_cons List.foldrRecOn_cons
 
 @[simp]
-theorem foldl_rec_on_nil {C : β → Sort _} (op : β → α → β) (b) (hb : C b) (hl) :
+theorem foldlRecOn_nil {C : β → Sort _} (op : β → α → β) (b) (hb : C b) (hl) :
     foldlRecOn [] op b hb hl = hb :=
   rfl
-#align list.foldl_rec_on_nil List.foldl_rec_on_nil
+#align list.foldl_rec_on_nil List.foldlRecOn_nil
 
 -- scanl
 section Scanl
chore: remove iff_self from simp only after lean4#1933 (#1406)

Co-authored-by: Scott Morrison <scott.morrison@gmail.com>

Diff
@@ -138,7 +138,7 @@ fun p ↦ ⟨ne_of_not_mem_cons p, not_mem_of_not_mem_cons p⟩
 -- Porting TODO: fix `List.mem_map` in Std to this statement.
 @[simp]
 theorem mem_map' {f : α → β} {b : β} {l : List α} : b ∈ map f l ↔ ∃ a, a ∈ l ∧ f a = b := by
-  simp only [List.mem_map, eq_comm, iff_self]
+  simp only [List.mem_map, eq_comm]
 #align list.mem_map List.mem_map'
 
 alias mem_map' ↔ exists_of_mem_map' _
chore: bump to nightly-2023-01-06 (#1397)

Co-authored-by: Scott Morrison <scott.morrison@gmail.com>

Diff
@@ -2037,9 +2037,7 @@ theorem getLast_map (f : α → β) {l : List α} (hl : l ≠ []) :
   · apply (hl rfl).elim
   · cases l_tl
     · simp
-    · simpa using l_ih
--- Porting note: After https://github.com/leanprover/std4/pull/75,
--- last line above should be changed to end `l_ih _`.
+    · simpa using l_ih _
 #align list.last_map List.getLast_map
 
 theorem map_eq_replicate_iff {l : List α} {f : α → β} {b : β} :
feat port: Data.List.Basic (#966)

cf9386b5

Notes so far There are various problems with theorems already having been ported. Sometimes there was a change in universe level order, implicit argument order, or explicit arguments order or explicicity of arguments. In these situations I did the following. --Ignore the error and align the old lemma when the difference between the two was just universe. --Align the old lemma with the new lemma but incluce a porting note when the difference was the order of implicit arguments --Make a new lemma with a ' at the end when the difference was to do with explicit arguments.

I also added a bunch of definitions that were not imported, possibly with the wrong names. These definitions are repeat, ret, empty, init, last, ilast

There is a question to be answered about what to do with list.nth_le, which is discussed on Zulip

Co-authored-by: Scott Morrison <scott.morrison@gmail.com> Co-authored-by: ChrisHughes24 <chrishughes24@gmail.com> Co-authored-by: Johan Commelin <johan@commelin.net> Co-authored-by: Siddhartha Gadgil <siddhartha.gadgil@gmail.com>

Diff
@@ -1,268 +1,4960 @@
-import Mathlib.Logic.Basic
-import Mathlib.Logic.Function.Basic
-import Mathlib.Data.Nat.Basic
-import Mathlib.Data.Option.Basic
-import Mathlib.Data.Subtype
-import Std.Tactic.Simpa
+/-
+Copyright (c) 2014 Parikshit Khanna. All rights reserved.
+Released under Apache 2.0 license as described in the file LICENSE.
+Authors: Parikshit Khanna, Jeremy Avigad, Leonardo de Moura, Floris van Doorn, Mario Carneiro
+
+! This file was ported from Lean 3 source module data.list.basic
+! leanprover-community/mathlib commit cf9386b56953fb40904843af98b7a80757bbe7f9
+! Please do not edit these lines, except to modify the commit id
+! if you have ported upstream changes.
+-/
+import Mathlib.Init.Data.List.Basic
+import Mathlib.Data.Nat.Order.Basic
+import Mathlib.Data.List.Defs
+import Mathlib.Init.Core
 import Std.Data.List.Lemmas
-import Lean
+
+/-!
+# Basic properties of lists
+-/
+
+#align list.mem_cons_iff List.mem_cons
 
 open Function
 
+open Nat hiding one_pos
+
+-- Porting note: missing impl
+-- assert_not_exists Set.range
+
 namespace List
 
-/-!
-# Basic properties of Lists
--/
+universe u v w x
+
+variable {ι : Type _} {α : Type u} {β : Type v} {γ : Type w} {δ : Type x} {l₁ l₂ : List α}
+
+-- Porting note: Delete this attribute
+-- attribute [inline] List.head!
+
+/-- There is only one list of an empty type -/
+instance uniqueOfIsEmpty [IsEmpty α] : Unique (List α) :=
+  { instInhabitedList with
+    uniq := fun l =>
+      match l with
+      | [] => rfl
+      | a :: _ => isEmptyElim a }
+#align list.unique_of_is_empty List.uniqueOfIsEmpty
+
+instance : IsLeftId (List α) Append.append [] :=
+  ⟨nil_append⟩
+
+instance : IsRightId (List α) Append.append [] :=
+  ⟨append_nil⟩
+
+instance : IsAssociative (List α) Append.append :=
+  ⟨append_assoc⟩
 
--- instance : is_left_id (List α) has_append.append [] :=
--- ⟨ nil_append ⟩
+#align list.cons_ne_nil List.cons_ne_nil
+#align list.cons_ne_self List.cons_ne_self
 
--- instance : is_right_id (List α) has_append.append [] :=
--- ⟨ append_nil ⟩
+#align list.head_eq_of_cons_eq List.head_eq_of_cons_eqₓ -- implicits order
+#align list.tail_eq_of_cons_eq List.tail_eq_of_cons_eqₓ -- implicits order
 
--- instance : is_associative (List α) has_append.append :=
--- ⟨ append_assoc ⟩
+@[simp] theorem cons_injective {a : α} : Injective (cons a) := fun _ _ => tail_eq_of_cons_eq
+#align list.cons_injective List.cons_injective
 
-@[simp] theorem cons_injective {a : α} : Injective (cons a) :=
-λ _ _ Pe => tail_eq_of_cons_eq Pe
+#align list.cons_inj List.cons_inj
+
+theorem cons_eq_cons {a b : α} {l l' : List α} : a :: l = b :: l' ↔ a = b ∧ l = l' :=
+  ⟨List.cons.inj, fun h => h.1 ▸ h.2 ▸ rfl⟩
+#align list.cons_eq_cons List.cons_eq_cons
+
+theorem singleton_injective : Injective fun a : α => [a] := fun _ _ h => (cons_eq_cons.1 h).1
+#align list.singleton_injective List.singleton_injective
+
+theorem singleton_inj {a b : α} : [a] = [b] ↔ a = b :=
+  singleton_injective.eq_iff
+#align list.singleton_inj List.singleton_inj
+
+#align list.exists_cons_of_ne_nil List.exists_cons_of_ne_nil
+
+theorem set_of_mem_cons (l : List α) (a : α) : { x | x ∈ a :: l } = insert a { x | x ∈ l } :=
+  Set.ext fun _ => mem_cons
+#align list.set_of_mem_cons List.set_of_mem_cons
 
 /-! ### mem -/
 
+#align list.mem_singleton_self List.mem_singleton_self
+#align list.eq_of_mem_singleton List.eq_of_mem_singleton
+#align list.mem_singleton List.mem_singleton
+#align list.mem_of_mem_cons_of_mem List.mem_of_mem_cons_of_mem
+
+theorem _root_.Decidable.List.eq_or_ne_mem_of_mem [DecidableEq α]
+    {a b : α} {l : List α} (h : a ∈ b :: l) : a = b ∨ a ≠ b ∧ a ∈ l := by
+  by_cases hab : a = b
+  · exact Or.inl hab
+  · exact ((List.mem_cons.1 h).elim Or.inl (fun h => Or.inr ⟨hab, h⟩))
+#align decidable.list.eq_or_ne_mem_of_mem Decidable.List.eq_or_ne_mem_of_mem
+
+#align list.eq_or_ne_mem_of_mem List.eq_or_ne_mem_of_mem
+
+-- porting note: from init.data.list.lemmas
 alias mem_cons ↔ eq_or_mem_of_mem_cons _
+#align list.eq_or_mem_of_mem_cons List.eq_or_mem_of_mem_cons
 
 theorem not_mem_append {a : α} {s t : List α} (h₁ : a ∉ s) (h₂ : a ∉ t) : a ∉ s ++ t :=
 mt mem_append.1 $ not_or.mpr ⟨h₁, h₂⟩
+#align list.not_mem_append List.not_mem_append
+
+#align list.ne_nil_of_mem List.ne_nil_of_mem
+
+theorem mem_split {a : α} {l : List α} (h : a ∈ l) : ∃ s t : List α, l = s ++ a :: t := by
+  induction' l with b l ih; {cases h}; rcases h with (_ | ⟨_, h⟩)
+  · exact ⟨[], l, rfl⟩
+  · rcases ih h with ⟨s, t, rfl⟩
+    exact ⟨b :: s, t, rfl⟩
+#align list.mem_split List.mem_split
 
 theorem mem_of_ne_of_mem {a y : α} {l : List α} (h₁ : a ≠ y) (h₂ : a ∈ y :: l) : a ∈ l :=
 Or.elim (eq_or_mem_of_mem_cons h₂) (fun e ↦ absurd e h₁) (fun r ↦ r)
+#align list.mem_of_ne_of_mem List.mem_of_ne_of_mem
 
 theorem ne_of_not_mem_cons {a b : α} {l : List α} : (a ∉ b::l) → a ≠ b :=
 fun nin aeqb ↦ absurd (aeqb ▸ Mem.head ..) nin
+#align list.ne_of_not_mem_cons List.ne_of_not_mem_cons
 
 theorem not_mem_of_not_mem_cons {a b : α} {l : List α} : (a ∉ b::l) → a ∉ l :=
 fun nin nainl ↦ absurd (Mem.tail _ nainl) nin
+#align list.not_mem_of_not_mem_cons List.not_mem_of_not_mem_cons
 
 theorem not_mem_cons_of_ne_of_not_mem {a y : α} {l : List α} : a ≠ y → (a ∉ l) → (a ∉ y::l) :=
-fun p1 p2 ↦ fun Pain ↦ absurd (eq_or_mem_of_mem_cons Pain) (not_or.mpr ⟨p1, p2⟩)
+fun p1 p2 Pain ↦ absurd (eq_or_mem_of_mem_cons Pain) (not_or.mpr ⟨p1, p2⟩)
+#align list.not_mem_cons_of_ne_of_not_mem List.not_mem_cons_of_ne_of_not_mem
 
 theorem ne_and_not_mem_of_not_mem_cons {a y : α} {l : List α} : (a ∉ y::l) → a ≠ y ∧ a ∉ l :=
-fun p ↦ And.intro (ne_of_not_mem_cons p) (not_mem_of_not_mem_cons p)
+fun p ↦ ⟨ne_of_not_mem_cons p, not_mem_of_not_mem_cons p⟩
+#align list.ne_and_not_mem_of_not_mem_cons List.ne_and_not_mem_of_not_mem_cons
+
+-- Porting TODO: fix `List.mem_map` in Std to this statement.
+@[simp]
+theorem mem_map' {f : α → β} {b : β} {l : List α} : b ∈ map f l ↔ ∃ a, a ∈ l ∧ f a = b := by
+  simp only [List.mem_map, eq_comm, iff_self]
+#align list.mem_map List.mem_map'
+
+alias mem_map' ↔ exists_of_mem_map' _
+#align list.exists_of_mem_map List.exists_of_mem_map'
+
+#align list.mem_map_of_mem List.mem_map_of_memₓ -- implicits order
 
 theorem mem_map_of_injective {f : α → β} (H : Injective f) {a : α} {l : List α} :
     f a ∈ map f l ↔ a ∈ l :=
-  ⟨fun m ↦ let ⟨_, m', e⟩ := exists_of_mem_map m; H e ▸ m',
-   mem_map_of_mem _⟩
+  ⟨fun m => let ⟨_, m', e⟩ := exists_of_mem_map m; H e ▸ m', mem_map_of_mem _⟩
+#align list.mem_map_of_injective List.mem_map_of_injective
 
-theorem mem_split {a : α} {l : List α} (h : a ∈ l) : ∃ s t : List α, l = s ++ a :: t := by
-  induction l with
-  | nil => cases h
-  | cons b l ih =>
-    cases h with
-    | head => exact ⟨[], l, rfl⟩
-    | tail _ h =>
-      rcases ih h with ⟨s, t, rfl⟩
-      exact ⟨b :: s, t, rfl⟩
+@[simp]
+theorem _root_.Function.Involutive.exists_mem_and_apply_eq_iff {f : α → α}
+    (hf : Function.Involutive f) (x : α) (l : List α) : (∃ y : α, y ∈ l ∧ f y = x) ↔ f x ∈ l :=
+  ⟨by rintro ⟨y, h, rfl⟩; rwa [hf y], fun h => ⟨f x, h, hf _⟩⟩
+#align
+  function.involutive.exists_mem_and_apply_eq_iff
+  Function.Involutive.exists_mem_and_apply_eq_iff
+
+theorem mem_map_of_involutive {f : α → α} (hf : Involutive f) {a : α} {l : List α} :
+    a ∈ map f l ↔ f a ∈ l := by rw [mem_map', hf.exists_mem_and_apply_eq_iff]
+#align list.mem_map_of_involutive List.mem_map_of_involutive
+
+#align list.forall_mem_map_iff List.forall_mem_map_iffₓ -- universe order
+
+#align list.map_eq_nil List.map_eq_nilₓ -- universe order
+
+attribute [simp] List.mem_join
+#align list.mem_join List.mem_join
+
+#align list.exists_of_mem_join List.exists_of_mem_join
+
+#align list.mem_join_of_mem List.mem_join_of_memₓ -- implicits order
+
+attribute [simp] List.mem_bind
+#align list.mem_bind List.mem_bindₓ -- implicits order
+
+-- Porting note: bExists in Lean3, And in Lean4
+#align list.exists_of_mem_bind List.exists_of_mem_bindₓ -- implicits order
+
+#align list.mem_bind_of_mem List.mem_bind_of_memₓ -- implicits order
+
+#align list.bind_map List.bind_mapₓ -- implicits order
+
+theorem map_bind (g : β → List γ) (f : α → β) :
+    ∀ l : List α, (List.map f l).bind g = l.bind fun a => g (f a)
+  | [] => rfl
+  | a :: l => by simp only [cons_bind, map_cons, map_bind _ _ l]
+#align list.map_bind List.map_bind
 
 /-! ### length -/
 
+#align list.length_eq_zero List.length_eq_zero
+
+#align list.length_singleton List.length_singleton
+
+#align list.length_pos_of_mem List.length_pos_of_mem
+
+#align list.exists_mem_of_length_pos List.exists_mem_of_length_pos
+
+#align list.length_pos_iff_exists_mem List.length_pos_iff_exists_mem
+
 alias length_pos ↔ ne_nil_of_length_pos length_pos_of_ne_nil
+#align list.ne_nil_of_length_pos List.ne_nil_of_length_pos
+#align list.length_pos_of_ne_nil List.length_pos_of_ne_nil
 
-lemma exists_of_length_succ {n} :
-  ∀ l : List α, l.length = n + 1 → ∃ h t, l = h :: t
-| [], H => absurd H.symm $ Nat.succ_ne_zero n
-| h :: t, _ => ⟨h, t, rfl⟩
+theorem length_pos_iff_ne_nil {l : List α} : 0 < length l ↔ l ≠ [] :=
+  ⟨ne_nil_of_length_pos, length_pos_of_ne_nil⟩
+#align list.length_pos_iff_ne_nil List.length_pos_iff_ne_nil
 
-@[simp]
-lemma length_injective_iff : Injective (List.length : List α → ℕ) ↔ Subsingleton α := by
+#align list.exists_mem_of_ne_nil List.exists_mem_of_ne_nil
+
+#align list.length_eq_one List.length_eq_one
+
+theorem exists_of_length_succ {n} : ∀ l : List α, l.length = n + 1 → ∃ h t, l = h :: t
+  | [], H => absurd H.symm <| succ_ne_zero n
+  | h :: t, _ => ⟨h, t, rfl⟩
+#align list.exists_of_length_succ List.exists_of_length_succ
+
+@[simp] lemma length_injective_iff : Injective (List.length : List α → ℕ) ↔ Subsingleton α := by
   constructor
-  · intro h; refine ⟨λ x y => ?_⟩; (suffices [x] = [y] by simpa using this); apply h; rfl
+  · intro h; refine ⟨fun x y => ?_⟩; (suffices [x] = [y] by simpa using this); apply h; rfl
   · intros hα l1 l2 hl
     induction l1 generalizing l2 <;> cases l2
-    case nil.nil => rfl
-    case nil.cons => cases hl
-    case cons.nil => cases hl
-    case cons.cons ih _ _ => congr
-                             · exact Subsingleton.elim _ _
-                             · apply ih; simpa using hl
-
-@[simp default+1]
+    · rfl
+    · cases hl
+    · cases hl
+    · next ih _ _ =>
+      congr
+      · exact Subsingleton.elim _ _
+      · apply ih; simpa using hl
+#align list.length_injective_iff List.length_injective_iff
+
+@[simp default+1] -- Porting note: this used to be just @[simp]
 lemma length_injective [Subsingleton α] : Injective (length : List α → ℕ) :=
-length_injective_iff.mpr inferInstance
+  length_injective_iff.mpr inferInstance
+#align list.length_injective List.length_injective
+
+theorem length_eq_two {l : List α} : l.length = 2 ↔ ∃ a b, l = [a, b] :=
+  ⟨fun _ => let [a, b] := l; ⟨a, b, rfl⟩, fun ⟨_, _, e⟩ => e ▸ rfl⟩
+#align list.length_eq_two List.length_eq_two
+
+theorem length_eq_three {l : List α} : l.length = 3 ↔ ∃ a b c, l = [a, b, c] :=
+  ⟨fun _ => let [a, b, c] := l; ⟨a, b, c, rfl⟩, fun ⟨_, _, _, e⟩ => e ▸ rfl⟩
+#align list.length_eq_three List.length_eq_three
+
+-- Porting note: Lean 3 core library had the name length_le_of_sublist
+-- and data.list.basic the command `alias length_le_of_sublist ← sublist.length_le`,
+-- but Std has the name Sublist.length_le instead.
+alias Sublist.length_le ← length_le_of_sublist
+#align list.length_le_of_sublist List.length_le_of_sublist
+#align list.sublist.length_le List.Sublist.length_le
+
+/-! ### set-theoretic notation of lists -/
+
+-- ADHOC Porting note: instance from Lean3 core
+instance : Singleton α (List α) := ⟨fun x => [x]⟩
+#align list.has_singleton List.instSingletonList
+
+-- ADHOC Porting note: instance from Lean3 core
+instance [DecidableEq α] : Insert α (List α) := ⟨List.insert⟩
+
+-- ADHOC Porting note: instance from Lean3 core
+instance [DecidableEq α]: IsLawfulSingleton α (List α) :=
+  { insert_emptyc_eq := fun x =>
+      show (if x ∈ ([] : List α) then [] else [x]) = [x] from if_neg (not_mem_nil _) }
+
+#align list.empty_eq List.empty_eq
+
+theorem singleton_eq (x : α) : ({x} : List α) = [x] :=
+  rfl
+#align list.singleton_eq List.singleton_eq
 
-/-! ### set-theoretic notation of Lists -/
+theorem insert_neg [DecidableEq α] {x : α} {l : List α} (h : x ∉ l) : Insert.insert x l = x :: l :=
+  if_neg h
+#align list.insert_neg List.insert_neg
 
---lemma singleton_eq (x : α) : ({x} : List α) = [x] := rfl
---lemma insert_neg [DecidableEq α] {x : α} {l : List α} (h : x ∉ l) :
---  has_insert.insert x l = x :: l :=
---if_neg h
---lemma insert_pos [DecidableEq α] {x : α} {l : List α} (h : x ∈ l) :
---  has_insert.insert x l = l :=
---if_pos h
--- lemma doubleton_eq [DecidableEq α] {x y : α} (h : x ≠ y) : ({x, y} : List α) = [x, y] := by
---   rw [insert_neg, singleton_eq]; rwa [singleton_eq, mem_singleton]
+theorem insert_pos [DecidableEq α] {x : α} {l : List α} (h : x ∈ l) : Insert.insert x l = l :=
+  if_pos h
+#align list.insert_pos List.insert_pos
 
-/-! ### bounded quantifiers over Lists -/
+theorem doubleton_eq [DecidableEq α] {x y : α} (h : x ≠ y) : ({x, y} : List α) = [x, y] := by
+  rw [insert_neg, singleton_eq]
+  rwa [singleton_eq, mem_singleton]
+#align list.doubleton_eq List.doubleton_eq
 
-theorem forall_mem_of_forall_mem_cons {p : α → Prop} {a : α} {l : List α}
-    (h : ∀ x, x ∈ a :: l → p x) :
-  ∀ x, x ∈ l → p x :=
-(forall_mem_cons.1 h).2
+/-! ### bounded quantifiers over lists -/
 
-theorem not_exists_mem_nil (p : α → Prop) : ¬ ∃ x ∈ @nil α, p x := exists_mem_nil _
+#align list.forall_mem_nil List.forall_mem_nil
 
-alias exists_mem_cons ↔ or_exists_of_exists_mem_cons _
+#align list.forall_mem_cons List.forall_mem_cons
 
-theorem exists_mem_cons_of {p : α → Prop} {a : α} (l : List α) (h : p a) :
-  ∃ x ∈ a :: l, p x :=
-exists_mem_cons.2 (.inl h)
+theorem forall_mem_of_forall_mem_cons {p : α → Prop} {a : α} {l : List α} (h : ∀ x ∈ a :: l, p x) :
+    ∀ x ∈ l, p x := (forall_mem_cons.1 h).2
+#align list.forall_mem_of_forall_mem_cons List.forall_mem_of_forall_mem_cons
 
-theorem exists_mem_cons_of_exists {p : α → Prop} {a : α} {l : List α}
-    (h : ∃ x ∈ l, p x) : ∃ x ∈ a :: l, p x :=
-exists_mem_cons.2 (.inr h)
+#align list.forall_mem_singleton List.forall_mem_singleton
 
-/-! ### List subset -/
+#align list.forall_mem_append List.forall_mem_append
+
+theorem not_exists_mem_nil (p : α → Prop) : ¬∃ x ∈ @nil α, p x :=
+  fun.
+#align list.not_exists_mem_nil List.not_exists_mem_nilₓ -- bExists change
+
+-- Porting note: bExists in Lean3 and And in Lean4
+theorem exists_mem_cons_of {p : α → Prop} {a : α} (l : List α) (h : p a) : ∃ x ∈ a :: l, p x :=
+  ⟨a, mem_cons_self _ _, h⟩
+#align list.exists_mem_cons_of List.exists_mem_cons_ofₓ -- bExists change
+
+-- Porting note: bExists in Lean3 and And in Lean4
+theorem exists_mem_cons_of_exists {p : α → Prop} {a : α} {l : List α} : (∃ x ∈ l, p x) →
+    ∃ x ∈ a :: l, p x :=
+  fun ⟨x, xl, px⟩ => ⟨x, mem_cons_of_mem _ xl, px⟩
+#align list.exists_mem_cons_of_exists List.exists_mem_cons_of_existsₓ -- bExists change
+
+-- Porting note: bExists in Lean3 and And in Lean4
+theorem or_exists_of_exists_mem_cons {p : α → Prop} {a : α} {l : List α} : (∃ x ∈ a :: l, p x) →
+    p a ∨ ∃ x ∈ l, p x :=
+  fun ⟨x, xal, px⟩ =>
+    Or.elim (eq_or_mem_of_mem_cons xal) (fun h : x = a => by rw [← h]; left; exact px)
+      fun h : x ∈ l => Or.inr ⟨x, h, px⟩
+#align list.or_exists_of_exists_mem_cons List.or_exists_of_exists_mem_consₓ -- bExists change
+
+theorem exists_mem_cons_iff (p : α → Prop) (a : α) (l : List α) :
+    (∃ x ∈ a :: l, p x) ↔ p a ∨ ∃ x ∈ l, p x :=
+  Iff.intro or_exists_of_exists_mem_cons fun h =>
+    Or.elim h (exists_mem_cons_of l) exists_mem_cons_of_exists
+#align list.exists_mem_cons_iff List.exists_mem_cons_iff
+
+/-! ### list subset -/
+
+#align list.subset_def List.subset_def
+
+#align list.subset_append_of_subset_left List.subset_append_of_subset_left
+
+@[deprecated subset_append_of_subset_right]
+theorem subset_append_of_subset_right' (l l₁ l₂ : List α) : l ⊆ l₂ → l ⊆ l₁ ++ l₂ :=
+  subset_append_of_subset_right _
+#align list.subset_append_of_subset_right List.subset_append_of_subset_right'
+
+#align list.cons_subset List.cons_subset
 
 theorem cons_subset_of_subset_of_mem {a : α} {l m : List α}
   (ainm : a ∈ m) (lsubm : l ⊆ m) : a::l ⊆ m :=
 cons_subset.2 ⟨ainm, lsubm⟩
+#align list.cons_subset_of_subset_of_mem List.cons_subset_of_subset_of_mem
 
 theorem append_subset_of_subset_of_subset {l₁ l₂ l : List α} (l₁subl : l₁ ⊆ l) (l₂subl : l₂ ⊆ l) :
   l₁ ++ l₂ ⊆ l :=
 fun _ h ↦ (mem_append.1 h).elim (@l₁subl _) (@l₂subl _)
+#align list.append_subset_of_subset_of_subset List.append_subset_of_subset_of_subset
+
+-- Porting note: in Std
+#align list.append_subset_iff List.append_subset
 
 alias subset_nil ↔ eq_nil_of_subset_nil _
+#align list.eq_nil_of_subset_nil List.eq_nil_of_subset_nil
+
+#align list.eq_nil_iff_forall_not_mem List.eq_nil_iff_forall_not_mem
 
--- theorem map_subset_iff {l₁ l₂ : List α} (f : α → β) (h : injective f) :
---   map f l₁ ⊆ map f l₂ ↔ l₁ ⊆ l₂ :=
--- begin
---   refine ⟨_, map_subset f⟩, intros h2 x hx,
---   rcases mem_map.1 (h2 (mem_map_of_mem f hx)) with ⟨x', hx', hxx'⟩,
---   cases h hxx', exact hx'
--- end
+#align list.map_subset List.map_subset
+
+theorem map_subset_iff {l₁ l₂ : List α} (f : α → β) (h : Injective f) :
+    map f l₁ ⊆ map f l₂ ↔ l₁ ⊆ l₂ := by
+  refine' ⟨_, map_subset f⟩; intro h2 x hx
+  rcases mem_map.1 (h2 (mem_map_of_mem f hx)) with ⟨x', hx', hxx'⟩
+  cases h hxx'; exact hx'
+#align list.map_subset_iff List.map_subset_iff
 
 /-! ### append -/
 
--- theorem append_eq_append_iff {a b c d : List α} :
---   a ++ b = c ++ d ↔ (∃ a', c = a ++ a' ∧ b = a' ++ d) ∨ ∃ c', a = c ++ c' ∧ d = c' ++ b := by
---   induction a generalizing c with
---   | nil =>
---     rw [nil_append]; constructor
---     · rintro rfl; left; exact ⟨_, rfl, rfl⟩
---     · rintro (⟨a', rfl, rfl⟩ | ⟨a', H, rfl⟩); {rfl}; rw [←append_assoc, ←H]; rfl
---   | cons a as ih =>
---     cases c
---     · simp only [cons_append, nil_append, false_and, exists_false, false_or, exists_eq_left']
---       exact eq_comm
---     · simp only [cons_append, @eq_comm _ a, ih, and_assoc, and_or_distrib_left,
---         exists_and_distrib_left]
-
--- @[simp] theorem split_at_eq_take_drop :
---   ∀ (n : ℕ) (l : List α), split_at n l = (take n l, drop n l)
--- | 0, a => rfl
--- | n+1, [] => rfl
--- | n+1, x :: xs => by simp only [split_at, split_at_eq_take_drop n xs, take, drop]
+theorem append_eq_has_append {L₁ L₂ : List α} : List.append L₁ L₂ = L₁ ++ L₂ :=
+  rfl
+#align list.append_eq_has_append List.append_eq_has_append
+
+#align list.singleton_append List.singleton_append
+
+#align list.append_ne_nil_of_ne_nil_left List.append_ne_nil_of_ne_nil_left
+
+#align list.append_ne_nil_of_ne_nil_right List.append_ne_nil_of_ne_nil_right
+
+#align list.append_eq_nil List.append_eq_nil
+
+-- Porting note: in Std
+#align list.nil_eq_append_iff List.nil_eq_append
+
+theorem append_eq_cons_iff {a b c : List α} {x : α} :
+    a ++ b = x :: c ↔ a = [] ∧ b = x :: c ∨ ∃ a', a = x :: a' ∧ c = a' ++ b := by
+  cases a <;>
+    simp only [and_assoc, @eq_comm _ c, nil_append, cons_append, cons.injEq, true_and_iff,
+      false_and_iff, exists_false, false_or_iff, or_false_iff, exists_and_left, exists_eq_left']
+#align list.append_eq_cons_iff List.append_eq_cons_iff
+
+theorem cons_eq_append_iff {a b c : List α} {x : α} :
+    (x :: c : List α) = a ++ b ↔ a = [] ∧ b = x :: c ∨ ∃ a', a = x :: a' ∧ c = a' ++ b := by
+  rw [eq_comm, append_eq_cons_iff]
+#align list.cons_eq_append_iff List.cons_eq_append_iff
+
+#align list.append_eq_append_iff List.append_eq_append_iff
+
+#align list.take_append_drop List.take_append_drop
+
+#align list.append_inj List.append_inj
+
+#align list.append_inj_right List.append_inj_rightₓ -- implicits order
+
+#align list.append_inj_left List.append_inj_leftₓ -- implicits order
+
+#align list.append_inj' List.append_inj'ₓ -- implicits order
+
+#align list.append_inj_right' List.append_inj_right'ₓ -- implicits order
+
+#align list.append_inj_left' List.append_inj_left'ₓ -- implicits order
 
 theorem append_left_cancel {s t₁ t₂ : List α} (h : s ++ t₁ = s ++ t₂) : t₁ = t₂ :=
   (append_right_inj _).1 h
+#align list.append_left_cancel List.append_left_cancel
 
 theorem append_right_cancel {s₁ s₂ t : List α} (h : s₁ ++ t = s₂ ++ t) : s₁ = s₂ :=
   (append_left_inj _).1 h
+#align list.append_right_cancel List.append_right_cancel
 
 theorem append_right_injective (s : List α) : Injective fun t ↦ s ++ t :=
 fun _ _ ↦ append_left_cancel
+#align list.append_right_injective List.append_right_injective
+
+#align list.append_right_inj List.append_right_inj
 
 theorem append_left_injective (t : List α) : Injective fun s ↦ s ++ t :=
 fun _ _ ↦ append_right_cancel
+#align list.append_left_injective List.append_left_injective
 
-/-! ### nth element -/
+#align list.append_left_inj List.append_left_inj
 
-theorem get?_injective {α : Type u} {xs : List α} {i j : ℕ}
-  (h₀ : i < xs.length)
-  (h₁ : Nodup xs)
-  (h₂ : xs.get? i = xs.get? j) : i = j := by
-  induction xs generalizing i j with
-  | nil => cases h₀
-  | cons x xs ih =>
-    match i, j with
-    | 0, 0 => rfl
-    | i+1, j+1 => simp; cases h₁ with
-      | cons ha h₁ => exact ih (Nat.lt_of_succ_lt_succ h₀) h₁ h₂
-    | i+1, 0 => ?_ | 0, j+1 => ?_
-    all_goals
-      simp at h₂
-      cases h₁; rename_i h' h
-      have := h x ?_ rfl; cases this
-      rw [mem_iff_get?]
-    exact ⟨_, h₂⟩; exact ⟨_ , h₂.symm⟩
-
-/--
-List.prod satisfies a specification of cartesian product on lists.
--/
-theorem product_spec (xs : List α) (ys : List β) (x : α) (y : β) :
-  (x, y) ∈ product xs ys ↔ x ∈ xs ∧ y ∈ ys := by
-  constructor
-  · simp only [List.product, and_imp, exists_prop, List.mem_map, Prod.mk.injEq,
-      exists_eq_right_right', List.mem_bind]
-    exact And.intro
-  · simp only [product, mem_bind, mem_map, Prod.mk.injEq, exists_eq_right_right', exists_prop]
-    exact id
+#align list.map_eq_append_split List.map_eq_append_split
+
+-- porting note: TODO: #align list.repeat List.replicate & theorems below?
+/-! ### repeat -/
+
+attribute [simp] replicate_succ
+
+theorem eq_replicate_of_mem {a : α} :
+    ∀ {l : List α}, (∀ b ∈ l, b = a) → l = List.replicate l.length a
+  | [], _ => rfl
+  | b :: l, H => by
+    rw [length_cons, List.replicate]
+    cases' forall_mem_cons.1 H with H₁ H₂
+    conv_lhs => rw [H₁, eq_replicate_of_mem H₂]
+
+theorem eq_replicate' {a : α} {l : List α} : l = List.replicate l.length a ↔ ∀ b ∈ l, b = a :=
+  ⟨fun h => h.symm ▸ fun _ => eq_of_mem_replicate, eq_replicate_of_mem⟩
+
+theorem eq_replicate {a : α} {n} {l : List α} :
+    l = List.replicate n a ↔ length l = n ∧ ∀ b ∈ l, b = a :=
+  ⟨fun h => h.symm ▸ ⟨length_replicate _ _, fun _ => eq_of_mem_replicate⟩, fun ⟨e, al⟩ =>
+    e ▸ eq_replicate_of_mem al⟩
+
+theorem replicate_add (a : α) (m n) :
+    List.replicate (m + n) a = List.replicate m a ++ List.replicate n a := by
+  induction m <;> simp [*, zero_add, succ_add, List.replicate]
+
+theorem replicate_subset_singleton (a : α) (n) : List.replicate n a ⊆ [a] := fun _ h =>
+  mem_singleton.2 (eq_of_mem_replicate h)
+
+theorem subset_singleton_iff {a : α} : ∀ L : List α, L ⊆ [a] ↔ ∃ n, L = List.replicate n a
+  | [] => ⟨fun _ => ⟨0, by simp⟩, by simp⟩
+  | h :: L => by
+    refine' ⟨fun h => _, fun ⟨k, hk⟩ => by simp [hk, replicate_subset_singleton]⟩
+    rw [cons_subset] at h
+    obtain ⟨n, rfl⟩ := (subset_singleton_iff L).mp h.2
+    exact ⟨n.succ, by simp [mem_singleton.mp h.1]⟩
+
+@[simp] theorem map_replicate (f : α → β) (a : α) (n) :
+    map f (List.replicate n a) = List.replicate n (f a) := by
+  induction n <;> [rfl, simp only [*, List.replicate, map]]
+
+@[simp] theorem tail_replicate (a : α) (n) :
+    tail (List.replicate n a) = List.replicate n.pred a := by cases n <;> rfl
+
+@[simp] theorem join_replicate_nil (n : ℕ) : join (List.replicate n []) = @nil α := by
+  induction n <;> [rfl, simp only [*, List.replicate, join, append_nil]]
+
+theorem replicate_left_injective {n : ℕ} (hn : n ≠ 0) :
+    Function.Injective (@List.replicate α n ·) :=
+  fun _ _ h => (eq_replicate.1 h).2 _ <| mem_replicate.2 ⟨hn, rfl⟩
+
+theorem replicate_left_inj {a b : α} {n : ℕ} (hn : n ≠ 0) :
+    List.replicate n a = List.replicate n b ↔ a = b :=
+  (replicate_left_injective hn).eq_iff
+
+@[simp] theorem replicate_left_inj' {a b : α} : ∀ {n},
+    List.replicate n a = List.replicate n b ↔ n = 0 ∨ a = b
+  | 0 => by simp
+  | n + 1 => (replicate_left_inj n.succ_ne_zero).trans <| by simp [n.succ_ne_zero, false_or_iff]
+
+theorem replicate_right_injective (a : α) : Function.Injective (List.replicate · a) :=
+  Function.LeftInverse.injective (length_replicate · a)
 
-/-- Partial map. If `f : Π a, p a → β` is a partial function defined on
-  `a : α` satisfying `p`, then `pmap f l h` is essentially the same as `map f l`
-  but is defined only when all members of `l` satisfy `p`, using the proof
-  to apply `f`. -/
 @[simp]
-def pmap {p : α → Prop} (f : ∀ a, p a → β) : ∀ l : List α, (∀ a ∈ l, p a) → List β
-  | [], _ => []
-  | a :: l, H => f a (forall_mem_cons.1 H).1 :: pmap f l (forall_mem_cons.1 H).2
+theorem replicate_right_inj {a : α} {n m : ℕ} :
+    List.replicate n a = List.replicate m a ↔ n = m :=
+  (replicate_right_injective a).eq_iff
 
-/-- "Attach" the proof that the elements of `l` are in `l` to produce a new list
-  with the same elements but in the type `{x // x ∈ l}`. -/
-def attach (l : List α) : List { x // x ∈ l } :=
-  pmap Subtype.mk l (fun _ ↦ id)
+section deprecated
+set_option linter.deprecated false
+
+-- Porting note: From Lean3 Core
+@[deprecated length_replicate]
+lemma length_repeat (a : α) (n : ℕ) : length (List.repeat a n) = n := length_replicate ..
+#align list.length_repeat List.length_repeat
+
+@[deprecated replicate_succ]
+theorem repeat_succ (a : α) (n) : List.repeat a (n + 1) = a :: List.repeat a n :=
+  rfl
+#align list.repeat_succ List.repeat_succ
+
+@[deprecated mem_replicate]
+theorem mem_repeat {a b : α} {n} : b ∈ List.repeat a n ↔ n ≠ 0 ∧ b = a := mem_replicate
+#align list.mem_repeat List.mem_repeat
+
+@[deprecated eq_of_mem_replicate]
+theorem eq_of_mem_repeat {a b : α} {n} (h : b ∈ List.repeat a n) : b = a := eq_of_mem_replicate h
+#align list.eq_of_mem_repeat List.eq_of_mem_repeat
+
+@[deprecated eq_replicate_of_mem]
+theorem eq_repeat_of_mem {a : α} {l : List α} : (∀ b ∈ l, b = a) → l = List.repeat a l.length :=
+  eq_replicate_of_mem
+#align list.eq_repeat_of_mem List.eq_repeat_of_mem
+
+@[deprecated eq_replicate']
+theorem eq_repeat' {a : α} {l : List α} : l = List.repeat a l.length ↔ ∀ b ∈ l, b = a :=
+  eq_replicate'
+#align list.eq_repeat' List.eq_repeat'
+
+@[deprecated eq_replicate]
+theorem eq_repeat {a : α} {n} {l : List α} : l = List.repeat a n ↔ length l = n ∧ ∀ b ∈ l, b = a :=
+  eq_replicate
+#align list.eq_repeat List.eq_repeat
+
+@[deprecated replicate_add]
+theorem repeat_add (a : α) (m n) : List.repeat a (m + n) = List.repeat a m ++ List.repeat a n :=
+  replicate_add ..
+#align list.repeat_add List.repeat_add
+
+@[deprecated replicate_subset_singleton]
+theorem repeat_subset_singleton (a : α) (n) : List.repeat a n ⊆ [a] :=
+  replicate_subset_singleton ..
+#align list.repeat_subset_singleton List.repeat_subset_singleton
+
+#align list.subset_singleton_iff List.subset_singleton_iff
+
+@[deprecated map_replicate]
+theorem map_repeat (f : α → β) (a : α) (n) : map f (List.repeat a n) = List.repeat (f a) n :=
+  map_replicate ..
+#align list.map_repeat List.map_repeat
+
+@[deprecated tail_replicate]
+theorem tail_repeat (a : α) (n) : tail (List.repeat a n) = List.repeat a n.pred :=
+  tail_replicate ..
+#align list.tail_repeat List.tail_repeat
+
+@[deprecated join_replicate_nil]
+theorem join_repeat_nil (n : ℕ) : join (List.repeat [] n) = @nil α :=
+  join_replicate_nil ..
+#align list.join_repeat_nil List.join_repeat_nil
+
+@[deprecated replicate_left_injective]
+theorem repeat_left_injective {n : ℕ} (hn : n ≠ 0) :
+    Function.Injective fun a : α => List.repeat a n := replicate_left_injective hn
+#align list.repeat_left_injective List.repeat_left_injective
+
+@[deprecated replicate_left_inj]
+theorem repeat_left_inj {a b : α} {n : ℕ} (hn : n ≠ 0) :
+    List.repeat a n = List.repeat b n ↔ a = b :=
+  replicate_left_inj hn
+#align list.repeat_left_inj List.repeat_left_inj
+
+@[deprecated replicate_left_inj']
+theorem repeat_left_inj' {a b : α} {n} : List.repeat a n = List.repeat b n ↔ n = 0 ∨ a = b :=
+  replicate_left_inj'
+#align list.repeat_left_inj' List.repeat_left_inj'
+
+@[deprecated replicate_right_injective]
+theorem repeat_right_injective (a : α) : Function.Injective (List.repeat a) :=
+  replicate_right_injective ..
+#align list.repeat_right_injective List.repeat_right_injective
+
+@[deprecated replicate_right_inj]
+theorem repeat_right_inj {a : α} {n m : ℕ} : List.repeat a n = List.repeat a m ↔ n = m :=
+  replicate_right_inj ..
+#align list.repeat_right_inj List.repeat_right_inj
+
+end deprecated
+
+/-! ### pure -/
+
+-- ADHOC Porting note: TODO this is from Lean3 core, so doesn't belong here
+instance : Monad List := { pure := @List.ret, bind := @List.bind, map := @List.map }
+
+-- Porting note: simp can prove this
+-- @[simp]
+theorem bind_singleton (f : α → List β) (x : α) : [x].bind f = f x :=
+  append_nil (f x)
+#align list.bind_singleton List.bind_singleton
+
+@[simp] theorem bind_singleton' (l : List α) : (l.bind fun x => [x]) = l := by
+  induction l <;> simp [*]
+#align list.bind_singleton' List.bind_singleton'
+
+theorem map_eq_bind {α β} (f : α → β) (l : List α) : map f l = l.bind fun x => [f x] := by
+  trans
+  rw [← bind_singleton' l, bind_map]
+  rfl
+#align list.map_eq_bind List.map_eq_bind
+
+theorem bind_assoc {α β} (l : List α) (f : α → List β) (g : β → List γ) :
+    (l.bind f).bind g = l.bind fun x => (f x).bind g := by induction l <;> simp [*]
+#align list.bind_assoc List.bind_assoc
+
+-- ADHOC Porting note: TODO this is from Lean3 core, so doesn't belong here
+instance : LawfulMonad List := LawfulMonad.mk'
+  (id_map := map_id)
+  (pure_bind := fun _ _ => List.append_nil _)
+  (bind_assoc := List.bind_assoc)
+  (bind_pure_comp := fun _ _ => (map_eq_bind _ _).symm)
 
 @[simp]
-theorem pmap_eq_map (p : α → Prop) (f : α → β) (l : List α) (H) :
-    @pmap _ _ p (fun a _ ↦ f a) l H = map f l := by
-  induction l with
-  | nil => rfl
-  | cons => simp only [*, pmap, map]
+theorem mem_pure {α} (x y : α) : x ∈ (pure y : List α) ↔ x = y :=
+  show x ∈ [y] ↔ x = y by simp
+#align list.mem_pure List.mem_pure
 
-theorem pmap_congr {p q : α → Prop} {f : ∀ a, p a → β} {g : ∀ a, q a → β} (l : List α) {H₁ H₂}
-    (h : ∀ a ∈ l, ∀ (h₁ h₂), f a h₁ = g a h₂) : pmap f l H₁ = pmap g l H₂ := by
-  induction l with
-  | nil => rfl
-  | cons a l ih =>
-    rw [pmap, pmap, h _ (mem_cons_self _ _), ih (fun a ha ↦ h a (mem_cons_of_mem _ ha))]
+/-! ### bind -/
 
-theorem map_pmap {p : α → Prop} (g : β → γ) (f : ∀ a, p a → β) (l H) :
-    map g (pmap f l H) = pmap (fun a h ↦ g (f a h)) l H := by
-  induction l with
-  | nil => rfl
-  | cons => simp only [*, pmap, map]
+@[simp]
+theorem bind_eq_bind {α β} (f : α → List β) (l : List α) : l >>= f = l.bind f :=
+  rfl
+#align list.bind_eq_bind List.bind_eq_bind
 
-theorem pmap_map {p : β → Prop} (g : ∀ b, p b → γ) (f : α → β) (l H) :
-    pmap g (map f l) H = pmap (fun a h ↦ g (f a) h) l fun a h ↦ H _ (mem_map_of_mem _ h) := by
-  induction l with
-  | nil => rfl
-  | cons => simp only [*, pmap, map]
+-- TODO: duplicate of a lemma in core
+theorem bind_append (f : α → List β) (l₁ l₂ : List α) :
+    (l₁ ++ l₂).bind f = l₁.bind f ++ l₂.bind f :=
+  append_bind _ _ _
+#align list.bind_append List.bind_append
 
-theorem pmap_eq_map_attach {p : α → Prop} (f : ∀ a, p a → β) (l H) :
-    pmap f l H = l.attach.map fun x ↦ f x.1 (H _ x.2) := by
-  rw [attach, map_pmap]; exact pmap_congr l fun _ _ _ _ ↦ rfl
+/-! ### concat -/
+
+theorem concat_nil (a : α) : concat [] a = [a] :=
+  rfl
+#align list.concat_nil List.concat_nil
+
+theorem concat_cons (a b : α) (l : List α) : concat (a :: l) b = a :: concat l b :=
+  rfl
+#align list.concat_cons List.concat_cons
+
+@[deprecated concat_eq_append]
+theorem concat_eq_append' (a : α) (l : List α) : concat l a = l ++ [a] :=
+  concat_eq_append l a
+#align list.concat_eq_append List.concat_eq_append'
+
+theorem init_eq_of_concat_eq {a : α} {l₁ l₂ : List α} : concat l₁ a = concat l₂ a → l₁ = l₂ := by
+  intro h
+  rw [concat_eq_append, concat_eq_append] at h
+  exact append_right_cancel h
+#align list.init_eq_of_concat_eq List.init_eq_of_concat_eq
+
+theorem last_eq_of_concat_eq {a b : α} {l : List α} : concat l a = concat l b → a = b := by
+  intro h
+  rw [concat_eq_append, concat_eq_append] at h
+  exact head_eq_of_cons_eq (append_left_cancel h)
+#align list.last_eq_of_concat_eq List.last_eq_of_concat_eq
+
+theorem concat_ne_nil (a : α) (l : List α) : concat l a ≠ [] := by simp
+#align list.concat_ne_nil List.concat_ne_nil
+
+theorem concat_append (a : α) (l₁ l₂ : List α) : concat l₁ a ++ l₂ = l₁ ++ a :: l₂ := by simp
+#align list.concat_append List.concat_append
+
+@[deprecated length_concat]
+theorem length_concat' (a : α) (l : List α) : length (concat l a) = succ (length l) := by
+  simp only [concat_eq_append, length_append, length]
+#align list.length_concat List.length_concat'
+
+theorem append_concat (a : α) (l₁ l₂ : List α) : l₁ ++ concat l₂ a = concat (l₁ ++ l₂) a := by simp
+#align list.append_concat List.append_concat
+
+/-! ### reverse -/
+
+#align list.reverse_nil List.reverse_nil
+
+#align list.reverse_core List.reverseAux
 
-theorem attach_map_val (l : List α) : l.attach.map Subtype.val = l := by
-  rw [attach, map_pmap]; exact (pmap_eq_map ..).trans (map_id l)
+-- Porting note: Do we need this?
+attribute [local simp] reverseAux
+
+#align list.reverse_cons List.reverse_cons
+
+#align list.reverse_core_eq List.reverseAux_eq
+
+theorem reverse_cons' (a : α) (l : List α) : reverse (a :: l) = concat (reverse l) a := by
+  simp only [reverse_cons, concat_eq_append]
+#align list.reverse_cons' List.reverse_cons'
+
+-- Porting note: simp can prove this
+-- @[simp]
+theorem reverse_singleton (a : α) : reverse [a] = [a] :=
+  rfl
+#align list.reverse_singleton List.reverse_singleton
+
+#align list.reverse_append List.reverse_append
+#align list.reverse_concat List.reverse_concat
+#align list.reverse_reverse List.reverse_reverse
 
 @[simp]
-theorem mem_attach (l : List α) : ∀ x, x ∈ l.attach
-  | ⟨a, h⟩ => by
-    have := mem_map.1 (by rw [attach_map_val] <;> exact h)
-    rcases this with ⟨⟨_, _⟩, m, rfl⟩
-    exact m
+theorem reverse_involutive : Involutive (@reverse α) :=
+  reverse_reverse
+#align list.reverse_involutive List.reverse_involutive
 
 @[simp]
-theorem mem_pmap {p : α → Prop} {f : ∀ a, p a → β} {l H b} :
-    b ∈ pmap f l H ↔ ∃ (a : _)(h : a ∈ l), f a (H a h) = b := by
-  simp only [pmap_eq_map_attach, mem_map, mem_attach, true_and, Subtype.exists, eq_comm]
+theorem reverse_injective : Injective (@reverse α) :=
+  reverse_involutive.injective
+#align list.reverse_injective List.reverse_injective
+
+theorem reverse_surjective : Surjective (@reverse α) :=
+  reverse_involutive.surjective
+#align list.reverse_surjective List.reverse_surjective
+
+theorem reverse_bijective : Bijective (@reverse α) :=
+  reverse_involutive.bijective
+#align list.reverse_bijective List.reverse_bijective
+
+@[simp]
+theorem reverse_inj {l₁ l₂ : List α} : reverse l₁ = reverse l₂ ↔ l₁ = l₂ :=
+  reverse_injective.eq_iff
+#align list.reverse_inj List.reverse_inj
+
+theorem reverse_eq_iff {l l' : List α} : l.reverse = l' ↔ l = l'.reverse :=
+  reverse_involutive.eq_iff
+#align list.reverse_eq_iff List.reverse_eq_iff
+
+@[simp]
+theorem reverse_eq_nil {l : List α} : reverse l = [] ↔ l = [] :=
+  @reverse_inj _ l []
+#align list.reverse_eq_nil List.reverse_eq_nil
+
+theorem concat_eq_reverse_cons (a : α) (l : List α) : concat l a = reverse (a :: reverse l) := by
+  simp only [concat_eq_append, reverse_cons, reverse_reverse]
+#align list.concat_eq_reverse_cons List.concat_eq_reverse_cons
+
+#align list.length_reverse List.length_reverse
+
+-- Porting note: This one was @[simp] in mathlib 3,
+-- but Std contains a competing simp lemma reverse_map.
+-- For now we remove @[simp] to avoid simplification loops.
+-- TODO: Change Std lemma to match mathlib 3?
+theorem map_reverse (f : α → β) (l : List α) : map f (reverse l) = reverse (map f l) :=
+  (reverse_map f l).symm
+#align list.map_reverse List.map_reverse
+
+theorem map_reverseAux (f : α → β) (l₁ l₂ : List α) :
+    map f (reverseAux l₁ l₂) = reverseAux (map f l₁) (map f l₂) := by
+  simp only [reverseAux_eq, map_append, map_reverse]
+#align list.map_reverse_core List.map_reverseAux
+
+-- Porting TODO: Fix statement of `mem_reverse` in Std to match Lean3,
+-- then deprecate/remove this one
+theorem mem_reverse' {a : α} {l : List α} : a ∈ reverse l ↔ a ∈ l :=
+  List.mem_reverse _ _
+#align list.mem_reverse List.mem_reverse'
+
+@[simp] theorem reverse_replicate (n) (a : α) : reverse (List.replicate n a) = List.replicate n a :=
+  eq_replicate.2
+    ⟨by simp only [length_reverse, length_replicate],
+     fun b h => eq_of_mem_replicate (mem_reverse'.1 h)⟩
+
+set_option linter.deprecated false in
+@[deprecated reverse_replicate]
+theorem reverse_repeat (a : α) (n) : reverse (List.repeat a n) = List.repeat a n :=
+  reverse_replicate ..
+#align list.reverse_repeat List.reverse_repeat
+
+/-! ### empty -/
+
+-- Porting note: Definition from Lean3 core, so should be moved
+#align list.empty List.isEmpty
+
+-- Porting note: this does not work as desired
+-- attribute [simp] List.isEmpty
+
+theorem isEmpty_iff_eq_nil {l : List α} : l.isEmpty ↔ l = [] := by cases l <;> simp [isEmpty]
+#align list.empty_iff_eq_nil List.isEmpty_iff_eq_nil
+
+/-! ### dropLast -/
+
+@[simp]
+theorem length_dropLast : ∀ l : List α, length l.dropLast = length l - 1
+  | [] | [_] => rfl
+  | a::b::l => by
+    rw [dropLast, length_cons, length_cons, length_dropLast (b::l), succ_sub_one, length_cons,
+      succ_sub_one]
+    simp
+#align list.length_init List.length_dropLast
+
+-- Porting note: `rw [dropLast]` in Lean4 generates a goal `(b::l) ≠ []`
+-- so we use this lemma instead
+theorem dropLast_cons_cons (a b : α) (l : List α) : dropLast (a::b::l) = a::dropLast (b::l) := rfl
+
+/-! ### getLast -/
+
+-- Porting note: TODO: After https://github.com/leanprover/std4/pull/75, change to:
+-- @[simp]
+@[simp 1100, nolint simpNF]
+theorem getLast_cons {a : α} {l : List α} :
+    ∀ h : l ≠ nil, getLast (a :: l) (cons_ne_nil a l) = getLast l h := by
+  induction l <;> intros
+  contradiction
+  rfl
+#align list.last_cons List.getLast_cons
+
+theorem getLast_append_singleton {a : α} (l : List α) :
+    getLast (l ++ [a]) (append_ne_nil_of_ne_nil_right l _ (cons_ne_nil a _)) = a := by
+  simp only [getLast_append]
+#align list.last_append_singleton List.getLast_append_singleton
+
+-- Porting note: name should be fixed upstream
+theorem getLast_append' (l₁ l₂ : List α) (h : l₂ ≠ []) :
+    getLast (l₁ ++ l₂) (append_ne_nil_of_ne_nil_right l₁ l₂ h) = getLast l₂ h := by
+  induction' l₁ with _ _ ih
+  · simp
+  · simp only [cons_append]
+    rw [List.getLast_cons]
+    exact ih
+#align list.getLast_append List.getLast_append'
+
+theorem getLast_concat' {a : α} (l : List α) : getLast (concat l a) (concat_ne_nil a l) = a :=
+  getLast_concat ..
+#align list.last_concat List.getLast_concat'
+
+-- Porting note: TODO: After https://github.com/leanprover/std4/pull/75, change to:
+-- @[simp]
+@[simp 1100, nolint simpNF]
+theorem getLast_singleton' (a : α) : getLast [a] (cons_ne_nil a []) = a := rfl
+#align list.last_singleton List.getLast_singleton'
+
+-- Porting note: simp can prove this
+-- @[simp]
+theorem getLast_cons_cons (a₁ a₂ : α) (l : List α) :
+    getLast (a₁ :: a₂ :: l) (cons_ne_nil _ _) = getLast (a₂ :: l) (cons_ne_nil a₂ l) :=
+  rfl
+#align list.last_cons_cons List.getLast_cons_cons
+
+theorem dropLast_append_getLast : ∀ {l : List α} (h : l ≠ []), dropLast l ++ [getLast l h] = l
+  | [], h => absurd rfl h
+  | [a], h => rfl
+  | a :: b :: l, h => by
+    rw [dropLast_cons_cons, cons_append, getLast_cons (cons_ne_nil _ _)]
+    congr
+    exact dropLast_append_getLast (cons_ne_nil b l)
+#align list.init_append_last List.dropLast_append_getLast
+
+theorem getLast_congr {l₁ l₂ : List α} (h₁ : l₁ ≠ []) (h₂ : l₂ ≠ []) (h₃ : l₁ = l₂) :
+    getLast l₁ h₁ = getLast l₂ h₂ := by subst l₁; rfl
+#align list.last_congr List.getLast_congr
+
+theorem getLast_mem : ∀ {l : List α} (h : l ≠ []), getLast l h ∈ l
+  | [], h => absurd rfl h
+  | [a], _ => by simp only [getLast, mem_singleton]
+  | a :: b :: l, h =>
+    List.mem_cons.2 <| Or.inr <| by
+        rw [getLast_cons_cons]
+        exact getLast_mem (cons_ne_nil b l)
+#align list.last_mem List.getLast_mem
+
+theorem getLast_replicate_succ (m a : ℕ) :
+    (List.replicate m.succ a).getLast (ne_nil_of_length_eq_succ
+      (show (List.replicate m.succ a).length = m.succ by rw [length_replicate])) = a := by
+  induction' m with k IH
+  · simp
+  · simpa only [replicate_succ, getLast]
+
+set_option linter.deprecated false in
+@[deprecated getLast_replicate_succ]
+theorem getLast_repeat_succ (a m : ℕ) :
+    (List.repeat a m.succ).getLast (ne_nil_of_length_eq_succ
+      (show (List.repeat a m.succ).length = m.succ by rw [length_repeat])) = a :=
+  getLast_replicate_succ ..
+#align list.last_repeat_succ List.getLast_repeat_succ
+
+/-! ### getLast? -/
+
+-- Porting note: New lemma, since definition of getLast? is slightly different.
+-- Porting note: TODO: After https://github.com/leanprover/std4/pull/75, change to:
+-- @[simp]
+@[simp 1100, nolint simpNF] theorem getLast?_singleton (a : α) :
+    getLast? [a] = a := rfl
+
+-- Porting note: Moved earlier in file, for use in subsequent lemmas.
+-- Porting note: TODO: After https://github.com/leanprover/std4/pull/75, change to:
+-- @[simp]
+@[simp 1100, nolint simpNF] theorem getLast?_cons_cons (a b : α) (l : List α) :
+    getLast? (a :: b :: l) = getLast? (b :: l) := rfl
+
+@[simp]
+theorem getLast?_isNone : ∀ {l : List α}, (getLast? l).isNone ↔ l = []
+  | [] => by simp
+  | [a] => by simp
+  | a :: b :: l => by simp [@getLast?_isNone (b :: l)]
+#align list.last'_is_none List.getLast?_isNone
+
+@[simp]
+theorem getLast?_isSome : ∀ {l : List α}, l.getLast?.isSome ↔ l ≠ []
+  | [] => by simp
+  | [a] => by simp
+  | a :: b :: l => by simp [@getLast?_isSome (b :: l)]
+#align list.last'_is_some List.getLast?_isSome
+
+theorem mem_getLast?_eq_getLast : ∀ {l : List α} {x : α}, x ∈ l.getLast? → ∃ h, x = getLast l h
+  | [], x, hx => False.elim <| by simp at hx
+  | [a], x, hx =>
+    have : a = x := by simpa using hx
+    this ▸ ⟨cons_ne_nil a [], rfl⟩
+  | a :: b :: l, x, hx => by
+    rw [getLast?_cons_cons] at hx
+    rcases mem_getLast?_eq_getLast hx with ⟨_, h₂⟩
+    use cons_ne_nil _ _
+#align list.mem_last'_eq_last List.mem_getLast?_eq_getLast
+
+theorem getLast?_eq_getLast_of_ne_nil : ∀ {l : List α} (h : l ≠ []), l.getLast? = some (l.getLast h)
+  | [], h => (h rfl).elim
+  | [_], _ => rfl
+  | _ :: b :: l, _ => @getLast?_eq_getLast_of_ne_nil (b :: l) (cons_ne_nil _ _)
+#align list.last'_eq_last_of_ne_nil List.getLast?_eq_getLast_of_ne_nil
+
+theorem mem_getLast?_cons {x y : α} : ∀ {l : List α}, x ∈ l.getLast? → x ∈ (y :: l).getLast?
+  | [], _ => by contradiction
+  | _ :: _, h => h
+#align list.mem_last'_cons List.mem_getLast?_cons
+
+theorem mem_of_mem_getLast? {l : List α} {a : α} (ha : a ∈ l.getLast?) : a ∈ l :=
+  let ⟨_, h₂⟩ := mem_getLast?_eq_getLast ha
+  h₂.symm ▸ getLast_mem _
+#align list.mem_of_mem_last' List.mem_of_mem_getLast?
+
+theorem dropLast_append_getLast? : ∀ {l : List α}, ∀ a ∈ l.getLast?, dropLast l ++ [a] = l
+  | [], a, ha => (Option.not_mem_none a ha).elim
+  | [a], _, rfl => rfl
+  | a :: b :: l, c, hc => by
+    rw [getLast?_cons_cons] at hc
+    rw [dropLast_cons_cons, cons_append, dropLast_append_getLast? _ hc]
+#align list.init_append_last' List.dropLast_append_getLast?
+
+theorem getLastI_eq_getLast? [Inhabited α] : ∀ l : List α, l.getLastI = l.getLast?.iget
+  | [] => by simp [getLastI, Inhabited.default]
+  | [a] => rfl
+  | [a, b] => rfl
+  | [a, b, c] => rfl
+  | _ :: _ :: c :: l => by simp [getLastI, getLastI_eq_getLast? (c :: l)]
+#align list.ilast_eq_last' List.getLastI_eq_getLast?
+
+@[simp]
+theorem getLast?_append_cons :
+    ∀ (l₁ : List α) (a : α) (l₂ : List α), getLast? (l₁ ++ a :: l₂) = getLast? (a :: l₂)
+  | [], a, l₂ => rfl
+  | [b], a, l₂ => rfl
+  | b :: c :: l₁, a, l₂ => by rw [cons_append, cons_append, getLast?_cons_cons,
+    ← cons_append, getLast?_append_cons (c :: l₁)]
+#align list.last'_append_cons List.getLast?_append_cons
+
+#align list.last'_cons_cons List.getLast?_cons_cons
+
+theorem getLast?_append_of_ne_nil (l₁ : List α) :
+    ∀ {l₂ : List α} (_ : l₂ ≠ []), getLast? (l₁ ++ l₂) = getLast? l₂
+  | [], hl₂ => by contradiction
+  | b :: l₂, _ => getLast?_append_cons l₁ b l₂
+#align list.last'_append_of_ne_nil List.getLast?_append_of_ne_nil
+
+theorem getLast?_append {l₁ l₂ : List α} {x : α} (h : x ∈ l₂.getLast?) :
+    x ∈ (l₁ ++ l₂).getLast? := by
+  cases l₂
+  · contradiction
+  · rw [List.getLast?_append_cons]
+    exact h
+#align list.last'_append List.getLast?_append
+
+/-! ### head(!?) and tail -/
+
+theorem head!_eq_head? [Inhabited α] (l : List α) : head! l = (head? l).iget := by cases l <;> rfl
+#align list.head_eq_head' List.head!_eq_head?
+
+theorem surjective_head [Inhabited α] : Surjective (@head! α _) := fun x => ⟨[x], rfl⟩
+#align list.surjective_head List.surjective_head
+
+theorem surjective_head' : Surjective (@head? α) :=
+  Option.forall.2 ⟨⟨[], rfl⟩, fun x => ⟨[x], rfl⟩⟩
+#align list.surjective_head' List.surjective_head'
+
+theorem surjective_tail : Surjective (@tail α)
+  | [] => ⟨[], rfl⟩
+  | a :: l => ⟨a :: a :: l, rfl⟩
+#align list.surjective_tail List.surjective_tail
+
+theorem eq_cons_of_mem_head? {x : α} : ∀ {l : List α}, x ∈ l.head? → l = x :: tail l
+  | [], h => (Option.not_mem_none _ h).elim
+  | a :: l, h => by
+    simp only [head?, Option.mem_def, Option.some_inj] at h
+    exact h ▸ rfl
+#align list.eq_cons_of_mem_head' List.eq_cons_of_mem_head?
+
+theorem mem_of_mem_head? {x : α} {l : List α} (h : x ∈ l.head?) : x ∈ l :=
+  (eq_cons_of_mem_head? h).symm ▸ mem_cons_self _ _
+#align list.mem_of_mem_head' List.mem_of_mem_head?
+
+@[simp] theorem head!_cons [Inhabited α] (a : α) (l : List α) : head! (a :: l) = a := rfl
+#align list.head_cons List.head!_cons
+
+#align list.tail_nil List.tail_nil
+#align list.tail_cons List.tail_cons
+
+@[simp]
+theorem head!_append [Inhabited α] (t : List α) {s : List α} (h : s ≠ []) :
+    head! (s ++ t) = head! s := by induction s; contradiction; rfl
+#align list.head_append List.head!_append
+
+theorem head?_append {s t : List α} {x : α} (h : x ∈ s.head?) : x ∈ (s ++ t).head? := by
+  cases s; contradiction; exact h
+#align list.head'_append List.head?_append
+
+theorem head?_append_of_ne_nil :
+    ∀ (l₁ : List α) {l₂ : List α} (_ : l₁ ≠ []), head? (l₁ ++ l₂) = head? l₁
+  | _ :: _, _, _ => rfl
+#align list.head'_append_of_ne_nil List.head?_append_of_ne_nil
+
+theorem tail_append_singleton_of_ne_nil {a : α} {l : List α} (h : l ≠ nil) :
+    tail (l ++ [a]) = tail l ++ [a] := by
+  induction l; contradiction; rw [tail, cons_append, tail]
+#align list.tail_append_singleton_of_ne_nil List.tail_append_singleton_of_ne_nil
+
+theorem cons_head?_tail : ∀ {l : List α} {a : α}, a ∈ head? l → a :: tail l = l
+  | [], a, h => by contradiction
+  | b :: l, a, h => by
+    simp at h
+    simp [h]
+#align list.cons_head'_tail List.cons_head?_tail
+
+theorem head!_mem_head? [Inhabited α] : ∀ {l : List α}, l ≠ [] → head! l ∈ head? l
+  | [], h => by contradiction
+  | a :: l, _ => rfl
+#align list.head_mem_head' List.head!_mem_head?
+
+theorem cons_head!_tail [Inhabited α] {l : List α} (h : l ≠ []) : head! l :: tail l = l :=
+  cons_head?_tail (head!_mem_head? h)
+#align list.cons_head_tail List.cons_head!_tail
+
+theorem head!_mem_self [Inhabited α] {l : List α} (h : l ≠ nil) : l.head! ∈ l := by
+  have h' := mem_cons_self l.head! l.tail
+  rwa [cons_head!_tail h] at h'
+#align list.head_mem_self List.head!_mem_self
+
+@[simp]
+theorem head?_map (f : α → β) (l) : head? (map f l) = (head? l).map f := by cases l <;> rfl
+#align list.head'_map List.head?_map
+
+theorem tail_append_of_ne_nil (l l' : List α) (h : l ≠ []) : (l ++ l').tail = l.tail ++ l' := by
+  cases l
+  · contradiction
+  · simp
+#align list.tail_append_of_ne_nil List.tail_append_of_ne_nil
+
+section deprecated
+set_option linter.deprecated false -- TODO(Mario): make replacements for theorems in this section
+
+@[simp] theorem nthLe_tail (l : List α) (i) (h : i < l.tail.length)
+    (h' : i + 1 < l.length := (by simpa [← lt_tsub_iff_right] using h)) :
+    l.tail.nthLe i h = l.nthLe (i + 1) h' := by
+  -- Porting note: cases l <;> [cases h, rfl] fails
+  cases l; {cases h}; rfl
+#align list.nth_le_tail List.nthLe_tail
+
+theorem nthLe_cons_aux {l : List α} {a : α} {n} (hn : n ≠ 0) (h : n < (a :: l).length) :
+    n - 1 < l.length := by
+  contrapose! h
+  rw [length_cons]
+  convert succ_le_succ h
+  exact (Nat.succ_pred_eq_of_pos hn.bot_lt).symm
+#align list.nth_le_cons_aux List.nthLe_cons_aux
+
+theorem nthLe_cons {l : List α} {a : α} {n} (hl) :
+    (a :: l).nthLe n hl = if hn : n = 0 then a else l.nthLe (n - 1) (nthLe_cons_aux hn hl) := by
+  split_ifs with h
+  · simp [nthLe, h]
+  cases l
+  · rw [length_singleton, lt_succ_iff, nonpos_iff_eq_zero] at hl
+    contradiction
+  cases n
+  · contradiction
+  rfl
+#align list.nth_le_cons List.nthLe_cons
+
+end deprecated
+
+-- Porting note: List.modifyHead has @[simp], and Lean 4 treats this as
+-- an invitation to unfold modifyHead in any context,
+-- not just use the equational lemmas.
+
+-- @[simp]
+@[simp 1100, nolint simpNF]
+theorem modifyHead_modifyHead (l : List α) (f g : α → α) :
+    (l.modifyHead f).modifyHead g = l.modifyHead (g ∘ f) := by cases l <;> simp
+#align list.modify_head_modify_head List.modifyHead_modifyHead
+
+/-! ### Induction from the right -/
+
+/-- Induction principle from the right for lists: if a property holds for the empty list, and
+for `l ++ [a]` if it holds for `l`, then it holds for all lists. The principle is given for
+a `Sort`-valued predicate, i.e., it can also be used to construct data. -/
+@[elab_as_elim]
+def reverseRecOn {C : List α → Sort _} (l : List α) (H0 : C [])
+    (H1 : ∀ (l : List α) (a : α), C l → C (l ++ [a])) : C l := by
+  rw [← reverse_reverse l]
+  match h:(reverse l) with
+  | [] => exact H0
+  | head :: tail =>
+    have : tail.length < l.length := by
+      rw [← length_reverse l, h, length_cons]
+      simp [Nat.lt_succ]
+    let ih := reverseRecOn (reverse tail) H0 H1
+    rw [reverse_cons]
+    exact H1 _ _ ih
+termination_by _ _ l _ _ => l.length
+#align list.reverse_rec_on List.reverseRecOn
+
+/-- Bidirectional induction principle for lists: if a property holds for the empty list, the
+singleton list, and `a :: (l ++ [b])` from `l`, then it holds for all lists. This can be used to
+prove statements about palindromes. The principle is given for a `Sort`-valued predicate, i.e., it
+can also be used to construct data. -/
+def bidirectionalRec {C : List α → Sort _} (H0 : C []) (H1 : ∀ a : α, C [a])
+    (Hn : ∀ (a : α) (l : List α) (b : α), C l → C (a :: (l ++ [b]))) : ∀ l, C l
+  | [] => H0
+  | [a] => H1 a
+  | a :: b :: l => by
+    let l' := dropLast (b :: l)
+    let b' := getLast (b :: l) (cons_ne_nil _ _)
+    rw [← dropLast_append_getLast (cons_ne_nil b l)]
+    have : C l' := bidirectionalRec H0 H1 Hn l'
+    exact Hn a l' b' this
+termination_by' measure List.length
+#align list.bidirectional_rec List.bidirectionalRecₓ -- universe order
+
+/-- Like `bidirectionalRec`, but with the list parameter placed first. -/
+@[elab_as_elim]
+def bidirectionalRecOn {C : List α → Sort _} (l : List α) (H0 : C []) (H1 : ∀ a : α, C [a])
+    (Hn : ∀ (a : α) (l : List α) (b : α), C l → C (a :: (l ++ [b]))) : C l :=
+  bidirectionalRec H0 H1 Hn l
+#align list.bidirectional_rec_on List.bidirectionalRecOn
+
+/-! ### sublists -/
+
+attribute [refl] List.Sublist.refl
+
+#align list.sublist.cons2 List.Sublist.cons₂
+
+#align list.nil_sublist List.nil_sublist
+#align list.sublist.refl List.Sublist.refl
+#align list.sublist.trans List.Sublist.trans
+#align list.sublist_cons List.sublist_cons
+#align list.sublist_of_cons_sublist List.sublist_of_cons_sublist
+
+theorem Sublist.cons_cons {l₁ l₂ : List α} (a : α) (s : l₁ <+ l₂) : a :: l₁ <+ a :: l₂ :=
+  Sublist.cons₂ _ s
+#align list.sublist.cons_cons List.Sublist.cons_cons
+
+#align list.sublist_append_left List.sublist_append_left
+#align list.sublist_append_right List.sublist_append_right
+
+theorem sublist_cons_of_sublist (a : α) {l₁ l₂ : List α} : l₁ <+ l₂ → l₁ <+ a :: l₂ :=
+  Sublist.cons _
+#align list.sublist_cons_of_sublist List.sublist_cons_of_sublist
+
+#align list.sublist_append_of_sublist_left List.sublist_append_of_sublist_left
+#align list.sublist_append_of_sublist_right List.sublist_append_of_sublist_right
+
+theorem sublist_of_cons_sublist_cons {l₁ l₂ : List α} : ∀ {a : α}, a :: l₁ <+ a :: l₂ → l₁ <+ l₂
+  | _, Sublist.cons _ s => sublist_of_cons_sublist s
+  | _, Sublist.cons₂ _ s => s
+#align list.sublist_of_cons_sublist_cons List.sublist_of_cons_sublist_cons
+
+theorem cons_sublist_cons_iff {l₁ l₂ : List α} {a : α} : a :: l₁ <+ a :: l₂ ↔ l₁ <+ l₂ :=
+  ⟨sublist_of_cons_sublist_cons, Sublist.cons_cons _⟩
+#align list.cons_sublist_cons_iff List.cons_sublist_cons_iff
+
+#align list.append_sublist_append_left List.append_sublist_append_left
+#align list.sublist.append_right List.Sublist.append_right
+#align list.sublist_or_mem_of_sublist List.sublist_or_mem_of_sublist
+#align list.sublist.reverse List.Sublist.reverse
+
+#align list.reverse_sublist_iff List.reverse_sublist
+
+#align list.append_sublist_append_right List.append_sublist_append_right
+#align list.sublist.append List.Sublist.append
+#align list.sublist.subset List.Sublist.subset
+
+@[simp]
+theorem singleton_sublist {a : α} {l} : [a] <+ l ↔ a ∈ l :=
+  ⟨fun h => h.subset (mem_singleton_self _), fun h =>
+    let ⟨_, _, e⟩ := mem_split h
+    e.symm ▸ ((nil_sublist _).cons_cons _).trans (sublist_append_right _ _)⟩
+#align list.singleton_sublist List.singleton_sublist
+
+theorem eq_nil_of_sublist_nil {l : List α} (s : l <+ []) : l = [] :=
+  eq_nil_of_subset_nil <| s.subset
+#align list.eq_nil_of_sublist_nil List.eq_nil_of_sublist_nil
+
+@[simp]
+theorem sublist_nil_iff_eq_nil {l : List α} : l <+ [] ↔ l = [] :=
+  ⟨eq_nil_of_sublist_nil, fun H => H ▸ Sublist.refl _⟩
+#align list.sublist_nil_iff_eq_nil List.sublist_nil_iff_eq_nil
+
+@[simp]
+theorem replicate_sublist_replicate {m n} (a : α) :
+    List.replicate m a <+ List.replicate n a ↔ m ≤ n :=
+  ⟨fun h => by simpa only [length_replicate] using h.length_le, fun h => by
+    induction h <;> [rfl, simp only [*, replicate_succ, Sublist.cons]]⟩
+
+set_option linter.deprecated false in
+@[deprecated replicate_sublist_replicate]
+theorem repeat_sublist_repeat (a : α) {m n} : List.repeat a m <+ List.repeat a n ↔ m ≤ n :=
+  replicate_sublist_replicate _
+#align list.repeat_sublist_repeat List.repeat_sublist_repeat
+
+theorem sublist_replicate_iff {l : List α} {a : α} {n : ℕ} :
+    l <+ List.replicate n a ↔ ∃ k ≤ n, l = List.replicate k a :=
+  ⟨fun h =>
+    ⟨l.length, h.length_le.trans (length_replicate _ _).le,
+      eq_replicate.mpr ⟨rfl, fun b hb => List.eq_of_mem_replicate (h.subset hb)⟩⟩,
+    by rintro ⟨k, h, rfl⟩; exact (replicate_sublist_replicate _).mpr h⟩
+
+set_option linter.deprecated false in
+@[deprecated sublist_replicate_iff]
+theorem sublist_repeat_iff {l : List α} {a : α} {n : ℕ} :
+    l <+ List.repeat a n ↔ ∃ k ≤ n, l = List.repeat a k := sublist_replicate_iff
+#align list.sublist_repeat_iff List.sublist_repeat_iff
+
+theorem Sublist.eq_of_length : ∀ {l₁ l₂ : List α}, l₁ <+ l₂ → length l₁ = length l₂ → l₁ = l₂
+  | _, _, Sublist.slnil, _ => rfl
+  | _, _, Sublist.cons a s, h => by
+    cases s.length_le.not_lt (by rw [h]; apply lt_succ_self)
+  | _, _, Sublist.cons₂ a s, h => by
+    rw [length, length] at h; injection h with h; rw [s.eq_of_length h]
+#align list.sublist.eq_of_length List.Sublist.eq_of_length
+
+theorem Sublist.eq_of_length_le (s : l₁ <+ l₂) (h : length l₂ ≤ length l₁) : l₁ = l₂ :=
+  s.eq_of_length <| s.length_le.antisymm h
+#align list.sublist.eq_of_length_le List.Sublist.eq_of_length_le
+
+theorem Sublist.antisymm (s₁ : l₁ <+ l₂) (s₂ : l₂ <+ l₁) : l₁ = l₂ :=
+  s₁.eq_of_length_le s₂.length_le
+#align list.sublist.antisymm List.Sublist.antisymm
+
+instance decidableSublist [DecidableEq α] : ∀ l₁ l₂ : List α, Decidable (l₁ <+ l₂)
+  | [], _ => isTrue <| nil_sublist _
+  | _ :: _, [] => isFalse fun h => List.noConfusion <| eq_nil_of_sublist_nil h
+  | a :: l₁, b :: l₂ =>
+    if h : a = b then
+      @decidable_of_decidable_of_iff _ _ (decidableSublist l₁ l₂) <|
+        h ▸ ⟨Sublist.cons_cons _, sublist_of_cons_sublist_cons⟩
+    else
+      @decidable_of_decidable_of_iff _ _ (decidableSublist (a :: l₁) l₂)
+        ⟨sublist_cons_of_sublist _, fun s =>
+          match a, l₁, s, h with
+          | _, _, Sublist.cons _ s', h => s'
+          | _, _, Sublist.cons₂ t _, h => absurd rfl h⟩
+#align list.decidable_sublist List.decidableSublist
+
+/-! ### indexOf -/
+
+section IndexOf
+
+variable [DecidableEq α]
+
+-- Porting note: simp can prove this
+-- @[simp]
+theorem indexOf_nil (a : α) : indexOf a [] = 0 :=
+  rfl
+#align list.index_of_nil List.indexOf_nil
+
+/-
+  Porting note: The following proofs were simpler prior to the port. These proofs use the low-level
+  `findIdx.go`.
+  * `indexOf_cons_self`
+  * `indexOf_cons_eq`
+  * `indexOf_cons_ne`
+  * `indexOf_cons`
+
+  The ported versions of the earlier proofs are given in comments.
+-/
+
+-- indexOf_cons_eq _ rfl
+@[simp]
+theorem indexOf_cons_self (a : α) (l : List α) : indexOf a (a :: l) = 0 := by
+  rw [indexOf, findIdx, findIdx.go, beq_self_eq_true, cond]
+#align list.index_of_cons_self List.indexOf_cons_self
+
+-- fun e => if_pos e
+theorem indexOf_cons_eq {a b : α} (l : List α) : a = b → indexOf a (b :: l) = 0
+  | e => by rw [e]; exact indexOf_cons_self b l
+#align list.index_of_cons_eq List.indexOf_cons_eq
+
+-- fun n => if_neg n
+@[simp]
+theorem indexOf_cons_ne {a b : α} (l : List α) : a ≠ b → indexOf a (b :: l) = succ (indexOf a l)
+  | n => by
+    cases l with
+    | nil => rw [indexOf, findIdx, findIdx.go, beq_false_of_ne n, cond, ←succ_eq_add_one]; rfl
+    | cons head tail =>
+      by_cases a = head
+      · rw [indexOf_cons_eq tail h, indexOf, findIdx, findIdx.go, beq_false_of_ne n, cond, h,
+          findIdx.go, beq_self_eq_true head, cond]
+      · rw [indexOf, findIdx, findIdx, findIdx.go, beq_false_of_ne, cond, findIdx.go,
+          beq_false_of_ne h, cond_false]
+        change _ = succ (cond (a == head) _ _)
+        rw [beq_false_of_ne h, cond_false]
+        simp only [findIdx_go_succ (fun x ↦ a == x) tail _]
+        exact n
+where
+  findIdx_go_succ (p : α → Bool) (l : List α) (n : ℕ) :
+      findIdx.go p l (n + 1) = succ (findIdx.go p l n) := by
+    cases l with
+    | nil => unfold findIdx.go; exact succ_eq_add_one n
+    | cons head tail =>
+      unfold findIdx.go
+      cases p head <;> simp only [cond]
+      · exact findIdx_go_succ p tail (n + 1)
+#align list.index_of_cons_ne List.indexOf_cons_ne
+
+-- rfl
+theorem indexOf_cons (a b : α) (l : List α) :
+    indexOf a (b :: l) = if a = b then 0 else succ (indexOf a l) := by
+  cases l <;> by_cases a = b
+  case pos | pos => rw [if_pos h]; exact indexOf_cons_eq _ h
+  case neg | neg => rw [if_neg h]; exact indexOf_cons_ne _ h
+#align list.index_of_cons List.indexOf_cons
+
+theorem indexOf_eq_length {a : α} {l : List α} : indexOf a l = length l ↔ a ∉ l := by
+  induction' l with b l ih
+  · exact iff_of_true rfl (not_mem_nil _)
+  simp only [length, mem_cons, indexOf_cons]; split_ifs with h
+  · exact iff_of_false (by rintro ⟨⟩) fun H => H <| Or.inl h
+  · simp only [h, false_or_iff]
+    rw [← ih]
+    exact succ_inj'
+#align list.index_of_eq_length List.indexOf_eq_length
+
+@[simp]
+theorem indexOf_of_not_mem {l : List α} {a : α} : a ∉ l → indexOf a l = length l :=
+  indexOf_eq_length.2
+#align list.index_of_of_not_mem List.indexOf_of_not_mem
+
+theorem indexOf_le_length {a : α} {l : List α} : indexOf a l ≤ length l := by
+  induction' l with b l ih; · rfl
+  simp only [length, indexOf_cons]
+  by_cases h : a = b;
+  · rw [if_pos h]
+    exact Nat.zero_le _
+  rw [if_neg h]; exact succ_le_succ ih
+#align list.index_of_le_length List.indexOf_le_length
+
+theorem indexOf_lt_length {a} {l : List α} : indexOf a l < length l ↔ a ∈ l :=
+  ⟨fun h => Decidable.by_contradiction fun al => Nat.ne_of_lt h <| indexOf_eq_length.2 al,
+   fun al => (lt_of_le_of_ne indexOf_le_length) fun h => indexOf_eq_length.1 h al⟩
+#align list.index_of_lt_length List.indexOf_lt_length
+
+theorem indexOf_append_of_mem {a : α} (h : a ∈ l₁) : indexOf a (l₁ ++ l₂) = indexOf a l₁ := by
+  induction' l₁ with d₁ t₁ ih
+  · exfalso
+    exact not_mem_nil a h
+  rw [List.cons_append]
+  by_cases hh : a = d₁
+  · iterate 2 rw [indexOf_cons_eq _ hh]
+  rw [indexOf_cons_ne _ hh, indexOf_cons_ne _ hh, ih (mem_of_ne_of_mem hh h)]
+#align list.index_of_append_of_mem List.indexOf_append_of_mem
+
+theorem indexOf_append_of_not_mem {a : α} (h : a ∉ l₁) :
+    indexOf a (l₁ ++ l₂) = l₁.length + indexOf a l₂ := by
+  induction' l₁ with d₁ t₁ ih
+  · rw [List.nil_append, List.length, zero_add]
+  rw [List.cons_append, indexOf_cons_ne _ (ne_of_not_mem_cons h), List.length,
+    ih (not_mem_of_not_mem_cons h), Nat.succ_add]
+#align list.index_of_append_of_not_mem List.indexOf_append_of_not_mem
+
+end IndexOf
+
+/-! ### nth element -/
+
+section deprecated
+set_option linter.deprecated false
+
+@[deprecated get_of_mem]
+theorem nthLe_of_mem {a} {l : List α} (h : a ∈ l) : ∃ n h, nthLe l n h = a :=
+  let ⟨i, h⟩ := get_of_mem h; ⟨i.1, i.2, h⟩
+#align list.nth_le_of_mem List.nthLe_of_mem
+
+@[deprecated get?_eq_get]
+theorem nthLe_get? {l : List α} {n} (h) : get? l n = some (nthLe l n h) := get?_eq_get _
+#align list.nth_le_nth List.nthLe_get?
+
+#align list.nth_len_le List.get?_len_le
+
+@[simp]
+theorem get?_length (l : List α) : l.get? l.length = none := get?_len_le le_rfl
+#align list.nth_length List.get?_length
+
+@[deprecated get?_eq_some]
+theorem get?_eq_some' {l : List α} {n a} : get? l n = some a ↔ ∃ h, nthLe l n h = a := get?_eq_some
+#align list.nth_eq_some List.get?_eq_some'
+
+#align list.nth_eq_none_iff List.get?_eq_none
+#align list.nth_of_mem List.get?_of_mem
+
+@[deprecated get_mem]
+theorem nthLe_mem (l : List α) (n h) : nthLe l n h ∈ l := get_mem ..
+#align list.nth_le_mem List.nthLe_mem
+
+#align list.nth_mem List.get?_mem
+
+@[deprecated mem_iff_get]
+theorem mem_iff_nthLe {a} {l : List α} : a ∈ l ↔ ∃ n h, nthLe l n h = a :=
+  mem_iff_get.trans ⟨fun ⟨⟨n, h⟩, e⟩ => ⟨n, h, e⟩, fun ⟨n, h, e⟩ => ⟨⟨n, h⟩, e⟩⟩
+#align list.mem_iff_nth_le List.mem_iff_nthLe
+
+#align list.mem_iff_nth List.mem_iff_get?
+#align list.nth_zero List.get?_zero
+
+-- Porting note: couldn't synthesize _ in cases h x _ rfl anymore, needed to be given explicitly
+theorem get?_injective {α : Type u} {xs : List α} {i j : ℕ} (h₀ : i < xs.length) (h₁ : Nodup xs)
+    (h₂ : xs.get? i = xs.get? j) : i = j := by
+  induction xs generalizing i j with
+  | nil => cases h₀
+  | cons x xs tail_ih =>
+    cases i <;> cases j
+    case zero.zero => rfl
+    case succ.succ =>
+      congr; cases h₁
+      apply tail_ih <;> solve_by_elim [lt_of_succ_lt_succ]
+    all_goals ( dsimp at h₂; cases' h₁ with _ _ h h')
+    · cases (h x (mem_iff_get?.mpr ⟨_, h₂.symm⟩) rfl)
+    · cases (h x (mem_iff_get?.mpr ⟨_, h₂⟩) rfl)
+#align list.nth_injective List.get?_injective
+
+#align list.nth_map List.get?_map
+
+@[deprecated get_map]
+theorem nthLe_map (f : α → β) {l n} (H1 H2) : nthLe (map f l) n H1 = f (nthLe l n H2) := get_map ..
+#align list.nth_le_map List.nthLe_map
+
+/-- A version of `get_map` that can be used for rewriting. -/
+theorem get_map_rev (f : α → β) {l n} :
+    f (get l n) = get (map f l) ⟨n.1, (l.length_map f).symm ▸ n.2⟩ := Eq.symm (get_map _)
+
+/-- A version of `nthLe_map` that can be used for rewriting. -/
+@[deprecated get_map_rev]
+theorem nthLe_map_rev (f : α → β) {l n} (H) :
+    f (nthLe l n H) = nthLe (map f l) n ((l.length_map f).symm ▸ H) :=
+  (nthLe_map f _ _).symm
+#align list.nth_le_map_rev List.nthLe_map_rev
+
+@[simp, deprecated get_map]
+theorem nthLe_map' (f : α → β) {l n} (H) :
+    nthLe (map f l) n H = f (nthLe l n (l.length_map f ▸ H)) := nthLe_map f _ _
+#align list.nth_le_map' List.nthLe_map'
+
+/-- If one has `nthLe 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 lemma `nth_le_of_eq` can be used to make
+such a rewrite, with `rw (nth_le_of_eq h)`. -/
+@[deprecated get_of_eq]
+theorem nthLe_of_eq {L L' : List α} (h : L = L') {i : ℕ} (hi : i < L.length) :
+    nthLe L i hi = nthLe L' i (h ▸ hi) := by congr
+#align list.nth_le_of_eq List.nthLe_of_eq
+
+@[simp, deprecated get_singleton]
+theorem nthLe_singleton (a : α) {n : ℕ} (hn : n < 1) : nthLe [a] n hn = a := get_singleton ..
+#align list.nth_le_singleton List.nthLe_singleton
+
+@[deprecated] -- FIXME: replacement -- it's not `get_zero` and it's not `get?_zero`
+theorem nthLe_zero [Inhabited α] {L : List α} (h : 0 < L.length) : List.nthLe L 0 h = L.head! := by
+  cases L
+  cases h
+  simp [nthLe]
+#align list.nth_le_zero List.nthLe_zero
+
+@[deprecated get_append]
+theorem nthLe_append {l₁ l₂ : List α} {n : ℕ} (hn₁) (hn₂) :
+    (l₁ ++ l₂).nthLe n hn₁ = l₁.nthLe n hn₂ := get_append _ hn₂
+#align list.nth_le_append List.nthLe_append
+
+@[deprecated get_append_right']
+theorem nthLe_append_right {l₁ l₂ : List α} {n : ℕ} (h₁ : l₁.length ≤ n) (h₂) :
+    (l₁ ++ l₂).nthLe n h₂ = l₂.nthLe (n - l₁.length) (get_append_right_aux h₁ h₂) :=
+  get_append_right' h₁ h₂
+#align list.nth_le_append_right_aux List.get_append_right_aux
+#align list.nth_le_append_right List.nthLe_append_right
+
+@[deprecated get_replicate]
+theorem nthLe_repeat (a : α) {n m : ℕ} (h : m < (List.repeat a n).length) :
+    (List.repeat a n).nthLe m h = a := get_replicate ..
+#align list.nth_le_repeat List.nthLe_repeat
+
+#align list.nth_append List.get?_append
+#align list.nth_append_right List.get?_append_right
+
+@[deprecated getLast_eq_get]
+theorem getLast_eq_nthLe (l : List α) (h : l ≠ []) :
+    getLast l h = l.nthLe (l.length - 1) (Nat.sub_lt (length_pos_of_ne_nil h) one_pos) :=
+  getLast_eq_get ..
+#align list.last_eq_nth_le List.getLast_eq_nthLe
+
+theorem get_length_sub_one {l : List α} (h : l.length - 1 < l.length) :
+    l.get ⟨l.length - 1, h⟩ = l.getLast (by rintro rfl; exact Nat.lt_irrefl 0 h) :=
+  (getLast_eq_get l _).symm
+
+@[deprecated get_length_sub_one]
+theorem nthLe_length_sub_one {l : List α} (h : l.length - 1 < l.length) :
+    l.nthLe (l.length - 1) h = l.getLast (by rintro rfl; exact Nat.lt_irrefl 0 h) :=
+  get_length_sub_one _
+#align list.nth_le_length_sub_one List.nthLe_length_sub_one
+
+#align list.nth_concat_length List.get?_concat_length
+
+@[deprecated get_cons_length]
+theorem nthLe_cons_length : ∀ (x : α) (xs : List α) (n : ℕ) (h : n = xs.length),
+    (x :: xs).nthLe n (by simp [h]) = (x :: xs).getLast (cons_ne_nil x xs) := get_cons_length
+#align list.nth_le_cons_length List.nthLe_cons_length
+
+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
+  induction' l with x l ih generalizing n
+  · cases h
+  · by_cases h₁ : l = []
+    · subst h₁
+      rw [get_singleton]
+      simp [lt_succ_iff] at h
+      subst h
+      simp
+    have h₂ := h
+    rw [length_cons, Nat.lt_succ_iff, le_iff_eq_or_lt] at h₂
+    cases n
+    · simp [get]
+    rw [drop, get]
+    apply ih
+
+@[deprecated take_one_drop_eq_of_lt_length]
+theorem take_one_drop_eq_of_lt_length' {l : List α} {n : ℕ} (h : n < l.length) :
+    (l.drop n).take 1 = [l.nthLe n h] := take_one_drop_eq_of_lt_length h
+#align list.take_one_drop_eq_of_lt_length List.take_one_drop_eq_of_lt_length'
+
+#align list.ext List.ext
+
+@[deprecated ext_get]
+theorem ext_nthLe {l₁ l₂ : List α} (hl : length l₁ = length l₂)
+    (h : ∀ n h₁ h₂, nthLe l₁ n h₁ = nthLe l₂ n h₂) : l₁ = l₂ :=
+  ext_get hl h
+#align list.ext_le List.ext_nthLe
+
+@[simp]
+theorem indexOf_get [DecidableEq α] {a : α} : ∀ {l : List α} (h), get l ⟨indexOf a l, h⟩ = a
+  | b :: l, h => by
+    by_cases h' : a = b <;>
+      simp only [h', if_pos, if_false, indexOf_cons, get, @indexOf_get _ _ l]
+
+@[simp, deprecated indexOf_get]
+theorem indexOf_nthLe [DecidableEq α] {a : α} : ∀ {l : List α} (h), nthLe l (indexOf a l) h = a :=
+  indexOf_get
+#align list.index_of_nth_le List.indexOf_nthLe
+
+@[simp]
+theorem indexOf_get? [DecidableEq α] {a : α} {l : List α} (h : a ∈ l) :
+    get? l (indexOf a l) = some a := by rw [nthLe_get?, indexOf_nthLe (indexOf_lt_length.2 h)]
+#align list.index_of_nth List.indexOf_get?
+
+@[deprecated]
+theorem get_reverse_aux₁ :
+    ∀ (l r : List α) (i h1 h2), get (reverseAux l r) ⟨i + length l, h1⟩ = get r ⟨i, h2⟩
+  | [], r, i => fun h1 _ => rfl
+  | a :: l, r, i => by
+    rw [show i + length (a :: l) = i + 1 + length l from add_right_comm i (length l) 1]
+    exact fun h1 h2 => get_reverse_aux₁ l (a :: r) (i + 1) h1 (succ_lt_succ h2)
+#align list.nth_le_reverse_aux1 List.get_reverse_aux₁
+
+theorem indexOf_inj [DecidableEq α] {l : List α} {x y : α} (hx : x ∈ l) (hy : y ∈ l) :
+    indexOf x l = indexOf y l ↔ x = y :=
+  ⟨fun h => by
+    have x_eq_y :
+        get l ⟨indexOf x l, indexOf_lt_length.2 hx⟩ =
+        get l ⟨indexOf y l, indexOf_lt_length.2 hy⟩ := by
+      simp only [h]
+    simp only [indexOf_get] at x_eq_y; exact x_eq_y, fun h => by subst h; rfl⟩
+#align list.index_of_inj List.indexOf_inj
+
+theorem get_reverse_aux₂ :
+    ∀ (l r : List α) (i : Nat) (h1) (h2),
+      get (reverseAux l r) ⟨length l - 1 - i, h1⟩ = get l ⟨i, h2⟩
+  | [], r, i, h1, h2 => absurd h2 (Nat.not_lt_zero _)
+  | a :: l, r, 0, h1, _ => by
+    have aux := get_reverse_aux₁ l (a :: r) 0
+    rw [zero_add] at aux
+    exact aux _ (zero_lt_succ _)
+  | a :: l, r, i + 1, h1, h2 => by
+    have aux := get_reverse_aux₂ l (a :: r) i
+    have heq :=
+      calc
+        length (a :: l) - 1 - (i + 1) = length l - (1 + i) := by rw [add_comm]; rfl
+        _ = length l - 1 - i := by rw [← tsub_add_eq_tsub_tsub]
+    rw [← heq] at aux
+    apply aux
+#align list.nth_le_reverse_aux2 List.get_reverse_aux₂
+
+@[simp] theorem get_reverse (l : List α) (i : Nat) (h1 h2) :
+    get (reverse l) ⟨length l - 1 - i, h1⟩ = get l ⟨i, h2⟩ :=
+  get_reverse_aux₂ _ _ _ _ _
+
+@[simp, deprecated get_reverse]
+theorem nthLe_reverse (l : List α) (i : Nat) (h1 h2) :
+    nthLe (reverse l) (length l - 1 - i) h1 = nthLe l i h2 :=
+  get_reverse ..
+#align list.nth_le_reverse List.nthLe_reverse
+
+theorem nthLe_reverse' (l : List α) (n : ℕ) (hn : n < l.reverse.length) (hn') :
+    l.reverse.nthLe n hn = l.nthLe (l.length - 1 - n) hn' := by
+  rw [eq_comm]
+  convert nthLe_reverse l.reverse n (by simpa) hn using 1
+  simp
+#align list.nth_le_reverse' List.nthLe_reverse'
+
+theorem get_reverse' (l : List α) (n) (hn') :
+    l.reverse.get n = l.get ⟨l.length - 1 - n, hn'⟩ := nthLe_reverse' ..
+
+-- FIXME: prove it the other way around
+attribute [deprecated get_reverse'] nthLe_reverse'
+
+theorem eq_cons_of_length_one {l : List α} (h : l.length = 1) :
+    l = [l.nthLe 0 (h.symm ▸ zero_lt_one)] := by
+  refine' ext_get (by convert h) fun n h₁ h₂ => _
+  simp only [get_singleton]
+  congr
+  exact eq_bot_iff.mpr (Nat.lt_succ_iff.mp h₂)
+#align list.eq_cons_of_length_one List.eq_cons_of_length_one
+
+theorem get_eq_iff {l : List α} {n : Fin l.length} {x : α} : l.get n = x ↔ l.get? n.1 = some x := by
+  rw [get?_eq_some]
+  simp [n.2]
+
+@[deprecated get_eq_iff]
+theorem nthLe_eq_iff {l : List α} {n : ℕ} {x : α} {h} : l.nthLe n h = x ↔ l.get? n = some x :=
+  get_eq_iff
+#align list.nth_le_eq_iff List.nthLe_eq_iff
+
+@[deprecated get?_eq_get]
+theorem some_nthLe_eq {l : List α} {n : ℕ} {h} : some (l.nthLe n h) = l.get? n :=
+  (get?_eq_get _).symm
+#align list.some_nth_le_eq List.some_nthLe_eq
+
+end deprecated
+
+theorem modifyNthTail_modifyNthTail {f g : List α → List α} (m : ℕ) :
+    ∀ (n) (l : List α),
+      (l.modifyNthTail f n).modifyNthTail g (m + n) =
+        l.modifyNthTail (fun l => (f l).modifyNthTail g m) n
+  | 0, _ => rfl
+  | _ + 1, [] => rfl
+  | n + 1, a :: l => congr_arg (List.cons a) (modifyNthTail_modifyNthTail m n l)
+#align list.modify_nth_tail_modify_nth_tail List.modifyNthTail_modifyNthTail
+
+theorem modifyNthTail_modifyNthTail_le {f g : List α → List α} (m n : ℕ) (l : List α)
+    (h : n ≤ m) :
+    (l.modifyNthTail f n).modifyNthTail g m =
+      l.modifyNthTail (fun l => (f l).modifyNthTail g (m - n)) n := by
+  rcases exists_add_of_le h with ⟨m, rfl⟩
+  rw [add_tsub_cancel_left, add_comm, modifyNthTail_modifyNthTail]
+#align list.modify_nth_tail_modify_nth_tail_le List.modifyNthTail_modifyNthTail_le
+
+theorem modifyNthTail_modifyNthTail_same {f g : List α → List α} (n : ℕ) (l : List α) :
+    (l.modifyNthTail f n).modifyNthTail g n = l.modifyNthTail (g ∘ f) n := by
+  rw [modifyNthTail_modifyNthTail_le n n l (le_refl n), tsub_self]; rfl
+#align list.modify_nth_tail_modify_nth_tail_same List.modifyNthTail_modifyNthTail_same
+
+#align list.modify_nth_tail_id List.modifyNthTail_id
+
+theorem removeNth_eq_nthTail : ∀ (n) (l : List α), removeNth l n = modifyNthTail tail n l
+  | 0, l => by cases l <;> rfl
+  | n + 1, [] => rfl
+  | n + 1, a :: l => congr_arg (cons _) (removeNth_eq_nthTail _ _)
+#align list.remove_nth_eq_nth_tail List.removeNth_eq_nthTail
+
+#align list.update_nth_eq_modify_nth List.set_eq_modifyNth
+
+theorem modifyNth_eq_set (f : α → α) :
+    ∀ (n) (l : List α), modifyNth f n l = ((fun a => set l n (f a)) <$> get? l n).getD l
+  | 0, l => by cases l <;> rfl
+  | n + 1, [] => rfl
+  | n + 1, b :: l =>
+    (congr_arg (cons b) (modifyNth_eq_set f n l)).trans <| by cases get? l n <;> rfl
+#align list.modify_nth_eq_update_nth List.modifyNth_eq_set
+
+#align list.nth_modify_nth List.get?_modifyNth
+
+theorem length_modifyNthTail (f : List α → List α) (H : ∀ l, length (f l) = length l) :
+    ∀ n l, length (modifyNthTail f n l) = length l
+  | 0, _ => H _
+  | _ + 1, [] => rfl
+  | _ + 1, _ :: _ => @congr_arg _ _ _ _ (· + 1) (length_modifyNthTail _ H _ _)
+#align list.modify_nth_tail_length List.length_modifyNthTail
+
+-- Porting note: Duplicate of `modify_get?_length`
+-- (but with a substantially better name?)
+-- @[simp]
+theorem length_modifyNth (f : α → α) : ∀ n l, length (modifyNth f n l) = length l :=
+  modify_get?_length f
+#align list.modify_nth_length List.length_modifyNth
+
+#align list.update_nth_length List.length_set
+
+#align list.nth_modify_nth_eq List.get?_modifyNth_eq
+#align list.nth_modify_nth_ne List.get?_modifyNth_ne
+#align list.nth_update_nth_eq List.get?_set_eq
+#align list.nth_update_nth_of_lt List.get?_set_eq_of_lt
+#align list.nth_update_nth_ne List.get?_set_ne
+#align list.update_nth_nil List.set_nil
+#align list.update_nth_succ List.set_succ
+#align list.update_nth_comm List.set_comm
+
+@[simp, deprecated get_set_eq]
+theorem nthLe_set_eq (l : List α) (i : ℕ) (a : α) (h : i < (l.set i a).length) :
+    (l.set i a).nthLe i h = a := get_set_eq ..
+#align list.nth_le_update_nth_eq List.nthLe_set_eq
+
+@[simp]
+theorem get_set_of_ne {l : List α} {i j : ℕ} (h : i ≠ j) (a : α)
+    (hj : j < (l.set i a).length) :
+    (l.set i a).get ⟨j, hj⟩ = l.get ⟨j, by simpa using hj⟩ := by
+  rw [← Option.some_inj, ← List.get?_eq_get, List.get?_set_ne _ _ h, List.get?_eq_get]
+
+@[simp, deprecated get_set_of_ne]
+theorem nthLe_set_of_ne {l : List α} {i j : ℕ} (h : i ≠ j) (a : α)
+    (hj : j < (l.set i a).length) :
+    (l.set i a).nthLe j hj = l.nthLe j (by simpa using hj) :=
+  get_set_of_ne h _ hj
+#align list.nth_le_update_nth_of_ne List.nthLe_set_of_ne
+
+#align list.mem_or_eq_of_mem_update_nth List.mem_or_eq_of_mem_set
+
+section InsertNth
+
+variable {a : α}
+
+@[simp]
+theorem insertNth_zero (s : List α) (x : α) : insertNth 0 x s = x :: s :=
+  rfl
+#align list.insert_nth_zero List.insertNth_zero
+
+@[simp]
+theorem insertNth_succ_nil (n : ℕ) (a : α) : insertNth (n + 1) a [] = [] :=
+  rfl
+#align list.insert_nth_succ_nil List.insertNth_succ_nil
+
+@[simp]
+theorem insertNth_succ_cons (s : List α) (hd x : α) (n : ℕ) :
+    insertNth (n + 1) x (hd :: s) = hd :: insertNth n x s :=
+  rfl
+#align list.insert_nth_succ_cons List.insertNth_succ_cons
+
+theorem length_insertNth : ∀ n as, n ≤ length as → length (insertNth n a as) = length as + 1
+  | 0, _, _ => rfl
+  | _ + 1, [], h => (Nat.not_succ_le_zero _ h).elim
+  | n + 1, _ :: as, h => congr_arg Nat.succ <| length_insertNth n as (Nat.le_of_succ_le_succ h)
+#align list.length_insert_nth List.length_insertNth
+
+theorem removeNth_insertNth (n : ℕ) (l : List α) : (l.insertNth n a).removeNth n = l := by
+  rw [removeNth_eq_nth_tail, insertNth, modifyNthTail_modifyNthTail_same]
+  exact modifyNthTail_id _ _
+#align list.remove_nth_insert_nth List.removeNth_insertNth
+
+theorem insertNth_removeNth_of_ge :
+    ∀ n m as,
+      n < length as → n ≤ m → insertNth m a (as.removeNth n) = (as.insertNth (m + 1) a).removeNth n
+  | 0, 0, [], has, _ => (lt_irrefl _ has).elim
+  | 0, 0, _ :: as, _, _ => by simp [removeNth, insertNth]
+  | 0, m + 1, a :: as, _, _ => rfl
+  | n + 1, m + 1, a :: as, has, hmn =>
+    congr_arg (cons a) <|
+      insertNth_removeNth_of_ge n m as (Nat.lt_of_succ_lt_succ has) (Nat.le_of_succ_le_succ hmn)
+#align list.insert_nth_remove_nth_of_ge List.insertNth_removeNth_of_ge
+
+theorem insertNth_removeNth_of_le :
+    ∀ n m as,
+      n < length as → m ≤ n → insertNth m a (as.removeNth n) = (as.insertNth m a).removeNth (n + 1)
+  | _, 0, _ :: _, _, _ => rfl
+  | n + 1, m + 1, a :: as, has, hmn =>
+    congr_arg (cons a) <|
+      insertNth_removeNth_of_le n m as (Nat.lt_of_succ_lt_succ has) (Nat.le_of_succ_le_succ hmn)
+#align list.insert_nth_remove_nth_of_le List.insertNth_removeNth_of_le
+
+theorem insertNth_comm (a b : α) :
+    ∀ (i j : ℕ) (l : List α) (_ : i ≤ j) (_ : j ≤ length l),
+      (l.insertNth i a).insertNth (j + 1) b = (l.insertNth j b).insertNth i a
+  | 0, j, l => by simp [insertNth]
+  | i + 1, 0, l => fun h => (Nat.not_lt_zero _ h).elim
+  | i + 1, j + 1, [] => by simp
+  | i + 1, j + 1, c :: l => fun h₀ h₁ => by
+    simp [insertNth]
+    exact insertNth_comm a b i j l (Nat.le_of_succ_le_succ h₀) (Nat.le_of_succ_le_succ h₁)
+#align list.insert_nth_comm List.insertNth_comm
+
+theorem mem_insertNth {a b : α} :
+    ∀ {n : ℕ} {l : List α} (_ : n ≤ l.length), a ∈ l.insertNth n b ↔ a = b ∨ a ∈ l
+  | 0, as, _ => by simp
+  | n + 1, [], h => (Nat.not_succ_le_zero _ h).elim
+  | n + 1, a' :: as, h => by
+    rw [List.insertNth_succ_cons, mem_cons, mem_insertNth (Nat.le_of_succ_le_succ h),
+      ← or_assoc, @or_comm (a = a'), or_assoc, mem_cons]
+#align list.mem_insert_nth List.mem_insertNth
+
+theorem insertNth_of_length_lt (l : List α) (x : α) (n : ℕ) (h : l.length < n) :
+    insertNth n x l = l := by
+  induction' l with hd tl IH generalizing n
+  · cases n
+    · simp at h
+    · simp
+  · cases n
+    · simp at h
+    · simp only [Nat.succ_lt_succ_iff, length] at h
+      simpa using IH _ h
+#align list.insert_nth_of_length_lt List.insertNth_of_length_lt
+
+@[simp]
+theorem insertNth_length_self (l : List α) (x : α) : insertNth l.length x l = l ++ [x] := by
+  induction' l with hd tl IH
+  · simp
+  · simpa using IH
+#align list.insert_nth_length_self List.insertNth_length_self
+
+theorem length_le_length_insertNth (l : List α) (x : α) (n : ℕ) :
+    l.length ≤ (insertNth n x l).length := by
+  cases' le_or_lt n l.length with hn hn
+  · rw [length_insertNth _ _ hn]
+    exact (Nat.lt_succ_self _).le
+  · rw [insertNth_of_length_lt _ _ _ hn]
+#align list.length_le_length_insert_nth List.length_le_length_insertNth
+
+theorem length_insertNth_le_succ (l : List α) (x : α) (n : ℕ) :
+    (insertNth n x l).length ≤ l.length + 1 := by
+  cases' le_or_lt n l.length with hn hn
+  · rw [length_insertNth _ _ hn]
+  · rw [insertNth_of_length_lt _ _ _ hn]
+    exact (Nat.lt_succ_self _).le
+#align list.length_insert_nth_le_succ List.length_insertNth_le_succ
+
+theorem get_insertNth_of_lt (l : List α) (x : α) (n k : ℕ) (hn : k < n) (hk : k < l.length)
+    (hk' : k < (insertNth n x l).length := hk.trans_le (length_le_length_insertNth _ _ _)) :
+    (insertNth n x l).get ⟨k, hk'⟩ = l.get ⟨k, hk⟩ := by
+  induction' n with n IH generalizing k l
+  · simp at hn
+  · cases' l with hd tl
+    · simp
+    · cases k
+      · simp [get]
+      · rw [Nat.succ_lt_succ_iff] at hn
+        simpa using IH _ _ hn _
+
+@[deprecated get_insertNth_of_lt]
+theorem nthLe_insertNth_of_lt : ∀ (l : List α) (x : α) (n k : ℕ), k < n → ∀ (hk : k < l.length)
+    (hk' : k < (insertNth n x l).length := hk.trans_le (length_le_length_insertNth _ _ _)),
+    (insertNth n x l).nthLe k hk' = l.nthLe k hk := @get_insertNth_of_lt _
+#align list.nth_le_insert_nth_of_lt List.nthLe_insertNth_of_lt
+
+@[simp, nolint simpNF] -- Porting note: bug in linter, see std4#78
+theorem get_insertNth_self (l : List α) (x : α) (n : ℕ) (hn : n ≤ l.length)
+    (hn' : n < (insertNth n x l).length := (by rwa [length_insertNth _ _ hn, Nat.lt_succ_iff])) :
+    (insertNth n x l).get ⟨n, hn'⟩ = x := by
+  induction' l with hd tl IH generalizing n
+  · simp only [length, nonpos_iff_eq_zero] at hn
+    cases hn
+    simp only [insertNth_zero, get_singleton]
+  · cases n
+    · simp
+    · simp only [Nat.succ_le_succ_iff, length] at hn
+      simpa using IH _ hn
+
+@[simp, deprecated get_insertNth_self, nolint simpNF] -- Porting note: bug in linter, see std4#78
+theorem nthLe_insertNth_self (l : List α) (x : α) (n : ℕ) (hn : n ≤ l.length)
+    (hn' : n < (insertNth n x l).length := (by rwa [length_insertNth _ _ hn, Nat.lt_succ_iff])) :
+    (insertNth n x l).nthLe n hn' = x := get_insertNth_self _ _ _ hn
+#align list.nth_le_insert_nth_self List.nthLe_insertNth_self
+
+theorem get_insertNth_add_succ (l : List α) (x : α) (n k : ℕ) (hk' : n + k < l.length)
+    (hk : n + k + 1 < (insertNth n x l).length := (by
+      -- Porting note: the original proof fails
+      -- rwa [length_insertNth _ _ (le_self_add.trans hk'.le), Nat.succ_lt_succ_iff]
+      rw [length_insertNth _ _ (le_self_add.trans hk'.le)]; exact Nat.succ_lt_succ_iff.2 hk')) :
+    (insertNth n x l).get ⟨n + k + 1, hk⟩ = get l ⟨n + k, hk'⟩ := by
+  induction' l with hd tl IH generalizing n k
+  · simp at hk'
+  · cases n
+    · simp
+    · simpa [succ_add] using IH _ _ _
+
+set_option linter.deprecated false in
+@[deprecated get_insertNth_add_succ]
+theorem nthLe_insertNth_add_succ : ∀ (l : List α) (x : α) (n k : ℕ) (hk' : n + k < l.length)
+    (hk : n + k + 1 < (insertNth n x l).length := (by
+      -- Porting note: the original proof fails
+      -- rwa [length_insertNth _ _ (le_self_add.trans hk'.le), Nat.succ_lt_succ_iff]
+      rw [length_insertNth _ _ (le_self_add.trans hk'.le)]; exact Nat.succ_lt_succ_iff.2 hk')),
+    (insertNth n x l).nthLe (n + k + 1) hk = nthLe l (n + k) hk' :=
+  @get_insertNth_add_succ _
+#align list.nth_le_insert_nth_add_succ List.nthLe_insertNth_add_succ
+
+set_option linter.unnecessarySimpa false in
+theorem insertNth_injective (n : ℕ) (x : α) : Function.Injective (insertNth n x) := by
+  induction' n with n IH
+  · have : insertNth 0 x = cons x := funext fun _ => rfl
+    simp [this]
+  · rintro (_ | ⟨a, as⟩) (_ | ⟨b, bs⟩) h <;> simpa [IH.eq_iff] using h
+#align list.insert_nth_injective List.insertNth_injective
+
+end InsertNth
+
+/-! ### map -/
+
+#align list.map_nil List.map_nil
+
+theorem map_eq_foldr (f : α → β) (l : List α) : map f l = foldr (fun a bs => f a :: bs) [] l := by
+  induction l <;> simp [*]
+#align list.map_eq_foldr List.map_eq_foldr
+
+theorem map_congr {f g : α → β} : ∀ {l : List α}, (∀ x ∈ l, f x = g x) → map f l = map g l
+  | [], _ => rfl
+  | a :: l, h => by
+    let ⟨h₁, h₂⟩ := forall_mem_cons.1 h
+    rw [map, map, h₁, map_congr h₂]
+#align list.map_congr List.map_congr
+
+theorem map_eq_map_iff {f g : α → β} {l : List α} : map f l = map g l ↔ ∀ x ∈ l, f x = g x := by
+  refine' ⟨_, map_congr⟩; intro h x hx
+  rw [mem_iff_get] at hx; rcases hx with ⟨n, hn, rfl⟩
+  rw [get_map_rev f, get_map_rev g]
+  -- Porting note: with `nthLe` instead of `get` the remainder of the proof is simply `congr`
+  generalize_proofs h₁ h₂
+  generalize map f l = x, map g l = y at *
+  cases h
+  congr
+#align list.map_eq_map_iff List.map_eq_map_iff
+
+theorem map_concat (f : α → β) (a : α) (l : List α) :
+    map f (concat l a) = concat (map f l) (f a) := by
+  induction l <;> [rfl, simp only [*, concat_eq_append, cons_append, map, map_append]]
+#align list.map_concat List.map_concat
+
+@[simp]
+theorem map_id'' (l : List α) : map (fun x => x) l = l :=
+  map_id _
+#align list.map_id'' List.map_id''
+
+theorem map_id' {f : α → α} (h : ∀ x, f x = x) (l : List α) : map f l = l := by
+  simp [show f = id from funext h]
+#align list.map_id' List.map_id'
+
+theorem eq_nil_of_map_eq_nil {f : α → β} {l : List α} (h : map f l = nil) : l = nil :=
+  eq_nil_of_length_eq_zero <| by rw [← length_map l f, h]; rfl
+#align list.eq_nil_of_map_eq_nil List.eq_nil_of_map_eq_nil
+
+@[simp]
+theorem map_join (f : α → β) (L : List (List α)) : map f (join L) = join (map (map f) L) := by
+  induction L <;> [rfl, simp only [*, join, map, map_append]]
+#align list.map_join List.map_join
+
+theorem bind_ret_eq_map (f : α → β) (l : List α) : l.bind (List.ret ∘ f) = map f l := by
+  unfold List.bind
+  induction l <;> simp [map, join, List.ret, cons_append, nil_append, *] at *
+  assumption
+#align list.bind_ret_eq_map List.bind_ret_eq_map
+
+theorem bind_congr {l : List α} {f g : α → List β} (h : ∀ x ∈ l, f x = g x) :
+    List.bind l f = List.bind l g :=
+  (congr_arg List.join <| map_congr h : _)
+#align list.bind_congr List.bind_congr
+
+@[simp]
+theorem map_eq_map {α β} (f : α → β) (l : List α) : f <$> l = map f l :=
+  rfl
+#align list.map_eq_map List.map_eq_map
+
+@[simp]
+theorem map_tail (f : α → β) (l) : map f (tail l) = tail (map f l) := by cases l <;> rfl
+#align list.map_tail List.map_tail
+
+@[simp]
+theorem map_injective_iff {f : α → β} : Injective (map f) ↔ Injective f := by
+  constructor <;> intro h x y hxy
+  · suffices [x] = [y] by simpa using this
+    apply h
+    simp [hxy]
+  · induction' y with yh yt y_ih generalizing x
+    simpa using hxy
+    cases x
+    simp at hxy
+    simp at hxy
+    simp [y_ih hxy.2, h hxy.1]
+#align list.map_injective_iff List.map_injective_iff
+
+/-- A single `list.map` of a composition of functions is equal to
+composing a `list.map` with another `list.map`, fully applied.
+This is the reverse direction of `list.map_map`.
+-/
+theorem comp_map (h : β → γ) (g : α → β) (l : List α) : map (h ∘ g) l = map h (map g l) :=
+  (map_map _ _ _).symm
+#align list.comp_map List.comp_map
+
+/-- Composing a `list.map` with another `list.map` is equal to
+a single `list.map` of composed functions.
+-/
+@[simp]
+theorem map_comp_map (g : β → γ) (f : α → β) : map g ∘ map f = map (g ∘ f) := by
+  ext l; rw [comp_map]; rfl
+#align list.map_comp_map List.map_comp_map
+
+theorem map_filter_eq_foldr (f : α → β) (p : α → Bool) (as : List α) :
+    map f (filter p as) = foldr (fun a bs => bif p a then f a :: bs else bs) [] as := by
+  induction' as with head tail
+  · rfl
+  · simp only [foldr]
+    cases hp : p head <;> simp [filter, *]
+#align list.map_filter_eq_foldr List.map_filter_eq_foldr
+
+theorem getLast_map (f : α → β) {l : List α} (hl : l ≠ []) :
+    (l.map f).getLast (mt eq_nil_of_map_eq_nil hl) = f (l.getLast hl) := by
+  induction' l with l_hd l_tl l_ih
+  · apply (hl rfl).elim
+  · cases l_tl
+    · simp
+    · simpa using l_ih
+-- Porting note: After https://github.com/leanprover/std4/pull/75,
+-- last line above should be changed to end `l_ih _`.
+#align list.last_map List.getLast_map
+
+theorem map_eq_replicate_iff {l : List α} {f : α → β} {b : β} :
+    l.map f = List.replicate l.length b ↔ ∀ x ∈ l, f x = b := by
+  induction' l with x l' ih
+  · simp only [List.replicate, length, not_mem_nil, IsEmpty.forall_iff, imp_true_iff, map_nil,
+      eq_self_iff_true]
+  · simp only [map, List.replicate, add_eq, add_zero, cons.injEq, mem_cons,
+      forall_eq_or_imp, and_congr_right_iff]
+    exact fun _ => ih
+
+set_option linter.deprecated false in
+@[deprecated map_eq_replicate_iff]
+theorem map_eq_repeat_iff {l : List α} {f : α → β} {b : β} :
+    l.map f = List.repeat b l.length ↔ ∀ x ∈ l, f x = b :=
+  map_eq_replicate_iff
+#align list.map_eq_repeat_iff List.map_eq_repeat_iff
+
+@[simp]
+theorem map_const (l : List α) (b : β) : map (Function.const α b) l = List.replicate l.length b :=
+  map_eq_replicate_iff.mpr fun _ _ => rfl
+
+set_option linter.deprecated false in
+@[deprecated map_const]
+theorem map_const' (l : List α) (b : β) : map (Function.const α b) l = List.repeat b l.length :=
+  map_eq_replicate_iff.mpr fun _ _ => rfl
+#align list.map_const List.map_const'
+
+theorem eq_of_mem_map_const {b₁ b₂ : β} {l : List α} (h : b₁ ∈ map (Function.const α b₂) l) :
+    b₁ = b₂ := by rw [map_const] at h; exact eq_of_mem_replicate h
+#align list.eq_of_mem_map_const List.eq_of_mem_map_const
+
+/-! ### zipWith -/
+
+theorem nil_zipWith (f : α → β → γ) (l : List β) : zipWith f [] l = [] := by cases l <;> rfl
+#align list.nil_map₂ List.nil_zipWith
+
+theorem zipWith_nil (f : α → β → γ) (l : List α) : zipWith f l [] = [] := by cases l <;> rfl
+#align list.map₂_nil List.zipWith_nil
+
+@[simp]
+theorem zipWith_flip (f : α → β → γ) : ∀ as bs, zipWith (flip f) bs as = zipWith f as bs
+  | [], [] => rfl
+  | [], b :: bs => rfl
+  | a :: as, [] => rfl
+  | a :: as, b :: bs => by
+    simp! [zipWith_flip]
+    rfl
+#align list.map₂_flip List.zipWith_flip
+
+/-! ### take, drop -/
+
+@[simp]
+theorem take_zero (l : List α) : take 0 l = [] :=
+  rfl
+#align list.take_zero List.take_zero
+
+@[simp]
+theorem take_nil : ∀ n, take n [] = ([] : List α)
+  | 0 | _ + 1 => rfl
+#align list.take_nil List.take_nil
+
+theorem take_cons (n) (a : α) (l : List α) : take (succ n) (a :: l) = a :: take n l :=
+  rfl
+#align list.take_cons List.take_cons
+
+#align list.take_length List.take_length
+
+theorem take_all_of_le : ∀ {n} {l : List α}, length l ≤ n → take n l = l
+  | 0, [], _ => rfl
+  | 0, a :: l, h => absurd h (not_le_of_gt (zero_lt_succ _))
+  | n + 1, [], _ => rfl
+  | n + 1, a :: l, h => by
+    change a :: take n l = a :: l
+    rw [take_all_of_le (le_of_succ_le_succ h)]
+#align list.take_all_of_le List.take_all_of_le
+
+@[simp]
+theorem take_left : ∀ l₁ l₂ : List α, take (length l₁) (l₁ ++ l₂) = l₁
+  | [], _ => rfl
+  | a :: l₁, l₂ => congr_arg (cons a) (take_left l₁ l₂)
+#align list.take_left List.take_left
+
+theorem take_left' {l₁ l₂ : List α} {n} (h : length l₁ = n) : take n (l₁ ++ l₂) = l₁ := by
+  rw [← h]; apply take_left
+#align list.take_left' List.take_left'
+
+theorem take_take : ∀ (n m) (l : List α), take n (take m l) = take (min n m) l
+  | n, 0, l => by rw [min_zero, take_zero, take_nil]
+  | 0, m, l => by rw [zero_min, take_zero, take_zero]
+  | succ n, succ m, nil => by simp only [take_nil]
+  | succ n, succ m, a :: l => by
+    simp only [take, min_succ_succ, take_take n m l]
+#align list.take_take List.take_take
+
+theorem take_replicate (a : α) : ∀ n m : ℕ, take n (List.replicate m a) = List.replicate (min n m) a
+  | n, 0 => by simp
+  | 0, m => by simp
+  | succ n, succ m => by simp [min_succ_succ, take_replicate]
+
+set_option linter.deprecated false in
+@[deprecated take_replicate]
+theorem take_repeat (a : α) (n m : ℕ) : take n (List.repeat a m) = List.repeat a (min n m) :=
+  take_replicate ..
+#align list.take_repeat List.take_repeat
+
+theorem map_take {α β : Type _} (f : α → β) :
+    ∀ (L : List α) (i : ℕ), (L.take i).map f = (L.map f).take i
+  | [], i => by simp
+  | _, 0 => by simp
+  | h :: t, n + 1 => by dsimp; rw [map_take f t n]
+#align list.map_take List.map_take
+
+/-- Taking the first `n` elements in `l₁ ++ l₂` is the same as appending the first `n` elements
+of `l₁` to the first `n - l₁.length` elements of `l₂`. -/
+theorem take_append_eq_append_take {l₁ l₂ : List α} {n : ℕ} :
+    take n (l₁ ++ l₂) = take n l₁ ++ take (n - l₁.length) l₂ := by
+  induction l₁ generalizing n; {simp}
+  cases n <;> simp [*]
+#align list.take_append_eq_append_take List.take_append_eq_append_take
+
+theorem take_append_of_le_length {l₁ l₂ : List α} {n : ℕ} (h : n ≤ l₁.length) :
+    (l₁ ++ l₂).take n = l₁.take n := by simp [take_append_eq_append_take, tsub_eq_zero_iff_le.mpr h]
+#align list.take_append_of_le_length List.take_append_of_le_length
+
+/-- Taking the first `l₁.length + i` elements in `l₁ ++ l₂` is the same as appending the first
+`i` elements of `l₂` to `l₁`. -/
+theorem take_append {l₁ l₂ : List α} (i : ℕ) : take (l₁.length + i) (l₁ ++ l₂) = l₁ ++ take i l₂ :=
+  by simp [take_append_eq_append_take, take_all_of_le le_self_add]
+#align list.take_append List.take_append
+
+/-- The `i`-th element of a list coincides with the `i`-th element of any of its prefixes of
+length `> i`. Version designed to rewrite from the big list to the small list. -/
+theorem get_take (L : List α) {i j : ℕ} (hi : i < L.length) (hj : i < j) :
+    get L ⟨i, hi⟩ = get (L.take j) ⟨i, length_take .. ▸ lt_min hj hi⟩ :=
+  get_of_eq (take_append_drop j L).symm _ ▸ get_append ..
+
+set_option linter.deprecated false in
+/-- The `i`-th element of a list coincides with the `i`-th element of any of its prefixes of
+length `> i`. Version designed to rewrite from the big list to the small list. -/
+@[deprecated get_take]
+theorem nthLe_take (L : List α) {i j : ℕ} (hi : i < L.length) (hj : i < j) :
+    nthLe L i hi = nthLe (L.take j) i (length_take .. ▸ lt_min hj hi) :=
+  get_take _ hi hj
+#align list.nth_le_take List.nthLe_take
+
+/-- The `i`-th element of a list coincides with the `i`-th element of any of its prefixes of
+length `> i`. Version designed to rewrite from the small list to the big list. -/
+theorem get_take' (L : List α) {j i} :
+    get (L.take j) i = get L ⟨i.1, lt_of_lt_of_le i.2 (by simp [le_refl])⟩ := by
+  let ⟨i, hi⟩ := i; simp at hi; rw [get_take L _ hi.1]
+
+set_option linter.deprecated false in
+/-- The `i`-th element of a list coincides with the `i`-th element of any of its prefixes of
+length `> i`. Version designed to rewrite from the small list to the big list. -/
+@[deprecated get_take']
+theorem nthLe_take' (L : List α) {i j : ℕ} (hi : i < (L.take j).length) :
+    nthLe (L.take j) i hi = nthLe L i (lt_of_lt_of_le hi (by simp [le_refl])) := get_take' _
+#align list.nth_le_take' List.nthLe_take'
+
+theorem get?_take {l : List α} {n m : ℕ} (h : m < n) : (l.take n).get? m = l.get? m := by
+  induction' n with n hn generalizing l m
+  · simp only [Nat.zero_eq] at h
+    exact absurd h (not_lt_of_le m.zero_le)
+  · cases' l with hd tl
+    · simp only [take_nil]
+    · cases m
+      · simp only [get?, take]
+      · simpa only using hn (Nat.lt_of_succ_lt_succ h)
+#align list.nth_take List.get?_take
+
+@[simp]
+theorem nth_take_of_succ {l : List α} {n : ℕ} : (l.take (n + 1)).get? n = l.get? n :=
+  get?_take (Nat.lt_succ_self n)
+#align list.nth_take_of_succ List.nth_take_of_succ
+
+theorem take_succ {l : List α} {n : ℕ} : l.take (n + 1) = l.take n ++ (l.get? n).toList := by
+  induction' l with hd tl hl generalizing n
+  · simp only [Option.toList, get?, take_nil, append_nil]
+  · cases n
+    · simp only [Option.toList, get?, eq_self_iff_true, and_self_iff, take, nil_append]
+    · simp only [hl, cons_append, get?, eq_self_iff_true, and_self_iff, take]
+#align list.take_succ List.take_succ
+
+@[simp]
+theorem take_eq_nil_iff {l : List α} {k : ℕ} : l.take k = [] ↔ l = [] ∨ k = 0 := by
+  cases l <;> cases k <;> simp [Nat.succ_ne_zero]
+#align list.take_eq_nil_iff List.take_eq_nil_iff
+
+theorem take_eq_take :
+    ∀ {l : List α} {m n : ℕ}, l.take m = l.take n ↔ min m l.length = min n l.length
+  | [], m, n => by simp
+  | _ :: xs, 0, 0 => by simp
+  | x :: xs, m + 1, 0 => by simp
+  | x :: xs, 0, n + 1 => by simp [@eq_comm ℕ 0]
+  | x :: xs, m + 1, n + 1 => by simp [Nat.min_succ_succ, take_eq_take]
+#align list.take_eq_take List.take_eq_take
+
+theorem take_add (l : List α) (m n : ℕ) : l.take (m + n) = l.take m ++ (l.drop m).take n := by
+  convert_to take (m + n) (take m l ++ drop m l) = take m l ++ take n (drop m l)
+  · rw [take_append_drop]
+  rw [take_append_eq_append_take, take_all_of_le, append_right_inj]
+  · simp only [take_eq_take, length_take, length_drop]
+    generalize l.length = k; by_cases h : m ≤ k
+    · simp [min_eq_left_iff.mpr h]
+    · push_neg  at h
+      simp [Nat.sub_eq_zero_of_le (le_of_lt h)]
+  · trans m
+    · apply length_take_le
+    · simp
+#align list.take_add List.take_add
+
+theorem dropLast_eq_take (l : List α) : l.dropLast = l.take l.length.pred := by
+  cases' l with x l
+  · simp [dropLast]
+  · induction' l with hd tl hl generalizing x
+    · simp [dropLast]
+    · simp [dropLast, hl]
+#align list.init_eq_take List.dropLast_eq_take
+
+theorem dropLast_take {n : ℕ} {l : List α} (h : n < l.length) :
+    (l.take n).dropLast = l.take n.pred := by
+  simp [dropLast_eq_take, min_eq_left_of_lt h, take_take, pred_le]
+#align list.init_take List.dropLast_take
+
+theorem dropLast_cons_of_ne_nil {α : Type _} {x : α}
+    {l : List α} (h : l ≠ []) : (x :: l).dropLast = x :: l.dropLast := by simp [h]
+#align list.init_cons_of_ne_nil List.dropLast_cons_of_ne_nil
+
+@[simp]
+theorem dropLast_append_of_ne_nil {α : Type _} {l : List α} :
+    ∀ (l' : List α) (_ : l ≠ []), (l' ++ l).dropLast = l' ++ l.dropLast
+  | [], _ => by simp only [nil_append]
+  | a :: l', h => by
+    rw [cons_append, dropLast, dropLast_append_of_ne_nil l' h, cons_append]
+    simp [h]
+#align list.init_append_of_ne_nil List.dropLast_append_of_ne_nil
+
+#align list.drop_eq_nil_of_le List.drop_eq_nil_of_le
+
+theorem drop_eq_nil_iff_le {l : List α} {k : ℕ} : l.drop k = [] ↔ l.length ≤ k := by
+  refine' ⟨fun h => _, drop_eq_nil_of_le⟩
+  induction' k with k hk generalizing l
+  · simp only [drop] at h
+    simp [h]
+  · cases l
+    · simp
+    · simp only [drop] at h
+      simpa [Nat.succ_le_succ_iff] using hk h
+#align list.drop_eq_nil_iff_le List.drop_eq_nil_iff_le
+
+theorem tail_drop (l : List α) (n : ℕ) : (l.drop n).tail = l.drop (n + 1) := by
+  induction' l with hd tl hl generalizing n
+  · simp
+  · cases n
+    · simp
+    · simp [hl]
+#align list.tail_drop List.tail_drop
+
+theorem cons_get_drop_succ {l : List α} {n} :
+    l.get n :: l.drop (n.1 + 1) = l.drop n.1 := by
+  induction' l with hd tl hl
+  · exact absurd n.1.zero_le (not_le_of_lt (nomatch n))
+  · match n with
+    | ⟨0, _⟩ => simp [get]
+    | ⟨n+1, hn⟩ =>
+      simp only [Nat.succ_lt_succ_iff, List.length] at hn
+      simpa [List.get, List.drop] using hl
+
+@[deprecated cons_get_drop_succ]
+theorem cons_nthLe_drop_succ {l : List α} {n : ℕ} (hn : n < l.length) :
+    l.nthLe n hn :: l.drop (n + 1) = l.drop n := cons_get_drop_succ
+#align list.cons_nth_le_drop_succ List.cons_nthLe_drop_succ
+
+#align list.drop_nil List.drop_nil
+
+@[simp]
+theorem drop_one : ∀ l : List α, drop 1 l = tail l
+  | [] | _ :: _ => rfl
+#align list.drop_one List.drop_one
+
+theorem drop_add : ∀ (m n) (l : List α), drop (m + n) l = drop m (drop n l)
+  | _, 0, _ => rfl
+  | _, _ + 1, [] => drop_nil.symm
+  | m, n + 1, _ :: _ => drop_add m n _
+#align list.drop_add List.drop_add
+
+@[simp]
+theorem drop_left : ∀ l₁ l₂ : List α, drop (length l₁) (l₁ ++ l₂) = l₂
+  | [], _ => rfl
+  | _ :: l₁, l₂ => drop_left l₁ l₂
+#align list.drop_left List.drop_left
+
+theorem drop_left' {l₁ l₂ : List α} {n} (h : length l₁ = n) : drop n (l₁ ++ l₂) = l₂ := by
+  rw [← h]; apply drop_left
+#align list.drop_left' List.drop_left'
+
+theorem drop_eq_get_cons : ∀ {n} {l : List α} (h), drop n l = get l ⟨n, h⟩ :: drop (n + 1) l
+  | 0, _ :: _, _ => rfl
+  | n + 1, _ :: _, _ => @drop_eq_get_cons n _ _
+#align list.drop_eq_nth_le_cons List.drop_eq_get_consₓ -- nth_le vs get
+
+#align list.drop_length List.drop_length
+
+theorem drop_length_cons {l : List α} (h : l ≠ []) (a : α) :
+    (a :: l).drop l.length = [l.getLast h] := by
+  induction' l with y l ih generalizing a
+  · cases h rfl
+  · simp only [drop, length]
+    by_cases h₁ : l = []
+    · simp [h₁]
+    rw [getLast_cons h₁]
+    exact ih h₁ y
+#align list.drop_length_cons List.drop_length_cons
+
+/-- 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. -/
+theorem drop_append_eq_append_drop {l₁ l₂ : List α} {n : ℕ} :
+    drop n (l₁ ++ l₂) = drop n l₁ ++ drop (n - l₁.length) l₂ := by
+  induction l₁ generalizing n; · simp
+  cases n <;> simp [*]
+#align list.drop_append_eq_append_drop List.drop_append_eq_append_drop
+
+theorem drop_append_of_le_length {l₁ l₂ : List α} {n : ℕ} (h : n ≤ l₁.length) :
+    (l₁ ++ l₂).drop n = l₁.drop n ++ l₂ := by
+  simp [drop_append_eq_append_drop, tsub_eq_zero_iff_le.mpr h]
+#align list.drop_append_of_le_length List.drop_append_of_le_length
+
+/-- Dropping the elements up to `l₁.length + i` in `l₁ + l₂` is the same as dropping the elements
+up to `i` in `l₂`. -/
+theorem drop_append {l₁ l₂ : List α} (i : ℕ) : drop (l₁.length + i) (l₁ ++ l₂) = drop i l₂ := by
+  rw [drop_append_eq_append_drop, drop_eq_nil_of_le] <;> simp
+#align list.drop_append List.drop_append
+
+theorem drop_sizeOf_le [SizeOf α] (l : List α) : ∀ n : ℕ, sizeOf (l.drop n) ≤ sizeOf l := by
+  induction' l with _ _ lih <;> intro n
+  · rw [drop_nil]
+  · induction' n with n
+    · rfl
+    · exact Trans.trans (lih _) le_add_self
+#align list.drop_sizeof_le List.drop_sizeOf_le
+
+set_option linter.deprecated false in -- FIXME
+/-- The `i + j`-th element of a list coincides with the `j`-th element of the list obtained by
+dropping the first `i` elements. Version designed to rewrite from the big list to the small list. -/
+theorem get_drop (L : List α) {i j : ℕ} (h : i + j < L.length) :
+    get L ⟨i + j, h⟩ = get (L.drop i) ⟨j, by
+      have A : i < L.length := lt_of_le_of_lt (Nat.le.intro rfl) h
+      rw [(take_append_drop i L).symm] at h
+      simpa only [le_of_lt A, min_eq_left, add_lt_add_iff_left, length_take,
+        length_append] using h⟩ := by
+  rw [← nthLe_eq, ← nthLe_eq]
+  rw [nthLe_of_eq (take_append_drop i L).symm h, nthLe_append_right] <;>
+  simp [min_eq_left (show i ≤ length L from le_trans (by simp) (le_of_lt h))]
+
+set_option linter.deprecated false in
+/-- The `i + j`-th element of a list coincides with the `j`-th element of the list obtained by
+dropping the first `i` elements. Version designed to rewrite from the big list to the small list. -/
+@[deprecated get_drop]
+theorem nthLe_drop (L : List α) {i j : ℕ} (h : i + j < L.length) :
+    nthLe L (i + j) h = nthLe (L.drop i) j (by
+      have A : i < L.length := lt_of_le_of_lt (Nat.le.intro rfl) h
+      rw [(take_append_drop i L).symm] at h
+      simpa only [le_of_lt A, min_eq_left, add_lt_add_iff_left, length_take,
+        length_append] using h) := get_drop ..
+#align list.nth_le_drop List.nthLe_drop
+
+/-- The `i + j`-th element of a list coincides with the `j`-th element of the list obtained by
+dropping the first `i` elements. Version designed to rewrite from the small list to the big list. -/
+theorem get_drop' (L : List α) {i j} :
+    get (L.drop i) j = get L ⟨i + j, lt_tsub_iff_left.mp (length_drop i L ▸ j.2)⟩ := by
+  rw [get_drop]
+
+set_option linter.deprecated false in
+/-- The `i + j`-th element of a list coincides with the `j`-th element of the list obtained by
+dropping the first `i` elements. Version designed to rewrite from the small list to the big list. -/
+@[deprecated get_drop']
+theorem nthLe_drop' (L : List α) {i j : ℕ} (h : j < (L.drop i).length) :
+    nthLe (L.drop i) j h = nthLe L (i + j) (lt_tsub_iff_left.mp (length_drop i L ▸ h)) :=
+  get_drop' ..
+#align list.nth_le_drop' List.nthLe_drop'
+
+theorem get?_drop (L : List α) (i j : ℕ) : get? (L.drop i) j = get? L (i + j) := by
+  ext
+  simp only [get?_eq_some, get_drop', Option.mem_def]
+  constructor <;> exact fun ⟨h, ha⟩ => ⟨by simpa [lt_tsub_iff_left] using h, ha⟩
+#align list.nth_drop List.get?_drop
+
+@[simp]
+theorem drop_drop (n : ℕ) : ∀ (m) (l : List α), drop n (drop m l) = drop (n + m) l
+  | m, [] => by simp
+  | 0, l => by simp
+  | m + 1, a :: l =>
+    calc
+      drop n (drop (m + 1) (a :: l)) = drop n (drop m l) := rfl
+      _ = drop (n + m) l := drop_drop n m l
+      _ = drop (n + (m + 1)) (a :: l) := rfl
+#align list.drop_drop List.drop_drop
+
+theorem drop_take : ∀ (m : ℕ) (n : ℕ) (l : List α), drop m (take (m + n) l) = take n (drop m l)
+  | 0, n, _ => by simp
+  | m + 1, n, nil => by simp
+  | m + 1, n, _ :: l => by
+    have h : m + 1 + n = m + n + 1 := by ac_rfl
+    simpa [take_cons, h] using drop_take m n l
+#align list.drop_take List.drop_take
+
+theorem map_drop {α β : Type _} (f : α → β) :
+    ∀ (L : List α) (i : ℕ), (L.drop i).map f = (L.map f).drop i
+  | [], i => by simp
+  | L, 0 => by simp
+  | h :: t, n + 1 => by
+    dsimp
+    rw [map_drop f t]
+#align list.map_drop List.map_drop
+
+theorem modifyNthTail_eq_take_drop (f : List α → List α) (H : f [] = []) :
+    ∀ n l, modifyNthTail f n l = take n l ++ f (drop n l)
+  | 0, _ => rfl
+  | _ + 1, [] => H.symm
+  | n + 1, b :: l => congr_arg (cons b) (modifyNthTail_eq_take_drop f H n l)
+#align list.modify_nth_tail_eq_take_drop List.modifyNthTail_eq_take_drop
+
+theorem modifyNth_eq_take_drop (f : α → α) :
+    ∀ n l, modifyNth f n l = take n l ++ modifyHead f (drop n l) :=
+  modifyNthTail_eq_take_drop _ rfl
+#align list.modify_nth_eq_take_drop List.modifyNth_eq_take_drop
+
+theorem modifyNth_eq_take_cons_drop (f : α → α) {n l} (h) :
+    modifyNth f n l = take n l ++ f (get l ⟨n, h⟩) :: drop (n + 1) l := by
+  rw [modifyNth_eq_take_drop, drop_eq_get_cons h]; rfl
+#align list.modify_nth_eq_take_cons_drop List.modifyNth_eq_take_cons_drop
+
+theorem set_eq_take_cons_drop (a : α) {n l} (h : n < length l) :
+    set l n a = take n l ++ a :: drop (n + 1) l := by
+  rw [set_eq_modifyNth, modifyNth_eq_take_cons_drop _ h]
+#align list.update_nth_eq_take_cons_drop List.set_eq_take_cons_drop
+
+theorem reverse_take {α} {xs : List α} (n : ℕ) (h : n ≤ xs.length) :
+    xs.reverse.take n = (xs.drop (xs.length - n)).reverse := by
+  induction' xs with xs_hd xs_tl xs_ih generalizing n <;>
+    simp only [reverse_cons, drop, reverse_nil, zero_tsub, length, take_nil]
+  cases' h.lt_or_eq_dec with h' h'
+  · replace h' := le_of_succ_le_succ h'
+    rw [take_append_of_le_length, xs_ih _ h']
+    rw [show xs_tl.length + 1 - n = succ (xs_tl.length - n) from _, drop]
+    · rwa [succ_eq_add_one, ← tsub_add_eq_add_tsub]
+    · rwa [length_reverse]
+  · subst h'
+    rw [length, tsub_self, drop]
+    suffices xs_tl.length + 1 = (xs_tl.reverse ++ [xs_hd]).length by
+      rw [this, take_length, reverse_cons]
+    rw [length_append, length_reverse]
+    rfl
+#align list.reverse_take List.reverse_take
+
+@[simp]
+theorem set_eq_nil (l : List α) (n : ℕ) (a : α) : l.set n a = [] ↔ l = [] := by
+  cases l <;> cases n <;> simp only [set]
+#align list.update_nth_eq_nil List.set_eq_nil
+
+section TakeI
+
+variable [Inhabited α]
+
+@[simp]
+theorem takeI_length : ∀ n l, length (@takeI α _ n l) = n
+  | 0, _ => rfl
+  | _ + 1, _ => congr_arg succ (takeI_length _ _)
+#align list.take'_length List.takeI_length
+
+@[simp]
+theorem takeI_nil : ∀ n, takeI n (@nil α) = replicate n default
+  | 0 => rfl
+  | _ + 1 => congr_arg (cons _) (takeI_nil _)
+#align list.take'_nil List.takeI_nil
+
+theorem takeI_eq_take : ∀ {n} {l : List α}, n ≤ length l → takeI n l = take n l
+  | 0, _, _ => rfl
+  | _ + 1, _ :: _, h => congr_arg (cons _) <| takeI_eq_take <| le_of_succ_le_succ h
+#align list.take'_eq_take List.takeI_eq_take
+
+@[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 _ _)
+#align list.take'_left List.takeI_left
+
+theorem takeI_left' {l₁ l₂ : List α} {n} (h : length l₁ = n) : takeI n (l₁ ++ l₂) = l₁ := by
+  rw [← h]; apply takeI_left
+#align list.take'_left' List.takeI_left'
+
+end TakeI
+
+/- Porting note: in mathlib3 we just had `take` and `take'`. Now we have `take`, `takeI`, and
+  `takeD`. The following section replicates the theorems above but for `takeD`. -/
+section TakeD
+
+@[simp]
+theorem takeD_length : ∀ n l a, length (@takeD α n l a) = n
+  | 0, _, _ => rfl
+  | _ + 1, _, _ => congr_arg succ (takeD_length _ _ _)
+
+-- Porting note: `takeD_nil` is already in std
+
+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
+
+@[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 _ _)
+
+theorem takeD_left' {l₁ l₂ : List α} {n} {a} (h : length l₁ = n) : takeD n (l₁ ++ l₂) a = l₁ :=
+  by rw [← h]; apply takeD_left
+
+end TakeD
+
+/-! ### foldl, foldr -/
+
+theorem foldl_ext (f g : α → β → α) (a : α) {l : List β} (H : ∀ a : α, ∀ b ∈ l, f a b = g a b) :
+    foldl f a l = foldl g a l := by
+  induction l generalizing a with
+  | nil => rfl
+  | cons hd tl ih =>
+    unfold foldl
+    rw [ih _ fun a b bin => H a b <| mem_cons_of_mem _ bin, H a hd (mem_cons_self _ _)]
+#align list.foldl_ext List.foldl_ext
+
+theorem foldr_ext (f g : α → β → β) (b : β) {l : List α} (H : ∀ a ∈ l, ∀ b : β, f a b = g a b) :
+    foldr f b l = foldr g b l := by
+  induction' l with hd tl ih; · rfl
+  simp only [mem_cons, or_imp, forall_and, forall_eq] at H
+  simp only [foldr, ih H.2, H.1]
+#align list.foldr_ext List.foldr_ext
+
+@[simp]
+theorem foldl_nil (f : α → β → α) (a : α) : foldl f a [] = a :=
+  rfl
+#align list.foldl_nil List.foldl_nil
+
+@[simp]
+theorem foldl_cons (f : α → β → α) (a : α) (b : β) (l : List β) :
+    foldl f a (b :: l) = foldl f (f a b) l :=
+  rfl
+#align list.foldl_cons List.foldl_cons
+
+@[simp]
+theorem foldr_nil (f : α → β → β) (b : β) : foldr f b [] = b :=
+  rfl
+#align list.foldr_nil List.foldr_nil
+
+@[simp]
+theorem foldr_cons (f : α → β → β) (b : β) (a : α) (l : List α) :
+    foldr f b (a :: l) = f a (foldr f b l) :=
+  rfl
+#align list.foldr_cons List.foldr_cons
+
+#align list.foldl_append List.foldl_append
+
+#align list.foldr_append List.foldr_append
+
+theorem foldl_fixed' {f : α → β → α} {a : α} (hf : ∀ b, f a b = a) : ∀ l : List β, foldl f a l = a
+  | [] => rfl
+  | b :: l => by rw [foldl_cons, hf b, foldl_fixed' hf l]
+#align list.foldl_fixed' List.foldl_fixed'
+
+theorem foldr_fixed' {f : α → β → β} {b : β} (hf : ∀ a, f a b = b) : ∀ l : List α, foldr f b l = b
+  | [] => rfl
+  | a :: l => by rw [foldr_cons, foldr_fixed' hf l, hf a]
+#align list.foldr_fixed' List.foldr_fixed'
+
+@[simp]
+theorem foldl_fixed {a : α} : ∀ l : List β, foldl (fun a _ => a) a l = a :=
+  foldl_fixed' fun _ => rfl
+#align list.foldl_fixed List.foldl_fixed
+
+@[simp]
+theorem foldr_fixed {b : β} : ∀ l : List α, foldr (fun _ b => b) b l = b :=
+  foldr_fixed' fun _ => rfl
+#align list.foldr_fixed List.foldr_fixed
+
+@[simp]
+theorem foldl_join (f : α → β → α) :
+    ∀ (a : α) (L : List (List β)), foldl f a (join L) = foldl (foldl f) a L
+  | a, [] => rfl
+  | a, l :: L => by simp only [join, foldl_append, foldl_cons, foldl_join f (foldl f a l) L]
+#align list.foldl_join List.foldl_join
+
+@[simp]
+theorem foldr_join (f : α → β → β) :
+    ∀ (b : β) (L : List (List α)), foldr f b (join L) = foldr (fun l b => foldr f b l) b L
+  | a, [] => rfl
+  | a, l :: L => by simp only [join, foldr_append, foldr_join f a L, foldr_cons]
+#align list.foldr_join List.foldr_join
+
+#align list.foldl_reverse List.foldl_reverse
+
+#align list.foldr_reverse List.foldr_reverse
+
+-- Porting note: simp can prove this
+-- @[simp]
+theorem foldr_eta : ∀ l : List α, foldr cons [] l = l :=
+  by simp only [foldr_self_append, append_nil, forall_const]
+#align list.foldr_eta List.foldr_eta
+
+@[simp]
+theorem reverse_foldl {l : List α} : reverse (foldl (fun t h => h :: t) [] l) = l := by
+  rw [← foldr_reverse]; simp only [foldr_self_append, append_nil, reverse_reverse]
+#align list.reverse_foldl List.reverse_foldl
+
+#align list.foldl_map List.foldl_map
+
+#align list.foldr_map List.foldr_map
+
+theorem foldl_map' {α β : Type u} (g : α → β) (f : α → α → α) (f' : β → β → β) (a : α) (l : List α)
+    (h : ∀ x y, f' (g x) (g y) = g (f x y)) :
+    List.foldl f' (g a) (l.map g) = g (List.foldl f a l) := by
+  induction l generalizing a
+  · simp
+  · simp [*, h]
+#align list.foldl_map' List.foldl_map'
+
+theorem foldr_map' {α β : Type u} (g : α → β) (f : α → α → α) (f' : β → β → β) (a : α) (l : List α)
+    (h : ∀ x y, f' (g x) (g y) = g (f x y)) :
+    List.foldr f' (g a) (l.map g) = g (List.foldr f a l) := by
+  induction l generalizing a
+  · simp
+  · simp [*, h]
+#align list.foldr_map' List.foldr_map'
+
+#align list.foldl_hom List.foldl_hom
+
+#align list.foldr_hom List.foldr_hom
+
+theorem foldl_hom₂ (l : List ι) (f : α → β → γ) (op₁ : α → ι → α) (op₂ : β → ι → β)
+    (op₃ : γ → ι → γ) (a : α) (b : β) (h : ∀ a b i, f (op₁ a i) (op₂ b i) = op₃ (f a b) i) :
+    foldl op₃ (f a b) l = f (foldl op₁ a l) (foldl op₂ b l) :=
+  Eq.symm <| by
+    revert a b
+    induction l <;> intros <;> [rfl, simp only [*, foldl]]
+#align list.foldl_hom₂ List.foldl_hom₂
+
+theorem foldr_hom₂ (l : List ι) (f : α → β → γ) (op₁ : ι → α → α) (op₂ : ι → β → β)
+    (op₃ : ι → γ → γ) (a : α) (b : β) (h : ∀ a b i, f (op₁ i a) (op₂ i b) = op₃ i (f a b)) :
+    foldr op₃ (f a b) l = f (foldr op₁ a l) (foldr op₂ b l) := by
+  revert a
+  induction l <;> intros <;> [rfl, simp only [*, foldr]]
+#align list.foldr_hom₂ List.foldr_hom₂
+
+theorem injective_foldl_comp {α : Type _} {l : List (α → α)} {f : α → α}
+    (hl : ∀ f ∈ l, Function.Injective f) (hf : Function.Injective f) :
+    Function.Injective (@List.foldl (α → α) (α → α) Function.comp f l) := by
+  induction' l with lh lt l_ih generalizing f
+  · exact hf
+  · apply l_ih fun _ h => hl _ (List.mem_cons_of_mem _ h)
+    apply Function.Injective.comp hf
+    apply hl _ (List.mem_cons_self _ _)
+#align list.injective_foldl_comp List.injective_foldl_comp
+
+/- Porting note: couldn't do induction proof because "code generator does not support recursor
+  'List.rec' yet". Earlier proof:
+
+  induction l with
+  | nil => exact hb
+  | cons hd tl IH =>
+    refine' hl _ _ hd (mem_cons_self hd tl)
+    refine' IH _
+    intro y hy x hx
+    exact hl y hy x (mem_cons_of_mem hd hx)
+-/
+/-- Induction principle for values produced by a `foldr`: if a property holds
+for the seed element `b : β` and for all incremental `op : α → β → β`
+performed on the elements `(a : α) ∈ l`. The principle is given for
+a `Sort`-valued predicate, i.e., it can also be used to construct data. -/
+def foldrRecOn {C : β → Sort _} (l : List α) (op : α → β → β) (b : β) (hb : C b)
+    (hl : ∀ (b : β) (_ : C b) (a : α) (_ : a ∈ l), C (op a b)) : C (foldr op b l) := by
+  cases l with
+  | nil => exact hb
+  | cons hd tl =>
+    have IH : ((b : β) → C b → (a : α) → a ∈ tl → C (op a b)) → C (foldr op b tl) :=
+      foldrRecOn _ _ _ hb
+    refine' hl _ _ hd (mem_cons_self hd tl)
+    refine' IH _
+    intro y hy x hx
+    exact hl y hy x (mem_cons_of_mem hd hx)
+#align list.foldr_rec_on List.foldrRecOn
+
+/- Porting note: couldn't do induction proof because "code generator does not support recursor
+  'List.rec' yet". Earlier proof:
+
+  induction l generalizing b with
+  | nil => exact hb
+  | cons hd tl IH =>
+    refine' IH _ _ _
+    · exact hl b hb hd (mem_cons_self hd tl)
+    · intro y hy x hx
+      exact hl y hy x (mem_cons_of_mem hd hx)
+-/
+/-- Induction principle for values produced by a `foldl`: if a property holds
+for the seed element `b : β` and for all incremental `op : β → α → β`
+performed on the elements `(a : α) ∈ l`. The principle is given for
+a `Sort`-valued predicate, i.e., it can also be used to construct data. -/
+def foldlRecOn {C : β → Sort _} (l : List α) (op : β → α → β) (b : β) (hb : C b)
+    (hl : ∀ (b : β) (_ : C b) (a : α) (_ : a ∈ l), C (op b a)) : C (foldl op b l) := by
+  cases l with
+  | nil => exact hb
+  | cons hd tl =>
+    have IH : (b : β) → C b → ((b : β) → C b → (a : α) → a ∈ tl → C (op b a)) → C (foldl op b tl) :=
+      foldlRecOn _ _
+    refine' IH _ _ _
+    · exact hl b hb hd (mem_cons_self hd tl)
+    · intro y hy x hx
+      exact hl y hy x (mem_cons_of_mem hd hx)
+#align list.foldl_rec_on List.foldlRecOn
+
+@[simp]
+theorem foldr_rec_on_nil {C : β → Sort _} (op : α → β → β) (b) (hb : C b) (hl) :
+    foldrRecOn [] op b hb hl = hb :=
+  rfl
+#align list.foldr_rec_on_nil List.foldr_rec_on_nil
+
+@[simp]
+theorem foldr_rec_on_cons {C : β → Sort _} (x : α) (l : List α) (op : α → β → β) (b) (hb : C b)
+    (hl : ∀ (b : β) (_ : C b) (a : α) (_ : a ∈ x :: l), C (op a b)) :
+    foldrRecOn (x :: l) op b hb hl =
+      hl _ (foldrRecOn l op b hb fun b hb a ha => hl b hb a (mem_cons_of_mem _ ha)) x
+        (mem_cons_self _ _) :=
+  rfl
+#align list.foldr_rec_on_cons List.foldr_rec_on_cons
+
+@[simp]
+theorem foldl_rec_on_nil {C : β → Sort _} (op : β → α → β) (b) (hb : C b) (hl) :
+    foldlRecOn [] op b hb hl = hb :=
+  rfl
+#align list.foldl_rec_on_nil List.foldl_rec_on_nil
+
+-- scanl
+section Scanl
+
+variable {f : β → α → β} {b : β} {a : α} {l : List α}
+
+theorem length_scanl : ∀ a l, length (scanl f a l) = l.length + 1
+  | a, [] => rfl
+  | a, x :: l => by
+    rw [scanl, length_cons, length_cons, ←succ_eq_add_one, congr_arg succ]
+    exact length_scanl _ _
+#align list.length_scanl List.length_scanl
+
+@[simp]
+theorem scanl_nil (b : β) : scanl f b nil = [b] :=
+  rfl
+#align list.scanl_nil List.scanl_nil
+
+@[simp]
+theorem scanl_cons : scanl f b (a :: l) = [b] ++ scanl f (f b a) l := by
+  simp only [scanl, eq_self_iff_true, singleton_append, and_self_iff]
+#align list.scanl_cons List.scanl_cons
+
+@[simp]
+theorem get?_zero_scanl : (scanl f b l).get? 0 = some b := by
+  cases l
+  · simp only [get?, scanl_nil]
+  · simp only [get?, scanl_cons, singleton_append]
+#align list.nth_zero_scanl List.get?_zero_scanl
+
+@[simp]
+theorem get_zero_scanl {h : 0 < (scanl f b l).length} : (scanl f b l).get ⟨0, h⟩ = b := by
+  cases l
+  · simp only [get, scanl_nil]
+  · simp only [get, scanl_cons, singleton_append]
+
+set_option linter.deprecated false in
+@[simp, deprecated get_zero_scanl]
+theorem nthLe_zero_scanl {h : 0 < (scanl f b l).length} : (scanl f b l).nthLe 0 h = b :=
+  get_zero_scanl
+#align list.nth_le_zero_scanl List.nthLe_zero_scanl
+
+theorem get?_succ_scanl {i : ℕ} : (scanl f b l).get? (i + 1) =
+    ((scanl f b l).get? i).bind fun x => (l.get? i).map fun y => f x y := by
+  induction' l with hd tl hl generalizing b i
+  · symm
+    simp only [Option.bind_eq_none', get?, forall₂_true_iff, not_false_iff, Option.map_none',
+      scanl_nil, Option.not_mem_none, forall_true_iff]
+  · simp only [scanl_cons, singleton_append]
+    cases i
+    · simp only [Option.map_some', get?_zero_scanl, get?, Option.some_bind']
+    · simp only [hl, get?]
+#align list.nth_succ_scanl List.get?_succ_scanl
+
+set_option linter.deprecated false in
+theorem nthLe_succ_scanl {i : ℕ} {h : i + 1 < (scanl f b l).length} :
+    (scanl f b l).nthLe (i + 1) h =
+      f ((scanl f b l).nthLe i (Nat.lt_of_succ_lt h))
+        (l.nthLe i (Nat.lt_of_succ_lt_succ (lt_of_lt_of_le h (le_of_eq (length_scanl b l))))) := by
+  induction i generalizing b l with
+  | zero =>
+    cases l
+    · simp only [length, zero_add, scanl_nil] at h
+    · simp [scanl_cons, singleton_append, nthLe_zero_scanl, nthLe_cons]
+  | succ i hi =>
+    cases l
+    · simp only [length, add_lt_iff_neg_right, scanl_nil] at h
+      exact absurd h (not_lt_of_lt Nat.succ_pos')
+    · simp_rw [scanl_cons]
+      rw [nthLe_append_right]
+      · simp only [length, zero_add 1, succ_add_sub_one, hi]; rfl
+      · simp only [length, Nat.zero_le, le_add_iff_nonneg_left]
+#align list.nth_le_succ_scanl List.nthLe_succ_scanl
+
+theorem get_succ_scanl {i : ℕ} {h : i + 1 < (scanl f b l).length} :
+    (scanl f b l).get ⟨i + 1, h⟩ =
+      f ((scanl f b l).get ⟨i, Nat.lt_of_succ_lt h⟩)
+        (l.get ⟨i, Nat.lt_of_succ_lt_succ (lt_of_lt_of_le h (le_of_eq (length_scanl b l)))⟩) :=
+  nthLe_succ_scanl
+
+-- FIXME: we should do the proof the other way around
+attribute [deprecated get_succ_scanl] nthLe_succ_scanl
+
+end Scanl
+
+-- scanr
+@[simp]
+theorem scanr_nil (f : α → β → β) (b : β) : scanr f b [] = [b] :=
+  rfl
+#align list.scanr_nil List.scanr_nil
+
+#noalign list.scanr_aux_cons
+
+@[simp]
+theorem scanr_cons (f : α → β → β) (b : β) (a : α) (l : List α) :
+    scanr f b (a :: l) = foldr f b (a :: l) :: scanr f b l := by
+  simp only [scanr, foldr, cons.injEq, and_true]
+  induction l generalizing a with
+  | nil => rfl
+  | cons hd tl ih => simp only [foldr, ih]
+#align list.scanr_cons List.scanr_cons
+
+section FoldlEqFoldr
+
+-- foldl and foldr coincide when f is commutative and associative
+variable {f : α → α → α} (hcomm : Commutative f) (hassoc : Associative f)
+
+theorem foldl1_eq_foldr1 : ∀ a b l, foldl f a (l ++ [b]) = foldr f b (a :: l)
+  | a, b, nil => rfl
+  | a, b, c :: l => by
+    simp only [cons_append, foldl_cons, foldr_cons, foldl1_eq_foldr1 _ _ l]; rw [hassoc]
+#align list.foldl1_eq_foldr1 List.foldl1_eq_foldr1
+
+theorem foldl_eq_of_comm_of_assoc : ∀ a b l, foldl f a (b :: l) = f b (foldl f a l)
+  | a, b, nil => hcomm a b
+  | a, b, c :: l => by
+    simp only [foldl_cons]
+    rw [← foldl_eq_of_comm_of_assoc .., right_comm _ hcomm hassoc]; rfl
+#align list.foldl_eq_of_comm_of_assoc List.foldl_eq_of_comm_of_assoc
+
+theorem foldl_eq_foldr : ∀ a l, foldl f a l = foldr f a l
+  | a, nil => rfl
+  | a, b :: l => by
+    simp only [foldr_cons, foldl_eq_of_comm_of_assoc hcomm hassoc]; rw [foldl_eq_foldr a l]
+#align list.foldl_eq_foldr List.foldl_eq_foldr
+
+end FoldlEqFoldr
+
+section FoldlEqFoldlr'
+
+variable {f : α → β → α}
+
+variable (hf : ∀ a b c, f (f a b) c = f (f a c) b)
+
+theorem foldl_eq_of_comm' : ∀ a b l, foldl f a (b :: l) = f (foldl f a l) b
+  | a, b, [] => rfl
+  | a, b, c :: l => by rw [foldl, foldl, foldl, ← foldl_eq_of_comm' .., foldl, hf]
+#align list.foldl_eq_of_comm' List.foldl_eq_of_comm'
+
+theorem foldl_eq_foldr' : ∀ a l, foldl f a l = foldr (flip f) a l
+  | a, [] => rfl
+  | a, b :: l => by rw [foldl_eq_of_comm' hf, foldr, foldl_eq_foldr' ..]; rfl
+#align list.foldl_eq_foldr' List.foldl_eq_foldr'
+
+end FoldlEqFoldlr'
+
+section FoldlEqFoldlr'
+
+variable {f : α → β → β}
+
+variable (hf : ∀ a b c, f a (f b c) = f b (f a c))
+
+theorem foldr_eq_of_comm' : ∀ a b l, foldr f a (b :: l) = foldr f (f b a) l
+  | a, b, [] => rfl
+  | a, b, c :: l => by rw [foldr, foldr, foldr, hf, ← foldr_eq_of_comm' ..]; rfl
+#align list.foldr_eq_of_comm' List.foldr_eq_of_comm'
+
+end FoldlEqFoldlr'
+
+section
+
+variable {op : α → α → α} [ha : IsAssociative α op] [hc : IsCommutative α op]
+
+/-- Notation for `op a b`. -/
+local notation a " ⋆ " b => op a b
+
+/-- Notation for `foldl op a l`. -/
+local notation l " <*> " a => foldl op a l
+
+theorem foldl_assoc : ∀ {l : List α} {a₁ a₂}, (l <*> a₁ ⋆ a₂) = a₁ ⋆ l <*> a₂
+  | [], a₁, a₂ => rfl
+  | a :: l, a₁, a₂ =>
+    calc
+      ((a :: l) <*> a₁ ⋆ a₂) = l <*> a₁ ⋆ a₂ ⋆ a := by simp only [foldl_cons, ha.assoc]
+      _ = a₁ ⋆ (a :: l) <*> a₂ := by rw [foldl_assoc, foldl_cons]
+
+#align list.foldl_assoc List.foldl_assoc
+
+theorem foldl_op_eq_op_foldr_assoc :
+    ∀ {l : List α} {a₁ a₂}, ((l <*> a₁) ⋆ a₂) = a₁ ⋆ l.foldr (· ⋆ ·) a₂
+  | [], a₁, a₂ => rfl
+  | a :: l, a₁, a₂ => by
+    simp only [foldl_cons, foldr_cons, foldl_assoc, ha.assoc]; rw [foldl_op_eq_op_foldr_assoc]
+#align list.foldl_op_eq_op_foldr_assoc List.foldl_op_eq_op_foldr_assoc
+
+theorem foldl_assoc_comm_cons {l : List α} {a₁ a₂} : ((a₁ :: l) <*> a₂) = a₁ ⋆ l <*> a₂ := by
+  rw [foldl_cons, hc.comm, foldl_assoc]
+#align list.foldl_assoc_comm_cons List.foldl_assoc_comm_cons
+
+end
+
+/-! ### foldlM, foldrM, mapM -/
+
+section FoldlMFoldrM
+
+variable {m : Type v → Type w} [Monad m]
+
+@[simp]
+theorem foldlM_nil (f : β → α → m β) {b} : List.foldlM f b [] = pure b :=
+  rfl
+#align list.mfoldl_nil List.foldlM_nil
+
+-- Porting note: now in std
+#align list.mfoldr_nil List.foldrM_nil
+
+@[simp]
+theorem foldlM_cons {f : β → α → m β} {b a l} :
+    List.foldlM f b (a :: l) = f b a >>= fun b' => List.foldlM f b' l :=
+  rfl
+#align list.mfoldl_cons List.foldlM_cons
+
+/- Porting note: now in std; now assumes an instance of `LawfulMonad m`, so we make everything
+  `foldrM_eq_foldr` depend on one as well. (An instance of `LawfulMonad m` was already present for
+  everything following; this just moves it a few lines up.) -/
+#align list.mfoldr_cons List.foldrM_cons
+
+variable [LawfulMonad m]
+
+theorem foldrM_eq_foldr (f : α → β → m β) (b l) :
+    foldrM f b l = foldr (fun a mb => mb >>= f a) (pure b) l := by induction l <;> simp [*]
+#align list.mfoldr_eq_foldr List.foldrM_eq_foldr
+
+attribute [simp] mapM mapM'
+
+theorem foldlM_eq_foldl (f : β → α → m β) (b l) :
+    List.foldlM f b l = foldl (fun mb a => mb >>= fun b => f b a) (pure b) l := by
+  suffices h :
+    ∀ mb : m β, (mb >>= fun b => List.foldlM f b l) = foldl (fun mb a => mb >>= fun b => f b a) mb l
+  · simp [← h (pure b)]
+  induction l with
+  | nil => intro; simp
+  | cons _ _ l_ih => intro; simp only [List.foldlM, foldl, ←l_ih, functor_norm]
+#align list.mfoldl_eq_foldl List.foldlM_eq_foldl
+
+-- Porting note: now in std
+#align list.mfoldl_append List.foldlM_append
+
+--Porting note: now in std
+#align list.mfoldr_append List.foldrM_append
+
+end FoldlMFoldrM
+
+/-! ### intersperse -/
+
+@[simp]
+theorem intersperse_nil {α : Type u} (a : α) : intersperse a [] = [] :=
+  rfl
+#align list.intersperse_nil List.intersperse_nil
+
+@[simp]
+theorem intersperse_singleton {α : Type u} (a b : α) : intersperse a [b] = [b] :=
+  rfl
+#align list.intersperse_singleton List.intersperse_singleton
+
+@[simp]
+theorem intersperse_cons_cons {α : Type u} (a b c : α) (tl : List α) :
+    intersperse a (b :: c :: tl) = b :: a :: intersperse a (c :: tl) :=
+  rfl
+#align list.intersperse_cons_cons List.intersperse_cons_cons
+
+/-! ### splitAt and splitOn -/
+
+section SplitAtOn
+
+/- Porting note: the new version of `splitOnP` uses a `Bool`-valued predicate instead of a
+  `Prop`-valued one. All downstream defintions have been updated to match. -/
+
+variable (p : α → Bool) (xs ys : List α) (ls : List (List α)) (f : List α → List α)
+
+/- Porting note: this had to be rewritten because of the new implementation of `splitAt`. It's
+  long in large part because `splitAt.go` (`splitAt`'s auxiliary function) works differently
+  in the case where n ≥ length l, requiring two separate cases (and two separate inductions). Still,
+  this can hopefully be golfed. -/
+
+@[simp]
+theorem splitAt_eq_take_drop (n : ℕ) (l : List α) : splitAt n l = (take n l, drop n l) := by
+  by_cases n < l.length <;> rw [splitAt, go_eq_take_drop]
+  · rw [if_pos h]; rfl
+  · rw [if_neg h, take_all_of_le <| le_of_not_lt h, drop_eq_nil_of_le <| le_of_not_lt h]
+where
+  go_eq_take_drop (n : ℕ) (l xs : List α) (acc : Array α) : splitAt.go l xs n acc =
+      if n < xs.length then (acc.toList ++ take n xs, drop n xs) else (l, []) := by
+    split_ifs with h
+    · induction n generalizing xs acc with
+      | zero =>
+        rw [splitAt.go, take, drop, append_nil]
+        · intros h₁; rw [h₁] at h; contradiction
+        · intros; contradiction
+      | succ _ ih =>
+        cases xs with
+        | nil => contradiction
+        | cons hd tl =>
+          rw [length, succ_eq_add_one] at h
+          rw [splitAt.go, take, drop, append_cons, Array.toList_eq, ←Array.push_data,
+            ←Array.toList_eq]
+          exact ih _ _ <| lt_of_add_lt_add_right h
+    · induction n generalizing xs acc with
+      | zero =>
+        rw [zero_eq, not_lt, nonpos_iff_eq_zero] at h
+        rw [eq_nil_of_length_eq_zero h, splitAt.go]
+      | succ _ ih =>
+        cases xs with
+        | nil => rw [splitAt.go]
+        | cons hd tl =>
+          rw [length, succ_eq_add_one] at h
+          rw [splitAt.go]
+          exact ih _ _ <| not_imp_not.mpr (Nat.add_lt_add_right · 1) h
+#align list.split_at_eq_take_drop List.splitAt_eq_take_drop
+
+@[simp]
+theorem splitOn_nil {α : Type u} [DecidableEq α] (a : α) : [].splitOn a = [[]] :=
+  rfl
+#align list.split_on_nil List.splitOn_nil
+
+@[simp]
+theorem splitOnP_nil : [].splitOnP p = [[]] :=
+  rfl
+#align list.split_on_p_nil List.splitOnP_nilₓ
+
+/- Porting note: `split_on_p_aux` and `split_on_p_aux'` were used to prove facts about
+  `split_on_p`. `splitOnP` has a different structure, and we need different facts about
+  `splitOnP.go`. Theorems involving `split_on_p_aux` have been omitted where possible. -/
+
+#noalign list.split_on_p_aux_ne_nil
+#noalign list.split_on_p_aux_spec
+#noalign list.split_on_p_aux'
+#noalign list.split_on_p_aux_eq
+#noalign list.split_on_p_aux_nil
+
+theorem splitOnP.go_append (xs : List α) (acc : Array α) (r : Array (List α)) :
+    splitOnP.go p xs acc r = r.toListAppend (splitOnP.go p xs acc #[]) := by
+  cases xs with
+  | nil => rfl
+  | cons a as =>
+    simp only [go]
+    by_cases p a
+    · simp only [h, cond_true]
+      rw [go_append as, go_append as _ (Array.push #[] (Array.toList acc))]
+      simp only [Array.toListAppend_eq, Array.push_data]
+      rw [Array.data_toArray, nil_append, append_assoc]
+    · simp only [eq_false_of_ne_true h, cond_false]
+      exact go_append as _ _
+
+theorem splitOnP.go_acc (xs : List α) (acc : Array α) :
+    splitOnP.go p xs acc #[] = modifyHead (acc.toListAppend) (splitOnP.go p xs #[] #[]) := by
+  cases xs with
+  | nil => rfl
+  | cons hd tl =>
+    simp only [go]
+    by_cases p hd
+    · simp only [h, cond_true]
+      rw [go_append, go_append _ _ _ (Array.push #[] (Array.toList #[]))]
+      rfl
+    · simp only [eq_false_of_ne_true h, cond_false]
+      rw [go_acc tl, go_acc tl (Array.push #[] hd), modifyHead_modifyHead]
+      change modifyHead (fun a ↦ Array.toListAppend (Array.push acc hd) a) _ =
+        modifyHead (fun a ↦ Array.toListAppend acc <| Array.toListAppend (Array.push #[] hd) a) _
+      simp only [Array.toListAppend_eq, Array.push_data, Array.data_toArray, nil_append,
+        append_assoc]
+
+theorem splitOnP_ne_nil (xs : List α) : xs.splitOnP p ≠ [] := by
+  cases xs with
+  | nil => exact cons_ne_nil [] []
+  | cons hd tl =>
+    rw [splitOnP, splitOnP.go]
+    by_cases p hd
+    · rw [h, cond_true, splitOnP.go_append]
+      exact append_ne_nil_of_ne_nil_left [[]] _ (cons_ne_nil [] [])
+    · rw [eq_false_of_ne_true h, cond_false, splitOnP.go_acc, ←splitOnP]
+      exact modifyHead_ne_nil_of_ne_nil (splitOnP_ne_nil tl)
+where
+  modifyHead_ne_nil_of_ne_nil {α} {f} {l : List α} (_ : l ≠ []) : modifyHead f l ≠ [] := by
+    cases l with | nil => contradiction | cons => rw [modifyHead]; exact cons_ne_nil _ _
+#align list.split_on_p_ne_nil List.splitOnP_ne_nilₓ
+
+@[simp]
+theorem splitOnP_cons (x : α) (xs : List α) :
+    (x :: xs).splitOnP p =
+      if p x then [] :: xs.splitOnP p else (xs.splitOnP p).modifyHead (cons x) := by
+  rw [splitOnP, splitOnP.go]
+  by_cases p x
+  · rw [if_pos h, h, cond_true, splitOnP.go_append, splitOnP]; rfl
+  · rw [if_neg h, eq_false_of_ne_true h, cond_false, splitOnP.go_acc, splitOnP]; congr 1
+#align list.split_on_p_cons List.splitOnP_consₓ
+
+/-- The original list `L` can be recovered by joining the lists produced by `splitOnP p L`,
+interspersed with the elements `L.filter p`. -/
+theorem splitOnP_spec (as : List α) :
+    join (zipWith (· ++ ·) (splitOnP p as) (((as.filter p).map fun x => [x]) ++ [[]])) = as := by
+  induction as with
+  | nil => rfl
+  | cons a as' ih =>
+    rw [splitOnP_cons, filter]
+    by_cases p a
+    · rw [if_pos h, h, map, cons_append, zipWith, nil_append, join, cons_append, cons_inj]
+      exact ih
+    · rw [if_neg h, eq_false_of_ne_true h, join_zipWith (splitOnP_ne_nil _ _)
+        (append_ne_nil_of_ne_nil_right _ [[]] (cons_ne_nil [] [])), cons_inj]
+      exact ih
+where
+  join_zipWith {xs ys : List (List α)} {a : α} (hxs : xs ≠ []) (hys : ys ≠ []) :
+      join (zipWith (fun x x_1 ↦ x ++ x_1) (modifyHead (cons a) xs) ys) =
+        a :: join (zipWith (fun x x_1 ↦ x ++ x_1) xs ys) := by
+    cases xs with | nil => contradiction | cons =>
+      cases ys with | nil => contradiction | cons => rfl
+#align list.split_on_p_spec List.splitOnP_specₓ
+
+/-- If no element satisfies `p` in the list `xs`, then `xs.splitOnP p = [xs]` -/
+theorem splitOnP_eq_single (h : ∀ x ∈ xs, ¬p x) : xs.splitOnP p = [xs] := by
+  induction xs with
+  | nil => rfl
+  | cons hd tl ih =>
+    simp only [splitOnP_cons, h hd (mem_cons_self hd tl), if_neg]
+    rw [ih <| forall_mem_of_forall_mem_cons h]
+    rfl
+#align list.split_on_p_eq_single List.splitOnP_eq_singleₓ
+
+/-- When a list of the form `[...xs, sep, ...as]` is split on `p`, the first element is `xs`,
+  assuming no element in `xs` satisfies `p` but `sep` does satisfy `p` -/
+theorem splitOnP_first (h : ∀ x ∈ xs, ¬p x) (sep : α) (hsep : p sep) (as : List α) :
+    (xs ++ sep :: as).splitOnP p = xs :: as.splitOnP p := by
+  induction xs with
+  | nil => simp [hsep]
+  | cons hd tl ih => simp [h hd _, ih <| forall_mem_of_forall_mem_cons h]
+#align list.split_on_p_first List.splitOnP_firstₓ
+
+/-- `intercalate [x]` is the left inverse of `splitOn x`  -/
+theorem intercalate_splitOn (x : α) [DecidableEq α] : [x].intercalate (xs.splitOn x) = xs := by
+  simp only [intercalate, splitOn]
+  induction' xs with hd tl ih; · simp [join]
+  cases' h' : splitOnP (· == x) tl with hd' tl'; · exact (splitOnP_ne_nil _ tl h').elim
+  rw [h'] at ih
+  rw [splitOnP_cons]
+  split_ifs with h;
+  · rw [beq_iff_eq] at h
+    subst h
+    simp [ih, join, h']
+  cases tl' <;> simpa [join, h'] using ih
+#align list.intercalate_split_on List.intercalate_splitOn
+
+/-- `splitOn x` is the left inverse of `intercalate [x]`, on the domain
+  consisting of each nonempty list of lists `ls` whose elements do not contain `x`  -/
+theorem splitOn_intercalate [DecidableEq α] (x : α) (hx : ∀ l ∈ ls, x ∉ l) (hls : ls ≠ []) :
+    ([x].intercalate ls).splitOn x = ls := by
+  simp only [intercalate]
+  induction' ls with hd tl ih; · contradiction
+  cases tl
+  · suffices hd.splitOn x = [hd] by simpa [join]
+    refine' splitOnP_eq_single _ _ _
+    intro y hy H
+    rw [eq_of_beq H] at hy
+    refine' hx hd _ hy
+    simp
+  · simp only [intersperse_cons_cons, singleton_append, join]
+    specialize ih _ _
+    · intro l hl
+      apply hx l
+      simp at hl⊢
+      exact Or.inr hl
+    · exact List.noConfusion
+    have := splitOnP_first (· == x) hd ?h x (beq_self_eq_true _)
+    case h =>
+      intro y hy H
+      rw [eq_of_beq H] at hy
+      exact hx hd (.head _) hy
+    simp only [splitOn] at ih⊢
+    rw [this, ih]
+#align list.split_on_intercalate List.splitOn_intercalate
+
+end SplitAtOn
+
+/- Porting note: new; here tentatively -/
+/-! ### ModifyLast -/
+
+section ModifyLast
+
+theorem modifyLast.go_append_one (f : α → α) (a : α) (tl : List α) (r : Array α):
+    modifyLast.go f (tl ++ [a]) r = (r.toListAppend <| modifyLast.go f (tl ++ [a]) #[]) := by
+  cases tl with
+  | nil =>
+    simp only [nil_append, modifyLast.go]; rfl
+  | cons hd tl =>
+    simp only [cons_append]
+    rw [modifyLast.go, modifyLast.go]
+    case x_3 | x_3 => exact append_ne_nil_of_ne_nil_right tl [a] (cons_ne_nil a [])
+    rw [modifyLast.go_append_one _ _ tl _, modifyLast.go_append_one _ _ tl (Array.push #[] hd)]
+    simp only [Array.toListAppend_eq, Array.push_data, Array.data_toArray, nil_append, append_assoc]
+
+theorem modifyLast_append_one (f : α → α) (a : α) (l : List α) :
+    modifyLast f (l ++ [a]) = l ++ [f a] := by
+  cases l with
+  | nil =>
+    simp only [nil_append, modifyLast, modifyLast.go, Array.toListAppend_eq, Array.data_toArray]
+  | cons _ tl =>
+    simp only [cons_append, modifyLast]
+    rw [modifyLast.go]
+    case x_3 => exact append_ne_nil_of_ne_nil_right tl [a] (cons_ne_nil a [])
+    rw [modifyLast.go_append_one, Array.toListAppend_eq, Array.push_data, Array.data_toArray,
+      nil_append, cons_append, nil_append, cons_inj]
+    exact modifyLast_append_one _ _ tl
+
+theorem modifyLast_append (f : α → α) (l₁ l₂ : List α) (_ : l₂ ≠ []) :
+    modifyLast f (l₁ ++ l₂) = l₁ ++ modifyLast f l₂ := by
+  cases l₂ with
+  | nil => contradiction
+  | cons hd tl =>
+    cases tl with
+    | nil => exact modifyLast_append_one _ hd _
+    | cons hd' tl' =>
+      rw [append_cons, ←nil_append (hd :: hd' :: tl'), append_cons [], nil_append,
+        modifyLast_append _ (l₁ ++ [hd]) (hd' :: tl') _, modifyLast_append _ [hd] (hd' :: tl') _,
+        append_assoc]
+      all_goals { exact cons_ne_nil _ _ }
+
+end ModifyLast
+
+/-! ### map for partial functions -/
+
+/-- Partial map. If `f : Π a, p a → β` is a partial function defined on
+  `a : α` satisfying `p`, then `pmap f l h` is essentially the same as `map f l`
+  but is defined only when all members of `l` satisfy `p`, using the proof
+  to apply `f`. -/
+@[simp]
+def pmap {p : α → Prop} (f : ∀ a, p a → β) : ∀ l : List α, (∀ a ∈ l, p a) → List β
+  | [], _ => []
+  | a :: l, H => f a (forall_mem_cons.1 H).1 :: pmap f l (forall_mem_cons.1 H).2
+#align list.pmap List.pmap
+
+/-- "Attach" the proof that the elements of `l` are in `l` to produce a new list
+  with the same elements but in the type `{x // x ∈ l}`. -/
+def attach (l : List α) : List { x // x ∈ l } :=
+  pmap Subtype.mk l fun _ => id
+#align list.attach List.attach
+
+theorem sizeOf_lt_sizeOf_of_mem [SizeOf α] {x : α} {l : List α} (hx : x ∈ l) :
+    SizeOf.sizeOf x < SizeOf.sizeOf l := by
+  induction' l with h t ih <;> cases hx <;> rw [cons.sizeOf_spec]
+  · exact lt_add_of_lt_of_nonneg (lt_one_add _) (Nat.zero_le _)
+  · refine lt_add_of_pos_of_le ?_ (le_of_lt (ih ‹_›))
+    rw [add_comm]; exact succ_pos _
+#align list.sizeof_lt_sizeof_of_mem List.sizeOf_lt_sizeOf_of_mem
+
+@[simp]
+theorem pmap_eq_map (p : α → Prop) (f : α → β) (l : List α) (H) :
+    @pmap _ _ p (fun a _ => f a) l H = map f l := by
+  induction l <;> [rfl, simp only [*, pmap, map]]
+#align list.pmap_eq_map List.pmap_eq_map
+
+theorem pmap_congr {p q : α → Prop} {f : ∀ a, p a → β} {g : ∀ a, q a → β} (l : List α) {H₁ H₂}
+    (h : ∀ a ∈ l, ∀ (h₁ h₂), f a h₁ = g a h₂) : pmap f l H₁ = pmap g l H₂ := by
+  induction' l with _ _ ih
+  · rfl
+  · rw [pmap, pmap, h _ (mem_cons_self _ _), ih fun a ha => h a (mem_cons_of_mem _ ha)]
+#align list.pmap_congr List.pmap_congr
+
+theorem map_pmap {p : α → Prop} (g : β → γ) (f : ∀ a, p a → β) (l H) :
+    map g (pmap f l H) = pmap (fun a h => g (f a h)) l H := by
+  induction l <;> [rfl, simp only [*, pmap, map]]
+#align list.map_pmap List.map_pmap
+
+theorem pmap_map {p : β → Prop} (g : ∀ b, p b → γ) (f : α → β) (l H) :
+    pmap g (map f l) H = pmap (fun a h => g (f a) h) l fun a h => H _ (mem_map_of_mem _ h) := by
+  induction l <;> [rfl, simp only [*, pmap, map]]
+#align list.pmap_map List.pmap_map
+
+theorem pmap_eq_map_attach {p : α → Prop} (f : ∀ a, p a → β) (l H) :
+    pmap f l H = l.attach.map fun x => f x.1 (H _ x.2) := by
+  rw [attach, map_pmap]; exact pmap_congr l fun _ _ _ _ => rfl
+#align list.pmap_eq_map_attach List.pmap_eq_map_attach
+
+-- @[simp] -- Porting note: lean 4 simp can't rewrite with this
+theorem attach_map_coe' (l : List α) (f : α → β) :
+    (l.attach.map fun (i : {i // i ∈ l}) => f i) = l.map f := by
+  rw [attach, map_pmap]; exact pmap_eq_map _ _ _ _
+#align list.attach_map_coe' List.attach_map_coe'
+
+theorem attach_map_val' (l : List α) (f : α → β) : (l.attach.map fun i => f i.val) = l.map f :=
+  attach_map_coe' _ _
+#align list.attach_map_val' List.attach_map_val'
+
+@[simp]
+theorem attach_map_val (l : List α) : l.attach.map Subtype.val = l :=
+  (attach_map_coe' _ _).trans l.map_id
+-- porting note: coe is expanded eagerly, so "attach_map_coe" would have the same syntactic form.
+#align list.attach_map_coe List.attach_map_val
+#align list.attach_map_val List.attach_map_val
+
+@[simp]
+theorem mem_attach (l : List α) : ∀ x, x ∈ l.attach
+  | ⟨a, h⟩ => by
+    have := mem_map.1 (by rw [attach_map_val] <;> exact h);
+      · rcases this with ⟨⟨_, _⟩, m, rfl⟩
+        exact m
+#align list.mem_attach List.mem_attach
+
+@[simp]
+theorem mem_pmap {p : α → Prop} {f : ∀ a, p a → β} {l H b} :
+    b ∈ pmap f l H ↔ ∃ (a : _)(h : a ∈ l), f a (H a h) = b := by
+  simp only [pmap_eq_map_attach, mem_map, mem_attach, true_and_iff, Subtype.exists, eq_comm]
+#align list.mem_pmap List.mem_pmap
+
+@[simp]
+theorem length_pmap {p : α → Prop} {f : ∀ a, p a → β} {l H} : length (pmap f l H) = length l := by
+  induction l <;> [rfl, simp only [*, pmap, length]]
+#align list.length_pmap List.length_pmap
+
+@[simp]
+theorem length_attach (L : List α) : L.attach.length = L.length :=
+  length_pmap
+#align list.length_attach List.length_attach
+
+@[simp]
+theorem pmap_eq_nil {p : α → Prop} {f : ∀ a, p a → β} {l H} : pmap f l H = [] ↔ l = [] := by
+  rw [← length_eq_zero, length_pmap, length_eq_zero]
+#align list.pmap_eq_nil List.pmap_eq_nil
+
+@[simp]
+theorem attach_eq_nil (l : List α) : l.attach = [] ↔ l = [] :=
+  pmap_eq_nil
+#align list.attach_eq_nil List.attach_eq_nil
+
+theorem getLast_pmap {α β : Type _} (p : α → Prop) (f : ∀ a, p a → β) (l : List α)
+    (hl₁ : ∀ a ∈ l, p a) (hl₂ : l ≠ []) :
+    (l.pmap f hl₁).getLast (mt List.pmap_eq_nil.1 hl₂) =
+      f (l.getLast hl₂) (hl₁ _ (List.getLast_mem hl₂)) := by
+  induction' l with l_hd l_tl l_ih
+  · apply (hl₂ rfl).elim
+  · by_cases hl_tl : l_tl = []
+    · simp [hl_tl]
+    · simp only [pmap]
+      rw [getLast_cons, l_ih _ hl_tl]
+      simp only [getLast_cons hl_tl]
+#align list.last_pmap List.getLast_pmap
+
+theorem get?_pmap {p : α → Prop} (f : ∀ a, p a → β) {l : List α} (h : ∀ a ∈ l, p a) (n : ℕ) :
+    get? (pmap f l h) n = Option.pmap f (get? l n) fun x H => h x (get?_mem H) := by
+  induction' l with hd tl hl generalizing n
+  · simp
+  · cases' n with n
+    . simp
+    . simp [hl]
+      dsimp
+#align list.nth_pmap List.get?_pmap
+
+theorem get_pmap {p : α → Prop} (f : ∀ a, p a → β) {l : List α} (h : ∀ a ∈ l, p a) {n : ℕ}
+    (hn : n < (pmap f l h).length) :
+    get (pmap f l h) ⟨n, hn⟩ =
+      f (get l ⟨n, @length_pmap _ _ p f l h ▸ hn⟩)
+        (h _ (get_mem l n (@length_pmap _ _ p f l h ▸ hn))) := by
+  induction' l with hd tl hl generalizing n
+  · simp only [length, pmap] at hn
+    exact absurd hn (not_lt_of_le n.zero_le)
+  · cases n
+    · simp
+    · simp [hl]
+
+set_option linter.deprecated false in
+@[deprecated get_pmap]
+theorem nthLe_pmap {p : α → Prop} (f : ∀ a, p a → β) {l : List α} (h : ∀ a ∈ l, p a) {n : ℕ}
+    (hn : n < (pmap f l h).length) :
+    nthLe (pmap f l h) n hn =
+      f (nthLe l n (@length_pmap _ _ p f l h ▸ hn))
+        (h _ (get_mem l n (@length_pmap _ _ p f l h ▸ hn))) :=
+  get_pmap ..
+
+#align list.nth_le_pmap List.nthLe_pmap
+
+theorem pmap_append {p : ι → Prop} (f : ∀ a : ι, p a → α) (l₁ l₂ : List ι)
+    (h : ∀ a ∈ l₁ ++ l₂, p a) :
+    (l₁ ++ l₂).pmap f h =
+      (l₁.pmap f fun a ha => h a (mem_append_left l₂ ha)) ++
+        l₂.pmap f fun a ha => h a (mem_append_right l₁ ha) := by
+  induction' l₁ with _ _ ih
+  · rfl
+  · dsimp only [pmap, cons_append]
+    rw [ih]
+#align list.pmap_append List.pmap_append
+
+theorem pmap_append' {α β : Type _} {p : α → Prop} (f : ∀ a : α, p a → β) (l₁ l₂ : List α)
+    (h₁ : ∀ a ∈ l₁, p a) (h₂ : ∀ a ∈ l₂, p a) :
+    ((l₁ ++ l₂).pmap f fun a ha => (List.mem_append.1 ha).elim (h₁ a) (h₂ a)) =
+      l₁.pmap f h₁ ++ l₂.pmap f h₂ :=
+  pmap_append f l₁ l₂ _
+#align list.pmap_append' List.pmap_append'
+
+/-! ### find -/
+
+section find?
+
+variable {p : α → Bool} {l : List α} {a : α}
+
+@[simp]
+theorem find?_nil (p : α → Bool) : find? p [] = none :=
+  rfl
+#align list.find_nil List.find?_nil
+
+-- Porting note: List.find? is given @[simp] in Std.Data.List.Init.Lemmas
+-- @[simp]
+@[simp 1100, nolint simpNF]
+theorem find?_cons_of_pos (l) (h : p a) : find? p (a :: l) = some a :=
+  by simp [find?, h]
+#align list.find_cons_of_pos List.find?_cons_of_pos
+
+-- Porting note: List.find? is given @[simp] in Std.Data.List.Init.Lemmas
+-- @[simp]
+@[simp 1100, nolint simpNF]
+theorem find?_cons_of_neg (l) (h : ¬p a) : find? p (a :: l) = find? p l :=
+  by simp [find?, h]
+#align list.find_cons_of_neg List.find?_cons_of_neg
+
+@[simp]
+theorem find?_eq_none : find? p l = none ↔ ∀ x ∈ l, ¬p x := by
+  induction' l with a l IH
+  · exact iff_of_true rfl (forall_mem_nil _)
+  rw [forall_mem_cons]; by_cases h : p a
+  · simp only [find?_cons_of_pos _ h, h, not_true, false_and_iff]
+  · rwa [find?_cons_of_neg _ h, iff_true_intro h, true_and_iff]
+#align list.find_eq_none List.find?_eq_none
+
+theorem find?_some (H : find? p l = some a) : p a := by
+  induction' l with b l IH; · contradiction
+  by_cases h : p b
+  · rw [find?_cons_of_pos _ h] at H
+    cases H
+    exact h
+  · rw [find?_cons_of_neg _ h] at H
+    exact IH H
+#align list.find_some List.find?_some
+
+@[simp]
+theorem find?_mem (H : find? p l = some a) : a ∈ l := by
+  induction' l with b l IH; · contradiction
+  by_cases h : p b
+  · rw [find?_cons_of_pos _ h] at H
+    cases H
+    apply mem_cons_self
+  · rw [find?_cons_of_neg _ h] at H
+    exact mem_cons_of_mem _ (IH H)
+#align list.find_mem List.find?_mem
+
+end find?
+
+/-! ### lookmap -/
+
+section Lookmap
+
+variable (f : α → Option α)
+
+/- Porting note: need a helper theorem for lookmap.go. -/
+theorem lookmap.go_append (l : List α) (acc : Array α) :
+    lookmap.go f l acc = acc.toListAppend (lookmap f l) := by
+  cases l with
+  | nil => rfl
+  | cons hd tl =>
+    rw [lookmap, go, go]
+    cases f hd with
+    | none => simp only [go_append tl _, Array.toListAppend_eq, append_assoc, Array.push_data]; rfl
+    | some a => rfl
+
+@[simp]
+theorem lookmap_nil : [].lookmap f = [] :=
+  rfl
+#align list.lookmap_nil List.lookmap_nil
+
+@[simp]
+theorem lookmap_cons_none {a : α} (l : List α) (h : f a = none) :
+    (a :: l).lookmap f = a :: l.lookmap f := by
+  simp only [lookmap, lookmap.go, Array.toListAppend_eq, Array.data_toArray, nil_append]
+  rw [lookmap.go_append, h]; rfl
+#align list.lookmap_cons_none List.lookmap_cons_none
+
+@[simp]
+theorem lookmap_cons_some {a b : α} (l : List α) (h : f a = some b) :
+    (a :: l).lookmap f = b :: l := by
+  simp only [lookmap, lookmap.go, Array.toListAppend_eq, Array.data_toArray, nil_append]
+  rw [h]
+#align list.lookmap_cons_some List.lookmap_cons_some
+
+theorem lookmap_some : ∀ l : List α, l.lookmap some = l
+  | [] => rfl
+  | _ :: _ => rfl
+#align list.lookmap_some List.lookmap_some
+
+theorem lookmap_none : ∀ l : List α, (l.lookmap fun _ => none) = l
+  | [] => rfl
+  | a :: l => (lookmap_cons_none _ l rfl).trans (congr_arg (cons a) (lookmap_none l))
+#align list.lookmap_none List.lookmap_none
+
+theorem lookmap_congr {f g : α → Option α} :
+    ∀ {l : List α}, (∀ a ∈ l, f a = g a) → l.lookmap f = l.lookmap g
+  | [], _ => rfl
+  | a :: l, H => by
+    cases' forall_mem_cons.1 H with H₁ H₂
+    cases' h : g a with b
+    · simp [h, H₁.trans h, lookmap_congr H₂]
+    · simp [lookmap_cons_some _ _ h, lookmap_cons_some _ _ (H₁.trans h)]
+#align list.lookmap_congr List.lookmap_congr
+
+theorem lookmap_of_forall_not {l : List α} (H : ∀ a ∈ l, f a = none) : l.lookmap f = l :=
+  (lookmap_congr H).trans (lookmap_none l)
+#align list.lookmap_of_forall_not List.lookmap_of_forall_not
+
+theorem lookmap_map_eq (g : α → β) (h : ∀ (a), ∀ b ∈ f a, g a = g b) :
+    ∀ l : List α, map g (l.lookmap f) = map g l
+  | [] => rfl
+  | a :: l => by
+    cases' h' : f a with b
+    · simp [h']; exact lookmap_map_eq _ h l
+    · simp [lookmap_cons_some _ _ h', h _ _ h']
+#align list.lookmap_map_eq List.lookmap_map_eq
+
+theorem lookmap_id' (h : ∀ (a), ∀ b ∈ f a, a = b) (l : List α) : l.lookmap f = l := by
+  rw [← map_id (l.lookmap f), lookmap_map_eq, map_id]; exact h
+#align list.lookmap_id' List.lookmap_id'
+
+theorem length_lookmap (l : List α) : length (l.lookmap f) = length l := by
+  rw [← length_map, lookmap_map_eq _ fun _ => (), length_map]; simp
+#align list.length_lookmap List.length_lookmap
+
+end Lookmap
+
+/-! ### filter -/
+-- Porting note: These lemmas are from Lean3 core
+
+@[simp] theorem filter_nil (p : α → Bool) : filter p [] = [] := rfl
+#align list.filter_nil List.filter_nil
+
+@[simp] theorem filter_cons_of_pos {p : α → Bool} {a : α} :
+   ∀ l, p a → filter p (a::l) = a :: filter p l :=
+fun l pa => by rw [filter, pa]
+#align list.filter_cons_of_pos List.filter_cons_of_pos
+
+@[simp] theorem filter_cons_of_neg {p : α → Bool} {a : α} :
+  ∀ l, ¬ p a → filter p (a::l) = filter p l :=
+fun l pa => by rw [filter, eq_false_of_ne_true pa]
+#align list.filter_cons_of_neg List.filter_cons_of_neg
+
+@[simp] theorem filter_append {p : α → Bool} :
+  ∀ (l₁ l₂ : List α), filter p (l₁++l₂) = filter p l₁ ++ filter p l₂
+| [],    l₂ => rfl
+| a::l₁, l₂ => by rw [cons_append, filter, filter]; cases p a <;> dsimp <;> rw [filter_append l₁]
+#align list.filter_append List.filter_append
+
+@[simp] theorem filter_sublist {p : α → Bool} :
+    ∀ (l : List α), filter p l <+ l
+| []     => Sublist.slnil
+| (a::l) => by
+  rw [filter]
+  cases p a
+  . exact Sublist.cons _ (filter_sublist l)
+  . exact Sublist.cons₂ _ (filter_sublist l)
+#align list.filter_sublist List.filter_sublist
+
+/-! ### filterMap -/
+
+@[simp]
+theorem filterMap_nil (f : α → Option β) : filterMap f [] = [] :=
+  rfl
+#align list.filter_map_nil List.filterMap_nil
+
+-- Porting note: List.filterMap is given @[simp] in Std.Data.List.Init.Lemmas
+-- @[simp]
+@[simp 1100, nolint simpNF]
+theorem filterMap_cons_none {f : α → Option β} (a : α) (l : List α) (h : f a = none) :
+    filterMap f (a :: l) = filterMap f l := by simp only [filterMap, h]
+#align list.filter_map_cons_none List.filterMap_cons_none
+
+-- @[simp]
+@[simp 1100, nolint simpNF]
+theorem filterMap_cons_some (f : α → Option β) (a : α) (l : List α) {b : β} (h : f a = some b) :
+    filterMap f (a :: l) = b :: filterMap f l := by
+  simp only [filterMap, h]
+#align list.filter_map_cons_some List.filterMap_cons_some
+
+theorem filterMap_cons (f : α → Option β) (a : α) (l : List α) :
+    filterMap f (a :: l) = Option.casesOn (f a) (filterMap f l) fun b => b :: filterMap f l := by
+  generalize eq : f a = b
+  cases b
+  · rw [filterMap_cons_none _ _ eq]
+  · rw [filterMap_cons_some _ _ _ eq]
+#align list.filter_map_cons List.filterMap_cons
+
+theorem filterMap_append {α β : Type _} (l l' : List α) (f : α → Option β) :
+    filterMap f (l ++ l') = filterMap f l ++ filterMap f l' := by
+  induction' l with hd tl hl generalizing l'
+  · simp
+  · rw [cons_append, filterMap, filterMap]
+    cases f hd <;> simp only [filterMap, hl, cons_append, eq_self_iff_true, and_self_iff]
+#align list.filter_map_append List.filterMap_append
+
+theorem filterMap_eq_map (f : α → β) : filterMap (some ∘ f) = map f := by
+  funext l
+  induction' l with a l IH; · rfl
+  simp only [filterMap_cons_some (some ∘ f) _ _ rfl, IH, map_cons]
+#align list.filter_map_eq_map List.filterMap_eq_map
+
+theorem filterMap_eq_filter (p : α → Bool) :
+    filterMap (Option.guard (p ·)) = filter p := by
+  funext l
+  induction' l with a l IH; · rfl
+  by_cases pa : p a
+  · simp only [filterMap, Option.guard, pa, ite_true, filter, decide_True, ← IH]
+  · simp only [filterMap, Option.guard, pa, ite_false, filter, decide_False, ← IH]
+#align list.filter_map_eq_filter List.filterMap_eq_filter
+
+theorem filterMap_filterMap (f : α → Option β) (g : β → Option γ) (l : List α) :
+    filterMap g (filterMap f l) = filterMap (fun x => (f x).bind g) l := by
+  induction' l with a l IH; · rfl
+  cases' h : f a with b
+  · rw [filterMap_cons_none _ _ h, filterMap_cons_none, IH]
+    simp only [h, Option.none_bind']
+  rw [filterMap_cons_some _ _ _ h]
+  cases' h' : g b with c <;> [rw [filterMap_cons_none _ _ h', filterMap_cons_none, IH],
+      rw [filterMap_cons_some _ _ _ h', filterMap_cons_some, IH]] <;>
+    simp only [h, h', Option.some_bind']
+#align list.filter_map_filter_map List.filterMap_filterMap
+
+theorem map_filterMap (f : α → Option β) (g : β → γ) (l : List α) :
+    map g (filterMap f l) = filterMap (fun x => (f x).map g) l := by
+  simp only [← filterMap_eq_map, filterMap_filterMap, Option.map_eq_bind]
+#align list.map_filter_map List.map_filterMap
+
+theorem filterMap_map (f : α → β) (g : β → Option γ) (l : List α) :
+    filterMap g (map f l) = filterMap (g ∘ f) l := by
+  rw [← filterMap_eq_map, filterMap_filterMap]; rfl
+#align list.filter_map_map List.filterMap_map
+
+theorem filter_filterMap (f : α → Option β) (p : β → Bool) (l : List α) :
+    filter p (filterMap f l) = filterMap (fun x => (f x).filter p) l := by
+  rw [← filterMap_eq_filter, filterMap_filterMap]
+  congr
+  funext x
+  cases f x <;> simp [Option.filter, Option.guard]
+#align list.filter_filter_map List.filter_filterMap
+
+theorem filterMap_filter (p : α → Bool) (f : α → Option β) (l : List α) :
+    filterMap f (filter p l) = filterMap (fun x => if p x then f x else none) l := by
+  rw [← filterMap_eq_filter, filterMap_filterMap]; congr
+  funext x
+  by_cases h : p x <;> simp [Option.guard, h]
+#align list.filter_map_filter List.filterMap_filter
+
+@[simp]
+theorem filterMap_some (l : List α) : filterMap some l = l := by
+  erw [filterMap_eq_map]; apply map_id
+#align list.filter_map_some List.filterMap_some
+
+theorem map_filterMap_some_eq_filter_map_is_some (f : α → Option β) (l : List α) :
+    (l.filterMap f).map some = (l.map f).filter fun b => b.isSome := by
+  induction' l with x xs ih
+  · rfl
+  · cases h : f x <;> rw [List.filterMap_cons, h] <;> simp [h, ih]
+#align list.map_filter_map_some_eq_filter_map_is_some List.map_filterMap_some_eq_filter_map_is_some
+
+@[simp]
+theorem mem_filterMap (f : α → Option β) (l : List α) {b : β} :
+    b ∈ filterMap f l ↔ ∃ a, a ∈ l ∧ f a = some b := by
+  induction' l with a l IH
+  · constructor
+    · intro H
+      cases H
+    · rintro ⟨_, H, _⟩
+      cases H
+  cases' h : f a with b'
+  · have : f a ≠ some b := by
+      rw [h]
+      intro
+      contradiction
+    simp only [filterMap_cons_none _ _ h, IH, mem_cons, or_and_right, exists_or,
+      exists_eq_left, this, false_or_iff]
+  · have : f a = some b ↔ b = b' := by
+      constructor <;> intro t
+      · rw [t] at h; injection h
+      · exact t.symm ▸ h
+    simp only [filterMap_cons_some _ _ _ h, IH, mem_cons, or_and_right, exists_or, this,
+      exists_eq_left]
+#align list.mem_filter_map List.mem_filterMap
+
+@[simp]
+theorem filterMap_join (f : α → Option β) (L : List (List α)) :
+    filterMap f (join L) = join (map (filterMap f) L) := by
+  induction' L with hd tl ih
+  · rfl
+  · rw [map, join, join, filterMap_append, ih]
+#align list.filter_map_join List.filterMap_join
+
+theorem map_filterMap_of_inv (f : α → Option β) (g : β → α) (H : ∀ x : α, (f x).map g = some x)
+    (l : List α) : map g (filterMap f l) = l := by simp only [map_filterMap, H, filterMap_some]
+#align list.map_filter_map_of_inv List.map_filterMap_of_inv
+
+theorem length_filter_le (p : α → Bool) (l : List α) :
+    (l.filter p).length ≤ l.length :=
+  (List.filter_sublist _).length_le
+#align list.length_filter_le List.length_filter_leₓ
+
+theorem length_filterMap_le (f : α → Option β) (l : List α) :
+    (List.filterMap f l).length ≤ l.length := by
+  rw [←List.length_map _ some, List.map_filterMap_some_eq_filter_map_is_some, ←List.length_map _ f]
+  apply List.length_filter_le
+#align list.length_filter_map_le List.length_filterMap_le
+
+theorem Sublist.filterMap (f : α → Option β) {l₁ l₂ : List α} (s : l₁ <+ l₂) :
+    filterMap f l₁ <+ filterMap f l₂ := by
+  induction' s with l₁ l₂ a s IH l₁ l₂ a s IH
+  . simp
+  . rw [filterMap]
+    cases f a <;> simp [IH, Sublist.cons]
+  . rw [filterMap, filterMap]
+    cases f a <;> simp [IH, Sublist.cons₂]
+#align list.sublist.filter_map List.Sublist.filterMap
+
+theorem Sublist.map (f : α → β) {l₁ l₂ : List α} (s : l₁ <+ l₂) : map f l₁ <+ map f l₂ :=
+  filterMap_eq_map f ▸ s.filterMap _
+#align list.sublist.map List.Sublist.map
+
+/-! ### reduceOption -/
+
+@[simp]
+theorem reduceOption_cons_of_some (x : α) (l : List (Option α)) :
+    reduceOption (some x :: l) = x :: l.reduceOption := by
+  simp only [reduceOption, filterMap, id.def, eq_self_iff_true, and_self_iff]
+#align list.reduce_option_cons_of_some List.reduceOption_cons_of_some
+
+@[simp]
+theorem reduceOption_cons_of_none (l : List (Option α)) :
+    reduceOption (none :: l) = l.reduceOption := by simp only [reduceOption, filterMap, id.def]
+#align list.reduce_option_cons_of_none List.reduceOption_cons_of_none
+
+@[simp]
+theorem reduceOption_nil : @reduceOption α [] = [] :=
+  rfl
+#align list.reduce_option_nil List.reduceOption_nil
+
+@[simp]
+theorem reduceOption_map {l : List (Option α)} {f : α → β} :
+    reduceOption (map (Option.map f) l) = map f (reduceOption l) := by
+  induction' l with hd tl hl
+  · simp only [reduceOption_nil, map_nil]
+  ·cases hd <;>
+      simpa [true_and_iff, Option.map_some', map, eq_self_iff_true,
+        reduceOption_cons_of_some] using hl
+#align list.reduce_option_map List.reduceOption_map
+
+theorem reduceOption_append (l l' : List (Option α)) :
+    (l ++ l').reduceOption = l.reduceOption ++ l'.reduceOption :=
+  filterMap_append l l' id
+#align list.reduce_option_append List.reduceOption_append
+
+theorem reduceOption_length_le (l : List (Option α)) : l.reduceOption.length ≤ l.length := by
+  induction' l with hd tl hl
+  · simp only [reduceOption_nil, length]
+  · cases hd
+    · exact Nat.le_succ_of_le hl
+    · simpa only [length, add_le_add_iff_right, reduceOption_cons_of_some] using hl
+#align list.reduce_option_length_le List.reduceOption_length_le
+
+theorem reduceOption_length_eq_iff {l : List (Option α)} :
+    l.reduceOption.length = l.length ↔ ∀ x ∈ l, Option.isSome x := by
+  induction' l with hd tl hl
+  · simp only [forall_const, reduceOption_nil, not_mem_nil, forall_prop_of_false, eq_self_iff_true,
+      length, not_false_iff]
+  · cases hd
+    · simp only [mem_cons, forall_eq_or_imp, Bool.coe_sort_false, false_and_iff,
+        reduceOption_cons_of_none, length, Option.isSome_none, iff_false_iff]
+      intro H
+      have := reduceOption_length_le tl
+      rw [H] at this
+      exact absurd (Nat.lt_succ_self _) (not_lt_of_le this)
+    · simp only [length, add_left_inj, find?, mem_cons, forall_eq_or_imp, Option.isSome_some,
+        ← hl, reduceOption, true_and]
+#align list.reduce_option_length_eq_iff List.reduceOption_length_eq_iff
+
+theorem reduceOption_length_lt_iff {l : List (Option α)} :
+    l.reduceOption.length < l.length ↔ none ∈ l := by
+  rw [(reduceOption_length_le l).lt_iff_ne, Ne, reduceOption_length_eq_iff]
+  induction l <;> simp [*]
+  rw [@eq_comm _ none, ← Option.not_isSome_iff_eq_none, Decidable.imp_iff_not_or]
+  simp [Option.isNone_iff_eq_none]
+#align list.reduce_option_length_lt_iff List.reduceOption_length_lt_iff
+
+theorem reduceOption_singleton (x : Option α) : [x].reduceOption = x.toList := by cases x <;> rfl
+#align list.reduce_option_singleton List.reduceOption_singleton
+
+theorem reduceOption_concat (l : List (Option α)) (x : Option α) :
+    (l.concat x).reduceOption = l.reduceOption ++ x.toList := by
+  induction' l with hd tl hl generalizing x
+  · cases x <;> simp [Option.toList]
+  · simp only [concat_eq_append, reduceOption_append] at hl
+    cases hd <;> simp [hl, reduceOption_append]
+#align list.reduce_option_concat List.reduceOption_concat
+
+theorem reduceOption_concat_of_some (l : List (Option α)) (x : α) :
+    (l.concat (some x)).reduceOption = l.reduceOption.concat x := by
+  simp only [reduceOption_nil, concat_eq_append, reduceOption_append, reduceOption_cons_of_some]
+#align list.reduce_option_concat_of_some List.reduceOption_concat_of_some
+
+theorem reduceOption_mem_iff {l : List (Option α)} {x : α} : x ∈ l.reduceOption ↔ some x ∈ l := by
+  simp only [reduceOption, id.def, mem_filterMap, exists_eq_right]
+#align list.reduce_option_mem_iff List.reduceOption_mem_iff
+
+theorem reduceOption_get?_iff {l : List (Option α)} {x : α} :
+    (∃ i, l.get? i = some (some x)) ↔ ∃ i, l.reduceOption.get? i = some x := by
+  rw [← mem_iff_get?, ← mem_iff_get?, reduceOption_mem_iff]
+#align list.reduce_option_nth_iff List.reduceOption_get?_iff
+
+/-! ### filter -/
+
+section Filter
+
+-- Porting note: Lemmas for `filter` are stated in terms of `p : α → Bool`
+-- rather than `p : α → Prop` with `DecidablePred p`, since `filter` itself is.
+-- Likewise, `if` sometimes becomes `bif`.
+variable {p : α → Bool}
+
+theorem filter_singleton {a : α} : [a].filter p = bif p a then [a] else [] :=
+  rfl
+#align list.filter_singleton List.filter_singleton
+
+theorem filter_eq_foldr (p : α → Bool) (l : List α) :
+    filter p l = foldr (fun a out => bif p a then a :: out else out) [] l := by
+  induction l <;> simp [*, filter]; rfl
+#align list.filter_eq_foldr List.filter_eq_foldr
+
+theorem filter_congr' {p q : α → Bool} :
+    ∀ {l : List α}, (∀ x ∈ l, p x ↔ q x) → filter p l = filter q l
+  | [], _ => rfl
+  | a :: l, h => by
+    rw [forall_mem_cons] at h; by_cases pa : p a <;>
+      [simp only [filter_cons_of_pos _ pa, filter_cons_of_pos _ (h.1.1 pa), filter_congr' h.2],
+      simp only [filter_cons_of_neg _ pa, filter_cons_of_neg _ (mt h.1.2 pa),
+        filter_congr' h.2]]
+#align list.filter_congr' List.filter_congr'
+
+@[simp]
+theorem filter_subset (l : List α) : filter p l ⊆ l :=
+  (filter_sublist l).subset
+#align list.filter_subset List.filter_subset
+
+theorem of_mem_filter {a : α} : ∀ {l}, a ∈ filter p l → p a
+  | b :: l, ain =>
+    if pb : p b then
+      have : a ∈ b :: filter p l := by simpa only [filter_cons_of_pos _ pb] using ain
+      Or.elim (eq_or_mem_of_mem_cons this) (fun h : a = b => by rw [← h] at pb; exact pb)
+        fun h : a ∈ filter p l => of_mem_filter h
+    else by simp only [filter_cons_of_neg _ pb] at ain; exact of_mem_filter ain
+#align list.of_mem_filter List.of_mem_filter
+
+theorem mem_of_mem_filter {a : α} {l} (h : a ∈ filter p l) : a ∈ l :=
+  filter_subset l h
+#align list.mem_of_mem_filter List.mem_of_mem_filter
+
+theorem mem_filter_of_mem {a : α} : ∀ {l}, a ∈ l → p a → a ∈ filter p l
+  | x :: l, h, h1 => by
+    rcases mem_cons.1 h with rfl | h
+    . simp [filter, h1]
+    . rw [filter]
+      cases p x <;> simp [mem_filter_of_mem h h1]
+
+#align list.mem_filter_of_mem List.mem_filter_of_mem
+
+#align list.mem_filter List.mem_filter
+
+theorem monotone_filter_left (p : α → Bool) ⦃l l' : List α⦄ (h : l ⊆ l') :
+    filter p l ⊆ filter p l' := by
+  intro x hx
+  rw [mem_filter] at hx⊢
+  exact ⟨h hx.left, hx.right⟩
+#align list.monotone_filter_left List.monotone_filter_left
+
+theorem filter_eq_self {l} : filter p l = l ↔ ∀ a ∈ l, p a := by
+  induction' l with a l ih
+  · exact iff_of_true rfl (forall_mem_nil _)
+  rw [forall_mem_cons]; by_cases p a
+  · rw [filter_cons_of_pos _ h, cons_inj, ih, and_iff_right h]
+  · refine' iff_of_false (fun hl => h <| of_mem_filter (_ : a ∈ filter p (a :: l))) (mt And.left h)
+    rw [hl]
+    exact mem_cons_self _ _
+#align list.filter_eq_self List.filter_eq_self
+
+theorem filter_length_eq_length {l} : (filter p l).length = l.length ↔ ∀ a ∈ l, p a :=
+  Iff.trans ⟨l.filter_sublist.eq_of_length, congr_arg List.length⟩ filter_eq_self
+#align list.filter_length_eq_length List.filter_length_eq_length
+
+theorem filter_eq_nil {l} : filter p l = [] ↔ ∀ a ∈ l, ¬p a := by
+  simp only [eq_nil_iff_forall_not_mem, mem_filter, not_and]
+#align list.filter_eq_nil List.filter_eq_nil
+
+variable (p)
+
+theorem Sublist.filter {l₁ l₂} (s : l₁ <+ l₂) : filter p l₁ <+ filter p l₂ := by
+  have := filterMap_eq_filter (fun a => p a)
+  simp only [Bool.decide_coe] at this
+  rw [← this]
+  apply s.filterMap
+#align list.sublist.filter List.Sublist.filter
+
+theorem monotone_filter_right (l : List α) ⦃p q : α → Bool⦄
+    (h : ∀ a, p a → q a) : l.filter p <+ l.filter q := by
+  induction' l with hd tl IH
+  · rfl
+  · by_cases hp : p hd
+    · rw [filter_cons_of_pos _ hp, filter_cons_of_pos _ (h _ hp)]
+      exact IH.cons_cons hd
+    · rw [filter_cons_of_neg _ hp]
+      by_cases hq : q hd
+      · rw [filter_cons_of_pos _ hq]
+        exact sublist_cons_of_sublist hd IH
+      · rw [filter_cons_of_neg _ hq]
+        exact IH
+#align list.monotone_filter_right List.monotone_filter_right
+
+theorem map_filter (f : β → α) (l : List β) : filter p (map f l) = map f (filter (p ∘ f) l) := by
+  rw [← filterMap_eq_map, filter_filterMap, filterMap_filter]; rfl
+#align list.map_filter List.map_filter
+
+@[simp]
+theorem filter_filter (q) :
+    ∀ l, filter p (filter q l) = filter (fun a => p a ∧ q a) l
+  | [] => rfl
+  | a :: l => by
+    by_cases hp : p a <;> by_cases hq : q a <;>
+      simp only [hp, hq, filter, if_true, if_false, true_and_iff, false_and_iff, filter_filter _ l,
+        eq_self_iff_true, decide_True, decide_False]
+#align list.filter_filter List.filter_filter
+
+@[simp]
+theorem filter_true  (l : List α) :
+    filter (fun _ => true) l = l := by induction l <;> simp [*, filter]
+#align list.filter_true List.filter_true
+
+@[simp]
+theorem filter_false (l : List α) :
+    filter (fun _ => false) l = [] := by induction l <;> simp [*, filter]
+#align list.filter_false List.filter_false
+
+/- Porting note: need a helper theorem for span.loop. -/
+theorem span.loop_eq_take_drop :
+  ∀ l₁ l₂ : List α, span.loop p l₁ l₂ = (l₂.reverse ++ takeWhile p l₁, dropWhile p l₁)
+  | [], l₂ => by simp [span.loop]
+  | (a :: l), l₂ => by cases hp : p a <;> simp [hp, span.loop, span.loop_eq_take_drop]
+
+@[simp]
+theorem span_eq_take_drop (l : List α) : span p l = (takeWhile p l, dropWhile p l) := by
+  simpa using span.loop_eq_take_drop p l []
+#align list.span_eq_take_drop List.span_eq_take_drop
+
+@[simp]
+theorem takeWhile_append_drop : ∀ l : List α, takeWhile p l ++ dropWhile p l = l
+  | [] => rfl
+  | a :: l =>
+    if pa : p a then by
+      simp [takeWhile, dropWhile, pa, cons_append, takeWhile_append_drop l]
+    else by simp [takeWhile, dropWhile, pa, nil_append]
+#align list.take_while_append_drop List.takeWhile_append_drop
+
+theorem dropWhile_nthLe_zero_not (l : List α) (hl : 0 < (l.dropWhile p).length) :
+    ¬p ((l.dropWhile p).nthLe 0 hl) := by
+  induction' l with hd tl IH
+  · cases hl
+  · simp only [dropWhile]
+    by_cases hp : p hd
+    · simp [hp, IH]
+    · simp [hp, nthLe_cons]
+-- porting note: How did the Lean 3 proof work,
+-- without mentioning nthLe_cons?
+-- Same question for takeWhile_eq_nil_iff below
+#align list.drop_while_nth_le_zero_not List.dropWhile_nthLe_zero_not
+
+variable {p} {l : List α}
+
+@[simp]
+theorem dropWhile_eq_nil_iff : dropWhile p l = [] ↔ ∀ x ∈ l, p x := by
+  induction' l with x xs IH
+  · simp [dropWhile]
+  · by_cases hp : p x <;> simp [hp, dropWhile, IH]
+#align list.drop_while_eq_nil_iff List.dropWhile_eq_nil_iff
+
+@[simp]
+theorem takeWhile_eq_self_iff : takeWhile p l = l ↔ ∀ x ∈ l, p x := by
+  induction' l with x xs IH
+  · simp [takeWhile]
+  · by_cases hp : p x <;> simp [hp, takeWhile, IH]
+#align list.take_while_eq_self_iff List.takeWhile_eq_self_iff
+
+@[simp]
+theorem takeWhile_eq_nil_iff : takeWhile p l = [] ↔ ∀ hl : 0 < l.length, ¬p (l.nthLe 0 hl) := by
+  induction' l with x xs IH
+  · simp [takeWhile, true_iff]
+    intro h
+    simp at h
+  · by_cases hp : p x <;> simp [hp, takeWhile, IH, nthLe_cons]
+#align list.take_while_eq_nil_iff List.takeWhile_eq_nil_iff
+
+theorem mem_takeWhile_imp {x : α} (hx : x ∈ takeWhile p l) : p x := by
+  induction' l with hd tl IH
+  · simp at hx
+  · simp only [takeWhile] at hx
+    cases hp : p hd
+    · simp [hp] at hx
+    · rw [hp, mem_cons] at hx
+      rcases hx with (rfl | hx)
+      · exact hp
+      · exact IH hx
+#align list.mem_take_while_imp List.mem_takeWhile_imp
+
+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 hd tl IH
+  · simp [takeWhile]
+  · by_cases hp : p hd <;> by_cases hq : q hd <;> simp [takeWhile, hp, hq, IH]
+#align list.take_while_take_while List.takeWhile_takeWhile
+
+theorem takeWhile_idem : takeWhile p (takeWhile p l) = takeWhile p l := by
+  simp_rw [takeWhile_takeWhile, and_self_iff, Bool.decide_coe]
+#align list.take_while_idem List.takeWhile_idem
+
+end Filter
+
+/-! ### erasep -/
+
+section eraseP
+
+variable {p : α → Bool}
+
+#align list.erasep_nil List.eraseP_nilₓ -- prop -> bool
+#align list.erasep_cons List.eraseP_consₓ -- prop -> bool
+
+#align list.erasep_cons_of_pos List.eraseP_cons_of_posₓ -- prop -> bool
+#align list.erasep_cons_of_neg List.eraseP_cons_of_negₓ -- prop -> bool
+#align list.erasep_of_forall_not List.eraseP_of_forall_notₓ -- prop -> bool
+#align list.exists_of_erasep List.exists_of_erasePₓ -- prop -> bool
+#align list.exists_or_eq_self_of_erasep List.exists_or_eq_self_of_erasePₓ -- prop -> bool
+#align list.length_erasep_of_mem List.length_eraseP_of_memₓ -- prop -> bool
+
+@[simp]
+theorem length_eraseP_add_one {l : List α} {a} (al : a ∈ l) (pa : p a) :
+    (l.eraseP p).length + 1 = l.length := by
+  let ⟨_, l₁, l₂, _, _, h₁, h₂⟩ := exists_of_eraseP al pa
+  rw [h₂, h₁, length_append, length_append]
+  rfl
+#align list.length_erasep_add_one List.length_eraseP_add_oneₓ -- prop -> bool
+
+#align list.erasep_append_left List.eraseP_append_leftₓ -- prop -> bool
+#align list.erasep_append_right List.eraseP_append_rightₓ -- prop -> bool
+#align list.erasep_sublist List.eraseP_sublistₓ -- prop -> bool
+#align list.erasep_subset List.eraseP_subsetₓ -- prop -> bool
+#align list.sublist.erasep List.Sublist.erasePₓ -- prop -> bool
+#align list.mem_of_mem_erasep List.mem_of_mem_erasePₓ -- prop -> bool
+#align list.mem_erasep_of_neg List.mem_eraseP_of_negₓ -- prop -> bool
+#align list.erasep_map List.eraseP_mapₓ -- prop -> bool
+#align list.extractp_eq_find_erasep List.extractP_eq_find?_erasePₓ -- prop -> bool
+
+end eraseP
+
+/-! ### erase -/
+
+section Erase
+
+variable [DecidableEq α]
+
+#align list.erase_nil List.erase_nil
+
+#align list.erase_cons List.erase_consₓ -- DecidableEq -> BEq
+#align list.erase_cons_head List.erase_cons_headₓ -- DecidableEq -> BEq
+#align list.erase_cons_tail List.erase_cons_tailₓ -- DecidableEq -> BEq
+#align list.erase_eq_erasep List.erase_eq_erasePₓ -- DecidableEq -> BEq
+#align list.erase_of_not_mem List.erase_of_not_memₓ -- DecidableEq -> BEq
+#align list.exists_erase_eq List.exists_erase_eqₓ -- DecidableEq -> BEq
+#align list.length_erase_of_mem List.length_erase_of_memₓ -- DecidableEq -> BEq
+
+@[simp] theorem length_erase_add_one {a : α} {l : List α} (h : a ∈ l) :
+    (l.erase a).length + 1 = l.length := by
+  rw [erase_eq_eraseP, length_eraseP_add_one h (decide_eq_true rfl)]
+#align list.length_erase_add_one List.length_erase_add_oneₓ -- DecidableEq -> BEq
+
+#align list.erase_append_left List.erase_append_leftₓ -- DecidableEq -> BEq
+#align list.erase_append_right List.erase_append_rightₓ -- DecidableEq -> BEq
+#align list.erase_sublist List.erase_sublistₓ -- DecidableEq -> BEq
+#align list.erase_subset List.erase_subsetₓ -- DecidableEq -> BEq
+
+theorem Sublist.erase (a : α) {l₁ l₂ : List α} (h : l₁ <+ l₂) : l₁.erase a <+ l₂.erase a := by
+  simp [erase_eq_eraseP]; exact Sublist.eraseP h
+#align list.sublist.erase List.Sublist.eraseₓ -- DecidableEq -> BEq
+
+#align list.mem_of_mem_erase List.mem_of_mem_eraseₓ -- DecidableEq -> BEq
+#align list.mem_erase_of_ne List.mem_erase_of_neₓ -- DecidableEq -> BEq
+#align list.erase_comm List.erase_commₓ -- DecidableEq -> BEq
+
+theorem map_erase [DecidableEq β] {f : α → β} (finj : Injective f) {a : α} (l : List α) :
+    map f (l.erase a) = (map f l).erase (f a) := by
+  have this : Eq a = Eq (f a) ∘ f := by ext b; simp [finj.eq_iff]
+  simp [erase_eq_eraseP, erase_eq_eraseP, eraseP_map, this]; rfl
+#align list.map_erase List.map_erase
+
+theorem map_foldl_erase [DecidableEq β] {f : α → β} (finj : Injective f) {l₁ l₂ : List α} :
+    map f (foldl List.erase l₁ l₂) = foldl (fun l a => l.erase (f a)) (map f l₁) l₂ := by
+  induction l₂ generalizing l₁ <;> [rfl, simp only [foldl_cons, map_erase finj, *]]
+#align list.map_foldl_erase List.map_foldl_erase
+
+end Erase
+
+/-! ### diff -/
+
+section Diff
+
+variable [DecidableEq α]
+
+@[simp]
+theorem diff_nil (l : List α) : l.diff [] = l :=
+  rfl
+#align list.diff_nil List.diff_nil
+
+@[simp]
+theorem diff_cons (l₁ l₂ : List α) (a : α) : l₁.diff (a :: l₂) = (l₁.erase a).diff l₂ :=
+  if h : elem a l₁ then by simp only [List.diff, if_pos h]
+  else by simp only [List.diff, if_neg h, erase_of_not_mem (mt elem_eq_true_of_mem h)]
+#align list.diff_cons List.diff_cons
+
+theorem diff_cons_right (l₁ l₂ : List α) (a : α) : l₁.diff (a :: l₂) = (l₁.diff l₂).erase a := by
+  induction' l₂ with b l₂ ih generalizing l₁ a
+  · simp_rw [diff_cons, diff_nil]
+  · rw [diff_cons, diff_cons, erase_comm, ← diff_cons, ih, ← diff_cons]
+#align list.diff_cons_right List.diff_cons_right
+
+theorem diff_erase (l₁ l₂ : List α) (a : α) : (l₁.diff l₂).erase a = (l₁.erase a).diff l₂ := by
+  rw [← diff_cons_right, diff_cons]
+#align list.diff_erase List.diff_erase
+
+@[simp]
+theorem nil_diff (l : List α) : [].diff l = [] := by
+  induction l <;> [rfl, simp only [*, diff_cons, erase_of_not_mem (not_mem_nil _)]]
+#align list.nil_diff List.nil_diff
+
+theorem cons_diff (a : α) (l₁ l₂ : List α) :
+    (a :: l₁).diff l₂ = if a ∈ l₂ then l₁.diff (l₂.erase a) else a :: l₁.diff l₂ := by
+  induction' l₂ with b l₂ ih; · rfl
+  rcases eq_or_ne a b with (rfl | hne)
+  · simp
+  · simp only [mem_cons, *, false_or_iff, diff_cons_right]
+    split_ifs with h₂ <;> simp [diff_erase, List.erase, mt eq_of_beq hne, mt eq_of_beq hne.symm]
+#align list.cons_diff List.cons_diff
+
+theorem cons_diff_of_mem {a : α} {l₂ : List α} (h : a ∈ l₂) (l₁ : List α) :
+    (a :: l₁).diff l₂ = l₁.diff (l₂.erase a) := by rw [cons_diff, if_pos h]
+#align list.cons_diff_of_mem List.cons_diff_of_mem
+
+theorem cons_diff_of_not_mem {a : α} {l₂ : List α} (h : a ∉ l₂) (l₁ : List α) :
+    (a :: l₁).diff l₂ = a :: l₁.diff l₂ := by rw [cons_diff, if_neg h]
+#align list.cons_diff_of_not_mem List.cons_diff_of_not_mem
+
+theorem diff_eq_foldl : ∀ l₁ l₂ : List α, l₁.diff l₂ = foldl List.erase l₁ l₂
+  | _, [] => rfl
+  | l₁, a :: l₂ => (diff_cons l₁ l₂ a).trans (diff_eq_foldl _ _)
+#align list.diff_eq_foldl List.diff_eq_foldl
+
+@[simp]
+theorem diff_append (l₁ l₂ l₃ : List α) : l₁.diff (l₂ ++ l₃) = (l₁.diff l₂).diff l₃ := by
+  simp only [diff_eq_foldl, foldl_append]
+#align list.diff_append List.diff_append
+
+@[simp]
+theorem map_diff [DecidableEq β] {f : α → β} (finj : Injective f) {l₁ l₂ : List α} :
+    map f (l₁.diff l₂) = (map f l₁).diff (map f l₂) := by
+  simp only [diff_eq_foldl, foldl_map, map_foldl_erase finj]
+#align list.map_diff List.map_diff
+
+theorem diff_sublist : ∀ l₁ l₂ : List α, l₁.diff l₂ <+ l₁
+  | _, [] => Sublist.refl _
+  | l₁, a :: l₂ =>
+    calc
+      l₁.diff (a :: l₂) = (l₁.erase a).diff l₂ := diff_cons _ _ _
+      _ <+ l₁.erase a := diff_sublist _ _
+      _ <+ l₁ := List.erase_sublist _ _
+#align list.diff_sublist List.diff_sublist
+
+theorem diff_subset (l₁ l₂ : List α) : l₁.diff l₂ ⊆ l₁ :=
+  (diff_sublist _ _).subset
+#align list.diff_subset List.diff_subset
+
+theorem mem_diff_of_mem {a : α} : ∀ {l₁ l₂ : List α}, a ∈ l₁ → a ∉ l₂ → a ∈ l₁.diff l₂
+  | _, [], h₁, _ => h₁
+  | l₁, b :: l₂, h₁, h₂ => by
+    rw [diff_cons] ;
+      exact
+        mem_diff_of_mem ((mem_erase_of_ne (ne_of_not_mem_cons h₂)).2 h₁)
+          (not_mem_of_not_mem_cons h₂)
+#align list.mem_diff_of_mem List.mem_diff_of_mem
+
+theorem Sublist.diff_right : ∀ {l₁ l₂ l₃ : List α}, l₁ <+ l₂ → l₁.diff l₃ <+ l₂.diff l₃
+  | _,  _, [], h => h
+  | l₁, l₂, a :: l₃, h => by simp only [diff_cons, (h.erase _).diff_right]
+#align list.sublist.diff_right List.Sublist.diff_right
+
+theorem erase_diff_erase_sublist_of_sublist {a : α} :
+    ∀ {l₁ l₂ : List α}, l₁ <+ l₂ → (l₂.erase a).diff (l₁.erase a) <+ l₂.diff l₁
+  | [], l₂, _ => erase_sublist _ _
+  | b :: l₁, l₂, h =>
+    if heq : b = a then by simp only [heq, erase_cons_head, diff_cons]; rfl
+    else by
+      simp only [erase_cons_head b l₁, erase_cons_tail l₁ heq,
+        diff_cons ((List.erase l₂ a)) (List.erase l₁ a) b, diff_cons l₂ l₁ b, erase_comm a b l₂]
+      have h' := h.erase b
+      rw [erase_cons_head] at h'
+      exact @erase_diff_erase_sublist_of_sublist _ l₁ (l₂.erase b) h'
+#align list.erase_diff_erase_sublist_of_sublist List.erase_diff_erase_sublist_of_sublist
+
+end Diff
+
+/-! ### enum -/
+
+theorem length_enumFrom : ∀ (n) (l : List α), length (enumFrom n l) = length l
+  | _, [] => rfl
+  | _, _ :: _ => congr_arg Nat.succ (length_enumFrom _ _)
+#align list.length_enum_from List.length_enumFrom
+
+theorem length_enum : ∀ l : List α, length (enum l) = length l :=
+  length_enumFrom _
+#align list.length_enum List.length_enum
+
+@[simp]
+theorem enumFrom_get? :
+    ∀ (n) (l : List α) (m), get? (enumFrom n l) m = (fun a => (n + m, a)) <$> get? l m
+  | n, [], m => rfl
+  | n, a :: l, 0 => rfl
+  | n, a :: l, m + 1 => (enumFrom_get? (n + 1) l m).trans <| by rw [add_right_comm]; rfl
+#align list.enum_from_nth List.enumFrom_get?
+
+@[simp]
+theorem enum_get? : ∀ (l : List α) (n), get? (enum l) n = (fun a => (n, a)) <$> get? l n := by
+  simp only [enum, enumFrom_get?, zero_add]; intros; trivial
+#align list.enum_nth List.enum_get?
+
+@[simp]
+theorem enumFrom_map_snd : ∀ (n) (l : List α), map Prod.snd (enumFrom n l) = l
+  | _, [] => rfl
+  | _, _ :: _ => congr_arg (cons _) (enumFrom_map_snd _ _)
+#align list.enum_from_map_snd List.enumFrom_map_snd
+
+@[simp]
+theorem enum_map_snd : ∀ l : List α, map Prod.snd (enum l) = l :=
+  enumFrom_map_snd _
+#align list.enum_map_snd List.enum_map_snd
+
+theorem mem_enumFrom {x : α} {i : ℕ} :
+    ∀ {j : ℕ} (xs : List α), (i, x) ∈ xs.enumFrom j → j ≤ i ∧ i < j + xs.length ∧ x ∈ xs
+  | j, [] => by simp [enumFrom]
+  | j, y :: ys => by
+    suffices
+      i = j ∧ x = y ∨ (i, x) ∈ enumFrom (j + 1) ys →
+        j ≤ i ∧ i < j + (length ys + 1) ∧ (x = y ∨ x ∈ ys)
+      by simpa [enumFrom, mem_enumFrom ys]
+    rintro (h | h)
+    · refine' ⟨le_of_eq h.1.symm, h.1 ▸ _, Or.inl h.2⟩
+      apply Nat.lt_add_of_pos_right; simp
+    · have ⟨hji, hijlen, hmem⟩ := mem_enumFrom _ h
+      refine' ⟨_, _, _⟩
+      · exact le_trans (Nat.le_succ _) hji
+      · convert hijlen using 1
+        ac_rfl
+      · simp [hmem]
+#align list.mem_enum_from List.mem_enumFrom
+
+@[simp]
+theorem enum_nil : enum ([] : List α) = [] :=
+  rfl
+#align list.enum_nil List.enum_nil
+
+@[simp]
+theorem enumFrom_nil (n : ℕ) : enumFrom n ([] : List α) = [] :=
+  rfl
+#align list.enum_from_nil List.enumFrom_nil
+
+@[simp]
+theorem enumFrom_cons (x : α) (xs : List α) (n : ℕ) :
+    enumFrom n (x :: xs) = (n, x) :: enumFrom (n + 1) xs :=
+  rfl
+#align list.enum_from_cons List.enumFrom_cons
+
+@[simp]
+theorem enum_cons (x : α) (xs : List α) : enum (x :: xs) = (0, x) :: enumFrom 1 xs :=
+  rfl
+#align list.enum_cons List.enum_cons
+
+@[simp]
+theorem enumFrom_singleton (x : α) (n : ℕ) : enumFrom n [x] = [(n, x)] :=
+  rfl
+#align list.enum_from_singleton List.enumFrom_singleton
+
+@[simp]
+theorem enum_singleton (x : α) : enum [x] = [(0, x)] :=
+  rfl
+#align list.enum_singleton List.enum_singleton
+
+theorem enumFrom_append (xs ys : List α) (n : ℕ) :
+    enumFrom n (xs ++ ys) = enumFrom n xs ++ enumFrom (n + xs.length) ys := by
+  induction' xs with x xs IH generalizing ys n
+  · simp
+  · rw [cons_append, enumFrom_cons, IH, ← cons_append, ← enumFrom_cons, length, add_right_comm,
+      add_assoc]
+#align list.enum_from_append List.enumFrom_append
+
+theorem enum_append (xs ys : List α) : enum (xs ++ ys) = enum xs ++ enumFrom xs.length ys := by
+  simp [enum, enumFrom_append]
+#align list.enum_append List.enum_append
+
+theorem map_fst_add_enumFrom_eq_enumFrom (l : List α) (n k : ℕ) :
+    map (Prod.map (· + n) id) (enumFrom k l) = enumFrom (n + k) l := by
+  induction' l with hd tl IH generalizing n k
+  · simp [enumFrom]
+  · simp only [enumFrom, map, zero_add, Prod.map_mk, id.def, eq_self_iff_true, true_and_iff]
+    simp [IH, add_comm n k, add_assoc, add_left_comm]
+#align list.map_fst_add_enum_from_eq_enum_from List.map_fst_add_enumFrom_eq_enumFrom
+
+theorem map_fst_add_enum_eq_enumFrom (l : List α) (n : ℕ) :
+    map (Prod.map (· + n) id) (enum l) = enumFrom n l :=
+  map_fst_add_enumFrom_eq_enumFrom l _ _
+#align list.map_fst_add_enum_eq_enum_from List.map_fst_add_enum_eq_enumFrom
+
+theorem get_enumFrom (l : List α) (n) (i : Fin (l.enumFrom n).length)
+    (hi : i.1 < l.length := (by simpa [length_enumFrom] using i.2)) :
+    (l.enumFrom n).get i = (n + i, l.get ⟨i, hi⟩) := by
+  rw [← Option.some_inj, ← get?_eq_get]
+  simp [enumFrom_get?, get?_eq_get hi]
+
+set_option linter.deprecated false in
+@[deprecated get_enumFrom]
+theorem nthLe_enumFrom (l : List α) (n i : ℕ) (hi' : i < (l.enumFrom n).length)
+    (hi : i < l.length := (by simpa [length_enumFrom] using hi')) :
+    (l.enumFrom n).nthLe i hi' = (n + i, l.nthLe i hi) :=
+  get_enumFrom ..
+#align list.nth_le_enum_from List.nthLe_enumFrom
+
+theorem get_enum (l : List α) (i : Fin l.enum.length)
+    (hi : i < l.length := (by simpa [length_enum] using i.2)) :
+    l.enum.get i = (i.1, l.get ⟨i, hi⟩) := by
+  convert get_enumFrom _ _ i
+  exact (zero_add _).symm
+
+set_option linter.deprecated false in
+@[deprecated get_enum]
+theorem nthLe_enum (l : List α) (i : ℕ) (hi' : i < l.enum.length)
+    (hi : i < l.length := (by simpa [length_enum] using hi')) :
+    l.enum.nthLe i hi' = (i, l.nthLe i hi) := get_enum ..
+#align list.nth_le_enum List.nthLe_enum
+
+section Choose
+
+variable (p : α → Prop) [DecidablePred p] (l : List α)
+
+theorem choose_spec (hp : ∃ a, a ∈ l ∧ p a) : choose p l hp ∈ l ∧ p (choose p l hp) :=
+  (chooseX p l hp).property
+#align list.choose_spec List.choose_spec
+
+theorem choose_mem (hp : ∃ a, a ∈ l ∧ p a) : choose p l hp ∈ l :=
+  (choose_spec _ _ _).1
+#align list.choose_mem List.choose_mem
+
+theorem choose_property (hp : ∃ a, a ∈ l ∧ p a) : p (choose p l hp) :=
+  (choose_spec _ _ _).2
+#align list.choose_property List.choose_property
+
+end Choose
+
+/-! ### map₂Left' -/
+
+section Map₂Left'
+
+-- The definitional equalities for `map₂Left'` can already be used by the
+-- simplifie because `map₂Left'` is marked `@[simp]`.
+@[simp]
+theorem map₂Left'_nil_right (f : α → Option β → γ) (as) :
+    map₂Left' f as [] = (as.map fun a => f a none, []) := by cases as <;> rfl
+#align list.map₂_left'_nil_right List.map₂Left'_nil_right
+
+end Map₂Left'
+
+/-! ### map₂Right' -/
+
+section Map₂Right'
+
+variable (f : Option α → β → γ) (a : α) (as : List α) (b : β) (bs : List β)
+
+@[simp]
+theorem map₂Right'_nil_left : map₂Right' f [] bs = (bs.map (f none), []) := by cases bs <;> rfl
+#align list.map₂_right'_nil_left List.map₂Right'_nil_left
+
+@[simp]
+theorem map₂Right'_nil_right : map₂Right' f as [] = ([], as) :=
+  rfl
+#align list.map₂_right'_nil_right List.map₂Right'_nil_right
+
+-- Porting note: simp can prove this
+-- @[simp]
+theorem map₂Right'_nil_cons : map₂Right' f [] (b :: bs) = (f none b :: bs.map (f none), []) :=
+  rfl
+#align list.map₂_right'_nil_cons List.map₂Right'_nil_cons
+
+@[simp]
+theorem map₂Right'_cons_cons :
+    map₂Right' f (a :: as) (b :: bs) =
+      let r := map₂Right' f as bs
+      (f (some a) b :: r.fst, r.snd) :=
+  rfl
+#align list.map₂_right'_cons_cons List.map₂Right'_cons_cons
+
+end Map₂Right'
+
+/-! ### zipLeft' -/
+
+section ZipLeft'
+
+variable (a : α) (as : List α) (b : β) (bs : List β)
+
+@[simp]
+theorem zipLeft'_nil_right : zipLeft' as ([] : List β) = (as.map fun a => (a, none), []) := by
+  cases as <;> rfl
+#align list.zip_left'_nil_right List.zipLeft'_nil_right
+
+@[simp]
+theorem zipLeft'_nil_left : zipLeft' ([] : List α) bs = ([], bs) :=
+  rfl
+#align list.zip_left'_nil_left List.zipLeft'_nil_left
+
+-- Porting note: simp can prove this
+-- @[simp]
+theorem zipLeft'_cons_nil :
+    zipLeft' (a :: as) ([] : List β) = ((a, none) :: as.map fun a => (a, none), []) :=
+  rfl
+#align list.zip_left'_cons_nil List.zipLeft'_cons_nil
+
+@[simp]
+theorem zipLeft'_cons_cons :
+    zipLeft' (a :: as) (b :: bs) =
+      let r := zipLeft' as bs
+      ((a, some b) :: r.fst, r.snd) :=
+  rfl
+#align list.zip_left'_cons_cons List.zipLeft'_cons_cons
+
+end ZipLeft'
+
+/-! ### zipRight' -/
+
+section ZipRight'
+
+variable (a : α) (as : List α) (b : β) (bs : List β)
+
+@[simp]
+theorem zipRight'_nil_left : zipRight' ([] : List α) bs = (bs.map fun b => (none, b), []) := by
+  cases bs <;> rfl
+#align list.zip_right'_nil_left List.zipRight'_nil_left
+
+@[simp]
+theorem zipRight'_nil_right : zipRight' as ([] : List β) = ([], as) :=
+  rfl
+#align list.zip_right'_nil_right List.zipRight'_nil_right
+
+-- Porting note: simp can prove this
+-- @[simp]
+theorem zipRight'_nil_cons :
+    zipRight' ([] : List α) (b :: bs) = ((none, b) :: bs.map fun b => (none, b), []) :=
+  rfl
+#align list.zip_right'_nil_cons List.zipRight'_nil_cons
+
+@[simp]
+theorem zipRight'_cons_cons :
+    zipRight' (a :: as) (b :: bs) =
+      let r := zipRight' as bs
+      ((some a, b) :: r.fst, r.snd) :=
+  rfl
+#align list.zip_right'_cons_cons List.zipRight'_cons_cons
+
+end ZipRight'
+
+/-! ### map₂Left -/
+
+section Map₂Left
+
+variable (f : α → Option β → γ) (as : List α)
+
+-- The definitional equalities for `map₂Left` can already be used by the
+-- simplifier because `map₂Left` is marked `@[simp]`.
+@[simp]
+theorem map₂Left_nil_right : map₂Left f as [] = as.map fun a => f a none := by cases as <;> rfl
+#align list.map₂_left_nil_right List.map₂Left_nil_right
+
+theorem map₂Left_eq_map₂Left' : ∀ as bs, map₂Left f as bs = (map₂Left' f as bs).fst
+  | [], _ => by simp
+  | a :: as, [] => by simp
+  | a :: as, b :: bs => by simp [map₂Left_eq_map₂Left']
+#align list.map₂_left_eq_map₂_left' List.map₂Left_eq_map₂Left'
+
+theorem map₂Left_eq_zipWith :
+    ∀ as bs, length as ≤ length bs → map₂Left f as bs = zipWith (fun a b => f a (some b)) as bs
+  | [], [], _ => by simp
+  | [], _ :: _, _ => by simp
+  | a :: as, [], h => by
+    simp at h
+  | a :: as, b :: bs, h => by
+    simp [Nat.succ_le_succ_iff] at h
+    simp [h, map₂Left_eq_zipWith]
+#align list.map₂_left_eq_map₂ List.map₂Left_eq_zipWith
+
+end Map₂Left
+
+/-! ### map₂Right -/
+
+section Map₂Right
+
+variable (f : Option α → β → γ) (a : α) (as : List α) (b : β) (bs : List β)
+
+@[simp]
+theorem map₂Right_nil_left : map₂Right f [] bs = bs.map (f none) := by cases bs <;> rfl
+#align list.mapmap₂Right₂_right_nil_left List.map₂Right_nil_left
+
+@[simp]
+theorem map₂Right_nil_right : map₂Right f as [] = [] :=
+  rfl
+#align list.map₂_right_nil_right List.map₂Right_nil_right
+
+-- Porting note: simp can prove this
+-- @[simp]
+theorem map₂Right_nil_cons : map₂Right f [] (b :: bs) = f none b :: bs.map (f none) :=
+  rfl
+#align list.map₂_right_nil_cons List.map₂Right_nil_cons
+
+@[simp]
+theorem map₂Right_cons_cons :
+    map₂Right f (a :: as) (b :: bs) = f (some a) b :: map₂Right f as bs :=
+  rfl
+#align list.map₂_right_cons_cons List.map₂Right_cons_cons
+
+theorem map₂Right_eq_map₂Right' : map₂Right f as bs = (map₂Right' f as bs).fst := by
+  simp only [map₂Right, map₂Right', map₂Left_eq_map₂Left']
+#align list.map₂_right_eq_map₂_right' List.map₂Right_eq_map₂Right'
+
+theorem map₂Right_eq_zipWith (h : length bs ≤ length as) :
+    map₂Right f as bs = zipWith (fun a b => f (some a) b) as bs := by
+  have : (fun a b => flip f a (some b)) = flip fun a b => f (some a) b := rfl
+  simp only [map₂Right, map₂Left_eq_zipWith, zipWith_flip, *]
+#align list.map₂_right_eq_map₂ List.map₂Right_eq_zipWith
+
+end Map₂Right
+
+/-! ### zipLeft -/
+
+section ZipLeft
+
+variable (a : α) (as : List α) (b : β) (bs : List β)
+
+@[simp]
+theorem zipLeft_nil_right : zipLeft as ([] : List β) = as.map fun a => (a, none) := by
+  cases as <;> rfl
+#align list.zip_left_nil_right List.zipLeft_nil_right
+
+@[simp]
+theorem zipLeft_nil_left : zipLeft ([] : List α) bs = [] :=
+  rfl
+#align list.zip_left_nil_left List.zipLeft_nil_left
+
+-- Porting note: simp can prove this
+-- @[simp]
+theorem zipLeft_cons_nil :
+    zipLeft (a :: as) ([] : List β) = (a, none) :: as.map fun a => (a, none) :=
+  rfl
+#align list.zip_left_cons_nil List.zipLeft_cons_nil
+
+@[simp]
+theorem zipLeft_cons_cons : zipLeft (a :: as) (b :: bs) = (a, some b) :: zipLeft as bs :=
+  rfl
+#align list.zip_left_cons_cons List.zipLeft_cons_cons
+
+-- Porting note: arguments explicit for recursion
+theorem zipLeft_eq_zipLeft' (as : List α) (bs : List β) : zipLeft as bs = (zipLeft' as bs).fst := by
+  rw [zipLeft, zipLeft']
+  cases as with
+  | nil => rfl
+  | cons _ atl =>
+    cases bs with
+    | nil => rfl
+    | cons _ btl => rw [zipWithLeft, zipWithLeft', cons_inj]; exact @zipLeft_eq_zipLeft' atl btl
+#align list.zip_left_eq_zip_left' List.zipLeft_eq_zipLeft'
+
+end ZipLeft
+
+/-! ### zipRight -/
+
+section ZipRight
+
+variable (a : α) (as : List α) (b : β) (bs : List β)
+
+@[simp]
+theorem zipRight_nil_left : zipRight ([] : List α) bs = bs.map fun b => (none, b) := by
+  cases bs <;> rfl
+#align list.zip_right_nil_left List.zipRight_nil_left
+
+@[simp]
+theorem zipRight_nil_right : zipRight as ([] : List β) = [] :=
+  rfl
+#align list.zip_right_nil_right List.zipRight_nil_right
+
+-- Porting note: simp can prove this
+-- @[simp]
+theorem zipRight_nil_cons :
+    zipRight ([] : List α) (b :: bs) = (none, b) :: bs.map fun b => (none, b) :=
+  rfl
+#align list.zip_right_nil_cons List.zipRight_nil_cons
+
+@[simp]
+theorem zipRight_cons_cons : zipRight (a :: as) (b :: bs) = (some a, b) :: zipRight as bs :=
+  rfl
+#align list.zip_right_cons_cons List.zipRight_cons_cons
+
+theorem zipRight_eq_zipRight' : zipRight as bs = (zipRight' as bs).fst := by
+  induction as generalizing bs <;> cases bs <;> simp [*]
+#align list.zip_right_eq_zip_right' List.zipRight_eq_zipRight'
+
+end ZipRight
+
+/-! ### toChunks -/
+
+-- Porting note:
+-- The definition of `toChunks` has changed substantially from Lean 3.
+-- The theorems about `toChunks` are not used anywhere in mathlib, anyways.
+-- TODO: Prove these theorems for the new definitions.
+
+#noalign list.to_chunks_nil
+#noalign list.to_chunks_aux_eq
+#noalign list.to_chunks_eq_cons'
+#noalign list.to_chunks_eq_cons
+#noalign list.to_chunks_aux_join
+#noalign list.to_chunks_join
+#noalign list.to_chunks_length_le
+
+/-! ### all₂ -/
+
+section All₂
+
+variable {p q : α → Prop} {l : List α}
+
+@[simp]
+theorem all₂_cons (p : α → Prop) (x : α) : ∀ l : List α, All₂ p (x :: l) ↔ p x ∧ All₂ p l
+  | [] => (and_true_iff _).symm
+  | _ :: _ => Iff.rfl
+#align list.all₂_cons List.all₂_cons
+
+theorem all₂_iff_forall : ∀ {l : List α}, All₂ p l ↔ ∀ x ∈ l, p x
+  | [] => (iff_true_intro <| forall_mem_nil _).symm
+  | x :: l => by rw [forall_mem_cons, all₂_cons, all₂_iff_forall]
+#align list.all₂_iff_forall List.all₂_iff_forall
+
+theorem All₂.imp (h : ∀ x, p x → q x) : ∀ {l : List α}, All₂ p l → All₂ q l
+  | [] => id
+  | x :: l => by simp; rw [←and_imp]; exact And.imp (h x) (All₂.imp h)
+#align list.all₂.imp List.All₂.imp
+
+@[simp]
+theorem all₂_map_iff {p : β → Prop} (f : α → β) : All₂ p (l.map f) ↔ All₂ (p ∘ f) l := by
+  induction l <;> simp [*]
+#align list.all₂_map_iff List.all₂_map_iff
+
+instance (p : α → Prop) [DecidablePred p] : DecidablePred (All₂ p) := fun _ =>
+  decidable_of_iff' _ all₂_iff_forall
+
+end All₂
+
+/-! ### Retroattributes
+
+The list definitions happen earlier than `to_additive`, so here we tag the few multiplicative
+definitions that couldn't be tagged earlier.
+-/
+
+attribute [to_additive] List.prod -- `list.sum`
+attribute [to_additive] alternatingProd -- `list.alternatingSum`
+
+/-! ### Miscellaneous lemmas -/
+
+theorem getLast_reverse {l : List α} (hl : l.reverse ≠ [])
+    (hl' : 0 < l.length := (by
+      contrapose! hl
+      simpa [length_eq_zero] using hl)) :
+    l.reverse.getLast hl = l.get ⟨0, hl'⟩ := by
+  rw [getLast_eq_get, get_reverse']
+  · simp
+  · simpa using hl'
+#align list.last_reverse List.getLast_reverse
+
+theorem ilast'_mem : ∀ a l, @ilast' α a l ∈ a :: l
+  | a, [] => by simp [ilast']
+  | a, b :: l => by rw [mem_cons]; exact Or.inr (ilast'_mem b l)
+#align list.ilast'_mem List.ilast'_mem
+
+@[simp]
+theorem get_attach (L : List α) (i) :
+    (L.attach.get i).1 = L.get ⟨i, length_attach L ▸ i.2⟩ :=
+  calc
+    (L.attach.get i).1 = (L.attach.map Subtype.val).get ⟨i, by simpa using i.2⟩ :=
+      by rw [get_map]
+    _ = L.get { val := i, isLt := _ } := by congr 2 <;> simp
+
+@[simp, deprecated get_attach]
+theorem nthLe_attach (L : List α) (i) (H : i < L.attach.length) :
+    (L.attach.nthLe i H).1 = L.nthLe i (length_attach L ▸ H) := get_attach ..
+#align list.nth_le_attach List.nthLe_attach
+
+@[simp 1100]
+theorem mem_map_swap (x : α) (y : β) (xs : List (α × β)) :
+    (y, x) ∈ map Prod.swap xs ↔ (x, y) ∈ xs := by
+  induction' xs with x xs xs_ih
+  · simp only [not_mem_nil, map_nil]
+  · cases' x with a b
+    simp only [mem_cons, Prod.mk.inj_iff, map, Prod.swap_prod_mk, Prod.exists, xs_ih, and_comm]
+#align list.mem_map_swap List.mem_map_swap
+
+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]
+#align list.slice_eq List.dropSlice_eq
+
+theorem sizeOf_dropSlice_lt [SizeOf α] (i j : ℕ) (hj : 0 < j) (xs : List α) (hi : i < xs.length) :
+    SizeOf.sizeOf (List.dropSlice i j xs) < SizeOf.sizeOf xs := by
+  induction xs generalizing i j hj with
+  | nil => cases hi
+  | cons x xs xs_ih =>
+    cases i <;> simp only [List.dropSlice]
+    · cases j with
+      | zero => contradiction
+      | succ n =>
+        dsimp only [drop]; apply @lt_of_le_of_lt _ _ _ (sizeOf xs)
+        induction xs generalizing n with
+        | nil => rw [drop_nil]
+        | cons _ xs_tl =>
+          cases n
+          · simp
+          · simp [drop]
+            rw [←Nat.zero_add (sizeOf (drop _ xs_tl))]
+            exact Nat.add_le_add (Nat.zero_le _) (drop_sizeOf_le xs_tl _)
+        · simp
+    · simp
+      apply xs_ih _ j hj
+      apply lt_of_succ_lt_succ hi
+#align list.sizeof_slice_lt List.sizeOf_dropSlice_lt
+
+/-! ### getD and getI -/
+
+section getD
+
+variable (l : List α) (x : α) (xs : List α) (d : α) (n : ℕ)
+
+@[simp]
+theorem getD_nil : getD [] n d = d :=
+  rfl
+#align list.nthd_nil List.getD_nilₓ -- argument order
+
+@[simp]
+theorem getD_cons_zero : getD (x :: xs) 0 d = x :=
+  rfl
+#align list.nthd_cons_zero List.getD_cons_zeroₓ -- argument order
+
+@[simp]
+theorem getD_cons_succ : getD (x :: xs) (n + 1) d = getD xs n d :=
+  rfl
+#align list.nthd_cons_succ List.getD_cons_succₓ -- argument order
+
+theorem getD_eq_get {n : ℕ} (hn : n < l.length) : l.getD n d = l.get ⟨n, hn⟩ := by
+  induction' l with hd tl IH generalizing n
+  · exact absurd hn (not_lt_of_ge (Nat.zero_le _))
+  · cases n
+    · exact getD_cons_zero _ _ _
+    · exact IH _
+
+set_option linter.deprecated false in
+@[deprecated getD_eq_get]
+theorem getD_eq_nthLe {n : ℕ} (hn : n < l.length) : l.getD n d = l.nthLe n hn :=
+  getD_eq_get ..
+#align list.nthd_eq_nth_le List.getD_eq_nthLeₓ -- argument order
+
+theorem getD_eq_default {n : ℕ} (hn : l.length ≤ n) : l.getD n d = d := by
+  induction' l with hd tl IH generalizing n
+  · exact getD_nil _ _
+  · cases n
+    · refine' absurd (Nat.zero_lt_succ _) (not_lt_of_ge hn)
+    · exact IH (Nat.le_of_succ_le_succ hn)
+#align list.nthd_eq_default List.getD_eq_defaultₓ -- argument order
+
+/-- An empty list can always be decidably checked for the presence of an element.
+Not an instance because it would clash with `decidable_eq α`. -/
+def decidableGetDNilNe {α} (a : α) : DecidablePred fun i : ℕ => getD ([] : List α) i a ≠ a :=
+  fun _ => isFalse fun H => H (getD_nil _ _)
+#align list.decidable_nthd_nil_ne List.decidableGetDNilNeₓ -- argument order
+
+@[simp]
+theorem getD_singleton_default_eq (n : ℕ) : [d].getD n d = d := by cases n <;> simp
+#align list.nthd_singleton_default_eq List.getD_singleton_default_eqₓ -- argument order
+
+@[simp]
+theorem getD_replicate_default_eq (r n : ℕ) : (replicate r d).getD n d = d := by
+  induction' r with r IH generalizing n
+  · simp
+  · cases n <;> simp [IH]
+#align list.nthd_repeat_default_eq List.getD_replicate_default_eqₓ -- argument order
+
+theorem getD_append (l l' : List α) (d : α) (n : ℕ) (h : n < l.length)
+    (h' : n < (l ++ l').length := h.trans_le ((length_append l l').symm ▸ le_self_add)) :
+    (l ++ l').getD n d = l.getD n d := by
+  rw [getD_eq_get _ _ h', get_append _ h, getD_eq_get]
+#align list.nthd_append List.getD_appendₓ -- argument order
+
+theorem getD_append_right (l l' : List α) (d : α) (n : ℕ) (h : l.length ≤ n) :
+    (l ++ l').getD n d = l'.getD (n - l.length) d := by
+  cases' lt_or_le n (l ++l').length with h' h'
+  · rw [getD_eq_get (l ++ l') d h', get_append_right, getD_eq_get]
+    · rw [length_append] at h'
+      exact Nat.sub_lt_left_of_lt_add h h'
+    · exact not_lt_of_le h
+  · rw [getD_eq_default _ _ h', getD_eq_default]
+    rwa [le_tsub_iff_left h, ← length_append]
+#align list.nthd_append_right List.getD_append_rightₓ -- argument order
+
+theorem getD_eq_getD_get? (n : ℕ) : l.getD n d = (l.get? n).getD d := by
+  cases' lt_or_le n l.length with h h
+  · rw [getD_eq_get _ _ h, get?_eq_get h, Option.getD_some]
+  · rw [getD_eq_default _ _ h, get?_eq_none.mpr h, Option.getD_none]
+#align list.nthd_eq_get_or_else_nth List.getD_eq_getD_get?ₓ -- argument order
+
+end getD
+
+section getI
+
+variable [Inhabited α] (l : List α) (x : α) (xs : List α) (n : ℕ)
+
+@[simp]
+theorem getI_nil : getI ([] : List α) n = default :=
+  rfl
+#align list.inth_nil List.getI_nil
+
+@[simp]
+theorem getI_cons_zero : getI (x :: xs) 0 = x :=
+  rfl
+#align list.inth_cons_zero List.getI_cons_zero
+
+@[simp]
+theorem getI_cons_succ : getI (x :: xs) (n + 1) = getI xs n :=
+  rfl
+#align list.inth_cons_succ List.getI_cons_succ
+
+theorem getI_eq_get {n : ℕ} (hn : n < l.length) : l.getI n = l.get ⟨n, hn⟩ :=
+  getD_eq_get ..
+
+@[deprecated getI_eq_get]
+theorem getI_eq_nthLe {n : ℕ} (hn : n < l.length) : l.getI n = l.nthLe n hn :=
+  getI_eq_get ..
+#align list.inth_eq_nth_le List.getI_eq_nthLe
+
+theorem getI_eq_default {n : ℕ} (hn : l.length ≤ n) : l.getI n = default :=
+  getD_eq_default _ _ hn
+#align list.inth_eq_default List.getI_eq_default
+
+theorem getD_default_eq_getI {n : ℕ} : l.getD n default = l.getI n :=
+  rfl
+#align list.nthd_default_eq_inth List.getD_default_eq_getIₓ -- new argument `n`
+
+theorem getI_append (l l' : List α) (n : ℕ) (h : n < l.length)
+    (h' : n < (l ++ l').length := h.trans_le ((length_append l l').symm ▸ le_self_add)) :
+    (l ++ l').getI n = l.getI n :=
+  getD_append _ _ _ _ h h'
+#align list.inth_append List.getI_append
+
+theorem getI_append_right (l l' : List α) (n : ℕ) (h : l.length ≤ n) :
+    (l ++ l').getI n = l'.getI (n - l.length) :=
+  getD_append_right _ _ _ _ h
+#align list.inth_append_right List.getI_append_right
+
+theorem getI_eq_iget_get? (n : ℕ) : l.getI n = (l.get? n).iget := by
+  rw [← getD_default_eq_getI, getD_eq_getD_get?, Option.getD_default_eq_iget]
+#align list.inth_eq_iget_nth List.getI_eq_iget_get?
+
+theorem getI_zero_eq_head! : l.getI 0 = l.head! := by cases l <;> rfl
+#align list.inth_zero_eq_head List.getI_zero_eq_head!
+
+end getI
+
+end List

Dependencies 1 + 71

72 files ported (98.6%)
37015 lines ported (99.8%)
Show graph

The unported dependencies are