l3lab/ntp-mathlib huggingface dataset:
theorem of_eval₂ (f : Polynomial (FixedPoints.subfield G F))
    (hf : Polynomial.eval₂ (Subfield.subtype <| FixedPoints.subfield G F) x f = 0) :
    minpoly G F x ∣ f := by
-- Porting note: the two `have` below were not needed.
  have : (subfield G F).subtype = (subfield G F).toSubring.subtype := rfl
  have h : Polynomial.map (MulSemiringActionHom.toRingHom (IsInvariantSubring.subtypeHom G
    (subfield G F).toSubring)) f = Polynomial.map
    ((IsInvariantSubring.subtypeHom G (subfield G F).toSubring)) f := rfl
  erw [← Polynomial.map_dvd_map' (Subfield.subtype <| FixedPoints.subfield G F), minpoly, this,
    Polynomial.map_toSubring _ _, prodXSubSMul]
  refine'
    Fintype.prod_dvd_of_coprime
      (Polynomial.pairwise_coprime_X_sub_C <| MulAction.injective_ofQuotientStabilizer G x) fun y =>
      QuotientGroup.induction_on y fun g => _
  

Proof state:
M : Type u
inst✝⁵ : Monoid M
G : Type u
inst✝⁴ : Group G
F : Type v
inst✝³ : Field F
inst✝² : MulSemiringAction M F
inst✝¹ : MulSemiringAction G F
m : M
inst✝ : Fintype G
x : F
f : Polynomial ↥(subfield G F)
hf : Polynomial.eval₂ (Subfield.subtype (subfield G F)) x f = 0
this : Subfield.subtype (subfield G F) = Subring.subtype (subfield G F).toSubring
h :
  Polynomial.map (MulSemiringActionHom.toRingHom (IsInvariantSubring.subtypeHom G (subfield G F).toSubring)) f =
    Polynomial.map (↑(IsInvariantSubring.subtypeHom G (subfield G F).toSubring)) f
y : G ⧸ stabilizer G x
g : G
⊢ Polynomial.X - Polynomial.C (ofQuotientStabilizer G x ↑g) ∣
    Polynomial.map (Subring.subtype (subfield G F).toSubring) f

Next tactic:
rw [Polynomial.dvd_iff_isRoot, Polynomial.IsRoot.def, MulAction.ofQuotientStabilizer_mk,
    Polynomial.eval_smul', ← this, ← Subfield.toSubring_subtype_eq_subtype, ←
    IsInvariantSubring.coe_subtypeHom' G (FixedPoints.subfield G F).toSubring, h,
    ← MulSemiringActionHom.coe_polynomial, ← MulSemiringActionHom.map_smul, smul_polynomial,
    MulSemiringActionHom.coe_polynomial, ← h, IsInvariantSubring.coe_subtypeHom',
    Polynomial.eval_map, Subfield.toSubring_subtype_eq_subtype, hf, smul_zero]
theorem irreducible_aux (f g : Polynomial (FixedPoints.subfield G F)) (hf : f.Monic) (hg : g.Monic)
    (hfg : f * g = minpoly G F x) : f = 1 ∨ g = 1 := by
  

Proof state:
M : Type u
inst✝⁵ : Monoid M
G : Type u
inst✝⁴ : Group G
F : Type v
inst✝³ : Field F
inst✝² : MulSemiringAction M F
inst✝¹ : MulSemiringAction G F
m : M
inst✝ : Fintype G
x : F
f g : Polynomial ↥(subfield G F)
hf : Polynomial.Monic f
hg : Polynomial.Monic g
hfg : f * g = minpoly G F x
⊢ f = 1 ∨ g = 1

Next tactic:
have hf2 : f ∣ minpoly G F x := by rw [← hfg]; exact dvd_mul_right _ _
theorem irreducible_aux (f g : Polynomial (FixedPoints.subfield G F)) (hf : f.Monic) (hg : g.Monic)
    (hfg : f * g = minpoly G F x) : f = 1 ∨ g = 1 := by
  have hf2 : f ∣ minpoly G F x := by 

Proof state:
M : Type u
inst✝⁵ : Monoid M
G : Type u
inst✝⁴ : Group G
F : Type v
inst✝³ : Field F
inst✝² : MulSemiringAction M F
inst✝¹ : MulSemiringAction G F
m : M
inst✝ : Fintype G
x : F
f g : Polynomial ↥(subfield G F)
hf : Polynomial.Monic f
hg : Polynomial.Monic g
hfg : f * g = minpoly G F x
⊢ f ∣ minpoly G F x

