l3lab/ntp-mathlib huggingface dataset:
theorem Normal.of_isSplittingField (p : F[X]) [hFEp : IsSplittingField F E p] : Normal F E := by
  rcases eq_or_ne p 0 with (rfl | hp)
  · have := hFEp.adjoin_rootSet
    rw [rootSet_zero, Algebra.adjoin_empty] at this
    exact Normal.of_algEquiv
      (AlgEquiv.ofBijective (Algebra.ofId F E) (Algebra.bijective_algebraMap_iff.2 this.symm))
  refine normal_iff.mpr fun x ↦ ?_
  haveI : FiniteDimensional F E := IsSplittingField.finiteDimensional E p
  have hx := IsIntegral.of_finite F x
  let L := (p * minpoly F x).SplittingField
  have hL := splits_of_splits_mul' _ ?_ (SplittingField.splits (p * minpoly F x))
  · let j : E →ₐ[F] L := IsSplittingField.lift E p hL.1
    refine ⟨hx, splits_of_comp _ (j : E →+* L) (j.comp_algebraMap ▸ hL.2) fun a ha ↦ ?_⟩
    rw [j.comp_algebraMap] at ha
    letI : Algebra F⟮x⟯ L := ((algHomAdjoinIntegralEquiv F hx).symm ⟨a, ha⟩).toRingHom.toAlgebra
    let j' : E →ₐ[F⟮x⟯] L := IsSplittingField.lift E (p.map (algebraMap F F⟮x⟯)) ?_
    · change a ∈ j.range
      rw [← IsSplittingField.adjoin_rootSet_eq_range E p j,
            IsSplittingField.adjoin_rootSet_eq_range E p (j'.restrictScalars F)]
      exact ⟨x, (j'.commutes _).trans (algHomAdjoinIntegralEquiv_symm_apply_gen F hx _)⟩
    · rw [splits_map_iff, ← IsScalarTower.algebraMap_eq]; exact hL.1
  · 

Proof state:
case inr.refine_1
F : Type u_1
K : Type u_2
inst✝¹¹ : Field F
inst✝¹⁰ : Field K
inst✝⁹ : Algebra F K
E : Type u_3
inst✝⁸ : Field E
inst✝⁷ : Algebra F E
inst✝⁶ : Algebra K E
inst✝⁵ : IsScalarTower F K E
E' : Type u_4
inst✝⁴ : Field F
inst✝³ : Field E
inst✝² : Algebra F E
inst✝¹ : Field E'
inst✝ : Algebra F E'
p : F[X]
hFEp : IsSplittingField F E p
hp : p ≠ 0
x : E
this : FiniteDimensional F E
hx : IsIntegral F x
L : Type u_1 := SplittingField (p * minpoly F x)
⊢ Polynomial.map (algebraMap F (SplittingField (p * minpoly F x))) (p * minpoly F x) ≠ 0

Next tactic:
rw [Polynomial.map_ne_zero_iff (algebraMap F L).injective, mul_ne_zero_iff]
theorem Normal.of_isSplittingField (p : F[X]) [hFEp : IsSplittingField F E p] : Normal F E := by
  rcases eq_or_ne p 0 with (rfl | hp)
  · have := hFEp.adjoin_rootSet
    rw [rootSet_zero, Algebra.adjoin_empty] at this
    exact Normal.of_algEquiv
      (AlgEquiv.ofBijective (Algebra.ofId F E) (Algebra.bijective_algebraMap_iff.2 this.symm))
  refine normal_iff.mpr fun x ↦ ?_
  haveI : FiniteDimensional F E := IsSplittingField.finiteDimensional E p
  have hx := IsIntegral.of_finite F x
  let L := (p * minpoly F x).SplittingField
  have hL := splits_of_splits_mul' _ ?_ (SplittingField.splits (p * minpoly F x))
  · let j : E →ₐ[F] L := IsSplittingField.lift E p hL.1
    refine ⟨hx, splits_of_comp _ (j : E →+* L) (j.comp_algebraMap ▸ hL.2) fun a ha ↦ ?_⟩
    rw [j.comp_algebraMap] at ha
    letI : Algebra F⟮x⟯ L := ((algHomAdjoinIntegralEquiv F hx).symm ⟨a, ha⟩).toRingHom.toAlgebra
    let j' : E →ₐ[F⟮x⟯] L := IsSplittingField.lift E (p.map (algebraMap F F⟮x⟯)) ?_
    · change a ∈ j.range
      rw [← IsSplittingField.adjoin_rootSet_eq_range E p j,
            IsSplittingField.adjoin_rootSet_eq_range E p (j'.restrictScalars F)]
      exact ⟨x, (j'.commutes _).trans (algHomAdjoinIntegralEquiv_symm_apply_gen F hx _)⟩
    · rw [splits_map_iff, ← IsScalarTower.algebraMap_eq]; exact hL.1
  · rw [Polynomial.map_ne_zero_iff (algebraMap F L).injective, mul_ne_zero_iff]
    

Proof state:
case inr.refine_1
F : Type u_1
K : Type u_2
inst✝¹¹ : Field F
inst✝¹⁰ : Field K
inst✝⁹ : Algebra F K
E : Type u_3
inst✝⁸ : Field E
inst✝⁷ : Algebra F E
inst✝⁶ : Algebra K E
inst✝⁵ : IsScalarTower F K E
E' : Type u_4
inst✝⁴ : Field F
inst✝³ : Field E
inst✝² : Algebra F E
inst✝¹ : Field E'
inst✝ : Algebra F E'
p : F[X]
hFEp : IsSplittingField F E p
hp : p ≠ 0
x : E
this : FiniteDimensional F E
hx : IsIntegral F x
L : Type u_1 := SplittingField (p * minpoly F x)
⊢ p ≠ 0 ∧ minpoly F x ≠ 0

Next tactic:
exact ⟨hp, minpoly.ne_zero hx⟩
/-- A compositum of normal extensions is normal -/
instance normal_iSup {ι : Type*} (t : ι → IntermediateField F K) [h : ∀ i, Normal F (t i)] :
    Normal F (⨆ i, t i : IntermediateField F K) := by
  

Proof state:
F : Type u_1
K : Type u_2
inst✝² : Field F
inst✝¹ : Field K
inst✝ : Algebra F K
ι : Type u_3
t : ι → IntermediateField F K
h : ∀ (i : ι), Normal F ↥(t i)
⊢ Normal F ↥(⨆ i, t i)

Next tactic:
refine' ⟨isAlgebraic_iSup fun i => (h i).1, fun x => _⟩
/-- A compositum of normal extensions is normal -/
instance normal_iSup {ι : Type*} (t : ι → IntermediateField F K) [h : ∀ i, Normal F (t i)] :
    Normal F (⨆ i, t i : IntermediateField F K) := by
  refine' ⟨isAlgebraic_iSup fun i => (h i).1, fun x => _⟩
  

Proof state:
F : Type u_1
K : Type u_2
inst✝² : Field F
inst✝¹ : Field K
inst✝ : Algebra F K
ι : Type u_3
t : ι → IntermediateField F K
h : ∀ (i : ι), Normal F ↥(t i)
x : ↥(⨆ i, t i)
⊢ Splits (algebraMap F ↥(⨆ i, t i)) (minpoly F x)

Next tactic:
obtain ⟨s, hx⟩ := exists_finset_of_mem_supr'' (fun i => (h i).1) x.2
/-- A compositum of normal extensions is normal -/
instance normal_iSup {ι : Type*} (t : ι → IntermediateField F K) [h : ∀ i, Normal F (t i)] :
    Normal F (⨆ i, t i : IntermediateField F K) := by
  refine' ⟨isAlgebraic_iSup fun i => (h i).1, fun x => _⟩
  obtain ⟨s, hx⟩ := exists_finset_of_mem_supr'' (fun i => (h i).1) x.2
  

Proof state:
case intro
F : Type u_1
K : Type u_2
inst✝² : Field F
inst✝¹ : Field K
inst✝ : Algebra F K
ι : Type u_3
t : ι → IntermediateField F K
h : ∀ (i : ι), Normal F ↥(t i)
x : ↥(⨆ i, t i)
s : Finset ((i : ι) × ↥(t i))
hx : ↑x ∈ ⨆ i ∈ s, adjoin F (rootSet (minpoly F i.snd) K)
⊢ Splits (algebraMap F ↥(⨆ i, t i)) (minpoly F x)

Next tactic:
let E : IntermediateField F K := ⨆ i ∈ s, adjoin F ((minpoly F (i.2 : _)).rootSet K)
/-- A compositum of normal extensions is normal -/
instance normal_iSup {ι : Type*} (t : ι → IntermediateField F K) [h : ∀ i, Normal F (t i)] :
    Normal F (⨆ i, t i : IntermediateField F K) := by
  refine' ⟨isAlgebraic_iSup fun i => (h i).1, fun x => _⟩
  obtain ⟨s, hx⟩ := exists_finset_of_mem_supr'' (fun i => (h i).1) x.2
  let E : IntermediateField F K := ⨆ i ∈ s, adjoin F ((minpoly F (i.2 : _)).rootSet K)
  

Proof state:
case intro
F : Type u_1
K : Type u_2
inst✝² : Field F
inst✝¹ : Field K
inst✝ : Algebra F K
ι : Type u_3
t : ι → IntermediateField F K
h : ∀ (i : ι), Normal F ↥(t i)
x : ↥(⨆ i, t i)
s : Finset ((i : ι) × ↥(t i))
hx : ↑x ∈ ⨆ i ∈ s, adjoin F (rootSet (minpoly F i.snd) K)
E : IntermediateField F K := ⨆ i ∈ s, adjoin F (rootSet (minpoly F i.snd) K)
⊢ Splits (algebraMap F ↥(⨆ i, t i)) (minpoly F x)

Next tactic:
have hF : Normal F E := by
    haveI : IsSplittingField F E (∏ i in s, minpoly F i.snd) := by
      refine' isSplittingField_iSup _ fun i _ => adjoin_rootSet_isSplittingField _
      · exact Finset.prod_ne_zero_iff.mpr fun i _ => minpoly.ne_zero ((h i.1).isIntegral i.2)
      · exact Polynomial.splits_comp_of_splits _ (algebraMap (t i.1) K) ((h i.1).splits i.2)
    apply Normal.of_isSplittingField (∏ i in s, minpoly F i.2)
/-- A compositum of normal extensions is normal -/
instance normal_iSup {ι : Type*} (t : ι → IntermediateField F K) [h : ∀ i, Normal F (t i)] :
    Normal F (⨆ i, t i : IntermediateField F K) := by
  refine' ⟨isAlgebraic_iSup fun i => (h i).1, fun x => _⟩
  obtain ⟨s, hx⟩ := exists_finset_of_mem_supr'' (fun i => (h i).1) x.2
  let E : IntermediateField F K := ⨆ i ∈ s, adjoin F ((minpoly F (i.2 : _)).rootSet K)
  have hF : Normal F E := by
    

Proof state:
F : Type u_1
K : Type u_2
inst✝² : Field F
inst✝¹ : Field K
inst✝ : Algebra F K
ι : Type u_3
t : ι → IntermediateField F K
h : ∀ (i : ι), Normal F ↥(t i)
x : ↥(⨆ i, t i)
s : Finset ((i : ι) × ↥(t i))
hx : ↑x ∈ ⨆ i ∈ s, adjoin F (rootSet (minpoly F i.snd) K)
E : IntermediateField F K := ⨆ i ∈ s, adjoin F (rootSet (minpoly F i.snd) K)
⊢ Normal F ↥E

Next tactic:
haveI : IsSplittingField F E (∏ i in s, minpoly F i.snd) := by
      refine' isSplittingField_iSup _ fun i _ => adjoin_rootSet_isSplittingField _
      · exact Finset.prod_ne_zero_iff.mpr fun i _ => minpoly.ne_zero ((h i.1).isIntegral i.2)
      · exact Polynomial.splits_comp_of_splits _ (algebraMap (t i.1) K) ((h i.1).splits i.2)
/-- A compositum of normal extensions is normal -/
instance normal_iSup {ι : Type*} (t : ι → IntermediateField F K) [h : ∀ i, Normal F (t i)] :
    Normal F (⨆ i, t i : IntermediateField F K) := by
  refine' ⟨isAlgebraic_iSup fun i => (h i).1, fun x => _⟩
  obtain ⟨s, hx⟩ := exists_finset_of_mem_supr'' (fun i => (h i).1) x.2
  let E : IntermediateField F K := ⨆ i ∈ s, adjoin F ((minpoly F (i.2 : _)).rootSet K)
  have hF : Normal F E := by
    haveI : IsSplittingField F E (∏ i in s, minpoly F i.snd) := by
      

Proof state:
F : Type u_1
K : Type u_2
inst✝² : Field F
inst✝¹ : Field K
inst✝ : Algebra F K
ι : Type u_3
t : ι → IntermediateField F K
h : ∀ (i : ι), Normal F ↥(t i)
x : ↥(⨆ i, t i)
s : Finset ((i : ι) × ↥(t i))
hx : ↑x ∈ ⨆ i ∈ s, adjoin F (rootSet (minpoly F i.snd) K)
E : IntermediateField F K := ⨆ i ∈ s, adjoin F (rootSet (minpoly F i.snd) K)
⊢ IsSplittingField F (↥E) (∏ i in s, minpoly F i.snd)

Next tactic:
refine' isSplittingField_iSup _ fun i _ => adjoin_rootSet_isSplittingField _
/-- A compositum of normal extensions is normal -/
instance normal_iSup {ι : Type*} (t : ι → IntermediateField F K) [h : ∀ i, Normal F (t i)] :
    Normal F (⨆ i, t i : IntermediateField F K) := by
  refine' ⟨isAlgebraic_iSup fun i => (h i).1, fun x => _⟩
  obtain ⟨s, hx⟩ := exists_finset_of_mem_supr'' (fun i => (h i).1) x.2
  let E : IntermediateField F K := ⨆ i ∈ s, adjoin F ((minpoly F (i.2 : _)).rootSet K)
  have hF : Normal F E := by
    haveI : IsSplittingField F E (∏ i in s, minpoly F i.snd) := by
      refine' isSplittingField_iSup _ fun i _ => adjoin_rootSet_isSplittingField _
      · 

Proof state:
case refine'_1
F : Type u_1
K : Type u_2
inst✝² : Field F
inst✝¹ : Field K
inst✝ : Algebra F K
ι : Type u_3
t : ι → IntermediateField F K
h : ∀ (i : ι), Normal F ↥(t i)
x : ↥(⨆ i, t i)
s : Finset ((i : ι) × ↥(t i))
hx : ↑x ∈ ⨆ i ∈ s, adjoin F (rootSet (minpoly F i.snd) K)
E : IntermediateField F K := ⨆ i ∈ s, adjoin F (rootSet (minpoly F i.snd) K)
⊢ ∏ i in s, minpoly F i.snd ≠ 0

Next tactic:
exact Finset.prod_ne_zero_iff.mpr fun i _ => minpoly.ne_zero ((h i.1).isIntegral i.2)
/-- A compositum of normal extensions is normal -/
instance normal_iSup {ι : Type*} (t : ι → IntermediateField F K) [h : ∀ i, Normal F (t i)] :
    Normal F (⨆ i, t i : IntermediateField F K) := by
  refine' ⟨isAlgebraic_iSup fun i => (h i).1, fun x => _⟩
  obtain ⟨s, hx⟩ := exists_finset_of_mem_supr'' (fun i => (h i).1) x.2
  let E : IntermediateField F K := ⨆ i ∈ s, adjoin F ((minpoly F (i.2 : _)).rootSet K)
  have hF : Normal F E := by
    haveI : IsSplittingField F E (∏ i in s, minpoly F i.snd) := by
      refine' isSplittingField_iSup _ fun i _ => adjoin_rootSet_isSplittingField _
      · exact Finset.prod_ne_zero_iff.mpr fun i _ => minpoly.ne_zero ((h i.1).isIntegral i.2)
      · 

Proof state:
case refine'_2
F : Type u_1
K : Type u_2
inst✝² : Field F
inst✝¹ : Field K
inst✝ : Algebra F K
ι : Type u_3
t : ι → IntermediateField F K
h : ∀ (i : ι), Normal F ↥(t i)
x : ↥(⨆ i, t i)
s : Finset ((i : ι) × ↥(t i))
hx : ↑x ∈ ⨆ i ∈ s, adjoin F (rootSet (minpoly F i.snd) K)
E : IntermediateField F K := ⨆ i ∈ s, adjoin F (rootSet (minpoly F i.snd) K)
i : (i : ι) × ↥(t i)
x✝ : i ∈ s
⊢ Splits (algebraMap F K) (minpoly F i.snd)

Next tactic:
exact Polynomial.splits_comp_of_splits _ (algebraMap (t i.1) K) ((h i.1).splits i.2)
/-- A compositum of normal extensions is normal -/
instance normal_iSup {ι : Type*} (t : ι → IntermediateField F K) [h : ∀ i, Normal F (t i)] :
    Normal F (⨆ i, t i : IntermediateField F K) := by
  refine' ⟨isAlgebraic_iSup fun i => (h i).1, fun x => _⟩
  obtain ⟨s, hx⟩ := exists_finset_of_mem_supr'' (fun i => (h i).1) x.2
  let E : IntermediateField F K := ⨆ i ∈ s, adjoin F ((minpoly F (i.2 : _)).rootSet K)
  have hF : Normal F E := by
    haveI : IsSplittingField F E (∏ i in s, minpoly F i.snd) := by
      refine' isSplittingField_iSup _ fun i _ => adjoin_rootSet_isSplittingField _
      · exact Finset.prod_ne_zero_iff.mpr fun i _ => minpoly.ne_zero ((h i.1).isIntegral i.2)
      · exact Polynomial.splits_comp_of_splits _ (algebraMap (t i.1) K) ((h i.1).splits i.2)
    

Proof state:
F : Type u_1
K : Type u_2
inst✝² : Field F
inst✝¹ : Field K
inst✝ : Algebra F K
ι : Type u_3
t : ι → IntermediateField F K
h : ∀ (i : ι), Normal F ↥(t i)
x : ↥(⨆ i, t i)
s : Finset ((i : ι) × ↥(t i))
hx : ↑x ∈ ⨆ i ∈ s, adjoin F (rootSet (minpoly F i.snd) K)
E : IntermediateField F K := ⨆ i ∈ s, adjoin F (rootSet (minpoly F i.snd) K)
this : IsSplittingField F (↥E) (∏ i in s, minpoly F i.snd)
⊢ Normal F ↥E

Next tactic:
apply Normal.of_isSplittingField (∏ i in s, minpoly F i.2)
/-- A compositum of normal extensions is normal -/
instance normal_iSup {ι : Type*} (t : ι → IntermediateField F K) [h : ∀ i, Normal F (t i)] :
    Normal F (⨆ i, t i : IntermediateField F K) := by
  refine' ⟨isAlgebraic_iSup fun i => (h i).1, fun x => _⟩
  obtain ⟨s, hx⟩ := exists_finset_of_mem_supr'' (fun i => (h i).1) x.2
  let E : IntermediateField F K := ⨆ i ∈ s, adjoin F ((minpoly F (i.2 : _)).rootSet K)
  have hF : Normal F E := by
    haveI : IsSplittingField F E (∏ i in s, minpoly F i.snd) := by
      refine' isSplittingField_iSup _ fun i _ => adjoin_rootSet_isSplittingField _
      · exact Finset.prod_ne_zero_iff.mpr fun i _ => minpoly.ne_zero ((h i.1).isIntegral i.2)
      · exact Polynomial.splits_comp_of_splits _ (algebraMap (t i.1) K) ((h i.1).splits i.2)
    apply Normal.of_isSplittingField (∏ i in s, minpoly F i.2)
  

Proof state:
case intro
F : Type u_1
K : Type u_2
inst✝² : Field F
inst✝¹ : Field K
inst✝ : Algebra F K
ι : Type u_3
t : ι → IntermediateField F K
h : ∀ (i : ι), Normal F ↥(t i)
x : ↥(⨆ i, t i)
s : Finset ((i : ι) × ↥(t i))
hx : ↑x ∈ ⨆ i ∈ s, adjoin F (rootSet (minpoly F i.snd) K)
E : IntermediateField F K := ⨆ i ∈ s, adjoin F (rootSet (minpoly F i.snd) K)
hF : Normal F ↥E
⊢ Splits (algebraMap F ↥(⨆ i, t i)) (minpoly F x)

Next tactic:
have hE : E ≤ ⨆ i, t i := by
    refine' iSup_le fun i => iSup_le fun _ => le_iSup_of_le i.1 _
    rw [adjoin_le_iff, ← image_rootSet ((h i.1).splits i.2) (t i.1).val]
    exact fun _ ⟨a, _, h⟩ => h ▸ a.2
/-- A compositum of normal extensions is normal -/
instance normal_iSup {ι : Type*} (t : ι → IntermediateField F K) [h : ∀ i, Normal F (t i)] :
    Normal F (⨆ i, t i : IntermediateField F K) := by
  refine' ⟨isAlgebraic_iSup fun i => (h i).1, fun x => _⟩
  obtain ⟨s, hx⟩ := exists_finset_of_mem_supr'' (fun i => (h i).1) x.2
  let E : IntermediateField F K := ⨆ i ∈ s, adjoin F ((minpoly F (i.2 : _)).rootSet K)
  have hF : Normal F E := by
    haveI : IsSplittingField F E (∏ i in s, minpoly F i.snd) := by
      refine' isSplittingField_iSup _ fun i _ => adjoin_rootSet_isSplittingField _
      · exact Finset.prod_ne_zero_iff.mpr fun i _ => minpoly.ne_zero ((h i.1).isIntegral i.2)
      · exact Polynomial.splits_comp_of_splits _ (algebraMap (t i.1) K) ((h i.1).splits i.2)
    apply Normal.of_isSplittingField (∏ i in s, minpoly F i.2)
  have hE : E ≤ ⨆ i, t i := by
    

Proof state:
F : Type u_1
K : Type u_2
inst✝² : Field F
inst✝¹ : Field K
inst✝ : Algebra F K
ι : Type u_3
t : ι → IntermediateField F K
h : ∀ (i : ι), Normal F ↥(t i)
x : ↥(⨆ i, t i)
s : Finset ((i : ι) × ↥(t i))
hx : ↑x ∈ ⨆ i ∈ s, adjoin F (rootSet (minpoly F i.snd) K)
E : IntermediateField F K := ⨆ i ∈ s, adjoin F (rootSet (minpoly F i.snd) K)
hF : Normal F ↥E
⊢ E ≤ ⨆ i, t i

Next tactic:
refine' iSup_le fun i => iSup_le fun _ => le_iSup_of_le i.1 _
/-- A compositum of normal extensions is normal -/
instance normal_iSup {ι : Type*} (t : ι → IntermediateField F K) [h : ∀ i, Normal F (t i)] :
    Normal F (⨆ i, t i : IntermediateField F K) := by
  refine' ⟨isAlgebraic_iSup fun i => (h i).1, fun x => _⟩
  obtain ⟨s, hx⟩ := exists_finset_of_mem_supr'' (fun i => (h i).1) x.2
  let E : IntermediateField F K := ⨆ i ∈ s, adjoin F ((minpoly F (i.2 : _)).rootSet K)
  have hF : Normal F E := by
    haveI : IsSplittingField F E (∏ i in s, minpoly F i.snd) := by
      refine' isSplittingField_iSup _ fun i _ => adjoin_rootSet_isSplittingField _
      · exact Finset.prod_ne_zero_iff.mpr fun i _ => minpoly.ne_zero ((h i.1).isIntegral i.2)
      · exact Polynomial.splits_comp_of_splits _ (algebraMap (t i.1) K) ((h i.1).splits i.2)
    apply Normal.of_isSplittingField (∏ i in s, minpoly F i.2)
  have hE : E ≤ ⨆ i, t i := by
    refine' iSup_le fun i => iSup_le fun _ => le_iSup_of_le i.1 _
    

Proof state:
F : Type u_1
K : Type u_2
inst✝² : Field F
inst✝¹ : Field K
inst✝ : Algebra F K
ι : Type u_3
t : ι → IntermediateField F K
h : ∀ (i : ι), Normal F ↥(t i)
x : ↥(⨆ i, t i)
s : Finset ((i : ι) × ↥(t i))
hx : ↑x ∈ ⨆ i ∈ s, adjoin F (rootSet (minpoly F i.snd) K)
E : IntermediateField F K := ⨆ i ∈ s, adjoin F (rootSet (minpoly F i.snd) K)
hF : Normal F ↥E
i : (i : ι) × ↥(t i)
x✝ : i ∈ s
⊢ adjoin F (rootSet (minpoly F i.snd) K) ≤ t i.fst

Next tactic:
rw [adjoin_le_iff, ← image_rootSet ((h i.1).splits i.2) (t i.1).val]
/-- A compositum of normal extensions is normal -/
instance normal_iSup {ι : Type*} (t : ι → IntermediateField F K) [h : ∀ i, Normal F (t i)] :
    Normal F (⨆ i, t i : IntermediateField F K) := by
  refine' ⟨isAlgebraic_iSup fun i => (h i).1, fun x => _⟩
  obtain ⟨s, hx⟩ := exists_finset_of_mem_supr'' (fun i => (h i).1) x.2
  let E : IntermediateField F K := ⨆ i ∈ s, adjoin F ((minpoly F (i.2 : _)).rootSet K)
  have hF : Normal F E := by
    haveI : IsSplittingField F E (∏ i in s, minpoly F i.snd) := by
      refine' isSplittingField_iSup _ fun i _ => adjoin_rootSet_isSplittingField _
      · exact Finset.prod_ne_zero_iff.mpr fun i _ => minpoly.ne_zero ((h i.1).isIntegral i.2)
      · exact Polynomial.splits_comp_of_splits _ (algebraMap (t i.1) K) ((h i.1).splits i.2)
    apply Normal.of_isSplittingField (∏ i in s, minpoly F i.2)
  have hE : E ≤ ⨆ i, t i := by
    refine' iSup_le fun i => iSup_le fun _ => le_iSup_of_le i.1 _
    rw [adjoin_le_iff, ← image_rootSet ((h i.1).splits i.2) (t i.1).val]
    

Proof state:
F : Type u_1
K : Type u_2
inst✝² : Field F
inst✝¹ : Field K
inst✝ : Algebra F K
ι : Type u_3
t : ι → IntermediateField F K
h : ∀ (i : ι), Normal F ↥(t i)
x : ↥(⨆ i, t i)
s : Finset ((i : ι) × ↥(t i))
hx : ↑x ∈ ⨆ i ∈ s, adjoin F (rootSet (minpoly F i.snd) K)
E : IntermediateField F K := ⨆ i ∈ s, adjoin F (rootSet (minpoly F i.snd) K)
hF : Normal F ↥E
i : (i : ι) × ↥(t i)
x✝ : i ∈ s
⊢ ⇑(val (t i.fst)) '' rootSet (minpoly F i.snd) ↥(t i.fst) ≤ ↑(t i.fst)

Next tactic:
exact fun _ ⟨a, _, h⟩ => h ▸ a.2
/-- A compositum of normal extensions is normal -/
instance normal_iSup {ι : Type*} (t : ι → IntermediateField F K) [h : ∀ i, Normal F (t i)] :
    Normal F (⨆ i, t i : IntermediateField F K) := by
  refine' ⟨isAlgebraic_iSup fun i => (h i).1, fun x => _⟩
  obtain ⟨s, hx⟩ := exists_finset_of_mem_supr'' (fun i => (h i).1) x.2
  let E : IntermediateField F K := ⨆ i ∈ s, adjoin F ((minpoly F (i.2 : _)).rootSet K)
  have hF : Normal F E := by
    haveI : IsSplittingField F E (∏ i in s, minpoly F i.snd) := by
      refine' isSplittingField_iSup _ fun i _ => adjoin_rootSet_isSplittingField _
      · exact Finset.prod_ne_zero_iff.mpr fun i _ => minpoly.ne_zero ((h i.1).isIntegral i.2)
      · exact Polynomial.splits_comp_of_splits _ (algebraMap (t i.1) K) ((h i.1).splits i.2)
    apply Normal.of_isSplittingField (∏ i in s, minpoly F i.2)
  have hE : E ≤ ⨆ i, t i := by
    refine' iSup_le fun i => iSup_le fun _ => le_iSup_of_le i.1 _
    rw [adjoin_le_iff, ← image_rootSet ((h i.1).splits i.2) (t i.1).val]
    exact fun _ ⟨a, _, h⟩ => h ▸ a.2
  

Proof state:
case intro
F : Type u_1
K : Type u_2
inst✝² : Field F
inst✝¹ : Field K
inst✝ : Algebra F K
ι : Type u_3
t : ι → IntermediateField F K
h : ∀ (i : ι), Normal F ↥(t i)
x : ↥(⨆ i, t i)
s : Finset ((i : ι) × ↥(t i))
hx : ↑x ∈ ⨆ i ∈ s, adjoin F (rootSet (minpoly F i.snd) K)
E : IntermediateField F K := ⨆ i ∈ s, adjoin F (rootSet (minpoly F i.snd) K)
hF : Normal F ↥E
hE : E ≤ ⨆ i, t i
⊢ Splits (algebraMap F ↥(⨆ i, t i)) (minpoly F x)

Next tactic:
have := hF.splits ⟨x, hx⟩
/-- A compositum of normal extensions is normal -/
instance normal_iSup {ι : Type*} (t : ι → IntermediateField F K) [h : ∀ i, Normal F (t i)] :
    Normal F (⨆ i, t i : IntermediateField F K) := by
  refine' ⟨isAlgebraic_iSup fun i => (h i).1, fun x => _⟩
  obtain ⟨s, hx⟩ := exists_finset_of_mem_supr'' (fun i => (h i).1) x.2
  let E : IntermediateField F K := ⨆ i ∈ s, adjoin F ((minpoly F (i.2 : _)).rootSet K)
  have hF : Normal F E := by
    haveI : IsSplittingField F E (∏ i in s, minpoly F i.snd) := by
      refine' isSplittingField_iSup _ fun i _ => adjoin_rootSet_isSplittingField _
      · exact Finset.prod_ne_zero_iff.mpr fun i _ => minpoly.ne_zero ((h i.1).isIntegral i.2)
      · exact Polynomial.splits_comp_of_splits _ (algebraMap (t i.1) K) ((h i.1).splits i.2)
    apply Normal.of_isSplittingField (∏ i in s, minpoly F i.2)
  have hE : E ≤ ⨆ i, t i := by
    refine' iSup_le fun i => iSup_le fun _ => le_iSup_of_le i.1 _
    rw [adjoin_le_iff, ← image_rootSet ((h i.1).splits i.2) (t i.1).val]
    exact fun _ ⟨a, _, h⟩ => h ▸ a.2
  have := hF.splits ⟨x, hx⟩
  

Proof state:
case intro
F : Type u_1
K : Type u_2
inst✝² : Field F
inst✝¹ : Field K
inst✝ : Algebra F K
ι : Type u_3
t : ι → IntermediateField F K
h : ∀ (i : ι), Normal F ↥(t i)
x : ↥(⨆ i, t i)
s : Finset ((i : ι) × ↥(t i))
hx : ↑x ∈ ⨆ i ∈ s, adjoin F (rootSet (minpoly F i.snd) K)
E : IntermediateField F K := ⨆ i ∈ s, adjoin F (rootSet (minpoly F i.snd) K)
hF : Normal F ↥E
hE : E ≤ ⨆ i, t i
this : Splits (algebraMap F ↥E) (minpoly F { val := ↑x, property := hx })
⊢ Splits (algebraMap F ↥(⨆ i, t i)) (minpoly F x)

Next tactic:
rw [minpoly_eq, Subtype.coe_mk, ← minpoly_eq] at this
/-- A compositum of normal extensions is normal -/
instance normal_iSup {ι : Type*} (t : ι → IntermediateField F K) [h : ∀ i, Normal F (t i)] :
    Normal F (⨆ i, t i : IntermediateField F K) := by
  refine' ⟨isAlgebraic_iSup fun i => (h i).1, fun x => _⟩
  obtain ⟨s, hx⟩ := exists_finset_of_mem_supr'' (fun i => (h i).1) x.2
  let E : IntermediateField F K := ⨆ i ∈ s, adjoin F ((minpoly F (i.2 : _)).rootSet K)
  have hF : Normal F E := by
    haveI : IsSplittingField F E (∏ i in s, minpoly F i.snd) := by
      refine' isSplittingField_iSup _ fun i _ => adjoin_rootSet_isSplittingField _
      · exact Finset.prod_ne_zero_iff.mpr fun i _ => minpoly.ne_zero ((h i.1).isIntegral i.2)
      · exact Polynomial.splits_comp_of_splits _ (algebraMap (t i.1) K) ((h i.1).splits i.2)
    apply Normal.of_isSplittingField (∏ i in s, minpoly F i.2)
  have hE : E ≤ ⨆ i, t i := by
    refine' iSup_le fun i => iSup_le fun _ => le_iSup_of_le i.1 _
    rw [adjoin_le_iff, ← image_rootSet ((h i.1).splits i.2) (t i.1).val]
    exact fun _ ⟨a, _, h⟩ => h ▸ a.2
  have := hF.splits ⟨x, hx⟩
  rw [minpoly_eq, Subtype.coe_mk, ← minpoly_eq] at this
  

Proof state:
case intro
F : Type u_1
K : Type u_2
inst✝² : Field F
inst✝¹ : Field K
inst✝ : Algebra F K
ι : Type u_3
t : ι → IntermediateField F K
h : ∀ (i : ι), Normal F ↥(t i)
x : ↥(⨆ i, t i)
s : Finset ((i : ι) × ↥(t i))
hx : ↑x ∈ ⨆ i ∈ s, adjoin F (rootSet (minpoly F i.snd) K)
E : IntermediateField F K := ⨆ i ∈ s, adjoin F (rootSet (minpoly F i.snd) K)
hF : Normal F ↥E
hE : E ≤ ⨆ i, t i
this : Splits (algebraMap F ↥E) (minpoly F x)
⊢ Splits (algebraMap F ↥(⨆ i, t i)) (minpoly F x)

Next tactic:
exact Polynomial.splits_comp_of_splits _ (inclusion hE).toRingHom this
/-- If a set of algebraic elements in a field extension `K/F` have minimal polynomials that
  split in another extension `L/F`, then all minimal polynomials in the intermediate field
  generated by the set also split in `L/F`. -/
theorem splits_of_mem_adjoin {L} [Field L] [Algebra F L] {S : Set K}
    (splits : ∀ x ∈ S, IsIntegral F x ∧ (minpoly F x).Splits (algebraMap F L)) {x : K}
    (hx : x ∈ adjoin F S) : (minpoly F x).Splits (algebraMap F L) := by
  

Proof state:
F : Type u_1
K : Type u_2
inst✝⁴ : Field F
inst✝³ : Field K
inst✝² : Algebra F K
L : Type u_3
inst✝¹ : Field L
inst✝ : Algebra F L
S : Set K
splits : ∀ x ∈ S, IsIntegral F x ∧ Splits (algebraMap F L) (minpoly F x)
x : K
hx : x ∈ adjoin F S
⊢ Splits (algebraMap F L) (minpoly F x)

Next tactic:
let E : IntermediateField F L := ⨆ x : S, adjoin F ((minpoly F x.val).rootSet L)