l3lab/ntp-mathlib huggingface dataset:
/-- 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_of_lt 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
    

Proof state:
case inr.right
M : Type u_1
N : Type u_2
G : Type u_3
R : Type u_4
S : Type u_5
F : Type u_6
inst✝⁴ : CommMonoid M
inst✝³ : CommMonoid N
inst✝² : DivisionCommMonoid G
k l : ℕ
inst✝¹ : CommRing R
ζ✝ : Rˣ
h✝ : IsPrimitiveRoot ζ✝ k
inst✝ : IsDomain R
ζ : R
n : ℕ
hpos : n > 0
m : ℕ+ := Nat.toPNat' n
h : IsPrimitiveRoot ζ ↑m
ha : Multiset.card (Multiset.dedup (nthRoots (↑m) 1)) < ↑m
hrw : Multiset.card (Multiset.dedup (nthRoots (↑m) 1)) = Fintype.card { x // x ∈ nthRoots (↑m) 1 }
⊢ False

Next tactic:
rw [hrw, ← Fintype.card_congr (rootsOfUnityEquivNthRoots R m), card_rootsOfUnity h] at ha
/-- 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_of_lt 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
    

Proof state:
case inr.right
M : Type u_1
N : Type u_2
G : Type u_3
R : Type u_4
S : Type u_5
F : Type u_6
inst✝⁴ : CommMonoid M
inst✝³ : CommMonoid N
inst✝² : DivisionCommMonoid G
k l : ℕ
inst✝¹ : CommRing R
ζ✝ : Rˣ
h✝ : IsPrimitiveRoot ζ✝ k
inst✝ : IsDomain R
ζ : R
n : ℕ
hpos : n > 0
m : ℕ+ := Nat.toPNat' n
h : IsPrimitiveRoot ζ ↑m
ha : ↑m < ↑m
hrw : Multiset.card (Multiset.dedup (nthRoots (↑m) 1)) = Fintype.card { x // x ∈ nthRoots (↑m) 1 }
⊢ False

Next tactic:
exact Nat.lt_asymm ha ha
@[simp]
theorem card_nthRootsFinset {ζ : R} {n : ℕ} (h : IsPrimitiveRoot ζ n) :
    (nthRootsFinset n R).card = n := by
  

Proof state:
M : Type u_1
N : Type u_2
G : Type u_3
R : Type u_4
S : Type u_5
F : Type u_6
inst✝⁴ : CommMonoid M
inst✝³ : CommMonoid N
inst✝² : DivisionCommMonoid G
k l : ℕ
inst✝¹ : CommRing R
ζ✝ : Rˣ
h✝ : IsPrimitiveRoot ζ✝ k
inst✝ : IsDomain R
ζ : R
n : ℕ
h : IsPrimitiveRoot ζ n
⊢ card (nthRootsFinset n R) = n

Next tactic:
rw [nthRootsFinset, ← Multiset.toFinset_eq (nthRoots_nodup h), card_mk, h.card_nthRoots]
/-- 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
  

Proof state:
M : Type u_1
N : Type u_2
G : Type u_3
R : Type u_4
S : Type u_5
F : Type u_6
inst✝⁴ : CommMonoid M
inst✝³ : CommMonoid N
inst✝² : DivisionCommMonoid G
k✝ l : ℕ
inst✝¹ : CommRing R
ζ✝ : Rˣ
h✝ : IsPrimitiveRoot ζ✝ k✝
inst✝ : IsDomain R
ζ : R
k : ℕ
h : IsPrimitiveRoot ζ k
⊢ card (primitiveRoots k R) = φ k

Next tactic:
by_cases h0 : k = 0
/-- 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
  by_cases h0 : k = 0
  · 

Proof state:
case pos
M : Type u_1
N : Type u_2
G : Type u_3
R : Type u_4
S : Type u_5
F : Type u_6
inst✝⁴ : CommMonoid M
inst✝³ : CommMonoid N
inst✝² : DivisionCommMonoid G
k✝ l : ℕ
inst✝¹ : CommRing R
ζ✝ : Rˣ
h✝ : IsPrimitiveRoot ζ✝ k✝
inst✝ : IsDomain R
ζ : R
k : ℕ
h : IsPrimitiveRoot ζ k
h0 : k = 0
⊢ card (primitiveRoots k R) = φ k

Next tactic:
simp [h0]
/-- 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
  by_cases h0 : k = 0
  · simp [h0]
  

Proof state:
case neg
M : Type u_1
N : Type u_2
G : Type u_3
R : Type u_4
S : Type u_5
F : Type u_6
inst✝⁴ : CommMonoid M
inst✝³ : CommMonoid N
inst✝² : DivisionCommMonoid G
k✝ l : ℕ
inst✝¹ : CommRing R
ζ✝ : Rˣ
h✝ : IsPrimitiveRoot ζ✝ k✝
inst✝ : IsDomain R
ζ : R
k : ℕ
h : IsPrimitiveRoot ζ k
h0 : ¬k = 0
⊢ card (primitiveRoots k R) = φ k

Next tactic:
symm
/-- 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
  by_cases h0 : k = 0
  · simp [h0]
  symm
  

Proof state:
case neg
M : Type u_1
N : Type u_2
G : Type u_3
R : Type u_4
S : Type u_5
F : Type u_6
inst✝⁴ : CommMonoid M
inst✝³ : CommMonoid N
inst✝² : DivisionCommMonoid G
k✝ l : ℕ
inst✝¹ : CommRing R
ζ✝ : Rˣ
h✝ : IsPrimitiveRoot ζ✝ k✝
inst✝ : IsDomain R
ζ : R
k : ℕ
h : IsPrimitiveRoot ζ k
h0 : ¬k = 0
⊢ φ k = card (primitiveRoots k R)

Next tactic:
refine' Finset.card_congr (fun i _ => ζ ^ i) _ _ _
/-- 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
  by_cases h0 : k = 0
  · simp [h0]
  symm
  refine' Finset.card_congr (fun i _ => ζ ^ i) _ _ _
  · 

Proof state:
case neg.refine'_1
M : Type u_1
N : Type u_2
G : Type u_3
R : Type u_4
S : Type u_5
F : Type u_6
inst✝⁴ : CommMonoid M
inst✝³ : CommMonoid N
inst✝² : DivisionCommMonoid G
k✝ l : ℕ
inst✝¹ : CommRing R
ζ✝ : Rˣ
h✝ : IsPrimitiveRoot ζ✝ k✝
inst✝ : IsDomain R
ζ : R
k : ℕ
h : IsPrimitiveRoot ζ k
h0 : ¬k = 0
⊢ ∀ (a : ℕ) (ha : a ∈ filter (Nat.Coprime k) (range k)), (fun i x => ζ ^ i) a ha ∈ primitiveRoots k R

Next tactic:
simp only [true_and_iff, and_imp, mem_filter, mem_range, mem_univ]
/-- 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
  by_cases h0 : k = 0
  · simp [h0]
  symm
  refine' Finset.card_congr (fun i _ => ζ ^ i) _ _ _
  · simp only [true_and_iff, and_imp, mem_filter, mem_range, mem_univ]
    

Proof state:
case neg.refine'_1
M : Type u_1
N : Type u_2
G : Type u_3
R : Type u_4
S : Type u_5
F : Type u_6
inst✝⁴ : CommMonoid M
inst✝³ : CommMonoid N
inst✝² : DivisionCommMonoid G
k✝ l : ℕ
inst✝¹ : CommRing R
ζ✝ : Rˣ
h✝ : IsPrimitiveRoot ζ✝ k✝
inst✝ : IsDomain R
ζ : R
k : ℕ
h : IsPrimitiveRoot ζ k
h0 : ¬k = 0
⊢ ∀ a < k, Nat.Coprime k a → ζ ^ a ∈ primitiveRoots k R

Next tactic:
rintro i - hi
/-- 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
  by_cases h0 : k = 0
  · simp [h0]
  symm
  refine' Finset.card_congr (fun i _ => ζ ^ i) _ _ _
  · simp only [true_and_iff, and_imp, mem_filter, mem_range, mem_univ]
    rintro i - hi
    

Proof state:
case neg.refine'_1
M : Type u_1
N : Type u_2
G : Type u_3
R : Type u_4
S : Type u_5
F : Type u_6
inst✝⁴ : CommMonoid M
inst✝³ : CommMonoid N
inst✝² : DivisionCommMonoid G
k✝ l : ℕ
inst✝¹ : CommRing R
ζ✝ : Rˣ
h✝ : IsPrimitiveRoot ζ✝ k✝
inst✝ : IsDomain R
ζ : R
k : ℕ
h : IsPrimitiveRoot ζ k
h0 : ¬k = 0
i : ℕ
hi : Nat.Coprime k i
⊢ ζ ^ i ∈ primitiveRoots k R

Next tactic:
rw [mem_primitiveRoots (Nat.pos_of_ne_zero h0)]
/-- 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
  by_cases h0 : k = 0
  · simp [h0]
  symm
  refine' Finset.card_congr (fun i _ => ζ ^ i) _ _ _
  · simp only [true_and_iff, and_imp, mem_filter, mem_range, mem_univ]
    rintro i - hi
    rw [mem_primitiveRoots (Nat.pos_of_ne_zero h0)]
    

Proof state:
case neg.refine'_1
M : Type u_1
N : Type u_2
G : Type u_3
R : Type u_4
S : Type u_5
F : Type u_6
inst✝⁴ : CommMonoid M
inst✝³ : CommMonoid N
inst✝² : DivisionCommMonoid G
k✝ l : ℕ
inst✝¹ : CommRing R
ζ✝ : Rˣ
h✝ : IsPrimitiveRoot ζ✝ k✝
inst✝ : IsDomain R
ζ : R
k : ℕ
h : IsPrimitiveRoot ζ k
h0 : ¬k = 0
i : ℕ
hi : Nat.Coprime k i
⊢ IsPrimitiveRoot (ζ ^ i) k

Next tactic:
exact h.pow_of_coprime i hi.symm
/-- 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
  by_cases h0 : k = 0
  · simp [h0]
  symm
  refine' Finset.card_congr (fun i _ => ζ ^ i) _ _ _
  · simp only [true_and_iff, and_imp, mem_filter, mem_range, mem_univ]
    rintro i - hi
    rw [mem_primitiveRoots (Nat.pos_of_ne_zero h0)]
    exact h.pow_of_coprime i hi.symm
  · 

Proof state:
case neg.refine'_2
M : Type u_1
N : Type u_2
G : Type u_3
R : Type u_4
S : Type u_5
F : Type u_6
inst✝⁴ : CommMonoid M
inst✝³ : CommMonoid N
inst✝² : DivisionCommMonoid G
k✝ l : ℕ
inst✝¹ : CommRing R
ζ✝ : Rˣ
h✝ : IsPrimitiveRoot ζ✝ k✝
inst✝ : IsDomain R
ζ : R
k : ℕ
h : IsPrimitiveRoot ζ k
h0 : ¬k = 0
⊢ ∀ (a b : ℕ) (ha : a ∈ filter (Nat.Coprime k) (range k)) (hb : b ∈ filter (Nat.Coprime k) (range k)),
    (fun i x => ζ ^ i) a ha = (fun i x => ζ ^ i) b hb → a = b

Next tactic:
simp only [true_and_iff, and_imp, mem_filter, mem_range, mem_univ]
/-- 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
  by_cases h0 : k = 0
  · simp [h0]
  symm
  refine' Finset.card_congr (fun i _ => ζ ^ i) _ _ _
  · simp only [true_and_iff, and_imp, mem_filter, mem_range, mem_univ]
    rintro i - hi
    rw [mem_primitiveRoots (Nat.pos_of_ne_zero h0)]
    exact h.pow_of_coprime i hi.symm
  · simp only [true_and_iff, and_imp, mem_filter, mem_range, mem_univ]
    

Proof state:
case neg.refine'_2
M : Type u_1
N : Type u_2
G : Type u_3
R : Type u_4
S : Type u_5
F : Type u_6
inst✝⁴ : CommMonoid M
inst✝³ : CommMonoid N
inst✝² : DivisionCommMonoid G
k✝ l : ℕ
inst✝¹ : CommRing R
ζ✝ : Rˣ
h✝ : IsPrimitiveRoot ζ✝ k✝
inst✝ : IsDomain R
ζ : R
k : ℕ
h : IsPrimitiveRoot ζ k
h0 : ¬k = 0
⊢ ∀ (a b : ℕ), a < k → Nat.Coprime k a → b < k → Nat.Coprime k b → ζ ^ a = ζ ^ b → a = b

Next tactic:
rintro i j hi - hj - H
/-- 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
  by_cases h0 : k = 0
  · simp [h0]
  symm
  refine' Finset.card_congr (fun i _ => ζ ^ i) _ _ _
  · simp only [true_and_iff, and_imp, mem_filter, mem_range, mem_univ]
    rintro i - hi
    rw [mem_primitiveRoots (Nat.pos_of_ne_zero h0)]
    exact h.pow_of_coprime i hi.symm
  · simp only [true_and_iff, and_imp, mem_filter, mem_range, mem_univ]
    rintro i j hi - hj - H
    

Proof state:
case neg.refine'_2
M : Type u_1
N : Type u_2
G : Type u_3
R : Type u_4
S : Type u_5
F : Type u_6
inst✝⁴ : CommMonoid M
inst✝³ : CommMonoid N
inst✝² : DivisionCommMonoid G
k✝ l : ℕ
inst✝¹ : CommRing R
ζ✝ : Rˣ
h✝ : IsPrimitiveRoot ζ✝ k✝
inst✝ : IsDomain R
ζ : R
k : ℕ
h : IsPrimitiveRoot ζ k
h0 : ¬k = 0
i j : ℕ
hi : i < k
hj : j < k
H : ζ ^ i = ζ ^ j
⊢ i = j

Next tactic:
exact h.pow_inj hi hj H
/-- 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
  by_cases h0 : k = 0
  · simp [h0]
  symm
  refine' Finset.card_congr (fun i _ => ζ ^ i) _ _ _
  · simp only [true_and_iff, and_imp, mem_filter, mem_range, mem_univ]
    rintro i - hi
    rw [mem_primitiveRoots (Nat.pos_of_ne_zero h0)]
    exact h.pow_of_coprime i hi.symm
  · simp only [true_and_iff, and_imp, mem_filter, mem_range, mem_univ]
    rintro i j hi - hj - H
    exact h.pow_inj hi hj H
  · 

Proof state:
case neg.refine'_3
M : Type u_1
N : Type u_2
G : Type u_3
R : Type u_4
S : Type u_5
F : Type u_6
inst✝⁴ : CommMonoid M
inst✝³ : CommMonoid N
inst✝² : DivisionCommMonoid G
k✝ l : ℕ
inst✝¹ : CommRing R
ζ✝ : Rˣ
h✝ : IsPrimitiveRoot ζ✝ k✝
inst✝ : IsDomain R
ζ : R
k : ℕ
h : IsPrimitiveRoot ζ k
h0 : ¬k = 0
⊢ ∀ b ∈ primitiveRoots k R, ∃ a, ∃ (ha : a ∈ filter (Nat.Coprime k) (range k)), (fun i x => ζ ^ i) a ha = b

Next tactic:
simp only [exists_prop, true_and_iff, mem_filter, mem_range, mem_univ]
/-- 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
  by_cases h0 : k = 0
  · simp [h0]
  symm
  refine' Finset.card_congr (fun i _ => ζ ^ i) _ _ _
  · simp only [true_and_iff, and_imp, mem_filter, mem_range, mem_univ]
    rintro i - hi
    rw [mem_primitiveRoots (Nat.pos_of_ne_zero h0)]
    exact h.pow_of_coprime i hi.symm
  · simp only [true_and_iff, and_imp, mem_filter, mem_range, mem_univ]
    rintro i j hi - hj - H
    exact h.pow_inj hi hj H
  · simp only [exists_prop, true_and_iff, mem_filter, mem_range, mem_univ]
    

Proof state:
case neg.refine'_3
M : Type u_1
N : Type u_2
G : Type u_3
R : Type u_4
S : Type u_5
F : Type u_6
inst✝⁴ : CommMonoid M
inst✝³ : CommMonoid N
inst✝² : DivisionCommMonoid G
k✝ l : ℕ
inst✝¹ : CommRing R
ζ✝ : Rˣ
h✝ : IsPrimitiveRoot ζ✝ k✝
inst✝ : IsDomain R
ζ : R
k : ℕ
h : IsPrimitiveRoot ζ k
h0 : ¬k = 0
⊢ ∀ b ∈ primitiveRoots k R, ∃ a, (a < k ∧ Nat.Coprime k a) ∧ ζ ^ a = b

Next tactic:
intro ξ hξ
/-- 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
  by_cases h0 : k = 0
  · simp [h0]
  symm
  refine' Finset.card_congr (fun i _ => ζ ^ i) _ _ _
  · simp only [true_and_iff, and_imp, mem_filter, mem_range, mem_univ]
    rintro i - hi
    rw [mem_primitiveRoots (Nat.pos_of_ne_zero h0)]
    exact h.pow_of_coprime i hi.symm
  · simp only [true_and_iff, and_imp, mem_filter, mem_range, mem_univ]
    rintro i j hi - hj - H
    exact h.pow_inj hi hj H
  · simp only [exists_prop, true_and_iff, mem_filter, mem_range, mem_univ]
    intro ξ hξ
    

Proof state:
case neg.refine'_3
M : Type u_1
N : Type u_2
G : Type u_3
R : Type u_4
S : Type u_5
F : Type u_6
inst✝⁴ : CommMonoid M
inst✝³ : CommMonoid N
inst✝² : DivisionCommMonoid G
k✝ l : ℕ
inst✝¹ : CommRing R
ζ✝ : Rˣ
h✝ : IsPrimitiveRoot ζ✝ k✝
inst✝ : IsDomain R
ζ : R
k : ℕ
h : IsPrimitiveRoot ζ k
h0 : ¬k = 0
ξ : R
hξ : ξ ∈ primitiveRoots k R
⊢ ∃ a, (a < k ∧ Nat.Coprime k a) ∧ ζ ^ a = ξ

Next tactic:
rw [mem_primitiveRoots (Nat.pos_of_ne_zero h0),
      h.isPrimitiveRoot_iff (Nat.pos_of_ne_zero h0)] at hξ
/-- 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
  by_cases h0 : k = 0
  · simp [h0]
  symm
  refine' Finset.card_congr (fun i _ => ζ ^ i) _ _ _
  · simp only [true_and_iff, and_imp, mem_filter, mem_range, mem_univ]
    rintro i - hi
    rw [mem_primitiveRoots (Nat.pos_of_ne_zero h0)]
    exact h.pow_of_coprime i hi.symm
  · simp only [true_and_iff, and_imp, mem_filter, mem_range, mem_univ]
    rintro i j hi - hj - H
    exact h.pow_inj hi hj H
  · 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.isPrimitiveRoot_iff (Nat.pos_of_ne_zero h0)] at hξ
    

Proof state:
case neg.refine'_3
M : Type u_1
N : Type u_2
G : Type u_3
R : Type u_4
S : Type u_5
F : Type u_6
inst✝⁴ : CommMonoid M
inst✝³ : CommMonoid N
inst✝² : DivisionCommMonoid G
k✝ l : ℕ
inst✝¹ : CommRing R
ζ✝ : Rˣ
h✝ : IsPrimitiveRoot ζ✝ k✝
inst✝ : IsDomain R
ζ : R
k : ℕ
h : IsPrimitiveRoot ζ k
h0 : ¬k = 0
ξ : R
hξ : ∃ i < k, Nat.Coprime i k ∧ ζ ^ i = ξ
⊢ ∃ a, (a < k ∧ Nat.Coprime k a) ∧ ζ ^ a = ξ

Next tactic:
rcases hξ with ⟨i, hin, hi, H⟩
/-- 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
  by_cases h0 : k = 0
  · simp [h0]
  symm
  refine' Finset.card_congr (fun i _ => ζ ^ i) _ _ _
  · simp only [true_and_iff, and_imp, mem_filter, mem_range, mem_univ]
    rintro i - hi
    rw [mem_primitiveRoots (Nat.pos_of_ne_zero h0)]
    exact h.pow_of_coprime i hi.symm
  · simp only [true_and_iff, and_imp, mem_filter, mem_range, mem_univ]
    rintro i j hi - hj - H
    exact h.pow_inj hi hj H
  · 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.isPrimitiveRoot_iff (Nat.pos_of_ne_zero h0)] at hξ
    rcases hξ with ⟨i, hin, hi, H⟩
    

