ring_theory.roots_of_unity.basicMathlib.RingTheory.RootsOfUnity.Basic

This file has been ported!

Changes since the initial port

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

Changes in mathlib3

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(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
@@ -822,12 +822,12 @@ theorem pow_sub_one_eq [IsDomain R] {ζ : R} (hζ : IsPrimitiveRoot ζ k) (hk :
 and the powers of a primitive root of unity `ζ`. -/
 def zmodEquivZPowers (h : IsPrimitiveRoot ζ k) : ZMod k ≃+ Additive (Subgroup.zpowers ζ) :=
   AddEquiv.ofBijective
-    (AddMonoidHom.liftOfRightInverse (Int.castAddHom <| ZMod k) _ ZMod.int_cast_rightInverse
+    (AddMonoidHom.liftOfRightInverse (Int.castAddHom <| ZMod k) _ ZMod.intCast_rightInverse
       ⟨{  toFun := fun i => Additive.ofMul (⟨_, i, rfl⟩ : Subgroup.zpowers ζ)
           map_zero' := by simp only [zpow_zero]; rfl
           map_add' := by intro i j; simp only [zpow_add]; rfl }, fun i hi =>
         by
-        simp only [AddMonoidHom.mem_ker, CharP.int_cast_eq_zero_iff (ZMod k) k, AddMonoidHom.coe_mk,
+        simp only [AddMonoidHom.mem_ker, CharP.intCast_eq_zero_iff (ZMod k) k, AddMonoidHom.coe_mk,
           Int.coe_castAddHom] at hi ⊢
         obtain ⟨i, rfl⟩ := hi
         simp only [zpow_mul, h.pow_eq_one, one_zpow, zpow_natCast]
@@ -838,8 +838,8 @@ def zmodEquivZPowers (h : IsPrimitiveRoot ζ k) : ZMod k ≃+ Additive (Subgroup
         intro i hi
         rw [Subtype.ext_iff] at hi
         have := (h.zpow_eq_one_iff_dvd _).mp hi
-        rw [← (CharP.int_cast_eq_zero_iff (ZMod k) k _).mpr this, eq_comm]
-        exact ZMod.int_cast_rightInverse i
+        rw [← (CharP.intCast_eq_zero_iff (ZMod k) k _).mpr this, eq_comm]
+        exact ZMod.intCast_rightInverse i
       · rintro ⟨ξ, i, rfl⟩
         refine' ⟨Int.castAddHom _ i, _⟩
         rw [AddMonoidHom.liftOfRightInverse_comp_apply]
@@ -851,7 +851,7 @@ def zmodEquivZPowers (h : IsPrimitiveRoot ζ k) : ZMod k ≃+ Additive (Subgroup
 @[simp]
 theorem zmodEquivZPowers_apply_coe_int (i : ℤ) :
     h.zmodEquivZPowers i = Additive.ofMul (⟨ζ ^ i, i, rfl⟩ : Subgroup.zpowers ζ) :=
-  AddMonoidHom.liftOfRightInverse_comp_apply _ _ ZMod.int_cast_rightInverse _ _
+  AddMonoidHom.liftOfRightInverse_comp_apply _ _ ZMod.intCast_rightInverse _ _
 #align is_primitive_root.zmod_equiv_zpowers_apply_coe_int IsPrimitiveRoot.zmodEquivZPowers_apply_coe_int
 -/
 
@@ -1156,8 +1156,8 @@ noncomputable def autToPow : (S ≃ₐ[R] S) →* (ZMod n)ˣ :=
         replace h : μ' = μ' ^ h1.some :=
           rootsOfUnity.coe_injective (by simpa only [rootsOfUnity.coe_pow] using h)
         rw [← pow_one μ'] at h
-        rw [← @Nat.cast_one <| ZMod n, ZMod.nat_cast_eq_nat_cast_iff, ← ho, ←
-          pow_eq_pow_iff_modEq μ', h]
+        rw [← @Nat.cast_one <| ZMod n, ZMod.natCast_eq_natCast_iff, ← ho, ← pow_eq_pow_iff_modEq μ',
+          h]
       map_mul' := by
         generalize_proofs hxy' hx' hy'
         have hxy := hxy'.some_spec
@@ -1171,7 +1171,7 @@ noncomputable def autToPow : (S ≃ₐ[R] S) →* (ZMod n)ˣ :=
         rw [← pow_mul] at hxy
         replace hxy : μ' ^ (hx'.some * hy'.some) = μ' ^ hxy'.some :=
           rootsOfUnity.coe_injective (by simpa only [rootsOfUnity.coe_pow] using hxy)
-        rw [← Nat.cast_mul, ZMod.nat_cast_eq_nat_cast_iff, ← ho, ← pow_eq_pow_iff_modEq μ', hxy] }
+        rw [← Nat.cast_mul, ZMod.natCast_eq_natCast_iff, ← ho, ← pow_eq_pow_iff_modEq μ', hxy] }
 #align is_primitive_root.aut_to_pow IsPrimitiveRoot.autToPow
 -/
 
@@ -1196,7 +1196,7 @@ theorem autToPow_spec (f : S ≃ₐ[R] S) : μ ^ (hμ.autToPow R f : ZMod n).val
   rw [← rootsOfUnity.coe_pow, ← rootsOfUnity.coe_pow]
   congr 1
   rw [pow_eq_pow_iff_modEq, ← Subgroup.orderOf_coe, ← orderOf_units, hμ.coe_to_roots_of_unity_coe, ←
-    hμ.eq_order_of, ZMod.val_nat_cast]
+    hμ.eq_order_of, ZMod.val_natCast]
   exact Nat.mod_modEq _ _
 #align is_primitive_root.aut_to_pow_spec IsPrimitiveRoot.autToPow_spec
 -/
Diff
@@ -6,7 +6,7 @@ Authors: Johan Commelin
 import Algebra.CharP.Two
 import Algebra.NeZero
 import Algebra.GCDMonoid.IntegrallyClosed
-import Data.Polynomial.RingDivision
+import Algebra.Polynomial.RingDivision
 import FieldTheory.Finite.Basic
 import FieldTheory.Separable
 import GroupTheory.SpecificGroups.Cyclic
Diff
@@ -5,7 +5,7 @@ Authors: Johan Commelin
 -/
 import Algebra.CharP.Two
 import Algebra.NeZero
-import Algebra.GcdMonoid.IntegrallyClosed
+import Algebra.GCDMonoid.IntegrallyClosed
 import Data.Polynomial.RingDivision
 import FieldTheory.Finite.Basic
 import FieldTheory.Separable
@@ -246,7 +246,7 @@ def rootsOfUnityEquivNthRoots : rootsOfUnity k R ≃ { x // x ∈ nthRoots k (1
   pick_goal 4; · rintro ⟨x, hx⟩; ext; rfl
   all_goals
     rcases x with ⟨x, hx⟩; rw [mem_nth_roots k.pos] at hx
-    simp only [Subtype.coe_mk, ← pow_succ, ← pow_succ', hx,
+    simp only [Subtype.coe_mk, ← pow_succ', ← pow_succ, hx,
       tsub_add_cancel_of_le (show 1 ≤ (k : ℕ) from k.one_le)]
   · show (_ : Rˣ) ^ (k : ℕ) = 1
     simp only [Units.ext_iff, hx, Units.val_mk, Units.val_one, Subtype.coe_mk,
@@ -308,7 +308,7 @@ theorem map_rootsOfUnity_eq_pow_self [RingHomClass F R R] (σ : F) (ζ : rootsOf
   rw [← restrictRootsOfUnity_coe_apply, hm, zpow_mod_orderOf, ←
     Int.toNat_of_nonneg
       (m.mod_nonneg (int.coe_nat_ne_zero.mpr (pos_iff_ne_zero.mp (orderOf_pos ζ)))),
-    zpow_coe_nat, rootsOfUnity.coe_pow]
+    zpow_natCast, rootsOfUnity.coe_pow]
   exact ⟨(m % orderOf ζ).toNat, rfl⟩
 #align map_root_of_unity_eq_pow_self map_rootsOfUnity_eq_pow_self
 -/
@@ -432,7 +432,7 @@ theorem pow_eq_one_iff_dvd (l : ℕ) : ζ ^ l = 1 ↔ k ∣ l :=
 theorem isUnit (h : IsPrimitiveRoot ζ k) (h0 : 0 < k) : IsUnit ζ :=
   by
   apply isUnit_of_mul_eq_one ζ (ζ ^ (k - 1))
-  rw [← pow_succ, tsub_add_cancel_of_le h0.nat_succ_le, h.pow_eq_one]
+  rw [← pow_succ', tsub_add_cancel_of_le h0.nat_succ_le, h.pow_eq_one]
 #align is_primitive_root.is_unit IsPrimitiveRoot.isUnit
 -/
 
@@ -507,9 +507,9 @@ theorem pow_of_coprime (h : IsPrimitiveRoot ζ k) (i : ℕ) (hi : i.Coprime k) :
       dvd_of_pow_eq_one := _ }
   intro l hl
   apply h.dvd_of_pow_eq_one
-  rw [← pow_one ζ, ← zpow_coe_nat ζ, ← hi.gcd_eq_one, Nat.gcd_eq_gcd_ab, zpow_add, mul_pow, ←
-    zpow_coe_nat, ← zpow_mul, mul_right_comm]
-  simp only [zpow_mul, hl, h.pow_eq_one, one_zpow, one_pow, one_mul, zpow_coe_nat]
+  rw [← pow_one ζ, ← zpow_natCast ζ, ← hi.gcd_eq_one, Nat.gcd_eq_gcd_ab, zpow_add, mul_pow, ←
+    zpow_natCast, ← zpow_mul, mul_right_comm]
+  simp only [zpow_mul, hl, h.pow_eq_one, one_zpow, one_pow, one_mul, zpow_natCast]
 #align is_primitive_root.pow_of_coprime IsPrimitiveRoot.pow_of_coprime
 -/
 
@@ -668,7 +668,7 @@ section DivisionCommMonoid
 variable {ζ : G}
 
 #print IsPrimitiveRoot.zpow_eq_one /-
-theorem zpow_eq_one (h : IsPrimitiveRoot ζ k) : ζ ^ (k : ℤ) = 1 := by rw [zpow_coe_nat];
+theorem zpow_eq_one (h : IsPrimitiveRoot ζ k) : ζ ^ (k : ℤ) = 1 := by rw [zpow_natCast];
   exact h.pow_eq_one
 #align is_primitive_root.zpow_eq_one IsPrimitiveRoot.zpow_eq_one
 -/
@@ -677,12 +677,12 @@ theorem zpow_eq_one (h : IsPrimitiveRoot ζ k) : ζ ^ (k : ℤ) = 1 := by rw [zp
 theorem zpow_eq_one_iff_dvd (h : IsPrimitiveRoot ζ k) (l : ℤ) : ζ ^ l = 1 ↔ (k : ℤ) ∣ l :=
   by
   by_cases h0 : 0 ≤ l
-  · lift l to ℕ using h0; rw [zpow_coe_nat]; norm_cast; exact h.pow_eq_one_iff_dvd l
+  · lift l to ℕ using h0; rw [zpow_natCast]; norm_cast; exact h.pow_eq_one_iff_dvd l
   · have : 0 ≤ -l := by simp only [not_le, neg_nonneg] at h0 ⊢; exact le_of_lt h0
     lift -l to ℕ using this with l' hl'
     rw [← dvd_neg, ← hl']
     norm_cast
-    rw [← h.pow_eq_one_iff_dvd, ← inv_inj, ← zpow_neg, ← hl', zpow_coe_nat, inv_one]
+    rw [← h.pow_eq_one_iff_dvd, ← inv_inj, ← zpow_neg, ← hl', zpow_natCast, inv_one]
 #align is_primitive_root.zpow_eq_one_iff_dvd IsPrimitiveRoot.zpow_eq_one_iff_dvd
 -/
 
@@ -708,11 +708,11 @@ theorem zpow_of_gcd_eq_one (h : IsPrimitiveRoot ζ k) (i : ℤ) (hi : i.gcd k =
     IsPrimitiveRoot (ζ ^ i) k := by
   by_cases h0 : 0 ≤ i
   · lift i to ℕ using h0
-    rw [zpow_coe_nat]
+    rw [zpow_natCast]
     exact h.pow_of_coprime i hi
   have : 0 ≤ -i := by simp only [not_le, neg_nonneg] at h0 ⊢; exact le_of_lt h0
   lift -i to ℕ using this with i' hi'
-  rw [← inv_iff, ← zpow_neg, ← hi', zpow_coe_nat]
+  rw [← inv_iff, ← zpow_neg, ← hi', zpow_natCast]
   apply h.pow_of_coprime
   rw [Int.gcd, ← Int.natAbs_neg, ← hi'] at hi
   exact hi
@@ -751,7 +751,7 @@ theorem neZero' {n : ℕ+} (hζ : IsPrimitiveRoot ζ n) : NeZero ((n : ℕ) : R)
     haveI : NeZero p := NeZero.of_pos (Nat.pos_of_dvd_of_pos hp n.pos)
     haveI hpri : Fact p.prime := CharP.char_is_prime_of_pos R p
     have := hζ.pow_eq_one
-    rw [hm.1, hk, pow_succ, mul_assoc, pow_mul', ← frobenius_def, ← frobenius_one p] at this
+    rw [hm.1, hk, pow_succ', mul_assoc, pow_mul', ← frobenius_def, ← frobenius_one p] at this
     exfalso
     have hpos : 0 < p ^ k * m :=
       by
@@ -760,7 +760,7 @@ theorem neZero' {n : ℕ+} (hζ : IsPrimitiveRoot ζ n) : NeZero ((n : ℕ) : R)
       rw [h] at H
       simpa using H
     refine' hζ.pow_ne_one_of_pos_of_lt hpos _ (frobenius_inj R p this)
-    · rw [hm.1, hk, pow_succ, mul_assoc, mul_comm p]
+    · rw [hm.1, hk, pow_succ', mul_assoc, mul_comm p]
       exact lt_mul_of_one_lt_right hpos hpri.1.one_lt
   · exact NeZero.of_not_dvd R hp
 #align is_primitive_root.ne_zero' IsPrimitiveRoot.neZero'
@@ -830,7 +830,7 @@ def zmodEquivZPowers (h : IsPrimitiveRoot ζ k) : ZMod k ≃+ Additive (Subgroup
         simp only [AddMonoidHom.mem_ker, CharP.int_cast_eq_zero_iff (ZMod k) k, AddMonoidHom.coe_mk,
           Int.coe_castAddHom] at hi ⊢
         obtain ⟨i, rfl⟩ := hi
-        simp only [zpow_mul, h.pow_eq_one, one_zpow, zpow_coe_nat]
+        simp only [zpow_mul, h.pow_eq_one, one_zpow, zpow_natCast]
         rfl⟩)
     (by
       constructor
@@ -861,7 +861,7 @@ theorem zmodEquivZPowers_apply_coe_nat (i : ℕ) :
     h.zmodEquivZPowers i = Additive.ofMul (⟨ζ ^ i, i, rfl⟩ : Subgroup.zpowers ζ) :=
   by
   have : (i : ZMod k) = (i : ℤ) := by norm_cast
-  simp only [this, zmod_equiv_zpowers_apply_coe_int, zpow_coe_nat]
+  simp only [this, zmod_equiv_zpowers_apply_coe_int, zpow_natCast]
   rfl
 #align is_primitive_root.zmod_equiv_zpowers_apply_coe_nat IsPrimitiveRoot.zmodEquivZPowers_apply_coe_nat
 -/
@@ -927,7 +927,7 @@ theorem eq_pow_of_mem_rootsOfUnity {k : ℕ+} {ζ ξ : Rˣ} (h : IsPrimitiveRoot
   refine' ⟨i₀, _, _⟩
   · zify; rw [hi₀]; exact Int.emod_lt_of_pos _ hk0
   · have aux := h.zpow_eq_one; rw [← coe_coe] at aux
-    rw [← zpow_coe_nat, hi₀, ← Int.emod_add_ediv n k, zpow_add, zpow_mul, aux, one_zpow, mul_one]
+    rw [← zpow_natCast, hi₀, ← Int.emod_add_ediv n k, zpow_add, zpow_mul, aux, one_zpow, mul_one]
 #align is_primitive_root.eq_pow_of_mem_roots_of_unity IsPrimitiveRoot.eq_pow_of_mem_rootsOfUnity
 -/
 
Diff
@@ -245,7 +245,7 @@ def rootsOfUnityEquivNthRoots : rootsOfUnity k R ≃ { x // x ∈ nthRoots k (1
   pick_goal 4; · rintro ⟨x, hx⟩; ext; rfl
   pick_goal 4; · rintro ⟨x, hx⟩; ext; rfl
   all_goals
-    rcases x with ⟨x, hx⟩; rw [mem_nth_roots k.pos] at hx 
+    rcases x with ⟨x, hx⟩; rw [mem_nth_roots k.pos] at hx
     simp only [Subtype.coe_mk, ← pow_succ, ← pow_succ', hx,
       tsub_add_cancel_of_le (show 1 ≤ (k : ℕ) from k.one_le)]
   · show (_ : Rˣ) ^ (k : ℕ) = 1
@@ -529,9 +529,9 @@ theorem pow_iff_coprime (h : IsPrimitiveRoot ζ k) (h0 : 0 < k) (i : ℕ) :
   intro hi
   obtain ⟨a, ha⟩ := i.gcd_dvd_left k
   obtain ⟨b, hb⟩ := i.gcd_dvd_right k
-  suffices b = k by rwa [this, ← one_mul k, mul_left_inj' h0.ne', eq_comm] at hb 
-  rw [ha] at hi 
-  rw [mul_comm] at hb 
+  suffices b = k by rwa [this, ← one_mul k, mul_left_inj' h0.ne', eq_comm] at hb
+  rw [ha] at hi
+  rw [mul_comm] at hb
   apply Nat.dvd_antisymm ⟨i.gcd k, hb⟩ (hi.dvd_of_pow_eq_one b _)
   rw [← pow_mul', ← mul_assoc, ← hb, pow_mul, h.pow_eq_one, one_pow]
 #align is_primitive_root.pow_iff_coprime IsPrimitiveRoot.pow_iff_coprime
@@ -562,7 +562,7 @@ protected theorem iff (hk : 0 < k) :
   refine'
     ⟨fun h => ⟨h.pow_eq_one, fun l hl' hl => _⟩, fun ⟨hζ, hl⟩ =>
       IsPrimitiveRoot.mk_of_lt ζ hk hζ hl⟩
-  rw [h.eq_order_of] at hl 
+  rw [h.eq_order_of] at hl
   exact pow_ne_one_of_lt_orderOf' hl'.ne' hl
 #align is_primitive_root.iff IsPrimitiveRoot.iff
 -/
@@ -615,7 +615,7 @@ theorem map_of_injective [MonoidHomClass F M N] (h : IsPrimitiveRoot ζ k) (hf :
     dvd_of_pow_eq_one := by
       rw [h.eq_order_of]
       intro l hl
-      rw [← map_pow, ← map_one f] at hl 
+      rw [← map_pow, ← map_one f] at hl
       exact orderOf_dvd_of_pow_eq_one (hf hl) }
 #align is_primitive_root.map_of_injective IsPrimitiveRoot.map_of_injective
 -/
@@ -627,8 +627,8 @@ theorem of_map_of_injective [MonoidHomClass F M N] (h : IsPrimitiveRoot (f ζ) k
     dvd_of_pow_eq_one := by
       rw [h.eq_order_of]
       intro l hl
-      apply_fun f at hl 
-      rw [map_pow, _root_.map_one] at hl 
+      apply_fun f at hl
+      rw [map_pow, _root_.map_one] at hl
       exact orderOf_dvd_of_pow_eq_one hl }
 #align is_primitive_root.of_map_of_injective IsPrimitiveRoot.of_map_of_injective
 -/
@@ -714,7 +714,7 @@ theorem zpow_of_gcd_eq_one (h : IsPrimitiveRoot ζ k) (i : ℤ) (hi : i.gcd k =
   lift -i to ℕ using this with i' hi'
   rw [← inv_iff, ← zpow_neg, ← hi', zpow_coe_nat]
   apply h.pow_of_coprime
-  rw [Int.gcd, ← Int.natAbs_neg, ← hi'] at hi 
+  rw [Int.gcd, ← Int.natAbs_neg, ← hi'] at hi
   exact hi
 #align is_primitive_root.zpow_of_gcd_eq_one IsPrimitiveRoot.zpow_of_gcd_eq_one
 -/
@@ -735,7 +735,7 @@ theorem primitiveRoots_one : primitiveRoots 1 R = {(1 : R)} :=
   constructor
   · simp only [IsPrimitiveRoot.one_right_iff, mem_primitiveRoots zero_lt_one]
   · intro x hx
-    rw [mem_primitiveRoots zero_lt_one, IsPrimitiveRoot.one_right_iff] at hx 
+    rw [mem_primitiveRoots zero_lt_one, IsPrimitiveRoot.one_right_iff] at hx
     exact hx
 #align is_primitive_root.primitive_roots_one IsPrimitiveRoot.primitiveRoots_one
 -/
@@ -751,13 +751,13 @@ theorem neZero' {n : ℕ+} (hζ : IsPrimitiveRoot ζ n) : NeZero ((n : ℕ) : R)
     haveI : NeZero p := NeZero.of_pos (Nat.pos_of_dvd_of_pos hp n.pos)
     haveI hpri : Fact p.prime := CharP.char_is_prime_of_pos R p
     have := hζ.pow_eq_one
-    rw [hm.1, hk, pow_succ, mul_assoc, pow_mul', ← frobenius_def, ← frobenius_one p] at this 
+    rw [hm.1, hk, pow_succ, mul_assoc, pow_mul', ← frobenius_def, ← frobenius_one p] at this
     exfalso
     have hpos : 0 < p ^ k * m :=
       by
       refine' mul_pos (pow_pos hpri.1.Pos _) (Nat.pos_of_ne_zero fun h => _)
       have H := hm.1
-      rw [h] at H 
+      rw [h] at H
       simpa using H
     refine' hζ.pow_ne_one_of_pos_of_lt hpos _ (frobenius_inj R p this)
     · rw [hm.1, hk, pow_succ, mul_assoc, mul_comm p]
@@ -836,7 +836,7 @@ def zmodEquivZPowers (h : IsPrimitiveRoot ζ k) : ZMod k ≃+ Additive (Subgroup
       constructor
       · rw [injective_iff_map_eq_zero]
         intro i hi
-        rw [Subtype.ext_iff] at hi 
+        rw [Subtype.ext_iff] at hi
         have := (h.zpow_eq_one_iff_dvd _).mp hi
         rw [← (CharP.int_cast_eq_zero_iff (ZMod k) k _).mpr this, eq_comm]
         exact ZMod.int_cast_rightInverse i
@@ -919,14 +919,14 @@ theorem zpowers_eq {k : ℕ+} {ζ : Rˣ} (h : IsPrimitiveRoot ζ k) :
 theorem eq_pow_of_mem_rootsOfUnity {k : ℕ+} {ζ ξ : Rˣ} (h : IsPrimitiveRoot ζ k)
     (hξ : ξ ∈ rootsOfUnity k R) : ∃ (i : ℕ) (hi : i < k), ζ ^ i = ξ :=
   by
-  obtain ⟨n, rfl⟩ : ∃ n : ℤ, ζ ^ n = ξ := by rwa [← h.zpowers_eq] at hξ 
+  obtain ⟨n, rfl⟩ : ∃ n : ℤ, ζ ^ n = ξ := by rwa [← h.zpowers_eq] at hξ
   have hk0 : (0 : ℤ) < k := by exact_mod_cast k.pos
   let i := n % k
   have hi0 : 0 ≤ i := Int.emod_nonneg _ (ne_of_gt hk0)
   lift i to ℕ using hi0 with i₀ hi₀
   refine' ⟨i₀, _, _⟩
   · zify; rw [hi₀]; exact Int.emod_lt_of_pos _ hk0
-  · have aux := h.zpow_eq_one; rw [← coe_coe] at aux 
+  · have aux := h.zpow_eq_one; rw [← coe_coe] at aux
     rw [← zpow_coe_nat, hi₀, ← Int.emod_add_ediv n k, zpow_add, zpow_mul, aux, one_zpow, mul_one]
 #align is_primitive_root.eq_pow_of_mem_roots_of_unity IsPrimitiveRoot.eq_pow_of_mem_rootsOfUnity
 -/
@@ -939,7 +939,7 @@ theorem eq_pow_of_pow_eq_one {k : ℕ} {ζ ξ : R} (h : IsPrimitiveRoot ζ k) (h
   lift ξ to Rˣ using isUnit_ofPowEqOne hξ h0.ne'
   lift k to ℕ+ using h0
   simp only [← Units.val_pow_eq_pow_val, ← Units.ext_iff]
-  rw [coe_units_iff] at h 
+  rw [coe_units_iff] at h
   apply h.eq_pow_of_mem_roots_of_unity
   rw [mem_rootsOfUnity, Units.ext_iff, Units.val_pow_eq_pow_val, hξ, Units.val_one]
 #align is_primitive_root.eq_pow_of_pow_eq_one IsPrimitiveRoot.eq_pow_of_pow_eq_one
@@ -952,7 +952,7 @@ theorem isPrimitiveRoot_iff' {k : ℕ+} {ζ ξ : Rˣ} (h : IsPrimitiveRoot ζ k)
   constructor
   · intro hξ
     obtain ⟨i, hik, rfl⟩ := h.eq_pow_of_mem_roots_of_unity hξ.pow_eq_one
-    rw [h.pow_iff_coprime k.pos] at hξ 
+    rw [h.pow_iff_coprime k.pos] at hξ
     exact ⟨i, hik, hξ, rfl⟩
   · rintro ⟨i, -, hi, rfl⟩; exact h.pow_of_coprime i hi
 #align is_primitive_root.is_primitive_root_iff' IsPrimitiveRoot.isPrimitiveRoot_iff'
@@ -965,7 +965,7 @@ theorem isPrimitiveRoot_iff {k : ℕ} {ζ ξ : R} (h : IsPrimitiveRoot ζ k) (h0
   constructor
   · intro hξ
     obtain ⟨i, hik, rfl⟩ := h.eq_pow_of_pow_eq_one hξ.pow_eq_one h0
-    rw [h.pow_iff_coprime h0] at hξ 
+    rw [h.pow_iff_coprime h0] at hξ
     exact ⟨i, hik, hξ, rfl⟩
   · rintro ⟨i, -, hi, rfl⟩; exact h.pow_of_coprime i hi
 #align is_primitive_root.is_primitive_root_iff IsPrimitiveRoot.isPrimitiveRoot_iff
@@ -990,7 +990,7 @@ theorem card_rootsOfUnity {ζ : R} {n : ℕ+} (h : IsPrimitiveRoot ζ n) :
     Fintype.card (rootsOfUnity n R) = n :=
   by
   obtain ⟨ζ, hζ⟩ := h.is_unit n.pos
-  rw [← hζ, IsPrimitiveRoot.coe_units_iff] at h 
+  rw [← hζ, IsPrimitiveRoot.coe_units_iff] at h
   exact h.card_roots_of_unity'
 #align is_primitive_root.card_roots_of_unity IsPrimitiveRoot.card_rootsOfUnity
 -/
@@ -1009,10 +1009,10 @@ theorem card_nthRoots_one {ζ : R} {n : ℕ} (h : IsPrimitiveRoot ζ n) :
     have hcard :
       Fintype.card { x // x ∈ nth_roots n (1 : R) } ≤ (nth_roots n (1 : R)).attach.card :=
       Multiset.card_le_card (Multiset.dedup_le _)
-    rw [Multiset.card_attach] at hcard 
+    rw [Multiset.card_attach] at hcard
     rw [← PNat.toPNat'_coe hpos] at hcard h ⊢
     set m := Nat.toPNat' n
-    rw [← Fintype.card_congr (rootsOfUnityEquivNthRoots R m), card_rootsOfUnity h] at hcard 
+    rw [← Fintype.card_congr (rootsOfUnityEquivNthRoots R m), card_rootsOfUnity h] at hcard
     exact hcard
 #align is_primitive_root.card_nth_roots IsPrimitiveRoot.card_nthRoots_one
 -/
@@ -1030,16 +1030,16 @@ theorem nthRoots_one_nodup {ζ : R} {n : ℕ} (h : IsPrimitiveRoot ζ n) : (nthR
   · exact Multiset.dedup_le (nth_roots n (1 : R))
   · by_contra ha
     replace ha := Multiset.card_lt_of_lt ha
-    rw [card_nth_roots h] at ha 
+    rw [card_nth_roots h] at ha
     have hrw : (nth_roots n (1 : R)).dedup.card = Fintype.card { x // x ∈ nth_roots n (1 : R) } :=
       by
       set fs := (⟨(nth_roots n (1 : R)).dedup, Multiset.nodup_dedup _⟩ : Finset R)
       rw [← Finset.card_mk, ← Fintype.card_of_subtype fs _]
       intro x
       simp only [Multiset.mem_dedup, Finset.mem_mk]
-    rw [← PNat.toPNat'_coe hpos] at h hrw ha 
+    rw [← PNat.toPNat'_coe hpos] at h hrw ha
     set m := Nat.toPNat' n
-    rw [hrw, ← Fintype.card_congr (rootsOfUnityEquivNthRoots R m), card_rootsOfUnity h] at ha 
+    rw [hrw, ← Fintype.card_congr (rootsOfUnityEquivNthRoots R m), card_rootsOfUnity h] at ha
     exact Nat.lt_asymm ha ha
 #align is_primitive_root.nth_roots_nodup IsPrimitiveRoot.nthRoots_one_nodup
 -/
@@ -1072,7 +1072,7 @@ theorem card_primitiveRoots {ζ : R} {k : ℕ} (h : IsPrimitiveRoot ζ k) :
   · simp only [exists_prop, true_and_iff, mem_filter, mem_range, mem_univ]
     intro ξ hξ
     rw [mem_primitiveRoots (Nat.pos_of_ne_zero h0),
-      h.is_primitive_root_iff (Nat.pos_of_ne_zero h0)] at hξ 
+      h.is_primitive_root_iff (Nat.pos_of_ne_zero h0)] at hξ
     rcases hξ with ⟨i, hin, hi, H⟩
     exact ⟨i, ⟨hin, hi.symm⟩, H⟩
 #align is_primitive_root.card_primitive_roots IsPrimitiveRoot.card_primitiveRoots
@@ -1105,7 +1105,7 @@ theorem nthRoots_one_eq_biUnion_primitiveRoots' {ζ : R} {n : ℕ+} (h : IsPrimi
       contrapose! hd with ha0
       simp_all only [nonpos_iff_eq_zero, MulZeroClass.zero_mul]
       exact n.ne_zero
-    rw [mem_primitiveRoots hazero] at ha 
+    rw [mem_primitiveRoots hazero] at ha
     rw [hd, pow_mul, ha.pow_eq_one, one_pow]
   · apply le_of_eq
     rw [h.card_nth_roots_finset, Finset.card_biUnion]
@@ -1113,7 +1113,7 @@ theorem nthRoots_one_eq_biUnion_primitiveRoots' {ζ : R} {n : ℕ+} (h : IsPrimi
       refine' sum_congr rfl _
       simp only [Nat.mem_divisors]
       rintro k ⟨⟨d, hd⟩, -⟩
-      rw [mul_comm] at hd 
+      rw [mul_comm] at hd
       rw [(h.pow n.pos hd).card_primitiveRoots]
     · intro i hi j hj hdiff
       exact Disjoint hdiff
@@ -1155,7 +1155,7 @@ noncomputable def autToPow : (S ≃ₐ[R] S) →* (ZMod n)ˣ :=
           RingEquiv.coe_toRingHom, AlgEquiv.coe_ringEquiv] at *
         replace h : μ' = μ' ^ h1.some :=
           rootsOfUnity.coe_injective (by simpa only [rootsOfUnity.coe_pow] using h)
-        rw [← pow_one μ'] at h 
+        rw [← pow_one μ'] at h
         rw [← @Nat.cast_one <| ZMod n, ZMod.nat_cast_eq_nat_cast_iff, ← ho, ←
           pow_eq_pow_iff_modEq μ', h]
       map_mul' := by
@@ -1166,9 +1166,9 @@ noncomputable def autToPow : (S ≃ₐ[R] S) →* (ZMod n)ˣ :=
         dsimp only [AlgEquiv.toRingEquiv_eq_coe, RingEquiv.toRingHom_eq_coe,
           RingEquiv.coe_toRingHom, AlgEquiv.coe_ringEquiv, AlgEquiv.mul_apply] at *
         replace hxy : x (↑μ' ^ hy'.some) = ↑μ' ^ hxy'.some := hy ▸ hxy
-        rw [x.map_pow] at hxy 
+        rw [x.map_pow] at hxy
         replace hxy : ((μ' : S) ^ hx'.some) ^ hy'.some = μ' ^ hxy'.some := hx ▸ hxy
-        rw [← pow_mul] at hxy 
+        rw [← pow_mul] at hxy
         replace hxy : μ' ^ (hx'.some * hy'.some) = μ' ^ hxy'.some :=
           rootsOfUnity.coe_injective (by simpa only [rootsOfUnity.coe_pow] using hxy)
         rw [← Nat.cast_mul, ZMod.nat_cast_eq_nat_cast_iff, ← ho, ← pow_eq_pow_iff_modEq μ', hxy] }
@@ -1191,7 +1191,7 @@ theorem autToPow_spec (f : S ≃ₐ[R] S) : μ ^ (hμ.autToPow R f : ZMod n).val
   rw [IsPrimitiveRoot.coe_autToPow_apply]
   generalize_proofs h
   have := h.some_spec
-  dsimp only [AlgEquiv.toAlgHom_eq_coe, AlgEquiv.coe_algHom] at this 
+  dsimp only [AlgEquiv.toAlgHom_eq_coe, AlgEquiv.coe_algHom] at this
   refine' (_ : ↑hμ.to_roots_of_unity ^ _ = _).trans this.symm
   rw [← rootsOfUnity.coe_pow, ← rootsOfUnity.coe_pow]
   congr 1
Diff
@@ -308,7 +308,7 @@ theorem map_rootsOfUnity_eq_pow_self [RingHomClass F R R] (σ : F) (ζ : rootsOf
   rw [← restrictRootsOfUnity_coe_apply, hm, zpow_mod_orderOf, ←
     Int.toNat_of_nonneg
       (m.mod_nonneg (int.coe_nat_ne_zero.mpr (pos_iff_ne_zero.mp (orderOf_pos ζ)))),
-    zpow_ofNat, rootsOfUnity.coe_pow]
+    zpow_coe_nat, rootsOfUnity.coe_pow]
   exact ⟨(m % orderOf ζ).toNat, rfl⟩
 #align map_root_of_unity_eq_pow_self map_rootsOfUnity_eq_pow_self
 -/
@@ -507,9 +507,9 @@ theorem pow_of_coprime (h : IsPrimitiveRoot ζ k) (i : ℕ) (hi : i.Coprime k) :
       dvd_of_pow_eq_one := _ }
   intro l hl
   apply h.dvd_of_pow_eq_one
-  rw [← pow_one ζ, ← zpow_ofNat ζ, ← hi.gcd_eq_one, Nat.gcd_eq_gcd_ab, zpow_add, mul_pow, ←
-    zpow_ofNat, ← zpow_mul, mul_right_comm]
-  simp only [zpow_mul, hl, h.pow_eq_one, one_zpow, one_pow, one_mul, zpow_ofNat]
+  rw [← pow_one ζ, ← zpow_coe_nat ζ, ← hi.gcd_eq_one, Nat.gcd_eq_gcd_ab, zpow_add, mul_pow, ←
+    zpow_coe_nat, ← zpow_mul, mul_right_comm]
+  simp only [zpow_mul, hl, h.pow_eq_one, one_zpow, one_pow, one_mul, zpow_coe_nat]
 #align is_primitive_root.pow_of_coprime IsPrimitiveRoot.pow_of_coprime
 -/
 
@@ -668,7 +668,7 @@ section DivisionCommMonoid
 variable {ζ : G}
 
 #print IsPrimitiveRoot.zpow_eq_one /-
-theorem zpow_eq_one (h : IsPrimitiveRoot ζ k) : ζ ^ (k : ℤ) = 1 := by rw [zpow_ofNat];
+theorem zpow_eq_one (h : IsPrimitiveRoot ζ k) : ζ ^ (k : ℤ) = 1 := by rw [zpow_coe_nat];
   exact h.pow_eq_one
 #align is_primitive_root.zpow_eq_one IsPrimitiveRoot.zpow_eq_one
 -/
@@ -677,12 +677,12 @@ theorem zpow_eq_one (h : IsPrimitiveRoot ζ k) : ζ ^ (k : ℤ) = 1 := by rw [zp
 theorem zpow_eq_one_iff_dvd (h : IsPrimitiveRoot ζ k) (l : ℤ) : ζ ^ l = 1 ↔ (k : ℤ) ∣ l :=
   by
   by_cases h0 : 0 ≤ l
-  · lift l to ℕ using h0; rw [zpow_ofNat]; norm_cast; exact h.pow_eq_one_iff_dvd l
+  · lift l to ℕ using h0; rw [zpow_coe_nat]; norm_cast; exact h.pow_eq_one_iff_dvd l
   · have : 0 ≤ -l := by simp only [not_le, neg_nonneg] at h0 ⊢; exact le_of_lt h0
     lift -l to ℕ using this with l' hl'
     rw [← dvd_neg, ← hl']
     norm_cast
-    rw [← h.pow_eq_one_iff_dvd, ← inv_inj, ← zpow_neg, ← hl', zpow_ofNat, inv_one]
+    rw [← h.pow_eq_one_iff_dvd, ← inv_inj, ← zpow_neg, ← hl', zpow_coe_nat, inv_one]
 #align is_primitive_root.zpow_eq_one_iff_dvd IsPrimitiveRoot.zpow_eq_one_iff_dvd
 -/
 
@@ -708,11 +708,11 @@ theorem zpow_of_gcd_eq_one (h : IsPrimitiveRoot ζ k) (i : ℤ) (hi : i.gcd k =
     IsPrimitiveRoot (ζ ^ i) k := by
   by_cases h0 : 0 ≤ i
   · lift i to ℕ using h0
-    rw [zpow_ofNat]
+    rw [zpow_coe_nat]
     exact h.pow_of_coprime i hi
   have : 0 ≤ -i := by simp only [not_le, neg_nonneg] at h0 ⊢; exact le_of_lt h0
   lift -i to ℕ using this with i' hi'
-  rw [← inv_iff, ← zpow_neg, ← hi', zpow_ofNat]
+  rw [← inv_iff, ← zpow_neg, ← hi', zpow_coe_nat]
   apply h.pow_of_coprime
   rw [Int.gcd, ← Int.natAbs_neg, ← hi'] at hi 
   exact hi
@@ -830,7 +830,7 @@ def zmodEquivZPowers (h : IsPrimitiveRoot ζ k) : ZMod k ≃+ Additive (Subgroup
         simp only [AddMonoidHom.mem_ker, CharP.int_cast_eq_zero_iff (ZMod k) k, AddMonoidHom.coe_mk,
           Int.coe_castAddHom] at hi ⊢
         obtain ⟨i, rfl⟩ := hi
-        simp only [zpow_mul, h.pow_eq_one, one_zpow, zpow_ofNat]
+        simp only [zpow_mul, h.pow_eq_one, one_zpow, zpow_coe_nat]
         rfl⟩)
     (by
       constructor
@@ -861,7 +861,7 @@ theorem zmodEquivZPowers_apply_coe_nat (i : ℕ) :
     h.zmodEquivZPowers i = Additive.ofMul (⟨ζ ^ i, i, rfl⟩ : Subgroup.zpowers ζ) :=
   by
   have : (i : ZMod k) = (i : ℤ) := by norm_cast
-  simp only [this, zmod_equiv_zpowers_apply_coe_int, zpow_ofNat]
+  simp only [this, zmod_equiv_zpowers_apply_coe_int, zpow_coe_nat]
   rfl
 #align is_primitive_root.zmod_equiv_zpowers_apply_coe_nat IsPrimitiveRoot.zmodEquivZPowers_apply_coe_nat
 -/
@@ -927,7 +927,7 @@ theorem eq_pow_of_mem_rootsOfUnity {k : ℕ+} {ζ ξ : Rˣ} (h : IsPrimitiveRoot
   refine' ⟨i₀, _, _⟩
   · zify; rw [hi₀]; exact Int.emod_lt_of_pos _ hk0
   · have aux := h.zpow_eq_one; rw [← coe_coe] at aux 
-    rw [← zpow_ofNat, hi₀, ← Int.emod_add_ediv n k, zpow_add, zpow_mul, aux, one_zpow, mul_one]
+    rw [← zpow_coe_nat, hi₀, ← Int.emod_add_ediv n k, zpow_add, zpow_mul, aux, one_zpow, mul_one]
 #align is_primitive_root.eq_pow_of_mem_roots_of_unity IsPrimitiveRoot.eq_pow_of_mem_rootsOfUnity
 -/
 
Diff
@@ -185,32 +185,32 @@ theorem restrictRootsOfUnity_coe_apply [RingHomClass F R S] (σ : F) (ζ : roots
 #align restrict_roots_of_unity_coe_apply restrictRootsOfUnity_coe_apply
 -/
 
-#print RingEquiv.restrictRootsOfUnity /-
+#print MulEquiv.restrictRootsOfUnity /-
 /-- Restrict a ring isomorphism to the nth roots of unity -/
-def RingEquiv.restrictRootsOfUnity (σ : R ≃+* S) (n : ℕ+) : rootsOfUnity n R ≃* rootsOfUnity n S
+def MulEquiv.restrictRootsOfUnity (σ : R ≃+* S) (n : ℕ+) : rootsOfUnity n R ≃* rootsOfUnity n S
     where
   toFun := restrictRootsOfUnity σ.toRingHom n
   invFun := restrictRootsOfUnity σ.symm.toRingHom n
   left_inv ξ := by ext; exact σ.symm_apply_apply ξ
   right_inv ξ := by ext; exact σ.apply_symm_apply ξ
   map_mul' := (restrictRootsOfUnity _ n).map_hMul
-#align ring_equiv.restrict_roots_of_unity RingEquiv.restrictRootsOfUnity
+#align ring_equiv.restrict_roots_of_unity MulEquiv.restrictRootsOfUnity
 -/
 
-#print RingEquiv.restrictRootsOfUnity_coe_apply /-
+#print MulEquiv.restrictRootsOfUnity_coe_apply /-
 @[simp]
-theorem RingEquiv.restrictRootsOfUnity_coe_apply (σ : R ≃+* S) (ζ : rootsOfUnity k R) :
+theorem MulEquiv.restrictRootsOfUnity_coe_apply (σ : R ≃+* S) (ζ : rootsOfUnity k R) :
     ↑(σ.restrictRootsOfUnity k ζ) = σ ↑ζ :=
   rfl
-#align ring_equiv.restrict_roots_of_unity_coe_apply RingEquiv.restrictRootsOfUnity_coe_apply
+#align ring_equiv.restrict_roots_of_unity_coe_apply MulEquiv.restrictRootsOfUnity_coe_apply
 -/
 
-#print RingEquiv.restrictRootsOfUnity_symm /-
+#print MulEquiv.restrictRootsOfUnity_symm /-
 @[simp]
-theorem RingEquiv.restrictRootsOfUnity_symm (σ : R ≃+* S) :
+theorem MulEquiv.restrictRootsOfUnity_symm (σ : R ≃+* S) :
     (σ.restrictRootsOfUnity k).symm = σ.symm.restrictRootsOfUnity k :=
   rfl
-#align ring_equiv.restrict_roots_of_unity_symm RingEquiv.restrictRootsOfUnity_symm
+#align ring_equiv.restrict_roots_of_unity_symm MulEquiv.restrictRootsOfUnity_symm
 -/
 
 end CommSemiring
Diff
@@ -995,10 +995,11 @@ theorem card_rootsOfUnity {ζ : R} {n : ℕ+} (h : IsPrimitiveRoot ζ n) :
 #align is_primitive_root.card_roots_of_unity IsPrimitiveRoot.card_rootsOfUnity
 -/
 
-#print IsPrimitiveRoot.card_nthRoots /-
+#print IsPrimitiveRoot.card_nthRoots_one /-
 /-- The cardinality of the multiset `nth_roots ↑n (1 : R)` is `n`
 if there is a primitive root of unity in `R`. -/
-theorem card_nthRoots {ζ : R} {n : ℕ} (h : IsPrimitiveRoot ζ n) : (nthRoots n (1 : R)).card = n :=
+theorem card_nthRoots_one {ζ : R} {n : ℕ} (h : IsPrimitiveRoot ζ n) :
+    (nthRoots n (1 : R)).card = n :=
   by
   cases' Nat.eq_zero_or_pos n with hzero hpos
   · simp only [hzero, Multiset.card_zero, nth_roots_zero]
@@ -1013,13 +1014,13 @@ theorem card_nthRoots {ζ : R} {n : ℕ} (h : IsPrimitiveRoot ζ n) : (nthRoots
     set m := Nat.toPNat' n
     rw [← Fintype.card_congr (rootsOfUnityEquivNthRoots R m), card_rootsOfUnity h] at hcard 
     exact hcard
-#align is_primitive_root.card_nth_roots IsPrimitiveRoot.card_nthRoots
+#align is_primitive_root.card_nth_roots IsPrimitiveRoot.card_nthRoots_one
 -/
 
-#print IsPrimitiveRoot.nthRoots_nodup /-
+#print IsPrimitiveRoot.nthRoots_one_nodup /-
 /-- The multiset `nth_roots ↑n (1 : R)` has no repeated elements
 if there is a primitive root of unity in `R`. -/
-theorem nthRoots_nodup {ζ : R} {n : ℕ} (h : IsPrimitiveRoot ζ n) : (nthRoots n (1 : R)).Nodup :=
+theorem nthRoots_one_nodup {ζ : R} {n : ℕ} (h : IsPrimitiveRoot ζ n) : (nthRoots n (1 : R)).Nodup :=
   by
   cases' Nat.eq_zero_or_pos n with hzero hpos
   · simp only [hzero, Multiset.nodup_zero, nth_roots_zero]
@@ -1040,7 +1041,7 @@ theorem nthRoots_nodup {ζ : R} {n : ℕ} (h : IsPrimitiveRoot ζ n) : (nthRoots
     set m := Nat.toPNat' n
     rw [hrw, ← Fintype.card_congr (rootsOfUnityEquivNthRoots R m), card_rootsOfUnity h] at ha 
     exact Nat.lt_asymm ha ha
-#align is_primitive_root.nth_roots_nodup IsPrimitiveRoot.nthRoots_nodup
+#align is_primitive_root.nth_roots_nodup IsPrimitiveRoot.nthRoots_one_nodup
 -/
 
 #print IsPrimitiveRoot.card_nthRootsFinset /-
Diff
@@ -292,7 +292,7 @@ theorem card_rootsOfUnity : Fintype.card (rootsOfUnity k R) ≤ k :=
   calc
     Fintype.card (rootsOfUnity k R) = Fintype.card { x // x ∈ nthRoots k (1 : R) } :=
       Fintype.card_congr (rootsOfUnityEquivNthRoots R k)
-    _ ≤ (nthRoots k (1 : R)).attach.card := (Multiset.card_le_of_le (Multiset.dedup_le _))
+    _ ≤ (nthRoots k (1 : R)).attach.card := (Multiset.card_le_card (Multiset.dedup_le _))
     _ = (nthRoots k (1 : R)).card := Multiset.card_attach
     _ ≤ k := card_nthRoots k 1
 #align card_roots_of_unity card_rootsOfUnity
@@ -1007,7 +1007,7 @@ theorem card_nthRoots {ζ : R} {n : ℕ} (h : IsPrimitiveRoot ζ n) : (nthRoots
   · rw [not_lt]
     have hcard :
       Fintype.card { x // x ∈ nth_roots n (1 : R) } ≤ (nth_roots n (1 : R)).attach.card :=
-      Multiset.card_le_of_le (Multiset.dedup_le _)
+      Multiset.card_le_card (Multiset.dedup_le _)
     rw [Multiset.card_attach] at hcard 
     rw [← PNat.toPNat'_coe hpos] at hcard h ⊢
     set m := Nat.toPNat' n
Diff
@@ -817,10 +817,10 @@ theorem pow_sub_one_eq [IsDomain R] {ζ : R} (hζ : IsPrimitiveRoot ζ k) (hk :
 #align is_primitive_root.pow_sub_one_eq IsPrimitiveRoot.pow_sub_one_eq
 -/
 
-#print IsPrimitiveRoot.zmodEquivZpowers /-
+#print IsPrimitiveRoot.zmodEquivZPowers /-
 /-- The (additive) monoid equivalence between `zmod k`
 and the powers of a primitive root of unity `ζ`. -/
-def zmodEquivZpowers (h : IsPrimitiveRoot ζ k) : ZMod k ≃+ Additive (Subgroup.zpowers ζ) :=
+def zmodEquivZPowers (h : IsPrimitiveRoot ζ k) : ZMod k ≃+ Additive (Subgroup.zpowers ζ) :=
   AddEquiv.ofBijective
     (AddMonoidHom.liftOfRightInverse (Int.castAddHom <| ZMod k) _ ZMod.int_cast_rightInverse
       ⟨{  toFun := fun i => Additive.ofMul (⟨_, i, rfl⟩ : Subgroup.zpowers ζ)
@@ -844,56 +844,56 @@ def zmodEquivZpowers (h : IsPrimitiveRoot ζ k) : ZMod k ≃+ Additive (Subgroup
         refine' ⟨Int.castAddHom _ i, _⟩
         rw [AddMonoidHom.liftOfRightInverse_comp_apply]
         rfl)
-#align is_primitive_root.zmod_equiv_zpowers IsPrimitiveRoot.zmodEquivZpowers
+#align is_primitive_root.zmod_equiv_zpowers IsPrimitiveRoot.zmodEquivZPowers
 -/
 
-#print IsPrimitiveRoot.zmodEquivZpowers_apply_coe_int /-
+#print IsPrimitiveRoot.zmodEquivZPowers_apply_coe_int /-
 @[simp]
-theorem zmodEquivZpowers_apply_coe_int (i : ℤ) :
-    h.zmodEquivZpowers i = Additive.ofMul (⟨ζ ^ i, i, rfl⟩ : Subgroup.zpowers ζ) :=
+theorem zmodEquivZPowers_apply_coe_int (i : ℤ) :
+    h.zmodEquivZPowers i = Additive.ofMul (⟨ζ ^ i, i, rfl⟩ : Subgroup.zpowers ζ) :=
   AddMonoidHom.liftOfRightInverse_comp_apply _ _ ZMod.int_cast_rightInverse _ _
-#align is_primitive_root.zmod_equiv_zpowers_apply_coe_int IsPrimitiveRoot.zmodEquivZpowers_apply_coe_int
+#align is_primitive_root.zmod_equiv_zpowers_apply_coe_int IsPrimitiveRoot.zmodEquivZPowers_apply_coe_int
 -/
 
-#print IsPrimitiveRoot.zmodEquivZpowers_apply_coe_nat /-
+#print IsPrimitiveRoot.zmodEquivZPowers_apply_coe_nat /-
 @[simp]
-theorem zmodEquivZpowers_apply_coe_nat (i : ℕ) :
-    h.zmodEquivZpowers i = Additive.ofMul (⟨ζ ^ i, i, rfl⟩ : Subgroup.zpowers ζ) :=
+theorem zmodEquivZPowers_apply_coe_nat (i : ℕ) :
+    h.zmodEquivZPowers i = Additive.ofMul (⟨ζ ^ i, i, rfl⟩ : Subgroup.zpowers ζ) :=
   by
   have : (i : ZMod k) = (i : ℤ) := by norm_cast
   simp only [this, zmod_equiv_zpowers_apply_coe_int, zpow_ofNat]
   rfl
-#align is_primitive_root.zmod_equiv_zpowers_apply_coe_nat IsPrimitiveRoot.zmodEquivZpowers_apply_coe_nat
+#align is_primitive_root.zmod_equiv_zpowers_apply_coe_nat IsPrimitiveRoot.zmodEquivZPowers_apply_coe_nat
 -/
 
-#print IsPrimitiveRoot.zmodEquivZpowers_symm_apply_zpow /-
+#print IsPrimitiveRoot.zmodEquivZPowers_symm_apply_zpow /-
 @[simp]
-theorem zmodEquivZpowers_symm_apply_zpow (i : ℤ) :
-    h.zmodEquivZpowers.symm (Additive.ofMul (⟨ζ ^ i, i, rfl⟩ : Subgroup.zpowers ζ)) = i := by
+theorem zmodEquivZPowers_symm_apply_zpow (i : ℤ) :
+    h.zmodEquivZPowers.symm (Additive.ofMul (⟨ζ ^ i, i, rfl⟩ : Subgroup.zpowers ζ)) = i := by
   rw [← h.zmod_equiv_zpowers.symm_apply_apply i, zmod_equiv_zpowers_apply_coe_int]
-#align is_primitive_root.zmod_equiv_zpowers_symm_apply_zpow IsPrimitiveRoot.zmodEquivZpowers_symm_apply_zpow
+#align is_primitive_root.zmod_equiv_zpowers_symm_apply_zpow IsPrimitiveRoot.zmodEquivZPowers_symm_apply_zpow
 -/
 
-#print IsPrimitiveRoot.zmodEquivZpowers_symm_apply_zpow' /-
+#print IsPrimitiveRoot.zmodEquivZPowers_symm_apply_zpow' /-
 @[simp]
-theorem zmodEquivZpowers_symm_apply_zpow' (i : ℤ) : h.zmodEquivZpowers.symm ⟨ζ ^ i, i, rfl⟩ = i :=
-  h.zmodEquivZpowers_symm_apply_zpow i
-#align is_primitive_root.zmod_equiv_zpowers_symm_apply_zpow' IsPrimitiveRoot.zmodEquivZpowers_symm_apply_zpow'
+theorem zmodEquivZPowers_symm_apply_zpow' (i : ℤ) : h.zmodEquivZPowers.symm ⟨ζ ^ i, i, rfl⟩ = i :=
+  h.zmodEquivZPowers_symm_apply_zpow i
+#align is_primitive_root.zmod_equiv_zpowers_symm_apply_zpow' IsPrimitiveRoot.zmodEquivZPowers_symm_apply_zpow'
 -/
 
-#print IsPrimitiveRoot.zmodEquivZpowers_symm_apply_pow /-
+#print IsPrimitiveRoot.zmodEquivZPowers_symm_apply_pow /-
 @[simp]
-theorem zmodEquivZpowers_symm_apply_pow (i : ℕ) :
-    h.zmodEquivZpowers.symm (Additive.ofMul (⟨ζ ^ i, i, rfl⟩ : Subgroup.zpowers ζ)) = i := by
+theorem zmodEquivZPowers_symm_apply_pow (i : ℕ) :
+    h.zmodEquivZPowers.symm (Additive.ofMul (⟨ζ ^ i, i, rfl⟩ : Subgroup.zpowers ζ)) = i := by
   rw [← h.zmod_equiv_zpowers.symm_apply_apply i, zmod_equiv_zpowers_apply_coe_nat]
-#align is_primitive_root.zmod_equiv_zpowers_symm_apply_pow IsPrimitiveRoot.zmodEquivZpowers_symm_apply_pow
+#align is_primitive_root.zmod_equiv_zpowers_symm_apply_pow IsPrimitiveRoot.zmodEquivZPowers_symm_apply_pow
 -/
 
-#print IsPrimitiveRoot.zmodEquivZpowers_symm_apply_pow' /-
+#print IsPrimitiveRoot.zmodEquivZPowers_symm_apply_pow' /-
 @[simp]
-theorem zmodEquivZpowers_symm_apply_pow' (i : ℕ) : h.zmodEquivZpowers.symm ⟨ζ ^ i, i, rfl⟩ = i :=
-  h.zmodEquivZpowers_symm_apply_pow i
-#align is_primitive_root.zmod_equiv_zpowers_symm_apply_pow' IsPrimitiveRoot.zmodEquivZpowers_symm_apply_pow'
+theorem zmodEquivZPowers_symm_apply_pow' (i : ℕ) : h.zmodEquivZPowers.symm ⟨ζ ^ i, i, rfl⟩ = i :=
+  h.zmodEquivZPowers_symm_apply_pow i
+#align is_primitive_root.zmod_equiv_zpowers_symm_apply_pow' IsPrimitiveRoot.zmodEquivZPowers_symm_apply_pow'
 -/
 
 variable [IsDomain R]
Diff
@@ -1144,7 +1144,7 @@ variable {S} [CommRing S] [IsDomain S] {μ : S} {n : ℕ+} (hμ : IsPrimitiveRoo
 noncomputable def autToPow : (S ≃ₐ[R] S) →* (ZMod n)ˣ :=
   let μ' := hμ.toRootsOfUnity
   have ho : orderOf μ' = n := by
-    rw [hμ.eq_order_of, ← hμ.coe_to_roots_of_unity_coe, orderOf_units, orderOf_subgroup]
+    rw [hμ.eq_order_of, ← hμ.coe_to_roots_of_unity_coe, orderOf_units, Subgroup.orderOf_coe]
   MonoidHom.toHomUnits
     { toFun := fun σ => (map_rootsOfUnity_eq_pow_self σ.toAlgHom μ').some
       map_one' := by
@@ -1194,7 +1194,7 @@ theorem autToPow_spec (f : S ≃ₐ[R] S) : μ ^ (hμ.autToPow R f : ZMod n).val
   refine' (_ : ↑hμ.to_roots_of_unity ^ _ = _).trans this.symm
   rw [← rootsOfUnity.coe_pow, ← rootsOfUnity.coe_pow]
   congr 1
-  rw [pow_eq_pow_iff_modEq, ← orderOf_subgroup, ← orderOf_units, hμ.coe_to_roots_of_unity_coe, ←
+  rw [pow_eq_pow_iff_modEq, ← Subgroup.orderOf_coe, ← orderOf_units, hμ.coe_to_roots_of_unity_coe, ←
     hμ.eq_order_of, ZMod.val_nat_cast]
   exact Nat.mod_modEq _ _
 #align is_primitive_root.aut_to_pow_spec IsPrimitiveRoot.autToPow_spec
Diff
@@ -305,7 +305,7 @@ theorem map_rootsOfUnity_eq_pow_self [RingHomClass F R R] (σ : F) (ζ : rootsOf
     ∃ m : ℕ, σ ζ = ζ ^ m :=
   by
   obtain ⟨m, hm⟩ := MonoidHom.map_cyclic (restrictRootsOfUnity σ k)
-  rw [← restrictRootsOfUnity_coe_apply, hm, zpow_eq_mod_orderOf, ←
+  rw [← restrictRootsOfUnity_coe_apply, hm, zpow_mod_orderOf, ←
     Int.toNat_of_nonneg
       (m.mod_nonneg (int.coe_nat_ne_zero.mpr (pos_iff_ne_zero.mp (orderOf_pos ζ)))),
     zpow_ofNat, rootsOfUnity.coe_pow]
Diff
@@ -3,16 +3,16 @@ Copyright (c) 2020 Johan Commelin. All rights reserved.
 Released under Apache 2.0 license as described in the file LICENSE.
 Authors: Johan Commelin
 -/
-import Mathbin.Algebra.CharP.Two
-import Mathbin.Algebra.NeZero
-import Mathbin.Algebra.GcdMonoid.IntegrallyClosed
-import Mathbin.Data.Polynomial.RingDivision
-import Mathbin.FieldTheory.Finite.Basic
-import Mathbin.FieldTheory.Separable
-import Mathbin.GroupTheory.SpecificGroups.Cyclic
-import Mathbin.NumberTheory.Divisors
-import Mathbin.RingTheory.IntegralDomain
-import Mathbin.Tactic.Zify
+import Algebra.CharP.Two
+import Algebra.NeZero
+import Algebra.GcdMonoid.IntegrallyClosed
+import Data.Polynomial.RingDivision
+import FieldTheory.Finite.Basic
+import FieldTheory.Separable
+import GroupTheory.SpecificGroups.Cyclic
+import NumberTheory.Divisors
+import RingTheory.IntegralDomain
+import Tactic.Zify
 
 #align_import ring_theory.roots_of_unity.basic from "leanprover-community/mathlib"@"7e5137f579de09a059a5ce98f364a04e221aabf0"
 
@@ -520,7 +520,7 @@ theorem pow_of_prime (h : IsPrimitiveRoot ζ k) {p : ℕ} (hprime : Nat.Prime p)
 #align is_primitive_root.pow_of_prime IsPrimitiveRoot.pow_of_prime
 -/
 
-/- ./././Mathport/Syntax/Translate/Tactic/Lean3.lean:132:4: warning: unsupported: rw with cfg: { occs := occurrences.pos[occurrences.pos] «expr[ ,]»([1]) } -/
+/- ./././Mathport/Syntax/Translate/Tactic/Lean3.lean:133:4: warning: unsupported: rw with cfg: { occs := occurrences.pos[occurrences.pos] «expr[ ,]»([1]) } -/
 #print IsPrimitiveRoot.pow_iff_coprime /-
 theorem pow_iff_coprime (h : IsPrimitiveRoot ζ k) (h0 : 0 < k) (i : ℕ) :
     IsPrimitiveRoot (ζ ^ i) k ↔ i.Coprime k :=
@@ -1138,7 +1138,7 @@ section Automorphisms
 variable {S} [CommRing S] [IsDomain S] {μ : S} {n : ℕ+} (hμ : IsPrimitiveRoot μ n) (R) [CommRing R]
   [Algebra R S]
 
-/- ./././Mathport/Syntax/Translate/Tactic/Lean3.lean:132:4: warning: unsupported: rw with cfg: { occs := occurrences.pos[occurrences.pos] «expr[ ,]»([1]) } -/
+/- ./././Mathport/Syntax/Translate/Tactic/Lean3.lean:133:4: warning: unsupported: rw with cfg: { occs := occurrences.pos[occurrences.pos] «expr[ ,]»([1]) } -/
 #print IsPrimitiveRoot.autToPow /-
 /-- The `monoid_hom` that takes an automorphism to the power of μ that μ gets mapped to under it. -/
 noncomputable def autToPow : (S ≃ₐ[R] S) →* (ZMod n)ˣ :=
Diff
@@ -495,7 +495,7 @@ theorem coe_units_iff {ζ : Mˣ} : IsPrimitiveRoot (ζ : M) k ↔ IsPrimitiveRoo
 -/
 
 #print IsPrimitiveRoot.pow_of_coprime /-
-theorem pow_of_coprime (h : IsPrimitiveRoot ζ k) (i : ℕ) (hi : i.coprime k) :
+theorem pow_of_coprime (h : IsPrimitiveRoot ζ k) (i : ℕ) (hi : i.Coprime k) :
     IsPrimitiveRoot (ζ ^ i) k := by
   by_cases h0 : k = 0
   · subst k; simp_all only [pow_one, Nat.coprime_zero_right]
@@ -523,7 +523,7 @@ theorem pow_of_prime (h : IsPrimitiveRoot ζ k) {p : ℕ} (hprime : Nat.Prime p)
 /- ./././Mathport/Syntax/Translate/Tactic/Lean3.lean:132:4: warning: unsupported: rw with cfg: { occs := occurrences.pos[occurrences.pos] «expr[ ,]»([1]) } -/
 #print IsPrimitiveRoot.pow_iff_coprime /-
 theorem pow_iff_coprime (h : IsPrimitiveRoot ζ k) (h0 : 0 < k) (i : ℕ) :
-    IsPrimitiveRoot (ζ ^ i) k ↔ i.coprime k :=
+    IsPrimitiveRoot (ζ ^ i) k ↔ i.Coprime k :=
   by
   refine' ⟨_, h.pow_of_coprime i⟩
   intro hi
@@ -947,7 +947,7 @@ theorem eq_pow_of_pow_eq_one {k : ℕ} {ζ ξ : R} (h : IsPrimitiveRoot ζ k) (h
 
 #print IsPrimitiveRoot.isPrimitiveRoot_iff' /-
 theorem isPrimitiveRoot_iff' {k : ℕ+} {ζ ξ : Rˣ} (h : IsPrimitiveRoot ζ k) :
-    IsPrimitiveRoot ξ k ↔ ∃ i < (k : ℕ), ∃ hi : i.coprime k, ζ ^ i = ξ :=
+    IsPrimitiveRoot ξ k ↔ ∃ i < (k : ℕ), ∃ hi : i.Coprime k, ζ ^ i = ξ :=
   by
   constructor
   · intro hξ
@@ -960,7 +960,7 @@ theorem isPrimitiveRoot_iff' {k : ℕ+} {ζ ξ : Rˣ} (h : IsPrimitiveRoot ζ k)
 
 #print IsPrimitiveRoot.isPrimitiveRoot_iff /-
 theorem isPrimitiveRoot_iff {k : ℕ} {ζ ξ : R} (h : IsPrimitiveRoot ζ k) (h0 : 0 < k) :
-    IsPrimitiveRoot ξ k ↔ ∃ i < k, ∃ hi : i.coprime k, ζ ^ i = ξ :=
+    IsPrimitiveRoot ξ k ↔ ∃ i < k, ∃ hi : i.Coprime k, ζ ^ i = ξ :=
   by
   constructor
   · intro hξ
Diff
@@ -89,7 +89,7 @@ def rootsOfUnity (k : ℕ+) (M : Type _) [CommMonoid M] : Subgroup Mˣ
     where
   carrier := {ζ | ζ ^ (k : ℕ) = 1}
   one_mem' := one_pow _
-  mul_mem' ζ ξ hζ hξ := by simp_all only [Set.mem_setOf_eq, mul_pow, one_mul]
+  hMul_mem' ζ ξ hζ hξ := by simp_all only [Set.mem_setOf_eq, mul_pow, one_mul]
   inv_mem' ζ hζ := by simp_all only [Set.mem_setOf_eq, inv_pow, inv_one]
 #align roots_of_unity rootsOfUnity
 -/
@@ -193,7 +193,7 @@ def RingEquiv.restrictRootsOfUnity (σ : R ≃+* S) (n : ℕ+) : rootsOfUnity n
   invFun := restrictRootsOfUnity σ.symm.toRingHom n
   left_inv ξ := by ext; exact σ.symm_apply_apply ξ
   right_inv ξ := by ext; exact σ.apply_symm_apply ξ
-  map_mul' := (restrictRootsOfUnity _ n).map_mul
+  map_mul' := (restrictRootsOfUnity _ n).map_hMul
 #align ring_equiv.restrict_roots_of_unity RingEquiv.restrictRootsOfUnity
 -/
 
Diff
@@ -2,11 +2,6 @@
 Copyright (c) 2020 Johan Commelin. All rights reserved.
 Released under Apache 2.0 license as described in the file LICENSE.
 Authors: Johan Commelin
-
-! This file was ported from Lean 3 source module ring_theory.roots_of_unity.basic
-! leanprover-community/mathlib commit 7e5137f579de09a059a5ce98f364a04e221aabf0
-! Please do not edit these lines, except to modify the commit id
-! if you have ported upstream changes.
 -/
 import Mathbin.Algebra.CharP.Two
 import Mathbin.Algebra.NeZero
@@ -19,6 +14,8 @@ import Mathbin.NumberTheory.Divisors
 import Mathbin.RingTheory.IntegralDomain
 import Mathbin.Tactic.Zify
 
+#align_import ring_theory.roots_of_unity.basic from "leanprover-community/mathlib"@"7e5137f579de09a059a5ce98f364a04e221aabf0"
+
 /-!
 # Roots of unity and primitive roots of unity
 
Diff
@@ -743,8 +743,8 @@ theorem primitiveRoots_one : primitiveRoots 1 R = {(1 : R)} :=
 #align is_primitive_root.primitive_roots_one IsPrimitiveRoot.primitiveRoots_one
 -/
 
-#print IsPrimitiveRoot.ne_zero' /-
-theorem ne_zero' {n : ℕ+} (hζ : IsPrimitiveRoot ζ n) : NeZero ((n : ℕ) : R) :=
+#print IsPrimitiveRoot.neZero' /-
+theorem neZero' {n : ℕ+} (hζ : IsPrimitiveRoot ζ n) : NeZero ((n : ℕ) : R) :=
   by
   let p := ringChar R
   have hfin := multiplicity.finite_nat_iff.2 ⟨CharP.char_ne_one R p, n.pos⟩
@@ -766,7 +766,7 @@ theorem ne_zero' {n : ℕ+} (hζ : IsPrimitiveRoot ζ n) : NeZero ((n : ℕ) : R
     · rw [hm.1, hk, pow_succ, mul_assoc, mul_comm p]
       exact lt_mul_of_one_lt_right hpos hpri.1.one_lt
   · exact NeZero.of_not_dvd R hp
-#align is_primitive_root.ne_zero' IsPrimitiveRoot.ne_zero'
+#align is_primitive_root.ne_zero' IsPrimitiveRoot.neZero'
 -/
 
 #print IsPrimitiveRoot.mem_nthRootsFinset /-
Diff
@@ -86,6 +86,7 @@ section rootsOfUnity
 
 variable {k l : ℕ+}
 
+#print rootsOfUnity /-
 /-- `roots_of_unity k M` is the subgroup of elements `m : Mˣ` that satisfy `m ^ k = 1` -/
 def rootsOfUnity (k : ℕ+) (M : Type _) [CommMonoid M] : Subgroup Mˣ
     where
@@ -94,57 +95,75 @@ def rootsOfUnity (k : ℕ+) (M : Type _) [CommMonoid M] : Subgroup Mˣ
   mul_mem' ζ ξ hζ hξ := by simp_all only [Set.mem_setOf_eq, mul_pow, one_mul]
   inv_mem' ζ hζ := by simp_all only [Set.mem_setOf_eq, inv_pow, inv_one]
 #align roots_of_unity rootsOfUnity
+-/
 
+#print mem_rootsOfUnity /-
 @[simp]
 theorem mem_rootsOfUnity (k : ℕ+) (ζ : Mˣ) : ζ ∈ rootsOfUnity k M ↔ ζ ^ (k : ℕ) = 1 :=
   Iff.rfl
 #align mem_roots_of_unity mem_rootsOfUnity
+-/
 
+#print mem_rootsOfUnity' /-
 theorem mem_rootsOfUnity' (k : ℕ+) (ζ : Mˣ) : ζ ∈ rootsOfUnity k M ↔ (ζ : M) ^ (k : ℕ) = 1 := by
   rw [mem_rootsOfUnity]; norm_cast
 #align mem_roots_of_unity' mem_rootsOfUnity'
+-/
 
+#print rootsOfUnity.coe_injective /-
 theorem rootsOfUnity.coe_injective {n : ℕ+} : Function.Injective (coe : rootsOfUnity n M → M) :=
   Units.ext.comp fun x y => Subtype.ext
 #align roots_of_unity.coe_injective rootsOfUnity.coe_injective
+-/
 
+#print rootsOfUnity.mkOfPowEq /-
 /-- Make an element of `roots_of_unity` from a member of the base ring, and a proof that it has
 a positive power equal to one. -/
 @[simps coe_coe]
 def rootsOfUnity.mkOfPowEq (ζ : M) {n : ℕ+} (h : ζ ^ (n : ℕ) = 1) : rootsOfUnity n M :=
   ⟨Units.ofPowEqOne ζ n h n.NeZero, Units.pow_ofPowEqOne _ _⟩
 #align roots_of_unity.mk_of_pow_eq rootsOfUnity.mkOfPowEq
+-/
 
+#print rootsOfUnity.coe_mkOfPowEq /-
 @[simp]
 theorem rootsOfUnity.coe_mkOfPowEq {ζ : M} {n : ℕ+} (h : ζ ^ (n : ℕ) = 1) :
     (rootsOfUnity.mkOfPowEq _ h : M) = ζ :=
   rfl
 #align roots_of_unity.coe_mk_of_pow_eq rootsOfUnity.coe_mkOfPowEq
+-/
 
+#print rootsOfUnity_le_of_dvd /-
 theorem rootsOfUnity_le_of_dvd (h : k ∣ l) : rootsOfUnity k M ≤ rootsOfUnity l M :=
   by
   obtain ⟨d, rfl⟩ := h
   intro ζ h
   simp_all only [mem_rootsOfUnity, PNat.mul_coe, pow_mul, one_pow]
 #align roots_of_unity_le_of_dvd rootsOfUnity_le_of_dvd
+-/
 
+#print map_rootsOfUnity /-
 theorem map_rootsOfUnity (f : Mˣ →* Nˣ) (k : ℕ+) : (rootsOfUnity k M).map f ≤ rootsOfUnity k N :=
   by
   rintro _ ⟨ζ, h, rfl⟩
   simp_all only [← map_pow, mem_rootsOfUnity, SetLike.mem_coe, MonoidHom.map_one]
 #align map_roots_of_unity map_rootsOfUnity
+-/
 
+#print rootsOfUnity.coe_pow /-
 @[norm_cast]
 theorem rootsOfUnity.coe_pow [CommMonoid R] (ζ : rootsOfUnity k R) (m : ℕ) :
     ↑(ζ ^ m) = (ζ ^ m : R) := by
   change ↑(↑(ζ ^ m) : Rˣ) = ↑(ζ : Rˣ) ^ m
   rw [Subgroup.coe_pow, Units.val_pow_eq_pow_val]
 #align roots_of_unity.coe_pow rootsOfUnity.coe_pow
+-/
 
 section CommSemiring
 
 variable [CommSemiring R] [CommSemiring S]
 
+#print restrictRootsOfUnity /-
 /-- Restrict a ring homomorphism to the nth roots of unity -/
 def restrictRootsOfUnity [RingHomClass F R S] (σ : F) (n : ℕ+) :
     rootsOfUnity n R →* rootsOfUnity n S :=
@@ -159,13 +178,17 @@ def restrictRootsOfUnity [RingHomClass F R S] (σ : F) (n : ℕ+) :
     map_one' := by ext; exact map_one σ
     map_mul' := fun ξ₁ ξ₂ => by ext; rw [Subgroup.coe_mul, Units.val_mul]; exact map_mul σ _ _ }
 #align restrict_roots_of_unity restrictRootsOfUnity
+-/
 
+#print restrictRootsOfUnity_coe_apply /-
 @[simp]
 theorem restrictRootsOfUnity_coe_apply [RingHomClass F R S] (σ : F) (ζ : rootsOfUnity k R) :
     ↑(restrictRootsOfUnity σ k ζ) = σ ↑ζ :=
   rfl
 #align restrict_roots_of_unity_coe_apply restrictRootsOfUnity_coe_apply
+-/
 
+#print RingEquiv.restrictRootsOfUnity /-
 /-- Restrict a ring isomorphism to the nth roots of unity -/
 def RingEquiv.restrictRootsOfUnity (σ : R ≃+* S) (n : ℕ+) : rootsOfUnity n R ≃* rootsOfUnity n S
     where
@@ -175,18 +198,23 @@ def RingEquiv.restrictRootsOfUnity (σ : R ≃+* S) (n : ℕ+) : rootsOfUnity n
   right_inv ξ := by ext; exact σ.apply_symm_apply ξ
   map_mul' := (restrictRootsOfUnity _ n).map_mul
 #align ring_equiv.restrict_roots_of_unity RingEquiv.restrictRootsOfUnity
+-/
 
+#print RingEquiv.restrictRootsOfUnity_coe_apply /-
 @[simp]
 theorem RingEquiv.restrictRootsOfUnity_coe_apply (σ : R ≃+* S) (ζ : rootsOfUnity k R) :
     ↑(σ.restrictRootsOfUnity k ζ) = σ ↑ζ :=
   rfl
 #align ring_equiv.restrict_roots_of_unity_coe_apply RingEquiv.restrictRootsOfUnity_coe_apply
+-/
 
+#print RingEquiv.restrictRootsOfUnity_symm /-
 @[simp]
 theorem RingEquiv.restrictRootsOfUnity_symm (σ : R ≃+* S) :
     (σ.restrictRootsOfUnity k).symm = σ.symm.restrictRootsOfUnity k :=
   rfl
 #align ring_equiv.restrict_roots_of_unity_symm RingEquiv.restrictRootsOfUnity_symm
+-/
 
 end CommSemiring
 
@@ -194,14 +222,17 @@ section IsDomain
 
 variable [CommRing R] [IsDomain R]
 
+#print mem_rootsOfUnity_iff_mem_nthRoots /-
 theorem mem_rootsOfUnity_iff_mem_nthRoots {ζ : Rˣ} :
     ζ ∈ rootsOfUnity k R ↔ (ζ : R) ∈ nthRoots k (1 : R) := by
   simp only [mem_rootsOfUnity, mem_nth_roots k.pos, Units.ext_iff, Units.val_one,
     Units.val_pow_eq_pow_val]
 #align mem_roots_of_unity_iff_mem_nth_roots mem_rootsOfUnity_iff_mem_nthRoots
+-/
 
 variable (k R)
 
+#print rootsOfUnityEquivNthRoots /-
 /-- Equivalence between the `k`-th roots of unity in `R` and the `k`-th roots of `1`.
 
 This is implemented as equivalence of subtypes,
@@ -224,32 +255,42 @@ def rootsOfUnityEquivNthRoots : rootsOfUnity k R ≃ { x // x ∈ nthRoots k (1
     simp only [Units.ext_iff, hx, Units.val_mk, Units.val_one, Subtype.coe_mk,
       Units.val_pow_eq_pow_val]
 #align roots_of_unity_equiv_nth_roots rootsOfUnityEquivNthRoots
+-/
 
 variable {k R}
 
+#print rootsOfUnityEquivNthRoots_apply /-
 @[simp]
 theorem rootsOfUnityEquivNthRoots_apply (x : rootsOfUnity k R) :
     (rootsOfUnityEquivNthRoots R k x : R) = x :=
   rfl
 #align roots_of_unity_equiv_nth_roots_apply rootsOfUnityEquivNthRoots_apply
+-/
 
+#print rootsOfUnityEquivNthRoots_symm_apply /-
 @[simp]
 theorem rootsOfUnityEquivNthRoots_symm_apply (x : { x // x ∈ nthRoots k (1 : R) }) :
     ((rootsOfUnityEquivNthRoots R k).symm x : R) = x :=
   rfl
 #align roots_of_unity_equiv_nth_roots_symm_apply rootsOfUnityEquivNthRoots_symm_apply
+-/
 
 variable (k R)
 
+#print rootsOfUnity.fintype /-
 instance rootsOfUnity.fintype : Fintype (rootsOfUnity k R) :=
   Fintype.ofEquiv { x // x ∈ nthRoots k (1 : R) } <| (rootsOfUnityEquivNthRoots R k).symm
 #align roots_of_unity.fintype rootsOfUnity.fintype
+-/
 
+#print rootsOfUnity.isCyclic /-
 instance rootsOfUnity.isCyclic : IsCyclic (rootsOfUnity k R) :=
   isCyclic_of_subgroup_isDomain ((Units.coeHom R).comp (rootsOfUnity k R).Subtype)
     (Units.ext.comp Subtype.val_injective)
 #align roots_of_unity.is_cyclic rootsOfUnity.isCyclic
+-/
 
+#print card_rootsOfUnity /-
 theorem card_rootsOfUnity : Fintype.card (rootsOfUnity k R) ≤ k :=
   calc
     Fintype.card (rootsOfUnity k R) = Fintype.card { x // x ∈ nthRoots k (1 : R) } :=
@@ -258,9 +299,11 @@ theorem card_rootsOfUnity : Fintype.card (rootsOfUnity k R) ≤ k :=
     _ = (nthRoots k (1 : R)).card := Multiset.card_attach
     _ ≤ k := card_nthRoots k 1
 #align card_roots_of_unity card_rootsOfUnity
+-/
 
 variable {k R}
 
+#print map_rootsOfUnity_eq_pow_self /-
 theorem map_rootsOfUnity_eq_pow_self [RingHomClass F R R] (σ : F) (ζ : rootsOfUnity k R) :
     ∃ m : ℕ, σ ζ = ζ ^ m :=
   by
@@ -271,6 +314,7 @@ theorem map_rootsOfUnity_eq_pow_self [RingHomClass F R R] (σ : F) (ζ : rootsOf
     zpow_ofNat, rootsOfUnity.coe_pow]
   exact ⟨(m % orderOf ζ).toNat, rfl⟩
 #align map_root_of_unity_eq_pow_self map_rootsOfUnity_eq_pow_self
+-/
 
 end IsDomain
 
@@ -278,11 +322,13 @@ section Reduced
 
 variable (R) [CommRing R] [IsReduced R]
 
+#print mem_rootsOfUnity_prime_pow_mul_iff /-
 @[simp]
 theorem mem_rootsOfUnity_prime_pow_mul_iff (p k : ℕ) (m : ℕ+) [hp : Fact p.Prime] [CharP R p]
     {ζ : Rˣ} : ζ ∈ rootsOfUnity (⟨p, hp.1.Pos⟩ ^ k * m) R ↔ ζ ∈ rootsOfUnity m R := by
   simp [mem_rootsOfUnity']
 #align mem_roots_of_unity_prime_pow_mul_iff mem_rootsOfUnity_prime_pow_mul_iff
+-/
 
 end Reduced
 
@@ -297,11 +343,13 @@ structure IsPrimitiveRoot (ζ : M) (k : ℕ) : Prop where
 #align is_primitive_root IsPrimitiveRoot
 -/
 
+#print IsPrimitiveRoot.toRootsOfUnity /-
 /-- Turn a primitive root μ into a member of the `roots_of_unity` subgroup. -/
 @[simps]
 def IsPrimitiveRoot.toRootsOfUnity {μ : M} {n : ℕ+} (h : IsPrimitiveRoot μ n) : rootsOfUnity n M :=
   rootsOfUnity.mkOfPowEq μ h.pow_eq_one
 #align is_primitive_root.to_roots_of_unity IsPrimitiveRoot.toRootsOfUnity
+-/
 
 section primitiveRoots
 
@@ -347,10 +395,13 @@ namespace IsPrimitiveRoot
 
 variable {k l : ℕ}
 
+#print IsPrimitiveRoot.iff_def /-
 theorem iff_def (ζ : M) (k : ℕ) : IsPrimitiveRoot ζ k ↔ ζ ^ k = 1 ∧ ∀ l : ℕ, ζ ^ l = 1 → k ∣ l :=
   ⟨fun ⟨h1, h2⟩ => ⟨h1, h2⟩, fun ⟨h1, h2⟩ => ⟨h1, h2⟩⟩
 #align is_primitive_root.iff_def IsPrimitiveRoot.iff_def
+-/
 
+#print IsPrimitiveRoot.mk_of_lt /-
 theorem mk_of_lt (ζ : M) (hk : 0 < k) (h1 : ζ ^ k = 1) (h : ∀ l : ℕ, 0 < l → l < k → ζ ^ l ≠ 1) :
     IsPrimitiveRoot ζ k := by
   refine' ⟨h1, fun l hl => _⟩
@@ -360,6 +411,7 @@ theorem mk_of_lt (ζ : M) (hk : 0 < k) (h1 : ζ ^ k = 1) (h : ∀ l : ℕ, 0 < l
   intro h'; apply h _ (Nat.gcd_pos_of_pos_left _ hk) h'
   exact pow_gcd_eq_one _ h1 hl
 #align is_primitive_root.mk_of_lt IsPrimitiveRoot.mk_of_lt
+-/
 
 section CommMonoid
 
@@ -372,10 +424,12 @@ theorem of_subsingleton [Subsingleton M] (x : M) : IsPrimitiveRoot x 1 :=
 #align is_primitive_root.of_subsingleton IsPrimitiveRoot.of_subsingleton
 -/
 
+#print IsPrimitiveRoot.pow_eq_one_iff_dvd /-
 theorem pow_eq_one_iff_dvd (l : ℕ) : ζ ^ l = 1 ↔ k ∣ l :=
   ⟨h.dvd_of_pow_eq_one l, by rintro ⟨i, rfl⟩;
     simp only [pow_mul, h.pow_eq_one, one_pow, PNat.mul_coe]⟩
 #align is_primitive_root.pow_eq_one_iff_dvd IsPrimitiveRoot.pow_eq_one_iff_dvd
+-/
 
 #print IsPrimitiveRoot.isUnit /-
 theorem isUnit (h : IsPrimitiveRoot ζ k) (h0 : 0 < k) : IsUnit ζ :=
@@ -385,13 +439,17 @@ theorem isUnit (h : IsPrimitiveRoot ζ k) (h0 : 0 < k) : IsUnit ζ :=
 #align is_primitive_root.is_unit IsPrimitiveRoot.isUnit
 -/
 
+#print IsPrimitiveRoot.pow_ne_one_of_pos_of_lt /-
 theorem pow_ne_one_of_pos_of_lt (h0 : 0 < l) (hl : l < k) : ζ ^ l ≠ 1 :=
   mt (Nat.le_of_dvd h0 ∘ h.dvd_of_pow_eq_one _) <| not_le_of_lt hl
 #align is_primitive_root.pow_ne_one_of_pos_of_lt IsPrimitiveRoot.pow_ne_one_of_pos_of_lt
+-/
 
+#print IsPrimitiveRoot.ne_one /-
 theorem ne_one (hk : 1 < k) : ζ ≠ 1 :=
   h.pow_ne_one_of_pos_of_lt zero_lt_one hk ∘ (pow_one ζ).trans
 #align is_primitive_root.ne_one IsPrimitiveRoot.ne_one
+-/
 
 #print IsPrimitiveRoot.pow_inj /-
 theorem pow_inj (h : IsPrimitiveRoot ζ k) ⦃i j : ℕ⦄ (hi : i < k) (hj : j < k) (H : ζ ^ i = ζ ^ j) :
@@ -407,11 +465,14 @@ theorem pow_inj (h : IsPrimitiveRoot ζ k) ⦃i j : ℕ⦄ (hi : i < k) (hj : j
 #align is_primitive_root.pow_inj IsPrimitiveRoot.pow_inj
 -/
 
+#print IsPrimitiveRoot.one /-
 theorem one : IsPrimitiveRoot (1 : M) 1 :=
   { pow_eq_one := pow_one _
     dvd_of_pow_eq_one := fun l hl => one_dvd _ }
 #align is_primitive_root.one IsPrimitiveRoot.one
+-/
 
+#print IsPrimitiveRoot.one_right_iff /-
 @[simp]
 theorem one_right_iff : IsPrimitiveRoot ζ 1 ↔ ζ = 1 :=
   by
@@ -419,12 +480,15 @@ theorem one_right_iff : IsPrimitiveRoot ζ 1 ↔ ζ = 1 :=
   · intro h; rw [← pow_one ζ, h.pow_eq_one]
   · rintro rfl; exact one
 #align is_primitive_root.one_right_iff IsPrimitiveRoot.one_right_iff
+-/
 
+#print IsPrimitiveRoot.coe_submonoidClass_iff /-
 @[simp]
 theorem coe_submonoidClass_iff {M B : Type _} [CommMonoid M] [SetLike B M] [SubmonoidClass B M]
     {N : B} {ζ : N} : IsPrimitiveRoot (ζ : M) k ↔ IsPrimitiveRoot ζ k := by
   simp [iff_def, ← SubmonoidClass.coe_pow]
 #align is_primitive_root.coe_submonoid_class_iff IsPrimitiveRoot.coe_submonoidClass_iff
+-/
 
 #print IsPrimitiveRoot.coe_units_iff /-
 @[simp]
@@ -494,6 +558,7 @@ theorem eq_orderOf : k = orderOf ζ :=
 #align is_primitive_root.eq_order_of IsPrimitiveRoot.eq_orderOf
 -/
 
+#print IsPrimitiveRoot.iff /-
 protected theorem iff (hk : 0 < k) :
     IsPrimitiveRoot ζ k ↔ ζ ^ k = 1 ∧ ∀ l : ℕ, 0 < l → l < k → ζ ^ l ≠ 1 :=
   by
@@ -503,6 +568,7 @@ protected theorem iff (hk : 0 < k) :
   rw [h.eq_order_of] at hl 
   exact pow_ne_one_of_lt_orderOf' hl'.ne' hl
 #align is_primitive_root.iff IsPrimitiveRoot.iff
+-/
 
 #print IsPrimitiveRoot.not_iff /-
 protected theorem not_iff : ¬IsPrimitiveRoot ζ k ↔ orderOf ζ ≠ k :=
@@ -520,10 +586,12 @@ theorem pow_of_dvd (h : IsPrimitiveRoot ζ k) {p : ℕ} (hp : p ≠ 0) (hdiv : p
 #align is_primitive_root.pow_of_dvd IsPrimitiveRoot.pow_of_dvd
 -/
 
+#print IsPrimitiveRoot.mem_rootsOfUnity /-
 protected theorem mem_rootsOfUnity {ζ : Mˣ} {n : ℕ+} (h : IsPrimitiveRoot ζ n) :
     ζ ∈ rootsOfUnity n M :=
   h.pow_eq_one
 #align is_primitive_root.mem_roots_of_unity IsPrimitiveRoot.mem_rootsOfUnity
+-/
 
 #print IsPrimitiveRoot.pow /-
 /-- If there is a `n`-th primitive root of unity in `R` and `b` divides `n`,
@@ -543,6 +611,7 @@ section Maps
 
 open Function
 
+#print IsPrimitiveRoot.map_of_injective /-
 theorem map_of_injective [MonoidHomClass F M N] (h : IsPrimitiveRoot ζ k) (hf : Injective f) :
     IsPrimitiveRoot (f ζ) k :=
   { pow_eq_one := by rw [← map_pow, h.pow_eq_one, _root_.map_one]
@@ -552,7 +621,9 @@ theorem map_of_injective [MonoidHomClass F M N] (h : IsPrimitiveRoot ζ k) (hf :
       rw [← map_pow, ← map_one f] at hl 
       exact orderOf_dvd_of_pow_eq_one (hf hl) }
 #align is_primitive_root.map_of_injective IsPrimitiveRoot.map_of_injective
+-/
 
+#print IsPrimitiveRoot.of_map_of_injective /-
 theorem of_map_of_injective [MonoidHomClass F M N] (h : IsPrimitiveRoot (f ζ) k)
     (hf : Injective f) : IsPrimitiveRoot ζ k :=
   { pow_eq_one := by apply_fun f; rw [map_pow, _root_.map_one, h.pow_eq_one]
@@ -563,11 +634,14 @@ theorem of_map_of_injective [MonoidHomClass F M N] (h : IsPrimitiveRoot (f ζ) k
       rw [map_pow, _root_.map_one] at hl 
       exact orderOf_dvd_of_pow_eq_one hl }
 #align is_primitive_root.of_map_of_injective IsPrimitiveRoot.of_map_of_injective
+-/
 
+#print IsPrimitiveRoot.map_iff_of_injective /-
 theorem map_iff_of_injective [MonoidHomClass F M N] (hf : Injective f) :
     IsPrimitiveRoot (f ζ) k ↔ IsPrimitiveRoot ζ k :=
   ⟨fun h => h.of_map_of_injective hf, fun h => h.map_of_injective hf⟩
 #align is_primitive_root.map_iff_of_injective IsPrimitiveRoot.map_iff_of_injective
+-/
 
 end Maps
 
@@ -577,14 +651,18 @@ section CommMonoidWithZero
 
 variable {M₀ : Type _} [CommMonoidWithZero M₀]
 
+#print IsPrimitiveRoot.zero /-
 theorem zero [Nontrivial M₀] : IsPrimitiveRoot (0 : M₀) 0 :=
   ⟨pow_zero 0, fun l hl => by
     simpa [zero_pow_eq, show ∀ p, ¬p → False ↔ p from @Classical.not_not] using hl⟩
 #align is_primitive_root.zero IsPrimitiveRoot.zero
+-/
 
+#print IsPrimitiveRoot.ne_zero /-
 protected theorem ne_zero [Nontrivial M₀] {ζ : M₀} (h : IsPrimitiveRoot ζ k) : k ≠ 0 → ζ ≠ 0 :=
   mt fun hn => h.unique (hn.symm ▸ IsPrimitiveRoot.zero)
 #align is_primitive_root.ne_zero IsPrimitiveRoot.ne_zero
+-/
 
 end CommMonoidWithZero
 
@@ -592,10 +670,13 @@ section DivisionCommMonoid
 
 variable {ζ : G}
 
+#print IsPrimitiveRoot.zpow_eq_one /-
 theorem zpow_eq_one (h : IsPrimitiveRoot ζ k) : ζ ^ (k : ℤ) = 1 := by rw [zpow_ofNat];
   exact h.pow_eq_one
 #align is_primitive_root.zpow_eq_one IsPrimitiveRoot.zpow_eq_one
+-/
 
+#print IsPrimitiveRoot.zpow_eq_one_iff_dvd /-
 theorem zpow_eq_one_iff_dvd (h : IsPrimitiveRoot ζ k) (l : ℤ) : ζ ^ l = 1 ↔ (k : ℤ) ∣ l :=
   by
   by_cases h0 : 0 ≤ l
@@ -606,7 +687,9 @@ theorem zpow_eq_one_iff_dvd (h : IsPrimitiveRoot ζ k) (l : ℤ) : ζ ^ l = 1 
     norm_cast
     rw [← h.pow_eq_one_iff_dvd, ← inv_inj, ← zpow_neg, ← hl', zpow_ofNat, inv_one]
 #align is_primitive_root.zpow_eq_one_iff_dvd IsPrimitiveRoot.zpow_eq_one_iff_dvd
+-/
 
+#print IsPrimitiveRoot.inv /-
 theorem inv (h : IsPrimitiveRoot ζ k) : IsPrimitiveRoot ζ⁻¹ k :=
   { pow_eq_one := by simp only [h.pow_eq_one, inv_one, eq_self_iff_true, inv_pow]
     dvd_of_pow_eq_one := by
@@ -614,11 +697,14 @@ theorem inv (h : IsPrimitiveRoot ζ k) : IsPrimitiveRoot ζ⁻¹ k :=
       apply h.dvd_of_pow_eq_one l
       rw [← inv_inj, ← inv_pow, hl, inv_one] }
 #align is_primitive_root.inv IsPrimitiveRoot.inv
+-/
 
+#print IsPrimitiveRoot.inv_iff /-
 @[simp]
 theorem inv_iff : IsPrimitiveRoot ζ⁻¹ k ↔ IsPrimitiveRoot ζ k := by refine' ⟨_, fun h => inv h⟩;
   intro h; rw [← inv_inv ζ]; exact inv h
 #align is_primitive_root.inv_iff IsPrimitiveRoot.inv_iff
+-/
 
 #print IsPrimitiveRoot.zpow_of_gcd_eq_one /-
 theorem zpow_of_gcd_eq_one (h : IsPrimitiveRoot ζ k) (i : ℤ) (hi : i.gcd k = 1) :
@@ -644,6 +730,7 @@ variable {ζ : R}
 
 variable [CommRing R] [IsDomain R]
 
+#print IsPrimitiveRoot.primitiveRoots_one /-
 @[simp]
 theorem primitiveRoots_one : primitiveRoots 1 R = {(1 : R)} :=
   by
@@ -654,7 +741,9 @@ theorem primitiveRoots_one : primitiveRoots 1 R = {(1 : R)} :=
     rw [mem_primitiveRoots zero_lt_one, IsPrimitiveRoot.one_right_iff] at hx 
     exact hx
 #align is_primitive_root.primitive_roots_one IsPrimitiveRoot.primitiveRoots_one
+-/
 
+#print IsPrimitiveRoot.ne_zero' /-
 theorem ne_zero' {n : ℕ+} (hζ : IsPrimitiveRoot ζ n) : NeZero ((n : ℕ) : R) :=
   by
   let p := ringChar R
@@ -678,6 +767,7 @@ theorem ne_zero' {n : ℕ+} (hζ : IsPrimitiveRoot ζ n) : NeZero ((n : ℕ) : R
       exact lt_mul_of_one_lt_right hpos hpri.1.one_lt
   · exact NeZero.of_not_dvd R hp
 #align is_primitive_root.ne_zero' IsPrimitiveRoot.ne_zero'
+-/
 
 #print IsPrimitiveRoot.mem_nthRootsFinset /-
 theorem mem_nthRootsFinset (hζ : IsPrimitiveRoot ζ k) (hk : 0 < k) : ζ ∈ nthRootsFinset k R :=
@@ -693,20 +783,25 @@ variable [CommRing R]
 
 variable {ζ : Rˣ} (h : IsPrimitiveRoot ζ k)
 
+#print IsPrimitiveRoot.eq_neg_one_of_two_right /-
 theorem eq_neg_one_of_two_right [NoZeroDivisors R] {ζ : R} (h : IsPrimitiveRoot ζ 2) : ζ = -1 :=
   by
   apply (eq_or_eq_neg_of_sq_eq_sq ζ 1 _).resolve_left
   · rw [← pow_one ζ]; apply h.pow_ne_one_of_pos_of_lt <;> decide
   · simp only [h.pow_eq_one, one_pow]
 #align is_primitive_root.eq_neg_one_of_two_right IsPrimitiveRoot.eq_neg_one_of_two_right
+-/
 
+#print IsPrimitiveRoot.neg_one /-
 theorem neg_one (p : ℕ) [Nontrivial R] [h : CharP R p] (hp : p ≠ 2) : IsPrimitiveRoot (-1 : R) 2 :=
   by
   convert IsPrimitiveRoot.orderOf (-1 : R)
   rw [orderOf_neg_one, if_neg]
   rwa [ring_char.eq_iff.mpr h]
 #align is_primitive_root.neg_one IsPrimitiveRoot.neg_one
+-/
 
+#print IsPrimitiveRoot.geom_sum_eq_zero /-
 /-- If `1 < k` then `(∑ i in range k, ζ ^ i) = 0`. -/
 theorem geom_sum_eq_zero [IsDomain R] {ζ : R} (hζ : IsPrimitiveRoot ζ k) (hk : 1 < k) :
     ∑ i in range k, ζ ^ i = 0 :=
@@ -714,14 +809,18 @@ theorem geom_sum_eq_zero [IsDomain R] {ζ : R} (hζ : IsPrimitiveRoot ζ k) (hk
   refine' eq_zero_of_ne_zero_of_mul_left_eq_zero (sub_ne_zero_of_ne (hζ.ne_one hk).symm) _
   rw [mul_neg_geom_sum, hζ.pow_eq_one, sub_self]
 #align is_primitive_root.geom_sum_eq_zero IsPrimitiveRoot.geom_sum_eq_zero
+-/
 
+#print IsPrimitiveRoot.pow_sub_one_eq /-
 /-- If `1 < k`, then `ζ ^ k.pred = -(∑ i in range k.pred, ζ ^ i)`. -/
 theorem pow_sub_one_eq [IsDomain R] {ζ : R} (hζ : IsPrimitiveRoot ζ k) (hk : 1 < k) :
     ζ ^ k.pred = -∑ i in range k.pred, ζ ^ i := by
   rw [eq_neg_iff_add_eq_zero, add_comm, ← sum_range_succ, ← Nat.succ_eq_add_one,
     Nat.succ_pred_eq_of_pos (pos_of_gt hk), hζ.geom_sum_eq_zero hk]
 #align is_primitive_root.pow_sub_one_eq IsPrimitiveRoot.pow_sub_one_eq
+-/
 
+#print IsPrimitiveRoot.zmodEquivZpowers /-
 /-- The (additive) monoid equivalence between `zmod k`
 and the powers of a primitive root of unity `ζ`. -/
 def zmodEquivZpowers (h : IsPrimitiveRoot ζ k) : ZMod k ≃+ Additive (Subgroup.zpowers ζ) :=
@@ -749,13 +848,17 @@ def zmodEquivZpowers (h : IsPrimitiveRoot ζ k) : ZMod k ≃+ Additive (Subgroup
         rw [AddMonoidHom.liftOfRightInverse_comp_apply]
         rfl)
 #align is_primitive_root.zmod_equiv_zpowers IsPrimitiveRoot.zmodEquivZpowers
+-/
 
+#print IsPrimitiveRoot.zmodEquivZpowers_apply_coe_int /-
 @[simp]
 theorem zmodEquivZpowers_apply_coe_int (i : ℤ) :
     h.zmodEquivZpowers i = Additive.ofMul (⟨ζ ^ i, i, rfl⟩ : Subgroup.zpowers ζ) :=
   AddMonoidHom.liftOfRightInverse_comp_apply _ _ ZMod.int_cast_rightInverse _ _
 #align is_primitive_root.zmod_equiv_zpowers_apply_coe_int IsPrimitiveRoot.zmodEquivZpowers_apply_coe_int
+-/
 
+#print IsPrimitiveRoot.zmodEquivZpowers_apply_coe_nat /-
 @[simp]
 theorem zmodEquivZpowers_apply_coe_nat (i : ℕ) :
     h.zmodEquivZpowers i = Additive.ofMul (⟨ζ ^ i, i, rfl⟩ : Subgroup.zpowers ζ) :=
@@ -764,31 +867,41 @@ theorem zmodEquivZpowers_apply_coe_nat (i : ℕ) :
   simp only [this, zmod_equiv_zpowers_apply_coe_int, zpow_ofNat]
   rfl
 #align is_primitive_root.zmod_equiv_zpowers_apply_coe_nat IsPrimitiveRoot.zmodEquivZpowers_apply_coe_nat
+-/
 
+#print IsPrimitiveRoot.zmodEquivZpowers_symm_apply_zpow /-
 @[simp]
 theorem zmodEquivZpowers_symm_apply_zpow (i : ℤ) :
     h.zmodEquivZpowers.symm (Additive.ofMul (⟨ζ ^ i, i, rfl⟩ : Subgroup.zpowers ζ)) = i := by
   rw [← h.zmod_equiv_zpowers.symm_apply_apply i, zmod_equiv_zpowers_apply_coe_int]
 #align is_primitive_root.zmod_equiv_zpowers_symm_apply_zpow IsPrimitiveRoot.zmodEquivZpowers_symm_apply_zpow
+-/
 
+#print IsPrimitiveRoot.zmodEquivZpowers_symm_apply_zpow' /-
 @[simp]
 theorem zmodEquivZpowers_symm_apply_zpow' (i : ℤ) : h.zmodEquivZpowers.symm ⟨ζ ^ i, i, rfl⟩ = i :=
   h.zmodEquivZpowers_symm_apply_zpow i
 #align is_primitive_root.zmod_equiv_zpowers_symm_apply_zpow' IsPrimitiveRoot.zmodEquivZpowers_symm_apply_zpow'
+-/
 
+#print IsPrimitiveRoot.zmodEquivZpowers_symm_apply_pow /-
 @[simp]
 theorem zmodEquivZpowers_symm_apply_pow (i : ℕ) :
     h.zmodEquivZpowers.symm (Additive.ofMul (⟨ζ ^ i, i, rfl⟩ : Subgroup.zpowers ζ)) = i := by
   rw [← h.zmod_equiv_zpowers.symm_apply_apply i, zmod_equiv_zpowers_apply_coe_nat]
 #align is_primitive_root.zmod_equiv_zpowers_symm_apply_pow IsPrimitiveRoot.zmodEquivZpowers_symm_apply_pow
+-/
 
+#print IsPrimitiveRoot.zmodEquivZpowers_symm_apply_pow' /-
 @[simp]
 theorem zmodEquivZpowers_symm_apply_pow' (i : ℕ) : h.zmodEquivZpowers.symm ⟨ζ ^ i, i, rfl⟩ = i :=
   h.zmodEquivZpowers_symm_apply_pow i
 #align is_primitive_root.zmod_equiv_zpowers_symm_apply_pow' IsPrimitiveRoot.zmodEquivZpowers_symm_apply_pow'
+-/
 
 variable [IsDomain R]
 
+#print IsPrimitiveRoot.zpowers_eq /-
 theorem zpowers_eq {k : ℕ+} {ζ : Rˣ} (h : IsPrimitiveRoot ζ k) :
     Subgroup.zpowers ζ = rootsOfUnity k R :=
   by
@@ -803,7 +916,9 @@ theorem zpowers_eq {k : ℕ+} {ζ : Rˣ} (h : IsPrimitiveRoot ζ k) :
     _ = Fintype.card (ZMod k) := (ZMod.card k).symm
     _ = Fintype.card (Subgroup.zpowers ζ) := Fintype.card_congr h.zmod_equiv_zpowers.toEquiv
 #align is_primitive_root.zpowers_eq IsPrimitiveRoot.zpowers_eq
+-/
 
+#print IsPrimitiveRoot.eq_pow_of_mem_rootsOfUnity /-
 theorem eq_pow_of_mem_rootsOfUnity {k : ℕ+} {ζ ξ : Rˣ} (h : IsPrimitiveRoot ζ k)
     (hξ : ξ ∈ rootsOfUnity k R) : ∃ (i : ℕ) (hi : i < k), ζ ^ i = ξ :=
   by
@@ -817,7 +932,9 @@ theorem eq_pow_of_mem_rootsOfUnity {k : ℕ+} {ζ ξ : Rˣ} (h : IsPrimitiveRoot
   · have aux := h.zpow_eq_one; rw [← coe_coe] at aux 
     rw [← zpow_ofNat, hi₀, ← Int.emod_add_ediv n k, zpow_add, zpow_mul, aux, one_zpow, mul_one]
 #align is_primitive_root.eq_pow_of_mem_roots_of_unity IsPrimitiveRoot.eq_pow_of_mem_rootsOfUnity
+-/
 
+#print IsPrimitiveRoot.eq_pow_of_pow_eq_one /-
 theorem eq_pow_of_pow_eq_one {k : ℕ} {ζ ξ : R} (h : IsPrimitiveRoot ζ k) (hξ : ξ ^ k = 1)
     (h0 : 0 < k) : ∃ i < k, ζ ^ i = ξ :=
   by
@@ -829,7 +946,9 @@ theorem eq_pow_of_pow_eq_one {k : ℕ} {ζ ξ : R} (h : IsPrimitiveRoot ζ k) (h
   apply h.eq_pow_of_mem_roots_of_unity
   rw [mem_rootsOfUnity, Units.ext_iff, Units.val_pow_eq_pow_val, hξ, Units.val_one]
 #align is_primitive_root.eq_pow_of_pow_eq_one IsPrimitiveRoot.eq_pow_of_pow_eq_one
+-/
 
+#print IsPrimitiveRoot.isPrimitiveRoot_iff' /-
 theorem isPrimitiveRoot_iff' {k : ℕ+} {ζ ξ : Rˣ} (h : IsPrimitiveRoot ζ k) :
     IsPrimitiveRoot ξ k ↔ ∃ i < (k : ℕ), ∃ hi : i.coprime k, ζ ^ i = ξ :=
   by
@@ -840,7 +959,9 @@ theorem isPrimitiveRoot_iff' {k : ℕ+} {ζ ξ : Rˣ} (h : IsPrimitiveRoot ζ k)
     exact ⟨i, hik, hξ, rfl⟩
   · rintro ⟨i, -, hi, rfl⟩; exact h.pow_of_coprime i hi
 #align is_primitive_root.is_primitive_root_iff' IsPrimitiveRoot.isPrimitiveRoot_iff'
+-/
 
+#print IsPrimitiveRoot.isPrimitiveRoot_iff /-
 theorem isPrimitiveRoot_iff {k : ℕ} {ζ ξ : R} (h : IsPrimitiveRoot ζ k) (h0 : 0 < k) :
     IsPrimitiveRoot ξ k ↔ ∃ i < k, ∃ hi : i.coprime k, ζ ^ i = ξ :=
   by
@@ -851,7 +972,9 @@ theorem isPrimitiveRoot_iff {k : ℕ} {ζ ξ : R} (h : IsPrimitiveRoot ζ k) (h0
     exact ⟨i, hik, hξ, rfl⟩
   · rintro ⟨i, -, hi, rfl⟩; exact h.pow_of_coprime i hi
 #align is_primitive_root.is_primitive_root_iff IsPrimitiveRoot.isPrimitiveRoot_iff
+-/
 
+#print IsPrimitiveRoot.card_rootsOfUnity' /-
 theorem card_rootsOfUnity' {n : ℕ+} (h : IsPrimitiveRoot ζ n) :
     Fintype.card (rootsOfUnity n R) = n :=
   by
@@ -863,7 +986,9 @@ theorem card_rootsOfUnity' {n : ℕ+} (h : IsPrimitiveRoot ζ n) :
     _ = Fintype.card (ZMod n) := (Fintype.card_congr e.to_equiv.symm)
     _ = n := ZMod.card n
 #align is_primitive_root.card_roots_of_unity' IsPrimitiveRoot.card_rootsOfUnity'
+-/
 
+#print IsPrimitiveRoot.card_rootsOfUnity /-
 theorem card_rootsOfUnity {ζ : R} {n : ℕ+} (h : IsPrimitiveRoot ζ n) :
     Fintype.card (rootsOfUnity n R) = n :=
   by
@@ -871,7 +996,9 @@ theorem card_rootsOfUnity {ζ : R} {n : ℕ+} (h : IsPrimitiveRoot ζ n) :
   rw [← hζ, IsPrimitiveRoot.coe_units_iff] at h 
   exact h.card_roots_of_unity'
 #align is_primitive_root.card_roots_of_unity IsPrimitiveRoot.card_rootsOfUnity
+-/
 
+#print IsPrimitiveRoot.card_nthRoots /-
 /-- The cardinality of the multiset `nth_roots ↑n (1 : R)` is `n`
 if there is a primitive root of unity in `R`. -/
 theorem card_nthRoots {ζ : R} {n : ℕ} (h : IsPrimitiveRoot ζ n) : (nthRoots n (1 : R)).card = n :=
@@ -890,7 +1017,9 @@ theorem card_nthRoots {ζ : R} {n : ℕ} (h : IsPrimitiveRoot ζ n) : (nthRoots
     rw [← Fintype.card_congr (rootsOfUnityEquivNthRoots R m), card_rootsOfUnity h] at hcard 
     exact hcard
 #align is_primitive_root.card_nth_roots IsPrimitiveRoot.card_nthRoots
+-/
 
+#print IsPrimitiveRoot.nthRoots_nodup /-
 /-- The multiset `nth_roots ↑n (1 : R)` has no repeated elements
 if there is a primitive root of unity in `R`. -/
 theorem nthRoots_nodup {ζ : R} {n : ℕ} (h : IsPrimitiveRoot ζ n) : (nthRoots n (1 : R)).Nodup :=
@@ -915,6 +1044,7 @@ theorem nthRoots_nodup {ζ : R} {n : ℕ} (h : IsPrimitiveRoot ζ n) : (nthRoots
     rw [hrw, ← Fintype.card_congr (rootsOfUnityEquivNthRoots R m), card_rootsOfUnity h] at ha 
     exact Nat.lt_asymm ha ha
 #align is_primitive_root.nth_roots_nodup IsPrimitiveRoot.nthRoots_nodup
+-/
 
 #print IsPrimitiveRoot.card_nthRootsFinset /-
 @[simp]
@@ -950,12 +1080,14 @@ theorem card_primitiveRoots {ζ : R} {k : ℕ} (h : IsPrimitiveRoot ζ k) :
 #align is_primitive_root.card_primitive_roots IsPrimitiveRoot.card_primitiveRoots
 -/
 
+#print IsPrimitiveRoot.disjoint /-
 /-- The sets `primitive_roots k R` are pairwise disjoint. -/
 theorem disjoint {k l : ℕ} (h : k ≠ l) : Disjoint (primitiveRoots k R) (primitiveRoots l R) :=
   Finset.disjoint_left.2 fun z hk hl =>
     h <|
       (isPrimitiveRoot_of_mem_primitiveRoots hk).unique <| isPrimitiveRoot_of_mem_primitiveRoots hl
 #align is_primitive_root.disjoint IsPrimitiveRoot.disjoint
+-/
 
 #print IsPrimitiveRoot.nthRoots_one_eq_biUnion_primitiveRoots' /-
 /-- `nth_roots n` as a `finset` is equal to the union of `primitive_roots i R` for `i ∣ n`
@@ -1010,6 +1142,7 @@ variable {S} [CommRing S] [IsDomain S] {μ : S} {n : ℕ+} (hμ : IsPrimitiveRoo
   [Algebra R S]
 
 /- ./././Mathport/Syntax/Translate/Tactic/Lean3.lean:132:4: warning: unsupported: rw with cfg: { occs := occurrences.pos[occurrences.pos] «expr[ ,]»([1]) } -/
+#print IsPrimitiveRoot.autToPow /-
 /-- The `monoid_hom` that takes an automorphism to the power of μ that μ gets mapped to under it. -/
 noncomputable def autToPow : (S ≃ₐ[R] S) →* (ZMod n)ˣ :=
   let μ' := hμ.toRootsOfUnity
@@ -1042,14 +1175,18 @@ noncomputable def autToPow : (S ≃ₐ[R] S) →* (ZMod n)ˣ :=
           rootsOfUnity.coe_injective (by simpa only [rootsOfUnity.coe_pow] using hxy)
         rw [← Nat.cast_mul, ZMod.nat_cast_eq_nat_cast_iff, ← ho, ← pow_eq_pow_iff_modEq μ', hxy] }
 #align is_primitive_root.aut_to_pow IsPrimitiveRoot.autToPow
+-/
 
+#print IsPrimitiveRoot.coe_autToPow_apply /-
 -- We are not using @[simps] in aut_to_pow to avoid a timeout.
 theorem coe_autToPow_apply (f : S ≃ₐ[R] S) :
     (autToPow R hμ f : ZMod n) =
       ((map_rootsOfUnity_eq_pow_self f hμ.toRootsOfUnity).some : ZMod n) :=
   rfl
 #align is_primitive_root.coe_aut_to_pow_apply IsPrimitiveRoot.coe_autToPow_apply
+-/
 
+#print IsPrimitiveRoot.autToPow_spec /-
 @[simp]
 theorem autToPow_spec (f : S ≃ₐ[R] S) : μ ^ (hμ.autToPow R f : ZMod n).val = f μ :=
   by
@@ -1064,6 +1201,7 @@ theorem autToPow_spec (f : S ≃ₐ[R] S) : μ ^ (hμ.autToPow R f : ZMod n).val
     hμ.eq_order_of, ZMod.val_nat_cast]
   exact Nat.mod_modEq _ _
 #align is_primitive_root.aut_to_pow_spec IsPrimitiveRoot.autToPow_spec
+-/
 
 end Automorphisms
 
Diff
@@ -709,7 +709,7 @@ theorem neg_one (p : ℕ) [Nontrivial R] [h : CharP R p] (hp : p ≠ 2) : IsPrim
 
 /-- If `1 < k` then `(∑ i in range k, ζ ^ i) = 0`. -/
 theorem geom_sum_eq_zero [IsDomain R] {ζ : R} (hζ : IsPrimitiveRoot ζ k) (hk : 1 < k) :
-    (∑ i in range k, ζ ^ i) = 0 :=
+    ∑ i in range k, ζ ^ i = 0 :=
   by
   refine' eq_zero_of_ne_zero_of_mul_left_eq_zero (sub_ne_zero_of_ne (hζ.ne_one hk).symm) _
   rw [mul_neg_geom_sum, hζ.pow_eq_one, sub_self]
Diff
@@ -257,7 +257,6 @@ theorem card_rootsOfUnity : Fintype.card (rootsOfUnity k R) ≤ k :=
     _ ≤ (nthRoots k (1 : R)).attach.card := (Multiset.card_le_of_le (Multiset.dedup_le _))
     _ = (nthRoots k (1 : R)).card := Multiset.card_attach
     _ ≤ k := card_nthRoots k 1
-    
 #align card_roots_of_unity card_rootsOfUnity
 
 variable {k R}
@@ -803,7 +802,6 @@ theorem zpowers_eq {k : ℕ+} {ζ : Rˣ} (h : IsPrimitiveRoot ζ k) :
     Fintype.card (rootsOfUnity k R) ≤ k := card_rootsOfUnity R k
     _ = Fintype.card (ZMod k) := (ZMod.card k).symm
     _ = Fintype.card (Subgroup.zpowers ζ) := Fintype.card_congr h.zmod_equiv_zpowers.toEquiv
-    
 #align is_primitive_root.zpowers_eq IsPrimitiveRoot.zpowers_eq
 
 theorem eq_pow_of_mem_rootsOfUnity {k : ℕ+} {ζ ξ : Rˣ} (h : IsPrimitiveRoot ζ k)
@@ -864,7 +862,6 @@ theorem card_rootsOfUnity' {n : ℕ+} (h : IsPrimitiveRoot ζ n) :
       Fintype.card_congr <| by rw [h.zpowers_eq]
     _ = Fintype.card (ZMod n) := (Fintype.card_congr e.to_equiv.symm)
     _ = n := ZMod.card n
-    
 #align is_primitive_root.card_roots_of_unity' IsPrimitiveRoot.card_rootsOfUnity'
 
 theorem card_rootsOfUnity {ζ : R} {n : ℕ+} (h : IsPrimitiveRoot ζ n) :
Diff
@@ -4,7 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE.
 Authors: Johan Commelin
 
 ! This file was ported from Lean 3 source module ring_theory.roots_of_unity.basic
-! leanprover-community/mathlib commit 7fdeecc0d03cd40f7a165e6cf00a4d2286db599f
+! leanprover-community/mathlib commit 7e5137f579de09a059a5ce98f364a04e221aabf0
 ! Please do not edit these lines, except to modify the commit id
 ! if you have ported upstream changes.
 -/
@@ -22,6 +22,9 @@ import Mathbin.Tactic.Zify
 /-!
 # Roots of unity and primitive roots of unity
 
+> THIS FILE IS SYNCHRONIZED WITH MATHLIB4.
+> Any changes to this file require a corresponding PR to mathlib4.
+
 We define roots of unity in the context of an arbitrary commutative monoid,
 as a subgroup of the group of units. We also define a predicate `is_primitive_root` on commutative
 monoids, expressing that an element is a primitive root of unity.
Diff
@@ -97,9 +97,9 @@ theorem mem_rootsOfUnity (k : ℕ+) (ζ : Mˣ) : ζ ∈ rootsOfUnity k M ↔ ζ
   Iff.rfl
 #align mem_roots_of_unity mem_rootsOfUnity
 
-theorem mem_roots_of_unity' (k : ℕ+) (ζ : Mˣ) : ζ ∈ rootsOfUnity k M ↔ (ζ : M) ^ (k : ℕ) = 1 := by
+theorem mem_rootsOfUnity' (k : ℕ+) (ζ : Mˣ) : ζ ∈ rootsOfUnity k M ↔ (ζ : M) ^ (k : ℕ) = 1 := by
   rw [mem_rootsOfUnity]; norm_cast
-#align mem_roots_of_unity' mem_roots_of_unity'
+#align mem_roots_of_unity' mem_rootsOfUnity'
 
 theorem rootsOfUnity.coe_injective {n : ℕ+} : Function.Injective (coe : rootsOfUnity n M → M) :=
   Units.ext.comp fun x y => Subtype.ext
@@ -259,7 +259,7 @@ theorem card_rootsOfUnity : Fintype.card (rootsOfUnity k R) ≤ k :=
 
 variable {k R}
 
-theorem map_root_of_unity_eq_pow_self [RingHomClass F R R] (σ : F) (ζ : rootsOfUnity k R) :
+theorem map_rootsOfUnity_eq_pow_self [RingHomClass F R R] (σ : F) (ζ : rootsOfUnity k R) :
     ∃ m : ℕ, σ ζ = ζ ^ m :=
   by
   obtain ⟨m, hm⟩ := MonoidHom.map_cyclic (restrictRootsOfUnity σ k)
@@ -268,7 +268,7 @@ theorem map_root_of_unity_eq_pow_self [RingHomClass F R R] (σ : F) (ζ : rootsO
       (m.mod_nonneg (int.coe_nat_ne_zero.mpr (pos_iff_ne_zero.mp (orderOf_pos ζ)))),
     zpow_ofNat, rootsOfUnity.coe_pow]
   exact ⟨(m % orderOf ζ).toNat, rfl⟩
-#align map_root_of_unity_eq_pow_self map_root_of_unity_eq_pow_self
+#align map_root_of_unity_eq_pow_self map_rootsOfUnity_eq_pow_self
 
 end IsDomain
 
@@ -279,19 +279,21 @@ variable (R) [CommRing R] [IsReduced R]
 @[simp]
 theorem mem_rootsOfUnity_prime_pow_mul_iff (p k : ℕ) (m : ℕ+) [hp : Fact p.Prime] [CharP R p]
     {ζ : Rˣ} : ζ ∈ rootsOfUnity (⟨p, hp.1.Pos⟩ ^ k * m) R ↔ ζ ∈ rootsOfUnity m R := by
-  simp [mem_roots_of_unity']
+  simp [mem_rootsOfUnity']
 #align mem_roots_of_unity_prime_pow_mul_iff mem_rootsOfUnity_prime_pow_mul_iff
 
 end Reduced
 
 end rootsOfUnity
 
+#print IsPrimitiveRoot /-
 /-- An element `ζ` is a primitive `k`-th root of unity if `ζ ^ k = 1`,
 and if `l` satisfies `ζ ^ l = 1` then `k ∣ l`. -/
 structure IsPrimitiveRoot (ζ : M) (k : ℕ) : Prop where
   pow_eq_one : ζ ^ (k : ℕ) = 1
   dvd_of_pow_eq_one : ∀ l : ℕ, ζ ^ l = 1 → k ∣ l
 #align is_primitive_root IsPrimitiveRoot
+-/
 
 /-- Turn a primitive root μ into a member of the `roots_of_unity` subgroup. -/
 @[simps]
@@ -303,31 +305,39 @@ section primitiveRoots
 
 variable {k : ℕ}
 
+#print primitiveRoots /-
 /-- `primitive_roots k R` is the finset of primitive `k`-th roots of unity
 in the integral domain `R`. -/
 def primitiveRoots (k : ℕ) (R : Type _) [CommRing R] [IsDomain R] : Finset R :=
   (nthRoots k (1 : R)).toFinset.filterₓ fun ζ => IsPrimitiveRoot ζ k
 #align primitive_roots primitiveRoots
+-/
 
 variable [CommRing R] [IsDomain R]
 
+#print mem_primitiveRoots /-
 @[simp]
 theorem mem_primitiveRoots {ζ : R} (h0 : 0 < k) : ζ ∈ primitiveRoots k R ↔ IsPrimitiveRoot ζ k :=
   by
   rw [primitiveRoots, mem_filter, Multiset.mem_toFinset, mem_nth_roots h0, and_iff_right_iff_imp]
   exact IsPrimitiveRoot.pow_eq_one
 #align mem_primitive_roots mem_primitiveRoots
+-/
 
+#print primitiveRoots_zero /-
 @[simp]
 theorem primitiveRoots_zero : primitiveRoots 0 R = ∅ := by
   rw [primitiveRoots, nth_roots_zero, Multiset.toFinset_zero, Finset.filter_empty]
 #align primitive_roots_zero primitiveRoots_zero
+-/
 
+#print isPrimitiveRoot_of_mem_primitiveRoots /-
 theorem isPrimitiveRoot_of_mem_primitiveRoots {ζ : R} (h : ζ ∈ primitiveRoots k R) :
     IsPrimitiveRoot ζ k :=
   k.eq_zero_or_pos.elim (fun hk => False.elim <| by simpa [hk] using h) fun hk =>
     (mem_primitiveRoots hk).1 h
 #align is_primitive_root_of_mem_primitive_roots isPrimitiveRoot_of_mem_primitiveRoots
+-/
 
 end primitiveRoots
 
@@ -353,21 +363,25 @@ section CommMonoid
 
 variable {ζ : M} {f : F} (h : IsPrimitiveRoot ζ k)
 
+#print IsPrimitiveRoot.of_subsingleton /-
 @[nontriviality]
 theorem of_subsingleton [Subsingleton M] (x : M) : IsPrimitiveRoot x 1 :=
   ⟨Subsingleton.elim _ _, fun _ _ => one_dvd _⟩
 #align is_primitive_root.of_subsingleton IsPrimitiveRoot.of_subsingleton
+-/
 
 theorem pow_eq_one_iff_dvd (l : ℕ) : ζ ^ l = 1 ↔ k ∣ l :=
   ⟨h.dvd_of_pow_eq_one l, by rintro ⟨i, rfl⟩;
     simp only [pow_mul, h.pow_eq_one, one_pow, PNat.mul_coe]⟩
 #align is_primitive_root.pow_eq_one_iff_dvd IsPrimitiveRoot.pow_eq_one_iff_dvd
 
+#print IsPrimitiveRoot.isUnit /-
 theorem isUnit (h : IsPrimitiveRoot ζ k) (h0 : 0 < k) : IsUnit ζ :=
   by
   apply isUnit_of_mul_eq_one ζ (ζ ^ (k - 1))
   rw [← pow_succ, tsub_add_cancel_of_le h0.nat_succ_le, h.pow_eq_one]
 #align is_primitive_root.is_unit IsPrimitiveRoot.isUnit
+-/
 
 theorem pow_ne_one_of_pos_of_lt (h0 : 0 < l) (hl : l < k) : ζ ^ l ≠ 1 :=
   mt (Nat.le_of_dvd h0 ∘ h.dvd_of_pow_eq_one _) <| not_le_of_lt hl
@@ -377,6 +391,7 @@ theorem ne_one (hk : 1 < k) : ζ ≠ 1 :=
   h.pow_ne_one_of_pos_of_lt zero_lt_one hk ∘ (pow_one ζ).trans
 #align is_primitive_root.ne_one IsPrimitiveRoot.ne_one
 
+#print IsPrimitiveRoot.pow_inj /-
 theorem pow_inj (h : IsPrimitiveRoot ζ k) ⦃i j : ℕ⦄ (hi : i < k) (hj : j < k) (H : ζ ^ i = ζ ^ j) :
     i = j := by
   wlog hij : i ≤ j generalizing i j
@@ -388,6 +403,7 @@ theorem pow_inj (h : IsPrimitiveRoot ζ k) ⦃i j : ℕ⦄ (hi : i < k) (hj : j
   rw [← ((h.is_unit (lt_of_le_of_lt (Nat.zero_le _) hi)).pow i).mul_left_inj, ← pow_add,
     tsub_add_cancel_of_le hij, H, one_mul]
 #align is_primitive_root.pow_inj IsPrimitiveRoot.pow_inj
+-/
 
 theorem one : IsPrimitiveRoot (1 : M) 1 :=
   { pow_eq_one := pow_one _
@@ -408,11 +424,14 @@ theorem coe_submonoidClass_iff {M B : Type _} [CommMonoid M] [SetLike B M] [Subm
   simp [iff_def, ← SubmonoidClass.coe_pow]
 #align is_primitive_root.coe_submonoid_class_iff IsPrimitiveRoot.coe_submonoidClass_iff
 
+#print IsPrimitiveRoot.coe_units_iff /-
 @[simp]
 theorem coe_units_iff {ζ : Mˣ} : IsPrimitiveRoot (ζ : M) k ↔ IsPrimitiveRoot ζ k := by
   simp only [iff_def, Units.ext_iff, Units.val_pow_eq_pow_val, Units.val_one]
 #align is_primitive_root.coe_units_iff IsPrimitiveRoot.coe_units_iff
+-/
 
+#print IsPrimitiveRoot.pow_of_coprime /-
 theorem pow_of_coprime (h : IsPrimitiveRoot ζ k) (i : ℕ) (hi : i.coprime k) :
     IsPrimitiveRoot (ζ ^ i) k := by
   by_cases h0 : k = 0
@@ -429,13 +448,17 @@ theorem pow_of_coprime (h : IsPrimitiveRoot ζ k) (i : ℕ) (hi : i.coprime k) :
     zpow_ofNat, ← zpow_mul, mul_right_comm]
   simp only [zpow_mul, hl, h.pow_eq_one, one_zpow, one_pow, one_mul, zpow_ofNat]
 #align is_primitive_root.pow_of_coprime IsPrimitiveRoot.pow_of_coprime
+-/
 
+#print IsPrimitiveRoot.pow_of_prime /-
 theorem pow_of_prime (h : IsPrimitiveRoot ζ k) {p : ℕ} (hprime : Nat.Prime p) (hdiv : ¬p ∣ k) :
     IsPrimitiveRoot (ζ ^ p) k :=
   h.pow_of_coprime p (hprime.coprime_iff_not_dvd.2 hdiv)
 #align is_primitive_root.pow_of_prime IsPrimitiveRoot.pow_of_prime
+-/
 
 /- ./././Mathport/Syntax/Translate/Tactic/Lean3.lean:132:4: warning: unsupported: rw with cfg: { occs := occurrences.pos[occurrences.pos] «expr[ ,]»([1]) } -/
+#print IsPrimitiveRoot.pow_iff_coprime /-
 theorem pow_iff_coprime (h : IsPrimitiveRoot ζ k) (h0 : 0 < k) (i : ℕ) :
     IsPrimitiveRoot (ζ ^ i) k ↔ i.coprime k :=
   by
@@ -449,18 +472,25 @@ theorem pow_iff_coprime (h : IsPrimitiveRoot ζ k) (h0 : 0 < k) (i : ℕ) :
   apply Nat.dvd_antisymm ⟨i.gcd k, hb⟩ (hi.dvd_of_pow_eq_one b _)
   rw [← pow_mul', ← mul_assoc, ← hb, pow_mul, h.pow_eq_one, one_pow]
 #align is_primitive_root.pow_iff_coprime IsPrimitiveRoot.pow_iff_coprime
+-/
 
+#print IsPrimitiveRoot.orderOf /-
 protected theorem orderOf (ζ : M) : IsPrimitiveRoot ζ (orderOf ζ) :=
   ⟨pow_orderOf_eq_one ζ, fun l => orderOf_dvd_of_pow_eq_one⟩
 #align is_primitive_root.order_of IsPrimitiveRoot.orderOf
+-/
 
+#print IsPrimitiveRoot.unique /-
 theorem unique {ζ : M} (hk : IsPrimitiveRoot ζ k) (hl : IsPrimitiveRoot ζ l) : k = l :=
   Nat.dvd_antisymm (hk.2 _ hl.1) (hl.2 _ hk.1)
 #align is_primitive_root.unique IsPrimitiveRoot.unique
+-/
 
+#print IsPrimitiveRoot.eq_orderOf /-
 theorem eq_orderOf : k = orderOf ζ :=
   h.unique (IsPrimitiveRoot.orderOf ζ)
 #align is_primitive_root.eq_order_of IsPrimitiveRoot.eq_orderOf
+-/
 
 protected theorem iff (hk : 0 < k) :
     IsPrimitiveRoot ζ k ↔ ζ ^ k = 1 ∧ ∀ l : ℕ, 0 < l → l < k → ζ ^ l ≠ 1 :=
@@ -472,23 +502,28 @@ protected theorem iff (hk : 0 < k) :
   exact pow_ne_one_of_lt_orderOf' hl'.ne' hl
 #align is_primitive_root.iff IsPrimitiveRoot.iff
 
+#print IsPrimitiveRoot.not_iff /-
 protected theorem not_iff : ¬IsPrimitiveRoot ζ k ↔ orderOf ζ ≠ k :=
   ⟨fun h hk => h <| hk ▸ IsPrimitiveRoot.orderOf ζ, fun h hk =>
     h.symm <| hk.unique <| IsPrimitiveRoot.orderOf ζ⟩
 #align is_primitive_root.not_iff IsPrimitiveRoot.not_iff
+-/
 
+#print IsPrimitiveRoot.pow_of_dvd /-
 theorem pow_of_dvd (h : IsPrimitiveRoot ζ k) {p : ℕ} (hp : p ≠ 0) (hdiv : p ∣ k) :
     IsPrimitiveRoot (ζ ^ p) (k / p) :=
   by
   suffices orderOf (ζ ^ p) = k / p by exact this ▸ IsPrimitiveRoot.orderOf (ζ ^ p)
   rw [orderOf_pow' _ hp, ← eq_order_of h, Nat.gcd_eq_right hdiv]
 #align is_primitive_root.pow_of_dvd IsPrimitiveRoot.pow_of_dvd
+-/
 
 protected theorem mem_rootsOfUnity {ζ : Mˣ} {n : ℕ+} (h : IsPrimitiveRoot ζ n) :
     ζ ∈ rootsOfUnity n M :=
   h.pow_eq_one
 #align is_primitive_root.mem_roots_of_unity IsPrimitiveRoot.mem_rootsOfUnity
 
+#print IsPrimitiveRoot.pow /-
 /-- If there is a `n`-th primitive root of unity in `R` and `b` divides `n`,
 then there is a `b`-th primitive root of unity in `R`. -/
 theorem pow {n : ℕ} {a b : ℕ} (hn : 0 < n) (h : IsPrimitiveRoot ζ n) (hprod : n = a * b) :
@@ -500,6 +535,7 @@ theorem pow {n : ℕ} {a b : ℕ} (hn : 0 < n) (h : IsPrimitiveRoot ζ n) (hprod
   rwa [← mul_dvd_mul_iff_left ha0]
   exact h.dvd_of_pow_eq_one _ hl
 #align is_primitive_root.pow IsPrimitiveRoot.pow
+-/
 
 section Maps
 
@@ -582,6 +618,7 @@ theorem inv_iff : IsPrimitiveRoot ζ⁻¹ k ↔ IsPrimitiveRoot ζ k := by refin
   intro h; rw [← inv_inv ζ]; exact inv h
 #align is_primitive_root.inv_iff IsPrimitiveRoot.inv_iff
 
+#print IsPrimitiveRoot.zpow_of_gcd_eq_one /-
 theorem zpow_of_gcd_eq_one (h : IsPrimitiveRoot ζ k) (i : ℤ) (hi : i.gcd k = 1) :
     IsPrimitiveRoot (ζ ^ i) k := by
   by_cases h0 : 0 ≤ i
@@ -595,6 +632,7 @@ theorem zpow_of_gcd_eq_one (h : IsPrimitiveRoot ζ k) (i : ℤ) (hi : i.gcd k =
   rw [Int.gcd, ← Int.natAbs_neg, ← hi'] at hi 
   exact hi
 #align is_primitive_root.zpow_of_gcd_eq_one IsPrimitiveRoot.zpow_of_gcd_eq_one
+-/
 
 end DivisionCommMonoid
 
@@ -639,9 +677,11 @@ theorem ne_zero' {n : ℕ+} (hζ : IsPrimitiveRoot ζ n) : NeZero ((n : ℕ) : R
   · exact NeZero.of_not_dvd R hp
 #align is_primitive_root.ne_zero' IsPrimitiveRoot.ne_zero'
 
+#print IsPrimitiveRoot.mem_nthRootsFinset /-
 theorem mem_nthRootsFinset (hζ : IsPrimitiveRoot ζ k) (hk : 0 < k) : ζ ∈ nthRootsFinset k R :=
   (mem_nthRootsFinset hk).2 hζ.pow_eq_one
 #align is_primitive_root.mem_nth_roots_finset IsPrimitiveRoot.mem_nthRootsFinset
+-/
 
 end IsDomain
 
@@ -811,7 +851,7 @@ theorem isPrimitiveRoot_iff {k : ℕ} {ζ ξ : R} (h : IsPrimitiveRoot ζ k) (h0
   · rintro ⟨i, -, hi, rfl⟩; exact h.pow_of_coprime i hi
 #align is_primitive_root.is_primitive_root_iff IsPrimitiveRoot.isPrimitiveRoot_iff
 
-theorem card_roots_of_unity' {n : ℕ+} (h : IsPrimitiveRoot ζ n) :
+theorem card_rootsOfUnity' {n : ℕ+} (h : IsPrimitiveRoot ζ n) :
     Fintype.card (rootsOfUnity n R) = n :=
   by
   let e := h.zmod_equiv_zpowers
@@ -822,7 +862,7 @@ theorem card_roots_of_unity' {n : ℕ+} (h : IsPrimitiveRoot ζ n) :
     _ = Fintype.card (ZMod n) := (Fintype.card_congr e.to_equiv.symm)
     _ = n := ZMod.card n
     
-#align is_primitive_root.card_roots_of_unity' IsPrimitiveRoot.card_roots_of_unity'
+#align is_primitive_root.card_roots_of_unity' IsPrimitiveRoot.card_rootsOfUnity'
 
 theorem card_rootsOfUnity {ζ : R} {n : ℕ+} (h : IsPrimitiveRoot ζ n) :
     Fintype.card (rootsOfUnity n R) = n :=
@@ -876,14 +916,17 @@ theorem nthRoots_nodup {ζ : R} {n : ℕ} (h : IsPrimitiveRoot ζ n) : (nthRoots
     exact Nat.lt_asymm ha ha
 #align is_primitive_root.nth_roots_nodup IsPrimitiveRoot.nthRoots_nodup
 
+#print IsPrimitiveRoot.card_nthRootsFinset /-
 @[simp]
 theorem card_nthRootsFinset {ζ : R} {n : ℕ} (h : IsPrimitiveRoot ζ n) :
     (nthRootsFinset n R).card = n := by
   rw [nth_roots_finset, ← Multiset.toFinset_eq (nth_roots_nodup h), card_mk, h.card_nth_roots]
 #align is_primitive_root.card_nth_roots_finset IsPrimitiveRoot.card_nthRootsFinset
+-/
 
 open scoped Nat
 
+#print IsPrimitiveRoot.card_primitiveRoots /-
 /-- If an integral domain has a primitive `k`-th root of unity, then it has `φ k` of them. -/
 theorem card_primitiveRoots {ζ : R} {k : ℕ} (h : IsPrimitiveRoot ζ k) :
     (primitiveRoots k R).card = φ k := by
@@ -905,6 +948,7 @@ theorem card_primitiveRoots {ζ : R} {k : ℕ} (h : IsPrimitiveRoot ζ k) :
     rcases hξ with ⟨i, hin, hi, H⟩
     exact ⟨i, ⟨hin, hi.symm⟩, H⟩
 #align is_primitive_root.card_primitive_roots IsPrimitiveRoot.card_primitiveRoots
+-/
 
 /-- The sets `primitive_roots k R` are pairwise disjoint. -/
 theorem disjoint {k l : ℕ} (h : k ≠ l) : Disjoint (primitiveRoots k R) (primitiveRoots l R) :=
@@ -913,10 +957,11 @@ theorem disjoint {k l : ℕ} (h : k ≠ l) : Disjoint (primitiveRoots k R) (prim
       (isPrimitiveRoot_of_mem_primitiveRoots hk).unique <| isPrimitiveRoot_of_mem_primitiveRoots hl
 #align is_primitive_root.disjoint IsPrimitiveRoot.disjoint
 
+#print IsPrimitiveRoot.nthRoots_one_eq_biUnion_primitiveRoots' /-
 /-- `nth_roots n` as a `finset` is equal to the union of `primitive_roots i R` for `i ∣ n`
 if there is a primitive root of unity in `R`.
 This holds for any `nat`, not just `pnat`, see `nth_roots_one_eq_bUnion_primitive_roots`. -/
-theorem nth_roots_one_eq_biUnion_primitive_roots' {ζ : R} {n : ℕ+} (h : IsPrimitiveRoot ζ n) :
+theorem nthRoots_one_eq_biUnion_primitiveRoots' {ζ : R} {n : ℕ+} (h : IsPrimitiveRoot ζ n) :
     nthRootsFinset n R = (Nat.divisors ↑n).biUnion fun i => primitiveRoots i R :=
   by
   symm
@@ -942,17 +987,20 @@ theorem nth_roots_one_eq_biUnion_primitive_roots' {ζ : R} {n : ℕ+} (h : IsPri
       rw [(h.pow n.pos hd).card_primitiveRoots]
     · intro i hi j hj hdiff
       exact Disjoint hdiff
-#align is_primitive_root.nth_roots_one_eq_bUnion_primitive_roots' IsPrimitiveRoot.nth_roots_one_eq_biUnion_primitive_roots'
+#align is_primitive_root.nth_roots_one_eq_bUnion_primitive_roots' IsPrimitiveRoot.nthRoots_one_eq_biUnion_primitiveRoots'
+-/
 
+#print IsPrimitiveRoot.nthRoots_one_eq_biUnion_primitiveRoots /-
 /-- `nth_roots n` as a `finset` is equal to the union of `primitive_roots i R` for `i ∣ n`
 if there is a primitive root of unity in `R`. -/
-theorem nth_roots_one_eq_biUnion_primitiveRoots {ζ : R} {n : ℕ} (h : IsPrimitiveRoot ζ n) :
+theorem nthRoots_one_eq_biUnion_primitiveRoots {ζ : R} {n : ℕ} (h : IsPrimitiveRoot ζ n) :
     nthRootsFinset n R = (Nat.divisors n).biUnion fun i => primitiveRoots i R :=
   by
   by_cases hn : n = 0
   · simp [hn]
   exact @nth_roots_one_eq_bUnion_primitive_roots' _ _ _ _ ⟨n, Nat.pos_of_ne_zero hn⟩ h
-#align is_primitive_root.nth_roots_one_eq_bUnion_primitive_roots IsPrimitiveRoot.nth_roots_one_eq_biUnion_primitiveRoots
+#align is_primitive_root.nth_roots_one_eq_bUnion_primitive_roots IsPrimitiveRoot.nthRoots_one_eq_biUnion_primitiveRoots
+-/
 
 end IsDomain
 
@@ -968,7 +1016,7 @@ noncomputable def autToPow : (S ≃ₐ[R] S) →* (ZMod n)ˣ :=
   have ho : orderOf μ' = n := by
     rw [hμ.eq_order_of, ← hμ.coe_to_roots_of_unity_coe, orderOf_units, orderOf_subgroup]
   MonoidHom.toHomUnits
-    { toFun := fun σ => (map_root_of_unity_eq_pow_self σ.toAlgHom μ').some
+    { toFun := fun σ => (map_rootsOfUnity_eq_pow_self σ.toAlgHom μ').some
       map_one' := by
         generalize_proofs h1
         have h := h1.some_spec
@@ -998,7 +1046,7 @@ noncomputable def autToPow : (S ≃ₐ[R] S) →* (ZMod n)ˣ :=
 -- We are not using @[simps] in aut_to_pow to avoid a timeout.
 theorem coe_autToPow_apply (f : S ≃ₐ[R] S) :
     (autToPow R hμ f : ZMod n) =
-      ((map_root_of_unity_eq_pow_self f hμ.toRootsOfUnity).some : ZMod n) :=
+      ((map_rootsOfUnity_eq_pow_self f hμ.toRootsOfUnity).some : ZMod n) :=
   rfl
 #align is_primitive_root.coe_aut_to_pow_apply IsPrimitiveRoot.coe_autToPow_apply
 
Diff
@@ -3,8 +3,8 @@ Copyright (c) 2020 Johan Commelin. All rights reserved.
 Released under Apache 2.0 license as described in the file LICENSE.
 Authors: Johan Commelin
 
-! This file was ported from Lean 3 source module ring_theory.roots_of_unity
-! leanprover-community/mathlib commit e655e4ea5c6d02854696f97494997ba4c31be802
+! This file was ported from Lean 3 source module ring_theory.roots_of_unity.basic
+! leanprover-community/mathlib commit 7fdeecc0d03cd40f7a165e6cf00a4d2286db599f
 ! Please do not edit these lines, except to modify the commit id
 ! if you have ported upstream changes.
 -/
@@ -13,7 +13,6 @@ import Mathbin.Algebra.NeZero
 import Mathbin.Algebra.GcdMonoid.IntegrallyClosed
 import Mathbin.Data.Polynomial.RingDivision
 import Mathbin.FieldTheory.Finite.Basic
-import Mathbin.FieldTheory.Minpoly.IsIntegrallyClosed
 import Mathbin.FieldTheory.Separable
 import Mathbin.GroupTheory.SpecificGroups.Cyclic
 import Mathbin.NumberTheory.Divisors
@@ -87,7 +86,7 @@ variable {k l : ℕ+}
 /-- `roots_of_unity k M` is the subgroup of elements `m : Mˣ` that satisfy `m ^ k = 1` -/
 def rootsOfUnity (k : ℕ+) (M : Type _) [CommMonoid M] : Subgroup Mˣ
     where
-  carrier := { ζ | ζ ^ (k : ℕ) = 1 }
+  carrier := {ζ | ζ ^ (k : ℕ) = 1}
   one_mem' := one_pow _
   mul_mem' ζ ξ hζ hξ := by simp_all only [Set.mem_setOf_eq, mul_pow, one_mul]
   inv_mem' ζ hζ := by simp_all only [Set.mem_setOf_eq, inv_pow, inv_one]
@@ -522,7 +521,7 @@ theorem of_map_of_injective [MonoidHomClass F M N] (h : IsPrimitiveRoot (f ζ) k
     dvd_of_pow_eq_one := by
       rw [h.eq_order_of]
       intro l hl
-      apply_fun f  at hl 
+      apply_fun f at hl 
       rw [map_pow, _root_.map_one] at hl 
       exact orderOf_dvd_of_pow_eq_one hl }
 #align is_primitive_root.of_map_of_injective IsPrimitiveRoot.of_map_of_injective
@@ -957,223 +956,6 @@ theorem nth_roots_one_eq_biUnion_primitiveRoots {ζ : R} {n : ℕ} (h : IsPrimit
 
 end IsDomain
 
-section minpoly
-
-open minpoly
-
-section CommRing
-
-variable {n : ℕ} {K : Type _} [CommRing K] {μ : K} (h : IsPrimitiveRoot μ n) (hpos : 0 < n)
-
-include n μ h hpos
-
-/-- `μ` is integral over `ℤ`. -/
-theorem isIntegral : IsIntegral ℤ μ := by
-  use X ^ n - 1
-  constructor
-  · exact monic_X_pow_sub_C 1 (ne_of_lt hpos).symm
-  ·
-    simp only [((IsPrimitiveRoot.iff_def μ n).mp h).left, eval₂_one, eval₂_X_pow, eval₂_sub,
-      sub_self]
-#align is_primitive_root.is_integral IsPrimitiveRoot.isIntegral
-
-section IsDomain
-
-variable [IsDomain K] [CharZero K]
-
-omit hpos
-
-/-- The minimal polynomial of a root of unity `μ` divides `X ^ n - 1`. -/
-theorem minpoly_dvd_x_pow_sub_one : minpoly ℤ μ ∣ X ^ n - 1 :=
-  by
-  rcases n.eq_zero_or_pos with (rfl | hpos)
-  · simp
-  letI : IsIntegrallyClosed ℤ := GCDMonoid.toIsIntegrallyClosed
-  apply minpoly.isIntegrallyClosed_dvd (IsIntegral h hpos)
-  simp only [((IsPrimitiveRoot.iff_def μ n).mp h).left, aeval_X_pow, eq_intCast, Int.cast_one,
-    aeval_one, AlgHom.map_sub, sub_self]
-#align is_primitive_root.minpoly_dvd_X_pow_sub_one IsPrimitiveRoot.minpoly_dvd_x_pow_sub_one
-
-/-- The reduction modulo `p` of the minimal polynomial of a root of unity `μ` is separable. -/
-theorem separable_minpoly_mod {p : ℕ} [Fact p.Prime] (hdiv : ¬p ∣ n) :
-    Separable (map (Int.castRingHom (ZMod p)) (minpoly ℤ μ)) :=
-  by
-  have hdvd : map (Int.castRingHom (ZMod p)) (minpoly ℤ μ) ∣ X ^ n - 1 := by
-    simpa [Polynomial.map_pow, map_X, Polynomial.map_one, Polynomial.map_sub] using
-      RingHom.map_dvd (map_ring_hom (Int.castRingHom (ZMod p))) (minpoly_dvd_X_pow_sub_one h)
-  refine' separable.of_dvd (separable_X_pow_sub_C 1 _ one_ne_zero) hdvd
-  by_contra hzero
-  exact hdiv ((ZMod.nat_cast_zmod_eq_zero_iff_dvd n p).1 hzero)
-#align is_primitive_root.separable_minpoly_mod IsPrimitiveRoot.separable_minpoly_mod
-
-/-- The reduction modulo `p` of the minimal polynomial of a root of unity `μ` is squarefree. -/
-theorem squarefree_minpoly_mod {p : ℕ} [Fact p.Prime] (hdiv : ¬p ∣ n) :
-    Squarefree (map (Int.castRingHom (ZMod p)) (minpoly ℤ μ)) :=
-  (separable_minpoly_mod h hdiv).Squarefree
-#align is_primitive_root.squarefree_minpoly_mod IsPrimitiveRoot.squarefree_minpoly_mod
-
-/- Let `P` be the minimal polynomial of a root of unity `μ` and `Q` be the minimal polynomial of
-`μ ^ p`, where `p` is a natural number that does not divide `n`. Then `P` divides `expand ℤ p Q`. -/
-theorem minpoly_dvd_expand {p : ℕ} (hdiv : ¬p ∣ n) : minpoly ℤ μ ∣ expand ℤ p (minpoly ℤ (μ ^ p)) :=
-  by
-  rcases n.eq_zero_or_pos with (rfl | hpos)
-  · simp_all
-  letI : IsIntegrallyClosed ℤ := GCDMonoid.toIsIntegrallyClosed
-  refine' minpoly.isIntegrallyClosed_dvd (h.is_integral hpos) _
-  · rw [aeval_def, coe_expand, ← comp, eval₂_eq_eval_map, map_comp, Polynomial.map_pow, map_X,
-      eval_comp, eval_pow, eval_X, ← eval₂_eq_eval_map, ← aeval_def]
-    exact minpoly.aeval _ _
-#align is_primitive_root.minpoly_dvd_expand IsPrimitiveRoot.minpoly_dvd_expand
-
-/- Let `P` be the minimal polynomial of a root of unity `μ` and `Q` be the minimal polynomial of
-`μ ^ p`, where `p` is a prime that does not divide `n`. Then `P` divides `Q ^ p` modulo `p`. -/
-theorem minpoly_dvd_pow_mod {p : ℕ} [hprime : Fact p.Prime] (hdiv : ¬p ∣ n) :
-    map (Int.castRingHom (ZMod p)) (minpoly ℤ μ) ∣
-      map (Int.castRingHom (ZMod p)) (minpoly ℤ (μ ^ p)) ^ p :=
-  by
-  set Q := minpoly ℤ (μ ^ p)
-  have hfrob :
-    map (Int.castRingHom (ZMod p)) Q ^ p = map (Int.castRingHom (ZMod p)) (expand ℤ p Q) := by
-    rw [← ZMod.expand_card, map_expand]
-  rw [hfrob]
-  apply RingHom.map_dvd (map_ring_hom (Int.castRingHom (ZMod p)))
-  exact minpoly_dvd_expand h hdiv
-#align is_primitive_root.minpoly_dvd_pow_mod IsPrimitiveRoot.minpoly_dvd_pow_mod
-
-/- Let `P` be the minimal polynomial of a root of unity `μ` and `Q` be the minimal polynomial of
-`μ ^ p`, where `p` is a prime that does not divide `n`. Then `P` divides `Q` modulo `p`. -/
-theorem minpoly_dvd_mod_p {p : ℕ} [hprime : Fact p.Prime] (hdiv : ¬p ∣ n) :
-    map (Int.castRingHom (ZMod p)) (minpoly ℤ μ) ∣
-      map (Int.castRingHom (ZMod p)) (minpoly ℤ (μ ^ p)) :=
-  (UniqueFactorizationMonoid.dvd_pow_iff_dvd_of_squarefree (squarefree_minpoly_mod h hdiv)
-        hprime.1.NeZero).1
-    (minpoly_dvd_pow_mod h hdiv)
-#align is_primitive_root.minpoly_dvd_mod_p IsPrimitiveRoot.minpoly_dvd_mod_p
-
-/-- If `p` is a prime that does not divide `n`,
-then the minimal polynomials of a primitive `n`-th root of unity `μ`
-and of `μ ^ p` are the same. -/
-theorem minpoly_eq_pow {p : ℕ} [hprime : Fact p.Prime] (hdiv : ¬p ∣ n) :
-    minpoly ℤ μ = minpoly ℤ (μ ^ p) := by
-  by_cases hn : n = 0; · simp_all
-  have hpos := Nat.pos_of_ne_zero hn
-  by_contra hdiff
-  set P := minpoly ℤ μ
-  set Q := minpoly ℤ (μ ^ p)
-  have Pmonic : P.monic := minpoly.monic (h.is_integral hpos)
-  have Qmonic : Q.monic := minpoly.monic ((h.pow_of_prime hprime.1 hdiv).IsIntegral hpos)
-  have Pirr : Irreducible P := minpoly.irreducible (h.is_integral hpos)
-  have Qirr : Irreducible Q := minpoly.irreducible ((h.pow_of_prime hprime.1 hdiv).IsIntegral hpos)
-  have PQprim : is_primitive (P * Q) := Pmonic.is_primitive.mul Qmonic.is_primitive
-  have prod : P * Q ∣ X ^ n - 1 :=
-    by
-    rw [is_primitive.int.dvd_iff_map_cast_dvd_map_cast (P * Q) (X ^ n - 1) PQprim
-        (monic_X_pow_sub_C (1 : ℤ) (ne_of_gt hpos)).IsPrimitive,
-      Polynomial.map_mul]
-    refine' IsCoprime.mul_dvd _ _ _
-    · have aux := is_primitive.int.irreducible_iff_irreducible_map_cast Pmonic.is_primitive
-      refine' (dvd_or_coprime _ _ (aux.1 Pirr)).resolve_left _
-      rw [map_dvd_map (Int.castRingHom ℚ) Int.cast_injective Pmonic]
-      intro hdiv
-      refine' hdiff (eq_of_monic_of_associated Pmonic Qmonic _)
-      exact associated_of_dvd_dvd hdiv (Pirr.dvd_symm Qirr hdiv)
-    · apply (map_dvd_map (Int.castRingHom ℚ) Int.cast_injective Pmonic).2
-      exact minpoly_dvd_X_pow_sub_one h
-    · apply (map_dvd_map (Int.castRingHom ℚ) Int.cast_injective Qmonic).2
-      exact minpoly_dvd_X_pow_sub_one (pow_of_prime h hprime.1 hdiv)
-  replace prod := RingHom.map_dvd (map_ring_hom (Int.castRingHom (ZMod p))) Prod
-  rw [coe_map_ring_hom, Polynomial.map_mul, Polynomial.map_sub, Polynomial.map_one,
-    Polynomial.map_pow, map_X] at prod 
-  obtain ⟨R, hR⟩ := minpoly_dvd_mod_p h hdiv
-  rw [hR, ← mul_assoc, ← Polynomial.map_mul, ← sq, Polynomial.map_pow] at prod 
-  have habs : map (Int.castRingHom (ZMod p)) P ^ 2 ∣ map (Int.castRingHom (ZMod p)) P ^ 2 * R := by
-    use R
-  replace habs :=
-    lt_of_lt_of_le (PartENat.coe_lt_coe.2 one_lt_two)
-      (multiplicity.le_multiplicity_of_pow_dvd (dvd_trans habs Prod))
-  have hfree : Squarefree (X ^ n - 1 : (ZMod p)[X]) :=
-    (separable_X_pow_sub_C 1 (fun h => hdiv <| (ZMod.nat_cast_zmod_eq_zero_iff_dvd n p).1 h)
-        one_ne_zero).Squarefree
-  cases'
-    (multiplicity.squarefree_iff_multiplicity_le_one (X ^ n - 1)).1 hfree
-      (map (Int.castRingHom (ZMod p)) P) with
-    hle hunit
-  · rw [Nat.cast_one] at habs ; exact hle.not_lt habs
-  · replace hunit := degree_eq_zero_of_is_unit hunit
-    rw [degree_map_eq_of_leading_coeff_ne_zero (Int.castRingHom (ZMod p)) _] at hunit 
-    · exact (minpoly.degree_pos (IsIntegral h hpos)).ne' hunit
-    simp only [Pmonic, eq_intCast, monic.leading_coeff, Int.cast_one, Ne.def, not_false_iff,
-      one_ne_zero]
-#align is_primitive_root.minpoly_eq_pow IsPrimitiveRoot.minpoly_eq_pow
-
-/-- If `m : ℕ` is coprime with `n`,
-then the minimal polynomials of a primitive `n`-th root of unity `μ`
-and of `μ ^ m` are the same. -/
-theorem minpoly_eq_pow_coprime {m : ℕ} (hcop : Nat.coprime m n) : minpoly ℤ μ = minpoly ℤ (μ ^ m) :=
-  by
-  revert n hcop
-  refine' UniqueFactorizationMonoid.induction_on_prime m _ _ _
-  · intro n hn h
-    congr
-    simpa [(Nat.coprime_zero_left n).mp hn] using h
-  · intro u hunit n hcop h
-    congr
-    simp [nat.is_unit_iff.mp hunit]
-  · intro a p ha hprime hind n hcop h
-    rw [hind (Nat.coprime.coprime_mul_left hcop) h]; clear hind
-    replace hprime := hprime.nat_prime
-    have hdiv := (Nat.Prime.coprime_iff_not_dvd hprime).1 (Nat.coprime.coprime_mul_right hcop)
-    haveI := Fact.mk hprime
-    rw [minpoly_eq_pow (h.pow_of_coprime a (Nat.coprime.coprime_mul_left hcop)) hdiv]
-    congr 1
-    ring
-#align is_primitive_root.minpoly_eq_pow_coprime IsPrimitiveRoot.minpoly_eq_pow_coprime
-
-/-- If `m : ℕ` is coprime with `n`,
-then the minimal polynomial of a primitive `n`-th root of unity `μ`
-has `μ ^ m` as root. -/
-theorem pow_isRoot_minpoly {m : ℕ} (hcop : Nat.coprime m n) :
-    IsRoot (map (Int.castRingHom K) (minpoly ℤ μ)) (μ ^ m) := by
-  simpa [minpoly_eq_pow_coprime h hcop, eval_map, aeval_def (μ ^ m) _] using minpoly.aeval ℤ (μ ^ m)
-#align is_primitive_root.pow_is_root_minpoly IsPrimitiveRoot.pow_isRoot_minpoly
-
-/-- `primitive_roots n K` is a subset of the roots of the minimal polynomial of a primitive
-`n`-th root of unity `μ`. -/
-theorem is_roots_of_minpoly :
-    primitiveRoots n K ⊆ (map (Int.castRingHom K) (minpoly ℤ μ)).roots.toFinset :=
-  by
-  by_cases hn : n = 0; · simp_all
-  have hpos := Nat.pos_of_ne_zero hn
-  intro x hx
-  obtain ⟨m, hle, hcop, rfl⟩ := (is_primitive_root_iff h hpos).1 ((mem_primitiveRoots hpos).1 hx)
-  simpa [Multiset.mem_toFinset,
-    mem_roots (map_monic_ne_zero <| minpoly.monic <| IsIntegral h hpos)] using
-    pow_is_root_minpoly h hcop
-#align is_primitive_root.is_roots_of_minpoly IsPrimitiveRoot.is_roots_of_minpoly
-
-/-- The degree of the minimal polynomial of `μ` is at least `totient n`. -/
-theorem totient_le_degree_minpoly : Nat.totient n ≤ (minpoly ℤ μ).natDegree :=
-  let P : ℤ[X] := minpoly ℤ μ
-  let
-    P_K :-- minimal polynomial of `μ`
-      K[X] :=
-    map (Int.castRingHom K) P
-  -- minimal polynomial of `μ` sent to `K[X]`
-  calc
-    n.totient = (primitiveRoots n K).card := h.card_primitiveRoots.symm
-    _ ≤ P_K.roots.toFinset.card := (Finset.card_le_of_subset (is_roots_of_minpoly h))
-    _ ≤ P_K.roots.card := (Multiset.toFinset_card_le _)
-    _ ≤ P_K.natDegree := (card_roots' _)
-    _ ≤ P.natDegree := natDegree_map_le _ _
-    
-#align is_primitive_root.totient_le_degree_minpoly IsPrimitiveRoot.totient_le_degree_minpoly
-
-end IsDomain
-
-end CommRing
-
-end minpoly
-
 section Automorphisms
 
 variable {S} [CommRing S] [IsDomain S] {μ : S} {n : ℕ+} (hμ : IsPrimitiveRoot μ n) (R) [CommRing R]

Changes in mathlib4

mathlib3
mathlib4
chore: Rename nat_cast/int_cast/rat_cast to natCast/intCast/ratCast (#11486)

Now that I am defining NNRat.cast, I want a definitive answer to this naming issue. Plenty of lemmas in mathlib already use natCast/intCast/ratCast over nat_cast/int_cast/rat_cast, and this matches with the general expectation that underscore-separated name parts correspond to a single declaration.

Diff
@@ -718,11 +718,11 @@ theorem pow_sub_one_eq [IsDomain R] {ζ : R} (hζ : IsPrimitiveRoot ζ k) (hk :
 and the powers of a primitive root of unity `ζ`. -/
 def zmodEquivZPowers (h : IsPrimitiveRoot ζ k) : ZMod k ≃+ Additive (Subgroup.zpowers ζ) :=
   AddEquiv.ofBijective
-    (AddMonoidHom.liftOfRightInverse (Int.castAddHom <| ZMod k) _ ZMod.int_cast_rightInverse
+    (AddMonoidHom.liftOfRightInverse (Int.castAddHom <| ZMod k) _ ZMod.intCast_rightInverse
       ⟨{  toFun := fun i => Additive.ofMul (⟨_, i, rfl⟩ : Subgroup.zpowers ζ)
           map_zero' := by simp only [zpow_zero]; rfl
           map_add' := by intro i j; simp only [zpow_add]; rfl }, fun i hi => by
-        simp only [AddMonoidHom.mem_ker, CharP.int_cast_eq_zero_iff (ZMod k) k, AddMonoidHom.coe_mk,
+        simp only [AddMonoidHom.mem_ker, CharP.intCast_eq_zero_iff (ZMod k) k, AddMonoidHom.coe_mk,
           Int.coe_castAddHom] at hi ⊢
         obtain ⟨i, rfl⟩ := hi
         simp [zpow_mul, h.pow_eq_one, one_zpow, zpow_natCast]⟩)
@@ -732,8 +732,8 @@ def zmodEquivZPowers (h : IsPrimitiveRoot ζ k) : ZMod k ≃+ Additive (Subgroup
         intro i hi
         rw [Subtype.ext_iff] at hi
         have := (h.zpow_eq_one_iff_dvd _).mp hi
-        rw [← (CharP.int_cast_eq_zero_iff (ZMod k) k _).mpr this, eq_comm]
-        exact ZMod.int_cast_rightInverse i
+        rw [← (CharP.intCast_eq_zero_iff (ZMod k) k _).mpr this, eq_comm]
+        exact ZMod.intCast_rightInverse i
       · rintro ⟨ξ, i, rfl⟩
         refine' ⟨Int.castAddHom (ZMod k) i, _⟩
         rw [AddMonoidHom.liftOfRightInverse_comp_apply]
@@ -744,7 +744,7 @@ def zmodEquivZPowers (h : IsPrimitiveRoot ζ k) : ZMod k ≃+ Additive (Subgroup
 theorem zmodEquivZPowers_apply_coe_int (i : ℤ) :
     h.zmodEquivZPowers i = Additive.ofMul (⟨ζ ^ i, i, rfl⟩ : Subgroup.zpowers ζ) := by
   rw [zmodEquivZPowers, AddEquiv.ofBijective_apply] -- Porting note: Original proof didn't have `rw`
-  exact AddMonoidHom.liftOfRightInverse_comp_apply _ _ ZMod.int_cast_rightInverse _ _
+  exact AddMonoidHom.liftOfRightInverse_comp_apply _ _ ZMod.intCast_rightInverse _ _
 #align is_primitive_root.zmod_equiv_zpowers_apply_coe_int IsPrimitiveRoot.zmodEquivZPowers_apply_coe_int
 
 @[simp]
@@ -1037,7 +1037,7 @@ noncomputable def autToPow : (S ≃ₐ[R] S) →* (ZMod n)ˣ :=
         replace h : μ' = μ' ^ h1.choose :=
           rootsOfUnity.coe_injective (by simpa only [rootsOfUnity.coe_pow] using h)
         nth_rw 1 [← pow_one μ'] at h
-        rw [← Nat.cast_one, ZMod.nat_cast_eq_nat_cast_iff, ← ho, ← pow_eq_pow_iff_modEq, h]
+        rw [← Nat.cast_one, ZMod.natCast_eq_natCast_iff, ← ho, ← pow_eq_pow_iff_modEq, h]
       map_mul' := by
         intro x y
         dsimp only
@@ -1054,7 +1054,7 @@ noncomputable def autToPow : (S ≃ₐ[R] S) →* (ZMod n)ˣ :=
         rw [← pow_mul] at hxy
         replace hxy : μ' ^ (hx'.choose * hy'.choose) = μ' ^ hxy'.choose :=
           rootsOfUnity.coe_injective (by simpa only [rootsOfUnity.coe_pow] using hxy)
-        rw [← Nat.cast_mul, ZMod.nat_cast_eq_nat_cast_iff, ← ho, ← pow_eq_pow_iff_modEq, hxy] }
+        rw [← Nat.cast_mul, ZMod.natCast_eq_natCast_iff, ← ho, ← pow_eq_pow_iff_modEq, hxy] }
 #align is_primitive_root.aut_to_pow IsPrimitiveRoot.autToPow
 
 -- We are not using @[simps] in aut_to_pow to avoid a timeout.
@@ -1072,7 +1072,7 @@ theorem autToPow_spec (f : S ≃ₐ[R] S) : μ ^ (hμ.autToPow R f : ZMod n).val
   refine' (_ : ((hμ.toRootsOfUnity : Sˣ) : S) ^ _ = _).trans this.symm
   rw [← rootsOfUnity.coe_pow, ← rootsOfUnity.coe_pow]
   congr 2
-  rw [pow_eq_pow_iff_modEq, ZMod.val_nat_cast, hμ.eq_orderOf, ← Subgroup.orderOf_coe,
+  rw [pow_eq_pow_iff_modEq, ZMod.val_natCast, hμ.eq_orderOf, ← Subgroup.orderOf_coe,
     ← orderOf_units]
   exact Nat.mod_modEq _ _
 #align is_primitive_root.aut_to_pow_spec IsPrimitiveRoot.autToPow_spec
chore: superfluous parentheses part 2 (#12131)

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

Diff
@@ -243,7 +243,7 @@ theorem card_rootsOfUnity : Fintype.card (rootsOfUnity k R) ≤ k :=
   calc
     Fintype.card (rootsOfUnity k R) = Fintype.card { x // x ∈ nthRoots k (1 : R) } :=
       Fintype.card_congr (rootsOfUnityEquivNthRoots R k)
-    _ ≤ Multiset.card (nthRoots k (1 : R)).attach := (Multiset.card_le_card (Multiset.dedup_le _))
+    _ ≤ Multiset.card (nthRoots k (1 : R)).attach := Multiset.card_le_card (Multiset.dedup_le _)
     _ = Multiset.card (nthRoots k (1 : R)) := Multiset.card_attach
     _ ≤ k := card_nthRoots k 1
 #align card_roots_of_unity card_rootsOfUnity
@@ -901,7 +901,7 @@ theorem card_rootsOfUnity' {n : ℕ+} (h : IsPrimitiveRoot ζ n) :
   calc
     Fintype.card (rootsOfUnity n R) = Fintype.card (Subgroup.zpowers ζ) :=
       Fintype.card_congr <| by rw [h.zpowers_eq]
-    _ = Fintype.card (ZMod n) := (Fintype.card_congr e.toEquiv.symm)
+    _ = Fintype.card (ZMod n) := Fintype.card_congr e.toEquiv.symm
     _ = n := ZMod.card n
 #align is_primitive_root.card_roots_of_unity' IsPrimitiveRoot.card_rootsOfUnity'
 
move(Polynomial): Move out of Data (#11751)

Polynomial and MvPolynomial are algebraic objects, hence should be under Algebra (or at least not under Data)

Diff
@@ -6,7 +6,7 @@ Authors: Johan Commelin
 import Mathlib.Algebra.CharP.Two
 import Mathlib.Algebra.CharP.Reduced
 import Mathlib.Algebra.NeZero
-import Mathlib.Data.Polynomial.RingDivision
+import Mathlib.Algebra.Polynomial.RingDivision
 import Mathlib.GroupTheory.SpecificGroups.Cyclic
 import Mathlib.NumberTheory.Divisors
 import Mathlib.RingTheory.IntegralDomain
chore(Data/Int): Rename coe_nat to natCast (#11637)

Reduce the diff of #11499

Renames

All in the Int namespace:

  • ofNat_eq_castofNat_eq_natCast
  • cast_eq_cast_iff_NatnatCast_inj
  • natCast_eq_ofNatofNat_eq_natCast
  • coe_nat_subnatCast_sub
  • coe_nat_nonnegnatCast_nonneg
  • sign_coe_add_onesign_natCast_add_one
  • nat_succ_eq_int_succnatCast_succ
  • succ_neg_nat_succsucc_neg_natCast_succ
  • coe_pred_of_posnatCast_pred_of_pos
  • coe_nat_divnatCast_div
  • coe_nat_edivnatCast_ediv
  • sign_coe_nat_of_nonzerosign_natCast_of_ne_zero
  • toNat_coe_nattoNat_natCast
  • toNat_coe_nat_add_onetoNat_natCast_add_one
  • coe_nat_dvdnatCast_dvd_natCast
  • coe_nat_dvd_leftnatCast_dvd
  • coe_nat_dvd_rightdvd_natCast
  • le_coe_nat_suble_natCast_sub
  • succ_coe_nat_possucc_natCast_pos
  • coe_nat_modEq_iffnatCast_modEq_iff
  • coe_natAbsnatCast_natAbs
  • coe_nat_eq_zeronatCast_eq_zero
  • coe_nat_ne_zeronatCast_ne_zero
  • coe_nat_ne_zero_iff_posnatCast_ne_zero_iff_pos
  • abs_coe_natabs_natCast
  • coe_nat_nonpos_iffnatCast_nonpos_iff

Also rename Nat.coe_nat_dvd to Nat.cast_dvd_cast

Diff
@@ -255,7 +255,7 @@ theorem map_rootsOfUnity_eq_pow_self [FunLike F R R] [RingHomClass F R R] (σ :
     ∃ m : ℕ, σ (ζ : Rˣ) = ((ζ : Rˣ) : R) ^ m := by
   obtain ⟨m, hm⟩ := MonoidHom.map_cyclic (restrictRootsOfUnity σ k)
   rw [← restrictRootsOfUnity_coe_apply, hm, ← zpow_mod_orderOf, ← Int.toNat_of_nonneg
-      (m.emod_nonneg (Int.coe_nat_ne_zero.mpr (pos_iff_ne_zero.mp (orderOf_pos ζ)))),
+      (m.emod_nonneg (Int.natCast_ne_zero.mpr (pos_iff_ne_zero.mp (orderOf_pos ζ)))),
     zpow_natCast, rootsOfUnity.coe_pow]
   exact ⟨(m % orderOf ζ).toNat, rfl⟩
 #align map_root_of_unity_eq_pow_self map_rootsOfUnity_eq_pow_self
chore: avoid Ne.def (adaptation for nightly-2024-03-27) (#11813)
Diff
@@ -985,7 +985,7 @@ theorem nthRoots_one_eq_biUnion_primitiveRoots' {ζ : R} {n : ℕ+} (h : IsPrimi
   · intro x
     simp only [nthRootsFinset, ← Multiset.toFinset_eq (nthRoots_one_nodup h), exists_prop,
       Finset.mem_biUnion, Finset.mem_filter, Finset.mem_range, mem_nthRoots, Finset.mem_mk,
-      Nat.mem_divisors, and_true_iff, Ne.def, PNat.ne_zero, PNat.pos, not_false_iff]
+      Nat.mem_divisors, and_true_iff, Ne, PNat.ne_zero, PNat.pos, not_false_iff]
     rintro ⟨a, ⟨d, hd⟩, ha⟩
     have hazero : 0 < a := by
       contrapose! hd with ha0
change the order of operation in zsmulRec and nsmulRec (#11451)

We change the following field in the definition of an additive commutative monoid:

 nsmul_succ : ∀ (n : ℕ) (x : G),
-  AddMonoid.nsmul (n + 1) x = x + AddMonoid.nsmul n x
+  AddMonoid.nsmul (n + 1) x = AddMonoid.nsmul n x + x

where the latter is more natural

We adjust the definitions of ^ in monoids, groups, etc. Originally there was a warning comment about why this natural order was preferred

use x * npowRec n x and not npowRec n x * x in the definition to make sure that definitional unfolding of npowRec is blocked, to avoid deep recursion issues.

but it seems to no longer apply.

Remarks on the PR :

  • pow_succ and pow_succ' have switched their meanings.
  • Most of the time, the proofs were adjusted by priming/unpriming one lemma, or exchanging left and right; a few proofs were more complicated to adjust.
  • In particular, [Mathlib/NumberTheory/RamificationInertia.lean] used Ideal.IsPrime.mul_mem_pow which is defined in [Mathlib/RingTheory/DedekindDomain/Ideal.lean]. Changing the order of operation forced me to add the symmetric lemma Ideal.IsPrime.mem_pow_mul.
  • the docstring for Cauchy condensation test in [Mathlib/Analysis/PSeries.lean] was mathematically incorrect, I added the mention that the function is antitone.
Diff
@@ -360,7 +360,7 @@ theorem pow_eq_one_iff_dvd (l : ℕ) : ζ ^ l = 1 ↔ k ∣ l :=
 
 theorem isUnit (h : IsPrimitiveRoot ζ k) (h0 : 0 < k) : IsUnit ζ := by
   apply isUnit_of_mul_eq_one ζ (ζ ^ (k - 1))
-  rw [← pow_succ, tsub_add_cancel_of_le h0.nat_succ_le, h.pow_eq_one]
+  rw [← pow_succ', tsub_add_cancel_of_le h0.nat_succ_le, h.pow_eq_one]
 #align is_primitive_root.is_unit IsPrimitiveRoot.isUnit
 
 theorem pow_ne_one_of_pos_of_lt (h0 : 0 < l) (hl : l < k) : ζ ^ l ≠ 1 :=
@@ -662,7 +662,7 @@ theorem neZero' {n : ℕ+} (hζ : IsPrimitiveRoot ζ n) : NeZero ((n : ℕ) : R)
     haveI : NeZero p := NeZero.of_pos (Nat.pos_of_dvd_of_pos hp n.pos)
     haveI hpri : Fact p.Prime := CharP.char_is_prime_of_pos R p
     have := hζ.pow_eq_one
-    rw [hm.1, hk, pow_succ, mul_assoc, pow_mul', ← frobenius_def, ← frobenius_one p] at this
+    rw [hm.1, hk, pow_succ', mul_assoc, pow_mul', ← frobenius_def, ← frobenius_one p] at this
     exfalso
     have hpos : 0 < p ^ k * m := by
       refine' mul_pos (pow_pos hpri.1.pos _) (Nat.pos_of_ne_zero fun h => _)
@@ -670,7 +670,7 @@ theorem neZero' {n : ℕ+} (hζ : IsPrimitiveRoot ζ n) : NeZero ((n : ℕ) : R)
       rw [h] at H
       simp at H
     refine' hζ.pow_ne_one_of_pos_of_lt hpos _ (frobenius_inj R p this)
-    · rw [hm.1, hk, pow_succ, mul_assoc, mul_comm p]
+    · rw [hm.1, hk, pow_succ', mul_assoc, mul_comm p]
       exact lt_mul_of_one_lt_right hpos hpri.1.one_lt
   · exact NeZero.of_not_dvd R hp
 #align is_primitive_root.ne_zero' IsPrimitiveRoot.neZero'
feat: characterize roots of unity in cyclotomic extensions (#10710)

We add IsPrimitiveRoot.exists_pow_or_neg_mul_pow_of_isOfFinOrder: If x is a root of unity (spelled as IsOfFinOrder x) in an n-th cyclotomic extension of , where n is odd, and ζ is a primitive n-th root of unity, then there exists r < n such that x = ζ^r or x = -ζ^r.

From flt-regular

Diff
@@ -477,6 +477,16 @@ protected theorem not_iff : ¬IsPrimitiveRoot ζ k ↔ orderOf ζ ≠ k :=
     fun h hk => h.symm <| hk.unique <| IsPrimitiveRoot.orderOf ζ⟩
 #align is_primitive_root.not_iff IsPrimitiveRoot.not_iff
 
+theorem pow_mul_pow_lcm {ζ' : M} {k' : ℕ} (hζ : IsPrimitiveRoot ζ k) (hζ' : IsPrimitiveRoot ζ' k')
+    (hk : k ≠ 0) (hk' : k' ≠ 0) :
+    IsPrimitiveRoot
+      (ζ ^ (k / Nat.factorizationLCMLeft k k') * ζ' ^ (k' / Nat.factorizationLCMRight k k'))
+      (Nat.lcm k k') := by
+  convert IsPrimitiveRoot.orderOf _
+  convert ((Commute.all ζ ζ').orderOf_mul_pow_eq_lcm
+    (by simpa [← hζ.eq_orderOf]) (by simpa [← hζ'.eq_orderOf])).symm using 2
+  all_goals simp [hζ.eq_orderOf, hζ'.eq_orderOf]
+
 theorem pow_of_dvd (h : IsPrimitiveRoot ζ k) {p : ℕ} (hp : p ≠ 0) (hdiv : p ∣ k) :
     IsPrimitiveRoot (ζ ^ p) (k / p) := by
   suffices orderOf (ζ ^ p) = k / p by exact this ▸ IsPrimitiveRoot.orderOf (ζ ^ p)
chore: Rename zpow_coe_nat to zpow_natCast (#11528)

... and add a deprecated alias for the old name. This is mostly just me discovering the power of F2

Diff
@@ -256,7 +256,7 @@ theorem map_rootsOfUnity_eq_pow_self [FunLike F R R] [RingHomClass F R R] (σ :
   obtain ⟨m, hm⟩ := MonoidHom.map_cyclic (restrictRootsOfUnity σ k)
   rw [← restrictRootsOfUnity_coe_apply, hm, ← zpow_mod_orderOf, ← Int.toNat_of_nonneg
       (m.emod_nonneg (Int.coe_nat_ne_zero.mpr (pos_iff_ne_zero.mp (orderOf_pos ζ)))),
-    zpow_coe_nat, rootsOfUnity.coe_pow]
+    zpow_natCast, rootsOfUnity.coe_pow]
   exact ⟨(m % orderOf ζ).toNat, rfl⟩
 #align map_root_of_unity_eq_pow_self map_rootsOfUnity_eq_pow_self
 
@@ -426,9 +426,9 @@ theorem pow_of_coprime (i : ℕ) (hi : i.Coprime k) : IsPrimitiveRoot (ζ ^ i) k
       dvd_of_pow_eq_one := _ }
   intro l hl
   apply h.dvd_of_pow_eq_one
-  rw [← pow_one ζ, ← zpow_coe_nat ζ, ← hi.gcd_eq_one, Nat.gcd_eq_gcd_ab, zpow_add, mul_pow,
-    ← zpow_coe_nat, ← zpow_mul, mul_right_comm]
-  simp only [zpow_mul, hl, h.pow_eq_one, one_zpow, one_pow, one_mul, zpow_coe_nat]
+  rw [← pow_one ζ, ← zpow_natCast ζ, ← hi.gcd_eq_one, Nat.gcd_eq_gcd_ab, zpow_add, mul_pow,
+    ← zpow_natCast, ← zpow_mul, mul_right_comm]
+  simp only [zpow_mul, hl, h.pow_eq_one, one_zpow, one_pow, one_mul, zpow_natCast]
 #align is_primitive_root.pow_of_coprime IsPrimitiveRoot.pow_of_coprime
 
 theorem pow_of_prime (h : IsPrimitiveRoot ζ k) {p : ℕ} (hprime : Nat.Prime p) (hdiv : ¬p ∣ k) :
@@ -578,17 +578,17 @@ section DivisionCommMonoid
 variable {ζ : G}
 
 theorem zpow_eq_one (h : IsPrimitiveRoot ζ k) : ζ ^ (k : ℤ) = 1 := by
-  rw [zpow_coe_nat]; exact h.pow_eq_one
+  rw [zpow_natCast]; exact h.pow_eq_one
 #align is_primitive_root.zpow_eq_one IsPrimitiveRoot.zpow_eq_one
 
 theorem zpow_eq_one_iff_dvd (h : IsPrimitiveRoot ζ k) (l : ℤ) : ζ ^ l = 1 ↔ (k : ℤ) ∣ l := by
   by_cases h0 : 0 ≤ l
-  · lift l to ℕ using h0; rw [zpow_coe_nat]; norm_cast; exact h.pow_eq_one_iff_dvd l
+  · lift l to ℕ using h0; rw [zpow_natCast]; norm_cast; exact h.pow_eq_one_iff_dvd l
   · have : 0 ≤ -l := by simp only [not_le, neg_nonneg] at h0 ⊢; exact le_of_lt h0
     lift -l to ℕ using this with l' hl'
     rw [← dvd_neg, ← hl']
     norm_cast
-    rw [← h.pow_eq_one_iff_dvd, ← inv_inj, ← zpow_neg, ← hl', zpow_coe_nat, inv_one]
+    rw [← h.pow_eq_one_iff_dvd, ← inv_inj, ← zpow_neg, ← hl', zpow_natCast, inv_one]
 #align is_primitive_root.zpow_eq_one_iff_dvd IsPrimitiveRoot.zpow_eq_one_iff_dvd
 
 theorem inv (h : IsPrimitiveRoot ζ k) : IsPrimitiveRoot ζ⁻¹ k :=
@@ -608,11 +608,11 @@ theorem zpow_of_gcd_eq_one (h : IsPrimitiveRoot ζ k) (i : ℤ) (hi : i.gcd k =
     IsPrimitiveRoot (ζ ^ i) k := by
   by_cases h0 : 0 ≤ i
   · lift i to ℕ using h0
-    rw [zpow_coe_nat]
+    rw [zpow_natCast]
     exact h.pow_of_coprime i hi
   have : 0 ≤ -i := by simp only [not_le, neg_nonneg] at h0 ⊢; exact le_of_lt h0
   lift -i to ℕ using this with i' hi'
-  rw [← inv_iff, ← zpow_neg, ← hi', zpow_coe_nat]
+  rw [← inv_iff, ← zpow_neg, ← hi', zpow_natCast]
   apply h.pow_of_coprime
   rw [Int.gcd, ← Int.natAbs_neg, ← hi'] at hi
   exact hi
@@ -715,7 +715,7 @@ def zmodEquivZPowers (h : IsPrimitiveRoot ζ k) : ZMod k ≃+ Additive (Subgroup
         simp only [AddMonoidHom.mem_ker, CharP.int_cast_eq_zero_iff (ZMod k) k, AddMonoidHom.coe_mk,
           Int.coe_castAddHom] at hi ⊢
         obtain ⟨i, rfl⟩ := hi
-        simp [zpow_mul, h.pow_eq_one, one_zpow, zpow_coe_nat]⟩)
+        simp [zpow_mul, h.pow_eq_one, one_zpow, zpow_natCast]⟩)
     (by
       constructor
       · rw [injective_iff_map_eq_zero]
@@ -741,7 +741,7 @@ theorem zmodEquivZPowers_apply_coe_int (i : ℤ) :
 theorem zmodEquivZPowers_apply_coe_nat (i : ℕ) :
     h.zmodEquivZPowers i = Additive.ofMul (⟨ζ ^ i, i, rfl⟩ : Subgroup.zpowers ζ) := by
   have : (i : ZMod k) = (i : ℤ) := by norm_cast
-  simp only [this, zmodEquivZPowers_apply_coe_int, zpow_coe_nat]
+  simp only [this, zmodEquivZPowers_apply_coe_int, zpow_natCast]
 #align is_primitive_root.zmod_equiv_zpowers_apply_coe_nat IsPrimitiveRoot.zmodEquivZPowers_apply_coe_nat
 
 @[simp]
@@ -820,7 +820,7 @@ theorem eq_pow_of_mem_rootsOfUnity {k : ℕ+} {ζ ξ : Rˣ} (h : IsPrimitiveRoot
   lift i to ℕ using hi0 with i₀ hi₀
   refine' ⟨i₀, _, _⟩
   · zify; rw [hi₀]; exact Int.emod_lt_of_pos _ hk0
-  · rw [← zpow_coe_nat, hi₀, ← Int.emod_add_ediv n k, zpow_add, zpow_mul, h.zpow_eq_one, one_zpow,
+  · rw [← zpow_natCast, hi₀, ← Int.emod_add_ediv n k, zpow_add, zpow_mul, h.zpow_eq_one, one_zpow,
       mul_one]
 #align is_primitive_root.eq_pow_of_mem_roots_of_unity IsPrimitiveRoot.eq_pow_of_mem_rootsOfUnity
 
chore(*): remove empty lines between variable statements (#11418)

Empty lines were removed by executing the following Python script twice

import os
import re


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

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

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

      # Write the modified content back to the file
      with open(file_path, 'w') as file:
        file.write(modified_content)
Diff
@@ -71,7 +71,6 @@ open Polynomial
 open Finset
 
 variable {M N G R S F : Type*}
-
 variable [CommMonoid M] [CommMonoid N] [DivisionCommMonoid G]
 
 section rootsOfUnity
@@ -632,7 +631,6 @@ end CommRing
 section IsDomain
 
 variable {ζ : R}
-
 variable [CommRing R] [IsDomain R]
 
 @[simp]
@@ -677,7 +675,6 @@ end IsDomain
 section IsDomain
 
 variable [CommRing R]
-
 variable {ζ : Rˣ} (h : IsPrimitiveRoot ζ k)
 
 theorem eq_neg_one_of_two_right [NoZeroDivisors R] {ζ : R} (h : IsPrimitiveRoot ζ 2) : ζ = -1 := by
fix: correct statement of zpow_ofNat and ofNat_zsmul (#10969)

Previously these were syntactically identical to the corresponding zpow_coe_nat and coe_nat_zsmul lemmas, now they are about OfNat.ofNat.

Unfortunately, almost every call site uses the ofNat name to refer to Nat.cast, so the downstream proofs had to be adjusted too.

Diff
@@ -257,7 +257,7 @@ theorem map_rootsOfUnity_eq_pow_self [FunLike F R R] [RingHomClass F R R] (σ :
   obtain ⟨m, hm⟩ := MonoidHom.map_cyclic (restrictRootsOfUnity σ k)
   rw [← restrictRootsOfUnity_coe_apply, hm, ← zpow_mod_orderOf, ← Int.toNat_of_nonneg
       (m.emod_nonneg (Int.coe_nat_ne_zero.mpr (pos_iff_ne_zero.mp (orderOf_pos ζ)))),
-    zpow_ofNat, rootsOfUnity.coe_pow]
+    zpow_coe_nat, rootsOfUnity.coe_pow]
   exact ⟨(m % orderOf ζ).toNat, rfl⟩
 #align map_root_of_unity_eq_pow_self map_rootsOfUnity_eq_pow_self
 
@@ -427,9 +427,9 @@ theorem pow_of_coprime (i : ℕ) (hi : i.Coprime k) : IsPrimitiveRoot (ζ ^ i) k
       dvd_of_pow_eq_one := _ }
   intro l hl
   apply h.dvd_of_pow_eq_one
-  rw [← pow_one ζ, ← zpow_ofNat ζ, ← hi.gcd_eq_one, Nat.gcd_eq_gcd_ab, zpow_add, mul_pow,
-    ← zpow_ofNat, ← zpow_mul, mul_right_comm]
-  simp only [zpow_mul, hl, h.pow_eq_one, one_zpow, one_pow, one_mul, zpow_ofNat]
+  rw [← pow_one ζ, ← zpow_coe_nat ζ, ← hi.gcd_eq_one, Nat.gcd_eq_gcd_ab, zpow_add, mul_pow,
+    ← zpow_coe_nat, ← zpow_mul, mul_right_comm]
+  simp only [zpow_mul, hl, h.pow_eq_one, one_zpow, one_pow, one_mul, zpow_coe_nat]
 #align is_primitive_root.pow_of_coprime IsPrimitiveRoot.pow_of_coprime
 
 theorem pow_of_prime (h : IsPrimitiveRoot ζ k) {p : ℕ} (hprime : Nat.Prime p) (hdiv : ¬p ∣ k) :
@@ -579,17 +579,17 @@ section DivisionCommMonoid
 variable {ζ : G}
 
 theorem zpow_eq_one (h : IsPrimitiveRoot ζ k) : ζ ^ (k : ℤ) = 1 := by
-  rw [zpow_ofNat]; exact h.pow_eq_one
+  rw [zpow_coe_nat]; exact h.pow_eq_one
 #align is_primitive_root.zpow_eq_one IsPrimitiveRoot.zpow_eq_one
 
 theorem zpow_eq_one_iff_dvd (h : IsPrimitiveRoot ζ k) (l : ℤ) : ζ ^ l = 1 ↔ (k : ℤ) ∣ l := by
   by_cases h0 : 0 ≤ l
-  · lift l to ℕ using h0; rw [zpow_ofNat]; norm_cast; exact h.pow_eq_one_iff_dvd l
+  · lift l to ℕ using h0; rw [zpow_coe_nat]; norm_cast; exact h.pow_eq_one_iff_dvd l
   · have : 0 ≤ -l := by simp only [not_le, neg_nonneg] at h0 ⊢; exact le_of_lt h0
     lift -l to ℕ using this with l' hl'
     rw [← dvd_neg, ← hl']
     norm_cast
-    rw [← h.pow_eq_one_iff_dvd, ← inv_inj, ← zpow_neg, ← hl', zpow_ofNat, inv_one]
+    rw [← h.pow_eq_one_iff_dvd, ← inv_inj, ← zpow_neg, ← hl', zpow_coe_nat, inv_one]
 #align is_primitive_root.zpow_eq_one_iff_dvd IsPrimitiveRoot.zpow_eq_one_iff_dvd
 
 theorem inv (h : IsPrimitiveRoot ζ k) : IsPrimitiveRoot ζ⁻¹ k :=
@@ -609,11 +609,11 @@ theorem zpow_of_gcd_eq_one (h : IsPrimitiveRoot ζ k) (i : ℤ) (hi : i.gcd k =
     IsPrimitiveRoot (ζ ^ i) k := by
   by_cases h0 : 0 ≤ i
   · lift i to ℕ using h0
-    rw [zpow_ofNat]
+    rw [zpow_coe_nat]
     exact h.pow_of_coprime i hi
   have : 0 ≤ -i := by simp only [not_le, neg_nonneg] at h0 ⊢; exact le_of_lt h0
   lift -i to ℕ using this with i' hi'
-  rw [← inv_iff, ← zpow_neg, ← hi', zpow_ofNat]
+  rw [← inv_iff, ← zpow_neg, ← hi', zpow_coe_nat]
   apply h.pow_of_coprime
   rw [Int.gcd, ← Int.natAbs_neg, ← hi'] at hi
   exact hi
@@ -718,7 +718,7 @@ def zmodEquivZPowers (h : IsPrimitiveRoot ζ k) : ZMod k ≃+ Additive (Subgroup
         simp only [AddMonoidHom.mem_ker, CharP.int_cast_eq_zero_iff (ZMod k) k, AddMonoidHom.coe_mk,
           Int.coe_castAddHom] at hi ⊢
         obtain ⟨i, rfl⟩ := hi
-        simp [zpow_mul, h.pow_eq_one, one_zpow, zpow_ofNat]⟩)
+        simp [zpow_mul, h.pow_eq_one, one_zpow, zpow_coe_nat]⟩)
     (by
       constructor
       · rw [injective_iff_map_eq_zero]
@@ -744,7 +744,7 @@ theorem zmodEquivZPowers_apply_coe_int (i : ℤ) :
 theorem zmodEquivZPowers_apply_coe_nat (i : ℕ) :
     h.zmodEquivZPowers i = Additive.ofMul (⟨ζ ^ i, i, rfl⟩ : Subgroup.zpowers ζ) := by
   have : (i : ZMod k) = (i : ℤ) := by norm_cast
-  simp only [this, zmodEquivZPowers_apply_coe_int, zpow_ofNat]
+  simp only [this, zmodEquivZPowers_apply_coe_int, zpow_coe_nat]
 #align is_primitive_root.zmod_equiv_zpowers_apply_coe_nat IsPrimitiveRoot.zmodEquivZPowers_apply_coe_nat
 
 @[simp]
@@ -823,7 +823,7 @@ theorem eq_pow_of_mem_rootsOfUnity {k : ℕ+} {ζ ξ : Rˣ} (h : IsPrimitiveRoot
   lift i to ℕ using hi0 with i₀ hi₀
   refine' ⟨i₀, _, _⟩
   · zify; rw [hi₀]; exact Int.emod_lt_of_pos _ hk0
-  · rw [← zpow_ofNat, hi₀, ← Int.emod_add_ediv n k, zpow_add, zpow_mul, h.zpow_eq_one, one_zpow,
+  · rw [← zpow_coe_nat, hi₀, ← Int.emod_add_ediv n k, zpow_add, zpow_mul, h.zpow_eq_one, one_zpow,
       mul_one]
 #align is_primitive_root.eq_pow_of_mem_roots_of_unity IsPrimitiveRoot.eq_pow_of_mem_rootsOfUnity
 
chore: more backporting of simp changes from #10995 (#11001)

Co-authored-by: Patrick Massot <patrickmassot@free.fr> Co-authored-by: Scott Morrison <scott.morrison@gmail.com>

Diff
@@ -1025,7 +1025,7 @@ noncomputable def autToPow : (S ≃ₐ[R] S) →* (ZMod n)ˣ :=
         dsimp only
         generalize_proofs h1
         have h := h1.choose_spec
-        dsimp only [AlgEquiv.one_apply, AlgEquiv.toRingEquiv_eq_coe, RingEquiv.toRingHom_eq_coe,
+        dsimp only [μ', AlgEquiv.one_apply, AlgEquiv.toRingEquiv_eq_coe, RingEquiv.toRingHom_eq_coe,
           RingEquiv.coe_toRingHom, AlgEquiv.coe_ringEquiv] at *
         replace h : μ' = μ' ^ h1.choose :=
           rootsOfUnity.coe_injective (by simpa only [rootsOfUnity.coe_pow] using h)
@@ -1038,7 +1038,7 @@ noncomputable def autToPow : (S ≃ₐ[R] S) →* (ZMod n)ˣ :=
         have hxy := hxy'.choose_spec
         have hx := hx'.choose_spec
         have hy := hy'.choose_spec
-        dsimp only [AlgEquiv.toRingEquiv_eq_coe, RingEquiv.toRingHom_eq_coe,
+        dsimp only [μ', AlgEquiv.toRingEquiv_eq_coe, RingEquiv.toRingHom_eq_coe,
           RingEquiv.coe_toRingHom, AlgEquiv.coe_ringEquiv, AlgEquiv.mul_apply] at *
         replace hxy : x (((μ' : Sˣ) : S) ^ hy'.choose) = ((μ' : Sˣ) : S) ^ hxy'.choose := hy ▸ hxy
         rw [x.map_pow] at hxy
fix(RingTheory/RootsOfUnity/Basic): generalise some results to monoids (#10605)

These results are all proved for commutative semirings but all work for commutative monoids.

Diff
@@ -134,12 +134,12 @@ theorem rootsOfUnity.coe_pow [CommMonoid R] (ζ : rootsOfUnity k R) (m : ℕ) :
   rw [Subgroup.coe_pow, Units.val_pow_eq_pow_val]
 #align roots_of_unity.coe_pow rootsOfUnity.coe_pow
 
-section CommSemiring
+section CommMonoid
 
-variable [CommSemiring R] [CommSemiring S] [FunLike F R S]
+variable [CommMonoid R] [CommMonoid S] [FunLike F R S]
 
 /-- Restrict a ring homomorphism to the nth roots of unity. -/
-def restrictRootsOfUnity [RingHomClass F R S] (σ : F) (n : ℕ+) :
+def restrictRootsOfUnity [MonoidHomClass F R S] (σ : F) (n : ℕ+) :
     rootsOfUnity n R →* rootsOfUnity n S :=
   let h : ∀ ξ : rootsOfUnity n R, (σ (ξ : Rˣ)) ^ (n : ℕ) = 1 := fun ξ => by
     rw [← map_pow, ← Units.val_pow_eq_pow_val, show (ξ : Rˣ) ^ (n : ℕ) = 1 from ξ.2, Units.val_one,
@@ -152,34 +152,34 @@ def restrictRootsOfUnity [RingHomClass F R S] (σ : F) (n : ℕ+) :
 #align restrict_roots_of_unity restrictRootsOfUnity
 
 @[simp]
-theorem restrictRootsOfUnity_coe_apply [RingHomClass F R S] (σ : F) (ζ : rootsOfUnity k R) :
+theorem restrictRootsOfUnity_coe_apply [MonoidHomClass F R S] (σ : F) (ζ : rootsOfUnity k R) :
     (restrictRootsOfUnity σ k ζ : Sˣ) = σ (ζ : Rˣ) :=
   rfl
 #align restrict_roots_of_unity_coe_apply restrictRootsOfUnity_coe_apply
 
-/-- Restrict a ring isomorphism to the nth roots of unity. -/
-nonrec def RingEquiv.restrictRootsOfUnity (σ : R ≃+* S) (n : ℕ+) :
+/-- Restrict a monoid isomorphism to the nth roots of unity. -/
+nonrec def MulEquiv.restrictRootsOfUnity (σ : R ≃* S) (n : ℕ+) :
     rootsOfUnity n R ≃* rootsOfUnity n S where
-  toFun := restrictRootsOfUnity σ.toRingHom n
-  invFun := restrictRootsOfUnity σ.symm.toRingHom n
+  toFun := restrictRootsOfUnity σ n
+  invFun := restrictRootsOfUnity σ.symm n
   left_inv ξ := by ext; exact σ.symm_apply_apply (ξ : Rˣ)
   right_inv ξ := by ext; exact σ.apply_symm_apply (ξ : Sˣ)
   map_mul' := (restrictRootsOfUnity _ n).map_mul
-#align ring_equiv.restrict_roots_of_unity RingEquiv.restrictRootsOfUnity
+#align ring_equiv.restrict_roots_of_unity MulEquiv.restrictRootsOfUnity
 
 @[simp]
-theorem RingEquiv.restrictRootsOfUnity_coe_apply (σ : R ≃+* S) (ζ : rootsOfUnity k R) :
+theorem MulEquiv.restrictRootsOfUnity_coe_apply (σ : R ≃* S) (ζ : rootsOfUnity k R) :
     (σ.restrictRootsOfUnity k ζ : Sˣ) = σ (ζ : Rˣ) :=
   rfl
-#align ring_equiv.restrict_roots_of_unity_coe_apply RingEquiv.restrictRootsOfUnity_coe_apply
+#align ring_equiv.restrict_roots_of_unity_coe_apply MulEquiv.restrictRootsOfUnity_coe_apply
 
 @[simp]
-theorem RingEquiv.restrictRootsOfUnity_symm (σ : R ≃+* S) :
+theorem MulEquiv.restrictRootsOfUnity_symm (σ : R ≃* S) :
     (σ.restrictRootsOfUnity k).symm = σ.symm.restrictRootsOfUnity k :=
   rfl
-#align ring_equiv.restrict_roots_of_unity_symm RingEquiv.restrictRootsOfUnity_symm
+#align ring_equiv.restrict_roots_of_unity_symm MulEquiv.restrictRootsOfUnity_symm
 
-end CommSemiring
+end CommMonoid
 
 section IsDomain
 
feat(LinearAlgebra/Matrix): center of special linear group (#7826)

The center of a special linear group of degree n is a subgroup composed of scalar matrices, in which the scalars are the n-th roots of 1. Co-authored-by: Oliver Nash <[github@olivernash.org](mailto:github@olivernash.org)>

Co-authored-by: Eric Wieser <wieser.eric@gmail.com> Co-authored-by: Mario Carneiro <di.gama@gmail.com>

Diff
@@ -95,6 +95,9 @@ theorem mem_rootsOfUnity' (k : ℕ+) (ζ : Mˣ) : ζ ∈ rootsOfUnity k M ↔ (
   rw [mem_rootsOfUnity]; norm_cast
 #align mem_roots_of_unity' mem_rootsOfUnity'
 
+@[simp]
+theorem rootsOfUnity_one (M : Type*) [CommMonoid M] : rootsOfUnity 1 M = ⊥ := by ext; simp
+
 theorem rootsOfUnity.coe_injective {n : ℕ+} :
     Function.Injective (fun x : rootsOfUnity n M ↦ x.val.val) :=
   Units.ext.comp fun _ _ => Subtype.eq
refactor(Data/FunLike): use unbundled inheritance from FunLike (#8386)

The FunLike hierarchy is very big and gets scanned through each time we need a coercion (via the CoeFun instance). It looks like unbundled inheritance suits Lean 4 better here. The only class that still extends FunLike is EquivLike, since that has a custom coe_injective' field that is easier to implement. All other classes should take FunLike or EquivLike as a parameter.

Zulip thread

Important changes

Previously, morphism classes would be Type-valued and extend FunLike:

/-- `MyHomClass F A B` states that `F` is a type of `MyClass.op`-preserving morphisms.
You should extend this class when you extend `MyHom`. -/
class MyHomClass (F : Type*) (A B : outParam <| Type*) [MyClass A] [MyClass B]
  extends FunLike F A B :=
(map_op : ∀ (f : F) (x y : A), f (MyClass.op x y) = MyClass.op (f x) (f y))

After this PR, they should be Prop-valued and take FunLike as a parameter:

/-- `MyHomClass F A B` states that `F` is a type of `MyClass.op`-preserving morphisms.
You should extend this class when you extend `MyHom`. -/
class MyHomClass (F : Type*) (A B : outParam <| Type*) [MyClass A] [MyClass B]
  [FunLike F A B] : Prop :=
(map_op : ∀ (f : F) (x y : A), f (MyClass.op x y) = MyClass.op (f x) (f y))

(Note that A B stay marked as outParam even though they are not purely required to be so due to the FunLike parameter already filling them in. This is required to see through type synonyms, which is important in the category theory library. Also, I think keeping them as outParam is slightly faster.)

Similarly, MyEquivClass should take EquivLike as a parameter.

As a result, every mention of [MyHomClass F A B] should become [FunLike F A B] [MyHomClass F A B].

Remaining issues

Slower (failing) search

While overall this gives some great speedups, there are some cases that are noticeably slower. In particular, a failing application of a lemma such as map_mul is more expensive. This is due to suboptimal processing of arguments. For example:

variable [FunLike F M N] [Mul M] [Mul N] (f : F) (x : M) (y : M)

theorem map_mul [MulHomClass F M N] : f (x * y) = f x * f y

example [AddHomClass F A B] : f (x * y) = f x * f y := map_mul f _ _

Before this PR, applying map_mul f gives the goals [Mul ?M] [Mul ?N] [MulHomClass F ?M ?N]. Since M and N are out_params, [MulHomClass F ?M ?N] is synthesized first, supplies values for ?M and ?N and then the Mul M and Mul N instances can be found.

After this PR, the goals become [FunLike F ?M ?N] [Mul ?M] [Mul ?N] [MulHomClass F ?M ?N]. Now [FunLike F ?M ?N] is synthesized first, supplies values for ?M and ?N and then the Mul M and Mul N instances can be found, before trying MulHomClass F M N which fails. Since the Mul hierarchy is very big, this can be slow to fail, especially when there is no such Mul instance.

A long-term but harder to achieve solution would be to specify the order in which instance goals get solved. For example, we'd like to change the arguments to map_mul to look like [FunLike F M N] [Mul M] [Mul N] [highPriority <| MulHomClass F M N] because MulHomClass fails or succeeds much faster than the others.

As a consequence, the simpNF linter is much slower since by design it tries and fails to apply many map_ lemmas. The same issue occurs a few times in existing calls to simp [map_mul], where map_mul is tried "too soon" and fails. Thanks to the speedup of leanprover/lean4#2478 the impact is very limited, only in files that already were close to the timeout.

simp not firing sometimes

This affects map_smulₛₗ and related definitions. For simp lemmas Lean apparently uses a slightly different mechanism to find instances, so that rw can find every argument to map_smulₛₗ successfully but simp can't: leanprover/lean4#3701.

Missing instances due to unification failing

Especially in the category theory library, we might sometimes have a type A which is also accessible as a synonym (Bundled A hA).1. Instance synthesis doesn't always work if we have f : A →* B but x * y : (Bundled A hA).1 or vice versa. This seems to be mostly fixed by keeping A B as outParams in MulHomClass F A B. (Presumably because Lean will do a definitional check A =?= (Bundled A hA).1 instead of using the syntax in the discrimination tree.)

Workaround for issues

The timeouts can be worked around for now by specifying which map_mul we mean, either as map_mul f for some explicit f, or as e.g. MonoidHomClass.map_mul.

map_smulₛₗ not firing as simp lemma can be worked around by going back to the pre-FunLike situation and making LinearMap.map_smulₛₗ a simp lemma instead of the generic map_smulₛₗ. Writing simp [map_smulₛₗ _] also works.

Co-authored-by: Matthew Ballard <matt@mrb.email> Co-authored-by: Scott Morrison <scott.morrison@gmail.com> Co-authored-by: Scott Morrison <scott@tqft.net> Co-authored-by: Anne Baanen <Vierkantor@users.noreply.github.com>

Diff
@@ -133,7 +133,7 @@ theorem rootsOfUnity.coe_pow [CommMonoid R] (ζ : rootsOfUnity k R) (m : ℕ) :
 
 section CommSemiring
 
-variable [CommSemiring R] [CommSemiring S]
+variable [CommSemiring R] [CommSemiring S] [FunLike F R S]
 
 /-- Restrict a ring homomorphism to the nth roots of unity. -/
 def restrictRootsOfUnity [RingHomClass F R S] (σ : F) (n : ℕ+) :
@@ -248,7 +248,8 @@ theorem card_rootsOfUnity : Fintype.card (rootsOfUnity k R) ≤ k :=
 
 variable {k R}
 
-theorem map_rootsOfUnity_eq_pow_self [RingHomClass F R R] (σ : F) (ζ : rootsOfUnity k R) :
+theorem map_rootsOfUnity_eq_pow_self [FunLike F R R] [RingHomClass F R R] (σ : F)
+    (ζ : rootsOfUnity k R) :
     ∃ m : ℕ, σ (ζ : Rˣ) = ((ζ : Rˣ) : R) ^ m := by
   obtain ⟨m, hm⟩ := MonoidHom.map_cyclic (restrictRootsOfUnity σ k)
   rw [← restrictRootsOfUnity_coe_apply, hm, ← zpow_mod_orderOf, ← Int.toNat_of_nonneg
@@ -512,6 +513,8 @@ section Maps
 
 open Function
 
+variable [FunLike F M N]
+
 theorem map_of_injective [MonoidHomClass F M N] (h : IsPrimitiveRoot ζ k) (hf : Injective f) :
     IsPrimitiveRoot (f ζ) k where
   pow_eq_one := by rw [← map_pow, h.pow_eq_one, _root_.map_one]
@@ -779,7 +782,7 @@ theorem zpowers_eq {k : ℕ+} {ζ : Rˣ} (h : IsPrimitiveRoot ζ k) :
     _ = Fintype.card (Subgroup.zpowers ζ) := Fintype.card_congr h.zmodEquivZPowers.toEquiv
 #align is_primitive_root.zpowers_eq IsPrimitiveRoot.zpowers_eq
 
-lemma map_rootsOfUnity {S F} [CommRing S] [IsDomain S] [MonoidHomClass F R S]
+lemma map_rootsOfUnity {S F} [CommRing S] [IsDomain S] [FunLike F R S] [MonoidHomClass F R S]
     {ζ : R} {n : ℕ+} (hζ : IsPrimitiveRoot ζ n) {f : F} (hf : Function.Injective f) :
     (rootsOfUnity n R).map (Units.map f) = rootsOfUnity n S := by
   letI : CommMonoid Sˣ := inferInstance
@@ -793,14 +796,15 @@ then the `n`-th roots of unity in `R` and `S` are isomorphic.
 Also see `IsPrimitiveRoot.map_rootsOfUnity` for the equality as `Subgroup Sˣ`. -/
 @[simps! (config := .lemmasOnly) apply_coe_val apply_coe_inv_val]
 noncomputable
-def _root_.rootsOfUnityEquivOfPrimitiveRoots {S F} [CommRing S] [IsDomain S] [MonoidHomClass F R S]
+def _root_.rootsOfUnityEquivOfPrimitiveRoots {S F} [CommRing S] [IsDomain S]
+    [FunLike F R S] [MonoidHomClass F R S]
     {n : ℕ+} {f : F} (hf : Function.Injective f) (hζ : (primitiveRoots n R).Nonempty) :
     (rootsOfUnity n R) ≃* rootsOfUnity n S :=
   (Subgroup.equivMapOfInjective _ _ (Units.map_injective hf)).trans (MulEquiv.subgroupCongr
     (((mem_primitiveRoots (k := n) n.2).mp hζ.choose_spec).map_rootsOfUnity hf))
 
 lemma _root_.rootsOfUnityEquivOfPrimitiveRoots_symm_apply
-    {S F} [CommRing S] [IsDomain S] [MonoidHomClass F R S]
+    {S F} [CommRing S] [IsDomain S] [FunLike F R S] [MonoidHomClass F R S]
     {n : ℕ+} {f : F} (hf : Function.Injective f) (hζ : (primitiveRoots n R).Nonempty) (η) :
     f ((rootsOfUnityEquivOfPrimitiveRoots hf hζ).symm η : Rˣ) = (η : Sˣ) := by
   obtain ⟨ε, rfl⟩ := (rootsOfUnityEquivOfPrimitiveRoots hf hζ).surjective η
refactor: generalize CharP+Prime to ExpChar in frobenius (#10016)

Consequently, the part about frobenius in Algebra/CharP/Basic is moved to CharP/ExpChar, and imports are adjusted as necessary.

  • Add instances from CharP+Fact(Nat.Prime) and CharZero to ExpChar, to allow lemmas generalized to ExpChar still apply to CharP.

  • Remove lemmas in Algebra/CharP/ExpChar from [#9799](https://github.com/leanprover-community/mathlib4/commit/1e74fcfff8d5ffe5a3a9881864cf10fa39f619e6) because they coincide with the generalized lemmas, and golf the other lemmas (in Algebra/CharP/Basic).

  • Define the RingHom iterateFrobenius and the semilinear map LinearMap.(iterate)Frobenius for an algebra. When the characteristic is zero (ExpChar is 1), these are all equal to the identity map (· ^ 1). Also define iterateFrobeniusEquiv for perfect rings.

  • Fix and/or generalize other files.

Co-authored-by: Junyan Xu <junyanxu.math@gmail.com> Co-authored-by: acmepjz <acme_pjz@hotmail.com>

Diff
@@ -264,16 +264,16 @@ section Reduced
 variable (R) [CommRing R] [IsReduced R]
 
 -- @[simp] -- Porting note: simp normal form is `mem_rootsOfUnity_prime_pow_mul_iff'`
-theorem mem_rootsOfUnity_prime_pow_mul_iff (p k : ℕ) (m : ℕ+) [hp : Fact p.Prime] [CharP R p]
-    {ζ : Rˣ} : ζ ∈ rootsOfUnity (⟨p, hp.1.pos⟩ ^ k * m) R ↔ ζ ∈ rootsOfUnity m R := by
+theorem mem_rootsOfUnity_prime_pow_mul_iff (p k : ℕ) (m : ℕ+) [ExpChar R p]
+    {ζ : Rˣ} : ζ ∈ rootsOfUnity (⟨p, expChar_pos R p⟩ ^ k * m) R ↔ ζ ∈ rootsOfUnity m R := by
   simp only [mem_rootsOfUnity', PNat.mul_coe, PNat.pow_coe, PNat.mk_coe,
-    CharP.pow_prime_pow_mul_eq_one_iff]
+    ExpChar.pow_prime_pow_mul_eq_one_iff]
 #align mem_roots_of_unity_prime_pow_mul_iff mem_rootsOfUnity_prime_pow_mul_iff
 
 @[simp]
-theorem mem_rootsOfUnity_prime_pow_mul_iff' (p k : ℕ) (m : ℕ+) [hp : Fact p.Prime] [CharP R p]
+theorem mem_rootsOfUnity_prime_pow_mul_iff' (p k : ℕ) (m : ℕ+) [ExpChar R p]
     {ζ : Rˣ} : ζ ^ (p ^ k * ↑m) = 1 ↔ ζ ∈ rootsOfUnity m R := by
-  rw [← PNat.mk_coe p hp.1.pos, ← PNat.pow_coe, ← PNat.mul_coe, ← mem_rootsOfUnity,
+  rw [← PNat.mk_coe p (expChar_pos R p), ← PNat.pow_coe, ← PNat.mul_coe, ← mem_rootsOfUnity,
     mem_rootsOfUnity_prime_pow_mul_iff]
 
 end Reduced
feat: The support of f ^ n (#9617)

This involves moving lemmas from Algebra.GroupPower.Ring to Algebra.GroupWithZero.Basic and changing some 0 < n assumptions to n ≠ 0.

From LeanAPAP

Diff
@@ -856,7 +856,7 @@ theorem nthRoots_eq {n : ℕ} {ζ : R} (hζ : IsPrimitiveRoot ζ n)
     nthRoots n a = (Multiset.range n).map (ζ ^ · * α) := by
   obtain (rfl|hn) := n.eq_zero_or_pos; · simp
   by_cases hα : α = 0
-  · rw [hα, zero_pow hn] at e
+  · rw [hα, zero_pow hn.ne'] at e
     simp only [hα, e.symm, nthRoots_zero_right, mul_zero,
       Finset.range_val, Multiset.map_const', Multiset.card_range]
   classical
@@ -910,7 +910,7 @@ theorem nthRoots_nodup {ζ : R} {n : ℕ} (h : IsPrimitiveRoot ζ n) {a : R} (ha
   by_cases h : ∃ α, α ^ n = a
   · obtain ⟨α, hα⟩ := h
     by_cases hα' : α = 0
-    · exact (ha (by rwa [hα', zero_pow hn, eq_comm] at hα)).elim
+    · exact (ha (by rwa [hα', zero_pow hn.ne', eq_comm] at hα)).elim
     rw [nthRoots_eq h hα, Multiset.nodup_map_iff_inj_on (Multiset.nodup_range n)]
     exact h.injOn_pow_mul hα'
   · suffices nthRoots n a = 0 by simp [this]
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,11 +4,9 @@ Released under Apache 2.0 license as described in the file LICENSE.
 Authors: Johan Commelin
 -/
 import Mathlib.Algebra.CharP.Two
+import Mathlib.Algebra.CharP.Reduced
 import Mathlib.Algebra.NeZero
-import Mathlib.Algebra.GCDMonoid.IntegrallyClosed
 import Mathlib.Data.Polynomial.RingDivision
-import Mathlib.FieldTheory.Finite.Basic
-import Mathlib.FieldTheory.Separable
 import Mathlib.GroupTheory.SpecificGroups.Cyclic
 import Mathlib.NumberTheory.Divisors
 import Mathlib.RingTheory.IntegralDomain
feat: Kummer extensions are cyclic. (#9119)

Co-authored-by: Andrew Yang <36414270+erdOne@users.noreply.github.com>

Diff
@@ -407,6 +407,12 @@ theorem coe_units_iff {ζ : Mˣ} : IsPrimitiveRoot (ζ : M) k ↔ IsPrimitiveRoo
   simp only [iff_def, Units.ext_iff, Units.val_pow_eq_pow_val, Units.val_one]
 #align is_primitive_root.coe_units_iff IsPrimitiveRoot.coe_units_iff
 
+lemma isUnit_unit {ζ : M} {n} (hn) (hζ : IsPrimitiveRoot ζ n) :
+    IsPrimitiveRoot (hζ.isUnit hn).unit n := coe_units_iff.mp hζ
+
+lemma isUnit_unit' {ζ : G} {n} (hn) (hζ : IsPrimitiveRoot ζ n) :
+    IsPrimitiveRoot (hζ.isUnit hn).unit' n := coe_units_iff.mp hζ
+
 -- Porting note `variable` above already contains `(h : IsPrimitiveRoot ζ k)`
 theorem pow_of_coprime (i : ℕ) (hi : i.Coprime k) : IsPrimitiveRoot (ζ ^ i) k := by
   by_cases h0 : k = 0
@@ -494,6 +500,16 @@ theorem pow {n : ℕ} {a b : ℕ} (hn : 0 < n) (h : IsPrimitiveRoot ζ n) (hprod
   exact h.dvd_of_pow_eq_one _ hl
 #align is_primitive_root.pow IsPrimitiveRoot.pow
 
+lemma injOn_pow {n : ℕ} {ζ : M} (hζ : IsPrimitiveRoot ζ n) :
+    Set.InjOn (ζ ^ ·) (Finset.range n) := by
+  obtain (rfl|hn) := n.eq_zero_or_pos; · simp
+  intros i hi j hj e
+  rw [Finset.coe_range, Set.mem_Iio] at hi hj
+  have : (hζ.isUnit hn).unit ^ i = (hζ.isUnit hn).unit ^ j := Units.ext (by simpa using e)
+  rw [pow_inj_mod, ← orderOf_injective ⟨⟨Units.val, Units.val_one⟩, Units.val_mul⟩
+    Units.ext (hζ.isUnit hn).unit] at this
+  simpa [← hζ.eq_orderOf, Nat.mod_eq_of_lt, hi, hj] using this
+
 section Maps
 
 open Function
@@ -543,6 +559,17 @@ protected theorem ne_zero [Nontrivial M₀] {ζ : M₀} (h : IsPrimitiveRoot ζ
 
 end CommMonoidWithZero
 
+section CancelCommMonoidWithZero
+
+variable {M₀ : Type*} [CancelCommMonoidWithZero M₀]
+
+lemma injOn_pow_mul {n : ℕ} {ζ : M₀} (hζ : IsPrimitiveRoot ζ n)
+    {α : M₀} (hα : α ≠ 0) :
+    Set.InjOn (ζ ^ · * α) (Finset.range n) := fun i hi j hj e ↦
+  hζ.injOn_pow hi hj (by simpa [mul_eq_mul_right_iff, or_iff_left hα] using e)
+
+end CancelCommMonoidWithZero
+
 section DivisionCommMonoid
 
 variable {ζ : G}
@@ -754,6 +781,33 @@ theorem zpowers_eq {k : ℕ+} {ζ : Rˣ} (h : IsPrimitiveRoot ζ k) :
     _ = Fintype.card (Subgroup.zpowers ζ) := Fintype.card_congr h.zmodEquivZPowers.toEquiv
 #align is_primitive_root.zpowers_eq IsPrimitiveRoot.zpowers_eq
 
+lemma map_rootsOfUnity {S F} [CommRing S] [IsDomain S] [MonoidHomClass F R S]
+    {ζ : R} {n : ℕ+} (hζ : IsPrimitiveRoot ζ n) {f : F} (hf : Function.Injective f) :
+    (rootsOfUnity n R).map (Units.map f) = rootsOfUnity n S := by
+  letI : CommMonoid Sˣ := inferInstance
+  replace hζ := hζ.isUnit_unit n.2
+  rw [← hζ.zpowers_eq,
+    ← (hζ.map_of_injective (Units.map_injective (f := (f : R →* S)) hf)).zpowers_eq,
+    MonoidHom.map_zpowers]
+
+/-- If `R` contains a `n`-th primitive root, and `S/R` is a ring extension,
+then the `n`-th roots of unity in `R` and `S` are isomorphic.
+Also see `IsPrimitiveRoot.map_rootsOfUnity` for the equality as `Subgroup Sˣ`. -/
+@[simps! (config := .lemmasOnly) apply_coe_val apply_coe_inv_val]
+noncomputable
+def _root_.rootsOfUnityEquivOfPrimitiveRoots {S F} [CommRing S] [IsDomain S] [MonoidHomClass F R S]
+    {n : ℕ+} {f : F} (hf : Function.Injective f) (hζ : (primitiveRoots n R).Nonempty) :
+    (rootsOfUnity n R) ≃* rootsOfUnity n S :=
+  (Subgroup.equivMapOfInjective _ _ (Units.map_injective hf)).trans (MulEquiv.subgroupCongr
+    (((mem_primitiveRoots (k := n) n.2).mp hζ.choose_spec).map_rootsOfUnity hf))
+
+lemma _root_.rootsOfUnityEquivOfPrimitiveRoots_symm_apply
+    {S F} [CommRing S] [IsDomain S] [MonoidHomClass F R S]
+    {n : ℕ+} {f : F} (hf : Function.Injective f) (hζ : (primitiveRoots n R).Nonempty) (η) :
+    f ((rootsOfUnityEquivOfPrimitiveRoots hf hζ).symm η : Rˣ) = (η : Sˣ) := by
+  obtain ⟨ε, rfl⟩ := (rootsOfUnityEquivOfPrimitiveRoots hf hζ).surjective η
+  rw [MulEquiv.symm_apply_apply, val_rootsOfUnityEquivOfPrimitiveRoots_apply_coe]
+
 -- Porting note: rephrased the next few lemmas to avoid `∃ (Prop)`
 theorem eq_pow_of_mem_rootsOfUnity {k : ℕ+} {ζ ξ : Rˣ} (h : IsPrimitiveRoot ζ k)
     (hξ : ξ ∈ rootsOfUnity k R) : ∃ (i : ℕ), i < k ∧ ζ ^ i = ξ := by
@@ -799,6 +853,35 @@ theorem isPrimitiveRoot_iff {k : ℕ} {ζ ξ : R} (h : IsPrimitiveRoot ζ k) (h0
   · rintro ⟨i, -, hi, rfl⟩; exact h.pow_of_coprime i hi
 #align is_primitive_root.is_primitive_root_iff IsPrimitiveRoot.isPrimitiveRoot_iff
 
+theorem nthRoots_eq {n : ℕ} {ζ : R} (hζ : IsPrimitiveRoot ζ n)
+    {α a : R} (e : α ^ n = a) :
+    nthRoots n a = (Multiset.range n).map (ζ ^ · * α) := by
+  obtain (rfl|hn) := n.eq_zero_or_pos; · simp
+  by_cases hα : α = 0
+  · rw [hα, zero_pow hn] at e
+    simp only [hα, e.symm, nthRoots_zero_right, mul_zero,
+      Finset.range_val, Multiset.map_const', Multiset.card_range]
+  classical
+  symm; apply Multiset.eq_of_le_of_card_le
+  · rw [← Finset.range_val,
+      ← Finset.image_val_of_injOn (hζ.injOn_pow_mul hα), Finset.val_le_iff_val_subset]
+    intro x hx
+    simp only [Finset.image_val, Finset.range_val, Multiset.mem_dedup, Multiset.mem_map,
+      Multiset.mem_range] at hx
+    obtain ⟨m, _, rfl⟩ := hx
+    rw [mem_nthRoots hn, mul_pow, e, ← pow_mul, mul_comm m,
+      pow_mul, hζ.pow_eq_one, one_pow, one_mul]
+  · simpa only [Multiset.card_map, Multiset.card_range] using card_nthRoots n a
+
+theorem card_nthRoots {n : ℕ} {ζ : R} (hζ : IsPrimitiveRoot ζ n) (a : R) :
+    Multiset.card (nthRoots n a) = if ∃ α, α ^ n = a then n else 0 := by
+  split_ifs with h
+  · obtain ⟨α, hα⟩ := h
+    rw [nthRoots_eq hζ hα, Multiset.card_map, Multiset.card_range]
+  · obtain (rfl|hn) := n.eq_zero_or_pos; · simp
+    push_neg at h
+    simpa only [Multiset.card_eq_zero, Multiset.eq_zero_iff_forall_not_mem, mem_nthRoots hn]
+
 theorem card_rootsOfUnity' {n : ℕ+} (h : IsPrimitiveRoot ζ n) :
     Fintype.card (rootsOfUnity n R) = n := by
   let e := h.zmodEquivZPowers
@@ -819,51 +902,34 @@ theorem card_rootsOfUnity {ζ : R} {n : ℕ+} (h : IsPrimitiveRoot ζ n) :
 
 /-- The cardinality of the multiset `nthRoots ↑n (1 : R)` is `n`
 if there is a primitive root of unity in `R`. -/
-nonrec theorem card_nthRoots {ζ : R} {n : ℕ} (h : IsPrimitiveRoot ζ n) :
-    Multiset.card (nthRoots n (1 : R)) = n := by
-  rcases Nat.eq_zero_or_pos n with hzero | hpos
-  · simp only [hzero, Multiset.card_zero, nthRoots_zero]
-  rw [eq_iff_le_not_lt]
-  use card_nthRoots n 1
-  · rw [not_lt]
-    have hcard :
-        Fintype.card { x // x ∈ nthRoots n (1 : R) } ≤ Multiset.card (nthRoots n (1 : R)).attach :=
-      Multiset.card_le_card (Multiset.dedup_le _)
-    rw [Multiset.card_attach] at hcard
-    rw [← PNat.toPNat'_coe hpos] at hcard h ⊢
-    set m := Nat.toPNat' n
-    rw [← Fintype.card_congr (rootsOfUnityEquivNthRoots R m), card_rootsOfUnity h] at hcard
-    exact hcard
-#align is_primitive_root.card_nth_roots IsPrimitiveRoot.card_nthRoots
+theorem card_nthRoots_one {ζ : R} {n : ℕ} (h : IsPrimitiveRoot ζ n) :
+    Multiset.card (nthRoots n (1 : R)) = n := by rw [card_nthRoots h, if_pos ⟨ζ, h.pow_eq_one⟩]
+#align is_primitive_root.card_nth_roots IsPrimitiveRoot.card_nthRoots_one
+
+theorem nthRoots_nodup {ζ : R} {n : ℕ} (h : IsPrimitiveRoot ζ n) {a : R} (ha : a ≠ 0) :
+    (nthRoots n a).Nodup := by
+  obtain (rfl|hn) := n.eq_zero_or_pos; · simp
+  by_cases h : ∃ α, α ^ n = a
+  · obtain ⟨α, hα⟩ := h
+    by_cases hα' : α = 0
+    · exact (ha (by rwa [hα', zero_pow hn, eq_comm] at hα)).elim
+    rw [nthRoots_eq h hα, Multiset.nodup_map_iff_inj_on (Multiset.nodup_range n)]
+    exact h.injOn_pow_mul hα'
+  · suffices nthRoots n a = 0 by simp [this]
+    push_neg at h
+    simpa only [Multiset.card_eq_zero, Multiset.eq_zero_iff_forall_not_mem, mem_nthRoots hn]
 
 /-- The multiset `nthRoots ↑n (1 : R)` has no repeated elements
 if there is a primitive root of unity in `R`. -/
-theorem nthRoots_nodup {ζ : R} {n : ℕ} (h : IsPrimitiveRoot ζ n) : (nthRoots n (1 : R)).Nodup := by
-  rcases Nat.eq_zero_or_pos n with hzero | hpos
-  · simp only [hzero, Multiset.nodup_zero, nthRoots_zero]
-  apply (Multiset.dedup_eq_self (α := R)).1
-  rw [eq_iff_le_not_lt]
-  constructor
-  · exact Multiset.dedup_le (nthRoots n (1 : R))
-  · by_contra ha
-    replace ha := Multiset.card_lt_card ha
-    rw [card_nthRoots h] at ha
-    have hrw : Multiset.card (nthRoots n (1 : R)).dedup =
-        Fintype.card { x // x ∈ nthRoots n (1 : R) } := by
-      set fs := (⟨(nthRoots n (1 : R)).dedup, Multiset.nodup_dedup _⟩ : Finset R)
-      rw [← Finset.card_mk, Fintype.card_of_subtype fs _]
-      intro x
-      simp only [Multiset.mem_dedup, Finset.mem_mk]
-    rw [← PNat.toPNat'_coe hpos] at h hrw ha
-    set m := Nat.toPNat' n
-    rw [hrw, ← Fintype.card_congr (rootsOfUnityEquivNthRoots R m), card_rootsOfUnity h] at ha
-    exact Nat.lt_asymm ha ha
-#align is_primitive_root.nth_roots_nodup IsPrimitiveRoot.nthRoots_nodup
+theorem nthRoots_one_nodup {ζ : R} {n : ℕ} (h : IsPrimitiveRoot ζ n) :
+    (nthRoots n (1 : R)).Nodup :=
+  h.nthRoots_nodup one_ne_zero
+#align is_primitive_root.nth_roots_nodup IsPrimitiveRoot.nthRoots_one_nodup
 
 @[simp]
 theorem card_nthRootsFinset {ζ : R} {n : ℕ} (h : IsPrimitiveRoot ζ n) :
     (nthRootsFinset n R).card = n := by
-  rw [nthRootsFinset, ← Multiset.toFinset_eq (nthRoots_nodup h), card_mk, h.card_nthRoots]
+  rw [nthRootsFinset, ← Multiset.toFinset_eq (nthRoots_one_nodup h), card_mk, h.card_nthRoots_one]
 #align is_primitive_root.card_nth_roots_finset IsPrimitiveRoot.card_nthRootsFinset
 
 open scoped Nat
@@ -905,7 +971,7 @@ theorem nthRoots_one_eq_biUnion_primitiveRoots' {ζ : R} {n : ℕ+} (h : IsPrimi
   symm
   apply Finset.eq_of_subset_of_card_le
   · intro x
-    simp only [nthRootsFinset, ← Multiset.toFinset_eq (nthRoots_nodup h), exists_prop,
+    simp only [nthRootsFinset, ← Multiset.toFinset_eq (nthRoots_one_nodup h), exists_prop,
       Finset.mem_biUnion, Finset.mem_filter, Finset.mem_range, mem_nthRoots, Finset.mem_mk,
       Nat.mem_divisors, and_true_iff, Ne.def, PNat.ne_zero, PNat.pos, not_false_iff]
     rintro ⟨a, ⟨d, hd⟩, ha⟩
chore: Improve Finset lemma names (#8894)

Change a few lemma names that have historically bothered me.

  • Finset.card_le_of_subsetFinset.card_le_card
  • Multiset.card_le_of_leMultiset.card_le_card
  • Multiset.card_lt_of_ltMultiset.card_lt_card
  • Set.ncard_le_of_subsetSet.ncard_le_ncard
  • Finset.image_filterFinset.filter_image
  • CompleteLattice.finset_sup_compact_of_compactCompleteLattice.isCompactElement_finset_sup
Diff
@@ -243,7 +243,7 @@ theorem card_rootsOfUnity : Fintype.card (rootsOfUnity k R) ≤ k :=
   calc
     Fintype.card (rootsOfUnity k R) = Fintype.card { x // x ∈ nthRoots k (1 : R) } :=
       Fintype.card_congr (rootsOfUnityEquivNthRoots R k)
-    _ ≤ Multiset.card (nthRoots k (1 : R)).attach := (Multiset.card_le_of_le (Multiset.dedup_le _))
+    _ ≤ Multiset.card (nthRoots k (1 : R)).attach := (Multiset.card_le_card (Multiset.dedup_le _))
     _ = Multiset.card (nthRoots k (1 : R)) := Multiset.card_attach
     _ ≤ k := card_nthRoots k 1
 #align card_roots_of_unity card_rootsOfUnity
@@ -828,7 +828,7 @@ nonrec theorem card_nthRoots {ζ : R} {n : ℕ} (h : IsPrimitiveRoot ζ n) :
   · rw [not_lt]
     have hcard :
         Fintype.card { x // x ∈ nthRoots n (1 : R) } ≤ Multiset.card (nthRoots n (1 : R)).attach :=
-      Multiset.card_le_of_le (Multiset.dedup_le _)
+      Multiset.card_le_card (Multiset.dedup_le _)
     rw [Multiset.card_attach] at hcard
     rw [← PNat.toPNat'_coe hpos] at hcard h ⊢
     set m := Nat.toPNat' n
@@ -846,7 +846,7 @@ theorem nthRoots_nodup {ζ : R} {n : ℕ} (h : IsPrimitiveRoot ζ n) : (nthRoots
   constructor
   · exact Multiset.dedup_le (nthRoots n (1 : R))
   · by_contra ha
-    replace ha := Multiset.card_lt_of_lt ha
+    replace ha := Multiset.card_lt_card ha
     rw [card_nthRoots h] at ha
     have hrw : Multiset.card (nthRoots n (1 : R)).dedup =
         Fintype.card { x // x ∈ nthRoots n (1 : R) } := by
chore: remove uses of cases' (#9171)

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

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

Diff
@@ -821,7 +821,7 @@ theorem card_rootsOfUnity {ζ : R} {n : ℕ+} (h : IsPrimitiveRoot ζ n) :
 if there is a primitive root of unity in `R`. -/
 nonrec theorem card_nthRoots {ζ : R} {n : ℕ} (h : IsPrimitiveRoot ζ n) :
     Multiset.card (nthRoots n (1 : R)) = n := by
-  cases' Nat.eq_zero_or_pos n with hzero hpos
+  rcases Nat.eq_zero_or_pos n with hzero | hpos
   · simp only [hzero, Multiset.card_zero, nthRoots_zero]
   rw [eq_iff_le_not_lt]
   use card_nthRoots n 1
@@ -839,7 +839,7 @@ nonrec theorem card_nthRoots {ζ : R} {n : ℕ} (h : IsPrimitiveRoot ζ n) :
 /-- The multiset `nthRoots ↑n (1 : R)` has no repeated elements
 if there is a primitive root of unity in `R`. -/
 theorem nthRoots_nodup {ζ : R} {n : ℕ} (h : IsPrimitiveRoot ζ n) : (nthRoots n (1 : R)).Nodup := by
-  cases' Nat.eq_zero_or_pos n with hzero hpos
+  rcases Nat.eq_zero_or_pos n with hzero | hpos
   · simp only [hzero, Multiset.nodup_zero, nthRoots_zero]
   apply (Multiset.dedup_eq_self (α := R)).1
   rw [eq_iff_le_not_lt]
chore: Nsmul -> NSMul, Zpow -> ZPow, etc (#9067)

Normalising to naming convention rule number 6.

Diff
@@ -36,7 +36,7 @@ monoids, expressing that an element is a primitive root of unity.
 ## Main results
 
 * `rootsOfUnity.isCyclic`: the roots of unity in an integral domain form a cyclic group.
-* `IsPrimitiveRoot.zmodEquivZpowers`: `ZMod k` is equivalent to
+* `IsPrimitiveRoot.zmodEquivZPowers`: `ZMod k` is equivalent to
   the subgroup generated by a primitive `k`-th root of unity.
 * `IsPrimitiveRoot.zpowers_eq`: in an integral domain, the subgroup generated by
   a primitive `k`-th root of unity is equal to the `k`-th roots of unity.
@@ -678,7 +678,7 @@ theorem pow_sub_one_eq [IsDomain R] {ζ : R} (hζ : IsPrimitiveRoot ζ k) (hk :
 
 /-- The (additive) monoid equivalence between `ZMod k`
 and the powers of a primitive root of unity `ζ`. -/
-def zmodEquivZpowers (h : IsPrimitiveRoot ζ k) : ZMod k ≃+ Additive (Subgroup.zpowers ζ) :=
+def zmodEquivZPowers (h : IsPrimitiveRoot ζ k) : ZMod k ≃+ Additive (Subgroup.zpowers ζ) :=
   AddEquiv.ofBijective
     (AddMonoidHom.liftOfRightInverse (Int.castAddHom <| ZMod k) _ ZMod.int_cast_rightInverse
       ⟨{  toFun := fun i => Additive.ofMul (⟨_, i, rfl⟩ : Subgroup.zpowers ζ)
@@ -700,50 +700,50 @@ def zmodEquivZpowers (h : IsPrimitiveRoot ζ k) : ZMod k ≃+ Additive (Subgroup
         refine' ⟨Int.castAddHom (ZMod k) i, _⟩
         rw [AddMonoidHom.liftOfRightInverse_comp_apply]
         rfl)
-#align is_primitive_root.zmod_equiv_zpowers IsPrimitiveRoot.zmodEquivZpowers
+#align is_primitive_root.zmod_equiv_zpowers IsPrimitiveRoot.zmodEquivZPowers
 
 @[simp]
-theorem zmodEquivZpowers_apply_coe_int (i : ℤ) :
-    h.zmodEquivZpowers i = Additive.ofMul (⟨ζ ^ i, i, rfl⟩ : Subgroup.zpowers ζ) := by
-  rw [zmodEquivZpowers, AddEquiv.ofBijective_apply] -- Porting note: Original proof didn't have `rw`
+theorem zmodEquivZPowers_apply_coe_int (i : ℤ) :
+    h.zmodEquivZPowers i = Additive.ofMul (⟨ζ ^ i, i, rfl⟩ : Subgroup.zpowers ζ) := by
+  rw [zmodEquivZPowers, AddEquiv.ofBijective_apply] -- Porting note: Original proof didn't have `rw`
   exact AddMonoidHom.liftOfRightInverse_comp_apply _ _ ZMod.int_cast_rightInverse _ _
-#align is_primitive_root.zmod_equiv_zpowers_apply_coe_int IsPrimitiveRoot.zmodEquivZpowers_apply_coe_int
+#align is_primitive_root.zmod_equiv_zpowers_apply_coe_int IsPrimitiveRoot.zmodEquivZPowers_apply_coe_int
 
 @[simp]
-theorem zmodEquivZpowers_apply_coe_nat (i : ℕ) :
-    h.zmodEquivZpowers i = Additive.ofMul (⟨ζ ^ i, i, rfl⟩ : Subgroup.zpowers ζ) := by
+theorem zmodEquivZPowers_apply_coe_nat (i : ℕ) :
+    h.zmodEquivZPowers i = Additive.ofMul (⟨ζ ^ i, i, rfl⟩ : Subgroup.zpowers ζ) := by
   have : (i : ZMod k) = (i : ℤ) := by norm_cast
-  simp only [this, zmodEquivZpowers_apply_coe_int, zpow_ofNat]
-#align is_primitive_root.zmod_equiv_zpowers_apply_coe_nat IsPrimitiveRoot.zmodEquivZpowers_apply_coe_nat
+  simp only [this, zmodEquivZPowers_apply_coe_int, zpow_ofNat]
+#align is_primitive_root.zmod_equiv_zpowers_apply_coe_nat IsPrimitiveRoot.zmodEquivZPowers_apply_coe_nat
 
 @[simp]
-theorem zmodEquivZpowers_symm_apply_zpow (i : ℤ) :
-    h.zmodEquivZpowers.symm (Additive.ofMul (⟨ζ ^ i, i, rfl⟩ : Subgroup.zpowers ζ)) = i := by
-  rw [← h.zmodEquivZpowers.symm_apply_apply i, zmodEquivZpowers_apply_coe_int]
-#align is_primitive_root.zmod_equiv_zpowers_symm_apply_zpow IsPrimitiveRoot.zmodEquivZpowers_symm_apply_zpow
+theorem zmodEquivZPowers_symm_apply_zpow (i : ℤ) :
+    h.zmodEquivZPowers.symm (Additive.ofMul (⟨ζ ^ i, i, rfl⟩ : Subgroup.zpowers ζ)) = i := by
+  rw [← h.zmodEquivZPowers.symm_apply_apply i, zmodEquivZPowers_apply_coe_int]
+#align is_primitive_root.zmod_equiv_zpowers_symm_apply_zpow IsPrimitiveRoot.zmodEquivZPowers_symm_apply_zpow
 
 @[simp]
-theorem zmodEquivZpowers_symm_apply_zpow' (i : ℤ) : h.zmodEquivZpowers.symm ⟨ζ ^ i, i, rfl⟩ = i :=
-  h.zmodEquivZpowers_symm_apply_zpow i
-#align is_primitive_root.zmod_equiv_zpowers_symm_apply_zpow' IsPrimitiveRoot.zmodEquivZpowers_symm_apply_zpow'
+theorem zmodEquivZPowers_symm_apply_zpow' (i : ℤ) : h.zmodEquivZPowers.symm ⟨ζ ^ i, i, rfl⟩ = i :=
+  h.zmodEquivZPowers_symm_apply_zpow i
+#align is_primitive_root.zmod_equiv_zpowers_symm_apply_zpow' IsPrimitiveRoot.zmodEquivZPowers_symm_apply_zpow'
 
 @[simp]
-theorem zmodEquivZpowers_symm_apply_pow (i : ℕ) :
-    h.zmodEquivZpowers.symm (Additive.ofMul (⟨ζ ^ i, i, rfl⟩ : Subgroup.zpowers ζ)) = i := by
-  rw [← h.zmodEquivZpowers.symm_apply_apply i, zmodEquivZpowers_apply_coe_nat]
-#align is_primitive_root.zmod_equiv_zpowers_symm_apply_pow IsPrimitiveRoot.zmodEquivZpowers_symm_apply_pow
+theorem zmodEquivZPowers_symm_apply_pow (i : ℕ) :
+    h.zmodEquivZPowers.symm (Additive.ofMul (⟨ζ ^ i, i, rfl⟩ : Subgroup.zpowers ζ)) = i := by
+  rw [← h.zmodEquivZPowers.symm_apply_apply i, zmodEquivZPowers_apply_coe_nat]
+#align is_primitive_root.zmod_equiv_zpowers_symm_apply_pow IsPrimitiveRoot.zmodEquivZPowers_symm_apply_pow
 
 @[simp]
-theorem zmodEquivZpowers_symm_apply_pow' (i : ℕ) : h.zmodEquivZpowers.symm ⟨ζ ^ i, i, rfl⟩ = i :=
-  h.zmodEquivZpowers_symm_apply_pow i
-#align is_primitive_root.zmod_equiv_zpowers_symm_apply_pow' IsPrimitiveRoot.zmodEquivZpowers_symm_apply_pow'
+theorem zmodEquivZPowers_symm_apply_pow' (i : ℕ) : h.zmodEquivZPowers.symm ⟨ζ ^ i, i, rfl⟩ = i :=
+  h.zmodEquivZPowers_symm_apply_pow i
+#align is_primitive_root.zmod_equiv_zpowers_symm_apply_pow' IsPrimitiveRoot.zmodEquivZPowers_symm_apply_pow'
 
 variable [IsDomain R]
 
 theorem zpowers_eq {k : ℕ+} {ζ : Rˣ} (h : IsPrimitiveRoot ζ k) :
     Subgroup.zpowers ζ = rootsOfUnity k R := by
   apply SetLike.coe_injective
-  haveI F : Fintype (Subgroup.zpowers ζ) := Fintype.ofEquiv _ h.zmodEquivZpowers.toEquiv
+  haveI F : Fintype (Subgroup.zpowers ζ) := Fintype.ofEquiv _ h.zmodEquivZPowers.toEquiv
   refine'
     @Set.eq_of_subset_of_card_le Rˣ (Subgroup.zpowers ζ) (rootsOfUnity k R) F
       (rootsOfUnity.fintype R k)
@@ -751,7 +751,7 @@ theorem zpowers_eq {k : ℕ+} {ζ : Rˣ} (h : IsPrimitiveRoot ζ k) :
   calc
     Fintype.card (rootsOfUnity k R) ≤ k := card_rootsOfUnity R k
     _ = Fintype.card (ZMod k) := (ZMod.card k).symm
-    _ = Fintype.card (Subgroup.zpowers ζ) := Fintype.card_congr h.zmodEquivZpowers.toEquiv
+    _ = Fintype.card (Subgroup.zpowers ζ) := Fintype.card_congr h.zmodEquivZPowers.toEquiv
 #align is_primitive_root.zpowers_eq IsPrimitiveRoot.zpowers_eq
 
 -- Porting note: rephrased the next few lemmas to avoid `∃ (Prop)`
@@ -801,7 +801,7 @@ theorem isPrimitiveRoot_iff {k : ℕ} {ζ ξ : R} (h : IsPrimitiveRoot ζ k) (h0
 
 theorem card_rootsOfUnity' {n : ℕ+} (h : IsPrimitiveRoot ζ n) :
     Fintype.card (rootsOfUnity n R) = n := by
-  let e := h.zmodEquivZpowers
+  let e := h.zmodEquivZPowers
   haveI F : Fintype (Subgroup.zpowers ζ) := Fintype.ofEquiv _ e.toEquiv
   calc
     Fintype.card (rootsOfUnity n R) = Fintype.card (Subgroup.zpowers ζ) :=
chore: space after (#8178)

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

Diff
@@ -253,7 +253,7 @@ variable {k R}
 theorem map_rootsOfUnity_eq_pow_self [RingHomClass F R R] (σ : F) (ζ : rootsOfUnity k R) :
     ∃ m : ℕ, σ (ζ : Rˣ) = ((ζ : Rˣ) : R) ^ m := by
   obtain ⟨m, hm⟩ := MonoidHom.map_cyclic (restrictRootsOfUnity σ k)
-  rw [← restrictRootsOfUnity_coe_apply, hm, ←zpow_mod_orderOf, ← Int.toNat_of_nonneg
+  rw [← restrictRootsOfUnity_coe_apply, hm, ← zpow_mod_orderOf, ← Int.toNat_of_nonneg
       (m.emod_nonneg (Int.coe_nat_ne_zero.mpr (pos_iff_ne_zero.mp (orderOf_pos ζ)))),
     zpow_ofNat, rootsOfUnity.coe_pow]
   exact ⟨(m % orderOf ζ).toNat, rfl⟩
@@ -994,7 +994,8 @@ theorem autToPow_spec (f : S ≃ₐ[R] S) : μ ^ (hμ.autToPow R f : ZMod n).val
   refine' (_ : ((hμ.toRootsOfUnity : Sˣ) : S) ^ _ = _).trans this.symm
   rw [← rootsOfUnity.coe_pow, ← rootsOfUnity.coe_pow]
   congr 2
-  rw [pow_eq_pow_iff_modEq, ZMod.val_nat_cast, hμ.eq_orderOf, ←Subgroup.orderOf_coe, ←orderOf_units]
+  rw [pow_eq_pow_iff_modEq, ZMod.val_nat_cast, hμ.eq_orderOf, ← Subgroup.orderOf_coe,
+    ← orderOf_units]
   exact Nat.mod_modEq _ _
 #align is_primitive_root.aut_to_pow_spec IsPrimitiveRoot.autToPow_spec
 
chore: replace exact_mod_cast tactic with mod_cast elaborator where possible (#8404)

We still have the exact_mod_cast tactic, used in a few places, which somehow (?) works a little bit harder to prevent the expected type influencing the elaboration of the term. I would like to get to the bottom of this, and it will be easier once the only usages of exact_mod_cast are the ones that don't work using the term elaborator by itself.

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

Diff
@@ -758,7 +758,7 @@ theorem zpowers_eq {k : ℕ+} {ζ : Rˣ} (h : IsPrimitiveRoot ζ k) :
 theorem eq_pow_of_mem_rootsOfUnity {k : ℕ+} {ζ ξ : Rˣ} (h : IsPrimitiveRoot ζ k)
     (hξ : ξ ∈ rootsOfUnity k R) : ∃ (i : ℕ), i < k ∧ ζ ^ i = ξ := by
   obtain ⟨n, rfl⟩ : ∃ n : ℤ, ζ ^ n = ξ := by rwa [← h.zpowers_eq] at hξ
-  have hk0 : (0 : ℤ) < k := by exact_mod_cast k.pos
+  have hk0 : (0 : ℤ) < k := mod_cast k.pos
   let i := n % k
   have hi0 : 0 ≤ i := Int.emod_nonneg _ (ne_of_gt hk0)
   lift i to ℕ using hi0 with i₀ hi₀
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
@@ -129,7 +129,7 @@ theorem map_rootsOfUnity (f : Mˣ →* Nˣ) (k : ℕ+) : (rootsOfUnity k M).map
 
 @[norm_cast]
 theorem rootsOfUnity.coe_pow [CommMonoid R] (ζ : rootsOfUnity k R) (m : ℕ) :
-    ((ζ ^ m : Rˣ) : R) = ((ζ : Rˣ) : R) ^ m := by
+    (((ζ ^ m :) : Rˣ) : R) = ((ζ : Rˣ) : R) ^ m := by
   rw [Subgroup.coe_pow, Units.val_pow_eq_pow_val]
 #align roots_of_unity.coe_pow rootsOfUnity.coe_pow
 
@@ -265,8 +265,6 @@ section Reduced
 
 variable (R) [CommRing R] [IsReduced R]
 
-local macro_rules | `($x ^ $y) => `(HPow.hPow $x $y) -- Porting note: See issue lean4#2220
-
 -- @[simp] -- Porting note: simp normal form is `mem_rootsOfUnity_prime_pow_mul_iff'`
 theorem mem_rootsOfUnity_prime_pow_mul_iff (p k : ℕ) (m : ℕ+) [hp : Fact p.Prime] [CharP R p]
     {ζ : Rˣ} : ζ ∈ rootsOfUnity (⟨p, hp.1.pos⟩ ^ k * m) R ↔ ζ ∈ rootsOfUnity m R := by
perf(FunLike.Basic): beta reduce CoeFun.coe (#7905)

This eliminates (fun a ↦ β) α in the type when applying a FunLike.

Co-authored-by: Matthew Ballard <matt@mrb.email> Co-authored-by: Eric Wieser <wieser.eric@gmail.com>

Diff
@@ -993,7 +993,6 @@ theorem autToPow_spec (f : S ≃ₐ[R] S) : μ ^ (hμ.autToPow R f : ZMod n).val
   rw [IsPrimitiveRoot.coe_autToPow_apply]
   generalize_proofs h
   have := h.choose_spec
-  dsimp only [AlgEquiv.toAlgHom_eq_coe, AlgEquiv.coe_algHom] at this
   refine' (_ : ((hμ.toRootsOfUnity : Sˣ) : S) ^ _ = _).trans this.symm
   rw [← rootsOfUnity.coe_pow, ← rootsOfUnity.coe_pow]
   congr 2
feat: Order of elements of a subgroup (#8385)

The cardinality of a subgroup is greater than the order of any of its elements.

Rename

  • order_eq_card_zpowersFintype.card_zpowers
  • order_eq_card_zpowers'Nat.card_zpowers (and turn it around to match Nat.card_subgroupPowers)
  • Submonoid.powers_subsetSubmonoid.powers_le
  • orderOf_dvd_card_univorderOf_dvd_card
  • orderOf_subgroupSubgroup.orderOf
  • Subgroup.nonemptySubgroup.coe_nonempty
Diff
@@ -949,7 +949,7 @@ variable [CommRing S] [IsDomain S] {μ : S} {n : ℕ+} (hμ : IsPrimitiveRoot μ
 noncomputable def autToPow : (S ≃ₐ[R] S) →* (ZMod n)ˣ :=
   let μ' := hμ.toRootsOfUnity
   have ho : orderOf μ' = n := by
-    rw [hμ.eq_orderOf, ← hμ.val_toRootsOfUnity_coe, orderOf_units, orderOf_subgroup]
+    rw [hμ.eq_orderOf, ← hμ.val_toRootsOfUnity_coe, orderOf_units, Subgroup.orderOf_coe]
   MonoidHom.toHomUnits
     { toFun := fun σ => (map_rootsOfUnity_eq_pow_self σ.toAlgHom μ').choose
       map_one' := by
@@ -997,7 +997,7 @@ theorem autToPow_spec (f : S ≃ₐ[R] S) : μ ^ (hμ.autToPow R f : ZMod n).val
   refine' (_ : ((hμ.toRootsOfUnity : Sˣ) : S) ^ _ = _).trans this.symm
   rw [← rootsOfUnity.coe_pow, ← rootsOfUnity.coe_pow]
   congr 2
-  rw [pow_eq_pow_iff_modEq, ZMod.val_nat_cast, hμ.eq_orderOf, ← orderOf_subgroup, ← orderOf_units]
+  rw [pow_eq_pow_iff_modEq, ZMod.val_nat_cast, hμ.eq_orderOf, ←Subgroup.orderOf_coe, ←orderOf_units]
   exact Nat.mod_modEq _ _
 #align is_primitive_root.aut_to_pow_spec IsPrimitiveRoot.autToPow_spec
 
chore: Generalise lemmas from finite groups to torsion elements (#8342)

Many lemmas in GroupTheory.OrderOfElement were stated for elements of finite groups even though they work more generally for torsion elements of possibly infinite groups. This PR generalises those lemmas (and leaves convenience lemmas stated for finite groups), and fixes a bunch of names to use dot notation.

Renames

  • Function.eq_of_lt_minimalPeriod_of_iterate_eqFunction.iterate_injOn_Iio_minimalPeriod
  • Function.eq_iff_lt_minimalPeriod_of_iterate_eqFunction.iterate_eq_iterate_iff_of_lt_minimalPeriod
  • isOfFinOrder_iff_coeSubmonoid.isOfFinOrder_coe
  • orderOf_pos'IsOfFinOrder.orderOf_pos
  • pow_eq_mod_orderOfpow_mod_orderOf (and turned around)
  • pow_injective_of_lt_orderOfpow_injOn_Iio_orderOf
  • mem_powers_iff_mem_range_order_of'IsOfFinOrder.mem_powers_iff_mem_range_orderOf
  • orderOf_pow''IsOfFinOrder.orderOf_pow
  • orderOf_pow_coprimeNat.Coprime.orderOf_pow
  • zpow_eq_mod_orderOfzpow_mod_orderOf (and turned around)
  • exists_pow_eq_oneisOfFinOrder_of_finite
  • pow_apply_eq_pow_mod_orderOf_cycleOf_applypow_mod_orderOf_cycleOf_apply

New lemmas

  • IsOfFinOrder.powers_eq_image_range_orderOf
  • IsOfFinOrder.natCard_powers_le_orderOf
  • IsOfFinOrder.finite_powers
  • finite_powers
  • infinite_powers
  • Nat.card_submonoidPowers
  • IsOfFinOrder.mem_powers_iff_mem_zpowers
  • IsOfFinOrder.powers_eq_zpowers
  • IsOfFinOrder.mem_zpowers_iff_mem_range_orderOf
  • IsOfFinOrder.exists_pow_eq_one

Other changes

  • Move decidableMemPowers/fintypePowers to GroupTheory.Submonoid.Membership and decidableMemZpowers/fintypeZpowers to GroupTheory.Subgroup.ZPowers.
  • finEquivPowers, finEquivZpowers, powersEquivPowers and zpowersEquivZpowers now assume IsOfFinTorsion x instead of Finite G.
  • isOfFinOrder_iff_pow_eq_one now takes one less explicit argument.
  • Delete Equiv.Perm.IsCycle.exists_pow_eq_one since it was saying that a permutation over a finite type is torsion, but this is trivial since the group of permutation is itself finite, so we can use isOfFinOrder_of_finite instead.
Diff
@@ -253,7 +253,7 @@ variable {k R}
 theorem map_rootsOfUnity_eq_pow_self [RingHomClass F R R] (σ : F) (ζ : rootsOfUnity k R) :
     ∃ m : ℕ, σ (ζ : Rˣ) = ((ζ : Rˣ) : R) ^ m := by
   obtain ⟨m, hm⟩ := MonoidHom.map_cyclic (restrictRootsOfUnity σ k)
-  rw [← restrictRootsOfUnity_coe_apply, hm, zpow_eq_mod_orderOf, ← Int.toNat_of_nonneg
+  rw [← restrictRootsOfUnity_coe_apply, hm, ←zpow_mod_orderOf, ← Int.toNat_of_nonneg
       (m.emod_nonneg (Int.coe_nat_ne_zero.mpr (pos_iff_ne_zero.mp (orderOf_pos ζ)))),
     zpow_ofNat, rootsOfUnity.coe_pow]
   exact ⟨(m % orderOf ζ).toNat, rfl⟩
@@ -961,7 +961,7 @@ noncomputable def autToPow : (S ≃ₐ[R] S) →* (ZMod n)ˣ :=
         replace h : μ' = μ' ^ h1.choose :=
           rootsOfUnity.coe_injective (by simpa only [rootsOfUnity.coe_pow] using h)
         nth_rw 1 [← pow_one μ'] at h
-        rw [← Nat.cast_one, ZMod.nat_cast_eq_nat_cast_iff, ← ho, ← pow_eq_pow_iff_modEq μ', h]
+        rw [← Nat.cast_one, ZMod.nat_cast_eq_nat_cast_iff, ← ho, ← pow_eq_pow_iff_modEq, h]
       map_mul' := by
         intro x y
         dsimp only
@@ -978,7 +978,7 @@ noncomputable def autToPow : (S ≃ₐ[R] S) →* (ZMod n)ˣ :=
         rw [← pow_mul] at hxy
         replace hxy : μ' ^ (hx'.choose * hy'.choose) = μ' ^ hxy'.choose :=
           rootsOfUnity.coe_injective (by simpa only [rootsOfUnity.coe_pow] using hxy)
-        rw [← Nat.cast_mul, ZMod.nat_cast_eq_nat_cast_iff, ← ho, ← pow_eq_pow_iff_modEq μ', hxy] }
+        rw [← Nat.cast_mul, ZMod.nat_cast_eq_nat_cast_iff, ← ho, ← pow_eq_pow_iff_modEq, hxy] }
 #align is_primitive_root.aut_to_pow IsPrimitiveRoot.autToPow
 
 -- We are not using @[simps] in aut_to_pow to avoid a timeout.
feat: add some ring theory lemmas (#7466)

From flt-regular.

Co-authored-by: Andrew Yang <the.erd.one@gmail.com>

Diff
@@ -592,6 +592,14 @@ theorem zpow_of_gcd_eq_one (h : IsPrimitiveRoot ζ k) (i : ℤ) (hi : i.gcd k =
 
 end DivisionCommMonoid
 
+section CommRing
+
+variable [CommRing R]  {n : ℕ} (hn : 1 < n) {ζ : R} (hζ : IsPrimitiveRoot ζ n)
+
+theorem sub_one_ne_zero : ζ - 1 ≠ 0 := sub_ne_zero.mpr <| hζ.ne_one hn
+
+end CommRing
+
 section IsDomain
 
 variable {ζ : R}
chore: bump to v4.1.0-rc1 (2nd attempt) (#7216)

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

Diff
@@ -410,7 +410,7 @@ theorem coe_units_iff {ζ : Mˣ} : IsPrimitiveRoot (ζ : M) k ↔ IsPrimitiveRoo
 #align is_primitive_root.coe_units_iff IsPrimitiveRoot.coe_units_iff
 
 -- Porting note `variable` above already contains `(h : IsPrimitiveRoot ζ k)`
-theorem pow_of_coprime (i : ℕ) (hi : i.coprime k) : IsPrimitiveRoot (ζ ^ i) k := by
+theorem pow_of_coprime (i : ℕ) (hi : i.Coprime k) : IsPrimitiveRoot (ζ ^ i) k := by
   by_cases h0 : k = 0
   · subst k; simp_all only [pow_one, Nat.coprime_zero_right]
   rcases h.isUnit (Nat.pos_of_ne_zero h0) with ⟨ζ, rfl⟩
@@ -432,7 +432,7 @@ theorem pow_of_prime (h : IsPrimitiveRoot ζ k) {p : ℕ} (hprime : Nat.Prime p)
 #align is_primitive_root.pow_of_prime IsPrimitiveRoot.pow_of_prime
 
 theorem pow_iff_coprime (h : IsPrimitiveRoot ζ k) (h0 : 0 < k) (i : ℕ) :
-    IsPrimitiveRoot (ζ ^ i) k ↔ i.coprime k := by
+    IsPrimitiveRoot (ζ ^ i) k ↔ i.Coprime k := by
   refine' ⟨_, h.pow_of_coprime i⟩
   intro hi
   obtain ⟨a, ha⟩ := i.gcd_dvd_left k
@@ -440,7 +440,7 @@ theorem pow_iff_coprime (h : IsPrimitiveRoot ζ k) (h0 : 0 < k) (i : ℕ) :
   suffices b = k by
     -- Porting note: was `rwa [this, ← one_mul k, mul_left_inj' h0.ne', eq_comm] at hb`
     rw [this, eq_comm, Nat.mul_left_eq_self_iff h0] at hb
-    rwa [Nat.coprime]
+    rwa [Nat.Coprime]
   rw [ha] at hi
   rw [mul_comm] at hb
   apply Nat.dvd_antisymm ⟨i.gcd k, hb⟩ (hi.dvd_of_pow_eq_one b _)
@@ -774,7 +774,7 @@ theorem eq_pow_of_pow_eq_one {k : ℕ} {ζ ξ : R} (h : IsPrimitiveRoot ζ k) (h
 #align is_primitive_root.eq_pow_of_pow_eq_one IsPrimitiveRoot.eq_pow_of_pow_eq_one
 
 theorem isPrimitiveRoot_iff' {k : ℕ+} {ζ ξ : Rˣ} (h : IsPrimitiveRoot ζ k) :
-    IsPrimitiveRoot ξ k ↔ ∃ i < (k : ℕ), i.coprime k ∧ ζ ^ i = ξ := by
+    IsPrimitiveRoot ξ k ↔ ∃ i < (k : ℕ), i.Coprime k ∧ ζ ^ i = ξ := by
   constructor
   · intro hξ
     obtain ⟨i, hik, rfl⟩ := h.eq_pow_of_mem_rootsOfUnity hξ.pow_eq_one
@@ -784,7 +784,7 @@ theorem isPrimitiveRoot_iff' {k : ℕ+} {ζ ξ : Rˣ} (h : IsPrimitiveRoot ζ k)
 #align is_primitive_root.is_primitive_root_iff' IsPrimitiveRoot.isPrimitiveRoot_iff'
 
 theorem isPrimitiveRoot_iff {k : ℕ} {ζ ξ : R} (h : IsPrimitiveRoot ζ k) (h0 : 0 < k) :
-    IsPrimitiveRoot ξ k ↔ ∃ i < k, i.coprime k ∧ ζ ^ i = ξ := by
+    IsPrimitiveRoot ξ k ↔ ∃ i < k, i.Coprime k ∧ ζ ^ i = ξ := by
   constructor
   · intro hξ
     obtain ⟨i, hik, rfl⟩ := h.eq_pow_of_pow_eq_one hξ.pow_eq_one h0
Revert "chore: bump to v4.1.0-rc1 (#7174)" (#7198)

This reverts commit 6f8e8104. Unfortunately this bump was not linted correctly, as CI did not run runLinter Mathlib.

We can unrevert once that's fixed.

Diff
@@ -410,7 +410,7 @@ theorem coe_units_iff {ζ : Mˣ} : IsPrimitiveRoot (ζ : M) k ↔ IsPrimitiveRoo
 #align is_primitive_root.coe_units_iff IsPrimitiveRoot.coe_units_iff
 
 -- Porting note `variable` above already contains `(h : IsPrimitiveRoot ζ k)`
-theorem pow_of_coprime (i : ℕ) (hi : i.Coprime k) : IsPrimitiveRoot (ζ ^ i) k := by
+theorem pow_of_coprime (i : ℕ) (hi : i.coprime k) : IsPrimitiveRoot (ζ ^ i) k := by
   by_cases h0 : k = 0
   · subst k; simp_all only [pow_one, Nat.coprime_zero_right]
   rcases h.isUnit (Nat.pos_of_ne_zero h0) with ⟨ζ, rfl⟩
@@ -432,7 +432,7 @@ theorem pow_of_prime (h : IsPrimitiveRoot ζ k) {p : ℕ} (hprime : Nat.Prime p)
 #align is_primitive_root.pow_of_prime IsPrimitiveRoot.pow_of_prime
 
 theorem pow_iff_coprime (h : IsPrimitiveRoot ζ k) (h0 : 0 < k) (i : ℕ) :
-    IsPrimitiveRoot (ζ ^ i) k ↔ i.Coprime k := by
+    IsPrimitiveRoot (ζ ^ i) k ↔ i.coprime k := by
   refine' ⟨_, h.pow_of_coprime i⟩
   intro hi
   obtain ⟨a, ha⟩ := i.gcd_dvd_left k
@@ -440,7 +440,7 @@ theorem pow_iff_coprime (h : IsPrimitiveRoot ζ k) (h0 : 0 < k) (i : ℕ) :
   suffices b = k by
     -- Porting note: was `rwa [this, ← one_mul k, mul_left_inj' h0.ne', eq_comm] at hb`
     rw [this, eq_comm, Nat.mul_left_eq_self_iff h0] at hb
-    rwa [Nat.Coprime]
+    rwa [Nat.coprime]
   rw [ha] at hi
   rw [mul_comm] at hb
   apply Nat.dvd_antisymm ⟨i.gcd k, hb⟩ (hi.dvd_of_pow_eq_one b _)
@@ -774,7 +774,7 @@ theorem eq_pow_of_pow_eq_one {k : ℕ} {ζ ξ : R} (h : IsPrimitiveRoot ζ k) (h
 #align is_primitive_root.eq_pow_of_pow_eq_one IsPrimitiveRoot.eq_pow_of_pow_eq_one
 
 theorem isPrimitiveRoot_iff' {k : ℕ+} {ζ ξ : Rˣ} (h : IsPrimitiveRoot ζ k) :
-    IsPrimitiveRoot ξ k ↔ ∃ i < (k : ℕ), i.Coprime k ∧ ζ ^ i = ξ := by
+    IsPrimitiveRoot ξ k ↔ ∃ i < (k : ℕ), i.coprime k ∧ ζ ^ i = ξ := by
   constructor
   · intro hξ
     obtain ⟨i, hik, rfl⟩ := h.eq_pow_of_mem_rootsOfUnity hξ.pow_eq_one
@@ -784,7 +784,7 @@ theorem isPrimitiveRoot_iff' {k : ℕ+} {ζ ξ : Rˣ} (h : IsPrimitiveRoot ζ k)
 #align is_primitive_root.is_primitive_root_iff' IsPrimitiveRoot.isPrimitiveRoot_iff'
 
 theorem isPrimitiveRoot_iff {k : ℕ} {ζ ξ : R} (h : IsPrimitiveRoot ζ k) (h0 : 0 < k) :
-    IsPrimitiveRoot ξ k ↔ ∃ i < k, i.Coprime k ∧ ζ ^ i = ξ := by
+    IsPrimitiveRoot ξ k ↔ ∃ i < k, i.coprime k ∧ ζ ^ i = ξ := by
   constructor
   · intro hξ
     obtain ⟨i, hik, rfl⟩ := h.eq_pow_of_pow_eq_one hξ.pow_eq_one h0
chore: bump to v4.1.0-rc1 (#7174)

Some changes have already been review and delegated in #6910 and #7148.

The diff that needs looking at is https://github.com/leanprover-community/mathlib4/pull/7174/commits/64d6d07ee18163627c8f517eb31455411921c5ac

The std bump PR was insta-merged already!

Co-authored-by: leanprover-community-mathlib4-bot <leanprover-community-mathlib4-bot@users.noreply.github.com> Co-authored-by: Scott Morrison <scott.morrison@gmail.com>

Diff
@@ -410,7 +410,7 @@ theorem coe_units_iff {ζ : Mˣ} : IsPrimitiveRoot (ζ : M) k ↔ IsPrimitiveRoo
 #align is_primitive_root.coe_units_iff IsPrimitiveRoot.coe_units_iff
 
 -- Porting note `variable` above already contains `(h : IsPrimitiveRoot ζ k)`
-theorem pow_of_coprime (i : ℕ) (hi : i.coprime k) : IsPrimitiveRoot (ζ ^ i) k := by
+theorem pow_of_coprime (i : ℕ) (hi : i.Coprime k) : IsPrimitiveRoot (ζ ^ i) k := by
   by_cases h0 : k = 0
   · subst k; simp_all only [pow_one, Nat.coprime_zero_right]
   rcases h.isUnit (Nat.pos_of_ne_zero h0) with ⟨ζ, rfl⟩
@@ -432,7 +432,7 @@ theorem pow_of_prime (h : IsPrimitiveRoot ζ k) {p : ℕ} (hprime : Nat.Prime p)
 #align is_primitive_root.pow_of_prime IsPrimitiveRoot.pow_of_prime
 
 theorem pow_iff_coprime (h : IsPrimitiveRoot ζ k) (h0 : 0 < k) (i : ℕ) :
-    IsPrimitiveRoot (ζ ^ i) k ↔ i.coprime k := by
+    IsPrimitiveRoot (ζ ^ i) k ↔ i.Coprime k := by
   refine' ⟨_, h.pow_of_coprime i⟩
   intro hi
   obtain ⟨a, ha⟩ := i.gcd_dvd_left k
@@ -440,7 +440,7 @@ theorem pow_iff_coprime (h : IsPrimitiveRoot ζ k) (h0 : 0 < k) (i : ℕ) :
   suffices b = k by
     -- Porting note: was `rwa [this, ← one_mul k, mul_left_inj' h0.ne', eq_comm] at hb`
     rw [this, eq_comm, Nat.mul_left_eq_self_iff h0] at hb
-    rwa [Nat.coprime]
+    rwa [Nat.Coprime]
   rw [ha] at hi
   rw [mul_comm] at hb
   apply Nat.dvd_antisymm ⟨i.gcd k, hb⟩ (hi.dvd_of_pow_eq_one b _)
@@ -774,7 +774,7 @@ theorem eq_pow_of_pow_eq_one {k : ℕ} {ζ ξ : R} (h : IsPrimitiveRoot ζ k) (h
 #align is_primitive_root.eq_pow_of_pow_eq_one IsPrimitiveRoot.eq_pow_of_pow_eq_one
 
 theorem isPrimitiveRoot_iff' {k : ℕ+} {ζ ξ : Rˣ} (h : IsPrimitiveRoot ζ k) :
-    IsPrimitiveRoot ξ k ↔ ∃ i < (k : ℕ), i.coprime k ∧ ζ ^ i = ξ := by
+    IsPrimitiveRoot ξ k ↔ ∃ i < (k : ℕ), i.Coprime k ∧ ζ ^ i = ξ := by
   constructor
   · intro hξ
     obtain ⟨i, hik, rfl⟩ := h.eq_pow_of_mem_rootsOfUnity hξ.pow_eq_one
@@ -784,7 +784,7 @@ theorem isPrimitiveRoot_iff' {k : ℕ+} {ζ ξ : Rˣ} (h : IsPrimitiveRoot ζ k)
 #align is_primitive_root.is_primitive_root_iff' IsPrimitiveRoot.isPrimitiveRoot_iff'
 
 theorem isPrimitiveRoot_iff {k : ℕ} {ζ ξ : R} (h : IsPrimitiveRoot ζ k) (h0 : 0 < k) :
-    IsPrimitiveRoot ξ k ↔ ∃ i < k, i.coprime k ∧ ζ ^ i = ξ := by
+    IsPrimitiveRoot ξ k ↔ ∃ i < k, i.Coprime k ∧ ζ ^ i = ξ := by
   constructor
   · intro hξ
     obtain ⟨i, hik, rfl⟩ := h.eq_pow_of_pow_eq_one hξ.pow_eq_one h0
chore: use mk_iff more (#7105)
Diff
@@ -286,10 +286,12 @@ end rootsOfUnity
 
 /-- An element `ζ` is a primitive `k`-th root of unity if `ζ ^ k = 1`,
 and if `l` satisfies `ζ ^ l = 1` then `k ∣ l`. -/
+@[mk_iff IsPrimitiveRoot.iff_def]
 structure IsPrimitiveRoot (ζ : M) (k : ℕ) : Prop where
   pow_eq_one : ζ ^ (k : ℕ) = 1
   dvd_of_pow_eq_one : ∀ l : ℕ, ζ ^ l = 1 → k ∣ l
 #align is_primitive_root IsPrimitiveRoot
+#align is_primitive_root.iff_def IsPrimitiveRoot.iff_def
 
 /-- Turn a primitive root μ into a member of the `rootsOfUnity` subgroup. -/
 @[simps!]
@@ -333,10 +335,6 @@ namespace IsPrimitiveRoot
 
 variable {k l : ℕ}
 
-theorem iff_def (ζ : M) (k : ℕ) : IsPrimitiveRoot ζ k ↔ ζ ^ k = 1 ∧ ∀ l : ℕ, ζ ^ l = 1 → k ∣ l :=
-  ⟨fun ⟨h1, h2⟩ => ⟨h1, h2⟩, fun ⟨h1, h2⟩ => ⟨h1, h2⟩⟩
-#align is_primitive_root.iff_def IsPrimitiveRoot.iff_def
-
 theorem mk_of_lt (ζ : M) (hk : 0 < k) (h1 : ζ ^ k = 1) (h : ∀ l : ℕ, 0 < l → l < k → ζ ^ l ≠ 1) :
     IsPrimitiveRoot ζ k := by
   refine' ⟨h1, fun l hl => _⟩
fix: simps config for Units (#6514)
Diff
@@ -108,7 +108,7 @@ a positive power equal to one. -/
 def rootsOfUnity.mkOfPowEq (ζ : M) {n : ℕ+} (h : ζ ^ (n : ℕ) = 1) : rootsOfUnity n M :=
   ⟨Units.ofPowEqOne ζ n h n.ne_zero, Units.pow_ofPowEqOne _ _⟩
 #align roots_of_unity.mk_of_pow_eq rootsOfUnity.mkOfPowEq
-#align roots_of_unity.mk_of_pow_eq_coe_coe rootsOfUnity.mkOfPowEq_coe_val
+#align roots_of_unity.mk_of_pow_eq_coe_coe rootsOfUnity.val_mkOfPowEq_coe
 
 @[simp]
 theorem rootsOfUnity.coe_mkOfPowEq {ζ : M} {n : ℕ+} (h : ζ ^ (n : ℕ) = 1) :
@@ -296,8 +296,8 @@ structure IsPrimitiveRoot (ζ : M) (k : ℕ) : Prop where
 def IsPrimitiveRoot.toRootsOfUnity {μ : M} {n : ℕ+} (h : IsPrimitiveRoot μ n) : rootsOfUnity n M :=
   rootsOfUnity.mkOfPowEq μ h.pow_eq_one
 #align is_primitive_root.to_roots_of_unity IsPrimitiveRoot.toRootsOfUnity
-#align is_primitive_root.coe_to_roots_of_unity_coe IsPrimitiveRoot.toRootsOfUnity_coe_val
-#align is_primitive_root.coe_inv_to_roots_of_unity_coe IsPrimitiveRoot.toRootsOfUnity_coe_inv
+#align is_primitive_root.coe_to_roots_of_unity_coe IsPrimitiveRoot.val_toRootsOfUnity_coe
+#align is_primitive_root.coe_inv_to_roots_of_unity_coe IsPrimitiveRoot.val_inv_toRootsOfUnity_coe
 
 section primitiveRoots
 
@@ -943,7 +943,7 @@ variable [CommRing S] [IsDomain S] {μ : S} {n : ℕ+} (hμ : IsPrimitiveRoot μ
 noncomputable def autToPow : (S ≃ₐ[R] S) →* (ZMod n)ˣ :=
   let μ' := hμ.toRootsOfUnity
   have ho : orderOf μ' = n := by
-    rw [hμ.eq_orderOf, ← hμ.toRootsOfUnity_coe_val, orderOf_units, orderOf_subgroup]
+    rw [hμ.eq_orderOf, ← hμ.val_toRootsOfUnity_coe, orderOf_units, orderOf_subgroup]
   MonoidHom.toHomUnits
     { toFun := fun σ => (map_rootsOfUnity_eq_pow_self σ.toAlgHom μ').choose
       map_one' := by
chore: drop MulZeroClass. in mul_zero/zero_mul (#6682)

Search&replace MulZeroClass.mul_zero -> mul_zero, MulZeroClass.zero_mul -> zero_mul.

These were introduced by Mathport, as the full name of mul_zero is actually MulZeroClass.mul_zero (it's exported with the short name).

Diff
@@ -492,7 +492,7 @@ theorem pow {n : ℕ} {a b : ℕ} (hn : 0 < n) (h : IsPrimitiveRoot ζ n) (hprod
   subst n
   simp only [iff_def, ← pow_mul, h.pow_eq_one, eq_self_iff_true, true_and_iff]
   intro l hl
-  -- Porting note: was `by rintro rfl; simpa only [Nat.not_lt_zero, MulZeroClass.zero_mul] using hn`
+  -- Porting note: was `by rintro rfl; simpa only [Nat.not_lt_zero, zero_mul] using hn`
   have ha0 : a ≠ 0 := left_ne_zero_of_mul hn.ne'
   rw [← mul_dvd_mul_iff_left ha0]
   exact h.dvd_of_pow_eq_one _ hl
@@ -907,7 +907,7 @@ theorem nthRoots_one_eq_biUnion_primitiveRoots' {ζ : R} {n : ℕ+} (h : IsPrimi
     rintro ⟨a, ⟨d, hd⟩, ha⟩
     have hazero : 0 < a := by
       contrapose! hd with ha0
-      simp_all only [nonpos_iff_eq_zero, MulZeroClass.zero_mul]
+      simp_all only [nonpos_iff_eq_zero, zero_mul]
       exact n.ne_zero
     rw [mem_primitiveRoots hazero] at ha
     rw [hd, pow_mul, ha.pow_eq_one, one_pow]
chore: banish Type _ and Sort _ (#6499)

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

This has nice performance benefits.

Diff
@@ -72,7 +72,7 @@ open Polynomial
 
 open Finset
 
-variable {M N G R S F : Type _}
+variable {M N G R S F : Type*}
 
 variable [CommMonoid M] [CommMonoid N] [DivisionCommMonoid G]
 
@@ -81,7 +81,7 @@ section rootsOfUnity
 variable {k l : ℕ+}
 
 /-- `rootsOfUnity k M` is the subgroup of elements `m : Mˣ` that satisfy `m ^ k = 1`. -/
-def rootsOfUnity (k : ℕ+) (M : Type _) [CommMonoid M] : Subgroup Mˣ where
+def rootsOfUnity (k : ℕ+) (M : Type*) [CommMonoid M] : Subgroup Mˣ where
   carrier := {ζ | ζ ^ (k : ℕ) = 1}
   one_mem' := one_pow _
   mul_mem' _ _ := by simp_all only [Set.mem_setOf_eq, mul_pow, one_mul]
@@ -305,7 +305,7 @@ variable {k : ℕ}
 
 /-- `primitiveRoots k R` is the finset of primitive `k`-th roots of unity
 in the integral domain `R`. -/
-def primitiveRoots (k : ℕ) (R : Type _) [CommRing R] [IsDomain R] : Finset R :=
+def primitiveRoots (k : ℕ) (R : Type*) [CommRing R] [IsDomain R] : Finset R :=
   (nthRoots k (1 : R)).toFinset.filter fun ζ => IsPrimitiveRoot ζ k
 #align primitive_roots primitiveRoots
 
@@ -400,7 +400,7 @@ theorem one_right_iff : IsPrimitiveRoot ζ 1 ↔ ζ = 1 := by
 #align is_primitive_root.one_right_iff IsPrimitiveRoot.one_right_iff
 
 @[simp]
-theorem coe_submonoidClass_iff {M B : Type _} [CommMonoid M] [SetLike B M] [SubmonoidClass B M]
+theorem coe_submonoidClass_iff {M B : Type*} [CommMonoid M] [SetLike B M] [SubmonoidClass B M]
     {N : B} {ζ : N} : IsPrimitiveRoot (ζ : M) k ↔ IsPrimitiveRoot ζ k := by
   simp_rw [iff_def]
   norm_cast
@@ -534,7 +534,7 @@ end CommMonoid
 
 section CommMonoidWithZero
 
-variable {M₀ : Type _} [CommMonoidWithZero M₀]
+variable {M₀ : Type*} [CommMonoidWithZero M₀]
 
 theorem zero [Nontrivial M₀] : IsPrimitiveRoot (0 : M₀) 0 :=
   ⟨pow_zero 0, fun l hl => by
chore: regularize HPow.hPow porting notes (#6465)
Diff
@@ -265,7 +265,7 @@ section Reduced
 
 variable (R) [CommRing R] [IsReduced R]
 
-local macro_rules | `($x ^ $y)   => `(HPow.hPow $x $y) -- Porting note: See issue #2220
+local macro_rules | `($x ^ $y) => `(HPow.hPow $x $y) -- Porting note: See issue lean4#2220
 
 -- @[simp] -- Porting note: simp normal form is `mem_rootsOfUnity_prime_pow_mul_iff'`
 theorem mem_rootsOfUnity_prime_pow_mul_iff (p k : ℕ) (m : ℕ+) [hp : Fact p.Prime] [CharP R p]
chore: script to replace headers with #align_import statements (#5979)

Open in Gitpod

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

Diff
@@ -2,11 +2,6 @@
 Copyright (c) 2020 Johan Commelin. All rights reserved.
 Released under Apache 2.0 license as described in the file LICENSE.
 Authors: Johan Commelin
-
-! This file was ported from Lean 3 source module ring_theory.roots_of_unity.basic
-! leanprover-community/mathlib commit 7fdeecc0d03cd40f7a165e6cf00a4d2286db599f
-! Please do not edit these lines, except to modify the commit id
-! if you have ported upstream changes.
 -/
 import Mathlib.Algebra.CharP.Two
 import Mathlib.Algebra.NeZero
@@ -19,6 +14,8 @@ import Mathlib.NumberTheory.Divisors
 import Mathlib.RingTheory.IntegralDomain
 import Mathlib.Tactic.Zify
 
+#align_import ring_theory.roots_of_unity.basic from "leanprover-community/mathlib"@"7fdeecc0d03cd40f7a165e6cf00a4d2286db599f"
+
 /-!
 # Roots of unity and primitive roots of unity
 
chore: fix grammar in docs (#5668)
Diff
@@ -488,7 +488,7 @@ protected theorem mem_rootsOfUnity {ζ : Mˣ} {n : ℕ+} (h : IsPrimitiveRoot ζ
   h.pow_eq_one
 #align is_primitive_root.mem_roots_of_unity IsPrimitiveRoot.mem_rootsOfUnity
 
-/-- If there is a `n`-th primitive root of unity in `R` and `b` divides `n`,
+/-- If there is an `n`-th primitive root of unity in `R` and `b` divides `n`,
 then there is a `b`-th primitive root of unity in `R`. -/
 theorem pow {n : ℕ} {a b : ℕ} (hn : 0 < n) (h : IsPrimitiveRoot ζ n) (hprod : n = a * b) :
     IsPrimitiveRoot (ζ ^ a) b := by
fix: ∑' precedence (#5615)
  • Also remove most superfluous parentheses around big operators (, and variants).
  • roughly the used regex: ([^a-zA-Zα-ωΑ-Ω'𝓝ℳ₀𝕂ₛ)]) \(([∑∏][^()∑∏]*,[^()∑∏:]*)\) ([⊂⊆=<≤]) replaced by $1 $2 $3
Diff
@@ -663,7 +663,7 @@ theorem neg_one (p : ℕ) [Nontrivial R] [h : CharP R p] (hp : p ≠ 2) :
 
 /-- If `1 < k` then `(∑ i in range k, ζ ^ i) = 0`. -/
 theorem geom_sum_eq_zero [IsDomain R] {ζ : R} (hζ : IsPrimitiveRoot ζ k) (hk : 1 < k) :
-    (∑ i in range k, ζ ^ i) = 0 := by
+    ∑ i in range k, ζ ^ i = 0 := by
   refine' eq_zero_of_ne_zero_of_mul_left_eq_zero (sub_ne_zero_of_ne (hζ.ne_one hk).symm) _
   rw [mul_neg_geom_sum, hζ.pow_eq_one, sub_self]
 #align is_primitive_root.geom_sum_eq_zero IsPrimitiveRoot.geom_sum_eq_zero
chore: tidy various files (#5449)
Diff
@@ -613,7 +613,7 @@ theorem primitiveRoots_one : primitiveRoots 1 R = {(1 : R)} := by
     exact hx
 #align is_primitive_root.primitive_roots_one IsPrimitiveRoot.primitiveRoots_one
 
-theorem ne_zero' {n : ℕ+} (hζ : IsPrimitiveRoot ζ n) : NeZero ((n : ℕ) : R) := by
+theorem neZero' {n : ℕ+} (hζ : IsPrimitiveRoot ζ n) : NeZero ((n : ℕ) : R) := by
   let p := ringChar R
   have hfin := multiplicity.finite_nat_iff.2 ⟨CharP.char_ne_one R p, n.pos⟩
   obtain ⟨m, hm⟩ := multiplicity.exists_eq_pow_mul_and_not_dvd hfin
@@ -633,7 +633,7 @@ theorem ne_zero' {n : ℕ+} (hζ : IsPrimitiveRoot ζ n) : NeZero ((n : ℕ) : R
     · rw [hm.1, hk, pow_succ, mul_assoc, mul_comm p]
       exact lt_mul_of_one_lt_right hpos hpri.1.one_lt
   · exact NeZero.of_not_dvd R hp
-#align is_primitive_root.ne_zero' IsPrimitiveRoot.ne_zero'
+#align is_primitive_root.ne_zero' IsPrimitiveRoot.neZero'
 
 nonrec theorem mem_nthRootsFinset (hζ : IsPrimitiveRoot ζ k) (hk : 0 < k) :
     ζ ∈ nthRootsFinset k R :=
feat: port RingTheory.RootsOfUnity.Basic (#4677)

Co-authored-by: Johan Commelin <johan@commelin.net> Co-authored-by: Ruben Van de Velde <65514131+Ruben-VandeVelde@users.noreply.github.com> Co-authored-by: int-y1 <jason_yuen2007@hotmail.com> Co-authored-by: Parcly Taxel <reddeloostw@gmail.com>

Dependencies 10 + 668

669 files ported (98.5%)
277663 lines ported (98.8%)
Show graph

The unported dependencies are