data.list.rangeMathlib.Data.List.Range

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

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(last sync)

Changes in mathlib3port

mathlib3
mathlib3port
Diff
@@ -3,8 +3,8 @@ Copyright (c) 2018 Mario Carneiro. All rights reserved.
 Released under Apache 2.0 license as described in the file LICENSE.
 Authors: Mario Carneiro, Kenny Lau, Scott Morrison
 -/
-import Mathbin.Data.List.Chain
-import Mathbin.Data.List.Zip
+import Data.List.Chain
+import Data.List.Zip
 
 #align_import data.list.range from "leanprover-community/mathlib"@"be24ec5de6701447e5df5ca75400ffee19d65659"
 
Diff
@@ -2,15 +2,12 @@
 Copyright (c) 2018 Mario Carneiro. All rights reserved.
 Released under Apache 2.0 license as described in the file LICENSE.
 Authors: Mario Carneiro, Kenny Lau, Scott Morrison
-
-! This file was ported from Lean 3 source module data.list.range
-! leanprover-community/mathlib commit be24ec5de6701447e5df5ca75400ffee19d65659
-! Please do not edit these lines, except to modify the commit id
-! if you have ported upstream changes.
 -/
 import Mathbin.Data.List.Chain
 import Mathbin.Data.List.Zip
 
+#align_import data.list.range from "leanprover-community/mathlib"@"be24ec5de6701447e5df5ca75400ffee19d65659"
+
 /-!
 # Ranges of naturals as lists
 
Diff
@@ -34,16 +34,21 @@ namespace List
 
 variable {α : Type u}
 