Proof state:
case neg.refine'_3.intro.intro.intro
M : Type u_1
N : Type u_2
G : Type u_3
R : Type u_4
S : Type u_5
F : Type u_6
inst✝⁴ : CommMonoid M
inst✝³ : CommMonoid N
inst✝² : DivisionCommMonoid G
k✝ l : ℕ
inst✝¹ : CommRing R
ζ✝ : Rˣ
h✝ : IsPrimitiveRoot ζ✝ k✝
inst✝ : IsDomain R
ζ : R
k : ℕ
h : IsPrimitiveRoot ζ k
h0 : ¬k = 0
ξ : R
i : ℕ
hin : i < k
hi : Nat.Coprime i k
H : ζ ^ i = ξ
⊢ ∃ a, (a < k ∧ Nat.Coprime k a) ∧ ζ ^ a = ξ

Next tactic:
exact ⟨i, ⟨hin, hi.symm⟩, H⟩
/-- `nthRoots n` as a `Finset` is equal to the union of `primitiveRoots i R` for `i ∣ n`
if there is a primitive root of unity in `R`.
This holds for any `Nat`, not just `PNat`, see `nthRoots_one_eq_bUnion_primitive_roots`. -/
theorem nthRoots_one_eq_biUnion_primitiveRoots' {ζ : R} {n : ℕ+} (h : IsPrimitiveRoot ζ n) :
    nthRootsFinset n R = (Nat.divisors ↑n).biUnion fun i => primitiveRoots i R := by
  

