l3lab/ntp-mathlib huggingface dataset:
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 := 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₀]; 

Proof state:
case intro.intro.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
k : ℕ+
ζ : Rˣ
h : IsPrimitiveRoot ζ ↑k
n : ℤ
hξ : ζ ^ n ∈ rootsOfUnity k R
hk0 : 0 < ↑↑k
i : ℤ := n % ↑↑k
i₀ : ℕ
hi₀ : ↑i₀ = i
⊢ i < ↑↑k

Next tactic:
exact Int.emod_lt_of_pos _ hk0
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 := 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
  · 

Proof state:
case intro.intro.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
k : ℕ+
ζ : Rˣ
h : IsPrimitiveRoot ζ ↑k
n : ℤ
hξ : ζ ^ n ∈ rootsOfUnity k R
hk0 : 0 < ↑↑k
i : ℤ := n % ↑↑k
i₀ : ℕ
hi₀ : ↑i₀ = i
⊢ ζ ^ i₀ = ζ ^ n

Next tactic:
rw [← zpow_ofNat, hi₀, ← Int.emod_add_ediv n k, zpow_add, zpow_mul, h.zpow_eq_one, one_zpow,
      mul_one]
theorem eq_pow_of_pow_eq_one {k : ℕ} {ζ ξ : R} (h : IsPrimitiveRoot ζ k) (hξ : ξ ^ k = 1)
    (h0 : 0 < k) : ∃ i < k, ζ ^ i = ξ := 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
k : ℕ
ζ ξ : R
h : IsPrimitiveRoot ζ k
hξ : ξ ^ k = 1
h0 : 0 < k
⊢ ∃ i < k, ζ ^ i = ξ

Next tactic:
lift ζ to Rˣ using h.isUnit h0
theorem eq_pow_of_pow_eq_one {k : ℕ} {ζ ξ : R} (h : IsPrimitiveRoot ζ k) (hξ : ξ ^ k = 1)
    (h0 : 0 < k) : ∃ i < k, ζ ^ i = ξ := by
  lift ζ to Rˣ using h.isUnit h0
  

Proof state:
case 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
k : ℕ
ξ : R
hξ : ξ ^ k = 1
h0 : 0 < k
ζ : Rˣ
h : IsPrimitiveRoot (↑ζ) k
⊢ ∃ i < k, ↑ζ ^ i = ξ

Next tactic:
lift ξ to Rˣ using isUnit_ofPowEqOne hξ h0.ne'
theorem eq_pow_of_pow_eq_one {k : ℕ} {ζ ξ : R} (h : IsPrimitiveRoot ζ k) (hξ : ξ ^ k = 1)
    (h0 : 0 < k) : ∃ i < k, ζ ^ i = ξ := by
  lift ζ to Rˣ using h.isUnit h0
  lift ξ to Rˣ using isUnit_ofPowEqOne hξ h0.ne'
  

Proof state:
case 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
k : ℕ
h0 : 0 < k
ζ : Rˣ
h : IsPrimitiveRoot (↑ζ) k
ξ : Rˣ
hξ : ↑ξ ^ k = 1
⊢ ∃ i < k, ↑ζ ^ i = ↑ξ

Next tactic:
lift k to ℕ+ using h0
theorem eq_pow_of_pow_eq_one {k : ℕ} {ζ ξ : R} (h : IsPrimitiveRoot ζ k) (hξ : ξ ^ k = 1)
    (h0 : 0 < k) : ∃ i < k, ζ ^ i = ξ := by
  lift ζ to Rˣ using h.isUnit h0
  lift ξ to Rˣ using isUnit_ofPowEqOne hξ h0.ne'
  lift k to ℕ+ using h0
  

Proof state:
case 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
hξ : ↑ξ ^ ↑k = 1
⊢ ∃ i < ↑k, ↑ζ ^ i = ↑ξ

