l3lab/ntp-mathlib huggingface dataset:
@[to_additive]
theorem exponent_ne_zero_iff_range_orderOf_finite (h : ∀ g : G, 0 < orderOf g) :
    exponent G ≠ 0 ↔ (Set.range (orderOf : G → ℕ)).Finite := by
  refine' ⟨fun he => _, fun he => _⟩
  · by_contra h
    obtain ⟨m, ⟨t, rfl⟩, het⟩ := Set.Infinite.exists_gt h (exponent G)
    exact pow_ne_one_of_lt_orderOf' he het (pow_exponent_eq_one t)
  · lift Set.range (orderOf (G := G)) to Finset ℕ using he with t ht
    have htpos : 0 < t.prod id := by
      refine' Finset.prod_pos fun a ha => _
      rw [← Finset.mem_coe, ht] at ha
      obtain ⟨k, rfl⟩ := ha
      exact h k
    suffices exponent G ∣ t.prod id by
      intro h
      rw [h, zero_dvd_iff] at this
      exact htpos.ne' this
    

Proof state:
case refine'_2.intro
G : Type u
inst✝ : Monoid G
h : ∀ (g : G), 0 < orderOf g
t : Finset ℕ
ht : ↑t = Set.range orderOf
exponent_ne_zero_iff_range_orderOf_finite✝ exponent_ne_zero_iff_range_orderOf_finite :
  (∀ (g : G), 0 < orderOf g) → (exponent G ≠ 0 ↔ Set.Finite ↑t)
htpos : 0 < Finset.prod t id
⊢ exponent G ∣ Finset.prod t id

Next tactic:
refine' exponent_dvd_of_forall_pow_eq_one _ _ fun g => _
@[to_additive]
theorem exponent_ne_zero_iff_range_orderOf_finite (h : ∀ g : G, 0 < orderOf g) :
    exponent G ≠ 0 ↔ (Set.range (orderOf : G → ℕ)).Finite := by
  refine' ⟨fun he => _, fun he => _⟩
  · by_contra h
    obtain ⟨m, ⟨t, rfl⟩, het⟩ := Set.Infinite.exists_gt h (exponent G)
    exact pow_ne_one_of_lt_orderOf' he het (pow_exponent_eq_one t)
  · lift Set.range (orderOf (G := G)) to Finset ℕ using he with t ht
    have htpos : 0 < t.prod id := by
      refine' Finset.prod_pos fun a ha => _
      rw [← Finset.mem_coe, ht] at ha
      obtain ⟨k, rfl⟩ := ha
      exact h k
    suffices exponent G ∣ t.prod id by
      intro h
      rw [h, zero_dvd_iff] at this
      exact htpos.ne' this
    refine' exponent_dvd_of_forall_pow_eq_one _ _ fun g => _
    

Proof state:
case refine'_2.intro
G : Type u
inst✝ : Monoid G
h : ∀ (g : G), 0 < orderOf g
t : Finset ℕ
ht : ↑t = Set.range orderOf
exponent_ne_zero_iff_range_orderOf_finite✝ exponent_ne_zero_iff_range_orderOf_finite :
  (∀ (g : G), 0 < orderOf g) → (exponent G ≠ 0 ↔ Set.Finite ↑t)
htpos : 0 < Finset.prod t id
g : G
⊢ g ^ Finset.prod t id = 1

Next tactic:
rw [← pow_mod_orderOf, Nat.mod_eq_zero_of_dvd, pow_zero g]
@[to_additive]
theorem exponent_ne_zero_iff_range_orderOf_finite (h : ∀ g : G, 0 < orderOf g) :
    exponent G ≠ 0 ↔ (Set.range (orderOf : G → ℕ)).Finite := by
  refine' ⟨fun he => _, fun he => _⟩
  · by_contra h
    obtain ⟨m, ⟨t, rfl⟩, het⟩ := Set.Infinite.exists_gt h (exponent G)
    exact pow_ne_one_of_lt_orderOf' he het (pow_exponent_eq_one t)
  · lift Set.range (orderOf (G := G)) to Finset ℕ using he with t ht
    have htpos : 0 < t.prod id := by
      refine' Finset.prod_pos fun a ha => _
      rw [← Finset.mem_coe, ht] at ha
      obtain ⟨k, rfl⟩ := ha
      exact h k
    suffices exponent G ∣ t.prod id by
      intro h
      rw [h, zero_dvd_iff] at this
      exact htpos.ne' this
    refine' exponent_dvd_of_forall_pow_eq_one _ _ fun g => _
    rw [← pow_mod_orderOf, Nat.mod_eq_zero_of_dvd, pow_zero g]
    

