l3lab/ntp-mathlib huggingface dataset:
/-- This is the heart of the proof of the primitive element theorem. It shows that if `F` is
infinite and `α` and `β` are separable over `F` then `F⟮α, β⟯` is generated by a single element. -/
theorem primitive_element_inf_aux [IsSeparable F E] : ∃ γ : E, F⟮α, β⟯ = F⟮γ⟯ := by
  have hα := IsSeparable.isIntegral F α
  

Proof state:
F : Type u_1
inst✝⁴ : Field F
inst✝³ : Infinite F
E : Type u_2
inst✝² : Field E
ϕ : F →+* E
α β : E
inst✝¹ : Algebra F E
inst✝ : IsSeparable F E
hα : IsIntegral F α
⊢ ∃ γ, F⟮α, β⟯ = F⟮γ⟯

Next tactic:
have hβ := IsSeparable.isIntegral F β
/-- This is the heart of the proof of the primitive element theorem. It shows that if `F` is
infinite and `α` and `β` are separable over `F` then `F⟮α, β⟯` is generated by a single element. -/
theorem primitive_element_inf_aux [IsSeparable F E] : ∃ γ : E, F⟮α, β⟯ = F⟮γ⟯ := by
  have hα := IsSeparable.isIntegral F α
  have hβ := IsSeparable.isIntegral F β
  

Proof state:
F : Type u_1
inst✝⁴ : Field F
inst✝³ : Infinite F
E : Type u_2
inst✝² : Field E
ϕ : F →+* E
α β : E
inst✝¹ : Algebra F E
inst✝ : IsSeparable F E
hα : IsIntegral F α
hβ : IsIntegral F β
⊢ ∃ γ, F⟮α, β⟯ = F⟮γ⟯

Next tactic:
let f := minpoly F α
/-- This is the heart of the proof of the primitive element theorem. It shows that if `F` is
infinite and `α` and `β` are separable over `F` then `F⟮α, β⟯` is generated by a single element. -/
theorem primitive_element_inf_aux [IsSeparable F E] : ∃ γ : E, F⟮α, β⟯ = F⟮γ⟯ := by
  have hα := IsSeparable.isIntegral F α
  have hβ := IsSeparable.isIntegral F β
  let f := minpoly F α
  

Proof state:
F : Type u_1
inst✝⁴ : Field F
inst✝³ : Infinite F
E : Type u_2
inst✝² : Field E
ϕ : F →+* E
α β : E
inst✝¹ : Algebra F E
inst✝ : IsSeparable F E
hα : IsIntegral F α
hβ : IsIntegral F β
f : F[X] := minpoly F α
⊢ ∃ γ, F⟮α, β⟯ = F⟮γ⟯

Next tactic:
let g := minpoly F β
/-- This is the heart of the proof of the primitive element theorem. It shows that if `F` is
infinite and `α` and `β` are separable over `F` then `F⟮α, β⟯` is generated by a single element. -/
theorem primitive_element_inf_aux [IsSeparable F E] : ∃ γ : E, F⟮α, β⟯ = F⟮γ⟯ := by
  have hα := IsSeparable.isIntegral F α
  have hβ := IsSeparable.isIntegral F β
  let f := minpoly F α
  let g := minpoly F β
  

Proof state:
F : Type u_1
inst✝⁴ : Field F
inst✝³ : Infinite F
E : Type u_2
inst✝² : Field E
ϕ : F →+* E
α β : E
inst✝¹ : Algebra F E
inst✝ : IsSeparable F E
hα : IsIntegral F α
hβ : IsIntegral F β
f : F[X] := minpoly F α
g : F[X] := minpoly F β
⊢ ∃ γ, F⟮α, β⟯ = F⟮γ⟯

Next tactic:
let ιFE := algebraMap F E
/-- This is the heart of the proof of the primitive element theorem. It shows that if `F` is
infinite and `α` and `β` are separable over `F` then `F⟮α, β⟯` is generated by a single element. -/
theorem primitive_element_inf_aux [IsSeparable F E] : ∃ γ : E, F⟮α, β⟯ = F⟮γ⟯ := by
  have hα := IsSeparable.isIntegral F α
  have hβ := IsSeparable.isIntegral F β
  let f := minpoly F α
  let g := minpoly F β
  let ιFE := algebraMap F E
  

