l3lab/ntp-mathlib huggingface dataset:
theorem mem_iSup_of_directed {ι} [hι : Nonempty ι] {S : ι → Subsemiring R} (hS : Directed (· ≤ ·) S)
    {x : R} : (x ∈ ⨆ i, S i) ↔ ∃ i, x ∈ S i := by
  refine ⟨?_, fun ⟨i, hi⟩ ↦ le_iSup S i hi⟩
  let U : Subsemiring R :=
    Subsemiring.mk' (⋃ i, (S i : Set R))
      (⨆ i, (S i).toSubmonoid) (Submonoid.coe_iSup_of_directed hS)
      (⨆ i, (S i).toAddSubmonoid) (AddSubmonoid.coe_iSup_of_directed hS)
  -- Porting note: gave the hypothesis an explicit name because `@this` doesn't work
  suffices h : ⨆ i, S i ≤ U by simpa using @h x
  

Proof state:
R : Type u
S✝ : Type v
T : Type w
inst✝² : NonAssocSemiring R
M : Submonoid R
inst✝¹ : NonAssocSemiring S✝
inst✝ : NonAssocSemiring T
ι : Sort u_1
hι : Nonempty ι
S : ι → Subsemiring R
hS : Directed (fun x x_1 => x ≤ x_1) S
x : R
U : Subsemiring R :=
  Subsemiring.mk' (⋃ i, ↑(S i)) (⨆ i, (S i).toSubmonoid) (_ : ↑(⨆ i, (S i).toSubmonoid) = ⋃ i, ↑(S i).toSubmonoid)
    (⨆ i, toAddSubmonoid (S i)) (_ : ↑(⨆ i, toAddSubmonoid (S i)) = ⋃ i, ↑(toAddSubmonoid (S i)))
⊢ ⨆ i, S i ≤ U

Next tactic:
exact iSup_le fun i x hx ↦ Set.mem_iUnion.2 ⟨i, hx⟩
theorem coe_iSup_of_directed {ι} [hι : Nonempty ι] {S : ι → Subsemiring R}
    (hS : Directed (· ≤ ·) S) : ((⨆ i, S i : Subsemiring R) : Set R) = ⋃ i, S i :=
  Set.ext fun x ↦ by 

Proof state:
R : Type u
S✝ : Type v
T : Type w
inst✝² : NonAssocSemiring R
M : Submonoid R
inst✝¹ : NonAssocSemiring S✝
inst✝ : NonAssocSemiring T
ι : Sort u_1
hι : Nonempty ι
S : ι → Subsemiring R
hS : Directed (fun x x_1 => x ≤ x_1) S
x : R
⊢ x ∈ ↑(⨆ i, S i) ↔ x ∈ ⋃ i, ↑(S i)

Next tactic:
simp [mem_iSup_of_directed hS]
theorem mem_sSup_of_directedOn {S : Set (Subsemiring R)} (Sne : S.Nonempty)
    (hS : DirectedOn (· ≤ ·) S) {x : R} : x ∈ sSup S ↔ ∃ s ∈ S, x ∈ s := by
  

Proof state:
R : Type u
S✝ : Type v
T : Type w
inst✝² : NonAssocSemiring R
M : Submonoid R
inst✝¹ : NonAssocSemiring S✝
inst✝ : NonAssocSemiring T
S : Set (Subsemiring R)
Sne : Set.Nonempty S
hS : DirectedOn (fun x x_1 => x ≤ x_1) S
x : R
⊢ x ∈ sSup S ↔ ∃ s ∈ S, x ∈ s

Next tactic:
haveI : Nonempty S := Sne.to_subtype
theorem mem_sSup_of_directedOn {S : Set (Subsemiring R)} (Sne : S.Nonempty)
    (hS : DirectedOn (· ≤ ·) S) {x : R} : x ∈ sSup S ↔ ∃ s ∈ S, x ∈ s := by
  haveI : Nonempty S := Sne.to_subtype
  

Proof state:
R : Type u
S✝ : Type v
T : Type w
inst✝² : NonAssocSemiring R
M : Submonoid R
inst✝¹ : NonAssocSemiring S✝
inst✝ : NonAssocSemiring T
S : Set (Subsemiring R)
Sne : Set.Nonempty S
hS : DirectedOn (fun x x_1 => x ≤ x_1) S
x : R
this : Nonempty ↑S
⊢ x ∈ sSup S ↔ ∃ s ∈ S, x ∈ s