Next tactic:
rw [← hfg]
theorem irreducible_aux (f g : Polynomial (FixedPoints.subfield G F)) (hf : f.Monic) (hg : g.Monic)
    (hfg : f * g = minpoly G F x) : f = 1 ∨ g = 1 := by
  have hf2 : f ∣ minpoly G F x := by rw [← hfg]; 

Proof state:
M : Type u
inst✝⁵ : Monoid M
G : Type u
inst✝⁴ : Group G
F : Type v
inst✝³ : Field F
inst✝² : MulSemiringAction M F
inst✝¹ : MulSemiringAction G F
m : M
inst✝ : Fintype G
x : F
f g : Polynomial ↥(subfield G F)
hf : Polynomial.Monic f
hg : Polynomial.Monic g
hfg : f * g = minpoly G F x
⊢ f ∣ f * g

Next tactic:
exact dvd_mul_right _ _
theorem irreducible_aux (f g : Polynomial (FixedPoints.subfield G F)) (hf : f.Monic) (hg : g.Monic)
    (hfg : f * g = minpoly G F x) : f = 1 ∨ g = 1 := by
  have hf2 : f ∣ minpoly G F x := by rw [← hfg]; exact dvd_mul_right _ _
  

Proof state:
M : Type u
inst✝⁵ : Monoid M
G : Type u
inst✝⁴ : Group G
F : Type v
inst✝³ : Field F
inst✝² : MulSemiringAction M F
inst✝¹ : MulSemiringAction G F
m : M
inst✝ : Fintype G
x : F
f g : Polynomial ↥(subfield G F)
hf : Polynomial.Monic f
hg : Polynomial.Monic g
hfg : f * g = minpoly G F x
hf2 : f ∣ minpoly G F x
⊢ f = 1 ∨ g = 1

Next tactic:
have hg2 : g ∣ minpoly G F x := by rw [← hfg]; exact dvd_mul_left _ _
theorem irreducible_aux (f g : Polynomial (FixedPoints.subfield G F)) (hf : f.Monic) (hg : g.Monic)
    (hfg : f * g = minpoly G F x) : f = 1 ∨ g = 1 := by
  have hf2 : f ∣ minpoly G F x := by rw [← hfg]; exact dvd_mul_right _ _
  have hg2 : g ∣ minpoly G F x := by 

Proof state:
M : Type u
inst✝⁵ : Monoid M
G : Type u
inst✝⁴ : Group G
F : Type v
inst✝³ : Field F
inst✝² : MulSemiringAction M F
inst✝¹ : MulSemiringAction G F
m : M
inst✝ : Fintype G
x : F
f g : Polynomial ↥(subfield G F)
hf : Polynomial.Monic f
hg : Polynomial.Monic g
hfg : f * g = minpoly G F x
hf2 : f ∣ minpoly G F x
⊢ g ∣ minpoly G F x

Next tactic:
rw [← hfg]
theorem irreducible_aux (f g : Polynomial (FixedPoints.subfield G F)) (hf : f.Monic) (hg : g.Monic)
    (hfg : f * g = minpoly G F x) : f = 1 ∨ g = 1 := by
  have hf2 : f ∣ minpoly G F x := by rw [← hfg]; exact dvd_mul_right _ _
  have hg2 : g ∣ minpoly G F x := by rw [← hfg]; 

Proof state:
M : Type u
inst✝⁵ : Monoid M
G : Type u
inst✝⁴ : Group G
F : Type v
inst✝³ : Field F
inst✝² : MulSemiringAction M F
inst✝¹ : MulSemiringAction G F
m : M
inst✝ : Fintype G
x : F
f g : Polynomial ↥(subfield G F)
hf : Polynomial.Monic f
hg : Polynomial.Monic g
hfg : f * g = minpoly G F x
hf2 : f ∣ minpoly G F x
⊢ g ∣ f * g

Next tactic:
exact dvd_mul_left _ _
theorem irreducible_aux (f g : Polynomial (FixedPoints.subfield G F)) (hf : f.Monic) (hg : g.Monic)
    (hfg : f * g = minpoly G F x) : f = 1 ∨ g = 1 := by
  have hf2 : f ∣ minpoly G F x := by rw [← hfg]; exact dvd_mul_right _ _
  have hg2 : g ∣ minpoly G F x := by rw [← hfg]; exact dvd_mul_left _ _
  