Proof state:
case refine'_2.intro
G : Type u
inst✝ : Monoid G
h : ∀ (g : G), 0 < orderOf g
t : Finset ℕ
ht : ↑t = Set.range orderOf
exponent_ne_zero_iff_range_orderOf_finite✝ exponent_ne_zero_iff_range_orderOf_finite :
  (∀ (g : G), 0 < orderOf g) → (exponent G ≠ 0 ↔ Set.Finite ↑t)
htpos : 0 < Finset.prod t id
g : G
⊢ orderOf g ∣ Finset.prod t id

Next tactic:
apply Finset.dvd_prod_of_mem
@[to_additive]
theorem exponent_ne_zero_iff_range_orderOf_finite (h : ∀ g : G, 0 < orderOf g) :
    exponent G ≠ 0 ↔ (Set.range (orderOf : G → ℕ)).Finite := by
  refine' ⟨fun he => _, fun he => _⟩
  · by_contra h
    obtain ⟨m, ⟨t, rfl⟩, het⟩ := Set.Infinite.exists_gt h (exponent G)
    exact pow_ne_one_of_lt_orderOf' he het (pow_exponent_eq_one t)
  · lift Set.range (orderOf (G := G)) to Finset ℕ using he with t ht
    have htpos : 0 < t.prod id := by
      refine' Finset.prod_pos fun a ha => _
      rw [← Finset.mem_coe, ht] at ha
      obtain ⟨k, rfl⟩ := ha
      exact h k
    suffices exponent G ∣ t.prod id by
      intro h
      rw [h, zero_dvd_iff] at this
      exact htpos.ne' this
    refine' exponent_dvd_of_forall_pow_eq_one _ _ fun g => _
    rw [← pow_mod_orderOf, Nat.mod_eq_zero_of_dvd, pow_zero g]
    apply Finset.dvd_prod_of_mem
    

Proof state:
case refine'_2.intro.ha
G : Type u
inst✝ : Monoid G
h : ∀ (g : G), 0 < orderOf g
t : Finset ℕ
ht : ↑t = Set.range orderOf
exponent_ne_zero_iff_range_orderOf_finite✝ exponent_ne_zero_iff_range_orderOf_finite :
  (∀ (g : G), 0 < orderOf g) → (exponent G ≠ 0 ↔ Set.Finite ↑t)
htpos : 0 < Finset.prod t id
g : G
⊢ Function.minimalPeriod (fun x => g * x) 1 ∈ t

Next tactic:
rw [← Finset.mem_coe, ht]
@[to_additive]
theorem exponent_ne_zero_iff_range_orderOf_finite (h : ∀ g : G, 0 < orderOf g) :
    exponent G ≠ 0 ↔ (Set.range (orderOf : G → ℕ)).Finite := by
  refine' ⟨fun he => _, fun he => _⟩
  · by_contra h
    obtain ⟨m, ⟨t, rfl⟩, het⟩ := Set.Infinite.exists_gt h (exponent G)
    exact pow_ne_one_of_lt_orderOf' he het (pow_exponent_eq_one t)
  · lift Set.range (orderOf (G := G)) to Finset ℕ using he with t ht
    have htpos : 0 < t.prod id := by
      refine' Finset.prod_pos fun a ha => _
      rw [← Finset.mem_coe, ht] at ha
      obtain ⟨k, rfl⟩ := ha
      exact h k
    suffices exponent G ∣ t.prod id by
      intro h
      rw [h, zero_dvd_iff] at this
      exact htpos.ne' this
    refine' exponent_dvd_of_forall_pow_eq_one _ _ fun g => _
    rw [← pow_mod_orderOf, Nat.mod_eq_zero_of_dvd, pow_zero g]
    apply Finset.dvd_prod_of_mem
    rw [← Finset.mem_coe, ht]
    

Proof state:
case refine'_2.intro.ha
G : Type u
inst✝ : Monoid G
h : ∀ (g : G), 0 < orderOf g
t : Finset ℕ
ht : ↑t = Set.range orderOf
exponent_ne_zero_iff_range_orderOf_finite✝ exponent_ne_zero_iff_range_orderOf_finite :
  (∀ (g : G), 0 < orderOf g) → (exponent G ≠ 0 ↔ Set.Finite ↑t)
htpos : 0 < Finset.prod t id
g : G
⊢ Function.minimalPeriod (fun x => g * x) 1 ∈ Set.range orderOf