Next tactic:
simp only [sSup_eq_iSup', mem_iSup_of_directed hS.directed_val, SetCoe.exists, Subtype.coe_mk,
    exists_prop]
theorem coe_sSup_of_directedOn {S : Set (Subsemiring R)} (Sne : S.Nonempty)
    (hS : DirectedOn (· ≤ ·) S) : (↑(sSup S) : Set R) = ⋃ s ∈ S, ↑s :=
  Set.ext fun x => by 

Proof state:
R : Type u
S✝ : Type v
T : Type w
inst✝² : NonAssocSemiring R
M : Submonoid R
inst✝¹ : NonAssocSemiring S✝
inst✝ : NonAssocSemiring T
S : Set (Subsemiring R)
Sne : Set.Nonempty S
hS : DirectedOn (fun x x_1 => x ≤ x_1) S
x : R
⊢ x ∈ ↑(sSup S) ↔ x ∈ ⋃ s ∈ S, ↑s

Next tactic:
simp [mem_sSup_of_directedOn Sne hS]
theorem rangeS_top_iff_surjective {f : R →+* S} :
    f.rangeS = (⊤ : Subsemiring S) ↔ Function.Surjective f :=
  SetLike.ext'_iff.trans <| Iff.trans (by 

Proof state:
R : Type u
S : Type v
T : Type w
inst✝⁷ : NonAssocSemiring R
M : Submonoid R
inst✝⁶ : NonAssocSemiring S
inst✝⁵ inst✝⁴ : NonAssocSemiring T
s : Subsemiring R
σR : Type u_1
σS : Type u_2
inst✝³ : SetLike σR R
inst✝² : SetLike σS S
inst✝¹ : SubsemiringClass σR R
inst✝ : SubsemiringClass σS S
f : R →+* S
⊢ ↑(rangeS f) = ↑⊤ ↔ Set.range ⇑f = Set.univ