Next tactic:
simp only [← Units.val_pow_eq_pow_val, ← Units.ext_iff]
theorem eq_pow_of_pow_eq_one {k : ℕ} {ζ ξ : R} (h : IsPrimitiveRoot ζ k) (hξ : ξ ^ k = 1)
    (h0 : 0 < k) : ∃ i < k, ζ ^ i = ξ := by
  lift ζ to Rˣ using h.isUnit h0
  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]
  

Proof state:
case 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
hξ : ↑ξ ^ ↑k = 1
⊢ ∃ i < ↑k, ζ ^ i = ξ

Next tactic:
rw [coe_units_iff] at h
theorem eq_pow_of_pow_eq_one {k : ℕ} {ζ ξ : R} (h : IsPrimitiveRoot ζ k) (hξ : ξ ^ k = 1)
    (h0 : 0 < k) : ∃ i < k, ζ ^ i = ξ := by
  lift ζ to Rˣ using h.isUnit h0
  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
  

Proof state:
case 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
hξ : ↑ξ ^ ↑k = 1
⊢ ∃ i < ↑k, ζ ^ i = ξ

Next tactic:
apply h.eq_pow_of_mem_rootsOfUnity
theorem eq_pow_of_pow_eq_one {k : ℕ} {ζ ξ : R} (h : IsPrimitiveRoot ζ k) (hξ : ξ ^ k = 1)
    (h0 : 0 < k) : ∃ i < k, ζ ^ i = ξ := by
  lift ζ to Rˣ using h.isUnit h0
  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
  apply h.eq_pow_of_mem_rootsOfUnity
  

Proof state:
case 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
hξ : ↑ξ ^ ↑k = 1
⊢ ξ ∈ rootsOfUnity k R

Next tactic:
rw [mem_rootsOfUnity, Units.ext_iff, Units.val_pow_eq_pow_val, hξ, Units.val_one]
theorem isPrimitiveRoot_iff' {k : ℕ+} {ζ ξ : Rˣ} (h : IsPrimitiveRoot ζ k) :
    IsPrimitiveRoot ξ k ↔ ∃ i < (k : ℕ), i.Coprime k ∧ ζ ^ i = ξ := 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
k : ℕ+
ζ ξ : Rˣ
h : IsPrimitiveRoot ζ ↑k
⊢ IsPrimitiveRoot ξ ↑k ↔ ∃ i < ↑k, Nat.Coprime i ↑k ∧ ζ ^ i = ξ

Next tactic:
constructor
theorem isPrimitiveRoot_iff' {k : ℕ+} {ζ ξ : Rˣ} (h : IsPrimitiveRoot ζ k) :
    IsPrimitiveRoot ξ k ↔ ∃ i < (k : ℕ), i.Coprime k ∧ ζ ^ i = ξ := by
  constructor
  · 

Proof state:
case mp
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
k : ℕ+
ζ ξ : Rˣ
h : IsPrimitiveRoot ζ ↑k
⊢ IsPrimitiveRoot ξ ↑k → ∃ i < ↑k, Nat.Coprime i ↑k ∧ ζ ^ i = ξ

Next tactic:
intro hξ
theorem isPrimitiveRoot_iff' {k : ℕ+} {ζ ξ : Rˣ} (h : IsPrimitiveRoot ζ k) :
    IsPrimitiveRoot ξ k ↔ ∃ i < (k : ℕ), i.Coprime k ∧ ζ ^ i = ξ := by
  constructor
  · intro hξ
    

Proof state:
case mp
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
k : ℕ+
ζ ξ : Rˣ
h : IsPrimitiveRoot ζ ↑k
hξ : IsPrimitiveRoot ξ ↑k
⊢ ∃ i < ↑k, Nat.Coprime i ↑k ∧ ζ ^ i = ξ

Next tactic:
obtain ⟨i, hik, rfl⟩ := h.eq_pow_of_mem_rootsOfUnity hξ.pow_eq_one
theorem isPrimitiveRoot_iff' {k : ℕ+} {ζ ξ : Rˣ} (h : IsPrimitiveRoot ζ k) :
    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
    

