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 ↦ ?_
  

Proof state:
case inr
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
⊢ IsIntegral F x ∧ Splits (algebraMap F E) (minpoly F x)

Next tactic:
haveI : FiniteDimensional F E := IsSplittingField.finiteDimensional E p
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
  

Proof state:
case inr
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
⊢ IsIntegral F x ∧ Splits (algebraMap F E) (minpoly F x)

Next tactic:
have hx := IsIntegral.of_finite F x
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
  

Proof state:
case inr
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
⊢ IsIntegral F x ∧ Splits (algebraMap F E) (minpoly F x)

Next tactic:
let L := (p * minpoly F x).SplittingField
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
  

Proof state:
case inr
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)
⊢ IsIntegral F x ∧ Splits (algebraMap F E) (minpoly F x)

Next tactic:
have hL := splits_of_splits_mul' _ ?_ (SplittingField.splits (p * minpoly F x))
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))
  · 

Proof state:
case inr.refine_2
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)
hL :
  Splits (algebraMap F (SplittingField (p * minpoly F x))) p ∧
    Splits (algebraMap F (SplittingField (p * minpoly F x))) (minpoly F x)
⊢ IsIntegral F x ∧ Splits (algebraMap F E) (minpoly F x)

Next tactic:
let j : E →ₐ[F] L := IsSplittingField.lift E p hL.1
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
    

Proof state:
case inr.refine_2
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)
hL :
  Splits (algebraMap F (SplittingField (p * minpoly F x))) p ∧
    Splits (algebraMap F (SplittingField (p * minpoly F x))) (minpoly F x)
j : E →ₐ[F] L := IsSplittingField.lift E p (_ : Splits (algebraMap F (SplittingField (p * minpoly F x))) p)
⊢ IsIntegral F x ∧ Splits (algebraMap F E) (minpoly F x)

Next tactic:
refine ⟨hx, splits_of_comp _ (j : E →+* L) (j.comp_algebraMap ▸ hL.2) fun a ha ↦ ?_⟩
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 ↦ ?_⟩
    

Proof state:
case inr.refine_2
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)
hL :
  Splits (algebraMap F (SplittingField (p * minpoly F x))) p ∧
    Splits (algebraMap F (SplittingField (p * minpoly F x))) (minpoly F x)
j : E →ₐ[F] L := IsSplittingField.lift E p (_ : Splits (algebraMap F (SplittingField (p * minpoly F x))) p)
a : L
ha : a ∈ roots (Polynomial.map (RingHom.comp (↑j) (algebraMap F E)) (minpoly F x))
⊢ a ∈ RingHom.range ↑j

Next tactic:
rw [j.comp_algebraMap] at ha
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
    

Proof state:
case inr.refine_2
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)
hL :
  Splits (algebraMap F (SplittingField (p * minpoly F x))) p ∧
    Splits (algebraMap F (SplittingField (p * minpoly F x))) (minpoly F x)
j : E →ₐ[F] L := IsSplittingField.lift E p (_ : Splits (algebraMap F (SplittingField (p * minpoly F x))) p)
a : L
ha : a ∈ roots (Polynomial.map (algebraMap F L) (minpoly F x))
⊢ a ∈ RingHom.range ↑j

Next tactic:
letI : Algebra F⟮x⟯ L := ((algHomAdjoinIntegralEquiv F hx).symm ⟨a, ha⟩).toRingHom.toAlgebra
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
    

Proof state:
case inr.refine_2
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)
hL :
  Splits (algebraMap F (SplittingField (p * minpoly F x))) p ∧
    Splits (algebraMap F (SplittingField (p * minpoly F x))) (minpoly F x)
j : E →ₐ[F] L := IsSplittingField.lift E p (_ : Splits (algebraMap F (SplittingField (p * minpoly F x))) p)
a : L
ha : a ∈ roots (Polynomial.map (algebraMap F L) (minpoly F x))
this : Algebra (↥F⟮x⟯) L := RingHom.toAlgebra ↑((algHomAdjoinIntegralEquiv F hx).symm { val := a, property := ha })
⊢ a ∈ RingHom.range ↑j

Next tactic:
let j' : E →ₐ[F⟮x⟯] L := IsSplittingField.lift E (p.map (algebraMap F F⟮x⟯)) ?_
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⟯)) ?_
    · 

Proof state:
case inr.refine_2.refine_2
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)
hL :
  Splits (algebraMap F (SplittingField (p * minpoly F x))) p ∧
    Splits (algebraMap F (SplittingField (p * minpoly F x))) (minpoly F x)