Next tactic:
rw [coe_rangeS, coe_top]
/-- Restrict a ring homomorphism with a left inverse to a ring isomorphism to its
`RingHom.rangeS`. -/
def ofLeftInverseS {g : S → R} {f : R →+* S} (h : Function.LeftInverse g f) : R ≃+* f.rangeS :=
  { f.rangeSRestrict with
    toFun := fun x => f.rangeSRestrict x
    invFun := fun x => (g ∘ f.rangeS.subtype) x
    left_inv := h
    right_inv := fun x =>
      Subtype.ext <|
        let ⟨x', hx'⟩ := RingHom.mem_rangeS.mp x.prop
        show f (g x) = x by 

Proof state:
R : Type u
S : Type v
T : Type w
inst✝² : NonAssocSemiring R
M : Submonoid R
inst✝¹ : NonAssocSemiring S
inst✝ : NonAssocSemiring T
s t : Subsemiring R
g : S → R
f : R →+* S
h : Function.LeftInverse g ⇑f
src✝ : R →+* ↥(RingHom.rangeS f) := RingHom.rangeSRestrict f
x : ↥(RingHom.rangeS f)
x' : R
hx' : f x' = ↑x
⊢ f (g ↑x) = ↑x

Next tactic:
rw [← hx', h x']
/-- If all the elements of a set `s` commute, then `closure s` is a commutative monoid. -/
def closureCommSemiringOfComm {s : Set R'} (hcomm : ∀ a ∈ s, ∀ b ∈ s, a * b = b * a) :
    CommSemiring (closure s) :=
  { (closure s).toSemiring with
    mul_comm := fun x y => by
      

Proof state:
R : Type u
S : Type v
T : Type w
inst✝³ : NonAssocSemiring R
M : Submonoid R
inst✝² : NonAssocSemiring S
inst✝¹ : NonAssocSemiring T
R' : Type u_1
α : Type u_2
β : Type u_3
inst✝ : Semiring R'
s : Set R'
hcomm : ∀ a ∈ s, ∀ b ∈ s, a * b = b * a
src✝ : Semiring ↥(closure s) := toSemiring (closure s)
x y : ↥(closure s)
⊢ x * y = y * x

Next tactic:
ext
/-- If all the elements of a set `s` commute, then `closure s` is a commutative monoid. -/
def closureCommSemiringOfComm {s : Set R'} (hcomm : ∀ a ∈ s, ∀ b ∈ s, a * b = b * a) :
    CommSemiring (closure s) :=
  { (closure s).toSemiring with
    mul_comm := fun x y => by
      ext
      

Proof state:
case a
R : Type u
S : Type v
T : Type w
inst✝³ : NonAssocSemiring R
M : Submonoid R
inst✝² : NonAssocSemiring S
inst✝¹ : NonAssocSemiring T
R' : Type u_1
α : Type u_2
β : Type u_3
inst✝ : Semiring R'
s : Set R'
hcomm : ∀ a ∈ s, ∀ b ∈ s, a * b = b * a
src✝ : Semiring ↥(closure s) := toSemiring (closure s)
x y : ↥(closure s)
⊢ ↑(x * y) = ↑(y * x)

Next tactic:
simp only [Subsemiring.coe_mul]
/-- If all the elements of a set `s` commute, then `closure s` is a commutative monoid. -/
def closureCommSemiringOfComm {s : Set R'} (hcomm : ∀ a ∈ s, ∀ b ∈ s, a * b = b * a) :
    CommSemiring (closure s) :=
  { (closure s).toSemiring with
    mul_comm := fun x y => by
      ext
      simp only [Subsemiring.coe_mul]
      

Proof state:
case a
R : Type u
S : Type v
T : Type w
inst✝³ : NonAssocSemiring R
M : Submonoid R
inst✝² : NonAssocSemiring S
inst✝¹ : NonAssocSemiring T
R' : Type u_1
α : Type u_2
β : Type u_3
inst✝ : Semiring R'
s : Set R'
hcomm : ∀ a ∈ s, ∀ b ∈ s, a * b = b * a
src✝ : Semiring ↥(closure s) := toSemiring (closure s)
x y : ↥(closure s)
⊢ ↑x * ↑y = ↑y * ↑x

Next tactic:
refine'
        closure_induction₂ x.prop y.prop hcomm (fun x => by simp only [zero_mul, mul_zero])
          (fun x => by simp only [zero_mul, mul_zero]) (fun x => by simp only [one_mul, mul_one])
          (fun x => by simp only [one_mul, mul_one])
          (fun x y z h₁ h₂ => by simp only [add_mul, mul_add, h₁, h₂])
          (fun x y z h₁ h₂ => by simp only [add_mul, mul_add, h₁, h₂])
          (fun x y z h₁ h₂ => by rw [mul_assoc, h₂, ← mul_assoc, h₁, mul_assoc]) fun x y z h₁ h₂ =>
          by rw [← mul_assoc, h₁, mul_assoc, h₂, ← mul_assoc]
/-- If all the elements of a set `s` commute, then `closure s` is a commutative monoid. -/
def closureCommSemiringOfComm {s : Set R'} (hcomm : ∀ a ∈ s, ∀ b ∈ s, a * b = b * a) :
    CommSemiring (closure s) :=
  { (closure s).toSemiring with
    mul_comm := fun x y => by
      ext
      simp only [Subsemiring.coe_mul]
      refine'
        closure_induction₂ x.prop y.prop hcomm (fun x => by 

Proof state:
R : Type u
S : Type v
T : Type w
inst✝³ : NonAssocSemiring R
M : Submonoid R
inst✝² : NonAssocSemiring S
inst✝¹ : NonAssocSemiring T
R' : Type u_1
α : Type u_2
β : Type u_3
inst✝ : Semiring R'
s : Set R'
hcomm : ∀ a ∈ s, ∀ b ∈ s, a * b = b * a
src✝ : Semiring ↥(closure s) := toSemiring (closure s)
x✝ y : ↥(closure s)
x : R'
⊢ 0 * x = x * 0

Next tactic:
simp only [zero_mul, mul_zero]
/-- If all the elements of a set `s` commute, then `closure s` is a commutative monoid. -/
def closureCommSemiringOfComm {s : Set R'} (hcomm : ∀ a ∈ s, ∀ b ∈ s, a * b = b * a) :
    CommSemiring (closure s) :=
  { (closure s).toSemiring with
    mul_comm := fun x y => by
      ext
      simp only [Subsemiring.coe_mul]
      refine'
        closure_induction₂ x.prop y.prop hcomm (fun x => by simp only [zero_mul, mul_zero])
          (fun x => by 

Proof state:
R : Type u
S : Type v
T : Type w
inst✝³ : NonAssocSemiring R
M : Submonoid R
inst✝² : NonAssocSemiring S
inst✝¹ : NonAssocSemiring T
R' : Type u_1
α : Type u_2
β : Type u_3
inst✝ : Semiring R'
s : Set R'
hcomm : ∀ a ∈ s, ∀ b ∈ s, a * b = b * a
src✝ : Semiring ↥(closure s) := toSemiring (closure s)
x✝ y : ↥(closure s)
x : R'
⊢ x * 0 = 0 * x

Next tactic:
simp only [zero_mul, mul_zero]
/-- If all the elements of a set `s` commute, then `closure s` is a commutative monoid. -/
def closureCommSemiringOfComm {s : Set R'} (hcomm : ∀ a ∈ s, ∀ b ∈ s, a * b = b * a) :
    CommSemiring (closure s) :=
  { (closure s).toSemiring with
    mul_comm := fun x y => by
      ext
      simp only [Subsemiring.coe_mul]
      refine'
        closure_induction₂ x.prop y.prop hcomm (fun x => by simp only [zero_mul, mul_zero])
          (fun x => by simp only [zero_mul, mul_zero]) (fun x => by 

Proof state:
R : Type u
S : Type v
T : Type w
inst✝³ : NonAssocSemiring R
M : Submonoid R
inst✝² : NonAssocSemiring S
inst✝¹ : NonAssocSemiring T
R' : Type u_1
α : Type u_2
β : Type u_3
inst✝ : Semiring R'
s : Set R'
hcomm : ∀ a ∈ s, ∀ b ∈ s, a * b = b * a
src✝ : Semiring ↥(closure s) := toSemiring (closure s)
x✝ y : ↥(closure s)
x : R'
⊢ 1 * x = x * 1

Next tactic:
simp only [one_mul, mul_one]
/-- If all the elements of a set `s` commute, then `closure s` is a commutative monoid. -/
def closureCommSemiringOfComm {s : Set R'} (hcomm : ∀ a ∈ s, ∀ b ∈ s, a * b = b * a) :
    CommSemiring (closure s) :=
  { (closure s).toSemiring with
    mul_comm := fun x y => by
      ext
      simp only [Subsemiring.coe_mul]
      refine'
        closure_induction₂ x.prop y.prop hcomm (fun x => by simp only [zero_mul, mul_zero])
          (fun x => by simp only [zero_mul, mul_zero]) (fun x => by simp only [one_mul, mul_one])
          (fun x => by 

Proof state:
R : Type u
S : Type v
T : Type w
inst✝³ : NonAssocSemiring R
M : Submonoid R
inst✝² : NonAssocSemiring S
inst✝¹ : NonAssocSemiring T
R' : Type u_1
α : Type u_2
β : Type u_3
inst✝ : Semiring R'
s : Set R'
hcomm : ∀ a ∈ s, ∀ b ∈ s, a * b = b * a
src✝ : Semiring ↥(closure s) := toSemiring (closure s)
x✝ y : ↥(closure s)
x : R'
⊢ x * 1 = 1 * x

Next tactic:
simp only [one_mul, mul_one]
/-- If all the elements of a set `s` commute, then `closure s` is a commutative monoid. -/
def closureCommSemiringOfComm {s : Set R'} (hcomm : ∀ a ∈ s, ∀ b ∈ s, a * b = b * a) :
    CommSemiring (closure s) :=
  { (closure s).toSemiring with
    mul_comm := fun x y => by
      ext
      simp only [Subsemiring.coe_mul]
      refine'
        closure_induction₂ x.prop y.prop hcomm (fun x => by simp only [zero_mul, mul_zero])
          (fun x => by simp only [zero_mul, mul_zero]) (fun x => by simp only [one_mul, mul_one])
          (fun x => by simp only [one_mul, mul_one])
          (fun x y z h₁ h₂ => by 

Proof state:
R : Type u
S : Type v
T : Type w
inst✝³ : NonAssocSemiring R
M : Submonoid R
inst✝² : NonAssocSemiring S
inst✝¹ : NonAssocSemiring T
R' : Type u_1
α : Type u_2
β : Type u_3
inst✝ : Semiring R'
s : Set R'
hcomm : ∀ a ∈ s, ∀ b ∈ s, a * b = b * a
src✝ : Semiring ↥(closure s) := toSemiring (closure s)
x✝ y✝ : ↥(closure s)
x y z : R'
h₁ : x * z = z * x
h₂ : y * z = z * y
⊢ (x + y) * z = z * (x + y)

Next tactic:
simp only [add_mul, mul_add, h₁, h₂]
/-- If all the elements of a set `s` commute, then `closure s` is a commutative monoid. -/
def closureCommSemiringOfComm {s : Set R'} (hcomm : ∀ a ∈ s, ∀ b ∈ s, a * b = b * a) :
    CommSemiring (closure s) :=
  { (closure s).toSemiring with
    mul_comm := fun x y => by
      ext
      simp only [Subsemiring.coe_mul]
      refine'
        closure_induction₂ x.prop y.prop hcomm (fun x => by simp only [zero_mul, mul_zero])
          (fun x => by simp only [zero_mul, mul_zero]) (fun x => by simp only [one_mul, mul_one])
          (fun x => by simp only [one_mul, mul_one])
          (fun x y z h₁ h₂ => by simp only [add_mul, mul_add, h₁, h₂])
          (fun x y z h₁ h₂ => by 

Proof state:
R : Type u
S : Type v
T : Type w
inst✝³ : NonAssocSemiring R
M : Submonoid R
inst✝² : NonAssocSemiring S
inst✝¹ : NonAssocSemiring T
R' : Type u_1
α : Type u_2
β : Type u_3
inst✝ : Semiring R'
s : Set R'
hcomm : ∀ a ∈ s, ∀ b ∈ s, a * b = b * a
src✝ : Semiring ↥(closure s) := toSemiring (closure s)
x✝ y✝ : ↥(closure s)
x y z : R'
h₁ : x * y = y * x
h₂ : x * z = z * x
⊢ x * (y + z) = (y + z) * x

Next tactic:
simp only [add_mul, mul_add, h₁, h₂]
/-- If all the elements of a set `s` commute, then `closure s` is a commutative monoid. -/
def closureCommSemiringOfComm {s : Set R'} (hcomm : ∀ a ∈ s, ∀ b ∈ s, a * b = b * a) :
    CommSemiring (closure s) :=
  { (closure s).toSemiring with
    mul_comm := fun x y => by
      ext
      simp only [Subsemiring.coe_mul]
      refine'
        closure_induction₂ x.prop y.prop hcomm (fun x => by simp only [zero_mul, mul_zero])
          (fun x => by simp only [zero_mul, mul_zero]) (fun x => by simp only [one_mul, mul_one])
          (fun x => by simp only [one_mul, mul_one])
          (fun x y z h₁ h₂ => by simp only [add_mul, mul_add, h₁, h₂])
          (fun x y z h₁ h₂ => by simp only [add_mul, mul_add, h₁, h₂])
          (fun x y z h₁ h₂ => by 

Proof state:
R : Type u
S : Type v
T : Type w
inst✝³ : NonAssocSemiring R
M : Submonoid R
inst✝² : NonAssocSemiring S
inst✝¹ : NonAssocSemiring T
R' : Type u_1
α : Type u_2
β : Type u_3
inst✝ : Semiring R'
s : Set R'
hcomm : ∀ a ∈ s, ∀ b ∈ s, a * b = b * a
src✝ : Semiring ↥(closure s) := toSemiring (closure s)
x✝ y✝ : ↥(closure s)
x y z : R'
h₁ : x * z = z * x
h₂ : y * z = z * y
⊢ x * y * z = z * (x * y)

Next tactic:
rw [mul_assoc, h₂, ← mul_assoc, h₁, mul_assoc]
/-- If all the elements of a set `s` commute, then `closure s` is a commutative monoid. -/
def closureCommSemiringOfComm {s : Set R'} (hcomm : ∀ a ∈ s, ∀ b ∈ s, a * b = b * a) :
    CommSemiring (closure s) :=
  { (closure s).toSemiring with
    mul_comm := fun x y => by
      ext
      simp only [Subsemiring.coe_mul]
      refine'
        closure_induction₂ x.prop y.prop hcomm (fun x => by simp only [zero_mul, mul_zero])
          (fun x => by simp only [zero_mul, mul_zero]) (fun x => by simp only [one_mul, mul_one])
          (fun x => by simp only [one_mul, mul_one])
          (fun x y z h₁ h₂ => by simp only [add_mul, mul_add, h₁, h₂])
          (fun x y z h₁ h₂ => by simp only [add_mul, mul_add, h₁, h₂])
          (fun x y z h₁ h₂ => by rw [mul_assoc, h₂, ← mul_assoc, h₁, mul_assoc]) fun x y z h₁ h₂ =>
          by 

Proof state:
R : Type u
S : Type v
T : Type w
inst✝³ : NonAssocSemiring R
M : Submonoid R
inst✝² : NonAssocSemiring S
inst✝¹ : NonAssocSemiring T
R' : Type u_1
α : Type u_2
β : Type u_3
inst✝ : Semiring R'
s : Set R'
hcomm : ∀ a ∈ s, ∀ b ∈ s, a * b = b * a
src✝ : Semiring ↥(closure s) := toSemiring (closure s)
x✝ y✝ : ↥(closure s)
x y z : R'
h₁ : x * y = y * x
h₂ : x * z = z * x
⊢ x * (y * z) = y * z * x

Next tactic:
rw [← mul_assoc, h₁, mul_assoc, h₂, ← mul_assoc]
/-- A finite field has prime power cardinality. -/
theorem Fintype.isPrimePow_card_of_field {α} [Fintype α] [Field α] : IsPrimePow ‖α‖ := by
  -- TODO: `Algebra` version of `CharP.exists`, of type `∀ p, Algebra (ZMod p) α`
  

Proof state:
α : Type u_1
inst✝¹ : Fintype α
inst✝ : Field α
⊢ IsPrimePow ‖α‖

Next tactic:
cases' CharP.exists α with p _
/-- A finite field has prime power cardinality. -/
theorem Fintype.isPrimePow_card_of_field {α} [Fintype α] [Field α] : IsPrimePow ‖α‖ := by
  -- TODO: `Algebra` version of `CharP.exists`, of type `∀ p, Algebra (ZMod p) α`
  cases' CharP.exists α with p _
  

Proof state:
case intro
α : Type u_1
inst✝¹ : Fintype α
inst✝ : Field α
p : ℕ
h✝ : CharP α p
⊢ IsPrimePow ‖α‖

Next tactic:
haveI hp := Fact.mk (CharP.char_is_prime α p)
/-- A finite field has prime power cardinality. -/
theorem Fintype.isPrimePow_card_of_field {α} [Fintype α] [Field α] : IsPrimePow ‖α‖ := by
  -- TODO: `Algebra` version of `CharP.exists`, of type `∀ p, Algebra (ZMod p) α`
  cases' CharP.exists α with p _
  haveI hp := Fact.mk (CharP.char_is_prime α p)
  

Proof state:
case intro
α : Type u_1
inst✝¹ : Fintype α
inst✝ : Field α
p : ℕ
h✝ : CharP α p
hp : Fact (Nat.Prime p)
⊢ IsPrimePow ‖α‖

Next tactic:
letI : Algebra (ZMod p) α := ZMod.algebra _ _
/-- A finite field has prime power cardinality. -/
theorem Fintype.isPrimePow_card_of_field {α} [Fintype α] [Field α] : IsPrimePow ‖α‖ := by
  -- TODO: `Algebra` version of `CharP.exists`, of type `∀ p, Algebra (ZMod p) α`
  cases' CharP.exists α with p _
  haveI hp := Fact.mk (CharP.char_is_prime α p)
  letI : Algebra (ZMod p) α := ZMod.algebra _ _
  

Proof state:
case intro
α : Type u_1
inst✝¹ : Fintype α
inst✝ : Field α
p : ℕ
h✝ : CharP α p
hp : Fact (Nat.Prime p)
this : Algebra (ZMod p) α := ZMod.algebra α p
⊢ IsPrimePow ‖α‖

Next tactic:
let b := IsNoetherian.finsetBasis (ZMod p) α
/-- A finite field has prime power cardinality. -/
theorem Fintype.isPrimePow_card_of_field {α} [Fintype α] [Field α] : IsPrimePow ‖α‖ := by
  -- TODO: `Algebra` version of `CharP.exists`, of type `∀ p, Algebra (ZMod p) α`
  cases' CharP.exists α with p _
  haveI hp := Fact.mk (CharP.char_is_prime α p)
  letI : Algebra (ZMod p) α := ZMod.algebra _ _
  let b := IsNoetherian.finsetBasis (ZMod p) α
  

Proof state:
case intro
α : Type u_1
inst✝¹ : Fintype α
inst✝ : Field α
p : ℕ
h✝ : CharP α p
hp : Fact (Nat.Prime p)
this : Algebra (ZMod p) α := ZMod.algebra α p
b : Basis { x // x ∈ IsNoetherian.finsetBasisIndex (ZMod p) α } (ZMod p) α := IsNoetherian.finsetBasis (ZMod p) α
⊢ IsPrimePow ‖α‖

Next tactic:
rw [Module.card_fintype b, ZMod.card, isPrimePow_pow_iff]
/-- A finite field has prime power cardinality. -/
theorem Fintype.isPrimePow_card_of_field {α} [Fintype α] [Field α] : IsPrimePow ‖α‖ := by
  -- TODO: `Algebra` version of `CharP.exists`, of type `∀ p, Algebra (ZMod p) α`
  cases' CharP.exists α with p _
  haveI hp := Fact.mk (CharP.char_is_prime α p)
  letI : Algebra (ZMod p) α := ZMod.algebra _ _
  let b := IsNoetherian.finsetBasis (ZMod p) α
  rw [Module.card_fintype b, ZMod.card, isPrimePow_pow_iff]
  · 

Proof state:
case intro
α : Type u_1
inst✝¹ : Fintype α
inst✝ : Field α
p : ℕ
h✝ : CharP α p
hp : Fact (Nat.Prime p)
this : Algebra (ZMod p) α := ZMod.algebra α p
b : Basis { x // x ∈ IsNoetherian.finsetBasisIndex (ZMod p) α } (ZMod p) α := IsNoetherian.finsetBasis (ZMod p) α
⊢ IsPrimePow p

Next tactic:
exact hp.1.isPrimePow
/-- A finite field has prime power cardinality. -/
theorem Fintype.isPrimePow_card_of_field {α} [Fintype α] [Field α] : IsPrimePow ‖α‖ := by
  -- TODO: `Algebra` version of `CharP.exists`, of type `∀ p, Algebra (ZMod p) α`
  cases' CharP.exists α with p _
  haveI hp := Fact.mk (CharP.char_is_prime α p)
  letI : Algebra (ZMod p) α := ZMod.algebra _ _
  let b := IsNoetherian.finsetBasis (ZMod p) α
  rw [Module.card_fintype b, ZMod.card, isPrimePow_pow_iff]
  · exact hp.1.isPrimePow
  

Proof state:
case intro
α : Type u_1
inst✝¹ : Fintype α
inst✝ : Field α
p : ℕ
h✝ : CharP α p
hp : Fact (Nat.Prime p)
this : Algebra (ZMod p) α := ZMod.algebra α p
b : Basis { x // x ∈ IsNoetherian.finsetBasisIndex (ZMod p) α } (ZMod p) α := IsNoetherian.finsetBasis (ZMod p) α
⊢ ‖{ x // x ∈ IsNoetherian.finsetBasisIndex (ZMod p) α }‖ ≠ 0

Next tactic:
rw [← FiniteDimensional.finrank_eq_card_basis b]
/-- A finite field has prime power cardinality. -/
theorem Fintype.isPrimePow_card_of_field {α} [Fintype α] [Field α] : IsPrimePow ‖α‖ := by
  -- TODO: `Algebra` version of `CharP.exists`, of type `∀ p, Algebra (ZMod p) α`
  cases' CharP.exists α with p _
  haveI hp := Fact.mk (CharP.char_is_prime α p)
  letI : Algebra (ZMod p) α := ZMod.algebra _ _
  let b := IsNoetherian.finsetBasis (ZMod p) α
  rw [Module.card_fintype b, ZMod.card, isPrimePow_pow_iff]
  · exact hp.1.isPrimePow
  rw [← FiniteDimensional.finrank_eq_card_basis b]
  

Proof state:
case intro
α : Type u_1
inst✝¹ : Fintype α
inst✝ : Field α
p : ℕ
h✝ : CharP α p
hp : Fact (Nat.Prime p)
this : Algebra (ZMod p) α := ZMod.algebra α p
b : Basis { x // x ∈ IsNoetherian.finsetBasisIndex (ZMod p) α } (ZMod p) α := IsNoetherian.finsetBasis (ZMod p) α
⊢ FiniteDimensional.finrank (ZMod p) α ≠ 0

Next tactic:
exact FiniteDimensional.finrank_pos.ne'
/-- A `Fintype` can be given a field structure iff its cardinality is a prime power. -/
theorem Fintype.nonempty_field_iff {α} [Fintype α] : Nonempty (Field α) ↔ IsPrimePow ‖α‖ := by
  

Proof state:
α : Type u_1
inst✝ : Fintype α
⊢ Nonempty (Field α) ↔ IsPrimePow ‖α‖

Next tactic:
refine' ⟨fun ⟨h⟩ => Fintype.isPrimePow_card_of_field, _⟩
/-- A `Fintype` can be given a field structure iff its cardinality is a prime power. -/
theorem Fintype.nonempty_field_iff {α} [Fintype α] : Nonempty (Field α) ↔ IsPrimePow ‖α‖ := by
  refine' ⟨fun ⟨h⟩ => Fintype.isPrimePow_card_of_field, _⟩
  

Proof state:
α : Type u_1
inst✝ : Fintype α
⊢ IsPrimePow ‖α‖ → Nonempty (Field α)

Next tactic:
rintro ⟨p, n, hp, hn, hα⟩
/-- A `Fintype` can be given a field structure iff its cardinality is a prime power. -/
theorem Fintype.nonempty_field_iff {α} [Fintype α] : Nonempty (Field α) ↔ IsPrimePow ‖α‖ := by
  refine' ⟨fun ⟨h⟩ => Fintype.isPrimePow_card_of_field, _⟩
  rintro ⟨p, n, hp, hn, hα⟩
  

Proof state:
case intro.intro.intro.intro
α : Type u_1
inst✝ : Fintype α
p n : ℕ
hp : Prime p
hn : 0 < n
hα : p ^ n = ‖α‖
⊢ Nonempty (Field α)

Next tactic:
haveI := Fact.mk hp.nat_prime
/-- A `Fintype` can be given a field structure iff its cardinality is a prime power. -/
theorem Fintype.nonempty_field_iff {α} [Fintype α] : Nonempty (Field α) ↔ IsPrimePow ‖α‖ := by
  refine' ⟨fun ⟨h⟩ => Fintype.isPrimePow_card_of_field, _⟩
  rintro ⟨p, n, hp, hn, hα⟩
  haveI := Fact.mk hp.nat_prime
  

Proof state:
case intro.intro.intro.intro
α : Type u_1
inst✝ : Fintype α
p n : ℕ
hp : Prime p
hn : 0 < n
hα : p ^ n = ‖α‖
this : Fact (Nat.Prime p)
⊢ Nonempty (Field α)

Next tactic:
exact ⟨(Fintype.equivOfCardEq ((GaloisField.card p n hn.ne').trans hα)).symm.field⟩
/-- Any infinite type can be endowed a field structure. -/
theorem Infinite.nonempty_field {α : Type u} [Infinite α] : Nonempty (Field α) := by
  

Proof state:
α : Type u
inst✝ : Infinite α
⊢ Nonempty (Field α)

Next tactic:
letI K := FractionRing (MvPolynomial α <| ULift.{u} ℚ)
/-- Any infinite type can be endowed a field structure. -/
theorem Infinite.nonempty_field {α : Type u} [Infinite α] : Nonempty (Field α) := by
  letI K := FractionRing (MvPolynomial α <| ULift.{u} ℚ)
  

Proof state:
α : Type u
inst✝ : Infinite α
K : Type u := FractionRing (MvPolynomial α (ULift.{u, 0} ℚ))
⊢ Nonempty (Field α)

Next tactic:
suffices #α = #K by
    obtain ⟨e⟩ := Cardinal.eq.1 this
    exact ⟨e.field⟩
/-- Any infinite type can be endowed a field structure. -/
theorem Infinite.nonempty_field {α : Type u} [Infinite α] : Nonempty (Field α) := by
  letI K := FractionRing (MvPolynomial α <| ULift.{u} ℚ)
  suffices #α = #K by
    

Proof state:
α : Type u
inst✝ : Infinite α
K : Type u := FractionRing (MvPolynomial α (ULift.{u, 0} ℚ))
this : #α = #K
⊢ Nonempty (Field α)

Next tactic:
obtain ⟨e⟩ := Cardinal.eq.1 this
/-- Any infinite type can be endowed a field structure. -/
theorem Infinite.nonempty_field {α : Type u} [Infinite α] : Nonempty (Field α) := by
  letI K := FractionRing (MvPolynomial α <| ULift.{u} ℚ)
  suffices #α = #K by
    obtain ⟨e⟩ := Cardinal.eq.1 this
    

Proof state:
case intro
α : Type u
inst✝ : Infinite α
K : Type u := FractionRing (MvPolynomial α (ULift.{u, 0} ℚ))
this : #α = #K
e : α ≃ K
⊢ Nonempty (Field α)

Next tactic:
exact ⟨e.field⟩
/-- Any infinite type can be endowed a field structure. -/
theorem Infinite.nonempty_field {α : Type u} [Infinite α] : Nonempty (Field α) := by
  letI K := FractionRing (MvPolynomial α <| ULift.{u} ℚ)
  suffices #α = #K by
    obtain ⟨e⟩ := Cardinal.eq.1 this
    exact ⟨e.field⟩
  

Proof state:
α : Type u
inst✝ : Infinite α
K : Type u := FractionRing (MvPolynomial α (ULift.{u, 0} ℚ))
⊢ #α = #K

Next tactic:
rw [← IsLocalization.card (MvPolynomial α <| ULift.{u} ℚ)⁰ K le_rfl]