l3lab/ntp-mathlib huggingface dataset:
theorem of_map_of_injective [MonoidHomClass F M N] (h : IsPrimitiveRoot (f ζ) k)
    (hf : Injective f) : IsPrimitiveRoot ζ k where
  pow_eq_one := by apply_fun f; rw [map_pow, _root_.map_one, h.pow_eq_one]
  dvd_of_pow_eq_one := by
    rw [h.eq_orderOf]
    intro l hl
    apply_fun f at hl
    rw [map_pow, _root_.map_one] at hl
    

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✝ : ℕ
ζ : M
f : F
h✝ : IsPrimitiveRoot ζ k
inst✝ : MonoidHomClass F M N
h : IsPrimitiveRoot (f ζ) k
hf : Injective ⇑f
l : ℕ
hl : f ζ ^ l = 1
⊢ orderOf (f ζ) ∣ l

Next tactic:
exact orderOf_dvd_of_pow_eq_one hl
theorem zero [Nontrivial M₀] : IsPrimitiveRoot (0 : M₀) 0 :=
  ⟨pow_zero 0, fun l hl => 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✝ : ℕ
M₀ : Type u_7
inst✝¹ : CommMonoidWithZero M₀
inst✝ : Nontrivial M₀
l : ℕ
hl : 0 ^ l = 1
⊢ 0 ∣ l

Next tactic:
simpa [zero_pow_eq, show ∀ p, ¬p → False ↔ p from @Classical.not_not] using hl
theorem zpow_eq_one (h : IsPrimitiveRoot ζ k) : ζ ^ (k : ℤ) = 1 := 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 : ℕ
ζ : G
h : IsPrimitiveRoot ζ k
⊢ ζ ^ ↑k = 1

Next tactic:
rw [zpow_ofNat]
theorem zpow_eq_one (h : IsPrimitiveRoot ζ k) : ζ ^ (k : ℤ) = 1 := by
  rw [zpow_ofNat]; 

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 : ℕ
ζ : G
h : IsPrimitiveRoot ζ k
⊢ ζ ^ k = 1

Next tactic:
exact h.pow_eq_one
theorem zpow_eq_one_iff_dvd (h : IsPrimitiveRoot ζ k) (l : ℤ) : ζ ^ l = 1 ↔ (k : ℤ) ∣ l := 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✝ : ℕ
ζ : G
h : IsPrimitiveRoot ζ k
l : ℤ
⊢ ζ ^ l = 1 ↔ ↑k ∣ l

Next tactic:
by_cases h0 : 0 ≤ l
theorem zpow_eq_one_iff_dvd (h : IsPrimitiveRoot ζ k) (l : ℤ) : ζ ^ l = 1 ↔ (k : ℤ) ∣ l := by
  by_cases h0 : 0 ≤ l
  · 

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✝ : ℕ
ζ : G
h : IsPrimitiveRoot ζ k
l : ℤ
h0 : 0 ≤ l
⊢ ζ ^ l = 1 ↔ ↑k ∣ l

Next tactic:
lift l to ℕ using h0
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; 

Proof state:
case pos.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✝ : ℕ
ζ : G
h : IsPrimitiveRoot ζ k
l : ℕ
⊢ ζ ^ ↑l = 1 ↔ ↑k ∣ ↑l

Next tactic:
rw [zpow_ofNat]
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]; 

Proof state:
case pos.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✝ : ℕ
ζ : G
h : IsPrimitiveRoot ζ k
l : ℕ
⊢ ζ ^ l = 1 ↔ ↑k ∣ ↑l

Next tactic:
norm_cast
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; 

Proof state:
case pos.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✝ : ℕ
ζ : G
h : IsPrimitiveRoot ζ k
l : ℕ
⊢ ζ ^ l = 1 ↔ k ∣ l

Next tactic:
exact h.pow_eq_one_iff_dvd l
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
  · 

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✝ : ℕ
ζ : G
h : IsPrimitiveRoot ζ k
l : ℤ
h0 : ¬0 ≤ l
⊢ ζ ^ l = 1 ↔ ↑k ∣ l

Next tactic:
have : 0 ≤ -l := by simp only [not_le, neg_nonneg] at h0 ⊢; exact le_of_lt h0
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
  · have : 0 ≤ -l := 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✝ : ℕ
ζ : G
h : IsPrimitiveRoot ζ k
l : ℤ
h0 : ¬0 ≤ l
⊢ 0 ≤ -l