Next tactic:
exact Set.mem_range_self g
@[to_additive]
theorem exponent_eq_zero_iff_range_orderOf_infinite (h : ∀ g : G, 0 < orderOf g) :
    exponent G = 0 ↔ (Set.range (orderOf : G → ℕ)).Infinite := by
  

Proof state:
G : Type u
inst✝ : Monoid G
h : ∀ (g : G), 0 < orderOf g
⊢ exponent G = 0 ↔ Set.Infinite (Set.range orderOf)

Next tactic:
have := exponent_ne_zero_iff_range_orderOf_finite h
@[to_additive]
theorem exponent_eq_zero_iff_range_orderOf_infinite (h : ∀ g : G, 0 < orderOf g) :
    exponent G = 0 ↔ (Set.range (orderOf : G → ℕ)).Infinite := by
  have := exponent_ne_zero_iff_range_orderOf_finite h
  

Proof state:
G : Type u
inst✝ : Monoid G
h : ∀ (g : G), 0 < orderOf g
this : exponent G ≠ 0 ↔ Set.Finite (Set.range orderOf)
⊢ exponent G = 0 ↔ Set.Infinite (Set.range orderOf)

Next tactic:
rwa [Ne.def, not_iff_comm, Iff.comm] at this
@[to_additive lcm_addOrder_eq_exponent]
theorem lcm_order_eq_exponent [Fintype G] : (Finset.univ : Finset G).lcm orderOf = exponent G := by
  

Proof state:
G : Type u
inst✝¹ : Monoid G
inst✝ : Fintype G
⊢ Finset.lcm Finset.univ orderOf = exponent G

Next tactic:
apply Nat.dvd_antisymm (lcm_orderOf_dvd_exponent G)
@[to_additive lcm_addOrder_eq_exponent]
theorem lcm_order_eq_exponent [Fintype G] : (Finset.univ : Finset G).lcm orderOf = exponent G := by
  apply Nat.dvd_antisymm (lcm_orderOf_dvd_exponent G)
  

Proof state:
G : Type u
inst✝¹ : Monoid G
inst✝ : Fintype G
⊢ exponent G ∣ Finset.lcm Finset.univ orderOf

Next tactic:
refine' exponent_dvd_of_forall_pow_eq_one G _ fun g => _
@[to_additive lcm_addOrder_eq_exponent]
theorem lcm_order_eq_exponent [Fintype G] : (Finset.univ : Finset G).lcm orderOf = exponent G := by
  apply Nat.dvd_antisymm (lcm_orderOf_dvd_exponent G)
  refine' exponent_dvd_of_forall_pow_eq_one G _ fun g => _
  

Proof state:
G : Type u
inst✝¹ : Monoid G
inst✝ : Fintype G
g : G
⊢ g ^ Finset.lcm Finset.univ orderOf = 1

Next tactic:
obtain ⟨m, hm⟩ : orderOf g ∣ Finset.univ.lcm orderOf := Finset.dvd_lcm (Finset.mem_univ g)
@[to_additive lcm_addOrder_eq_exponent]
theorem lcm_order_eq_exponent [Fintype G] : (Finset.univ : Finset G).lcm orderOf = exponent G := by
  apply Nat.dvd_antisymm (lcm_orderOf_dvd_exponent G)
  refine' exponent_dvd_of_forall_pow_eq_one G _ fun g => _
  obtain ⟨m, hm⟩ : orderOf g ∣ Finset.univ.lcm orderOf := Finset.dvd_lcm (Finset.mem_univ g)
  

Proof state:
case intro
G : Type u
inst✝¹ : Monoid G
inst✝ : Fintype G
g : G
m : ℕ
hm : Finset.lcm Finset.univ orderOf = orderOf g * m
⊢ g ^ Finset.lcm Finset.univ orderOf = 1

Next tactic:
rw [hm, pow_mul, pow_orderOf_eq_one, one_pow]
@[to_additive]
theorem exponent_ne_zero_of_finite [Finite G] : exponent G ≠ 0 := by
  

Proof state:
G : Type u
inst✝¹ : LeftCancelMonoid G
inst✝ : Finite G
⊢ exponent G ≠ 0

Next tactic:
cases nonempty_fintype G
@[to_additive]
theorem exponent_ne_zero_of_finite [Finite G] : exponent G ≠ 0 := by
  cases nonempty_fintype G
  

Proof state:
case intro
G : Type u
inst✝¹ : LeftCancelMonoid G
inst✝ : Finite G
val✝ : Fintype G
⊢ exponent G ≠ 0

