ring_theory.roots_of_unity.basic
⟷
Mathlib.RingTheory.RootsOfUnity.Basic
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.
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(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)
mathlib commit https://github.com/leanprover-community/mathlib/commit/65a1391a0106c9204fe45bc73a039f056558cb83
@@ -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
-/
mathlib commit https://github.com/leanprover-community/mathlib/commit/65a1391a0106c9204fe45bc73a039f056558cb83
@@ -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
mathlib commit https://github.com/leanprover-community/mathlib/commit/65a1391a0106c9204fe45bc73a039f056558cb83
@@ -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
-/
mathlib commit https://github.com/leanprover-community/mathlib/commit/65a1391a0106c9204fe45bc73a039f056558cb83
@@ -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
mathlib commit https://github.com/leanprover-community/mathlib/commit/65a1391a0106c9204fe45bc73a039f056558cb83
@@ -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
-/
mathlib commit https://github.com/leanprover-community/mathlib/commit/65a1391a0106c9204fe45bc73a039f056558cb83
@@ -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
mathlib commit https://github.com/leanprover-community/mathlib/commit/65a1391a0106c9204fe45bc73a039f056558cb83
@@ -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 /-
mathlib commit https://github.com/leanprover-community/mathlib/commit/65a1391a0106c9204fe45bc73a039f056558cb83
@@ -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
mathlib commit https://github.com/leanprover-community/mathlib/commit/65a1391a0106c9204fe45bc73a039f056558cb83
@@ -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]
mathlib commit https://github.com/leanprover-community/mathlib/commit/65a1391a0106c9204fe45bc73a039f056558cb83
@@ -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
mathlib commit https://github.com/leanprover-community/mathlib/commit/65a1391a0106c9204fe45bc73a039f056558cb83
@@ -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]
mathlib commit https://github.com/leanprover-community/mathlib/commit/ce64cd319bb6b3e82f31c2d38e79080d377be451
@@ -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)ˣ :=
mathlib commit https://github.com/leanprover-community/mathlib/commit/ce64cd319bb6b3e82f31c2d38e79080d377be451
@@ -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ξ
mathlib commit https://github.com/leanprover-community/mathlib/commit/32a7e535287f9c73f2e4d2aef306a39190f0b504
@@ -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
-/
mathlib commit https://github.com/leanprover-community/mathlib/commit/8ea5598db6caeddde6cb734aa179cc2408dbd345
@@ -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
mathlib commit https://github.com/leanprover-community/mathlib/commit/93f880918cb51905fd51b76add8273cbc27718ab
@@ -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 /-
mathlib commit https://github.com/leanprover-community/mathlib/commit/9fb8964792b4237dac6200193a0d533f1b3f7423
@@ -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
mathlib commit https://github.com/leanprover-community/mathlib/commit/a3e83f0fa4391c8740f7d773a7a9b74e311ae2a3
@@ -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]
mathlib commit https://github.com/leanprover-community/mathlib/commit/7e5137f579de09a059a5ce98f364a04e221aabf0
@@ -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) :
mathlib commit https://github.com/leanprover-community/mathlib/commit/7e5137f579de09a059a5ce98f364a04e221aabf0
@@ -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.
mathlib commit https://github.com/leanprover-community/mathlib/commit/58a272265b5e05f258161260dd2c5d247213cbd3
@@ -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
mathlib commit https://github.com/leanprover-community/mathlib/commit/5f25c089cb34db4db112556f23c50d12da81b297
@@ -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]
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.
@@ -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
@@ -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'
Data
(#11751)
Polynomial
and MvPolynomial
are algebraic objects, hence should be under Algebra
(or at least not under Data
)
@@ -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
coe_nat
to natCast
(#11637)
Reduce the diff of #11499
All in the Int
namespace:
ofNat_eq_cast
→ ofNat_eq_natCast
cast_eq_cast_iff_Nat
→ natCast_inj
natCast_eq_ofNat
→ ofNat_eq_natCast
coe_nat_sub
→ natCast_sub
coe_nat_nonneg
→ natCast_nonneg
sign_coe_add_one
→ sign_natCast_add_one
nat_succ_eq_int_succ
→ natCast_succ
succ_neg_nat_succ
→ succ_neg_natCast_succ
coe_pred_of_pos
→ natCast_pred_of_pos
coe_nat_div
→ natCast_div
coe_nat_ediv
→ natCast_ediv
sign_coe_nat_of_nonzero
→ sign_natCast_of_ne_zero
toNat_coe_nat
→ toNat_natCast
toNat_coe_nat_add_one
→ toNat_natCast_add_one
coe_nat_dvd
→ natCast_dvd_natCast
coe_nat_dvd_left
→ natCast_dvd
coe_nat_dvd_right
→ dvd_natCast
le_coe_nat_sub
→ le_natCast_sub
succ_coe_nat_pos
→ succ_natCast_pos
coe_nat_modEq_iff
→ natCast_modEq_iff
coe_natAbs
→ natCast_natAbs
coe_nat_eq_zero
→ natCast_eq_zero
coe_nat_ne_zero
→ natCast_ne_zero
coe_nat_ne_zero_iff_pos
→ natCast_ne_zero_iff_pos
abs_coe_nat
→ abs_natCast
coe_nat_nonpos_iff
→ natCast_nonpos_iff
Also rename Nat.coe_nat_dvd
to Nat.cast_dvd_cast
@@ -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
@@ -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
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 notnpowRec n x * x
in the definition to make sure that definitional unfolding ofnpowRec
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.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
.@@ -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'
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
@@ -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)
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
@@ -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
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)
@@ -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
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.
@@ -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
@@ -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
These results are all proved for commutative semirings but all work for commutative monoids.
@@ -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
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>
@@ -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
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.
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]
.
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_param
s, [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 sometimesThis 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.
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 outParam
s 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.)
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>
@@ -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 η
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>
@@ -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
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
@@ -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]
@@ -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
@@ -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⟩
Finset
lemma names (#8894)
Change a few lemma names that have historically bothered me.
Finset.card_le_of_subset
→ Finset.card_le_card
Multiset.card_le_of_le
→ Multiset.card_le_card
Multiset.card_lt_of_lt
→ Multiset.card_lt_card
Set.ncard_le_of_subset
→ Set.ncard_le_ncard
Finset.image_filter
→ Finset.filter_image
CompleteLattice.finset_sup_compact_of_compact
→ CompleteLattice.isCompactElement_finset_sup
@@ -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
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
.
@@ -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]
Nsmul
-> NSMul
, Zpow
-> ZPow
, etc (#9067)
Normalising to naming convention rule number 6.
@@ -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 ζ) :=
@@ -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
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>
@@ -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₀
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.
In particular this includes adjustments for the Lean PRs
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).
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})
.
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:
(config := { unfoldPartialApp := true })
in some places, to recover the old behaviour@[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>
@@ -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
@@ -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
The cardinality of a subgroup is greater than the order of any of its elements.
Rename
order_eq_card_zpowers
→ Fintype.card_zpowers
order_eq_card_zpowers'
→ Nat.card_zpowers
(and turn it around to match Nat.card_subgroupPowers
)Submonoid.powers_subset
→ Submonoid.powers_le
orderOf_dvd_card_univ
→ orderOf_dvd_card
orderOf_subgroup
→ Subgroup.orderOf
Subgroup.nonempty
→ Subgroup.coe_nonempty
@@ -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
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.
Function.eq_of_lt_minimalPeriod_of_iterate_eq
→ Function.iterate_injOn_Iio_minimalPeriod
Function.eq_iff_lt_minimalPeriod_of_iterate_eq
→ Function.iterate_eq_iterate_iff_of_lt_minimalPeriod
isOfFinOrder_iff_coe
→ Submonoid.isOfFinOrder_coe
orderOf_pos'
→ IsOfFinOrder.orderOf_pos
pow_eq_mod_orderOf
→ pow_mod_orderOf
(and turned around)pow_injective_of_lt_orderOf
→ pow_injOn_Iio_orderOf
mem_powers_iff_mem_range_order_of'
→ IsOfFinOrder.mem_powers_iff_mem_range_orderOf
orderOf_pow''
→ IsOfFinOrder.orderOf_pow
orderOf_pow_coprime
→ Nat.Coprime.orderOf_pow
zpow_eq_mod_orderOf
→ zpow_mod_orderOf
(and turned around)exists_pow_eq_one
→ isOfFinOrder_of_finite
pow_apply_eq_pow_mod_orderOf_cycleOf_apply
→ pow_mod_orderOf_cycleOf_apply
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
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.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.@@ -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.
@@ -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}
@@ -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
@@ -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
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>
@@ -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
@@ -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 => _⟩
@@ -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
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).
@@ -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]
Type _
and Sort _
(#6499)
We remove all possible occurences of Type _
and Sort _
in favor of Type*
and Sort*
.
This has nice performance benefits.
@@ -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
@@ -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]
@@ -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
@@ -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
∑'
precedence (#5615)
∑
, ∏
and variants).([^a-zA-Zα-ωΑ-Ω'𝓝ℳ₀𝕂ₛ)]) \(([∑∏][^()∑∏]*,[^()∑∏:]*)\) ([⊂⊆=<≤])
replaced by $1 $2 $3
@@ -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
@@ -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 :=
The unported dependencies are