Proof state:
F : Type u_1
inst✝⁴ : Field F
inst✝³ : Infinite F
E : Type u_2
inst✝² : Field E
ϕ : F →+* E
α β : E
inst✝¹ : Algebra F E
inst✝ : IsSeparable F E
hα : IsIntegral F α
hβ : IsIntegral F β
f : F[X] := minpoly F α
g : F[X] := minpoly F β
ιFE : F →+* E := algebraMap F E
⊢ ∃ γ, F⟮α, β⟯ = F⟮γ⟯

Next tactic:
let ιEE' := algebraMap E (SplittingField (g.map ιFE))
/-- This is the heart of the proof of the primitive element theorem. It shows that if `F` is
infinite and `α` and `β` are separable over `F` then `F⟮α, β⟯` is generated by a single element. -/
theorem primitive_element_inf_aux [IsSeparable F E] : ∃ γ : E, F⟮α, β⟯ = F⟮γ⟯ := by
  have hα := IsSeparable.isIntegral F α
  have hβ := IsSeparable.isIntegral F β
  let f := minpoly F α
  let g := minpoly F β
  let ιFE := algebraMap F E
  let ιEE' := algebraMap E (SplittingField (g.map ιFE))
  

Proof state:
F : Type u_1
inst✝⁴ : Field F
inst✝³ : Infinite F
E : Type u_2
inst✝² : Field E
ϕ : F →+* E
α β : E
inst✝¹ : Algebra F E
inst✝ : IsSeparable F E
hα : IsIntegral F α
hβ : IsIntegral F β
f : F[X] := minpoly F α
g : F[X] := minpoly F β
ιFE : F →+* E := algebraMap F E
ιEE' : E →+* SplittingField (Polynomial.map ιFE g) := algebraMap E (SplittingField (Polynomial.map ιFE g))
⊢ ∃ γ, F⟮α, β⟯ = F⟮γ⟯