Next tactic:
simpa [← lcm_order_eq_exponent, Finset.lcm_eq_zero_iff] using fun x => (orderOf_pos x).ne'
@[to_additive]
theorem exponent_eq_iSup_orderOf (h : ∀ g : G, 0 < orderOf g) :
    exponent G = ⨆ g : G, orderOf g := by
  

Proof state:
G : Type u
inst✝ : CommMonoid G
h : ∀ (g : G), 0 < orderOf g
⊢ exponent G = ⨆ g, orderOf g

Next tactic:
rw [iSup]
@[to_additive]
theorem exponent_eq_iSup_orderOf (h : ∀ g : G, 0 < orderOf g) :
    exponent G = ⨆ g : G, orderOf g := by
  rw [iSup]
  

Proof state:
G : Type u
inst✝ : CommMonoid G
h : ∀ (g : G), 0 < orderOf g
⊢ exponent G = sSup (Set.range fun g => orderOf g)

Next tactic:
rcases eq_or_ne (exponent G) 0 with (he | he)
@[to_additive]
theorem exponent_eq_iSup_orderOf (h : ∀ g : G, 0 < orderOf g) :
    exponent G = ⨆ g : G, orderOf g := by
  rw [iSup]
  rcases eq_or_ne (exponent G) 0 with (he | he)
  · 

Proof state:
case inl
G : Type u
inst✝ : CommMonoid G
h : ∀ (g : G), 0 < orderOf g
he : exponent G = 0
⊢ exponent G = sSup (Set.range fun g => orderOf g)

Next tactic:
rw [he, Set.Infinite.Nat.sSup_eq_zero <| (exponent_eq_zero_iff_range_orderOf_infinite h).1 he]
@[to_additive]
theorem exponent_eq_iSup_orderOf (h : ∀ g : G, 0 < orderOf g) :
    exponent G = ⨆ g : G, orderOf g := by
  rw [iSup]
  rcases eq_or_ne (exponent G) 0 with (he | he)
  · rw [he, Set.Infinite.Nat.sSup_eq_zero <| (exponent_eq_zero_iff_range_orderOf_infinite h).1 he]
  

Proof state:
case inr
G : Type u
inst✝ : CommMonoid G
h : ∀ (g : G), 0 < orderOf g
he : exponent G ≠ 0
⊢ exponent G = sSup (Set.range fun g => orderOf g)

Next tactic:
have hne : (Set.range (orderOf : G → ℕ)).Nonempty := ⟨1, 1, orderOf_one⟩
@[to_additive]
theorem exponent_eq_iSup_orderOf (h : ∀ g : G, 0 < orderOf g) :
    exponent G = ⨆ g : G, orderOf g := by
  rw [iSup]
  rcases eq_or_ne (exponent G) 0 with (he | he)
  · rw [he, Set.Infinite.Nat.sSup_eq_zero <| (exponent_eq_zero_iff_range_orderOf_infinite h).1 he]
  have hne : (Set.range (orderOf : G → ℕ)).Nonempty := ⟨1, 1, orderOf_one⟩
  

Proof state:
case inr
G : Type u
inst✝ : CommMonoid G
h : ∀ (g : G), 0 < orderOf g
he : exponent G ≠ 0
hne : Set.Nonempty (Set.range orderOf)
⊢ exponent G = sSup (Set.range fun g => orderOf g)

Next tactic:
have hfin : (Set.range (orderOf : G → ℕ)).Finite := by
    rwa [← exponent_ne_zero_iff_range_orderOf_finite h]
@[to_additive]
theorem exponent_eq_iSup_orderOf (h : ∀ g : G, 0 < orderOf g) :
    exponent G = ⨆ g : G, orderOf g := by
  rw [iSup]
  rcases eq_or_ne (exponent G) 0 with (he | he)
  · rw [he, Set.Infinite.Nat.sSup_eq_zero <| (exponent_eq_zero_iff_range_orderOf_infinite h).1 he]
  have hne : (Set.range (orderOf : G → ℕ)).Nonempty := ⟨1, 1, orderOf_one⟩
  have hfin : (Set.range (orderOf : G → ℕ)).Finite := by
    

Proof state:
G : Type u
inst✝ : CommMonoid G
h : ∀ (g : G), 0 < orderOf g
he : exponent G ≠ 0
hne : Set.Nonempty (Set.range orderOf)
⊢ Set.Finite (Set.range orderOf)