Proof state:
M : Type u_1
N : Type u_2
G : Type u_3
R : Type u_4
S : Type u_5
F : Type u_6
inst✝⁴ : CommMonoid M
inst✝³ : CommMonoid N
inst✝² : DivisionCommMonoid G
k l : ℕ
inst✝¹ : CommRing R
ζ✝ : Rˣ
h✝ : IsPrimitiveRoot ζ✝ k
inst✝ : IsDomain R
ζ : R
n : ℕ+
h : IsPrimitiveRoot ζ ↑n
⊢ nthRootsFinset (↑n) R = Finset.biUnion (Nat.divisors ↑n) fun i => primitiveRoots i R

Next tactic:
symm
/-- `nthRoots n` as a `Finset` is equal to the union of `primitiveRoots i R` for `i ∣ n`
if there is a primitive root of unity in `R`.
This holds for any `Nat`, not just `PNat`, see `nthRoots_one_eq_bUnion_primitive_roots`. -/
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
  

Proof state:
M : Type u_1
N : Type u_2
G : Type u_3
R : Type u_4
S : Type u_5
F : Type u_6
inst✝⁴ : CommMonoid M
inst✝³ : CommMonoid N
inst✝² : DivisionCommMonoid G
k l : ℕ
inst✝¹ : CommRing R
ζ✝ : Rˣ
h✝ : IsPrimitiveRoot ζ✝ k
inst✝ : IsDomain R
ζ : R
n : ℕ+
h : IsPrimitiveRoot ζ ↑n
⊢ (Finset.biUnion (Nat.divisors ↑n) fun i => primitiveRoots i R) = nthRootsFinset (↑n) R