Proof state:
case mp.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
k : ℕ+
ζ : Rˣ
h : IsPrimitiveRoot ζ ↑k
i : ℕ
hik : i < ↑k
hξ : IsPrimitiveRoot (ζ ^ i) ↑k
⊢ ∃ i_1 < ↑k, Nat.Coprime i_1 ↑k ∧ ζ ^ i_1 = ζ ^ i

Next tactic:
rw [h.pow_iff_coprime k.pos] at hξ
theorem isPrimitiveRoot_iff' {k : ℕ+} {ζ ξ : Rˣ} (h : IsPrimitiveRoot ζ k) :
    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
    rw [h.pow_iff_coprime k.pos] at hξ
    

Proof state:
case mp.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
k : ℕ+
ζ : Rˣ
h : IsPrimitiveRoot ζ ↑k
i : ℕ
hik : i < ↑k
hξ : Nat.Coprime i ↑k
⊢ ∃ i_1 < ↑k, Nat.Coprime i_1 ↑k ∧ ζ ^ i_1 = ζ ^ i

Next tactic:
exact ⟨i, hik, hξ, rfl⟩
theorem isPrimitiveRoot_iff' {k : ℕ+} {ζ ξ : Rˣ} (h : IsPrimitiveRoot ζ k) :
    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
    rw [h.pow_iff_coprime k.pos] at hξ
    exact ⟨i, hik, hξ, rfl⟩
  · 

Proof state:
case mpr
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
k : ℕ+
ζ ξ : Rˣ
h : IsPrimitiveRoot ζ ↑k
⊢ (∃ i < ↑k, Nat.Coprime i ↑k ∧ ζ ^ i = ξ) → IsPrimitiveRoot ξ ↑k

Next tactic:
rintro ⟨i, -, hi, rfl⟩
theorem isPrimitiveRoot_iff' {k : ℕ+} {ζ ξ : Rˣ} (h : IsPrimitiveRoot ζ k) :
    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
    rw [h.pow_iff_coprime k.pos] at hξ
    exact ⟨i, hik, hξ, rfl⟩
  · rintro ⟨i, -, hi, rfl⟩; 

Proof state:
case mpr.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
k : ℕ+
ζ : Rˣ
h : IsPrimitiveRoot ζ ↑k
i : ℕ
hi : Nat.Coprime i ↑k
⊢ IsPrimitiveRoot (ζ ^ i) ↑k

Next tactic:
exact h.pow_of_coprime i hi
theorem isPrimitiveRoot_iff {k : ℕ} {ζ ξ : R} (h : IsPrimitiveRoot ζ k) (h0 : 0 < k) :
    IsPrimitiveRoot ξ k ↔ ∃ i < k, i.Coprime k ∧ ζ ^ i = ξ := 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
k : ℕ
ζ ξ : R
h : IsPrimitiveRoot ζ k
h0 : 0 < k
⊢ IsPrimitiveRoot ξ k ↔ ∃ i < k, Nat.Coprime i k ∧ ζ ^ i = ξ

Next tactic:
constructor
theorem isPrimitiveRoot_iff {k : ℕ} {ζ ξ : R} (h : IsPrimitiveRoot ζ k) (h0 : 0 < k) :
    IsPrimitiveRoot ξ k ↔ ∃ i < k, i.Coprime k ∧ ζ ^ i = ξ := by
  constructor
  · 

Proof state:
case mp
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
k : ℕ
ζ ξ : R
h : IsPrimitiveRoot ζ k
h0 : 0 < k
⊢ IsPrimitiveRoot ξ k → ∃ i < k, Nat.Coprime i k ∧ ζ ^ i = ξ

Next tactic:
intro hξ
theorem isPrimitiveRoot_iff {k : ℕ} {ζ ξ : R} (h : IsPrimitiveRoot ζ k) (h0 : 0 < k) :
    IsPrimitiveRoot ξ k ↔ ∃ i < k, i.Coprime k ∧ ζ ^ i = ξ := by
  constructor
  · intro hξ
    

Proof state:
case mp
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
k : ℕ
ζ ξ : R
h : IsPrimitiveRoot ζ k
h0 : 0 < k
hξ : IsPrimitiveRoot ξ k
⊢ ∃ i < k, Nat.Coprime i k ∧ ζ ^ i = ξ