Next tactic:
rwa [← exponent_ne_zero_iff_range_orderOf_finite h]
@[to_additive]
theorem exponent_eq_iSup_orderOf (h : ∀ g : G, 0 < orderOf g) :
    exponent G = ⨆ g : G, orderOf g := by
  rw [iSup]
  rcases eq_or_ne (exponent G) 0 with (he | he)
  · rw [he, Set.Infinite.Nat.sSup_eq_zero <| (exponent_eq_zero_iff_range_orderOf_infinite h).1 he]
  have hne : (Set.range (orderOf : G → ℕ)).Nonempty := ⟨1, 1, orderOf_one⟩
  have hfin : (Set.range (orderOf : G → ℕ)).Finite := by
    rwa [← exponent_ne_zero_iff_range_orderOf_finite h]
  

Proof state:
case inr
G : Type u
inst✝ : CommMonoid G
h : ∀ (g : G), 0 < orderOf g
he : exponent G ≠ 0
hne : Set.Nonempty (Set.range orderOf)
hfin : Set.Finite (Set.range orderOf)
⊢ exponent G = sSup (Set.range fun g => orderOf g)

Next tactic:
obtain ⟨t, ht⟩ := hne.cSup_mem hfin
@[to_additive]
theorem exponent_eq_iSup_orderOf (h : ∀ g : G, 0 < orderOf g) :
    exponent G = ⨆ g : G, orderOf g := by
  rw [iSup]
  rcases eq_or_ne (exponent G) 0 with (he | he)
  · rw [he, Set.Infinite.Nat.sSup_eq_zero <| (exponent_eq_zero_iff_range_orderOf_infinite h).1 he]
  have hne : (Set.range (orderOf : G → ℕ)).Nonempty := ⟨1, 1, orderOf_one⟩
  have hfin : (Set.range (orderOf : G → ℕ)).Finite := by
    rwa [← exponent_ne_zero_iff_range_orderOf_finite h]
  obtain ⟨t, ht⟩ := hne.cSup_mem hfin
  

Proof state:
case inr.intro
G : Type u
inst✝ : CommMonoid G
h : ∀ (g : G), 0 < orderOf g
he : exponent G ≠ 0
hne : Set.Nonempty (Set.range orderOf)
hfin : Set.Finite (Set.range orderOf)
t : G
ht : orderOf t = sSup (Set.range orderOf)
⊢ exponent G = sSup (Set.range fun g => orderOf g)

Next tactic:
apply Nat.dvd_antisymm _
@[to_additive]
theorem exponent_eq_iSup_orderOf (h : ∀ g : G, 0 < orderOf g) :
    exponent G = ⨆ g : G, orderOf g := by
  rw [iSup]
  rcases eq_or_ne (exponent G) 0 with (he | he)
  · rw [he, Set.Infinite.Nat.sSup_eq_zero <| (exponent_eq_zero_iff_range_orderOf_infinite h).1 he]
  have hne : (Set.range (orderOf : G → ℕ)).Nonempty := ⟨1, 1, orderOf_one⟩
  have hfin : (Set.range (orderOf : G → ℕ)).Finite := by
    rwa [← exponent_ne_zero_iff_range_orderOf_finite h]
  obtain ⟨t, ht⟩ := hne.cSup_mem hfin
  apply Nat.dvd_antisymm _
  · 

Proof state:
case inr.intro
G : Type u
inst✝ : CommMonoid G
h : ∀ (g : G), 0 < orderOf g
he : exponent G ≠ 0
hne : Set.Nonempty (Set.range orderOf)
hfin : Set.Finite (Set.range orderOf)
t : G
ht : orderOf t = sSup (Set.range orderOf)
⊢ sSup (Set.range fun g => orderOf g) ∣ exponent G

Next tactic:
rw [← ht]
@[to_additive]
theorem exponent_eq_iSup_orderOf (h : ∀ g : G, 0 < orderOf g) :
    exponent G = ⨆ g : G, orderOf g := by
  rw [iSup]
  rcases eq_or_ne (exponent G) 0 with (he | he)
  · rw [he, Set.Infinite.Nat.sSup_eq_zero <| (exponent_eq_zero_iff_range_orderOf_infinite h).1 he]
  have hne : (Set.range (orderOf : G → ℕ)).Nonempty := ⟨1, 1, orderOf_one⟩
  have hfin : (Set.range (orderOf : G → ℕ)).Finite := by
    rwa [← exponent_ne_zero_iff_range_orderOf_finite h]
  obtain ⟨t, ht⟩ := hne.cSup_mem hfin
  apply Nat.dvd_antisymm _
  · rw [← ht]
    