Next tactic:
apply Finset.eq_of_subset_of_card_le
/-- `nthRoots n` as a `Finset` is equal to the union of `primitiveRoots i R` for `i ∣ n`
if there is a primitive root of unity in `R`.
This holds for any `Nat`, not just `PNat`, see `nthRoots_one_eq_bUnion_primitive_roots`. -/
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
  apply Finset.eq_of_subset_of_card_le
  · 

Proof state:
case h
M : Type u_1
N : Type u_2
G : Type u_3
R : Type u_4
S : Type u_5
F : Type u_6
inst✝⁴ : CommMonoid M
inst✝³ : CommMonoid N
inst✝² : DivisionCommMonoid G
k l : ℕ
inst✝¹ : CommRing R
ζ✝ : Rˣ
h✝ : IsPrimitiveRoot ζ✝ k
inst✝ : IsDomain R
ζ : R
n : ℕ+
h : IsPrimitiveRoot ζ ↑n
⊢ (Finset.biUnion (Nat.divisors ↑n) fun i => primitiveRoots i R) ⊆ nthRootsFinset (↑n) R

Next tactic:
intro x
/-- `nthRoots n` as a `Finset` is equal to the union of `primitiveRoots i R` for `i ∣ n`
if there is a primitive root of unity in `R`.
This holds for any `Nat`, not just `PNat`, see `nthRoots_one_eq_bUnion_primitive_roots`. -/
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
  apply Finset.eq_of_subset_of_card_le
  · intro x
    