+#print List.length_range' /-
 @[simp]
 theorem length_range' : ∀ s n : ℕ, length (range' s n) = n
   | s, 0 => rfl
   | s, n + 1 => congr_arg succ (length_range' _ _)
 #align list.length_range' List.length_range'
+-/
 
+#print List.range'_eq_nil /-
 @[simp]
 theorem range'_eq_nil {s n : ℕ} : range' s n = [] ↔ n = 0 := by rw [← length_eq_zero, length_range']
 #align list.range'_eq_nil List.range'_eq_nil
+-/
 
+#print List.mem_range'_1 /-
 @[simp]
 theorem mem_range'_1 {m : ℕ} : ∀ {s n : ℕ}, m ∈ range' s n ↔ s ≤ m ∧ m < s + n
   | s, 0 => (false_iff_iff _).2 fun ⟨H1, H2⟩ => not_le_of_lt H2 H1
@@ -54,12 +59,16 @@ theorem mem_range'_1 {m : ℕ} : ∀ {s n : ℕ}, m ∈ range' s n ↔ s ≤ m 
     (mem_cons _ _ _).trans <| by
       simp only [mem_range', or_and_left, or_iff_right_of_imp this, l, add_right_comm] <;> rfl
 #align list.mem_range' List.mem_range'_1
+-/
 
+#print List.map_add_range' /-
 theorem map_add_range' (a) : ∀ s n : ℕ, map ((· + ·) a) (range' s n) = range' (a + s) n
   | s, 0 => rfl
   | s, n + 1 => congr_arg (cons _) (map_add_range' (s + 1) n)
 #align list.map_add_range' List.map_add_range'
+-/
 
+#print List.map_sub_range' /-
 theorem map_sub_range' (a) :
     ∀ (s n : ℕ) (h : a ≤ s), map (fun x => x - a) (range' s n) = range' (s - a) n
   | s, 0, _ => rfl
@@ -69,25 +78,35 @@ theorem map_sub_range' (a) :
     rw [Nat.succ_sub h]
     rfl
 #align list.map_sub_range' List.map_sub_range'
+-/
 
+#print List.chain_succ_range' /-
 theorem chain_succ_range' : ∀ s n : ℕ, Chain (fun a b => b = succ a) s (range' (s + 1) n)
   | s, 0 => Chain.nil
   | s, n + 1 => (chain_succ_range' (s + 1) n).cons rfl
 #align list.chain_succ_range' List.chain_succ_range'
+-/
 
+#print List.chain_lt_range' /-
 theorem chain_lt_range' (s n : ℕ) : Chain (· < ·) s (range' (s + 1) n) :=
   (chain_succ_range' s n).imp fun a b e => e.symm ▸ lt_succ_self _
 #align list.chain_lt_range' List.chain_lt_range'
+-/
 
+#print List.pairwise_lt_range' /-
 theorem pairwise_lt_range' : ∀ s n : ℕ, Pairwise (· < ·) (range' s n)
   | s, 0 => Pairwise.nil
   | s, n + 1 => chain_iff_pairwise.1 (chain_lt_range' s n)
 #align list.pairwise_lt_range' List.pairwise_lt_range'
+-/
 
+#print List.nodup_range' /-
 theorem nodup_range' (s n : ℕ) : Nodup (range' s n) :=
   (pairwise_lt_range' s n).imp fun a b => ne_of_lt
 #align list.nodup_range' List.nodup_range'
+-/
 
+#print List.range'_append /-
 @[simp]
 theorem range'_append : ∀ s m n : ℕ, range' s m ++ range' (s + m) n = range' s (n + m)
   | s, 0, n => rfl
@@ -95,12 +114,16 @@ theorem range'_append : ∀ s m n : ℕ, range' s m ++ range' (s + m) n = range'
     show s :: (range' (s + 1) m ++ range' (s + m + 1) n) = s :: range' (s + 1) (n + m) by
       rw [add_right_comm, range'_append]
 #align list.range'_append List.range'_append
+-/
 
+#print List.range'_sublist_right /-
 theorem range'_sublist_right {s m n : ℕ} : range' s m <+ range' s n ↔ m ≤ n :=
   ⟨fun h => by simpa only [length_range'] using h.length_le, fun h => by
     rw [← tsub_add_cancel_of_le h, ← range'_append] <;> apply sublist_append_left⟩
 #align list.range'_sublist_right List.range'_sublist_right
+-/
 
+#print List.range'_subset_right /-
 theorem range'_subset_right {s m n : ℕ} : range' s m ⊆ range' s n ↔ m ≤ n :=
   ⟨fun h =>
     le_of_not_lt fun hn =>
@@ -108,32 +131,43 @@ theorem range'_subset_right {s m n : ℕ} : range' s m ⊆ range' s n ↔ m ≤
         (mem_range'_1.1 <| h <| mem_range'_1.2 ⟨Nat.le_add_right _ _, Nat.add_lt_add_left hn s⟩).2,
     fun h => (range'_sublist_right.2 h).Subset⟩
 #align list.range'_subset_right List.range'_subset_right
+-/
 
+#print List.get?_range' /-
 theorem get?_range' : ∀ (s) {m n : ℕ}, m < n → get? (range' s n) m = some (s + m)
   | s, 0, n + 1, _ => rfl
   | s, m + 1, n + 1, h =>
     (nth_range' (s + 1) (lt_of_add_lt_add_right h)).trans <| by rw [add_right_comm] <;> rfl
 #align list.nth_range' List.get?_range'
+-/
 
+#print List.nthLe_range'_1 /-
 @[simp]
 theorem nthLe_range'_1 {n m} (i) (H : i < (range' n m).length) : nthLe (range' n m) i H = n + i :=
   Option.some.inj <| by rw [← nth_le_nth _, nth_range' _ (by simpa using H)]
 #align list.nth_le_range' List.nthLe_range'_1
+-/
 
+#print List.range'_concat /-
 theorem range'_concat (s n : ℕ) : range' s (n + 1) = range' s n ++ [s + n] := by
   rw [add_comm n 1] <;> exact (range'_append s n 1).symm
 #align list.range'_concat List.range'_concat
+-/
 
+#print List.range_loop_range' /-
 theorem range_loop_range' : ∀ s n : ℕ, List.range.loop s (range' s n) = range' 0 (n + s)
   | 0, n => rfl
   | s + 1, n => by
     rw [show n + (s + 1) = n + 1 + s from add_right_comm n s 1] <;>
       exact range_core_range' s (n + 1)
 #align list.range_core_range' List.range_loop_range'
+-/
 
+#print List.range_eq_range' /-
 theorem range_eq_range' (n : ℕ) : range n = range' 0 n :=
   (range_loop_range' n 0).trans <| by rw [zero_add]
 #align list.range_eq_range' List.range_eq_range'
+-/
 
 #print List.range_succ_eq_map /-
 theorem range_succ_eq_map (n : ℕ) : range (n + 1) = 0 :: map succ (range n) := by
@@ -142,9 +176,11 @@ theorem range_succ_eq_map (n : ℕ) : range (n + 1) = 0 :: map succ (range n) :=
 #align list.range_succ_eq_map List.range_succ_eq_map
 -/
 
+#print List.range'_eq_map_range /-
 theorem range'_eq_map_range (s n : ℕ) : range' s n = map ((· + ·) s) (range n) := by
   rw [range_eq_range', map_add_range'] <;> rfl
 #align list.range'_eq_map_range List.range'_eq_map_range
+-/
 
 #print List.length_range /-
 @[simp]
@@ -258,11 +294,13 @@ theorem range_add (a : ℕ) : ∀ b, range (a + b) = range a ++ (range b).map fu
 #align list.range_add List.range_add
 -/
 
+#print List.iota_eq_reverse_range' /-
 theorem iota_eq_reverse_range' : ∀ n : ℕ, iota n = reverse (range' 1 n)
   | 0 => rfl
   | n + 1 => by
     simp only [iota, range'_concat, iota_eq_reverse_range' n, reverse_append, add_comm] <;> rfl
 #align list.iota_eq_reverse_range' List.iota_eq_reverse_range'
+-/
 
 #print List.length_iota /-
 @[simp]
@@ -289,6 +327,7 @@ theorem mem_iota {m n : ℕ} : m ∈ iota n ↔ 1 ≤ m ∧ m ≤ n := by
 #align list.mem_iota List.mem_iota
 -/
 
+#print List.reverse_range' /-
 theorem reverse_range' : ∀ s n : ℕ, reverse (range' s n) = map (fun i => s + n - 1 - i) (range n)
   | s, 0 => rfl
   | s, n + 1 => by
@@ -297,6 +336,7 @@ theorem reverse_range' : ∀ s n : ℕ, reverse (range' s n) = map (fun i => s +
         show a - 1 - i = a - succ i from pred_sub _ _, reverse_singleton, map_cons, tsub_zero,
         cons_append, nil_append, eq_self_iff_true, true_and_iff, map_map] using reverse_range' s n
 #align list.reverse_range' List.reverse_range'
+-/
 
 #print List.finRange /-
 /-- All elements of `fin n`, from `0` to `n-1`. The corresponding finset is `finset.univ`. -/
@@ -339,13 +379,16 @@ theorem finRange_eq_nil {n : ℕ} : finRange n = [] ↔ n = 0 := by
 #align list.fin_range_eq_nil List.finRange_eq_nil
 -/
 
+#print List.prod_range_succ /-
 @[to_additive]
 theorem prod_range_succ {α : Type u} [Monoid α] (f : ℕ → α) (n : ℕ) :
     ((range n.succ).map f).Prod = ((range n).map f).Prod * f n := by
   rw [range_succ, map_append, map_singleton, prod_append, prod_cons, prod_nil, mul_one]
 #align list.prod_range_succ List.prod_range_succ
 #align list.sum_range_succ List.sum_range_succ
+-/
 
+#print List.prod_range_succ' /-
 /-- A variant of `prod_range_succ` which pulls off the first
   term in the product rather than the last.-/
 @[to_additive
@@ -356,12 +399,15 @@ theorem prod_range_succ' {α : Type u} [Monoid α] (f : ℕ → α) (n : ℕ) :
     rw [List.prod_range_succ, hd, mul_assoc, ← List.prod_range_succ]
 #align list.prod_range_succ' List.prod_range_succ'
 #align list.sum_range_succ' List.sum_range_succ'
+-/
 
+#print List.enumFrom_map_fst /-
 @[simp]
 theorem enumFrom_map_fst : ∀ (n) (l : List α), map Prod.fst (enumFrom n l) = range' n l.length
   | n, [] => rfl
   | n, a :: l => congr_arg (cons _) (enum_from_map_fst _ _)
 #align list.enum_from_map_fst List.enumFrom_map_fst
+-/
 
 #print List.enum_map_fst /-
 @[simp]
@@ -383,15 +429,19 @@ theorem unzip_enum_eq_prod (l : List α) : l.enum.unzip = (range l.length, l) :=
 #align list.unzip_enum_eq_prod List.unzip_enum_eq_prod
 -/
 
+#print List.enumFrom_eq_zip_range' /-
 theorem enumFrom_eq_zip_range' (l : List α) {n : ℕ} : l.enumFrom n = (range' n l.length).zip l :=
   zip_of_prod (enumFrom_map_fst _ _) (enumFrom_map_snd _ _)
 #align list.enum_from_eq_zip_range' List.enumFrom_eq_zip_range'
+-/
 
+#print List.unzip_enumFrom_eq_prod /-
 @[simp]
 theorem unzip_enumFrom_eq_prod (l : List α) {n : ℕ} :
     (l.enumFrom n).unzip = (range' n l.length, l) := by
   simp only [enum_from_eq_zip_range', unzip_zip, length_range']
 #align list.unzip_enum_from_eq_prod List.unzip_enumFrom_eq_prod
+-/
 
 #print List.nthLe_range /-
 @[simp]
Diff
@@ -45,7 +45,7 @@ theorem range'_eq_nil {s n : ℕ} : range' s n = [] ↔ n = 0 := by rw [← leng
 #align list.range'_eq_nil List.range'_eq_nil
 
 @[simp]
-theorem mem_range' {m : ℕ} : ∀ {s n : ℕ}, m ∈ range' s n ↔ s ≤ m ∧ m < s + n
+theorem mem_range'_1 {m : ℕ} : ∀ {s n : ℕ}, m ∈ range' s n ↔ s ≤ m ∧ m < s + n
   | s, 0 => (false_iff_iff _).2 fun ⟨H1, H2⟩ => not_le_of_lt H2 H1
   | s, succ n =>
     have : m = s → m < s + n + 1 := fun e => e ▸ lt_succ_of_le (Nat.le_add_right _ _)
@@ -53,7 +53,7 @@ theorem mem_range' {m : ℕ} : ∀ {s n : ℕ}, m ∈ range' s n ↔ s ≤ m ∧
       simpa only [eq_comm] using (@Decidable.le_iff_eq_or_lt _ _ _ s m).symm
     (mem_cons _ _ _).trans <| by
       simp only [mem_range', or_and_left, or_iff_right_of_imp this, l, add_right_comm] <;> rfl
-#align list.mem_range' List.mem_range'
+#align list.mem_range' List.mem_range'_1
 
 theorem map_add_range' (a) : ∀ s n : ℕ, map ((· + ·) a) (range' s n) = range' (a + s) n
   | s, 0 => rfl
@@ -105,7 +105,7 @@ theorem range'_subset_right {s m n : ℕ} : range' s m ⊆ range' s n ↔ m ≤
   ⟨fun h =>
     le_of_not_lt fun hn =>
       lt_irrefl (s + n) <|
-        (mem_range'.1 <| h <| mem_range'.2 ⟨Nat.le_add_right _ _, Nat.add_lt_add_left hn s⟩).2,
+        (mem_range'_1.1 <| h <| mem_range'_1.2 ⟨Nat.le_add_right _ _, Nat.add_lt_add_left hn s⟩).2,
     fun h => (range'_sublist_right.2 h).Subset⟩
 #align list.range'_subset_right List.range'_subset_right
 
@@ -116,9 +116,9 @@ theorem get?_range' : ∀ (s) {m n : ℕ}, m < n → get? (range' s n) m = some
 #align list.nth_range' List.get?_range'
 
 @[simp]
-theorem nthLe_range' {n m} (i) (H : i < (range' n m).length) : nthLe (range' n m) i H = n + i :=
+theorem nthLe_range'_1 {n m} (i) (H : i < (range' n m).length) : nthLe (range' n m) i H = n + i :=
   Option.some.inj <| by rw [← nth_le_nth _, nth_range' _ (by simpa using H)]
-#align list.nth_le_range' List.nthLe_range'
+#align list.nth_le_range' List.nthLe_range'_1
 
 theorem range'_concat (s n : ℕ) : range' s (n + 1) = range' s n ++ [s + n] := by
   rw [add_comm n 1] <;> exact (range'_append s n 1).symm
@@ -358,10 +358,10 @@ theorem prod_range_succ' {α : Type u} [Monoid α] (f : ℕ → α) (n : ℕ) :
 #align list.sum_range_succ' List.sum_range_succ'
 
 @[simp]
-theorem enum_from_map_fst : ∀ (n) (l : List α), map Prod.fst (enumFrom n l) = range' n l.length
+theorem enumFrom_map_fst : ∀ (n) (l : List α), map Prod.fst (enumFrom n l) = range' n l.length
   | n, [] => rfl
   | n, a :: l => congr_arg (cons _) (enum_from_map_fst _ _)
-#align list.enum_from_map_fst List.enum_from_map_fst
+#align list.enum_from_map_fst List.enumFrom_map_fst
 
 #print List.enum_map_fst /-
 @[simp]
@@ -383,15 +383,15 @@ theorem unzip_enum_eq_prod (l : List α) : l.enum.unzip = (range l.length, l) :=
 #align list.unzip_enum_eq_prod List.unzip_enum_eq_prod
 -/
 
-theorem enum_from_eq_zip_range' (l : List α) {n : ℕ} : l.enumFrom n = (range' n l.length).zip l :=
-  zip_of_prod (enum_from_map_fst _ _) (enumFrom_map_snd _ _)
-#align list.enum_from_eq_zip_range' List.enum_from_eq_zip_range'
+theorem enumFrom_eq_zip_range' (l : List α) {n : ℕ} : l.enumFrom n = (range' n l.length).zip l :=
+  zip_of_prod (enumFrom_map_fst _ _) (enumFrom_map_snd _ _)
+#align list.enum_from_eq_zip_range' List.enumFrom_eq_zip_range'
 
 @[simp]
-theorem unzip_enum_from_eq_prod (l : List α) {n : ℕ} :
+theorem unzip_enumFrom_eq_prod (l : List α) {n : ℕ} :
     (l.enumFrom n).unzip = (range' n l.length, l) := by
   simp only [enum_from_eq_zip_range', unzip_zip, length_range']
-#align list.unzip_enum_from_eq_prod List.unzip_enum_from_eq_prod
+#align list.unzip_enum_from_eq_prod List.unzip_enumFrom_eq_prod
 
 #print List.nthLe_range /-
 @[simp]
Diff
@@ -34,34 +34,16 @@ namespace List
 
 variable {α : Type u}
 
-/- warning: list.length_range' -> List.length_range' is a dubious translation:
-lean 3 declaration is
-  forall (s : Nat) (n : Nat), Eq.{1} Nat (List.length.{0} Nat (List.range' s n)) n
-but is expected to have type
-  forall (s : Nat) (n : Nat), Eq.{1} Nat (List.length.{0} Nat (List.range' s n (OfNat.ofNat.{0} Nat 1 (instOfNatNat 1)))) n
-Case conversion may be inaccurate. Consider using '#align list.length_range' List.length_range'ₓ'. -/
 @[simp]
 theorem length_range' : ∀ s n : ℕ, length (range' s n) = n
   | s, 0 => rfl
   | s, n + 1 => congr_arg succ (length_range' _ _)
 #align list.length_range' List.length_range'
 
-/- warning: list.range'_eq_nil -> List.range'_eq_nil is a dubious translation:
-lean 3 declaration is
-  forall {s : Nat} {n : Nat}, Iff (Eq.{1} (List.{0} Nat) (List.range' s n) (List.nil.{0} Nat)) (Eq.{1} Nat n (OfNat.ofNat.{0} Nat 0 (OfNat.mk.{0} Nat 0 (Zero.zero.{0} Nat Nat.hasZero))))
-but is expected to have type
-  forall {s : Nat} {n : Nat}, Iff (Eq.{1} (List.{0} Nat) (List.range' s n (OfNat.ofNat.{0} Nat 1 (instOfNatNat 1))) (List.nil.{0} Nat)) (Eq.{1} Nat n (OfNat.ofNat.{0} Nat 0 (instOfNatNat 0)))
-Case conversion may be inaccurate. Consider using '#align list.range'_eq_nil List.range'_eq_nilₓ'. -/
 @[simp]
 theorem range'_eq_nil {s n : ℕ} : range' s n = [] ↔ n = 0 := by rw [← length_eq_zero, length_range']
 #align list.range'_eq_nil List.range'_eq_nil
 
-/- warning: list.mem_range' -> List.mem_range' is a dubious translation:
-lean 3 declaration is
-  forall {m : Nat} {s : Nat} {n : Nat}, Iff (Membership.Mem.{0, 0} Nat (List.{0} Nat) (List.hasMem.{0} Nat) m (List.range' s n)) (And (LE.le.{0} Nat Nat.hasLe s m) (LT.lt.{0} Nat Nat.hasLt m (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat Nat.hasAdd) s n)))
-but is expected to have type
-  forall {m : Nat} {s : Nat} {n : Nat}, Iff (Membership.mem.{0, 0} Nat (List.{0} Nat) (List.instMembershipList.{0} Nat) m (List.range' s n (OfNat.ofNat.{0} Nat 1 (instOfNatNat 1)))) (And (LE.le.{0} Nat instLENat s m) (LT.lt.{0} Nat instLTNat m (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat instAddNat) s n)))
-Case conversion may be inaccurate. Consider using '#align list.mem_range' List.mem_range'ₓ'. -/
 @[simp]
 theorem mem_range' {m : ℕ} : ∀ {s n : ℕ}, m ∈ range' s n ↔ s ≤ m ∧ m < s + n
   | s, 0 => (false_iff_iff _).2 fun ⟨H1, H2⟩ => not_le_of_lt H2 H1
@@ -73,23 +55,11 @@ theorem mem_range' {m : ℕ} : ∀ {s n : ℕ}, m ∈ range' s n ↔ s ≤ m ∧
       simp only [mem_range', or_and_left, or_iff_right_of_imp this, l, add_right_comm] <;> rfl
 #align list.mem_range' List.mem_range'
 
-/- warning: list.map_add_range' -> List.map_add_range' is a dubious translation:
-lean 3 declaration is
-  forall (a : Nat) (s : Nat) (n : Nat), Eq.{1} (List.{0} Nat) (List.map.{0, 0} Nat Nat (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat Nat.hasAdd) a) (List.range' s n)) (List.range' (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat Nat.hasAdd) a s) n)
-but is expected to have type
-  forall (a : Nat) (s : Nat) (n : Nat), Eq.{1} (List.{0} Nat) (List.map.{0, 0} Nat Nat ((fun (x._@.Mathlib.Data.List.Range._hyg.391 : Nat) (x._@.Mathlib.Data.List.Range._hyg.393 : Nat) => HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat instAddNat) x._@.Mathlib.Data.List.Range._hyg.391 x._@.Mathlib.Data.List.Range._hyg.393) a) (List.range' s n (OfNat.ofNat.{0} Nat 1 (instOfNatNat 1)))) (List.range' (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat instAddNat) a s) n (OfNat.ofNat.{0} Nat 1 (instOfNatNat 1)))
-Case conversion may be inaccurate. Consider using '#align list.map_add_range' List.map_add_range'ₓ'. -/
 theorem map_add_range' (a) : ∀ s n : ℕ, map ((· + ·) a) (range' s n) = range' (a + s) n
   | s, 0 => rfl
   | s, n + 1 => congr_arg (cons _) (map_add_range' (s + 1) n)
 #align list.map_add_range' List.map_add_range'
 
-/- warning: list.map_sub_range' -> List.map_sub_range' is a dubious translation:
-lean 3 declaration is
-  forall (a : Nat) (s : Nat) (n : Nat), (LE.le.{0} Nat Nat.hasLe a s) -> (Eq.{1} (List.{0} Nat) (List.map.{0, 0} Nat Nat (fun (x : Nat) => HSub.hSub.{0, 0, 0} Nat Nat Nat (instHSub.{0} Nat Nat.hasSub) x a) (List.range' s n)) (List.range' (HSub.hSub.{0, 0, 0} Nat Nat Nat (instHSub.{0} Nat Nat.hasSub) s a) n))
-but is expected to have type
-  forall (a : Nat) (s : Nat) (n : Nat), (LE.le.{0} Nat instLENat a s) -> (Eq.{1} (List.{0} Nat) (List.map.{0, 0} Nat Nat (fun (x : Nat) => HSub.hSub.{0, 0, 0} Nat Nat Nat (instHSub.{0} Nat instSubNat) x a) (List.range' s n (OfNat.ofNat.{0} Nat 1 (instOfNatNat 1)))) (List.range' (HSub.hSub.{0, 0, 0} Nat Nat Nat (instHSub.{0} Nat instSubNat) s a) n (OfNat.ofNat.{0} Nat 1 (instOfNatNat 1))))
-Case conversion may be inaccurate. Consider using '#align list.map_sub_range' List.map_sub_range'ₓ'. -/
 theorem map_sub_range' (a) :
     ∀ (s n : ℕ) (h : a ≤ s), map (fun x => x - a) (range' s n) = range' (s - a) n
   | s, 0, _ => rfl
@@ -100,54 +70,24 @@ theorem map_sub_range' (a) :
     rfl
 #align list.map_sub_range' List.map_sub_range'
 
-/- warning: list.chain_succ_range' -> List.chain_succ_range' is a dubious translation:
-lean 3 declaration is
-  forall (s : Nat) (n : Nat), List.Chain.{0} Nat (fun (a : Nat) (b : Nat) => Eq.{1} Nat b (Nat.succ a)) s (List.range' (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat Nat.hasAdd) s (OfNat.ofNat.{0} Nat 1 (OfNat.mk.{0} Nat 1 (One.one.{0} Nat Nat.hasOne)))) n)
-but is expected to have type
-  forall (s : Nat) (n : Nat), List.Chain.{0} Nat (fun (a : Nat) (b : Nat) => Eq.{1} Nat b (Nat.succ a)) s (List.range' (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat instAddNat) s (OfNat.ofNat.{0} Nat 1 (instOfNatNat 1))) n (OfNat.ofNat.{0} Nat 1 (instOfNatNat 1)))
-Case conversion may be inaccurate. Consider using '#align list.chain_succ_range' List.chain_succ_range'ₓ'. -/
 theorem chain_succ_range' : ∀ s n : ℕ, Chain (fun a b => b = succ a) s (range' (s + 1) n)
   | s, 0 => Chain.nil
   | s, n + 1 => (chain_succ_range' (s + 1) n).cons rfl
 #align list.chain_succ_range' List.chain_succ_range'
 
-/- warning: list.chain_lt_range' -> List.chain_lt_range' is a dubious translation:
-lean 3 declaration is
-  forall (s : Nat) (n : Nat), List.Chain.{0} Nat (LT.lt.{0} Nat Nat.hasLt) s (List.range' (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat Nat.hasAdd) s (OfNat.ofNat.{0} Nat 1 (OfNat.mk.{0} Nat 1 (One.one.{0} Nat Nat.hasOne)))) n)
-but is expected to have type
-  forall (s : Nat) (n : Nat), List.Chain.{0} Nat (fun (x._@.Mathlib.Data.List.Range._hyg.791 : Nat) (x._@.Mathlib.Data.List.Range._hyg.793 : Nat) => LT.lt.{0} Nat instLTNat x._@.Mathlib.Data.List.Range._hyg.791 x._@.Mathlib.Data.List.Range._hyg.793) s (List.range' (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat instAddNat) s (OfNat.ofNat.{0} Nat 1 (instOfNatNat 1))) n (OfNat.ofNat.{0} Nat 1 (instOfNatNat 1)))
-Case conversion may be inaccurate. Consider using '#align list.chain_lt_range' List.chain_lt_range'ₓ'. -/
 theorem chain_lt_range' (s n : ℕ) : Chain (· < ·) s (range' (s + 1) n) :=
   (chain_succ_range' s n).imp fun a b e => e.symm ▸ lt_succ_self _
 #align list.chain_lt_range' List.chain_lt_range'
 
-/- warning: list.pairwise_lt_range' -> List.pairwise_lt_range' is a dubious translation:
-lean 3 declaration is
-  forall (s : Nat) (n : Nat), List.Pairwise.{0} Nat (LT.lt.{0} Nat Nat.hasLt) (List.range' s n)
-but is expected to have type
-  forall (s : Nat) (n : Nat), List.Pairwise.{0} Nat (fun (x._@.Mathlib.Data.List.Range._hyg.852 : Nat) (x._@.Mathlib.Data.List.Range._hyg.854 : Nat) => LT.lt.{0} Nat instLTNat x._@.Mathlib.Data.List.Range._hyg.852 x._@.Mathlib.Data.List.Range._hyg.854) (List.range' s n (OfNat.ofNat.{0} Nat 1 (instOfNatNat 1)))
-Case conversion may be inaccurate. Consider using '#align list.pairwise_lt_range' List.pairwise_lt_range'ₓ'. -/
 theorem pairwise_lt_range' : ∀ s n : ℕ, Pairwise (· < ·) (range' s n)
   | s, 0 => Pairwise.nil
   | s, n + 1 => chain_iff_pairwise.1 (chain_lt_range' s n)
 #align list.pairwise_lt_range' List.pairwise_lt_range'
 
-/- warning: list.nodup_range' -> List.nodup_range' is a dubious translation:
-lean 3 declaration is
-  forall (s : Nat) (n : Nat), List.Nodup.{0} Nat (List.range' s n)
-but is expected to have type
-  forall (s : Nat) (n : Nat), List.Nodup.{0} Nat (List.range' s n (OfNat.ofNat.{0} Nat 1 (instOfNatNat 1)))
-Case conversion may be inaccurate. Consider using '#align list.nodup_range' List.nodup_range'ₓ'. -/
 theorem nodup_range' (s n : ℕ) : Nodup (range' s n) :=
   (pairwise_lt_range' s n).imp fun a b => ne_of_lt
 #align list.nodup_range' List.nodup_range'
 
-/- warning: list.range'_append -> List.range'_append is a dubious translation:
-lean 3 declaration is
-  forall (s : Nat) (m : Nat) (n : Nat), Eq.{1} (List.{0} Nat) (Append.append.{0} (List.{0} Nat) (List.hasAppend.{0} Nat) (List.range' s m) (List.range' (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat Nat.hasAdd) s m) n)) (List.range' s (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat Nat.hasAdd) n m))
-but is expected to have type
-  forall (s : Nat) (m : Nat) (n : Nat), Eq.{1} (List.{0} Nat) (HAppend.hAppend.{0, 0, 0} (List.{0} Nat) (List.{0} Nat) (List.{0} Nat) (instHAppend.{0} (List.{0} Nat) (List.instAppendList.{0} Nat)) (List.range' s m (OfNat.ofNat.{0} Nat 1 (instOfNatNat 1))) (List.range' (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat instAddNat) s m) n (OfNat.ofNat.{0} Nat 1 (instOfNatNat 1)))) (List.range' s (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat instAddNat) n m) (OfNat.ofNat.{0} Nat 1 (instOfNatNat 1)))
-Case conversion may be inaccurate. Consider using '#align list.range'_append List.range'_appendₓ'. -/
 @[simp]
 theorem range'_append : ∀ s m n : ℕ, range' s m ++ range' (s + m) n = range' s (n + m)
   | s, 0, n => rfl
@@ -156,23 +96,11 @@ theorem range'_append : ∀ s m n : ℕ, range' s m ++ range' (s + m) n = range'
       rw [add_right_comm, range'_append]
 #align list.range'_append List.range'_append
 
-/- warning: list.range'_sublist_right -> List.range'_sublist_right is a dubious translation:
-lean 3 declaration is
-  forall {s : Nat} {m : Nat} {n : Nat}, Iff (List.Sublist.{0} Nat (List.range' s m) (List.range' s n)) (LE.le.{0} Nat Nat.hasLe m n)
-but is expected to have type
-  forall {s : Nat} {m : Nat} {n : Nat}, Iff (List.Sublist.{0} Nat (List.range' s m (OfNat.ofNat.{0} Nat 1 (instOfNatNat 1))) (List.range' s n (OfNat.ofNat.{0} Nat 1 (instOfNatNat 1)))) (LE.le.{0} Nat instLENat m n)
-Case conversion may be inaccurate. Consider using '#align list.range'_sublist_right List.range'_sublist_rightₓ'. -/
 theorem range'_sublist_right {s m n : ℕ} : range' s m <+ range' s n ↔ m ≤ n :=
   ⟨fun h => by simpa only [length_range'] using h.length_le, fun h => by
     rw [← tsub_add_cancel_of_le h, ← range'_append] <;> apply sublist_append_left⟩
 #align list.range'_sublist_right List.range'_sublist_right
 
-/- warning: list.range'_subset_right -> List.range'_subset_right is a dubious translation:
-lean 3 declaration is
-  forall {s : Nat} {m : Nat} {n : Nat}, Iff (HasSubset.Subset.{0} (List.{0} Nat) (List.hasSubset.{0} Nat) (List.range' s m) (List.range' s n)) (LE.le.{0} Nat Nat.hasLe m n)
-but is expected to have type
-  forall {s : Nat} {m : Nat} {n : Nat}, Iff (HasSubset.Subset.{0} (List.{0} Nat) (List.instHasSubsetList.{0} Nat) (List.range' s m (OfNat.ofNat.{0} Nat 1 (instOfNatNat 1))) (List.range' s n (OfNat.ofNat.{0} Nat 1 (instOfNatNat 1)))) (LE.le.{0} Nat instLENat m n)
-Case conversion may be inaccurate. Consider using '#align list.range'_subset_right List.range'_subset_rightₓ'. -/
 theorem range'_subset_right {s m n : ℕ} : range' s m ⊆ range' s n ↔ m ≤ n :=
   ⟨fun h =>
     le_of_not_lt fun hn =>
@@ -181,45 +109,21 @@ theorem range'_subset_right {s m n : ℕ} : range' s m ⊆ range' s n ↔ m ≤
     fun h => (range'_sublist_right.2 h).Subset⟩
 #align list.range'_subset_right List.range'_subset_right
 
-/- warning: list.nth_range' -> List.get?_range' is a dubious translation:
-lean 3 declaration is
-  forall (s : Nat) {m : Nat} {n : Nat}, (LT.lt.{0} Nat Nat.hasLt m n) -> (Eq.{1} (Option.{0} Nat) (List.get?.{0} Nat (List.range' s n) m) (Option.some.{0} Nat (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat Nat.hasAdd) s m)))
-but is expected to have type
-  forall (s : Nat) {m : Nat} {n : Nat}, (LT.lt.{0} Nat instLTNat m n) -> (Eq.{1} (Option.{0} Nat) (List.get?.{0} Nat (List.range' s n (OfNat.ofNat.{0} Nat 1 (instOfNatNat 1))) m) (Option.some.{0} Nat (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat instAddNat) s m)))
-Case conversion may be inaccurate. Consider using '#align list.nth_range' List.get?_range'ₓ'. -/
 theorem get?_range' : ∀ (s) {m n : ℕ}, m < n → get? (range' s n) m = some (s + m)
   | s, 0, n + 1, _ => rfl
   | s, m + 1, n + 1, h =>
     (nth_range' (s + 1) (lt_of_add_lt_add_right h)).trans <| by rw [add_right_comm] <;> rfl
 #align list.nth_range' List.get?_range'
 
-/- warning: list.nth_le_range' -> List.nthLe_range' is a dubious translation:
-lean 3 declaration is
-  forall {n : Nat} {m : Nat} (i : Nat) (H : LT.lt.{0} Nat Nat.hasLt i (List.length.{0} Nat (List.range' n m))), Eq.{1} Nat (List.nthLe.{0} Nat (List.range' n m) i H) (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat Nat.hasAdd) n i)
-but is expected to have type
-  forall {n : Nat} {m : Nat} (i : Nat) (H : LT.lt.{0} Nat instLTNat i (List.length.{0} Nat (List.range' n m (OfNat.ofNat.{0} Nat 1 (instOfNatNat 1))))), Eq.{1} Nat (List.nthLe.{0} Nat (List.range' n m (OfNat.ofNat.{0} Nat 1 (instOfNatNat 1))) i H) (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat instAddNat) n i)
-Case conversion may be inaccurate. Consider using '#align list.nth_le_range' List.nthLe_range'ₓ'. -/
 @[simp]
 theorem nthLe_range' {n m} (i) (H : i < (range' n m).length) : nthLe (range' n m) i H = n + i :=
   Option.some.inj <| by rw [← nth_le_nth _, nth_range' _ (by simpa using H)]
 #align list.nth_le_range' List.nthLe_range'
 
-/- warning: list.range'_concat -> List.range'_concat is a dubious translation:
-lean 3 declaration is
-  forall (s : Nat) (n : Nat), Eq.{1} (List.{0} Nat) (List.range' s (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))))) (Append.append.{0} (List.{0} Nat) (List.hasAppend.{0} Nat) (List.range' s n) (List.cons.{0} Nat (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat Nat.hasAdd) s n) (List.nil.{0} Nat)))
-but is expected to have type
-  forall (s : Nat) (n : Nat), Eq.{1} (List.{0} Nat) (List.range' s (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat instAddNat) n (OfNat.ofNat.{0} Nat 1 (instOfNatNat 1))) (OfNat.ofNat.{0} Nat 1 (instOfNatNat 1))) (HAppend.hAppend.{0, 0, 0} (List.{0} Nat) (List.{0} Nat) (List.{0} Nat) (instHAppend.{0} (List.{0} Nat) (List.instAppendList.{0} Nat)) (List.range' s n (OfNat.ofNat.{0} Nat 1 (instOfNatNat 1))) (List.cons.{0} Nat (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat instAddNat) s n) (List.nil.{0} Nat)))
-Case conversion may be inaccurate. Consider using '#align list.range'_concat List.range'_concatₓ'. -/
 theorem range'_concat (s n : ℕ) : range' s (n + 1) = range' s n ++ [s + n] := by
   rw [add_comm n 1] <;> exact (range'_append s n 1).symm
 #align list.range'_concat List.range'_concat
 
-/- warning: list.range_core_range' -> List.range_loop_range' is a dubious translation:
-lean 3 declaration is
-  forall (s : Nat) (n : Nat), Eq.{1} (List.{0} Nat) (List.range.loop s (List.range' s n)) (List.range' (OfNat.ofNat.{0} Nat 0 (OfNat.mk.{0} Nat 0 (Zero.zero.{0} Nat Nat.hasZero))) (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat Nat.hasAdd) n s))
-but is expected to have type
-  forall (s : Nat) (n : Nat), Eq.{1} (List.{0} Nat) (List.range.loop s (List.range' s n (OfNat.ofNat.{0} Nat 1 (instOfNatNat 1)))) (List.range' (OfNat.ofNat.{0} Nat 0 (instOfNatNat 0)) (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat instAddNat) n s) (OfNat.ofNat.{0} Nat 1 (instOfNatNat 1)))
-Case conversion may be inaccurate. Consider using '#align list.range_core_range' List.range_loop_range'ₓ'. -/
 theorem range_loop_range' : ∀ s n : ℕ, List.range.loop s (range' s n) = range' 0 (n + s)
   | 0, n => rfl
   | s + 1, n => by
@@ -227,12 +131,6 @@ theorem range_loop_range' : ∀ s n : ℕ, List.range.loop s (range' s n) = rang
       exact range_core_range' s (n + 1)
 #align list.range_core_range' List.range_loop_range'
 
-/- warning: list.range_eq_range' -> List.range_eq_range' is a dubious translation:
-lean 3 declaration is
-  forall (n : Nat), Eq.{1} (List.{0} Nat) (List.range n) (List.range' (OfNat.ofNat.{0} Nat 0 (OfNat.mk.{0} Nat 0 (Zero.zero.{0} Nat Nat.hasZero))) n)
-but is expected to have type
-  forall (n : Nat), Eq.{1} (List.{0} Nat) (List.range n) (List.range' (OfNat.ofNat.{0} Nat 0 (instOfNatNat 0)) n (OfNat.ofNat.{0} Nat 1 (instOfNatNat 1)))
-Case conversion may be inaccurate. Consider using '#align list.range_eq_range' List.range_eq_range'ₓ'. -/
 theorem range_eq_range' (n : ℕ) : range n = range' 0 n :=
   (range_loop_range' n 0).trans <| by rw [zero_add]
 #align list.range_eq_range' List.range_eq_range'
@@ -244,12 +142,6 @@ theorem range_succ_eq_map (n : ℕ) : range (n + 1) = 0 :: map succ (range n) :=
 #align list.range_succ_eq_map List.range_succ_eq_map
 -/
 
-/- warning: list.range'_eq_map_range -> List.range'_eq_map_range is a dubious translation:
-lean 3 declaration is
-  forall (s : Nat) (n : Nat), Eq.{1} (List.{0} Nat) (List.range' s n) (List.map.{0, 0} Nat Nat (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat Nat.hasAdd) s) (List.range n))
-but is expected to have type
-  forall (s : Nat) (n : Nat), Eq.{1} (List.{0} Nat) (List.range' s n (OfNat.ofNat.{0} Nat 1 (instOfNatNat 1))) (List.map.{0, 0} Nat Nat (fun (x._@.Mathlib.Data.List.Range._hyg.1967 : Nat) => HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat instAddNat) s x._@.Mathlib.Data.List.Range._hyg.1967) (List.range n))
-Case conversion may be inaccurate. Consider using '#align list.range'_eq_map_range List.range'_eq_map_rangeₓ'. -/
 theorem range'_eq_map_range (s n : ℕ) : range' s n = map ((· + ·) s) (range n) := by
   rw [range_eq_range', map_add_range'] <;> rfl
 #align list.range'_eq_map_range List.range'_eq_map_range
@@ -366,12 +258,6 @@ theorem range_add (a : ℕ) : ∀ b, range (a + b) = range a ++ (range b).map fu
 #align list.range_add List.range_add
 -/
 
-/- warning: list.iota_eq_reverse_range' -> List.iota_eq_reverse_range' is a dubious translation:
-lean 3 declaration is
-  forall (n : Nat), Eq.{1} (List.{0} Nat) (List.iota n) (List.reverse.{0} Nat (List.range' (OfNat.ofNat.{0} Nat 1 (OfNat.mk.{0} Nat 1 (One.one.{0} Nat Nat.hasOne))) n))
-but is expected to have type
-  forall (n : Nat), Eq.{1} (List.{0} Nat) (List.iota n) (List.reverse.{0} Nat (List.range' (OfNat.ofNat.{0} Nat 1 (instOfNatNat 1)) n (OfNat.ofNat.{0} Nat 1 (instOfNatNat 1))))
-Case conversion may be inaccurate. Consider using '#align list.iota_eq_reverse_range' List.iota_eq_reverse_range'ₓ'. -/
 theorem iota_eq_reverse_range' : ∀ n : ℕ, iota n = reverse (range' 1 n)
   | 0 => rfl
   | n + 1 => by
@@ -403,12 +289,6 @@ theorem mem_iota {m n : ℕ} : m ∈ iota n ↔ 1 ≤ m ∧ m ≤ n := by
 #align list.mem_iota List.mem_iota
 -/
 
-/- warning: list.reverse_range' -> List.reverse_range' is a dubious translation:
-lean 3 declaration is
-  forall (s : Nat) (n : Nat), Eq.{1} (List.{0} Nat) (List.reverse.{0} Nat (List.range' s n)) (List.map.{0, 0} Nat Nat (fun (i : Nat) => HSub.hSub.{0, 0, 0} Nat Nat Nat (instHSub.{0} Nat Nat.hasSub) (HSub.hSub.{0, 0, 0} Nat Nat Nat (instHSub.{0} Nat Nat.hasSub) (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat Nat.hasAdd) s n) (OfNat.ofNat.{0} Nat 1 (OfNat.mk.{0} Nat 1 (One.one.{0} Nat Nat.hasOne)))) i) (List.range n))
-but is expected to have type
-  forall (s : Nat) (n : Nat), Eq.{1} (List.{0} Nat) (List.reverse.{0} Nat (List.range' s n (OfNat.ofNat.{0} Nat 1 (instOfNatNat 1)))) (List.map.{0, 0} Nat Nat (fun (i : Nat) => HSub.hSub.{0, 0, 0} Nat Nat Nat (instHSub.{0} Nat instSubNat) (HSub.hSub.{0, 0, 0} Nat Nat Nat (instHSub.{0} Nat instSubNat) (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat instAddNat) s n) (OfNat.ofNat.{0} Nat 1 (instOfNatNat 1))) i) (List.range n))
-Case conversion may be inaccurate. Consider using '#align list.reverse_range' List.reverse_range'ₓ'. -/
 theorem reverse_range' : ∀ s n : ℕ, reverse (range' s n) = map (fun i => s + n - 1 - i) (range n)
   | s, 0 => rfl
   | s, n + 1 => by
@@ -459,12 +339,6 @@ theorem finRange_eq_nil {n : ℕ} : finRange n = [] ↔ n = 0 := by
 #align list.fin_range_eq_nil List.finRange_eq_nil
 -/
 
-/- warning: list.prod_range_succ -> List.prod_range_succ is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} [_inst_1 : Monoid.{u1} α] (f : Nat -> α) (n : Nat), Eq.{succ u1} α (List.prod.{u1} α (MulOneClass.toHasMul.{u1} α (Monoid.toMulOneClass.{u1} α _inst_1)) (MulOneClass.toHasOne.{u1} α (Monoid.toMulOneClass.{u1} α _inst_1)) (List.map.{0, u1} Nat α f (List.range (Nat.succ n)))) (HMul.hMul.{u1, u1, u1} α α α (instHMul.{u1} α (MulOneClass.toHasMul.{u1} α (Monoid.toMulOneClass.{u1} α _inst_1))) (List.prod.{u1} α (MulOneClass.toHasMul.{u1} α (Monoid.toMulOneClass.{u1} α _inst_1)) (MulOneClass.toHasOne.{u1} α (Monoid.toMulOneClass.{u1} α _inst_1)) (List.map.{0, u1} Nat α f (List.range n))) (f n))
-but is expected to have type
-  forall {α : Type.{u1}} [_inst_1 : Monoid.{u1} α] (f : Nat -> α) (n : Nat), Eq.{succ u1} α (List.prod.{u1} α (MulOneClass.toMul.{u1} α (Monoid.toMulOneClass.{u1} α _inst_1)) (Monoid.toOne.{u1} α _inst_1) (List.map.{0, u1} Nat α f (List.range (Nat.succ n)))) (HMul.hMul.{u1, u1, u1} α α α (instHMul.{u1} α (MulOneClass.toMul.{u1} α (Monoid.toMulOneClass.{u1} α _inst_1))) (List.prod.{u1} α (MulOneClass.toMul.{u1} α (Monoid.toMulOneClass.{u1} α _inst_1)) (Monoid.toOne.{u1} α _inst_1) (List.map.{0, u1} Nat α f (List.range n))) (f n))
-Case conversion may be inaccurate. Consider using '#align list.prod_range_succ List.prod_range_succₓ'. -/
 @[to_additive]
 theorem prod_range_succ {α : Type u} [Monoid α] (f : ℕ → α) (n : ℕ) :
     ((range n.succ).map f).Prod = ((range n).map f).Prod * f n := by
@@ -472,12 +346,6 @@ theorem prod_range_succ {α : Type u} [Monoid α] (f : ℕ → α) (n : ℕ) :
 #align list.prod_range_succ List.prod_range_succ
 #align list.sum_range_succ List.sum_range_succ
 
-/- warning: list.prod_range_succ' -> List.prod_range_succ' is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} [_inst_1 : Monoid.{u1} α] (f : Nat -> α) (n : Nat), Eq.{succ u1} α (List.prod.{u1} α (MulOneClass.toHasMul.{u1} α (Monoid.toMulOneClass.{u1} α _inst_1)) (MulOneClass.toHasOne.{u1} α (Monoid.toMulOneClass.{u1} α _inst_1)) (List.map.{0, u1} Nat α f (List.range (Nat.succ n)))) (HMul.hMul.{u1, u1, u1} α α α (instHMul.{u1} α (MulOneClass.toHasMul.{u1} α (Monoid.toMulOneClass.{u1} α _inst_1))) (f (OfNat.ofNat.{0} Nat 0 (OfNat.mk.{0} Nat 0 (Zero.zero.{0} Nat Nat.hasZero)))) (List.prod.{u1} α (MulOneClass.toHasMul.{u1} α (Monoid.toMulOneClass.{u1} α _inst_1)) (MulOneClass.toHasOne.{u1} α (Monoid.toMulOneClass.{u1} α _inst_1)) (List.map.{0, u1} Nat α (fun (i : Nat) => f (Nat.succ i)) (List.range n))))
-but is expected to have type
-  forall {α : Type.{u1}} [_inst_1 : Monoid.{u1} α] (f : Nat -> α) (n : Nat), Eq.{succ u1} α (List.prod.{u1} α (MulOneClass.toMul.{u1} α (Monoid.toMulOneClass.{u1} α _inst_1)) (Monoid.toOne.{u1} α _inst_1) (List.map.{0, u1} Nat α f (List.range (Nat.succ n)))) (HMul.hMul.{u1, u1, u1} α α α (instHMul.{u1} α (MulOneClass.toMul.{u1} α (Monoid.toMulOneClass.{u1} α _inst_1))) (f (OfNat.ofNat.{0} Nat 0 (instOfNatNat 0))) (List.prod.{u1} α (MulOneClass.toMul.{u1} α (Monoid.toMulOneClass.{u1} α _inst_1)) (Monoid.toOne.{u1} α _inst_1) (List.map.{0, u1} Nat α (fun (i : Nat) => f (Nat.succ i)) (List.range n))))
-Case conversion may be inaccurate. Consider using '#align list.prod_range_succ' List.prod_range_succ'ₓ'. -/
 /-- A variant of `prod_range_succ` which pulls off the first
   term in the product rather than the last.-/
 @[to_additive
@@ -489,12 +357,6 @@ theorem prod_range_succ' {α : Type u} [Monoid α] (f : ℕ → α) (n : ℕ) :
 #align list.prod_range_succ' List.prod_range_succ'
 #align list.sum_range_succ' List.sum_range_succ'
 
-/- warning: list.enum_from_map_fst -> List.enum_from_map_fst is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} (n : Nat) (l : List.{u1} α), Eq.{1} (List.{0} Nat) (List.map.{u1, 0} (Prod.{0, u1} Nat α) Nat (Prod.fst.{0, u1} Nat α) (List.enumFrom.{u1} α n l)) (List.range' n (List.length.{u1} α l))
-but is expected to have type
-  forall {α : Type.{u1}} (n : Nat) (l : List.{u1} α), Eq.{1} (List.{0} Nat) (List.map.{u1, 0} (Prod.{0, u1} Nat α) Nat (Prod.fst.{0, u1} Nat α) (List.enumFrom.{u1} α n l)) (List.range' n (List.length.{u1} α l) (OfNat.ofNat.{0} Nat 1 (instOfNatNat 1)))
-Case conversion may be inaccurate. Consider using '#align list.enum_from_map_fst List.enum_from_map_fstₓ'. -/
 @[simp]
 theorem enum_from_map_fst : ∀ (n) (l : List α), map Prod.fst (enumFrom n l) = range' n l.length
   | n, [] => rfl
@@ -521,22 +383,10 @@ theorem unzip_enum_eq_prod (l : List α) : l.enum.unzip = (range l.length, l) :=
 #align list.unzip_enum_eq_prod List.unzip_enum_eq_prod
 -/
 
-/- warning: list.enum_from_eq_zip_range' -> List.enum_from_eq_zip_range' is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} (l : List.{u1} α) {n : Nat}, Eq.{succ u1} (List.{u1} (Prod.{0, u1} Nat α)) (List.enumFrom.{u1} α n l) (List.zip.{0, u1} Nat α (List.range' n (List.length.{u1} α l)) l)
-but is expected to have type
-  forall {α : Type.{u1}} (l : List.{u1} α) {n : Nat}, Eq.{succ u1} (List.{u1} (Prod.{0, u1} Nat α)) (List.enumFrom.{u1} α n l) (List.zip.{0, u1} Nat α (List.range' n (List.length.{u1} α l) (OfNat.ofNat.{0} Nat 1 (instOfNatNat 1))) l)
-Case conversion may be inaccurate. Consider using '#align list.enum_from_eq_zip_range' List.enum_from_eq_zip_range'ₓ'. -/
 theorem enum_from_eq_zip_range' (l : List α) {n : ℕ} : l.enumFrom n = (range' n l.length).zip l :=
   zip_of_prod (enum_from_map_fst _ _) (enumFrom_map_snd _ _)
 #align list.enum_from_eq_zip_range' List.enum_from_eq_zip_range'
 
-/- warning: list.unzip_enum_from_eq_prod -> List.unzip_enum_from_eq_prod is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} (l : List.{u1} α) {n : Nat}, Eq.{succ u1} (Prod.{0, u1} (List.{0} Nat) (List.{u1} α)) (List.unzip.{0, u1} Nat α (List.enumFrom.{u1} α n l)) (Prod.mk.{0, u1} (List.{0} Nat) (List.{u1} α) (List.range' n (List.length.{u1} α l)) l)
-but is expected to have type
-  forall {α : Type.{u1}} (l : List.{u1} α) {n : Nat}, Eq.{succ u1} (Prod.{0, u1} (List.{0} Nat) (List.{u1} α)) (List.unzip.{0, u1} Nat α (List.enumFrom.{u1} α n l)) (Prod.mk.{0, u1} (List.{0} Nat) (List.{u1} α) (List.range' n (List.length.{u1} α l) (OfNat.ofNat.{0} Nat 1 (instOfNatNat 1))) l)
-Case conversion may be inaccurate. Consider using '#align list.unzip_enum_from_eq_prod List.unzip_enum_from_eq_prodₓ'. -/
 @[simp]
 theorem unzip_enum_from_eq_prod (l : List α) {n : ℕ} :
     (l.enumFrom n).unzip = (range' n l.length, l) := by
Diff
@@ -435,10 +435,7 @@ theorem finRange_zero : finRange 0 = [] :=
 #print List.mem_finRange /-
 @[simp]
 theorem mem_finRange {n : ℕ} (a : Fin n) : a ∈ finRange n :=
-  mem_pmap.2
-    ⟨a.1, mem_range.2 a.2, by
-      cases a
-      rfl⟩
+  mem_pmap.2 ⟨a.1, mem_range.2 a.2, by cases a; rfl⟩
 #align list.mem_fin_range List.mem_finRange
 -/
 
Diff
@@ -34,21 +34,34 @@ namespace List
 
 variable {α : Type u}
 
-#print List.length_range' /-
+/- warning: list.length_range' -> List.length_range' is a dubious translation:
+lean 3 declaration is
+  forall (s : Nat) (n : Nat), Eq.{1} Nat (List.length.{0} Nat (List.range' s n)) n
+but is expected to have type
+  forall (s : Nat) (n : Nat), Eq.{1} Nat (List.length.{0} Nat (List.range' s n (OfNat.ofNat.{0} Nat 1 (instOfNatNat 1)))) n
+Case conversion may be inaccurate. Consider using '#align list.length_range' List.length_range'ₓ'. -/
 @[simp]
 theorem length_range' : ∀ s n : ℕ, length (range' s n) = n
   | s, 0 => rfl
   | s, n + 1 => congr_arg succ (length_range' _ _)
 #align list.length_range' List.length_range'
--/
 
-#print List.range'_eq_nil /-
+/- warning: list.range'_eq_nil -> List.range'_eq_nil is a dubious translation:
+lean 3 declaration is
+  forall {s : Nat} {n : Nat}, Iff (Eq.{1} (List.{0} Nat) (List.range' s n) (List.nil.{0} Nat)) (Eq.{1} Nat n (OfNat.ofNat.{0} Nat 0 (OfNat.mk.{0} Nat 0 (Zero.zero.{0} Nat Nat.hasZero))))
+but is expected to have type
+  forall {s : Nat} {n : Nat}, Iff (Eq.{1} (List.{0} Nat) (List.range' s n (OfNat.ofNat.{0} Nat 1 (instOfNatNat 1))) (List.nil.{0} Nat)) (Eq.{1} Nat n (OfNat.ofNat.{0} Nat 0 (instOfNatNat 0)))
+Case conversion may be inaccurate. Consider using '#align list.range'_eq_nil List.range'_eq_nilₓ'. -/
 @[simp]
 theorem range'_eq_nil {s n : ℕ} : range' s n = [] ↔ n = 0 := by rw [← length_eq_zero, length_range']
 #align list.range'_eq_nil List.range'_eq_nil
--/
 
-#print List.mem_range' /-
+/- warning: list.mem_range' -> List.mem_range' is a dubious translation:
+lean 3 declaration is
+  forall {m : Nat} {s : Nat} {n : Nat}, Iff (Membership.Mem.{0, 0} Nat (List.{0} Nat) (List.hasMem.{0} Nat) m (List.range' s n)) (And (LE.le.{0} Nat Nat.hasLe s m) (LT.lt.{0} Nat Nat.hasLt m (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat Nat.hasAdd) s n)))
+but is expected to have type
+  forall {m : Nat} {s : Nat} {n : Nat}, Iff (Membership.mem.{0, 0} Nat (List.{0} Nat) (List.instMembershipList.{0} Nat) m (List.range' s n (OfNat.ofNat.{0} Nat 1 (instOfNatNat 1)))) (And (LE.le.{0} Nat instLENat s m) (LT.lt.{0} Nat instLTNat m (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat instAddNat) s n)))
+Case conversion may be inaccurate. Consider using '#align list.mem_range' List.mem_range'ₓ'. -/
 @[simp]
 theorem mem_range' {m : ℕ} : ∀ {s n : ℕ}, m ∈ range' s n ↔ s ≤ m ∧ m < s + n
   | s, 0 => (false_iff_iff _).2 fun ⟨H1, H2⟩ => not_le_of_lt H2 H1
@@ -59,16 +72,24 @@ theorem mem_range' {m : ℕ} : ∀ {s n : ℕ}, m ∈ range' s n ↔ s ≤ m ∧
     (mem_cons _ _ _).trans <| by
       simp only [mem_range', or_and_left, or_iff_right_of_imp this, l, add_right_comm] <;> rfl
 #align list.mem_range' List.mem_range'
--/
 
-#print List.map_add_range' /-
+/- warning: list.map_add_range' -> List.map_add_range' is a dubious translation:
+lean 3 declaration is
+  forall (a : Nat) (s : Nat) (n : Nat), Eq.{1} (List.{0} Nat) (List.map.{0, 0} Nat Nat (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat Nat.hasAdd) a) (List.range' s n)) (List.range' (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat Nat.hasAdd) a s) n)
+but is expected to have type
+  forall (a : Nat) (s : Nat) (n : Nat), Eq.{1} (List.{0} Nat) (List.map.{0, 0} Nat Nat ((fun (x._@.Mathlib.Data.List.Range._hyg.391 : Nat) (x._@.Mathlib.Data.List.Range._hyg.393 : Nat) => HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat instAddNat) x._@.Mathlib.Data.List.Range._hyg.391 x._@.Mathlib.Data.List.Range._hyg.393) a) (List.range' s n (OfNat.ofNat.{0} Nat 1 (instOfNatNat 1)))) (List.range' (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat instAddNat) a s) n (OfNat.ofNat.{0} Nat 1 (instOfNatNat 1)))
+Case conversion may be inaccurate. Consider using '#align list.map_add_range' List.map_add_range'ₓ'. -/
 theorem map_add_range' (a) : ∀ s n : ℕ, map ((· + ·) a) (range' s n) = range' (a + s) n
   | s, 0 => rfl
   | s, n + 1 => congr_arg (cons _) (map_add_range' (s + 1) n)
 #align list.map_add_range' List.map_add_range'
--/
 
-#print List.map_sub_range' /-
+/- warning: list.map_sub_range' -> List.map_sub_range' is a dubious translation:
+lean 3 declaration is
+  forall (a : Nat) (s : Nat) (n : Nat), (LE.le.{0} Nat Nat.hasLe a s) -> (Eq.{1} (List.{0} Nat) (List.map.{0, 0} Nat Nat (fun (x : Nat) => HSub.hSub.{0, 0, 0} Nat Nat Nat (instHSub.{0} Nat Nat.hasSub) x a) (List.range' s n)) (List.range' (HSub.hSub.{0, 0, 0} Nat Nat Nat (instHSub.{0} Nat Nat.hasSub) s a) n))
+but is expected to have type
+  forall (a : Nat) (s : Nat) (n : Nat), (LE.le.{0} Nat instLENat a s) -> (Eq.{1} (List.{0} Nat) (List.map.{0, 0} Nat Nat (fun (x : Nat) => HSub.hSub.{0, 0, 0} Nat Nat Nat (instHSub.{0} Nat instSubNat) x a) (List.range' s n (OfNat.ofNat.{0} Nat 1 (instOfNatNat 1)))) (List.range' (HSub.hSub.{0, 0, 0} Nat Nat Nat (instHSub.{0} Nat instSubNat) s a) n (OfNat.ofNat.{0} Nat 1 (instOfNatNat 1))))
+Case conversion may be inaccurate. Consider using '#align list.map_sub_range' List.map_sub_range'ₓ'. -/
 theorem map_sub_range' (a) :
     ∀ (s n : ℕ) (h : a ≤ s), map (fun x => x - a) (range' s n) = range' (s - a) n
   | s, 0, _ => rfl
@@ -78,35 +99,55 @@ theorem map_sub_range' (a) :
     rw [Nat.succ_sub h]
     rfl
 #align list.map_sub_range' List.map_sub_range'
--/
 
-#print List.chain_succ_range' /-
+/- warning: list.chain_succ_range' -> List.chain_succ_range' is a dubious translation:
+lean 3 declaration is
+  forall (s : Nat) (n : Nat), List.Chain.{0} Nat (fun (a : Nat) (b : Nat) => Eq.{1} Nat b (Nat.succ a)) s (List.range' (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat Nat.hasAdd) s (OfNat.ofNat.{0} Nat 1 (OfNat.mk.{0} Nat 1 (One.one.{0} Nat Nat.hasOne)))) n)
+but is expected to have type
+  forall (s : Nat) (n : Nat), List.Chain.{0} Nat (fun (a : Nat) (b : Nat) => Eq.{1} Nat b (Nat.succ a)) s (List.range' (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat instAddNat) s (OfNat.ofNat.{0} Nat 1 (instOfNatNat 1))) n (OfNat.ofNat.{0} Nat 1 (instOfNatNat 1)))
+Case conversion may be inaccurate. Consider using '#align list.chain_succ_range' List.chain_succ_range'ₓ'. -/
 theorem chain_succ_range' : ∀ s n : ℕ, Chain (fun a b => b = succ a) s (range' (s + 1) n)
   | s, 0 => Chain.nil
   | s, n + 1 => (chain_succ_range' (s + 1) n).cons rfl
 #align list.chain_succ_range' List.chain_succ_range'
--/
 
-#print List.chain_lt_range' /-
+/- warning: list.chain_lt_range' -> List.chain_lt_range' is a dubious translation:
+lean 3 declaration is
+  forall (s : Nat) (n : Nat), List.Chain.{0} Nat (LT.lt.{0} Nat Nat.hasLt) s (List.range' (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat Nat.hasAdd) s (OfNat.ofNat.{0} Nat 1 (OfNat.mk.{0} Nat 1 (One.one.{0} Nat Nat.hasOne)))) n)
+but is expected to have type
+  forall (s : Nat) (n : Nat), List.Chain.{0} Nat (fun (x._@.Mathlib.Data.List.Range._hyg.791 : Nat) (x._@.Mathlib.Data.List.Range._hyg.793 : Nat) => LT.lt.{0} Nat instLTNat x._@.Mathlib.Data.List.Range._hyg.791 x._@.Mathlib.Data.List.Range._hyg.793) s (List.range' (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat instAddNat) s (OfNat.ofNat.{0} Nat 1 (instOfNatNat 1))) n (OfNat.ofNat.{0} Nat 1 (instOfNatNat 1)))
+Case conversion may be inaccurate. Consider using '#align list.chain_lt_range' List.chain_lt_range'ₓ'. -/
 theorem chain_lt_range' (s n : ℕ) : Chain (· < ·) s (range' (s + 1) n) :=
   (chain_succ_range' s n).imp fun a b e => e.symm ▸ lt_succ_self _
 #align list.chain_lt_range' List.chain_lt_range'
--/
 
-#print List.pairwise_lt_range' /-
+/- warning: list.pairwise_lt_range' -> List.pairwise_lt_range' is a dubious translation:
+lean 3 declaration is
+  forall (s : Nat) (n : Nat), List.Pairwise.{0} Nat (LT.lt.{0} Nat Nat.hasLt) (List.range' s n)
+but is expected to have type
+  forall (s : Nat) (n : Nat), List.Pairwise.{0} Nat (fun (x._@.Mathlib.Data.List.Range._hyg.852 : Nat) (x._@.Mathlib.Data.List.Range._hyg.854 : Nat) => LT.lt.{0} Nat instLTNat x._@.Mathlib.Data.List.Range._hyg.852 x._@.Mathlib.Data.List.Range._hyg.854) (List.range' s n (OfNat.ofNat.{0} Nat 1 (instOfNatNat 1)))
+Case conversion may be inaccurate. Consider using '#align list.pairwise_lt_range' List.pairwise_lt_range'ₓ'. -/
 theorem pairwise_lt_range' : ∀ s n : ℕ, Pairwise (· < ·) (range' s n)
   | s, 0 => Pairwise.nil
   | s, n + 1 => chain_iff_pairwise.1 (chain_lt_range' s n)
 #align list.pairwise_lt_range' List.pairwise_lt_range'
--/
 
-#print List.nodup_range' /-
+/- warning: list.nodup_range' -> List.nodup_range' is a dubious translation:
+lean 3 declaration is
+  forall (s : Nat) (n : Nat), List.Nodup.{0} Nat (List.range' s n)
+but is expected to have type
+  forall (s : Nat) (n : Nat), List.Nodup.{0} Nat (List.range' s n (OfNat.ofNat.{0} Nat 1 (instOfNatNat 1)))
+Case conversion may be inaccurate. Consider using '#align list.nodup_range' List.nodup_range'ₓ'. -/
 theorem nodup_range' (s n : ℕ) : Nodup (range' s n) :=
   (pairwise_lt_range' s n).imp fun a b => ne_of_lt
 #align list.nodup_range' List.nodup_range'
--/
 
-#print List.range'_append /-
+/- warning: list.range'_append -> List.range'_append is a dubious translation:
+lean 3 declaration is
+  forall (s : Nat) (m : Nat) (n : Nat), Eq.{1} (List.{0} Nat) (Append.append.{0} (List.{0} Nat) (List.hasAppend.{0} Nat) (List.range' s m) (List.range' (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat Nat.hasAdd) s m) n)) (List.range' s (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat Nat.hasAdd) n m))
+but is expected to have type
+  forall (s : Nat) (m : Nat) (n : Nat), Eq.{1} (List.{0} Nat) (HAppend.hAppend.{0, 0, 0} (List.{0} Nat) (List.{0} Nat) (List.{0} Nat) (instHAppend.{0} (List.{0} Nat) (List.instAppendList.{0} Nat)) (List.range' s m (OfNat.ofNat.{0} Nat 1 (instOfNatNat 1))) (List.range' (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat instAddNat) s m) n (OfNat.ofNat.{0} Nat 1 (instOfNatNat 1)))) (List.range' s (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat instAddNat) n m) (OfNat.ofNat.{0} Nat 1 (instOfNatNat 1)))
+Case conversion may be inaccurate. Consider using '#align list.range'_append List.range'_appendₓ'. -/
 @[simp]
 theorem range'_append : ∀ s m n : ℕ, range' s m ++ range' (s + m) n = range' s (n + m)
   | s, 0, n => rfl
@@ -114,16 +155,24 @@ theorem range'_append : ∀ s m n : ℕ, range' s m ++ range' (s + m) n = range'
     show s :: (range' (s + 1) m ++ range' (s + m + 1) n) = s :: range' (s + 1) (n + m) by
       rw [add_right_comm, range'_append]
 #align list.range'_append List.range'_append
--/
 
-#print List.range'_sublist_right /-
+/- warning: list.range'_sublist_right -> List.range'_sublist_right is a dubious translation:
+lean 3 declaration is
+  forall {s : Nat} {m : Nat} {n : Nat}, Iff (List.Sublist.{0} Nat (List.range' s m) (List.range' s n)) (LE.le.{0} Nat Nat.hasLe m n)
+but is expected to have type
+  forall {s : Nat} {m : Nat} {n : Nat}, Iff (List.Sublist.{0} Nat (List.range' s m (OfNat.ofNat.{0} Nat 1 (instOfNatNat 1))) (List.range' s n (OfNat.ofNat.{0} Nat 1 (instOfNatNat 1)))) (LE.le.{0} Nat instLENat m n)
+Case conversion may be inaccurate. Consider using '#align list.range'_sublist_right List.range'_sublist_rightₓ'. -/
 theorem range'_sublist_right {s m n : ℕ} : range' s m <+ range' s n ↔ m ≤ n :=
   ⟨fun h => by simpa only [length_range'] using h.length_le, fun h => by
     rw [← tsub_add_cancel_of_le h, ← range'_append] <;> apply sublist_append_left⟩
 #align list.range'_sublist_right List.range'_sublist_right
--/
 
-#print List.range'_subset_right /-
+/- warning: list.range'_subset_right -> List.range'_subset_right is a dubious translation:
+lean 3 declaration is
+  forall {s : Nat} {m : Nat} {n : Nat}, Iff (HasSubset.Subset.{0} (List.{0} Nat) (List.hasSubset.{0} Nat) (List.range' s m) (List.range' s n)) (LE.le.{0} Nat Nat.hasLe m n)
+but is expected to have type
+  forall {s : Nat} {m : Nat} {n : Nat}, Iff (HasSubset.Subset.{0} (List.{0} Nat) (List.instHasSubsetList.{0} Nat) (List.range' s m (OfNat.ofNat.{0} Nat 1 (instOfNatNat 1))) (List.range' s n (OfNat.ofNat.{0} Nat 1 (instOfNatNat 1)))) (LE.le.{0} Nat instLENat m n)
+Case conversion may be inaccurate. Consider using '#align list.range'_subset_right List.range'_subset_rightₓ'. -/
 theorem range'_subset_right {s m n : ℕ} : range' s m ⊆ range' s n ↔ m ≤ n :=
   ⟨fun h =>
     le_of_not_lt fun hn =>
@@ -131,43 +180,62 @@ theorem range'_subset_right {s m n : ℕ} : range' s m ⊆ range' s n ↔ m ≤
         (mem_range'.1 <| h <| mem_range'.2 ⟨Nat.le_add_right _ _, Nat.add_lt_add_left hn s⟩).2,
     fun h => (range'_sublist_right.2 h).Subset⟩
 #align list.range'_subset_right List.range'_subset_right
--/
 
-#print List.get?_range' /-
+/- warning: list.nth_range' -> List.get?_range' is a dubious translation:
+lean 3 declaration is
+  forall (s : Nat) {m : Nat} {n : Nat}, (LT.lt.{0} Nat Nat.hasLt m n) -> (Eq.{1} (Option.{0} Nat) (List.get?.{0} Nat (List.range' s n) m) (Option.some.{0} Nat (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat Nat.hasAdd) s m)))
+but is expected to have type
+  forall (s : Nat) {m : Nat} {n : Nat}, (LT.lt.{0} Nat instLTNat m n) -> (Eq.{1} (Option.{0} Nat) (List.get?.{0} Nat (List.range' s n (OfNat.ofNat.{0} Nat 1 (instOfNatNat 1))) m) (Option.some.{0} Nat (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat instAddNat) s m)))
+Case conversion may be inaccurate. Consider using '#align list.nth_range' List.get?_range'ₓ'. -/
 theorem get?_range' : ∀ (s) {m n : ℕ}, m < n → get? (range' s n) m = some (s + m)
   | s, 0, n + 1, _ => rfl
   | s, m + 1, n + 1, h =>
     (nth_range' (s + 1) (lt_of_add_lt_add_right h)).trans <| by rw [add_right_comm] <;> rfl
 #align list.nth_range' List.get?_range'
--/
 
-#print List.nthLe_range' /-
+/- warning: list.nth_le_range' -> List.nthLe_range' is a dubious translation:
+lean 3 declaration is
+  forall {n : Nat} {m : Nat} (i : Nat) (H : LT.lt.{0} Nat Nat.hasLt i (List.length.{0} Nat (List.range' n m))), Eq.{1} Nat (List.nthLe.{0} Nat (List.range' n m) i H) (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat Nat.hasAdd) n i)
+but is expected to have type
+  forall {n : Nat} {m : Nat} (i : Nat) (H : LT.lt.{0} Nat instLTNat i (List.length.{0} Nat (List.range' n m (OfNat.ofNat.{0} Nat 1 (instOfNatNat 1))))), Eq.{1} Nat (List.nthLe.{0} Nat (List.range' n m (OfNat.ofNat.{0} Nat 1 (instOfNatNat 1))) i H) (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat instAddNat) n i)
+Case conversion may be inaccurate. Consider using '#align list.nth_le_range' List.nthLe_range'ₓ'. -/
 @[simp]
 theorem nthLe_range' {n m} (i) (H : i < (range' n m).length) : nthLe (range' n m) i H = n + i :=
   Option.some.inj <| by rw [← nth_le_nth _, nth_range' _ (by simpa using H)]
 #align list.nth_le_range' List.nthLe_range'
--/
 
-#print List.range'_concat /-
+/- warning: list.range'_concat -> List.range'_concat is a dubious translation:
+lean 3 declaration is
+  forall (s : Nat) (n : Nat), Eq.{1} (List.{0} Nat) (List.range' s (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))))) (Append.append.{0} (List.{0} Nat) (List.hasAppend.{0} Nat) (List.range' s n) (List.cons.{0} Nat (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat Nat.hasAdd) s n) (List.nil.{0} Nat)))
+but is expected to have type
+  forall (s : Nat) (n : Nat), Eq.{1} (List.{0} Nat) (List.range' s (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat instAddNat) n (OfNat.ofNat.{0} Nat 1 (instOfNatNat 1))) (OfNat.ofNat.{0} Nat 1 (instOfNatNat 1))) (HAppend.hAppend.{0, 0, 0} (List.{0} Nat) (List.{0} Nat) (List.{0} Nat) (instHAppend.{0} (List.{0} Nat) (List.instAppendList.{0} Nat)) (List.range' s n (OfNat.ofNat.{0} Nat 1 (instOfNatNat 1))) (List.cons.{0} Nat (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat instAddNat) s n) (List.nil.{0} Nat)))
+Case conversion may be inaccurate. Consider using '#align list.range'_concat List.range'_concatₓ'. -/
 theorem range'_concat (s n : ℕ) : range' s (n + 1) = range' s n ++ [s + n] := by
   rw [add_comm n 1] <;> exact (range'_append s n 1).symm
 #align list.range'_concat List.range'_concat
--/
 
-#print List.range_loop_range' /-
+/- warning: list.range_core_range' -> List.range_loop_range' is a dubious translation:
+lean 3 declaration is
+  forall (s : Nat) (n : Nat), Eq.{1} (List.{0} Nat) (List.range.loop s (List.range' s n)) (List.range' (OfNat.ofNat.{0} Nat 0 (OfNat.mk.{0} Nat 0 (Zero.zero.{0} Nat Nat.hasZero))) (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat Nat.hasAdd) n s))
+but is expected to have type
+  forall (s : Nat) (n : Nat), Eq.{1} (List.{0} Nat) (List.range.loop s (List.range' s n (OfNat.ofNat.{0} Nat 1 (instOfNatNat 1)))) (List.range' (OfNat.ofNat.{0} Nat 0 (instOfNatNat 0)) (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat instAddNat) n s) (OfNat.ofNat.{0} Nat 1 (instOfNatNat 1)))
+Case conversion may be inaccurate. Consider using '#align list.range_core_range' List.range_loop_range'ₓ'. -/
 theorem range_loop_range' : ∀ s n : ℕ, List.range.loop s (range' s n) = range' 0 (n + s)
   | 0, n => rfl
   | s + 1, n => by
     rw [show n + (s + 1) = n + 1 + s from add_right_comm n s 1] <;>
       exact range_core_range' s (n + 1)
 #align list.range_core_range' List.range_loop_range'
--/
 
-#print List.range_eq_range' /-
+/- warning: list.range_eq_range' -> List.range_eq_range' is a dubious translation:
+lean 3 declaration is
+  forall (n : Nat), Eq.{1} (List.{0} Nat) (List.range n) (List.range' (OfNat.ofNat.{0} Nat 0 (OfNat.mk.{0} Nat 0 (Zero.zero.{0} Nat Nat.hasZero))) n)
+but is expected to have type
+  forall (n : Nat), Eq.{1} (List.{0} Nat) (List.range n) (List.range' (OfNat.ofNat.{0} Nat 0 (instOfNatNat 0)) n (OfNat.ofNat.{0} Nat 1 (instOfNatNat 1)))
+Case conversion may be inaccurate. Consider using '#align list.range_eq_range' List.range_eq_range'ₓ'. -/
 theorem range_eq_range' (n : ℕ) : range n = range' 0 n :=
   (range_loop_range' n 0).trans <| by rw [zero_add]
 #align list.range_eq_range' List.range_eq_range'
--/
 
 #print List.range_succ_eq_map /-
 theorem range_succ_eq_map (n : ℕ) : range (n + 1) = 0 :: map succ (range n) := by
@@ -176,11 +244,15 @@ theorem range_succ_eq_map (n : ℕ) : range (n + 1) = 0 :: map succ (range n) :=
 #align list.range_succ_eq_map List.range_succ_eq_map
 -/
 
-#print List.range'_eq_map_range /-
+/- warning: list.range'_eq_map_range -> List.range'_eq_map_range is a dubious translation:
+lean 3 declaration is
+  forall (s : Nat) (n : Nat), Eq.{1} (List.{0} Nat) (List.range' s n) (List.map.{0, 0} Nat Nat (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat Nat.hasAdd) s) (List.range n))
+but is expected to have type
+  forall (s : Nat) (n : Nat), Eq.{1} (List.{0} Nat) (List.range' s n (OfNat.ofNat.{0} Nat 1 (instOfNatNat 1))) (List.map.{0, 0} Nat Nat (fun (x._@.Mathlib.Data.List.Range._hyg.1967 : Nat) => HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat instAddNat) s x._@.Mathlib.Data.List.Range._hyg.1967) (List.range n))
+Case conversion may be inaccurate. Consider using '#align list.range'_eq_map_range List.range'_eq_map_rangeₓ'. -/
 theorem range'_eq_map_range (s n : ℕ) : range' s n = map ((· + ·) s) (range n) := by
   rw [range_eq_range', map_add_range'] <;> rfl
 #align list.range'_eq_map_range List.range'_eq_map_range
--/
 
 #print List.length_range /-
 @[simp]
@@ -294,13 +366,17 @@ theorem range_add (a : ℕ) : ∀ b, range (a + b) = range a ++ (range b).map fu
 #align list.range_add List.range_add
 -/
 
-#print List.iota_eq_reverse_range' /-
+/- warning: list.iota_eq_reverse_range' -> List.iota_eq_reverse_range' is a dubious translation:
+lean 3 declaration is
+  forall (n : Nat), Eq.{1} (List.{0} Nat) (List.iota n) (List.reverse.{0} Nat (List.range' (OfNat.ofNat.{0} Nat 1 (OfNat.mk.{0} Nat 1 (One.one.{0} Nat Nat.hasOne))) n))
+but is expected to have type
+  forall (n : Nat), Eq.{1} (List.{0} Nat) (List.iota n) (List.reverse.{0} Nat (List.range' (OfNat.ofNat.{0} Nat 1 (instOfNatNat 1)) n (OfNat.ofNat.{0} Nat 1 (instOfNatNat 1))))
+Case conversion may be inaccurate. Consider using '#align list.iota_eq_reverse_range' List.iota_eq_reverse_range'ₓ'. -/
 theorem iota_eq_reverse_range' : ∀ n : ℕ, iota n = reverse (range' 1 n)
   | 0 => rfl
   | n + 1 => by
     simp only [iota, range'_concat, iota_eq_reverse_range' n, reverse_append, add_comm] <;> rfl
 #align list.iota_eq_reverse_range' List.iota_eq_reverse_range'
--/
 
 #print List.length_iota /-
 @[simp]
@@ -327,7 +403,12 @@ theorem mem_iota {m n : ℕ} : m ∈ iota n ↔ 1 ≤ m ∧ m ≤ n := by
 #align list.mem_iota List.mem_iota
 -/
 
-#print List.reverse_range' /-
+/- warning: list.reverse_range' -> List.reverse_range' is a dubious translation:
+lean 3 declaration is
+  forall (s : Nat) (n : Nat), Eq.{1} (List.{0} Nat) (List.reverse.{0} Nat (List.range' s n)) (List.map.{0, 0} Nat Nat (fun (i : Nat) => HSub.hSub.{0, 0, 0} Nat Nat Nat (instHSub.{0} Nat Nat.hasSub) (HSub.hSub.{0, 0, 0} Nat Nat Nat (instHSub.{0} Nat Nat.hasSub) (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat Nat.hasAdd) s n) (OfNat.ofNat.{0} Nat 1 (OfNat.mk.{0} Nat 1 (One.one.{0} Nat Nat.hasOne)))) i) (List.range n))
+but is expected to have type
+  forall (s : Nat) (n : Nat), Eq.{1} (List.{0} Nat) (List.reverse.{0} Nat (List.range' s n (OfNat.ofNat.{0} Nat 1 (instOfNatNat 1)))) (List.map.{0, 0} Nat Nat (fun (i : Nat) => HSub.hSub.{0, 0, 0} Nat Nat Nat (instHSub.{0} Nat instSubNat) (HSub.hSub.{0, 0, 0} Nat Nat Nat (instHSub.{0} Nat instSubNat) (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat instAddNat) s n) (OfNat.ofNat.{0} Nat 1 (instOfNatNat 1))) i) (List.range n))
+Case conversion may be inaccurate. Consider using '#align list.reverse_range' List.reverse_range'ₓ'. -/
 theorem reverse_range' : ∀ s n : ℕ, reverse (range' s n) = map (fun i => s + n - 1 - i) (range n)
   | s, 0 => rfl
   | s, n + 1 => by
@@ -336,7 +417,6 @@ theorem reverse_range' : ∀ s n : ℕ, reverse (range' s n) = map (fun i => s +
         show a - 1 - i = a - succ i from pred_sub _ _, reverse_singleton, map_cons, tsub_zero,
         cons_append, nil_append, eq_self_iff_true, true_and_iff, map_map] using reverse_range' s n
 #align list.reverse_range' List.reverse_range'
--/
 
 #print List.finRange /-
 /-- All elements of `fin n`, from `0` to `n-1`. The corresponding finset is `finset.univ`. -/
@@ -412,13 +492,17 @@ theorem prod_range_succ' {α : Type u} [Monoid α] (f : ℕ → α) (n : ℕ) :
 #align list.prod_range_succ' List.prod_range_succ'
 #align list.sum_range_succ' List.sum_range_succ'
 
-#print List.enum_from_map_fst /-
+/- warning: list.enum_from_map_fst -> List.enum_from_map_fst is a dubious translation:
+lean 3 declaration is
+  forall {α : Type.{u1}} (n : Nat) (l : List.{u1} α), Eq.{1} (List.{0} Nat) (List.map.{u1, 0} (Prod.{0, u1} Nat α) Nat (Prod.fst.{0, u1} Nat α) (List.enumFrom.{u1} α n l)) (List.range' n (List.length.{u1} α l))
+but is expected to have type
+  forall {α : Type.{u1}} (n : Nat) (l : List.{u1} α), Eq.{1} (List.{0} Nat) (List.map.{u1, 0} (Prod.{0, u1} Nat α) Nat (Prod.fst.{0, u1} Nat α) (List.enumFrom.{u1} α n l)) (List.range' n (List.length.{u1} α l) (OfNat.ofNat.{0} Nat 1 (instOfNatNat 1)))
+Case conversion may be inaccurate. Consider using '#align list.enum_from_map_fst List.enum_from_map_fstₓ'. -/
 @[simp]
 theorem enum_from_map_fst : ∀ (n) (l : List α), map Prod.fst (enumFrom n l) = range' n l.length
   | n, [] => rfl
   | n, a :: l => congr_arg (cons _) (enum_from_map_fst _ _)
 #align list.enum_from_map_fst List.enum_from_map_fst
--/
 
 #print List.enum_map_fst /-
 @[simp]
@@ -440,19 +524,27 @@ theorem unzip_enum_eq_prod (l : List α) : l.enum.unzip = (range l.length, l) :=
 #align list.unzip_enum_eq_prod List.unzip_enum_eq_prod
 -/
 
-#print List.enum_from_eq_zip_range' /-
+/- warning: list.enum_from_eq_zip_range' -> List.enum_from_eq_zip_range' is a dubious translation:
+lean 3 declaration is
+  forall {α : Type.{u1}} (l : List.{u1} α) {n : Nat}, Eq.{succ u1} (List.{u1} (Prod.{0, u1} Nat α)) (List.enumFrom.{u1} α n l) (List.zip.{0, u1} Nat α (List.range' n (List.length.{u1} α l)) l)
+but is expected to have type
+  forall {α : Type.{u1}} (l : List.{u1} α) {n : Nat}, Eq.{succ u1} (List.{u1} (Prod.{0, u1} Nat α)) (List.enumFrom.{u1} α n l) (List.zip.{0, u1} Nat α (List.range' n (List.length.{u1} α l) (OfNat.ofNat.{0} Nat 1 (instOfNatNat 1))) l)
+Case conversion may be inaccurate. Consider using '#align list.enum_from_eq_zip_range' List.enum_from_eq_zip_range'ₓ'. -/
 theorem enum_from_eq_zip_range' (l : List α) {n : ℕ} : l.enumFrom n = (range' n l.length).zip l :=
   zip_of_prod (enum_from_map_fst _ _) (enumFrom_map_snd _ _)
 #align list.enum_from_eq_zip_range' List.enum_from_eq_zip_range'
--/
 
-#print List.unzip_enum_from_eq_prod /-
+/- warning: list.unzip_enum_from_eq_prod -> List.unzip_enum_from_eq_prod is a dubious translation:
+lean 3 declaration is
+  forall {α : Type.{u1}} (l : List.{u1} α) {n : Nat}, Eq.{succ u1} (Prod.{0, u1} (List.{0} Nat) (List.{u1} α)) (List.unzip.{0, u1} Nat α (List.enumFrom.{u1} α n l)) (Prod.mk.{0, u1} (List.{0} Nat) (List.{u1} α) (List.range' n (List.length.{u1} α l)) l)
+but is expected to have type
+  forall {α : Type.{u1}} (l : List.{u1} α) {n : Nat}, Eq.{succ u1} (Prod.{0, u1} (List.{0} Nat) (List.{u1} α)) (List.unzip.{0, u1} Nat α (List.enumFrom.{u1} α n l)) (Prod.mk.{0, u1} (List.{0} Nat) (List.{u1} α) (List.range' n (List.length.{u1} α l) (OfNat.ofNat.{0} Nat 1 (instOfNatNat 1))) l)
+Case conversion may be inaccurate. Consider using '#align list.unzip_enum_from_eq_prod List.unzip_enum_from_eq_prodₓ'. -/
 @[simp]
 theorem unzip_enum_from_eq_prod (l : List α) {n : ℕ} :
     (l.enumFrom n).unzip = (range' n l.length, l) := by
   simp only [enum_from_eq_zip_range', unzip_zip, length_range']
 #align list.unzip_enum_from_eq_prod List.unzip_enum_from_eq_prod
--/
 
 #print List.nthLe_range /-
 @[simp]

Changes in mathlib4

mathlib3
mathlib4
chore(Data/List/Enum): move from Basic (#11697)
Diff
@@ -4,9 +4,10 @@ Released under Apache 2.0 license as described in the file LICENSE.
 Authors: Mario Carneiro, Kenny Lau, Scott Morrison
 -/
 import Mathlib.Data.List.Chain
+import Mathlib.Data.List.Enum
 import Mathlib.Data.List.Nodup
-import Mathlib.Data.List.Zip
 import Mathlib.Data.List.Pairwise
+import Mathlib.Data.List.Zip
 
 #align_import data.list.range from "leanprover-community/mathlib"@"7b78d1776212a91ecc94cf601f83bdcc46b04213"
 
chore(Data/List): Depend less on big operators (#11741)
  • Make Data.List.Count, Data.List.Dedup, Data.List.ProdSigma, Data.List.Range, Data.List.Rotate, Data.List.Zip not depend on Data.List.BigOperators.Basic.
  • As a consequence, move the big operators lemmas that were in there to Data.List.BigOperators.Basic. For the lemmas that were Nat-specific, keep a version of them in the original file but stated using Nat.sum.
  • To help with this, add Nat.sum_eq_listSum (l : List Nat) : Nat.sum l = l.sum.
Diff
@@ -165,24 +165,6 @@ theorem pairwise_lt_finRange (n : ℕ) : Pairwise (· < ·) (finRange n) :=
 theorem pairwise_le_finRange (n : ℕ) : Pairwise (· ≤ ·) (finRange n) :=
   (List.pairwise_le_range n).pmap (by simp) (by simp)
 
-@[to_additive]
-theorem prod_range_succ {α : Type u} [Monoid α] (f : ℕ → α) (n : ℕ) :
-    ((range n.succ).map f).prod = ((range n).map f).prod * f n := by
-  rw [range_succ, map_append, map_singleton, prod_append, prod_cons, prod_nil, mul_one]
-#align list.prod_range_succ List.prod_range_succ
-#align list.sum_range_succ List.sum_range_succ
-
-/-- A variant of `prod_range_succ` which pulls off the first
-  term in the product rather than the last.-/
-@[to_additive
-  "A variant of `sum_range_succ` which pulls off the first term in the sum rather than the last."]
-theorem prod_range_succ' {α : Type u} [Monoid α] (f : ℕ → α) (n : ℕ) :
-    ((range n.succ).map f).prod = f 0 * ((range n).map fun i => f (succ i)).prod :=
-  Nat.recOn n (show 1 * f 0 = f 0 * 1 by rw [one_mul, mul_one]) fun _ hd => by
-    rw [List.prod_range_succ, hd, mul_assoc, ← List.prod_range_succ]
-#align list.prod_range_succ' List.prod_range_succ'
-#align list.sum_range_succ' List.sum_range_succ'
-
 #align list.enum_from_map_fst List.enumFrom_map_fst
 #align list.enum_map_fst List.enum_map_fst
 
@@ -259,7 +241,7 @@ theorem ranges_disjoint (l : List ℕ) :
       rw [mem_map]
       rintro ⟨v, _, rfl⟩
       rw [mem_range] at hu
-      exact lt_iff_not_le.mp hu le_self_add
+      omega
     · rw [pairwise_map]
       apply Pairwise.imp _ hl
       intro u v
@@ -279,26 +261,20 @@ theorem ranges_length (l : List ℕ) :
     intro s _
     simp only [Function.comp_apply, length_map]
 
-theorem ranges_join (l : List ℕ) :
-    l.ranges.join = range l.sum := by
-  induction l with
-  | nil => exact rfl
-  | cons a l hl =>
-    simp only [sum_cons, join]
-    rw [← map_join, hl]
-    rw [range_add]
+/-- See `List.ranges_join` for the version about `List.sum`. -/
+lemma ranges_join' : ∀ l : List ℕ, l.ranges.join = range (Nat.sum l)
+  | [] => rfl
+  | a :: l => by simp only [sum_cons, join, ← map_join, ranges_join', range_add]
 
-/-- Any entry of any member of `l.ranges` is strictly smaller than `l.sum` -/
-theorem mem_mem_ranges_iff_lt_sum (l : List ℕ) {n : ℕ} :
-    (∃ s ∈ List.ranges l,  n ∈ s) ↔ n < l.sum := by
-  rw [← mem_range, ← ranges_join, mem_join]
+/-- Any entry of any member of `l.ranges` is strictly smaller than `Nat.sum l`.
+See `List.mem_mem_ranges_iff_lt_sum` for the version about `List.sum`. -/
+lemma mem_mem_ranges_iff_lt_natSum (l : List ℕ) {n : ℕ} :
+    (∃ s ∈ l.ranges, n ∈ s) ↔ n < Nat.sum l := by
+  rw [← mem_range, ← ranges_join', mem_join]
 
  /-- The members of `l.ranges` have no duplicate -/
-theorem ranges_nodup {l s : List ℕ} (hs : s ∈ ranges l) :
-    s.Nodup := by
-  refine (List.pairwise_join.mp ?_).1 s hs
-  rw [ranges_join]
-  exact nodup_range (sum l)
+theorem ranges_nodup {l s : List ℕ} (hs : s ∈ ranges l) : s.Nodup :=
+  (List.pairwise_join.mp $ by rw [ranges_join']; exact nodup_range _).1 s hs
 
 end Ranges
 
chore: classify new theorem / theorem porting notes (#11432)

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

  • "added theorem"
  • "added theorems"
  • "new theorem"
  • "new theorems"
  • "added lemma"
  • "new lemma"
  • "new lemmas"
Diff
@@ -211,13 +211,13 @@ theorem nthLe_range {n} (i) (H : i < (range n).length) : nthLe (range n) i H = i
   get_range i H
 #align list.nth_le_range List.nthLe_range
 
--- Porting note: new theorem
+-- Porting note (#10756): new theorem
 @[simp]
 theorem get_finRange {n : ℕ} {i : ℕ} (h) :
     (finRange n).get ⟨i, h⟩ = ⟨i, length_finRange n ▸ h⟩ := by
   simp only [finRange, get_range, get_pmap]
 
--- Porting note: new theorem, corresponding theorem used to be in Data.List.FinRange
+-- Porting note (#10756): new theorem, corresponding theorem used to be in Data.List.FinRange
 @[simp]
 theorem finRange_map_get (l : List α) : (finRange l.length).map l.get = l :=
   List.ext_get (by simp) (by simp)
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
@@ -217,7 +217,7 @@ theorem get_finRange {n : ℕ} {i : ℕ} (h) :
     (finRange n).get ⟨i, h⟩ = ⟨i, length_finRange n ▸ h⟩ := by
   simp only [finRange, get_range, get_pmap]
 
---Porting note: new theorem, corresponding theorem used to be in Data.List.FinRange
+-- Porting note: new theorem, corresponding theorem used to be in Data.List.FinRange
 @[simp]
 theorem finRange_map_get (l : List α) : (finRange l.length).map l.get = l :=
   List.ext_get (by simp) (by simp)
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
@@ -4,9 +4,9 @@ Released under Apache 2.0 license as described in the file LICENSE.
 Authors: Mario Carneiro, Kenny Lau, Scott Morrison
 -/
 import Mathlib.Data.List.Chain
-import Mathlib.Data.List.Join
 import Mathlib.Data.List.Nodup
 import Mathlib.Data.List.Zip
+import Mathlib.Data.List.Pairwise
 
 #align_import data.list.range from "leanprover-community/mathlib"@"7b78d1776212a91ecc94cf601f83bdcc46b04213"
 
chore: tidy various files (#8823)
Diff
@@ -243,7 +243,7 @@ section Ranges
 * Example: `[1,2,3].ranges = [[0],[1,2],[3,4,5]]` -/
 def ranges : List ℕ → List (List ℕ)
   | [] => nil
-  | a::l => range a::(ranges l).map (map (Nat.add a))
+  | a::l => range a::(ranges l).map (map (a + ·))
 
 /-- The members of `l.ranges` are pairwise disjoint -/
 theorem ranges_disjoint (l : List ℕ) :
@@ -287,7 +287,6 @@ theorem ranges_join (l : List ℕ) :
     simp only [sum_cons, join]
     rw [← map_join, hl]
     rw [range_add]
-    rfl
 
 /-- Any entry of any member of `l.ranges` is strictly smaller than `l.sum` -/
 theorem mem_mem_ranges_iff_lt_sum (l : List ℕ) {n : ℕ} :
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
@@ -76,14 +76,15 @@ theorem nthLe_range'_1 {n m} (i) (H : i < (range' n m).length) :
 #align list.range_eq_nil List.range_eq_nil
 
 theorem pairwise_lt_range (n : ℕ) : Pairwise (· < ·) (range n) := by
-  simp only [range_eq_range', pairwise_lt_range']
+  simp (config := {decide := true}) only [range_eq_range', pairwise_lt_range']
 #align list.pairwise_lt_range List.pairwise_lt_range
 
 theorem pairwise_le_range (n : ℕ) : Pairwise (· ≤ ·) (range n) :=
   Pairwise.imp (@le_of_lt ℕ _) (pairwise_lt_range _)
 #align list.pairwise_le_range List.pairwise_le_range
 
-theorem nodup_range (n : ℕ) : Nodup (range n) := by simp only [range_eq_range', nodup_range']
+theorem nodup_range (n : ℕ) : Nodup (range n) := by
+  simp (config := {decide := true}) only [range_eq_range', nodup_range']
 #align list.nodup_range List.nodup_range
 #align list.range_sublist List.range_sublist
 #align list.range_subset List.range_subset
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
@@ -4,6 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE.
 Authors: Mario Carneiro, Kenny Lau, Scott Morrison
 -/
 import Mathlib.Data.List.Chain
+import Mathlib.Data.List.Join
 import Mathlib.Data.List.Nodup
 import Mathlib.Data.List.Zip
 
@@ -234,4 +235,71 @@ theorem nthLe_finRange {n : ℕ} {i : ℕ} (h) :
   have h₂ : (finRange k).get ⟨i, by simp⟩ = i := get_finRange _
   simpa using (Nodup.get_inj_iff (nodup_finRange k)).mp (Eq.trans h₁ h₂.symm)
 
+section Ranges
+
+/-- From `l : List ℕ`, construct `l.ranges : List (List ℕ)` such that
+  `l.ranges.map List.length = l` and `l.ranges.join = range l.sum`
+* Example: `[1,2,3].ranges = [[0],[1,2],[3,4,5]]` -/
+def ranges : List ℕ → List (List ℕ)
+  | [] => nil
+  | a::l => range a::(ranges l).map (map (Nat.add a))
+
+/-- The members of `l.ranges` are pairwise disjoint -/
+theorem ranges_disjoint (l : List ℕ) :
+    Pairwise Disjoint (ranges l) := by
+  induction l with
+  | nil => exact Pairwise.nil
+  | cons a l hl =>
+    simp only [ranges, pairwise_cons]
+    constructor
+    · intro s hs
+      obtain ⟨s', _, rfl⟩ := mem_map.mp hs
+      intro u hu
+      rw [mem_map]
+      rintro ⟨v, _, rfl⟩
+      rw [mem_range] at hu
+      exact lt_iff_not_le.mp hu le_self_add
+    · rw [pairwise_map]
+      apply Pairwise.imp _ hl
+      intro u v
+      apply disjoint_map
+      exact fun u v => Nat.add_left_cancel
+#align list.ranges_disjoint List.ranges_disjoint
+
+/-- The lengths of the members of `l.ranges` are those given by `l` -/
+theorem ranges_length (l : List ℕ) :
+    l.ranges.map length = l := by
+  induction l with
+  | nil => simp only [ranges, map_nil]
+  | cons a l hl => -- (a :: l)
+    simp only [map, length_range, map_map, cons.injEq, true_and]
+    conv_rhs => rw [← hl]
+    apply map_congr
+    intro s _
+    simp only [Function.comp_apply, length_map]
+
+theorem ranges_join (l : List ℕ) :
+    l.ranges.join = range l.sum := by
+  induction l with
+  | nil => exact rfl
+  | cons a l hl =>
+    simp only [sum_cons, join]
+    rw [← map_join, hl]
+    rw [range_add]
+    rfl
+
+/-- Any entry of any member of `l.ranges` is strictly smaller than `l.sum` -/
+theorem mem_mem_ranges_iff_lt_sum (l : List ℕ) {n : ℕ} :
+    (∃ s ∈ List.ranges l,  n ∈ s) ↔ n < l.sum := by
+  rw [← mem_range, ← ranges_join, mem_join]
+
+ /-- The members of `l.ranges` have no duplicate -/
+theorem ranges_nodup {l s : List ℕ} (hs : s ∈ ranges l) :
+    s.Nodup := by
+  refine (List.pairwise_join.mp ?_).1 s hs
+  rw [ranges_join]
+  exact nodup_range (sum l)
+
+end Ranges
+
 end List
feat(Data/List/Range + Data/Finset/Sort): List.finRange lemmas (#7184)

Prove Fin.sort_univ and List.indexOf_finRange discussed in https://leanprover.zulipchat.com/#narrow/stream/113489-new-members/topic/.E2.9C.94.20value.20of.20.60fintypeEquivFin.60

Co-authored-by: palalansoukî <73170405+iehality@users.noreply.github.com> Co-authored-by: Eric Wieser <wieser.eric@gmail.com>

Diff
@@ -4,6 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE.
 Authors: Mario Carneiro, Kenny Lau, Scott Morrison
 -/
 import Mathlib.Data.List.Chain
+import Mathlib.Data.List.Nodup
 import Mathlib.Data.List.Zip
 
 #align_import data.list.range from "leanprover-community/mathlib"@"7b78d1776212a91ecc94cf601f83bdcc46b04213"
@@ -156,6 +157,12 @@ theorem finRange_eq_nil {n : ℕ} : finRange n = [] ↔ n = 0 := by
   rw [← length_eq_zero, length_finRange]
 #align list.fin_range_eq_nil List.finRange_eq_nil
 
+theorem pairwise_lt_finRange (n : ℕ) : Pairwise (· < ·) (finRange n) :=
+  (List.pairwise_lt_range n).pmap (by simp) (by simp)
+
+theorem pairwise_le_finRange (n : ℕ) : Pairwise (· ≤ ·) (finRange n) :=
+  (List.pairwise_le_range n).pmap (by simp) (by simp)
+
 @[to_additive]
 theorem prod_range_succ {α : Type u} [Monoid α] (f : ℕ → α) (n : ℕ) :
     ((range n.succ).map f).prod = ((range n).map f).prod * f n := by
@@ -221,4 +228,10 @@ theorem nthLe_finRange {n : ℕ} {i : ℕ} (h) :
   get_finRange h
 #align list.nth_le_fin_range List.nthLe_finRange
 
+@[simp] theorem indexOf_finRange (i : Fin k) : (finRange k).indexOf i = i := by
+  have : (finRange k).indexOf i < (finRange k).length := indexOf_lt_length.mpr (by simp)
+  have h₁ : (finRange k).get ⟨(finRange k).indexOf i, this⟩ = i := indexOf_get this
+  have h₂ : (finRange k).get ⟨i, by simp⟩ = i := get_finRange _
+  simpa using (Nodup.get_inj_iff (nodup_finRange k)).mp (Eq.trans h₁ h₂.symm)
+
 end List
fix: disable autoImplicit globally (#6528)

Autoimplicits are highly controversial and also defeat the performance-improving work in #6474.

The intent of this PR is to make autoImplicit opt-in on a per-file basis, by disabling it in the lakefile and enabling it again with set_option autoImplicit true in the few files that rely on it.

That also keeps this PR small, as opposed to attempting to "fix" files to not need it any more.

I claim that many of the uses of autoImplicit in these files are accidental; situations such as:

  • Assuming variables are in scope, but pasting the lemma in the wrong section
  • Pasting in a lemma from a scratch file without checking to see if the variable names are consistent with the rest of the file
  • Making a copy-paste error between lemmas and forgetting to add an explicit arguments.

Having set_option autoImplicit false as the default prevents these types of mistake being made in the 90% of files where autoImplicits are not used at all, and causes them to be caught by CI during review.

I think there were various points during the port where we encouraged porters to delete the universes u v lines; I think having autoparams for universe variables only would cover a lot of the cases we actually use them, while avoiding any real shortcomings.

A Zulip poll (after combining overlapping votes accordingly) was in favor of this change with 5:5:18 as the no:dontcare:yes vote ratio.

While this PR was being reviewed, a handful of files gained some more likely-accidental autoImplicits. In these places, set_option autoImplicit true has been placed locally within a section, rather than at the top of the file.

Diff
@@ -19,6 +19,8 @@ tactics. `range' a b = [a, ..., a + b - 1]` is there to help prove properties ab
 Actual maths should use `List.Ico` instead.
 -/
 
+set_option autoImplicit true
+
 
 universe u
 
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,15 +2,12 @@
 Copyright (c) 2018 Mario Carneiro. All rights reserved.
 Released under Apache 2.0 license as described in the file LICENSE.
 Authors: Mario Carneiro, Kenny Lau, Scott Morrison
-
-! This file was ported from Lean 3 source module data.list.range
-! leanprover-community/mathlib commit 7b78d1776212a91ecc94cf601f83bdcc46b04213
-! Please do not edit these lines, except to modify the commit id
-! if you have ported upstream changes.
 -/
 import Mathlib.Data.List.Chain
 import Mathlib.Data.List.Zip
 
+#align_import data.list.range from "leanprover-community/mathlib"@"7b78d1776212a91ecc94cf601f83bdcc46b04213"
+
 /-!
 # Ranges of naturals as lists
 
chore: disable relaxedAutoImplicit (#5277)

We disable the "relaxed" auto-implicit feature, so only single character identifiers become eligible as auto-implicits. See discussion on zulip and 2.

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

Diff
@@ -31,7 +31,7 @@ namespace List
 
 variable {α : Type u}
 
-@[simp] theorem range'_one : range' s 1 step = [s] := rfl
+@[simp] theorem range'_one {step} : range' s 1 step = [s] := rfl
 
 #align list.length_range' List.length_range'
 #align list.range'_eq_nil List.range'_eq_nil
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
@@ -14,8 +14,8 @@ import Mathlib.Data.List.Zip
 /-!
 # Ranges of naturals as lists
 
-This file shows basic results about `List.iota`, `List.range`, `List.range'` (all defined in
-`data.list.defs`) and defines `List.finRange`.
+This file shows basic results about `List.iota`, `List.range`, `List.range'`
+and defines `List.finRange`.
 `finRange n` is the list of elements of `Fin n`.
 `iota n = [n, n - 1, ..., 1]` and `range n = [0, ..., n - 1]` are basic list constructions used for
 tactics. `range' a b = [a, ..., a + b - 1]` is there to help prove properties about them.
@@ -31,133 +31,47 @@ namespace List
 
 variable {α : Type u}
 
-@[simp]
-theorem length_range' : ∀ s n : ℕ, length (range' s n) = n
-  | _, 0 => rfl
-  | _, _ + 1 => congr_arg succ (length_range' _ _)
-#align list.length_range' List.length_range'
+@[simp] theorem range'_one : range' s 1 step = [s] := rfl
 
-@[simp]
-theorem range'_eq_nil {s n : ℕ} : range' s n = [] ↔ n = 0 := by rw [← length_eq_zero, length_range']
+#align list.length_range' List.length_range'
 #align list.range'_eq_nil List.range'_eq_nil
-
-@[simp]
-theorem mem_range' {m : ℕ} : ∀ {s n : ℕ}, m ∈ range' s n ↔ s ≤ m ∧ m < s + n
-  | s, 0 => by
-    simp only [range', find?, not_mem_nil, add_zero, false_iff, not_and, not_lt, imp_self]
-  | s, n + 1 =>
-    have : m = s → m < s + n + 1 := fun e => e ▸ lt_succ_of_le (Nat.le_add_right _ _)
-    have l : m = s ∨ s + 1 ≤ m ↔ s ≤ m := by
-      simpa only [eq_comm] using (@Decidable.le_iff_eq_or_lt _ _ _ s m).symm
-    mem_cons.trans <| by
-      simp only [@mem_range' m (s + 1) n, or_and_left, or_iff_right_of_imp this, l,
-        add_right_comm, add_eq, add_zero, and_congr_right_iff, add_assoc, or_iff_right_iff_imp]
-      intro; exact this
-#align list.mem_range' List.mem_range'
-
-theorem map_add_range' (a) : ∀ s n : ℕ, map ((· + ·) a) (range' s n) = range' (a + s) n
-  | _, 0 => rfl
-  | s, n + 1 => congr_arg (cons _) (map_add_range' _ (s + 1) n)
+#align list.mem_range' List.mem_range'_1
 #align list.map_add_range' List.map_add_range'
-
-theorem map_sub_range' (a) :
-    ∀ (s n : ℕ) (_ : a ≤ s), map (fun x => x - a) (range' s n) = range' (s - a) n
-  | s, 0, _ => rfl
-  | s, n + 1, h => by
-    convert congr_arg (cons (s - a)) (map_sub_range' _ (s + 1) n (Nat.le_succ_of_le h)) using 1
-    rw [Nat.succ_sub h]
-    rfl
 #align list.map_sub_range' List.map_sub_range'
-
-theorem chain_succ_range' : ∀ s n : ℕ, Chain (fun a b => b = succ a) s (range' (s + 1) n)
-  | _, 0 => Chain.nil
-  | s, n + 1 => (chain_succ_range' (s + 1) n).cons rfl
 #align list.chain_succ_range' List.chain_succ_range'
-
-theorem chain_lt_range' (s n : ℕ) : Chain (· < ·) s (range' (s + 1) n) :=
-  (chain_succ_range' s n).imp fun _ _ e => e.symm ▸ lt_succ_self _
 #align list.chain_lt_range' List.chain_lt_range'
 
-theorem pairwise_lt_range' : ∀ s n : ℕ, Pairwise (· < ·) (range' s n)
-  | _, 0 => Pairwise.nil
-  | s, n + 1 => chain_iff_pairwise.1 (chain_lt_range' s n)
+theorem pairwise_lt_range' : ∀ s n (step := 1) (_ : 0 < step := by simp),
+  Pairwise (· < ·) (range' s n step)
+  | _, 0, _, _ => Pairwise.nil
+  | s, n + 1, _, h => chain_iff_pairwise.1 (chain_lt_range' s n h)
 #align list.pairwise_lt_range' List.pairwise_lt_range'
 
-theorem nodup_range' (s n : ℕ) : Nodup (range' s n) :=
-  (pairwise_lt_range' s n).imp _root_.ne_of_lt
+theorem nodup_range' (s n : ℕ) (step := 1) (h : 0 < step := by simp) : Nodup (range' s n step) :=
+  (pairwise_lt_range' s n step h).imp _root_.ne_of_lt
 #align list.nodup_range' List.nodup_range'
-
-@[simp]
-theorem range'_append : ∀ s m n : ℕ, range' s m ++ range' (s + m) n = range' s (n + m)
-  | s, 0, n => rfl
-  | s, m + 1, n =>
-    show s :: (range' (s + 1) m ++ range' (s + m + 1) n) = s :: range' (s + 1) (n + m) by
-      rw [add_right_comm, range'_append (s + 1) m n]
 #align list.range'_append List.range'_append
-
-theorem range'_sublist_right {s m n : ℕ} : range' s m <+ range' s n ↔ m ≤ n :=
-  ⟨fun h => by simpa only [length_range'] using h.length_le, fun h => by
-    rw [← tsub_add_cancel_of_le h, ← range'_append] ; apply sublist_append_left⟩
 #align list.range'_sublist_right List.range'_sublist_right
-
-theorem range'_subset_right {s m n : ℕ} : range' s m ⊆ range' s n ↔ m ≤ n :=
-  ⟨fun h =>
-    le_of_not_lt fun hn =>
-      lt_irrefl (s + n) <|
-        (mem_range'.1 <| h <| mem_range'.2 ⟨Nat.le_add_right _ _, Nat.add_lt_add_left hn s⟩).2,
-    fun h => (range'_sublist_right.2 h).subset⟩
 #align list.range'_subset_right List.range'_subset_right
-
-theorem get?_range' : ∀ (s) {m n : ℕ}, m < n → get? (range' s n) m = some (s + m)
-  | s, 0, n + 1, _ => rfl
-  | s, m + 1, n + 1, h =>
-    (get?_range' (s + 1) (lt_of_add_lt_add_right h)).trans <| by rw [add_right_comm] ; rfl
 #align list.nth_range' List.get?_range'
 
--- Porting note: new theorem
+set_option linter.deprecated false in
 @[simp]
-theorem get_range' {n m} (i) (H : i < (range' n m).length) : get (range' n m) ⟨i, H⟩ = n + i :=
-  Option.some.inj <| by rw [← get?_eq_get _, get?_range' _ (by simpa using H)]
+theorem nthLe_range' {n m step} (i) (H : i < (range' n m step).length) :
+    nthLe (range' n m step) i H = n + step * i := get_range' i H
 
 set_option linter.deprecated false in
-@[simp]
-theorem nthLe_range' {n m} (i) (H : i < (range' n m).length) : nthLe (range' n m) i H = n + i :=
-  get_range' i H
-#align list.nth_le_range' List.nthLe_range'
+theorem nthLe_range'_1 {n m} (i) (H : i < (range' n m).length) :
+    nthLe (range' n m) i H = n + i := by simp
+#align list.nth_le_range' List.nthLe_range'_1
 
-theorem range'_concat (s n : ℕ) : range' s (n + 1) = range' s n ++ [s + n] := by
-  rw [add_comm n 1] ; exact (range'_append s n 1).symm
 #align list.range'_concat List.range'_concat
-
 #align list.range_core List.range.loop
-
-theorem range_loop_range' : ∀ s n : ℕ, range.loop s (range' s n) = range' 0 (n + s)
-  | 0, n => rfl
-  | s + 1, n => by
-    rw [show n + (s + 1) = n + 1 + s from add_right_comm n s 1]
-    exact range_loop_range' s (n + 1)
 #align list.range_core_range' List.range_loop_range'
-
-theorem range_eq_range' (n : ℕ) : range n = range' 0 n :=
-  (range_loop_range' n 0).trans <| by rw [zero_add]
 #align list.range_eq_range' List.range_eq_range'
-
-theorem range_succ_eq_map (n : ℕ) : range (n + 1) = 0 :: map succ (range n) := by
-  rw [range_eq_range', range_eq_range', range', add_comm, ← map_add_range']
-  congr
-  exact funext one_add
 #align list.range_succ_eq_map List.range_succ_eq_map
-
-theorem range'_eq_map_range (s n : ℕ) : range' s n = map (s + ·) (range n) := by
-  rw [range_eq_range', map_add_range'] ; rfl
 #align list.range'_eq_map_range List.range'_eq_map_range
-
-@[simp]
-theorem length_range (n : ℕ) : length (range n) = n := by simp only [range_eq_range', length_range']
 #align list.length_range List.length_range
-
-@[simp]
-theorem range_eq_nil {n : ℕ} : range n = [] ↔ n = 0 := by rw [← length_eq_zero, length_range]
 #align list.range_eq_nil List.range_eq_nil
 
 theorem pairwise_lt_range (n : ℕ) : Pairwise (· < ·) (range n) := by
@@ -170,41 +84,13 @@ theorem pairwise_le_range (n : ℕ) : Pairwise (· ≤ ·) (range n) :=
 
 theorem nodup_range (n : ℕ) : Nodup (range n) := by simp only [range_eq_range', nodup_range']
 #align list.nodup_range List.nodup_range
-
-theorem range_sublist {m n : ℕ} : range m <+ range n ↔ m ≤ n := by
-  simp only [range_eq_range', range'_sublist_right]
 #align list.range_sublist List.range_sublist
-
-theorem range_subset {m n : ℕ} : range m ⊆ range n ↔ m ≤ n := by
-  simp only [range_eq_range', range'_subset_right]
 #align list.range_subset List.range_subset
-
-@[simp]
-theorem mem_range {m n : ℕ} : m ∈ range n ↔ m < n := by
-  simp only [range_eq_range', mem_range', Nat.zero_le, true_and_iff, zero_add]
 #align list.mem_range List.mem_range
-
--- @[simp] -- Porting note: simp can prove this
-theorem not_mem_range_self {n : ℕ} : n ∉ range n :=
-  mt mem_range.1 <| lt_irrefl _
 #align list.not_mem_range_self List.not_mem_range_self
-
--- @[simp] -- Porting note: simp can prove this
-theorem self_mem_range_succ (n : ℕ) : n ∈ range (n + 1) := by
-  simp only [succ_pos', lt_add_iff_pos_right, mem_range]
 #align list.self_mem_range_succ List.self_mem_range_succ
-
-theorem get?_range {m n : ℕ} (h : m < n) : get? (range n) m = some m := by
-  simp only [range_eq_range', get?_range' _ h, zero_add]
 #align list.nth_range List.get?_range
-
-theorem range_succ (n : ℕ) : range (succ n) = range n ++ [n] := by
-  simp only [range_eq_range', range'_concat, zero_add]
 #align list.range_succ List.range_succ
-
-@[simp]
-theorem range_zero : range 0 = [] :=
-  rfl
 #align list.range_zero List.range_zero
 
 theorem chain'_range_succ (r : ℕ → ℕ → Prop) (n : ℕ) :
@@ -224,22 +110,8 @@ theorem chain_range_succ (r : ℕ → ℕ → Prop) (n a : ℕ) :
   exact fun _ => Iff.rfl
 #align list.chain_range_succ List.chain_range_succ
 
-theorem range_add (a : ℕ) : ∀ b, range (a + b) = range a ++ (range b).map fun x => a + x
-  | 0 => by rw [add_zero, range_zero, map_nil, append_nil]
-  | b + 1 => by
-    rw [Nat.add_succ, range_succ, range_add a b, range_succ, map_append,
-      map_singleton, append_assoc]
 #align list.range_add List.range_add
-
-theorem iota_eq_reverse_range' : ∀ n : ℕ, iota n = reverse (range' 1 n)
-  | 0 => rfl
-  | n + 1 => by
-    simp only [iota, range'_concat, iota_eq_reverse_range' (n.add 0), reverse_append, add_comm]; rfl
 #align list.iota_eq_reverse_range' List.iota_eq_reverse_range'
-
-@[simp]
-theorem length_iota (n : ℕ) : length (iota n) = n := by
-  simp only [iota_eq_reverse_range', length_reverse, length_range']
 #align list.length_iota List.length_iota
 
 theorem pairwise_gt_iota (n : ℕ) : Pairwise (· > ·) (iota n) := by
@@ -250,17 +122,7 @@ theorem nodup_iota (n : ℕ) : Nodup (iota n) :=
   (pairwise_gt_iota n).imp _root_.ne_of_gt
 #align list.nodup_iota List.nodup_iota
 
-theorem mem_iota {m n : ℕ} : m ∈ iota n ↔ 1 ≤ m ∧ m ≤ n := by
-  simp only [iota_eq_reverse_range', mem_reverse, mem_range', add_comm, lt_succ_iff]
 #align list.mem_iota List.mem_iota
-
-theorem reverse_range' : ∀ s n : ℕ, reverse (range' s n) = map (fun i => s + n - 1 - i) (range n)
-  | s, 0 => rfl
-  | s, n + 1 => by
-    rw [range'_concat, reverse_append, range_succ_eq_map]
-    simp only [show s + (n + 1) - 1 = s + n from rfl, (· ∘ ·), fun a i =>
-      show a - 1 - i = a - succ i from pred_sub _ _, reverse_singleton, map_cons, tsub_zero,
-      cons_append, nil_append, eq_self_iff_true, true_and_iff, map_map, reverse_range' s n]
 #align list.reverse_range' List.reverse_range'
 
 /-- All elements of `Fin n`, from `0` to `n-1`. The corresponding finset is `Finset.univ`. -/
@@ -313,15 +175,7 @@ theorem prod_range_succ' {α : Type u} [Monoid α] (f : ℕ → α) (n : ℕ) :
 #align list.prod_range_succ' List.prod_range_succ'
 #align list.sum_range_succ' List.sum_range_succ'
 
-@[simp]
-theorem enum_from_map_fst : ∀ (n) (l : List α), map Prod.fst (enumFrom n l) = range' n l.length
-  | _, [] => rfl
-  | _, _ :: _ => congr_arg (cons _) (enum_from_map_fst _ _)
-#align list.enum_from_map_fst List.enum_from_map_fst
-
-@[simp]
-theorem enum_map_fst (l : List α) : map Prod.fst (enum l) = range l.length := by
-  simp only [enum, enum_from_map_fst, range_eq_range']
+#align list.enum_from_map_fst List.enumFrom_map_fst
 #align list.enum_map_fst List.enum_map_fst
 
 theorem enum_eq_zip_range (l : List α) : l.enum = (range l.length).zip l :=
@@ -333,20 +187,15 @@ theorem unzip_enum_eq_prod (l : List α) : l.enum.unzip = (range l.length, l) :=
   simp only [enum_eq_zip_range, unzip_zip, length_range]
 #align list.unzip_enum_eq_prod List.unzip_enum_eq_prod
 
-theorem enum_from_eq_zip_range' (l : List α) {n : ℕ} : l.enumFrom n = (range' n l.length).zip l :=
-  zip_of_prod (enum_from_map_fst _ _) (enumFrom_map_snd _ _)
-#align list.enum_from_eq_zip_range' List.enum_from_eq_zip_range'
+theorem enumFrom_eq_zip_range' (l : List α) {n : ℕ} : l.enumFrom n = (range' n l.length).zip l :=
+  zip_of_prod (enumFrom_map_fst _ _) (enumFrom_map_snd _ _)
+#align list.enum_from_eq_zip_range' List.enumFrom_eq_zip_range'
 
 @[simp]
-theorem unzip_enum_from_eq_prod (l : List α) {n : ℕ} :
+theorem unzip_enumFrom_eq_prod (l : List α) {n : ℕ} :
     (l.enumFrom n).unzip = (range' n l.length, l) := by
-  simp only [enum_from_eq_zip_range', unzip_zip, length_range']
-#align list.unzip_enum_from_eq_prod List.unzip_enum_from_eq_prod
-
--- Porting note: new theorem
-@[simp]
-theorem get_range {n} (i) (H : i < (range n).length) : get (range n) ⟨i, H⟩ = i :=
-  Option.some.inj <| by rw [← get?_eq_get _, get?_range (by simpa using H)]
+  simp only [enumFrom_eq_zip_range', unzip_zip, length_range']
+#align list.unzip_enum_from_eq_prod List.unzip_enumFrom_eq_prod
 
 set_option linter.deprecated false in
 @[simp]
feat: improvements to congr! and convert (#2606)
  • There is now configuration for congr!, convert, and convert_to to control parts of the congruence algorithm, in particular transparency settings when applying congruence lemmas.
  • congr! now applies congruence lemmas with reducible transparency by default. This prevents it from unfolding definitions when applying congruence lemmas. It also now tries both the LHS-biased and RHS-biased simp congruence lemmas, with a configuration option to set which it should try first.
  • There is now a new HEq congruence lemma generator that gives each hypothesis access to the proofs of previous hypotheses. This means that if you have an equality ⊢ ⟨a, x⟩ = ⟨b, y⟩ of sigma types, congr! turns this into goals ⊢ a = b and ⊢ a = b → HEq x y (note that congr! will also auto-introduce a = b for you in the second goal). This congruence lemma generator applies to more cases than the simp congruence lemma generator does.
  • congr! (and hence convert) are more careful about applying lemmas that don't force definitions to unfold. There were a number of cases in mathlib where the implementation of congr was being abused to unfold definitions.
  • With set_option trace.congr! true you can see what congr! sees when it is deciding on congruence lemmas.
  • There is also a bug fix in convert_to to do using 1 when there is no using clause, to match its documentation.

Note that congr! is more capable than congr at finding a way to equate left-hand sides and right-hand sides, so you will frequently need to limit its depth with a using clause. However, there is also a new heuristic to prevent considering unlikely-to-be-provable type equalities (controlled by the typeEqs option), which can help limit the depth automatically.

There is also a predefined configuration that you can invoke with, for example, convert (config := .unfoldSameFun) h, that causes it to behave more like congr, including using default transparency when unfolding.

Diff
@@ -64,7 +64,7 @@ theorem map_sub_range' (a) :
     ∀ (s n : ℕ) (_ : a ≤ s), map (fun x => x - a) (range' s n) = range' (s - a) n
   | s, 0, _ => rfl
   | s, n + 1, h => by
-    convert congr_arg (cons (s - a)) (map_sub_range' _ (s + 1) n (Nat.le_succ_of_le h))
+    convert congr_arg (cons (s - a)) (map_sub_range' _ (s + 1) n (Nat.le_succ_of_le h)) using 1
     rw [Nat.succ_sub h]
     rfl
 #align list.map_sub_range' List.map_sub_range'
chore: tidy various files (#2056)
Diff
@@ -14,12 +14,12 @@ import Mathlib.Data.List.Zip
 /-!
 # Ranges of naturals as lists
 
-This file shows basic results about `list.iota`, `list.range`, `list.range'` (all defined in
-`data.list.defs`) and defines `list.fin_range`.
-`fin_range n` is the list of elements of `fin n`.
+This file shows basic results about `List.iota`, `List.range`, `List.range'` (all defined in
+`data.list.defs`) and defines `List.finRange`.
+`finRange n` is the list of elements of `Fin n`.
 `iota n = [n, n - 1, ..., 1]` and `range n = [0, ..., n - 1]` are basic list constructions used for
 tactics. `range' a b = [a, ..., a + b - 1]` is there to help prove properties about them.
-Actual maths should use `list.Ico` instead.
+Actual maths should use `List.Ico` instead.
 -/
 
 
@@ -121,9 +121,9 @@ theorem get_range' {n m} (i) (H : i < (range' n m).length) : get (range' n m) 
 
 set_option linter.deprecated false in
 @[simp]
-theorem nth_le_range' {n m} (i) (H : i < (range' n m).length) : nthLe (range' n m) i H = n + i :=
+theorem nthLe_range' {n m} (i) (H : i < (range' n m).length) : nthLe (range' n m) i H = n + i :=
   get_range' i H
-#align list.nth_le_range' List.nth_le_range'
+#align list.nth_le_range' List.nthLe_range'
 
 theorem range'_concat (s n : ℕ) : range' s (n + 1) = range' s n ++ [s + n] := by
   rw [add_comm n 1] ; exact (range'_append s n 1).symm
@@ -134,8 +134,8 @@ theorem range'_concat (s n : ℕ) : range' s (n + 1) = range' s n ++ [s + n] :=
 theorem range_loop_range' : ∀ s n : ℕ, range.loop s (range' s n) = range' 0 (n + s)
   | 0, n => rfl
   | s + 1, n => by
-    rw [show n + (s + 1) = n + 1 + s from add_right_comm n s 1] ;
-      exact range_loop_range' s (n + 1)
+    rw [show n + (s + 1) = n + 1 + s from add_right_comm n s 1]
+    exact range_loop_range' s (n + 1)
 #align list.range_core_range' List.range_loop_range'
 
 theorem range_eq_range' (n : ℕ) : range n = range' 0 n :=
@@ -143,11 +143,12 @@ theorem range_eq_range' (n : ℕ) : range n = range' 0 n :=
 #align list.range_eq_range' List.range_eq_range'
 
 theorem range_succ_eq_map (n : ℕ) : range (n + 1) = 0 :: map succ (range n) := by
-  rw [range_eq_range', range_eq_range', range', add_comm, ← map_add_range'] ; congr ;
-    exact funext one_add
+  rw [range_eq_range', range_eq_range', range', add_comm, ← map_add_range']
+  congr
+  exact funext one_add
 #align list.range_succ_eq_map List.range_succ_eq_map
 
-theorem range'_eq_map_range (s n : ℕ) : range' s n = map ((· + ·) s) (range n) := by
+theorem range'_eq_map_range (s n : ℕ) : range' s n = map (s + ·) (range n) := by
   rw [range_eq_range', map_add_range'] ; rfl
 #align list.range'_eq_map_range List.range'_eq_map_range
 
@@ -193,9 +194,9 @@ theorem self_mem_range_succ (n : ℕ) : n ∈ range (n + 1) := by
   simp only [succ_pos', lt_add_iff_pos_right, mem_range]
 #align list.self_mem_range_succ List.self_mem_range_succ
 
-theorem nth_range {m n : ℕ} (h : m < n) : get? (range n) m = some m := by
+theorem get?_range {m n : ℕ} (h : m < n) : get? (range n) m = some m := by
   simp only [range_eq_range', get?_range' _ h, zero_add]
-#align list.nth_range List.nth_range
+#align list.nth_range List.get?_range
 
 theorem range_succ (n : ℕ) : range (succ n) = range n ++ [n] := by
   simp only [range_eq_range', range'_concat, zero_add]
@@ -345,7 +346,7 @@ theorem unzip_enum_from_eq_prod (l : List α) {n : ℕ} :
 -- Porting note: new theorem
 @[simp]
 theorem get_range {n} (i) (H : i < (range n).length) : get (range n) ⟨i, H⟩ = i :=
-  Option.some.inj <| by rw [← get?_eq_get _, nth_range (by simpa using H)]
+  Option.some.inj <| by rw [← get?_eq_get _, get?_range (by simpa using H)]
 
 set_option linter.deprecated false in
 @[simp]
chore: fix casing errors per naming scheme (#1670)
Diff
@@ -262,7 +262,7 @@ theorem reverse_range' : ∀ s n : ℕ, reverse (range' s n) = map (fun i => s +
       cons_append, nil_append, eq_self_iff_true, true_and_iff, map_map, reverse_range' s n]
 #align list.reverse_range' List.reverse_range'
 
-/-- All elements of `fin n`, from `0` to `n-1`. The corresponding finset is `finset.univ`. -/
+/-- All elements of `Fin n`, from `0` to `n-1`. The corresponding finset is `Finset.univ`. -/
 def finRange (n : ℕ) : List (Fin n) :=
   (range n).pmap Fin.mk fun _ => List.mem_range.1
 #align list.fin_range List.finRange
chore: add #align statements for to_additive decls (#1816)

Co-authored-by: Floris van Doorn <fpvdoorn@gmail.com>

Diff
@@ -299,6 +299,7 @@ theorem prod_range_succ {α : Type u} [Monoid α] (f : ℕ → α) (n : ℕ) :
     ((range n.succ).map f).prod = ((range n).map f).prod * f n := by
   rw [range_succ, map_append, map_singleton, prod_append, prod_cons, prod_nil, mul_one]
 #align list.prod_range_succ List.prod_range_succ
+#align list.sum_range_succ List.sum_range_succ
 
 /-- A variant of `prod_range_succ` which pulls off the first
   term in the product rather than the last.-/
@@ -309,6 +310,7 @@ theorem prod_range_succ' {α : Type u} [Monoid α] (f : ℕ → α) (n : ℕ) :
   Nat.recOn n (show 1 * f 0 = f 0 * 1 by rw [one_mul, mul_one]) fun _ hd => by
     rw [List.prod_range_succ, hd, mul_assoc, ← List.prod_range_succ]
 #align list.prod_range_succ' List.prod_range_succ'
+#align list.sum_range_succ' List.sum_range_succ'
 
 @[simp]
 theorem enum_from_map_fst : ∀ (n) (l : List α), map Prod.fst (enumFrom n l) = range' n l.length
chore: fix most phantom #aligns (#1794)
Diff
@@ -136,7 +136,7 @@ theorem range_loop_range' : ∀ s n : ℕ, range.loop s (range' s n) = range' 0
   | s + 1, n => by
     rw [show n + (s + 1) = n + 1 + s from add_right_comm n s 1] ;
       exact range_loop_range' s (n + 1)
-#align list.range_loop_range' List.range_loop_range'
+#align list.range_core_range' List.range_loop_range'
 
 theorem range_eq_range' (n : ℕ) : range n = range' 0 n :=
   (range_loop_range' n 0).trans <| by rw [zero_add]
chore: format by line breaks (#1523)

During porting, I usually fix the desired format we seem to want for the line breaks around by with

awk '{do {{if (match($0, "^  by$") && length(p) < 98) {p=p " by";} else {if (NR!=1) {print p}; p=$0}}} while (getline == 1) if (getline==0) print p}' Mathlib/File/Im/Working/On.lean

I noticed there are some more files that slipped through.

This pull request is the result of running this command:

grep -lr "^  by\$" Mathlib | xargs -n 1 awk -i inplace '{do {{if (match($0, "^  by$") && length(p) < 98 && not (match(p, "^[ \t]*--"))) {p=p " by";} else {if (NR!=1) {print p}; p=$0}}} while (getline == 1) if (getline==0) print p}'

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

Diff
@@ -207,8 +207,7 @@ theorem range_zero : range 0 = [] :=
 #align list.range_zero List.range_zero
 
 theorem chain'_range_succ (r : ℕ → ℕ → Prop) (n : ℕ) :
-    Chain' r (range n.succ) ↔ ∀ m < n, r m m.succ :=
-  by
+    Chain' r (range n.succ) ↔ ∀ m < n, r m m.succ := by
   rw [range_succ]
   induction' n with n hn
   · simp
@@ -219,8 +218,7 @@ theorem chain'_range_succ (r : ℕ → ℕ → Prop) (n : ℕ) :
 #align list.chain'_range_succ List.chain'_range_succ
 
 theorem chain_range_succ (r : ℕ → ℕ → Prop) (n a : ℕ) :
-    Chain r a (range n.succ) ↔ r a 0 ∧ ∀ m < n, r m m.succ :=
-  by
+    Chain r a (range n.succ) ↔ r a 0 ∧ ∀ m < n, r m m.succ := by
   rw [range_succ_eq_map, chain_cons, and_congr_right_iff, ← chain'_range_succ, range_succ_eq_map]
   exact fun _ => Iff.rfl
 #align list.chain_range_succ List.chain_range_succ
feat: port Data.List.FinRange (#1635)

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

Diff
@@ -359,9 +359,11 @@ theorem get_finRange {n : ℕ} {i : ℕ} (h) :
     (finRange n).get ⟨i, h⟩ = ⟨i, length_finRange n ▸ h⟩ := by
   simp only [finRange, get_range, get_pmap]
 
---Porting note: new theorem
+--Porting note: new theorem, corresponding theorem used to be in Data.List.FinRange
+@[simp]
 theorem finRange_map_get (l : List α) : (finRange l.length).map l.get = l :=
   List.ext_get (by simp) (by simp)
+#align list.map_nth_le List.finRange_map_get
 
 set_option linter.deprecated false in
 @[simp]
feat: port Data.List.Sublists (#1494)

Co-authored-by: qawbecrdtey <qawbecrdtey@kaist.ac.kr> Co-authored-by: ChrisHughes24 <chrishughes24@gmail.com>

Diff
@@ -359,6 +359,10 @@ theorem get_finRange {n : ℕ} {i : ℕ} (h) :
     (finRange n).get ⟨i, h⟩ = ⟨i, length_finRange n ▸ h⟩ := by
   simp only [finRange, get_range, get_pmap]
 
+--Porting note: new theorem
+theorem finRange_map_get (l : List α) : (finRange l.length).map l.get = l :=
+  List.ext_get (by simp) (by simp)
+
 set_option linter.deprecated false in
 @[simp]
 theorem nthLe_finRange {n : ℕ} {i : ℕ} (h) :
feat: port Mathlib.Data.List.Range (#1463)
Diff
@@ -2,76 +2,368 @@
 Copyright (c) 2018 Mario Carneiro. All rights reserved.
 Released under Apache 2.0 license as described in the file LICENSE.
 Authors: Mario Carneiro, Kenny Lau, Scott Morrison
+
+! This file was ported from Lean 3 source module data.list.range
+! leanprover-community/mathlib commit 7b78d1776212a91ecc94cf601f83bdcc46b04213
+! Please do not edit these lines, except to modify the commit id
+! if you have ported upstream changes.
 -/
-import Mathlib.Data.Nat.Basic
-import Mathlib.Data.List.Nodup
-import Mathlib.Order.Basic
-import Mathlib.Data.Fin.Basic
 import Mathlib.Data.List.Chain
+import Mathlib.Data.List.Zip
 
 /-!
 # Ranges of naturals as lists
 
-This file shows basic results about `List.iota`, `List.range`, `List.range'` (all defined in
-`Std.Data.List.Basic`) and defines `List.finRange`.
-`finRange n` is the list of elements of `Fin n`.
-`iota n = [1, ..., n]` and `range n = [0, ..., n - 1]` are basic list constructions used for
+This file shows basic results about `list.iota`, `list.range`, `list.range'` (all defined in
+`data.list.defs`) and defines `list.fin_range`.
+`fin_range n` is the list of elements of `fin n`.
+`iota n = [n, n - 1, ..., 1]` and `range n = [0, ..., n - 1]` are basic list constructions used for
 tactics. `range' a b = [a, ..., a + b - 1]` is there to help prove properties about them.
-Actual maths should use `List.Ico` instead.
+Actual maths should use `list.Ico` instead.
 -/
 
-namespace List
+
+universe u
 
 open Nat
 
+namespace List
+
+variable {α : Type u}
+
+@[simp]
+theorem length_range' : ∀ s n : ℕ, length (range' s n) = n
+  | _, 0 => rfl
+  | _, _ + 1 => congr_arg succ (length_range' _ _)
+#align list.length_range' List.length_range'
+
+@[simp]
+theorem range'_eq_nil {s n : ℕ} : range' s n = [] ↔ n = 0 := by rw [← length_eq_zero, length_range']
+#align list.range'_eq_nil List.range'_eq_nil
+
 @[simp]
 theorem mem_range' {m : ℕ} : ∀ {s n : ℕ}, m ∈ range' s n ↔ s ≤ m ∧ m < s + n
-  | s, 0 => by simp
-  | s, succ n =>
-    have : m = s → m < s + n + 1 := fun e ↦ e ▸ lt_succ_of_le (Nat.le_add_right _ _)
+  | s, 0 => by
+    simp only [range', find?, not_mem_nil, add_zero, false_iff, not_and, not_lt, imp_self]
+  | s, n + 1 =>
+    have : m = s → m < s + n + 1 := fun e => e ▸ lt_succ_of_le (Nat.le_add_right _ _)
     have l : m = s ∨ s + 1 ≤ m ↔ s ≤ m := by
       simpa only [eq_comm] using (@Decidable.le_iff_eq_or_lt _ _ _ s m).symm
     mem_cons.trans <| by
-      simp only [mem_range', or_and_left, or_iff_right_of_imp this, l, Nat.add_right_comm]; rfl
+      simp only [@mem_range' m (s + 1) n, or_and_left, or_iff_right_of_imp this, l,
+        add_right_comm, add_eq, add_zero, and_congr_right_iff, add_assoc, or_iff_right_iff_imp]
+      intro; exact this
+#align list.mem_range' List.mem_range'
 
-theorem range_loop_range' : ∀ s n : ℕ, range.loop s (range' s n) = range' 0 (n + s)
-  | 0, n => rfl
-  | s + 1, n => by
-    rw [show n + (s + 1) = n + 1 + s from Nat.add_right_comm n s 1]
-    exact range_loop_range' s (n + 1)
-
-theorem range_eq_range' (n : ℕ) : range n = range' 0 n :=
-  (range_loop_range' n 0).trans <| by rw [Nat.zero_add]
+theorem map_add_range' (a) : ∀ s n : ℕ, map ((· + ·) a) (range' s n) = range' (a + s) n
+  | _, 0 => rfl
+  | s, n + 1 => congr_arg (cons _) (map_add_range' _ (s + 1) n)
+#align list.map_add_range' List.map_add_range'
 
-@[simp]
-theorem mem_range {m n : ℕ} : m ∈ range n ↔ m < n := by
-  simp only [range_eq_range', mem_range', Nat.zero_le, true_and, Nat.zero_add]
+theorem map_sub_range' (a) :
+    ∀ (s n : ℕ) (_ : a ≤ s), map (fun x => x - a) (range' s n) = range' (s - a) n
+  | s, 0, _ => rfl
+  | s, n + 1, h => by
+    convert congr_arg (cons (s - a)) (map_sub_range' _ (s + 1) n (Nat.le_succ_of_le h))
+    rw [Nat.succ_sub h]
+    rfl
+#align list.map_sub_range' List.map_sub_range'
 
-theorem chain_succ_range' : ∀ s n : ℕ, Chain (fun a b ↦ b = succ a) s (range' (s + 1) n)
+theorem chain_succ_range' : ∀ s n : ℕ, Chain (fun a b => b = succ a) s (range' (s + 1) n)
   | _, 0 => Chain.nil
   | s, n + 1 => (chain_succ_range' (s + 1) n).cons rfl
+#align list.chain_succ_range' List.chain_succ_range'
 
 theorem chain_lt_range' (s n : ℕ) : Chain (· < ·) s (range' (s + 1) n) :=
-  (chain_succ_range' s n).imp fun _ _ e ↦ e.symm ▸ lt_succ_self _
+  (chain_succ_range' s n).imp fun _ _ e => e.symm ▸ lt_succ_self _
+#align list.chain_lt_range' List.chain_lt_range'
 
 theorem pairwise_lt_range' : ∀ s n : ℕ, Pairwise (· < ·) (range' s n)
   | _, 0 => Pairwise.nil
   | s, n + 1 => chain_iff_pairwise.1 (chain_lt_range' s n)
+#align list.pairwise_lt_range' List.pairwise_lt_range'
 
 theorem nodup_range' (s n : ℕ) : Nodup (range' s n) :=
-  (pairwise_lt_range' s n).imp Nat.ne_of_lt
+  (pairwise_lt_range' s n).imp _root_.ne_of_lt
+#align list.nodup_range' List.nodup_range'
 
-theorem nodup_range (n : ℕ) : Nodup (range n) := by
-  simp only [range_eq_range', nodup_range']
+@[simp]
+theorem range'_append : ∀ s m n : ℕ, range' s m ++ range' (s + m) n = range' s (n + m)
+  | s, 0, n => rfl
+  | s, m + 1, n =>
+    show s :: (range' (s + 1) m ++ range' (s + m + 1) n) = s :: range' (s + 1) (n + m) by
+      rw [add_right_comm, range'_append (s + 1) m n]
+#align list.range'_append List.range'_append
 
-/-- All elements of `Fin n`, from `0` to `n-1`. The corresponding finset is `Finset.univ`. -/
-def finRange (n : ℕ) : List (Fin n) := (range n).pmap Fin.mk fun _ ↦ mem_range.1
+theorem range'_sublist_right {s m n : ℕ} : range' s m <+ range' s n ↔ m ≤ n :=
+  ⟨fun h => by simpa only [length_range'] using h.length_le, fun h => by
+    rw [← tsub_add_cancel_of_le h, ← range'_append] ; apply sublist_append_left⟩
+#align list.range'_sublist_right List.range'_sublist_right
 
-@[simp] theorem fin_range_zero : finRange 0 = [] := rfl
+theorem range'_subset_right {s m n : ℕ} : range' s m ⊆ range' s n ↔ m ≤ n :=
+  ⟨fun h =>
+    le_of_not_lt fun hn =>
+      lt_irrefl (s + n) <|
+        (mem_range'.1 <| h <| mem_range'.2 ⟨Nat.le_add_right _ _, Nat.add_lt_add_left hn s⟩).2,
+    fun h => (range'_sublist_right.2 h).subset⟩
+#align list.range'_subset_right List.range'_subset_right
+
+theorem get?_range' : ∀ (s) {m n : ℕ}, m < n → get? (range' s n) m = some (s + m)
+  | s, 0, n + 1, _ => rfl
+  | s, m + 1, n + 1, h =>
+    (get?_range' (s + 1) (lt_of_add_lt_add_right h)).trans <| by rw [add_right_comm] ; rfl
+#align list.nth_range' List.get?_range'
+
+-- Porting note: new theorem
+@[simp]
+theorem get_range' {n m} (i) (H : i < (range' n m).length) : get (range' n m) ⟨i, H⟩ = n + i :=
+  Option.some.inj <| by rw [← get?_eq_get _, get?_range' _ (by simpa using H)]
+
+set_option linter.deprecated false in
+@[simp]
+theorem nth_le_range' {n m} (i) (H : i < (range' n m).length) : nthLe (range' n m) i H = n + i :=
+  get_range' i H
+#align list.nth_le_range' List.nth_le_range'
+
+theorem range'_concat (s n : ℕ) : range' s (n + 1) = range' s n ++ [s + n] := by
+  rw [add_comm n 1] ; exact (range'_append s n 1).symm
+#align list.range'_concat List.range'_concat
+
+#align list.range_core List.range.loop
+
+theorem range_loop_range' : ∀ s n : ℕ, range.loop s (range' s n) = range' 0 (n + s)
+  | 0, n => rfl
+  | s + 1, n => by
+    rw [show n + (s + 1) = n + 1 + s from add_right_comm n s 1] ;
+      exact range_loop_range' s (n + 1)
+#align list.range_loop_range' List.range_loop_range'
+
+theorem range_eq_range' (n : ℕ) : range n = range' 0 n :=
+  (range_loop_range' n 0).trans <| by rw [zero_add]
+#align list.range_eq_range' List.range_eq_range'
+
+theorem range_succ_eq_map (n : ℕ) : range (n + 1) = 0 :: map succ (range n) := by
+  rw [range_eq_range', range_eq_range', range', add_comm, ← map_add_range'] ; congr ;
+    exact funext one_add
+#align list.range_succ_eq_map List.range_succ_eq_map
+
+theorem range'_eq_map_range (s n : ℕ) : range' s n = map ((· + ·) s) (range n) := by
+  rw [range_eq_range', map_add_range'] ; rfl
+#align list.range'_eq_map_range List.range'_eq_map_range
+
+@[simp]
+theorem length_range (n : ℕ) : length (range n) = n := by simp only [range_eq_range', length_range']
+#align list.length_range List.length_range
+
+@[simp]
+theorem range_eq_nil {n : ℕ} : range n = [] ↔ n = 0 := by rw [← length_eq_zero, length_range]
+#align list.range_eq_nil List.range_eq_nil
+
+theorem pairwise_lt_range (n : ℕ) : Pairwise (· < ·) (range n) := by
+  simp only [range_eq_range', pairwise_lt_range']
+#align list.pairwise_lt_range List.pairwise_lt_range
+
+theorem pairwise_le_range (n : ℕ) : Pairwise (· ≤ ·) (range n) :=
+  Pairwise.imp (@le_of_lt ℕ _) (pairwise_lt_range _)
+#align list.pairwise_le_range List.pairwise_le_range
+
+theorem nodup_range (n : ℕ) : Nodup (range n) := by simp only [range_eq_range', nodup_range']
+#align list.nodup_range List.nodup_range
+
+theorem range_sublist {m n : ℕ} : range m <+ range n ↔ m ≤ n := by
+  simp only [range_eq_range', range'_sublist_right]
+#align list.range_sublist List.range_sublist
+
+theorem range_subset {m n : ℕ} : range m ⊆ range n ↔ m ≤ n := by
+  simp only [range_eq_range', range'_subset_right]
+#align list.range_subset List.range_subset
+
+@[simp]
+theorem mem_range {m n : ℕ} : m ∈ range n ↔ m < n := by
+  simp only [range_eq_range', mem_range', Nat.zero_le, true_and_iff, zero_add]
+#align list.mem_range List.mem_range
+
+-- @[simp] -- Porting note: simp can prove this
+theorem not_mem_range_self {n : ℕ} : n ∉ range n :=
+  mt mem_range.1 <| lt_irrefl _
+#align list.not_mem_range_self List.not_mem_range_self
+
+-- @[simp] -- Porting note: simp can prove this
+theorem self_mem_range_succ (n : ℕ) : n ∈ range (n + 1) := by
+  simp only [succ_pos', lt_add_iff_pos_right, mem_range]
+#align list.self_mem_range_succ List.self_mem_range_succ
+
+theorem nth_range {m n : ℕ} (h : m < n) : get? (range n) m = some m := by
+  simp only [range_eq_range', get?_range' _ h, zero_add]
+#align list.nth_range List.nth_range
+
+theorem range_succ (n : ℕ) : range (succ n) = range n ++ [n] := by
+  simp only [range_eq_range', range'_concat, zero_add]
+#align list.range_succ List.range_succ
+
+@[simp]
+theorem range_zero : range 0 = [] :=
+  rfl
+#align list.range_zero List.range_zero
+
+theorem chain'_range_succ (r : ℕ → ℕ → Prop) (n : ℕ) :
+    Chain' r (range n.succ) ↔ ∀ m < n, r m m.succ :=
+  by
+  rw [range_succ]
+  induction' n with n hn
+  · simp
+  · rw [range_succ]
+    simp only [append_assoc, singleton_append, chain'_append_cons_cons, chain'_singleton,
+      and_true_iff]
+    rw [hn, forall_lt_succ]
+#align list.chain'_range_succ List.chain'_range_succ
+
+theorem chain_range_succ (r : ℕ → ℕ → Prop) (n a : ℕ) :
+    Chain r a (range n.succ) ↔ r a 0 ∧ ∀ m < n, r m m.succ :=
+  by
+  rw [range_succ_eq_map, chain_cons, and_congr_right_iff, ← chain'_range_succ, range_succ_eq_map]
+  exact fun _ => Iff.rfl
+#align list.chain_range_succ List.chain_range_succ
+
+theorem range_add (a : ℕ) : ∀ b, range (a + b) = range a ++ (range b).map fun x => a + x
+  | 0 => by rw [add_zero, range_zero, map_nil, append_nil]
+  | b + 1 => by
+    rw [Nat.add_succ, range_succ, range_add a b, range_succ, map_append,
+      map_singleton, append_assoc]
+#align list.range_add List.range_add
+
+theorem iota_eq_reverse_range' : ∀ n : ℕ, iota n = reverse (range' 1 n)
+  | 0 => rfl
+  | n + 1 => by
+    simp only [iota, range'_concat, iota_eq_reverse_range' (n.add 0), reverse_append, add_comm]; rfl
+#align list.iota_eq_reverse_range' List.iota_eq_reverse_range'
+
+@[simp]
+theorem length_iota (n : ℕ) : length (iota n) = n := by
+  simp only [iota_eq_reverse_range', length_reverse, length_range']
+#align list.length_iota List.length_iota
+
+theorem pairwise_gt_iota (n : ℕ) : Pairwise (· > ·) (iota n) := by
+  simpa only [iota_eq_reverse_range', pairwise_reverse] using pairwise_lt_range' 1 n
+#align list.pairwise_gt_iota List.pairwise_gt_iota
+
+theorem nodup_iota (n : ℕ) : Nodup (iota n) :=
+  (pairwise_gt_iota n).imp _root_.ne_of_gt
+#align list.nodup_iota List.nodup_iota
+
+theorem mem_iota {m n : ℕ} : m ∈ iota n ↔ 1 ≤ m ∧ m ≤ n := by
+  simp only [iota_eq_reverse_range', mem_reverse, mem_range', add_comm, lt_succ_iff]
+#align list.mem_iota List.mem_iota
+
+theorem reverse_range' : ∀ s n : ℕ, reverse (range' s n) = map (fun i => s + n - 1 - i) (range n)
+  | s, 0 => rfl
+  | s, n + 1 => by
+    rw [range'_concat, reverse_append, range_succ_eq_map]
+    simp only [show s + (n + 1) - 1 = s + n from rfl, (· ∘ ·), fun a i =>
+      show a - 1 - i = a - succ i from pred_sub _ _, reverse_singleton, map_cons, tsub_zero,
+      cons_append, nil_append, eq_self_iff_true, true_and_iff, map_map, reverse_range' s n]
+#align list.reverse_range' List.reverse_range'
+
+/-- All elements of `fin n`, from `0` to `n-1`. The corresponding finset is `finset.univ`. -/
+def finRange (n : ℕ) : List (Fin n) :=
+  (range n).pmap Fin.mk fun _ => List.mem_range.1
+#align list.fin_range List.finRange
+
+@[simp]
+theorem finRange_zero : finRange 0 = [] :=
+  rfl
+#align list.fin_range_zero List.finRange_zero
+
+@[simp]
+theorem mem_finRange {n : ℕ} (a : Fin n) : a ∈ finRange n :=
+  mem_pmap.2
+    ⟨a.1, mem_range.2 a.2, by
+      cases a
+      rfl⟩
+#align list.mem_fin_range List.mem_finRange
+
+theorem nodup_finRange (n : ℕ) : (finRange n).Nodup :=
+  (Pairwise.pmap (nodup_range n) _) fun _ _ _ _ => @Fin.ne_of_vne _ ⟨_, _⟩ ⟨_, _⟩
+#align list.nodup_fin_range List.nodup_finRange
+
+@[simp]
+theorem length_finRange (n : ℕ) : (finRange n).length = n := by
+  rw [finRange, length_pmap, length_range]
+#align list.length_fin_range List.length_finRange
+
+@[simp]
+theorem finRange_eq_nil {n : ℕ} : finRange n = [] ↔ n = 0 := by
+  rw [← length_eq_zero, length_finRange]
+#align list.fin_range_eq_nil List.finRange_eq_nil
+
+@[to_additive]
+theorem prod_range_succ {α : Type u} [Monoid α] (f : ℕ → α) (n : ℕ) :
+    ((range n.succ).map f).prod = ((range n).map f).prod * f n := by
+  rw [range_succ, map_append, map_singleton, prod_append, prod_cons, prod_nil, mul_one]
+#align list.prod_range_succ List.prod_range_succ
+
+/-- A variant of `prod_range_succ` which pulls off the first
+  term in the product rather than the last.-/
+@[to_additive
+  "A variant of `sum_range_succ` which pulls off the first term in the sum rather than the last."]
+theorem prod_range_succ' {α : Type u} [Monoid α] (f : ℕ → α) (n : ℕ) :
+    ((range n.succ).map f).prod = f 0 * ((range n).map fun i => f (succ i)).prod :=
+  Nat.recOn n (show 1 * f 0 = f 0 * 1 by rw [one_mul, mul_one]) fun _ hd => by
+    rw [List.prod_range_succ, hd, mul_assoc, ← List.prod_range_succ]
+#align list.prod_range_succ' List.prod_range_succ'
+
+@[simp]
+theorem enum_from_map_fst : ∀ (n) (l : List α), map Prod.fst (enumFrom n l) = range' n l.length
+  | _, [] => rfl
+  | _, _ :: _ => congr_arg (cons _) (enum_from_map_fst _ _)
+#align list.enum_from_map_fst List.enum_from_map_fst
+
+@[simp]
+theorem enum_map_fst (l : List α) : map Prod.fst (enum l) = range l.length := by
+  simp only [enum, enum_from_map_fst, range_eq_range']
+#align list.enum_map_fst List.enum_map_fst
+
+theorem enum_eq_zip_range (l : List α) : l.enum = (range l.length).zip l :=
+  zip_of_prod (enum_map_fst _) (enum_map_snd _)
+#align list.enum_eq_zip_range List.enum_eq_zip_range
+
+@[simp]
+theorem unzip_enum_eq_prod (l : List α) : l.enum.unzip = (range l.length, l) := by
+  simp only [enum_eq_zip_range, unzip_zip, length_range]
+#align list.unzip_enum_eq_prod List.unzip_enum_eq_prod
+
+theorem enum_from_eq_zip_range' (l : List α) {n : ℕ} : l.enumFrom n = (range' n l.length).zip l :=
+  zip_of_prod (enum_from_map_fst _ _) (enumFrom_map_snd _ _)
+#align list.enum_from_eq_zip_range' List.enum_from_eq_zip_range'
+
+@[simp]
+theorem unzip_enum_from_eq_prod (l : List α) {n : ℕ} :
+    (l.enumFrom n).unzip = (range' n l.length, l) := by
+  simp only [enum_from_eq_zip_range', unzip_zip, length_range']
+#align list.unzip_enum_from_eq_prod List.unzip_enum_from_eq_prod
+
+-- Porting note: new theorem
+@[simp]
+theorem get_range {n} (i) (H : i < (range n).length) : get (range n) ⟨i, H⟩ = i :=
+  Option.some.inj <| by rw [← get?_eq_get _, nth_range (by simpa using H)]
+
+set_option linter.deprecated false in
+@[simp]
+theorem nthLe_range {n} (i) (H : i < (range n).length) : nthLe (range n) i H = i :=
+  get_range i H
+#align list.nth_le_range List.nthLe_range
+
+-- Porting note: new theorem
+@[simp]
+theorem get_finRange {n : ℕ} {i : ℕ} (h) :
+    (finRange n).get ⟨i, h⟩ = ⟨i, length_finRange n ▸ h⟩ := by
+  simp only [finRange, get_range, get_pmap]
 
+set_option linter.deprecated false in
 @[simp]
-theorem mem_fin_range {n : ℕ} (a : Fin n) : a ∈ finRange n :=
-  mem_pmap.2 ⟨a.1, mem_range.2 a.2, Fin.eta _ _⟩
+theorem nthLe_finRange {n : ℕ} {i : ℕ} (h) :
+    (finRange n).nthLe i h = ⟨i, length_finRange n ▸ h⟩ :=
+  get_finRange h
+#align list.nth_le_fin_range List.nthLe_finRange
 
-theorem nodup_fin_range (n : ℕ) : (finRange n).Nodup :=
-  (nodup_range _).pmap fun _ _ _ _ ↦ Fin.val_eq_of_eq
+end List

Dependencies 2 + 94

95 files ported (97.9%)
43665 lines ported (99.7%)
Show graph

The unported dependencies are