Proof state:
case inr.intro
G : Type u
inst✝ : CommMonoid G
h : ∀ (g : G), 0 < orderOf g
he : exponent G ≠ 0
hne : Set.Nonempty (Set.range orderOf)
hfin : Set.Finite (Set.range orderOf)
t : G
ht : orderOf t = sSup (Set.range orderOf)
⊢ orderOf t ∣ exponent G

Next tactic:
apply order_dvd_exponent
@[to_additive]
theorem exponent_eq_iSup_orderOf (h : ∀ g : G, 0 < orderOf g) :
    exponent G = ⨆ g : G, orderOf g := by
  rw [iSup]
  rcases eq_or_ne (exponent G) 0 with (he | he)
  · rw [he, Set.Infinite.Nat.sSup_eq_zero <| (exponent_eq_zero_iff_range_orderOf_infinite h).1 he]
  have hne : (Set.range (orderOf : G → ℕ)).Nonempty := ⟨1, 1, orderOf_one⟩
  have hfin : (Set.range (orderOf : G → ℕ)).Finite := by
    rwa [← exponent_ne_zero_iff_range_orderOf_finite h]
  obtain ⟨t, ht⟩ := hne.cSup_mem hfin
  apply Nat.dvd_antisymm _
  · rw [← ht]
    apply order_dvd_exponent
  

Proof state:
G : Type u
inst✝ : CommMonoid G
h : ∀ (g : G), 0 < orderOf g
he : exponent G ≠ 0
hne : Set.Nonempty (Set.range orderOf)
hfin : Set.Finite (Set.range orderOf)
t : G
ht : orderOf t = sSup (Set.range orderOf)
⊢ exponent G ∣ sSup (Set.range fun g => orderOf g)

Next tactic:
refine' Nat.dvd_of_factors_subperm he _
@[to_additive]
theorem exponent_eq_iSup_orderOf (h : ∀ g : G, 0 < orderOf g) :
    exponent G = ⨆ g : G, orderOf g := by
  rw [iSup]
  rcases eq_or_ne (exponent G) 0 with (he | he)
  · rw [he, Set.Infinite.Nat.sSup_eq_zero <| (exponent_eq_zero_iff_range_orderOf_infinite h).1 he]
  have hne : (Set.range (orderOf : G → ℕ)).Nonempty := ⟨1, 1, orderOf_one⟩
  have hfin : (Set.range (orderOf : G → ℕ)).Finite := by
    rwa [← exponent_ne_zero_iff_range_orderOf_finite h]
  obtain ⟨t, ht⟩ := hne.cSup_mem hfin
  apply Nat.dvd_antisymm _
  · rw [← ht]
    apply order_dvd_exponent
  refine' Nat.dvd_of_factors_subperm he _
  

Proof state:
G : Type u
inst✝ : CommMonoid G
h : ∀ (g : G), 0 < orderOf g
he : exponent G ≠ 0
hne : Set.Nonempty (Set.range orderOf)
hfin : Set.Finite (Set.range orderOf)
t : G
ht : orderOf t = sSup (Set.range orderOf)
⊢ List.Subperm (Nat.factors (exponent G)) (Nat.factors (sSup (Set.range fun g => orderOf g)))

Next tactic:
rw [List.subperm_ext_iff]
@[to_additive]
theorem exponent_eq_iSup_orderOf (h : ∀ g : G, 0 < orderOf g) :
    exponent G = ⨆ g : G, orderOf g := by
  rw [iSup]
  rcases eq_or_ne (exponent G) 0 with (he | he)
  · rw [he, Set.Infinite.Nat.sSup_eq_zero <| (exponent_eq_zero_iff_range_orderOf_infinite h).1 he]
  have hne : (Set.range (orderOf : G → ℕ)).Nonempty := ⟨1, 1, orderOf_one⟩
  have hfin : (Set.range (orderOf : G → ℕ)).Finite := by
    rwa [← exponent_ne_zero_iff_range_orderOf_finite h]
  obtain ⟨t, ht⟩ := hne.cSup_mem hfin
  apply Nat.dvd_antisymm _
  · rw [← ht]
    apply order_dvd_exponent
  refine' Nat.dvd_of_factors_subperm he _
  rw [List.subperm_ext_iff]
  

Proof state:
G : Type u
inst✝ : CommMonoid G
h : ∀ (g : G), 0 < orderOf g
he : exponent G ≠ 0
hne : Set.Nonempty (Set.range orderOf)
hfin : Set.Finite (Set.range orderOf)
t : G
ht : orderOf t = sSup (Set.range orderOf)
⊢ ∀ x ∈ Nat.factors (exponent G),
    List.count x (Nat.factors (exponent G)) ≤ List.count x (Nat.factors (sSup (Set.range fun g => orderOf g)))