Proof state:
M : Type u
inst✝⁵ : Monoid M
G : Type u
inst✝⁴ : Group G
F : Type v
inst✝³ : Field F
inst✝² : MulSemiringAction M F
inst✝¹ : MulSemiringAction G F
m : M
inst✝ : Fintype G
x : F
f g : Polynomial ↥(subfield G F)
hf : Polynomial.Monic f
hg : Polynomial.Monic g
hfg : f * g = minpoly G F x
hf2 : f ∣ minpoly G F x
hg2 : g ∣ minpoly G F x
⊢ f = 1 ∨ g = 1

Next tactic:
have := eval₂ G F x
theorem irreducible_aux (f g : Polynomial (FixedPoints.subfield G F)) (hf : f.Monic) (hg : g.Monic)
    (hfg : f * g = minpoly G F x) : f = 1 ∨ g = 1 := by
  have hf2 : f ∣ minpoly G F x := by rw [← hfg]; exact dvd_mul_right _ _
  have hg2 : g ∣ minpoly G F x := by rw [← hfg]; exact dvd_mul_left _ _
  have := eval₂ G F x
  

Proof state:
M : Type u
inst✝⁵ : Monoid M
G : Type u
inst✝⁴ : Group G
F : Type v
inst✝³ : Field F
inst✝² : MulSemiringAction M F
inst✝¹ : MulSemiringAction G F
m : M
inst✝ : Fintype G
x : F
f g : Polynomial ↥(subfield G F)
hf : Polynomial.Monic f
hg : Polynomial.Monic g
hfg : f * g = minpoly G F x
hf2 : f ∣ minpoly G F x
hg2 : g ∣ minpoly G F x
this : Polynomial.eval₂ (Subring.subtype (subfield G F).toSubring) x (minpoly G F x) = 0
⊢ f = 1 ∨ g = 1

Next tactic:
rw [← hfg, Polynomial.eval₂_mul, mul_eq_zero] at this
theorem irreducible_aux (f g : Polynomial (FixedPoints.subfield G F)) (hf : f.Monic) (hg : g.Monic)
    (hfg : f * g = minpoly G F x) : f = 1 ∨ g = 1 := by
  have hf2 : f ∣ minpoly G F x := by rw [← hfg]; exact dvd_mul_right _ _
  have hg2 : g ∣ minpoly G F x := by rw [← hfg]; exact dvd_mul_left _ _
  have := eval₂ G F x
  rw [← hfg, Polynomial.eval₂_mul, mul_eq_zero] at this
  

Proof state:
M : Type u
inst✝⁵ : Monoid M
G : Type u
inst✝⁴ : Group G
F : Type v
inst✝³ : Field F
inst✝² : MulSemiringAction M F
inst✝¹ : MulSemiringAction G F
m : M
inst✝ : Fintype G
x : F
f g : Polynomial ↥(subfield G F)
hf : Polynomial.Monic f
hg : Polynomial.Monic g
hfg : f * g = minpoly G F x
hf2 : f ∣ minpoly G F x
hg2 : g ∣ minpoly G F x
this :
  Polynomial.eval₂ (Subring.subtype (subfield G F).toSubring) x f = 0 ∨
    Polynomial.eval₂ (Subring.subtype (subfield G F).toSubring) x g = 0
⊢ f = 1 ∨ g = 1

Next tactic:
cases' this with this this
theorem irreducible_aux (f g : Polynomial (FixedPoints.subfield G F)) (hf : f.Monic) (hg : g.Monic)
    (hfg : f * g = minpoly G F x) : f = 1 ∨ g = 1 := by
  have hf2 : f ∣ minpoly G F x := by rw [← hfg]; exact dvd_mul_right _ _
  have hg2 : g ∣ minpoly G F x := by rw [← hfg]; exact dvd_mul_left _ _
  have := eval₂ G F x
  rw [← hfg, Polynomial.eval₂_mul, mul_eq_zero] at this
  cases' this with this this
  · 

Proof state:
case inl
M : Type u
inst✝⁵ : Monoid M
G : Type u
inst✝⁴ : Group G
F : Type v
inst✝³ : Field F
inst✝² : MulSemiringAction M F
inst✝¹ : MulSemiringAction G F
m : M
inst✝ : Fintype G
x : F
f g : Polynomial ↥(subfield G F)
hf : Polynomial.Monic f
hg : Polynomial.Monic g
hfg : f * g = minpoly G F x
hf2 : f ∣ minpoly G F x
hg2 : g ∣ minpoly G F x
this : Polynomial.eval₂ (Subring.subtype (subfield G F).toSubring) x f = 0
⊢ f = 1 ∨ g = 1