j : E →ₐ[F] L := IsSplittingField.lift E p (_ : Splits (algebraMap F (SplittingField (p * minpoly F x))) p)
a : L
ha : a ∈ roots (Polynomial.map (algebraMap F L) (minpoly F x))
this : Algebra (↥F⟮x⟯) L := RingHom.toAlgebra ↑((algHomAdjoinIntegralEquiv F hx).symm { val := a, property := ha })
j' : E →ₐ[↥F⟮x⟯] L := IsSplittingField.lift E (Polynomial.map (algebraMap F ↥F⟮x⟯) p) ?inr.refine_2.refine_1
⊢ a ∈ RingHom.range ↑j

Next tactic:
change a ∈ j.range
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
      

Proof state:
case inr.refine_2.refine_2
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)
hL :
  Splits (algebraMap F (SplittingField (p * minpoly F x))) p ∧
    Splits (algebraMap F (SplittingField (p * minpoly F x))) (minpoly F x)
j : E →ₐ[F] L := IsSplittingField.lift E p (_ : Splits (algebraMap F (SplittingField (p * minpoly F x))) p)
a : L
ha : a ∈ roots (Polynomial.map (algebraMap F L) (minpoly F x))
this : Algebra (↥F⟮x⟯) L := RingHom.toAlgebra ↑((algHomAdjoinIntegralEquiv F hx).symm { val := a, property := ha })
j' : E →ₐ[↥F⟮x⟯] L := IsSplittingField.lift E (Polynomial.map (algebraMap F ↥F⟮x⟯) p) ?inr.refine_2.refine_1
⊢ a ∈ AlgHom.range j

Next tactic:
rw [← IsSplittingField.adjoin_rootSet_eq_range E p j,
            IsSplittingField.adjoin_rootSet_eq_range E p (j'.restrictScalars F)]
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)]
      

Proof state:
case inr.refine_2.refine_2
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)
hL :
  Splits (algebraMap F (SplittingField (p * minpoly F x))) p ∧
    Splits (algebraMap F (SplittingField (p * minpoly F x))) (minpoly F x)
j : E →ₐ[F] L := IsSplittingField.lift E p (_ : Splits (algebraMap F (SplittingField (p * minpoly F x))) p)
a : L
ha : a ∈ roots (Polynomial.map (algebraMap F L) (minpoly F x))
this : Algebra (↥F⟮x⟯) L := RingHom.toAlgebra ↑((algHomAdjoinIntegralEquiv F hx).symm { val := a, property := ha })
j' : E →ₐ[↥F⟮x⟯] L := IsSplittingField.lift E (Polynomial.map (algebraMap F ↥F⟮x⟯) p) ?inr.refine_2.refine_1
⊢ a ∈ AlgHom.range (AlgHom.restrictScalars F j')

Next tactic:
exact ⟨x, (j'.commutes _).trans (algHomAdjoinIntegralEquiv_symm_apply_gen F hx _)⟩
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 _)⟩
    · 

Proof state:
case inr.refine_2.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)
hL :
  Splits (algebraMap F (SplittingField (p * minpoly F x))) p ∧
    Splits (algebraMap F (SplittingField (p * minpoly F x))) (minpoly F x)
j : E →ₐ[F] L := IsSplittingField.lift E p (_ : Splits (algebraMap F (SplittingField (p * minpoly F x))) p)
a : L
ha : a ∈ roots (Polynomial.map (algebraMap F L) (minpoly F x))
this : Algebra (↥F⟮x⟯) L := RingHom.toAlgebra ↑((algHomAdjoinIntegralEquiv F hx).symm { val := a, property := ha })
⊢ Splits (algebraMap (↥F⟮x⟯) L) (Polynomial.map (algebraMap F ↥F⟮x⟯) p)

Next tactic:
rw [splits_map_iff, ← IsScalarTower.algebraMap_eq]
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]; 

Proof state:
case inr.refine_2.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)
hL :
  Splits (algebraMap F (SplittingField (p * minpoly F x))) p ∧
    Splits (algebraMap F (SplittingField (p * minpoly F x))) (minpoly F x)
j : E →ₐ[F] L := IsSplittingField.lift E p (_ : Splits (algebraMap F (SplittingField (p * minpoly F x))) p)
a : L
ha : a ∈ roots (Polynomial.map (algebraMap F L) (minpoly F x))
this : Algebra (↥F⟮x⟯) L := RingHom.toAlgebra ↑((algHomAdjoinIntegralEquiv F hx).symm { val := a, property := ha })
⊢ Splits (algebraMap F L) p

Next tactic:
exact hL.1