Next tactic:
by_contra! h
@[to_additive]
theorem exponent_eq_iSup_orderOf (h : ∀ g : G, 0 < orderOf g) :
    exponent G = ⨆ g : G, orderOf g := by
  rw [iSup]
  rcases eq_or_ne (exponent G) 0 with (he | he)
  · rw [he, Set.Infinite.Nat.sSup_eq_zero <| (exponent_eq_zero_iff_range_orderOf_infinite h).1 he]
  have hne : (Set.range (orderOf : G → ℕ)).Nonempty := ⟨1, 1, orderOf_one⟩
  have hfin : (Set.range (orderOf : G → ℕ)).Finite := by
    rwa [← exponent_ne_zero_iff_range_orderOf_finite h]
  obtain ⟨t, ht⟩ := hne.cSup_mem hfin
  apply Nat.dvd_antisymm _
  · rw [← ht]
    apply order_dvd_exponent
  refine' Nat.dvd_of_factors_subperm he _
  rw [List.subperm_ext_iff]
  by_contra! h
  

Proof state:
G : Type u
inst✝ : CommMonoid G
h✝ : ∀ (g : G), 0 < orderOf g
he : exponent G ≠ 0
hne : Set.Nonempty (Set.range orderOf)
hfin : Set.Finite (Set.range orderOf)
t : G
ht : orderOf t = sSup (Set.range orderOf)
h :
  ∃ x ∈ Nat.factors (exponent G),
    List.count x (Nat.factors (sSup (Set.range fun g => orderOf g))) < List.count x (Nat.factors (exponent G))
⊢ False

Next tactic:
obtain ⟨p, hp, hpe⟩ := h
@[to_additive]
theorem exponent_eq_iSup_orderOf (h : ∀ g : G, 0 < orderOf g) :
    exponent G = ⨆ g : G, orderOf g := by
  rw [iSup]
  rcases eq_or_ne (exponent G) 0 with (he | he)
  · rw [he, Set.Infinite.Nat.sSup_eq_zero <| (exponent_eq_zero_iff_range_orderOf_infinite h).1 he]
  have hne : (Set.range (orderOf : G → ℕ)).Nonempty := ⟨1, 1, orderOf_one⟩
  have hfin : (Set.range (orderOf : G → ℕ)).Finite := by
    rwa [← exponent_ne_zero_iff_range_orderOf_finite h]
  obtain ⟨t, ht⟩ := hne.cSup_mem hfin
  apply Nat.dvd_antisymm _
  · rw [← ht]
    apply order_dvd_exponent
  refine' Nat.dvd_of_factors_subperm he _
  rw [List.subperm_ext_iff]
  by_contra! h
  obtain ⟨p, hp, hpe⟩ := h
  

Proof state:
case intro.intro
G : Type u
inst✝ : CommMonoid G
h : ∀ (g : G), 0 < orderOf g
he : exponent G ≠ 0
hne : Set.Nonempty (Set.range orderOf)
hfin : Set.Finite (Set.range orderOf)
t : G
ht : orderOf t = sSup (Set.range orderOf)
p : ℕ
hp : p ∈ Nat.factors (exponent G)
hpe : List.count p (Nat.factors (sSup (Set.range fun g => orderOf g))) < List.count p (Nat.factors (exponent G))
⊢ False

Next tactic:
replace hp := Nat.prime_of_mem_factors hp
@[to_additive]
theorem exponent_eq_iSup_orderOf (h : ∀ g : G, 0 < orderOf g) :
    exponent G = ⨆ g : G, orderOf g := by
  rw [iSup]
  rcases eq_or_ne (exponent G) 0 with (he | he)
  · rw [he, Set.Infinite.Nat.sSup_eq_zero <| (exponent_eq_zero_iff_range_orderOf_infinite h).1 he]
  have hne : (Set.range (orderOf : G → ℕ)).Nonempty := ⟨1, 1, orderOf_one⟩
  have hfin : (Set.range (orderOf : G → ℕ)).Finite := by
    rwa [← exponent_ne_zero_iff_range_orderOf_finite h]
  obtain ⟨t, ht⟩ := hne.cSup_mem hfin
  apply Nat.dvd_antisymm _
  · rw [← ht]
    apply order_dvd_exponent
  refine' Nat.dvd_of_factors_subperm he _
  rw [List.subperm_ext_iff]
  by_contra! h
  obtain ⟨p, hp, hpe⟩ := h
  replace hp := Nat.prime_of_mem_factors hp
  

