Theorem: Polynomial.X_pow_sub_one_eq_prod
File: Mathlib/RingTheory/Polynomial/Cyclotomic/Basic.lean

tactic: classical
rw [nthRootsFinset, ← Multiset.toFinset_eq (IsPrimitiveRoot.nthRoots_one_nodup h)]
simp only [Finset.prod_mk, RingHom.map_one]
rw [nthRoots]
have hmonic : (X ^ n - C (1 : R)).Monic := monic_X_pow_sub_C (1 : R) (ne_of_lt hpos).symm
symm
apply prod_multiset_X_sub_C_of_monic_of_roots_card_eq hmonic
rw [@natDegree_X_pow_sub_C R _ _ n 1, ← nthRoots]
exact IsPrimitiveRoot.card_nthRoots_one h
state_before: R : Type u_1
inst✝¹ : CommRing R
inst✝ : IsDomain R
ζ : R
n : ℕ
hpos : 0 < n
h : IsPrimitiveRoot ζ n
⊢ X ^ n - 1 = ∏ ζ ∈ nthRootsFinset n R, (X - C ζ)
state_after: no goals

tactic: rw [nthRootsFinset, ← Multiset.toFinset_eq (IsPrimitiveRoot.nthRoots_one_nodup h)]
state_before: R : Type u_1
inst✝¹ : CommRing R
inst✝ : IsDomain R
ζ : R
n : ℕ
hpos : 0 < n
h : IsPrimitiveRoot ζ n
⊢ X ^ n - 1 = ∏ ζ ∈ nthRootsFinset n R, (X - C ζ)
state_after: R : Type u_1
inst✝¹ : CommRing R
inst✝ : IsDomain R
ζ : R
n : ℕ
hpos : 0 < n
h : IsPrimitiveRoot ζ n
⊢ X ^ n - 1 = ∏ ζ ∈ { val := nthRoots n 1, nodup := ⋯ }, (X - C ζ)

tactic: simp only [Finset.prod_mk, RingHom.map_one]
state_before: R : Type u_1
inst✝¹ : CommRing R
inst✝ : IsDomain R
ζ : R
n : ℕ
hpos : 0 < n
h : IsPrimitiveRoot ζ n
⊢ X ^ n - 1 = ∏ ζ ∈ { val := nthRoots n 1, nodup := ⋯ }, (X - C ζ)
state_after: R : Type u_1
inst✝¹ : CommRing R
inst✝ : IsDomain R
ζ : R
n : ℕ
hpos : 0 < n
h : IsPrimitiveRoot ζ n
⊢ X ^ n - 1 = (Multiset.map (fun ζ => X - C ζ) (nthRoots n 1)).prod

tactic: rw [nthRoots]
state_before: R : Type u_1
inst✝¹ : CommRing R
inst✝ : IsDomain R
ζ : R
n : ℕ
hpos : 0 < n
h : IsPrimitiveRoot ζ n
⊢ X ^ n - 1 = (Multiset.map (fun ζ => X - C ζ) (nthRoots n 1)).prod
state_after: R : Type u_1
inst✝¹ : CommRing R
inst✝ : IsDomain R
ζ : R
n : ℕ
hpos : 0 < n
h : IsPrimitiveRoot ζ n
⊢ X ^ n - 1 = (Multiset.map (fun ζ => X - C ζ) (X ^ n - C 1).roots).prod

tactic: have hmonic : (X ^ n - C (1 : R)).Monic := monic_X_pow_sub_C (1 : R) (ne_of_lt hpos).symm
state_before: R : Type u_1
inst✝¹ : CommRing R
inst✝ : IsDomain R
ζ : R
n : ℕ
hpos : 0 < n
h : IsPrimitiveRoot ζ n
⊢ X ^ n - 1 = (Multiset.map (fun ζ => X - C ζ) (X ^ n - C 1).roots).prod
state_after: R : Type u_1
inst✝¹ : CommRing R
inst✝ : IsDomain R
ζ : R
n : ℕ
hpos : 0 < n
h : IsPrimitiveRoot ζ n
hmonic : (X ^ n - C 1).Monic
⊢ X ^ n - 1 = (Multiset.map (fun ζ => X - C ζ) (X ^ n - C 1).roots).prod

tactic: symm
state_before: R : Type u_1
inst✝¹ : CommRing R
inst✝ : IsDomain R
ζ : R
n : ℕ
hpos : 0 < n
h : IsPrimitiveRoot ζ n
hmonic : (X ^ n - C 1).Monic
⊢ X ^ n - 1 = (Multiset.map (fun ζ => X - C ζ) (X ^ n - C 1).roots).prod
state_after: R : Type u_1
inst✝¹ : CommRing R
inst✝ : IsDomain R
ζ : R
n : ℕ
hpos : 0 < n
h : IsPrimitiveRoot ζ n
hmonic : (X ^ n - C 1).Monic
⊢ (Multiset.map (fun ζ => X - C ζ) (X ^ n - C 1).roots).prod = X ^ n - 1

tactic: apply prod_multiset_X_sub_C_of_monic_of_roots_card_eq hmonic
state_before: R : Type u_1
inst✝¹ : CommRing R
inst✝ : IsDomain R
ζ : R
n : ℕ
hpos : 0 < n
h : IsPrimitiveRoot ζ n
hmonic : (X ^ n - C 1).Monic
⊢ (Multiset.map (fun ζ => X - C ζ) (X ^ n - C 1).roots).prod = X ^ n - 1
state_after: R : Type u_1
inst✝¹ : CommRing R
inst✝ : IsDomain R
ζ : R
n : ℕ
hpos : 0 < n
h : IsPrimitiveRoot ζ n
hmonic : (X ^ n - C 1).Monic
⊢ Multiset.card (X ^ n - C 1).roots = (X ^ n - C 1).natDegree

tactic: rw [@natDegree_X_pow_sub_C R _ _ n 1, ← nthRoots]
state_before: R : Type u_1
inst✝¹ : CommRing R
inst✝ : IsDomain R
ζ : R
n : ℕ
hpos : 0 < n
h : IsPrimitiveRoot ζ n
hmonic : (X ^ n - C 1).Monic
⊢ Multiset.card (X ^ n - C 1).roots = (X ^ n - C 1).natDegree
state_after: R : Type u_1
inst✝¹ : CommRing R
inst✝ : IsDomain R
ζ : R
n : ℕ
hpos : 0 < n
h : IsPrimitiveRoot ζ n
hmonic : (X ^ n - C 1).Monic
⊢ Multiset.card (nthRoots n 1) = n

tactic: exact IsPrimitiveRoot.card_nthRoots_one h
state_before: R : Type u_1
inst✝¹ : CommRing R
inst✝ : IsDomain R
ζ : R
n : ℕ
hpos : 0 < n
h : IsPrimitiveRoot ζ n
hmonic : (X ^ n - C 1).Monic
⊢ Multiset.card (nthRoots n 1) = n
state_after: no goals