Proof state:
case h
M : Type u_1
N : Type u_2
G : Type u_3
R : Type u_4
S : Type u_5
F : Type u_6
inst✝⁴ : CommMonoid M
inst✝³ : CommMonoid N
inst✝² : DivisionCommMonoid G
k l : ℕ
inst✝¹ : CommRing R
ζ✝ : Rˣ
h✝ : IsPrimitiveRoot ζ✝ k
inst✝ : IsDomain R
ζ : R
n : ℕ+
h : IsPrimitiveRoot ζ ↑n
x : R
⊢ (x ∈ Finset.biUnion (Nat.divisors ↑n) fun i => primitiveRoots i R) → x ∈ nthRootsFinset (↑n) R

Next tactic:
simp only [nthRootsFinset, ← Multiset.toFinset_eq (nthRoots_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]
/-- `nthRoots n` as a `Finset` is equal to the union of `primitiveRoots i R` for `i ∣ n`
if there is a primitive root of unity in `R`.
This holds for any `Nat`, not just `PNat`, see `nthRoots_one_eq_bUnion_primitive_roots`. -/
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
  apply Finset.eq_of_subset_of_card_le
  · intro x
    simp only [nthRootsFinset, ← Multiset.toFinset_eq (nthRoots_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]
    

Proof state:
case h
M : Type u_1
N : Type u_2
G : Type u_3
R : Type u_4
S : Type u_5
F : Type u_6
inst✝⁴ : CommMonoid M
inst✝³ : CommMonoid N
inst✝² : DivisionCommMonoid G
k l : ℕ
inst✝¹ : CommRing R
ζ✝ : Rˣ
h✝ : IsPrimitiveRoot ζ✝ k
inst✝ : IsDomain R
ζ : R
n : ℕ+
h : IsPrimitiveRoot ζ ↑n
x : R
⊢ (∃ a, a ∣ ↑n ∧ x ∈ primitiveRoots a R) → x ^ ↑n = 1

Next tactic:
rintro ⟨a, ⟨d, hd⟩, ha⟩
/-- `nthRoots n` as a `Finset` is equal to the union of `primitiveRoots i R` for `i ∣ n`
if there is a primitive root of unity in `R`.
This holds for any `Nat`, not just `PNat`, see `nthRoots_one_eq_bUnion_primitive_roots`. -/
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
  apply Finset.eq_of_subset_of_card_le
  · intro x
    simp only [nthRootsFinset, ← Multiset.toFinset_eq (nthRoots_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⟩
    

Proof state:
case h.intro.intro.intro
M : Type u_1
N : Type u_2
G : Type u_3
R : Type u_4
S : Type u_5
F : Type u_6
inst✝⁴ : CommMonoid M
inst✝³ : CommMonoid N
inst✝² : DivisionCommMonoid G
k l : ℕ
inst✝¹ : CommRing R
ζ✝ : Rˣ
h✝ : IsPrimitiveRoot ζ✝ k
inst✝ : IsDomain R
ζ : R
n : ℕ+
h : IsPrimitiveRoot ζ ↑n
x : R
a : ℕ
ha : x ∈ primitiveRoots a R
d : ℕ
hd : ↑n = a * d
⊢ x ^ ↑n = 1

Next tactic:
have hazero : 0 < a := by
      contrapose! hd with ha0
      simp_all only [nonpos_iff_eq_zero, zero_mul]
      exact n.ne_zero