Next tactic:
obtain ⟨c, hc⟩ := primitive_element_inf_aux_exists_c (ιEE'.comp ιFE) (ιEE' α) (ιEE' β) f g
/-- This is the heart of the proof of the primitive element theorem. It shows that if `F` is
infinite and `α` and `β` are separable over `F` then `F⟮α, β⟯` is generated by a single element. -/
theorem primitive_element_inf_aux [IsSeparable F E] : ∃ γ : E, F⟮α, β⟯ = F⟮γ⟯ := by
  have hα := IsSeparable.isIntegral F α
  have hβ := IsSeparable.isIntegral F β
  let f := minpoly F α
  let g := minpoly F β
  let ιFE := algebraMap F E
  let ιEE' := algebraMap E (SplittingField (g.map ιFE))
  obtain ⟨c, hc⟩ := primitive_element_inf_aux_exists_c (ιEE'.comp ιFE) (ιEE' α) (ιEE' β) f g
  

Proof state:
case intro
F : Type u_1
inst✝⁴ : Field F
inst✝³ : Infinite F
E : Type u_2
inst✝² : Field E
ϕ : F →+* E
α β : E
inst✝¹ : Algebra F E
inst✝ : IsSeparable F E
hα : IsIntegral F α
hβ : IsIntegral F β
f : F[X] := minpoly F α
g : F[X] := minpoly F β
ιFE : F →+* E := algebraMap F E
ιEE' : E →+* SplittingField (Polynomial.map ιFE g) := algebraMap E (SplittingField (Polynomial.map ιFE g))
c : F
hc :
  ∀ α' ∈ roots (Polynomial.map (RingHom.comp ιEE' ιFE) f),
    ∀ β' ∈ roots (Polynomial.map (RingHom.comp ιEE' ιFE) g), -(α' - ιEE' α) / (β' - ιEE' β) ≠ (RingHom.comp ιEE' ιFE) c
⊢ ∃ γ, F⟮α, β⟯ = F⟮γ⟯

Next tactic:
let γ := α + c • β
/-- This is the heart of the proof of the primitive element theorem. It shows that if `F` is
infinite and `α` and `β` are separable over `F` then `F⟮α, β⟯` is generated by a single element. -/
theorem primitive_element_inf_aux [IsSeparable F E] : ∃ γ : E, F⟮α, β⟯ = F⟮γ⟯ := by
  have hα := IsSeparable.isIntegral F α
  have hβ := IsSeparable.isIntegral F β
  let f := minpoly F α
  let g := minpoly F β
  let ιFE := algebraMap F E
  let ιEE' := algebraMap E (SplittingField (g.map ιFE))
  obtain ⟨c, hc⟩ := primitive_element_inf_aux_exists_c (ιEE'.comp ιFE) (ιEE' α) (ιEE' β) f g
  let γ := α + c • β
  

Proof state:
case intro
F : Type u_1
inst✝⁴ : Field F
inst✝³ : Infinite F
E : Type u_2
inst✝² : Field E
ϕ : F →+* E
α β : E
inst✝¹ : Algebra F E
inst✝ : IsSeparable F E
hα : IsIntegral F α
hβ : IsIntegral F β
f : F[X] := minpoly F α
g : F[X] := minpoly F β
ιFE : F →+* E := algebraMap F E
ιEE' : E →+* SplittingField (Polynomial.map ιFE g) := algebraMap E (SplittingField (Polynomial.map ιFE g))
c : F
hc :
  ∀ α' ∈ roots (Polynomial.map (RingHom.comp ιEE' ιFE) f),
    ∀ β' ∈ roots (Polynomial.map (RingHom.comp ιEE' ιFE) g), -(α' - ιEE' α) / (β' - ιEE' β) ≠ (RingHom.comp ιEE' ιFE) c
γ : E := α + c • β
⊢ ∃ γ, F⟮α, β⟯ = F⟮γ⟯

Next tactic:
suffices β_in_Fγ : β ∈ F⟮γ⟯
/-- This is the heart of the proof of the primitive element theorem. It shows that if `F` is
infinite and `α` and `β` are separable over `F` then `F⟮α, β⟯` is generated by a single element. -/
theorem primitive_element_inf_aux [IsSeparable F E] : ∃ γ : E, F⟮α, β⟯ = F⟮γ⟯ := by
  have hα := IsSeparable.isIntegral F α
  have hβ := IsSeparable.isIntegral F β
  let f := minpoly F α
  let g := minpoly F β
  let ιFE := algebraMap F E
  let ιEE' := algebraMap E (SplittingField (g.map ιFE))
  obtain ⟨c, hc⟩ := primitive_element_inf_aux_exists_c (ιEE'.comp ιFE) (ιEE' α) (ιEE' β) f g
  let γ := α + c • β
  suffices β_in_Fγ : β ∈ F⟮γ⟯
  · 

Proof state:
case intro
F : Type u_1
inst✝⁴ : Field F
inst✝³ : Infinite F
E : Type u_2
inst✝² : Field E
ϕ : F →+* E
α β : E
inst✝¹ : Algebra F E
inst✝ : IsSeparable F E
hα : IsIntegral F α
hβ : IsIntegral F β
f : F[X] := minpoly F α
g : F[X] := minpoly F β
ιFE : F →+* E := algebraMap F E
ιEE' : E →+* SplittingField (Polynomial.map ιFE g) := algebraMap E (SplittingField (Polynomial.map ιFE g))
c : F
hc :
  ∀ α' ∈ roots (Polynomial.map (RingHom.comp ιEE' ιFE) f),
    ∀ β' ∈ roots (Polynomial.map (RingHom.comp ιEE' ιFE) g), -(α' - ιEE' α) / (β' - ιEE' β) ≠ (RingHom.comp ιEE' ιFE) c
γ : E := α + c • β
β_in_Fγ : β ∈ F⟮γ⟯
⊢ ∃ γ, F⟮α, β⟯ = F⟮γ⟯

Next tactic:
use γ
/-- This is the heart of the proof of the primitive element theorem. It shows that if `F` is
infinite and `α` and `β` are separable over `F` then `F⟮α, β⟯` is generated by a single element. -/
theorem primitive_element_inf_aux [IsSeparable F E] : ∃ γ : E, F⟮α, β⟯ = F⟮γ⟯ := by
  have hα := IsSeparable.isIntegral F α
  have hβ := IsSeparable.isIntegral F β
  let f := minpoly F α
  let g := minpoly F β
  let ιFE := algebraMap F E
  let ιEE' := algebraMap E (SplittingField (g.map ιFE))
  obtain ⟨c, hc⟩ := primitive_element_inf_aux_exists_c (ιEE'.comp ιFE) (ιEE' α) (ιEE' β) f g
  let γ := α + c • β
  suffices β_in_Fγ : β ∈ F⟮γ⟯
  · use γ
    

Proof state:
case h
F : Type u_1
inst✝⁴ : Field F
inst✝³ : Infinite F
E : Type u_2
inst✝² : Field E
ϕ : F →+* E
α β : E
inst✝¹ : Algebra F E
inst✝ : IsSeparable F E
hα : IsIntegral F α
hβ : IsIntegral F β
f : F[X] := minpoly F α
g : F[X] := minpoly F β
ιFE : F →+* E := algebraMap F E
ιEE' : E →+* SplittingField (Polynomial.map ιFE g) := algebraMap E (SplittingField (Polynomial.map ιFE g))
c : F
hc :
  ∀ α' ∈ roots (Polynomial.map (RingHom.comp ιEE' ιFE) f),
    ∀ β' ∈ roots (Polynomial.map (RingHom.comp ιEE' ιFE) g), -(α' - ιEE' α) / (β' - ιEE' β) ≠ (RingHom.comp ιEE' ιFE) c
γ : E := α + c • β
β_in_Fγ : β ∈ F⟮γ⟯
⊢ F⟮α, β⟯ = F⟮γ⟯

Next tactic:
apply le_antisymm
/-- This is the heart of the proof of the primitive element theorem. It shows that if `F` is
infinite and `α` and `β` are separable over `F` then `F⟮α, β⟯` is generated by a single element. -/
theorem primitive_element_inf_aux [IsSeparable F E] : ∃ γ : E, F⟮α, β⟯ = F⟮γ⟯ := by
  have hα := IsSeparable.isIntegral F α
  have hβ := IsSeparable.isIntegral F β
  let f := minpoly F α
  let g := minpoly F β
  let ιFE := algebraMap F E
  let ιEE' := algebraMap E (SplittingField (g.map ιFE))
  obtain ⟨c, hc⟩ := primitive_element_inf_aux_exists_c (ιEE'.comp ιFE) (ιEE' α) (ιEE' β) f g
  let γ := α + c • β
  suffices β_in_Fγ : β ∈ F⟮γ⟯
  · use γ
    apply le_antisymm
    · 

Proof state:
case h.a
F : Type u_1
inst✝⁴ : Field F
inst✝³ : Infinite F
E : Type u_2
inst✝² : Field E
ϕ : F →+* E
α β : E
inst✝¹ : Algebra F E
inst✝ : IsSeparable F E
hα : IsIntegral F α
hβ : IsIntegral F β
f : F[X] := minpoly F α
g : F[X] := minpoly F β
ιFE : F →+* E := algebraMap F E
ιEE' : E →+* SplittingField (Polynomial.map ιFE g) := algebraMap E (SplittingField (Polynomial.map ιFE g))
c : F
hc :
  ∀ α' ∈ roots (Polynomial.map (RingHom.comp ιEE' ιFE) f),
    ∀ β' ∈ roots (Polynomial.map (RingHom.comp ιEE' ιFE) g), -(α' - ιEE' α) / (β' - ιEE' β) ≠ (RingHom.comp ιEE' ιFE) c
γ : E := α + c • β
β_in_Fγ : β ∈ F⟮γ⟯
⊢ F⟮α, β⟯ ≤ F⟮γ⟯

Next tactic:
rw [adjoin_le_iff]
/-- This is the heart of the proof of the primitive element theorem. It shows that if `F` is
infinite and `α` and `β` are separable over `F` then `F⟮α, β⟯` is generated by a single element. -/
theorem primitive_element_inf_aux [IsSeparable F E] : ∃ γ : E, F⟮α, β⟯ = F⟮γ⟯ := by
  have hα := IsSeparable.isIntegral F α
  have hβ := IsSeparable.isIntegral F β
  let f := minpoly F α
  let g := minpoly F β
  let ιFE := algebraMap F E
  let ιEE' := algebraMap E (SplittingField (g.map ιFE))
  obtain ⟨c, hc⟩ := primitive_element_inf_aux_exists_c (ιEE'.comp ιFE) (ιEE' α) (ιEE' β) f g
  let γ := α + c • β
  suffices β_in_Fγ : β ∈ F⟮γ⟯
  · use γ
    apply le_antisymm
    · rw [adjoin_le_iff]
      

Proof state:
case h.a
F : Type u_1
inst✝⁴ : Field F
inst✝³ : Infinite F
E : Type u_2
inst✝² : Field E
ϕ : F →+* E
α β : E
inst✝¹ : Algebra F E
inst✝ : IsSeparable F E
hα : IsIntegral F α
hβ : IsIntegral F β
f : F[X] := minpoly F α
g : F[X] := minpoly F β
ιFE : F →+* E := algebraMap F E
ιEE' : E →+* SplittingField (Polynomial.map ιFE g) := algebraMap E (SplittingField (Polynomial.map ιFE g))
c : F
hc :
  ∀ α' ∈ roots (Polynomial.map (RingHom.comp ιEE' ιFE) f),
    ∀ β' ∈ roots (Polynomial.map (RingHom.comp ιEE' ιFE) g), -(α' - ιEE' α) / (β' - ιEE' β) ≠ (RingHom.comp ιEE' ιFE) c
γ : E := α + c • β
β_in_Fγ : β ∈ F⟮γ⟯
⊢ {α, β} ≤ ↑F⟮γ⟯

Next tactic:
have α_in_Fγ : α ∈ F⟮γ⟯ := by
        rw [← add_sub_cancel α (c • β)]
        exact F⟮γ⟯.sub_mem (mem_adjoin_simple_self F γ) (F⟮γ⟯.toSubalgebra.smul_mem β_in_Fγ c)
/-- This is the heart of the proof of the primitive element theorem. It shows that if `F` is
infinite and `α` and `β` are separable over `F` then `F⟮α, β⟯` is generated by a single element. -/
theorem primitive_element_inf_aux [IsSeparable F E] : ∃ γ : E, F⟮α, β⟯ = F⟮γ⟯ := by
  have hα := IsSeparable.isIntegral F α
  have hβ := IsSeparable.isIntegral F β
  let f := minpoly F α
  let g := minpoly F β
  let ιFE := algebraMap F E
  let ιEE' := algebraMap E (SplittingField (g.map ιFE))
  obtain ⟨c, hc⟩ := primitive_element_inf_aux_exists_c (ιEE'.comp ιFE) (ιEE' α) (ιEE' β) f g
  let γ := α + c • β
  suffices β_in_Fγ : β ∈ F⟮γ⟯
  · use γ
    apply le_antisymm
    · rw [adjoin_le_iff]
      have α_in_Fγ : α ∈ F⟮γ⟯ := by
        

Proof state:
F : Type u_1
inst✝⁴ : Field F
inst✝³ : Infinite F
E : Type u_2
inst✝² : Field E
ϕ : F →+* E
α β : E
inst✝¹ : Algebra F E
inst✝ : IsSeparable F E
hα : IsIntegral F α
hβ : IsIntegral F β
f : F[X] := minpoly F α
g : F[X] := minpoly F β
ιFE : F →+* E := algebraMap F E
ιEE' : E →+* SplittingField (Polynomial.map ιFE g) := algebraMap E (SplittingField (Polynomial.map ιFE g))
c : F
hc :
  ∀ α' ∈ roots (Polynomial.map (RingHom.comp ιEE' ιFE) f),
    ∀ β' ∈ roots (Polynomial.map (RingHom.comp ιEE' ιFE) g), -(α' - ιEE' α) / (β' - ιEE' β) ≠ (RingHom.comp ιEE' ιFE) c
γ : E := α + c • β
β_in_Fγ : β ∈ F⟮γ⟯
⊢ α ∈ F⟮γ⟯

Next tactic:
rw [← add_sub_cancel α (c • β)]
/-- This is the heart of the proof of the primitive element theorem. It shows that if `F` is
infinite and `α` and `β` are separable over `F` then `F⟮α, β⟯` is generated by a single element. -/
theorem primitive_element_inf_aux [IsSeparable F E] : ∃ γ : E, F⟮α, β⟯ = F⟮γ⟯ := by
  have hα := IsSeparable.isIntegral F α
  have hβ := IsSeparable.isIntegral F β
  let f := minpoly F α
  let g := minpoly F β
  let ιFE := algebraMap F E
  let ιEE' := algebraMap E (SplittingField (g.map ιFE))
  obtain ⟨c, hc⟩ := primitive_element_inf_aux_exists_c (ιEE'.comp ιFE) (ιEE' α) (ιEE' β) f g
  let γ := α + c • β
  suffices β_in_Fγ : β ∈ F⟮γ⟯
  · use γ
    apply le_antisymm
    · rw [adjoin_le_iff]
      have α_in_Fγ : α ∈ F⟮γ⟯ := by
        rw [← add_sub_cancel α (c • β)]
        

Proof state:
F : Type u_1
inst✝⁴ : Field F
inst✝³ : Infinite F
E : Type u_2
inst✝² : Field E
ϕ : F →+* E
α β : E
inst✝¹ : Algebra F E
inst✝ : IsSeparable F E
hα : IsIntegral F α
hβ : IsIntegral F β
f : F[X] := minpoly F α
g : F[X] := minpoly F β
ιFE : F →+* E := algebraMap F E
ιEE' : E →+* SplittingField (Polynomial.map ιFE g) := algebraMap E (SplittingField (Polynomial.map ιFE g))
c : F
hc :
  ∀ α' ∈ roots (Polynomial.map (RingHom.comp ιEE' ιFE) f),
    ∀ β' ∈ roots (Polynomial.map (RingHom.comp ιEE' ιFE) g), -(α' - ιEE' α) / (β' - ιEE' β) ≠ (RingHom.comp ιEE' ιFE) c
γ : E := α + c • β
β_in_Fγ : β ∈ F⟮γ⟯
⊢ α + c • β - c • β ∈ F⟮γ⟯

Next tactic:
exact F⟮γ⟯.sub_mem (mem_adjoin_simple_self F γ) (F⟮γ⟯.toSubalgebra.smul_mem β_in_Fγ c)
/-- This is the heart of the proof of the primitive element theorem. It shows that if `F` is
infinite and `α` and `β` are separable over `F` then `F⟮α, β⟯` is generated by a single element. -/
theorem primitive_element_inf_aux [IsSeparable F E] : ∃ γ : E, F⟮α, β⟯ = F⟮γ⟯ := by
  have hα := IsSeparable.isIntegral F α
  have hβ := IsSeparable.isIntegral F β
  let f := minpoly F α
  let g := minpoly F β
  let ιFE := algebraMap F E
  let ιEE' := algebraMap E (SplittingField (g.map ιFE))
  obtain ⟨c, hc⟩ := primitive_element_inf_aux_exists_c (ιEE'.comp ιFE) (ιEE' α) (ιEE' β) f g
  let γ := α + c • β
  suffices β_in_Fγ : β ∈ F⟮γ⟯
  · use γ
    apply le_antisymm
    · rw [adjoin_le_iff]
      have α_in_Fγ : α ∈ F⟮γ⟯ := by
        rw [← add_sub_cancel α (c • β)]
        exact F⟮γ⟯.sub_mem (mem_adjoin_simple_self F γ) (F⟮γ⟯.toSubalgebra.smul_mem β_in_Fγ c)
      

Proof state:
case h.a
F : Type u_1
inst✝⁴ : Field F
inst✝³ : Infinite F
E : Type u_2
inst✝² : Field E
ϕ : F →+* E
α β : E
inst✝¹ : Algebra F E
inst✝ : IsSeparable F E
hα : IsIntegral F α
hβ : IsIntegral F β
f : F[X] := minpoly F α
g : F[X] := minpoly F β
ιFE : F →+* E := algebraMap F E
ιEE' : E →+* SplittingField (Polynomial.map ιFE g) := algebraMap E (SplittingField (Polynomial.map ιFE g))
c : F
hc :
  ∀ α' ∈ roots (Polynomial.map (RingHom.comp ιEE' ιFE) f),
    ∀ β' ∈ roots (Polynomial.map (RingHom.comp ιEE' ιFE) g), -(α' - ιEE' α) / (β' - ιEE' β) ≠ (RingHom.comp ιEE' ιFE) c
γ : E := α + c • β
β_in_Fγ : β ∈ F⟮γ⟯
α_in_Fγ : α ∈ F⟮γ⟯
⊢ {α, β} ≤ ↑F⟮γ⟯

Next tactic:
rintro x (rfl | rfl)
/-- This is the heart of the proof of the primitive element theorem. It shows that if `F` is
infinite and `α` and `β` are separable over `F` then `F⟮α, β⟯` is generated by a single element. -/
theorem primitive_element_inf_aux [IsSeparable F E] : ∃ γ : E, F⟮α, β⟯ = F⟮γ⟯ := by
  have hα := IsSeparable.isIntegral F α
  have hβ := IsSeparable.isIntegral F β
  let f := minpoly F α
  let g := minpoly F β
  let ιFE := algebraMap F E
  let ιEE' := algebraMap E (SplittingField (g.map ιFE))
  obtain ⟨c, hc⟩ := primitive_element_inf_aux_exists_c (ιEE'.comp ιFE) (ιEE' α) (ιEE' β) f g
  let γ := α + c • β
  suffices β_in_Fγ : β ∈ F⟮γ⟯
  · use γ
    apply le_antisymm
    · rw [adjoin_le_iff]
      have α_in_Fγ : α ∈ F⟮γ⟯ := by
        rw [← add_sub_cancel α (c • β)]
        exact F⟮γ⟯.sub_mem (mem_adjoin_simple_self F γ) (F⟮γ⟯.toSubalgebra.smul_mem β_in_Fγ c)
      rintro x (rfl | rfl) <;> 

Proof state:
case h.a.inl
F : Type u_1
inst✝⁴ : Field F
inst✝³ : Infinite F
E : Type u_2
inst✝² : Field E
ϕ : F →+* E
β : E
inst✝¹ : Algebra F E
inst✝ : IsSeparable F E
hβ : IsIntegral F β
g : F[X] := minpoly F β
ιFE : F →+* E := algebraMap F E
ιEE' : E →+* SplittingField (Polynomial.map ιFE g) := algebraMap E (SplittingField (Polynomial.map ιFE g))
c : F
x : E
hα : IsIntegral F x
f : F[X] := minpoly F x
hc :
  ∀ α' ∈ roots (Polynomial.map (RingHom.comp ιEE' ιFE) f),
    ∀ β' ∈ roots (Polynomial.map (RingHom.comp ιEE' ιFE) g), -(α' - ιEE' x) / (β' - ιEE' β) ≠ (RingHom.comp ιEE' ιFE) c
γ : E := x + c • β
β_in_Fγ : β ∈ F⟮γ⟯
α_in_Fγ : x ∈ F⟮γ⟯
⊢ x ∈ ↑F⟮γ⟯

Next tactic:
assumption
/-- This is the heart of the proof of the primitive element theorem. It shows that if `F` is
infinite and `α` and `β` are separable over `F` then `F⟮α, β⟯` is generated by a single element. -/
theorem primitive_element_inf_aux [IsSeparable F E] : ∃ γ : E, F⟮α, β⟯ = F⟮γ⟯ := by
  have hα := IsSeparable.isIntegral F α
  have hβ := IsSeparable.isIntegral F β
  let f := minpoly F α
  let g := minpoly F β
  let ιFE := algebraMap F E
  let ιEE' := algebraMap E (SplittingField (g.map ιFE))
  obtain ⟨c, hc⟩ := primitive_element_inf_aux_exists_c (ιEE'.comp ιFE) (ιEE' α) (ιEE' β) f g
  let γ := α + c • β
  suffices β_in_Fγ : β ∈ F⟮γ⟯
  · use γ
    apply le_antisymm
    · rw [adjoin_le_iff]
      have α_in_Fγ : α ∈ F⟮γ⟯ := by
        rw [← add_sub_cancel α (c • β)]
        exact F⟮γ⟯.sub_mem (mem_adjoin_simple_self F γ) (F⟮γ⟯.toSubalgebra.smul_mem β_in_Fγ c)
      rintro x (rfl | rfl) <;> 

Proof state:
case h.a.inr
F : Type u_1
inst✝⁴ : Field F
inst✝³ : Infinite F
E : Type u_2
inst✝² : Field E
ϕ : F →+* E
α : E
inst✝¹ : Algebra F E
inst✝ : IsSeparable F E
hα : IsIntegral F α
f : F[X] := minpoly F α
ιFE : F →+* E := algebraMap F E
c : F
x : E
hβ : IsIntegral F x
g : F[X] := minpoly F x
ιEE' : E →+* SplittingField (Polynomial.map ιFE g) := algebraMap E (SplittingField (Polynomial.map ιFE g))
hc :
  ∀ α' ∈ roots (Polynomial.map (RingHom.comp ιEE' ιFE) f),
    ∀ β' ∈ roots (Polynomial.map (RingHom.comp ιEE' ιFE) g), -(α' - ιEE' α) / (β' - ιEE' x) ≠ (RingHom.comp ιEE' ιFE) c
γ : E := α + c • x
β_in_Fγ : x ∈ F⟮γ⟯
α_in_Fγ : α ∈ F⟮γ⟯
⊢ x ∈ ↑F⟮γ⟯

Next tactic:
assumption
/-- This is the heart of the proof of the primitive element theorem. It shows that if `F` is
infinite and `α` and `β` are separable over `F` then `F⟮α, β⟯` is generated by a single element. -/
theorem primitive_element_inf_aux [IsSeparable F E] : ∃ γ : E, F⟮α, β⟯ = F⟮γ⟯ := by
  have hα := IsSeparable.isIntegral F α
  have hβ := IsSeparable.isIntegral F β
  let f := minpoly F α
  let g := minpoly F β
  let ιFE := algebraMap F E
  let ιEE' := algebraMap E (SplittingField (g.map ιFE))
  obtain ⟨c, hc⟩ := primitive_element_inf_aux_exists_c (ιEE'.comp ιFE) (ιEE' α) (ιEE' β) f g
  let γ := α + c • β
  suffices β_in_Fγ : β ∈ F⟮γ⟯
  · use γ
    apply le_antisymm
    · rw [adjoin_le_iff]
      have α_in_Fγ : α ∈ F⟮γ⟯ := by
        rw [← add_sub_cancel α (c • β)]
        exact F⟮γ⟯.sub_mem (mem_adjoin_simple_self F γ) (F⟮γ⟯.toSubalgebra.smul_mem β_in_Fγ c)
      rintro x (rfl | rfl) <;> assumption
    · 

Proof state:
case h.a
F : Type u_1
inst✝⁴ : Field F
inst✝³ : Infinite F
E : Type u_2
inst✝² : Field E
ϕ : F →+* E
α β : E
inst✝¹ : Algebra F E
inst✝ : IsSeparable F E
hα : IsIntegral F α
hβ : IsIntegral F β
f : F[X] := minpoly F α
g : F[X] := minpoly F β
ιFE : F →+* E := algebraMap F E
ιEE' : E →+* SplittingField (Polynomial.map ιFE g) := algebraMap E (SplittingField (Polynomial.map ιFE g))
c : F
hc :
  ∀ α' ∈ roots (Polynomial.map (RingHom.comp ιEE' ιFE) f),
    ∀ β' ∈ roots (Polynomial.map (RingHom.comp ιEE' ιFE) g), -(α' - ιEE' α) / (β' - ιEE' β) ≠ (RingHom.comp ιEE' ιFE) c
γ : E := α + c • β
β_in_Fγ : β ∈ F⟮γ⟯
⊢ F⟮γ⟯ ≤ F⟮α, β⟯

Next tactic:
rw [adjoin_simple_le_iff]
/-- This is the heart of the proof of the primitive element theorem. It shows that if `F` is
infinite and `α` and `β` are separable over `F` then `F⟮α, β⟯` is generated by a single element. -/
theorem primitive_element_inf_aux [IsSeparable F E] : ∃ γ : E, F⟮α, β⟯ = F⟮γ⟯ := by
  have hα := IsSeparable.isIntegral F α
  have hβ := IsSeparable.isIntegral F β
  let f := minpoly F α
  let g := minpoly F β
  let ιFE := algebraMap F E
  let ιEE' := algebraMap E (SplittingField (g.map ιFE))
  obtain ⟨c, hc⟩ := primitive_element_inf_aux_exists_c (ιEE'.comp ιFE) (ιEE' α) (ιEE' β) f g
  let γ := α + c • β
  suffices β_in_Fγ : β ∈ F⟮γ⟯
  · use γ
    apply le_antisymm
    · rw [adjoin_le_iff]
      have α_in_Fγ : α ∈ F⟮γ⟯ := by
        rw [← add_sub_cancel α (c • β)]
        exact F⟮γ⟯.sub_mem (mem_adjoin_simple_self F γ) (F⟮γ⟯.toSubalgebra.smul_mem β_in_Fγ c)
      rintro x (rfl | rfl) <;> assumption
    · rw [adjoin_simple_le_iff]
      

Proof state:
case h.a
F : Type u_1
inst✝⁴ : Field F
inst✝³ : Infinite F
E : Type u_2
inst✝² : Field E
ϕ : F →+* E
α β : E
inst✝¹ : Algebra F E
inst✝ : IsSeparable F E
hα : IsIntegral F α
hβ : IsIntegral F β
f : F[X] := minpoly F α
g : F[X] := minpoly F β
ιFE : F →+* E := algebraMap F E
ιEE' : E →+* SplittingField (Polynomial.map ιFE g) := algebraMap E (SplittingField (Polynomial.map ιFE g))
c : F
hc :
  ∀ α' ∈ roots (Polynomial.map (RingHom.comp ιEE' ιFE) f),
    ∀ β' ∈ roots (Polynomial.map (RingHom.comp ιEE' ιFE) g), -(α' - ιEE' α) / (β' - ιEE' β) ≠ (RingHom.comp ιEE' ιFE) c
γ : E := α + c • β
β_in_Fγ : β ∈ F⟮γ⟯
⊢ γ ∈ F⟮α, β⟯

Next tactic:
have α_in_Fαβ : α ∈ F⟮α, β⟯ := subset_adjoin F {α, β} (Set.mem_insert α {β})