Next tactic:
obtain ⟨i, hik, rfl⟩ := h.eq_pow_of_pow_eq_one hξ.pow_eq_one h0
theorem isPrimitiveRoot_iff {k : ℕ} {ζ ξ : R} (h : IsPrimitiveRoot ζ k) (h0 : 0 < k) :
    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
    

Proof state:
case mp.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
k : ℕ
ζ : R
h : IsPrimitiveRoot ζ k
h0 : 0 < k
i : ℕ
hik : i < k
hξ : IsPrimitiveRoot (ζ ^ i) k
⊢ ∃ i_1 < k, Nat.Coprime i_1 k ∧ ζ ^ i_1 = ζ ^ i

Next tactic:
rw [h.pow_iff_coprime h0] at hξ
theorem isPrimitiveRoot_iff {k : ℕ} {ζ ξ : R} (h : IsPrimitiveRoot ζ k) (h0 : 0 < k) :
    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
    rw [h.pow_iff_coprime h0] at hξ
    

Proof state:
case mp.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
k : ℕ
ζ : R
h : IsPrimitiveRoot ζ k
h0 : 0 < k
i : ℕ
hik : i < k
hξ : Nat.Coprime i k
⊢ ∃ i_1 < k, Nat.Coprime i_1 k ∧ ζ ^ i_1 = ζ ^ i

Next tactic:
exact ⟨i, hik, hξ, rfl⟩
theorem isPrimitiveRoot_iff {k : ℕ} {ζ ξ : R} (h : IsPrimitiveRoot ζ k) (h0 : 0 < k) :
    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
    rw [h.pow_iff_coprime h0] at hξ
    exact ⟨i, hik, hξ, rfl⟩
  · 

Proof state:
case mpr
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
k : ℕ
ζ ξ : R
h : IsPrimitiveRoot ζ k
h0 : 0 < k
⊢ (∃ i < k, Nat.Coprime i k ∧ ζ ^ i = ξ) → IsPrimitiveRoot ξ k

Next tactic:
rintro ⟨i, -, hi, rfl⟩
theorem isPrimitiveRoot_iff {k : ℕ} {ζ ξ : R} (h : IsPrimitiveRoot ζ k) (h0 : 0 < k) :
    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
    rw [h.pow_iff_coprime h0] at hξ
    exact ⟨i, hik, hξ, rfl⟩
  · rintro ⟨i, -, hi, rfl⟩; 

Proof state:
case mpr.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
k : ℕ
ζ : R
h : IsPrimitiveRoot ζ k
h0 : 0 < k
i : ℕ
hi : Nat.Coprime i k
⊢ IsPrimitiveRoot (ζ ^ i) k

Next tactic:
exact h.pow_of_coprime i hi
theorem card_rootsOfUnity' {n : ℕ+} (h : IsPrimitiveRoot ζ n) :
    Fintype.card (rootsOfUnity n R) = 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
n : ℕ+
h : IsPrimitiveRoot ζ ↑n
⊢ Fintype.card ↥(rootsOfUnity n R) = ↑n

Next tactic:
let e := h.zmodEquivZPowers
theorem card_rootsOfUnity' {n : ℕ+} (h : IsPrimitiveRoot ζ n) :
    Fintype.card (rootsOfUnity n R) = n := by
  let e := h.zmodEquivZPowers
  

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
n : ℕ+
h : IsPrimitiveRoot ζ ↑n
e : ZMod ↑n ≃+ Additive ↥(Subgroup.zpowers ζ) := zmodEquivZPowers h
⊢ Fintype.card ↥(rootsOfUnity n R) = ↑n