Next tactic:
right
theorem irreducible_aux (f g : Polynomial (FixedPoints.subfield G F)) (hf : f.Monic) (hg : g.Monic)
    (hfg : f * g = minpoly G F x) : f = 1 ∨ g = 1 := by
  have hf2 : f ∣ minpoly G F x := by rw [← hfg]; exact dvd_mul_right _ _
  have hg2 : g ∣ minpoly G F x := by rw [← hfg]; exact dvd_mul_left _ _
  have := eval₂ G F x
  rw [← hfg, Polynomial.eval₂_mul, mul_eq_zero] at this
  cases' this with this this
  · right
    

Proof state:
case inl.h
M : Type u
inst✝⁵ : Monoid M
G : Type u
inst✝⁴ : Group G
F : Type v
inst✝³ : Field F
inst✝² : MulSemiringAction M F
inst✝¹ : MulSemiringAction G F
m : M
inst✝ : Fintype G
x : F
f g : Polynomial ↥(subfield G F)
hf : Polynomial.Monic f
hg : Polynomial.Monic g
hfg : f * g = minpoly G F x
hf2 : f ∣ minpoly G F x
hg2 : g ∣ minpoly G F x
this : Polynomial.eval₂ (Subring.subtype (subfield G F).toSubring) x f = 0
⊢ g = 1

Next tactic:
have hf3 : f = minpoly G F x :=
      Polynomial.eq_of_monic_of_associated hf (monic G F x)
        (associated_of_dvd_dvd hf2 <| @of_eval₂ G _ F _ _ _ x f this)
theorem irreducible_aux (f g : Polynomial (FixedPoints.subfield G F)) (hf : f.Monic) (hg : g.Monic)
    (hfg : f * g = minpoly G F x) : f = 1 ∨ g = 1 := by
  have hf2 : f ∣ minpoly G F x := by rw [← hfg]; exact dvd_mul_right _ _
  have hg2 : g ∣ minpoly G F x := by rw [← hfg]; exact dvd_mul_left _ _
  have := eval₂ G F x
  rw [← hfg, Polynomial.eval₂_mul, mul_eq_zero] at this
  cases' this with this this
  · right
    have hf3 : f = minpoly G F x :=
      Polynomial.eq_of_monic_of_associated hf (monic G F x)
        (associated_of_dvd_dvd hf2 <| @of_eval₂ G _ F _ _ _ x f this)
    

Proof state:
case inl.h
M : Type u
inst✝⁵ : Monoid M
G : Type u
inst✝⁴ : Group G
F : Type v
inst✝³ : Field F
inst✝² : MulSemiringAction M F
inst✝¹ : MulSemiringAction G F
m : M
inst✝ : Fintype G
x : F
f g : Polynomial ↥(subfield G F)
hf : Polynomial.Monic f
hg : Polynomial.Monic g
hfg : f * g = minpoly G F x
hf2 : f ∣ minpoly G F x
hg2 : g ∣ minpoly G F x
this : Polynomial.eval₂ (Subring.subtype (subfield G F).toSubring) x f = 0
hf3 : f = minpoly G F x
⊢ g = 1