Next tactic:
simp only [not_le, neg_nonneg] at h0 ⊢
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
  · have : 0 ≤ -l := by simp only [not_le, neg_nonneg] at h0 ⊢; 

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✝ : ℕ
ζ : G
h : IsPrimitiveRoot ζ k
l : ℤ
h0 : l < 0
⊢ l ≤ 0

Next tactic:
exact le_of_lt h0
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
  · have : 0 ≤ -l := by simp only [not_le, neg_nonneg] at h0 ⊢; exact le_of_lt 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✝ : ℕ
ζ : G
h : IsPrimitiveRoot ζ k
l : ℤ
h0 : ¬0 ≤ l
this : 0 ≤ -l
⊢ ζ ^ l = 1 ↔ ↑k ∣ l

Next tactic:
lift -l to ℕ using this with l' hl'
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
  · 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'
    

Proof state:
case neg.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✝ : ℕ
ζ : G
h : IsPrimitiveRoot ζ k
l : ℤ
h0 : ¬0 ≤ l
l' : ℕ
hl' : ↑l' = -l
⊢ ζ ^ l = 1 ↔ ↑k ∣ l

Next tactic:
rw [← dvd_neg, ← hl']
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
  · 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']
    

Proof state:
case neg.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✝ : ℕ
ζ : G
h : IsPrimitiveRoot ζ k
l : ℤ
h0 : ¬0 ≤ l
l' : ℕ
hl' : ↑l' = -l
⊢ ζ ^ l = 1 ↔ ↑k ∣ ↑l'

Next tactic:
norm_cast
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
  · 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
    

Proof state:
case neg.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✝ : ℕ
ζ : G
h : IsPrimitiveRoot ζ k
l : ℤ
h0 : ¬0 ≤ l
l' : ℕ
hl' : ↑l' = -l
⊢ ζ ^ l = 1 ↔ k ∣ l'

Next tactic:
rw [← h.pow_eq_one_iff_dvd, ← inv_inj, ← zpow_neg, ← hl', zpow_ofNat, inv_one]
theorem inv (h : IsPrimitiveRoot ζ k) : IsPrimitiveRoot ζ⁻¹ k :=
  { pow_eq_one := 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 : ℕ
ζ : G
h : IsPrimitiveRoot ζ k
⊢ ζ⁻¹ ^ k = 1

Next tactic:
simp only [h.pow_eq_one, inv_one, eq_self_iff_true, inv_pow]
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
      

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 : ℕ
ζ : G
h : IsPrimitiveRoot ζ k
⊢ ∀ (l : ℕ), ζ⁻¹ ^ l = 1 → k ∣ l

Next tactic:
intro l hl
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
      intro l hl
      

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✝ : ℕ
ζ : G
h : IsPrimitiveRoot ζ k
l : ℕ
hl : ζ⁻¹ ^ l = 1
⊢ k ∣ l

Next tactic:
apply h.dvd_of_pow_eq_one l
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
      intro l hl
      apply h.dvd_of_pow_eq_one l
      

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✝ : ℕ
ζ : G
h : IsPrimitiveRoot ζ k
l : ℕ
hl : ζ⁻¹ ^ l = 1
⊢ ζ ^ l = 1

Next tactic:
rw [← inv_inj, ← inv_pow, hl, inv_one]
@[simp]
theorem inv_iff : IsPrimitiveRoot ζ⁻¹ k ↔ IsPrimitiveRoot ζ 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 : ℕ
ζ : G
⊢ IsPrimitiveRoot ζ⁻¹ k ↔ IsPrimitiveRoot ζ k

Next tactic:
refine' ⟨_, fun h => inv h⟩
@[simp]
theorem inv_iff : IsPrimitiveRoot ζ⁻¹ k ↔ IsPrimitiveRoot ζ k := by
  refine' ⟨_, fun h => inv h⟩; 

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 : ℕ
ζ : G
⊢ IsPrimitiveRoot ζ⁻¹ k → IsPrimitiveRoot ζ k

Next tactic:
intro h
@[simp]
theorem inv_iff : IsPrimitiveRoot ζ⁻¹ k ↔ IsPrimitiveRoot ζ k := by
  refine' ⟨_, fun h => inv h⟩; intro h; 

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 : ℕ
ζ : G
h : IsPrimitiveRoot ζ⁻¹ k
⊢ IsPrimitiveRoot ζ k

Next tactic:
rw [← inv_inv ζ]
@[simp]
theorem inv_iff : IsPrimitiveRoot ζ⁻¹ k ↔ IsPrimitiveRoot ζ k := by
  refine' ⟨_, fun h => inv h⟩; intro h; rw [← inv_inv ζ]; 

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 : ℕ
ζ : G
h : IsPrimitiveRoot ζ⁻¹ k
⊢ IsPrimitiveRoot ζ⁻¹⁻¹ k

Next tactic:
exact inv h
theorem zpow_of_gcd_eq_one (h : IsPrimitiveRoot ζ k) (i : ℤ) (hi : i.gcd k = 1) :
    IsPrimitiveRoot (ζ ^ i) 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 : ℕ
ζ : G
h : IsPrimitiveRoot ζ k
i : ℤ
hi : Int.gcd i ↑k = 1
⊢ IsPrimitiveRoot (ζ ^ i) k

Next tactic:
by_cases h0 : 0 ≤ i
theorem zpow_of_gcd_eq_one (h : IsPrimitiveRoot ζ k) (i : ℤ) (hi : i.gcd k = 1) :
    IsPrimitiveRoot (ζ ^ i) k := by
  by_cases h0 : 0 ≤ i
  · 

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 : ℕ
ζ : G
h : IsPrimitiveRoot ζ k
i : ℤ
hi : Int.gcd i ↑k = 1
h0 : 0 ≤ i
⊢ IsPrimitiveRoot (ζ ^ i) k

Next tactic:
lift i to ℕ using h0
theorem zpow_of_gcd_eq_one (h : IsPrimitiveRoot ζ k) (i : ℤ) (hi : i.gcd k = 1) :
    IsPrimitiveRoot (ζ ^ i) k := by
  by_cases h0 : 0 ≤ i
  · lift i to ℕ using h0
    

Proof state:
case pos.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 : ℕ
ζ : G
h : IsPrimitiveRoot ζ k
i : ℕ
hi : Int.gcd ↑i ↑k = 1
⊢ IsPrimitiveRoot (ζ ^ ↑i) k

Next tactic:
rw [zpow_ofNat]
theorem zpow_of_gcd_eq_one (h : IsPrimitiveRoot ζ k) (i : ℤ) (hi : i.gcd k = 1) :
    IsPrimitiveRoot (ζ ^ i) k := by
  by_cases h0 : 0 ≤ i
  · lift i to ℕ using h0
    rw [zpow_ofNat]
    

Proof state:
case pos.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 : ℕ
ζ : G
h : IsPrimitiveRoot ζ k
i : ℕ
hi : Int.gcd ↑i ↑k = 1
⊢ IsPrimitiveRoot (ζ ^ i) k

Next tactic:
exact h.pow_of_coprime i hi
theorem zpow_of_gcd_eq_one (h : IsPrimitiveRoot ζ k) (i : ℤ) (hi : i.gcd k = 1) :
    IsPrimitiveRoot (ζ ^ i) k := by
  by_cases h0 : 0 ≤ i
  · lift i to ℕ using h0
    rw [zpow_ofNat]
    exact h.pow_of_coprime i hi
  

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 : ℕ
ζ : G
h : IsPrimitiveRoot ζ k
i : ℤ
hi : Int.gcd i ↑k = 1
h0 : ¬0 ≤ i
⊢ IsPrimitiveRoot (ζ ^ i) k

Next tactic:
have : 0 ≤ -i := by simp only [not_le, neg_nonneg] at h0 ⊢; exact le_of_lt h0
theorem zpow_of_gcd_eq_one (h : IsPrimitiveRoot ζ k) (i : ℤ) (hi : i.gcd k = 1) :
    IsPrimitiveRoot (ζ ^ i) k := by
  by_cases h0 : 0 ≤ i
  · lift i to ℕ using h0
    rw [zpow_ofNat]
    exact h.pow_of_coprime i hi
  have : 0 ≤ -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 : ℕ
ζ : G
h : IsPrimitiveRoot ζ k
i : ℤ
hi : Int.gcd i ↑k = 1
h0 : ¬0 ≤ i
⊢ 0 ≤ -i

Next tactic:
simp only [not_le, neg_nonneg] at h0 ⊢
theorem zpow_of_gcd_eq_one (h : IsPrimitiveRoot ζ k) (i : ℤ) (hi : i.gcd k = 1) :
    IsPrimitiveRoot (ζ ^ i) k := by
  by_cases h0 : 0 ≤ i
  · lift i to ℕ using h0
    rw [zpow_ofNat]
    exact h.pow_of_coprime i hi
  have : 0 ≤ -i := by simp only [not_le, neg_nonneg] at h0 ⊢; 

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 : ℕ
ζ : G
h : IsPrimitiveRoot ζ k
i : ℤ
hi : Int.gcd i ↑k = 1
h0 : i < 0
⊢ i ≤ 0

Next tactic:
exact le_of_lt h0
theorem zpow_of_gcd_eq_one (h : IsPrimitiveRoot ζ k) (i : ℤ) (hi : i.gcd k = 1) :
    IsPrimitiveRoot (ζ ^ i) k := by
  by_cases h0 : 0 ≤ i
  · lift i to ℕ using h0
    rw [zpow_ofNat]
    exact h.pow_of_coprime i hi
  have : 0 ≤ -i := by simp only [not_le, neg_nonneg] at h0 ⊢; exact le_of_lt 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 : ℕ
ζ : G
h : IsPrimitiveRoot ζ k
i : ℤ
hi : Int.gcd i ↑k = 1
h0 : ¬0 ≤ i
this : 0 ≤ -i
⊢ IsPrimitiveRoot (ζ ^ i) k

Next tactic:
lift -i to ℕ using this with i' hi'
theorem zpow_of_gcd_eq_one (h : IsPrimitiveRoot ζ k) (i : ℤ) (hi : i.gcd k = 1) :
    IsPrimitiveRoot (ζ ^ i) k := by
  by_cases h0 : 0 ≤ i
  · lift i to ℕ using h0
    rw [zpow_ofNat]
    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'
  

Proof state:
case neg.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 : ℕ
ζ : G
h : IsPrimitiveRoot ζ k
i : ℤ
hi : Int.gcd i ↑k = 1
h0 : ¬0 ≤ i
i' : ℕ
hi' : ↑i' = -i
⊢ IsPrimitiveRoot (ζ ^ i) k

Next tactic:
rw [← inv_iff, ← zpow_neg, ← hi', zpow_ofNat]
theorem zpow_of_gcd_eq_one (h : IsPrimitiveRoot ζ k) (i : ℤ) (hi : i.gcd k = 1) :
    IsPrimitiveRoot (ζ ^ i) k := by
  by_cases h0 : 0 ≤ i
  · lift i to ℕ using h0
    rw [zpow_ofNat]
    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]
  

Proof state:
case neg.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 : ℕ
ζ : G
h : IsPrimitiveRoot ζ k
i : ℤ
hi : Int.gcd i ↑k = 1
h0 : ¬0 ≤ i
i' : ℕ
hi' : ↑i' = -i
⊢ IsPrimitiveRoot (ζ ^ i') k

Next tactic:
apply h.pow_of_coprime
theorem zpow_of_gcd_eq_one (h : IsPrimitiveRoot ζ k) (i : ℤ) (hi : i.gcd k = 1) :
    IsPrimitiveRoot (ζ ^ i) k := by
  by_cases h0 : 0 ≤ i
  · lift i to ℕ using h0
    rw [zpow_ofNat]
    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]
  apply h.pow_of_coprime
  

Proof state:
case neg.intro.hi
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 : ℕ
ζ : G
h : IsPrimitiveRoot ζ k
i : ℤ
hi : Int.gcd i ↑k = 1
h0 : ¬0 ≤ i
i' : ℕ
hi' : ↑i' = -i
⊢ Nat.Coprime i' k

Next tactic:
rw [Int.gcd, ← Int.natAbs_neg, ← hi'] at hi
theorem zpow_of_gcd_eq_one (h : IsPrimitiveRoot ζ k) (i : ℤ) (hi : i.gcd k = 1) :
    IsPrimitiveRoot (ζ ^ i) k := by
  by_cases h0 : 0 ≤ i
  · lift i to ℕ using h0
    rw [zpow_ofNat]
    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]
  apply h.pow_of_coprime
  rw [Int.gcd, ← Int.natAbs_neg, ← hi'] at hi
  

Proof state:
case neg.intro.hi
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 : ℕ
ζ : G
h : IsPrimitiveRoot ζ k
i : ℤ
h0 : ¬0 ≤ i
i' : ℕ
hi : Nat.gcd (Int.natAbs ↑i') (Int.natAbs ↑k) = 1
hi' : ↑i' = -i
⊢ Nat.Coprime i' k

Next tactic:
exact hi
@[simp]
theorem primitiveRoots_one : primitiveRoots 1 R = {(1 : 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 : ℕ
ζ : R
inst✝¹ : CommRing R
inst✝ : IsDomain R
⊢ primitiveRoots 1 R = {1}

Next tactic:
apply Finset.eq_singleton_iff_unique_mem.2
@[simp]
theorem primitiveRoots_one : primitiveRoots 1 R = {(1 : R)} := by
  apply Finset.eq_singleton_iff_unique_mem.2
  

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 : ℕ
ζ : R
inst✝¹ : CommRing R
inst✝ : IsDomain R
⊢ 1 ∈ primitiveRoots 1 R ∧ ∀ x ∈ primitiveRoots 1 R, x = 1

Next tactic:
constructor
@[simp]
theorem primitiveRoots_one : primitiveRoots 1 R = {(1 : R)} := by
  apply Finset.eq_singleton_iff_unique_mem.2
  constructor
  · 

Proof state:
case left
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 : ℕ
ζ : R
inst✝¹ : CommRing R
inst✝ : IsDomain R
⊢ 1 ∈ primitiveRoots 1 R

Next tactic:
simp only [IsPrimitiveRoot.one_right_iff, mem_primitiveRoots zero_lt_one]
@[simp]
theorem primitiveRoots_one : primitiveRoots 1 R = {(1 : R)} := by
  apply Finset.eq_singleton_iff_unique_mem.2
  constructor
  · simp only [IsPrimitiveRoot.one_right_iff, mem_primitiveRoots zero_lt_one]
  · 

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 : ℕ
ζ : R
inst✝¹ : CommRing R
inst✝ : IsDomain R
⊢ ∀ x ∈ primitiveRoots 1 R, x = 1

Next tactic:
intro x hx
@[simp]
theorem primitiveRoots_one : primitiveRoots 1 R = {(1 : R)} := by
  apply Finset.eq_singleton_iff_unique_mem.2
  constructor
  · simp only [IsPrimitiveRoot.one_right_iff, mem_primitiveRoots zero_lt_one]
  · intro x hx
    

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 : ℕ
ζ : R
inst✝¹ : CommRing R
inst✝ : IsDomain R
x : R
hx : x ∈ primitiveRoots 1 R
⊢ x = 1

Next tactic:
rw [mem_primitiveRoots zero_lt_one, IsPrimitiveRoot.one_right_iff] at hx
@[simp]
theorem primitiveRoots_one : primitiveRoots 1 R = {(1 : R)} := by
  apply Finset.eq_singleton_iff_unique_mem.2
  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
    

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 : ℕ
ζ : R
inst✝¹ : CommRing R
inst✝ : IsDomain R
x : R
hx : x = 1
⊢ x = 1

Next tactic:
exact hx
theorem neZero' {n : ℕ+} (hζ : IsPrimitiveRoot ζ n) : NeZero ((n : ℕ) : 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 : ℕ
ζ : R
inst✝¹ : CommRing R
inst✝ : IsDomain R
n : ℕ+
hζ : IsPrimitiveRoot ζ ↑n
⊢ NeZero ↑↑n

Next tactic:
let p := ringChar R
theorem neZero' {n : ℕ+} (hζ : IsPrimitiveRoot ζ n) : NeZero ((n : ℕ) : R) := by
  let p := ringChar R
  

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 : ℕ
ζ : R
inst✝¹ : CommRing R
inst✝ : IsDomain R
n : ℕ+
hζ : IsPrimitiveRoot ζ ↑n
p : ℕ := ringChar R
⊢ NeZero ↑↑n

Next tactic:
have hfin := multiplicity.finite_nat_iff.2 ⟨CharP.char_ne_one R p, n.pos⟩
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⟩
  

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 : ℕ
ζ : R
inst✝¹ : CommRing R
inst✝ : IsDomain R
n : ℕ+
hζ : IsPrimitiveRoot ζ ↑n
p : ℕ := ringChar R
hfin : multiplicity.Finite p ↑n
⊢ NeZero ↑↑n

Next tactic:
obtain ⟨m, hm⟩ := multiplicity.exists_eq_pow_mul_and_not_dvd hfin
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
  

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 : ℕ
ζ : R
inst✝¹ : CommRing R
inst✝ : IsDomain R
n : ℕ+
hζ : IsPrimitiveRoot ζ ↑n
p : ℕ := ringChar R
hfin : multiplicity.Finite p ↑n
m : ℕ
hm : ↑n = p ^ Part.get (multiplicity p ↑n) hfin * m ∧ ¬p ∣ m
⊢ NeZero ↑↑n

Next tactic:
by_cases hp : p ∣ n