Next tactic:
haveI F : Fintype (Subgroup.zpowers ζ) := Fintype.ofEquiv _ e.toEquiv
theorem card_rootsOfUnity' {n : ℕ+} (h : IsPrimitiveRoot ζ n) :
    Fintype.card (rootsOfUnity n R) = n := by
  let e := h.zmodEquivZPowers
  haveI F : Fintype (Subgroup.zpowers ζ) := Fintype.ofEquiv _ e.toEquiv
  

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
n : ℕ+
h : IsPrimitiveRoot ζ ↑n
e : ZMod ↑n ≃+ Additive ↥(Subgroup.zpowers ζ) := zmodEquivZPowers h
F : Fintype ↥(Subgroup.zpowers ζ)
⊢ Fintype.card ↥(rootsOfUnity n R) = ↑n

Next tactic:
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)
    _ = n := ZMod.card n
theorem card_rootsOfUnity' {n : ℕ+} (h : IsPrimitiveRoot ζ n) :
    Fintype.card (rootsOfUnity n R) = n := by
  let e := h.zmodEquivZPowers
  haveI F : Fintype (Subgroup.zpowers ζ) := Fintype.ofEquiv _ e.toEquiv
  calc
    Fintype.card (rootsOfUnity n R) = Fintype.card (Subgroup.zpowers ζ) :=
      Fintype.card_congr <| 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
n : ℕ+
h : IsPrimitiveRoot ζ ↑n
e : ZMod ↑n ≃+ Additive ↥(Subgroup.zpowers ζ) := zmodEquivZPowers h
F : Fintype ↥(Subgroup.zpowers ζ)
⊢ ↥(rootsOfUnity n R) ≃ ↥(Subgroup.zpowers ζ)

Next tactic:
rw [h.zpowers_eq]
theorem card_rootsOfUnity {ζ : R} {n : ℕ+} (h : IsPrimitiveRoot ζ n) :
    Fintype.card (rootsOfUnity n R) = 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
⊢ Fintype.card ↥(rootsOfUnity n R) = ↑n

Next tactic:
obtain ⟨ζ, hζ⟩ := h.isUnit n.pos
theorem card_rootsOfUnity {ζ : R} {n : ℕ+} (h : IsPrimitiveRoot ζ n) :
    Fintype.card (rootsOfUnity n R) = n := by
  obtain ⟨ζ, hζ⟩ := h.isUnit n.pos
  

Proof state:
case 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
ζ : Rˣ
hζ : ↑ζ = ζ✝
⊢ Fintype.card ↥(rootsOfUnity n R) = ↑n

Next tactic:
rw [← hζ, IsPrimitiveRoot.coe_units_iff] at h
theorem card_rootsOfUnity {ζ : R} {n : ℕ+} (h : IsPrimitiveRoot ζ n) :
    Fintype.card (rootsOfUnity n R) = n := by
  obtain ⟨ζ, hζ⟩ := h.isUnit n.pos
  rw [← hζ, IsPrimitiveRoot.coe_units_iff] at h
  

Proof state:
case 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 : ℕ+
ζ : Rˣ
h : IsPrimitiveRoot ζ ↑n
hζ : ↑ζ = ζ✝
⊢ Fintype.card ↥(rootsOfUnity n R) = ↑n

Next tactic:
exact h.card_rootsOfUnity'
/-- 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
  

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
⊢ Multiset.card (nthRoots n 1) = n

Next tactic:
rcases Nat.eq_zero_or_pos n with hzero | hpos
/-- 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
  · 

Proof state:
case inl
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
hzero : n = 0
⊢ Multiset.card (nthRoots n 1) = n

Next tactic:
simp only [hzero, Multiset.card_zero, nthRoots_zero]
/-- 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]
  

Proof state:
case inr
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
hpos : n > 0
⊢ Multiset.card (nthRoots n 1) = n

Next tactic:
rw [eq_iff_le_not_lt]
/-- 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]
  

Proof state:
case inr
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
hpos : n > 0
⊢ Multiset.card (nthRoots n 1) ≤ n ∧ ¬Multiset.card (nthRoots n 1) < n

Next tactic:
use card_nthRoots n 1
/-- 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
  · 

Proof state:
case 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 : ℕ
h : IsPrimitiveRoot ζ n
hpos : n > 0
⊢ ¬Multiset.card (nthRoots n 1) < n

Next tactic:
rw [not_lt]