Next tactic:
rwa [← mul_one (minpoly G F x), hf3, mul_right_inj' (monic G F x).ne_zero] at hfg
theorem irreducible_aux (f g : Polynomial (FixedPoints.subfield G F)) (hf : f.Monic) (hg : g.Monic)
    (hfg : f * g = minpoly G F x) : f = 1 ∨ g = 1 := by
  have hf2 : f ∣ minpoly G F x := by rw [← hfg]; exact dvd_mul_right _ _
  have hg2 : g ∣ minpoly G F x := by rw [← hfg]; exact dvd_mul_left _ _
  have := eval₂ G F x
  rw [← hfg, Polynomial.eval₂_mul, mul_eq_zero] at this
  cases' this with this this
  · right
    have hf3 : f = minpoly G F x :=
      Polynomial.eq_of_monic_of_associated hf (monic G F x)
        (associated_of_dvd_dvd hf2 <| @of_eval₂ G _ F _ _ _ x f this)
    rwa [← mul_one (minpoly G F x), hf3, mul_right_inj' (monic G F x).ne_zero] at hfg
  · 

Proof state:
case inr
M : Type u
inst✝⁵ : Monoid M
G : Type u
inst✝⁴ : Group G
F : Type v
inst✝³ : Field F
inst✝² : MulSemiringAction M F
inst✝¹ : MulSemiringAction G F
m : M
inst✝ : Fintype G
x : F
f g : Polynomial ↥(subfield G F)
hf : Polynomial.Monic f
hg : Polynomial.Monic g
hfg : f * g = minpoly G F x
hf2 : f ∣ minpoly G F x
hg2 : g ∣ minpoly G F x
this : Polynomial.eval₂ (Subring.subtype (subfield G F).toSubring) x g = 0
⊢ f = 1 ∨ g = 1

Next tactic:
left
theorem irreducible_aux (f g : Polynomial (FixedPoints.subfield G F)) (hf : f.Monic) (hg : g.Monic)
    (hfg : f * g = minpoly G F x) : f = 1 ∨ g = 1 := by
  have hf2 : f ∣ minpoly G F x := by rw [← hfg]; exact dvd_mul_right _ _
  have hg2 : g ∣ minpoly G F x := by rw [← hfg]; exact dvd_mul_left _ _
  have := eval₂ G F x
  rw [← hfg, Polynomial.eval₂_mul, mul_eq_zero] at this
  cases' this with this this
  · right
    have hf3 : f = minpoly G F x :=
      Polynomial.eq_of_monic_of_associated hf (monic G F x)
        (associated_of_dvd_dvd hf2 <| @of_eval₂ G _ F _ _ _ x f this)
    rwa [← mul_one (minpoly G F x), hf3, mul_right_inj' (monic G F x).ne_zero] at hfg
  · left
    

Proof state:
case inr.h
M : Type u
inst✝⁵ : Monoid M
G : Type u
inst✝⁴ : Group G
F : Type v
inst✝³ : Field F
inst✝² : MulSemiringAction M F
inst✝¹ : MulSemiringAction G F
m : M
inst✝ : Fintype G
x : F
f g : Polynomial ↥(subfield G F)
hf : Polynomial.Monic f
hg : Polynomial.Monic g
hfg : f * g = minpoly G F x
hf2 : f ∣ minpoly G F x
hg2 : g ∣ minpoly G F x
this : Polynomial.eval₂ (Subring.subtype (subfield G F).toSubring) x g = 0
⊢ f = 1

Next tactic:
have hg3 : g = minpoly G F x :=
      Polynomial.eq_of_monic_of_associated hg (monic G F x)
        (associated_of_dvd_dvd hg2 <| @of_eval₂ G _ F _ _ _ x g this)
theorem irreducible_aux (f g : Polynomial (FixedPoints.subfield G F)) (hf : f.Monic) (hg : g.Monic)
    (hfg : f * g = minpoly G F x) : f = 1 ∨ g = 1 := by
  have hf2 : f ∣ minpoly G F x := by rw [← hfg]; exact dvd_mul_right _ _
  have hg2 : g ∣ minpoly G F x := by rw [← hfg]; exact dvd_mul_left _ _
  have := eval₂ G F x
  rw [← hfg, Polynomial.eval₂_mul, mul_eq_zero] at this
  cases' this with this this
  · right
    have hf3 : f = minpoly G F x :=
      Polynomial.eq_of_monic_of_associated hf (monic G F x)
        (associated_of_dvd_dvd hf2 <| @of_eval₂ G _ F _ _ _ x f this)
    rwa [← mul_one (minpoly G F x), hf3, mul_right_inj' (monic G F x).ne_zero] at hfg
  · left
    have hg3 : g = minpoly G F x :=
      Polynomial.eq_of_monic_of_associated hg (monic G F x)
        (associated_of_dvd_dvd hg2 <| @of_eval₂ G _ F _ _ _ x g this)
    

Proof state:
case inr.h
M : Type u
inst✝⁵ : Monoid M
G : Type u
inst✝⁴ : Group G
F : Type v
inst✝³ : Field F
inst✝² : MulSemiringAction M F
inst✝¹ : MulSemiringAction G F
m : M
inst✝ : Fintype G
x : F
f g : Polynomial ↥(subfield G F)
hf : Polynomial.Monic f
hg : Polynomial.Monic g
hfg : f * g = minpoly G F x
hf2 : f ∣ minpoly G F x
hg2 : g ∣ minpoly G F x
this : Polynomial.eval₂ (Subring.subtype (subfield G F).toSubring) x g = 0
hg3 : g = minpoly G F x
⊢ f = 1

Next tactic:
rwa [← one_mul (minpoly G F x), hg3, mul_left_inj' (monic G F x).ne_zero] at hfg
theorem isIntegral [Finite G] (x : F) : IsIntegral (FixedPoints.subfield G F) x := by
  

Proof state:
M : Type u
inst✝⁵ : Monoid M
G : Type u
inst✝⁴ : Group G
F : Type v
inst✝³ : Field F
inst✝² : MulSemiringAction M F
inst✝¹ : MulSemiringAction G F
m : M
inst✝ : Finite G
x : F
⊢ IsIntegral (↥(subfield G F)) x

Next tactic:
cases nonempty_fintype G
theorem isIntegral [Finite G] (x : F) : IsIntegral (FixedPoints.subfield G F) x := by
  cases nonempty_fintype G; 

Proof state:
case intro
M : Type u
inst✝⁵ : Monoid M
G : Type u
inst✝⁴ : Group G
F : Type v
inst✝³ : Field F
inst✝² : MulSemiringAction M F
inst✝¹ : MulSemiringAction G F
m : M
inst✝ : Finite G
x : F
val✝ : Fintype G
⊢ IsIntegral (↥(subfield G F)) x

Next tactic:
exact ⟨minpoly G F x, minpoly.monic G F x, minpoly.eval₂ G F x⟩
theorem rank_le_card : Module.rank (FixedPoints.subfield G F) F ≤ Fintype.card G :=
  rank_le fun s hs => by
    

Proof state:
M : Type u
inst✝⁵ : Monoid M
G : Type u
inst✝⁴ : Group G
F : Type v
inst✝³ : Field F
inst✝² : MulSemiringAction M F
inst✝¹ : MulSemiringAction G F
m : M
inst✝ : Fintype G
x : F
s : Finset F
hs : LinearIndependent ↥(subfield G F) fun i => ↑i
⊢ card s ≤ Fintype.card G

Next tactic:
simpa only [rank_fun', Cardinal.mk_coe_finset, Finset.coe_sort_coe, Cardinal.lift_natCast,
      Cardinal.natCast_le] using
      cardinal_lift_le_rank_of_linearIndependent'
        (linearIndependent_smul_of_linearIndependent G F hs)
instance normal : Normal (FixedPoints.subfield G F) F :=
  ⟨fun x => (isIntegral G F x).isAlgebraic, fun x =>
    (Polynomial.splits_id_iff_splits _).1 <| by
      

Proof state:
M : Type u
inst✝⁵ : Monoid M
G : Type u
inst✝⁴ : Group G
F : Type v
inst✝³ : Field F
inst✝² : MulSemiringAction M F
inst✝¹ : MulSemiringAction G F
m : M
inst✝ : Finite G
x : F
⊢ Polynomial.Splits (RingHom.id F)
    (Polynomial.map (algebraMap (↥(subfield G F)) F) (_root_.minpoly (↥(subfield G F)) x))

Next tactic:
cases nonempty_fintype G
instance normal : Normal (FixedPoints.subfield G F) F :=
  ⟨fun x => (isIntegral G F x).isAlgebraic, fun x =>
    (Polynomial.splits_id_iff_splits _).1 <| by
      cases nonempty_fintype G
      

Proof state:
case intro
M : Type u
inst✝⁵ : Monoid M
G : Type u
inst✝⁴ : Group G
F : Type v
inst✝³ : Field F
inst✝² : MulSemiringAction M F
inst✝¹ : MulSemiringAction G F
m : M
inst✝ : Finite G
x : F
val✝ : Fintype G
⊢ Polynomial.Splits (RingHom.id F)
    (Polynomial.map (algebraMap (↥(subfield G F)) F) (_root_.minpoly (↥(subfield G F)) x))

Next tactic:
rw [← minpoly_eq_minpoly, minpoly, coe_algebraMap, ← Subfield.toSubring_subtype_eq_subtype,
        Polynomial.map_toSubring _ (subfield G F).toSubring, prodXSubSMul]
instance normal : Normal (FixedPoints.subfield G F) F :=
  ⟨fun x => (isIntegral G F x).isAlgebraic, fun x =>
    (Polynomial.splits_id_iff_splits _).1 <| by
      cases nonempty_fintype G
      rw [← minpoly_eq_minpoly, minpoly, coe_algebraMap, ← Subfield.toSubring_subtype_eq_subtype,
        Polynomial.map_toSubring _ (subfield G F).toSubring, prodXSubSMul]
      

Proof state:
case intro
M : Type u
inst✝⁵ : Monoid M
G : Type u
inst✝⁴ : Group G
F : Type v
inst✝³ : Field F
inst✝² : MulSemiringAction M F
inst✝¹ : MulSemiringAction G F
m : M
inst✝ : Finite G
x : F
val✝ : Fintype G
⊢ Polynomial.Splits (RingHom.id F)
    (∏ g : G ⧸ stabilizer G x, (Polynomial.X - Polynomial.C (ofQuotientStabilizer G x g)))

Next tactic:
exact Polynomial.splits_prod _ fun _ _ => Polynomial.splits_X_sub_C _
instance separable : IsSeparable (FixedPoints.subfield G F) F :=
  ⟨fun x => by
    

Proof state:
M : Type u
inst✝⁵ : Monoid M
G : Type u
inst✝⁴ : Group G
F : Type v
inst✝³ : Field F
inst✝² : MulSemiringAction M F
inst✝¹ : MulSemiringAction G F
m : M
inst✝ : Finite G
x : F
⊢ Polynomial.Separable (_root_.minpoly (↥(subfield G F)) x)

Next tactic:
cases nonempty_fintype G
instance separable : IsSeparable (FixedPoints.subfield G F) F :=
  ⟨fun x => by
    cases nonempty_fintype G
    -- this was a plain rw when we were using unbundled subrings
    

Proof state:
case intro
M : Type u
inst✝⁵ : Monoid M
G : Type u
inst✝⁴ : Group G
F : Type v
inst✝³ : Field F
inst✝² : MulSemiringAction M F
inst✝¹ : MulSemiringAction G F
m : M
inst✝ : Finite G
x : F
val✝ : Fintype G
⊢ Polynomial.Separable (_root_.minpoly (↥(subfield G F)) x)

Next tactic:
erw [← minpoly_eq_minpoly, ← Polynomial.separable_map (FixedPoints.subfield G F).subtype,
      minpoly, Polynomial.map_toSubring _ (subfield G F).toSubring]
instance separable : IsSeparable (FixedPoints.subfield G F) F :=
  ⟨fun x => by
    cases nonempty_fintype G
    -- this was a plain rw when we were using unbundled subrings
    erw [← minpoly_eq_minpoly, ← Polynomial.separable_map (FixedPoints.subfield G F).subtype,
      minpoly, Polynomial.map_toSubring _ (subfield G F).toSubring]
    

Proof state:
case intro
M : Type u
inst✝⁵ : Monoid M
G : Type u
inst✝⁴ : Group G
F : Type v
inst✝³ : Field F
inst✝² : MulSemiringAction M F
inst✝¹ : MulSemiringAction G F
m : M
inst✝ : Finite G
x : F
val✝ : Fintype G
⊢ Polynomial.Separable (prodXSubSMul G F x)

Next tactic:
exact Polynomial.separable_prod_X_sub_C_iff.2 (injective_ofQuotientStabilizer G x)
instance : FiniteDimensional (subfield G F) F := by
  

Proof state:
M : Type u
inst✝⁵ : Monoid M
G : Type u
inst✝⁴ : Group G
F : Type v
inst✝³ : Field F
inst✝² : MulSemiringAction M F
inst✝¹ : MulSemiringAction G F
m : M
inst✝ : Finite G
⊢ FiniteDimensional (↥(subfield G F)) F

Next tactic:
cases nonempty_fintype G
instance : FiniteDimensional (subfield G F) F := by
  cases nonempty_fintype G
  

Proof state:
case intro
M : Type u
inst✝⁵ : Monoid M
G : Type u
inst✝⁴ : Group G
F : Type v
inst✝³ : Field F
inst✝² : MulSemiringAction M F
inst✝¹ : MulSemiringAction G F
m : M
inst✝ : Finite G
val✝ : Fintype G
⊢ FiniteDimensional (↥(subfield G F)) F

Next tactic:
exact IsNoetherian.iff_fg.1
      (IsNoetherian.iff_rank_lt_aleph0.2 <| (rank_le_card G F).trans_lt <| Cardinal.nat_lt_aleph0 _)
theorem finrank_le_card [Fintype G] : finrank (subfield G F) F ≤ Fintype.card G := by
  

Proof state:
M : Type u
inst✝⁵ : Monoid M
G : Type u
inst✝⁴ : Group G
F : Type v
inst✝³ : Field F
inst✝² : MulSemiringAction M F
inst✝¹ : MulSemiringAction G F
m : M
inst✝ : Fintype G
⊢ finrank (↥(subfield G F)) F ≤ Fintype.card G

Next tactic:
rw [← Cardinal.natCast_le, finrank_eq_rank]
theorem finrank_le_card [Fintype G] : finrank (subfield G F) F ≤ Fintype.card G := by
  rw [← Cardinal.natCast_le, finrank_eq_rank]
  

Proof state:
M : Type u
inst✝⁵ : Monoid M
G : Type u
inst✝⁴ : Group G
F : Type v
inst✝³ : Field F
inst✝² : MulSemiringAction M F
inst✝¹ : MulSemiringAction G F
m : M
inst✝ : Fintype G
⊢ Module.rank (↥(subfield G F)) F ≤ ↑(Fintype.card G)

Next tactic:
apply rank_le_card
/-- `MulSemiringAction.toAlgHom` is bijective. -/
theorem toAlgHom_bijective (G : Type u) (F : Type v) [Group G] [Field F] [Finite G]
    [MulSemiringAction G F] [FaithfulSMul G F] :
    Function.Bijective (MulSemiringAction.toAlgHom _ _ : G → F →ₐ[subfield G F] F) := by
  

Proof state:
M : Type u
inst✝⁹ : Monoid M
G✝ : Type u
inst✝⁸ : Group G✝
F✝ : Type v
inst✝⁷ : Field F✝
inst✝⁶ : MulSemiringAction M F✝
inst✝⁵ : MulSemiringAction G✝ F✝
m : M
G : Type u
F : Type v
inst✝⁴ : Group G
inst✝³ : Field F
inst✝² : Finite G
inst✝¹ : MulSemiringAction G F
inst✝ : FaithfulSMul G F
⊢ Function.Bijective (MulSemiringAction.toAlgHom (↥(subfield G F)) F)

Next tactic:
cases nonempty_fintype G
/-- `MulSemiringAction.toAlgHom` is bijective. -/
theorem toAlgHom_bijective (G : Type u) (F : Type v) [Group G] [Field F] [Finite G]
    [MulSemiringAction G F] [FaithfulSMul G F] :
    Function.Bijective (MulSemiringAction.toAlgHom _ _ : G → F →ₐ[subfield G F] F) := by
  cases nonempty_fintype G
  

Proof state:
case intro
M : Type u
inst✝⁹ : Monoid M
G✝ : Type u
inst✝⁸ : Group G✝
F✝ : Type v
inst✝⁷ : Field F✝
inst✝⁶ : MulSemiringAction M F✝
inst✝⁵ : MulSemiringAction G✝ F✝
m : M
G : Type u
F : Type v
inst✝⁴ : Group G
inst✝³ : Field F
inst✝² : Finite G
inst✝¹ : MulSemiringAction G F
inst✝ : FaithfulSMul G F
val✝ : Fintype G
⊢ Function.Bijective (MulSemiringAction.toAlgHom (↥(subfield G F)) F)

Next tactic:
rw [Fintype.bijective_iff_injective_and_card]
/-- `MulSemiringAction.toAlgHom` is bijective. -/
theorem toAlgHom_bijective (G : Type u) (F : Type v) [Group G] [Field F] [Finite G]
    [MulSemiringAction G F] [FaithfulSMul G F] :
    Function.Bijective (MulSemiringAction.toAlgHom _ _ : G → F →ₐ[subfield G F] F) := by
  cases nonempty_fintype G
  rw [Fintype.bijective_iff_injective_and_card]
  

Proof state:
case intro
M : Type u
inst✝⁹ : Monoid M
G✝ : Type u
inst✝⁸ : Group G✝
F✝ : Type v
inst✝⁷ : Field F✝
inst✝⁶ : MulSemiringAction M F✝
inst✝⁵ : MulSemiringAction G✝ F✝
m : M
G : Type u
F : Type v
inst✝⁴ : Group G
inst✝³ : Field F
inst✝² : Finite G
inst✝¹ : MulSemiringAction G F
inst✝ : FaithfulSMul G F
val✝ : Fintype G
⊢ Function.Injective (MulSemiringAction.toAlgHom (↥(subfield G F)) F) ∧
    Fintype.card G = Fintype.card (F →ₐ[↥(subfield G F)] F)

Next tactic:
constructor