Proof state:
case intro.intro
G : Type u
inst✝ : CommMonoid G
h : ∀ (g : G), 0 < orderOf g
he : exponent G ≠ 0
hne : Set.Nonempty (Set.range orderOf)
hfin : Set.Finite (Set.range orderOf)
t : G
ht : orderOf t = sSup (Set.range orderOf)
p : ℕ
hpe : List.count p (Nat.factors (sSup (Set.range fun g => orderOf g))) < List.count p (Nat.factors (exponent G))
hp : Nat.Prime p
⊢ False

Next tactic:
simp only [Nat.factors_count_eq] at hpe
@[to_additive]
theorem exponent_eq_iSup_orderOf (h : ∀ g : G, 0 < orderOf g) :
    exponent G = ⨆ g : G, orderOf g := by
  rw [iSup]
  rcases eq_or_ne (exponent G) 0 with (he | he)
  · rw [he, Set.Infinite.Nat.sSup_eq_zero <| (exponent_eq_zero_iff_range_orderOf_infinite h).1 he]
  have hne : (Set.range (orderOf : G → ℕ)).Nonempty := ⟨1, 1, orderOf_one⟩
  have hfin : (Set.range (orderOf : G → ℕ)).Finite := by
    rwa [← exponent_ne_zero_iff_range_orderOf_finite h]
  obtain ⟨t, ht⟩ := hne.cSup_mem hfin
  apply Nat.dvd_antisymm _
  · rw [← ht]
    apply order_dvd_exponent
  refine' Nat.dvd_of_factors_subperm he _
  rw [List.subperm_ext_iff]
  by_contra! h
  obtain ⟨p, hp, hpe⟩ := h
  replace hp := Nat.prime_of_mem_factors hp
  simp only [Nat.factors_count_eq] at hpe
  

Proof state:
case intro.intro
G : Type u
inst✝ : CommMonoid G
h : ∀ (g : G), 0 < orderOf g
he : exponent G ≠ 0
hne : Set.Nonempty (Set.range orderOf)
hfin : Set.Finite (Set.range orderOf)
t : G
ht : orderOf t = sSup (Set.range orderOf)
p : ℕ
hp : Nat.Prime p
hpe : (Nat.factorization (sSup (Set.range fun g => orderOf g))) p < (Nat.factorization (exponent G)) p
⊢ False

Next tactic:
set k := (orderOf t).factorization p with hk
@[to_additive]
theorem exponent_eq_iSup_orderOf (h : ∀ g : G, 0 < orderOf g) :
    exponent G = ⨆ g : G, orderOf g := by
  rw [iSup]
  rcases eq_or_ne (exponent G) 0 with (he | he)
  · rw [he, Set.Infinite.Nat.sSup_eq_zero <| (exponent_eq_zero_iff_range_orderOf_infinite h).1 he]
  have hne : (Set.range (orderOf : G → ℕ)).Nonempty := ⟨1, 1, orderOf_one⟩
  have hfin : (Set.range (orderOf : G → ℕ)).Finite := by
    rwa [← exponent_ne_zero_iff_range_orderOf_finite h]
  obtain ⟨t, ht⟩ := hne.cSup_mem hfin
  apply Nat.dvd_antisymm _
  · rw [← ht]
    apply order_dvd_exponent
  refine' Nat.dvd_of_factors_subperm he _
  rw [List.subperm_ext_iff]
  by_contra! h
  obtain ⟨p, hp, hpe⟩ := h
  replace hp := Nat.prime_of_mem_factors hp
  simp only [Nat.factors_count_eq] at hpe
  set k := (orderOf t).factorization p with hk
  

Proof state:
case intro.intro
G : Type u
inst✝ : CommMonoid G
h : ∀ (g : G), 0 < orderOf g
he : exponent G ≠ 0
hne : Set.Nonempty (Set.range orderOf)
hfin : Set.Finite (Set.range orderOf)
t : G
ht : orderOf t = sSup (Set.range orderOf)
p : ℕ
hp : Nat.Prime p
hpe : (Nat.factorization (sSup (Set.range fun g => orderOf g))) p < (Nat.factorization (exponent G)) p
k : ℕ := (Nat.factorization (orderOf t)) p
hk : k = (Nat.factorization (orderOf t)) p
⊢ False

Next tactic:
obtain ⟨g, hg⟩ := hp.exists_orderOf_eq_pow_factorization_exponent G