-- Mathlib/FieldTheory/Normal/Closure.lean
/-- `normalClosure F K L` is a valid normal closure if `K/F` is algebraic
  and all minimal polynomials of `K/F` splits in `L/F`. -/
lemma isNormalClosure_normalClosure : IsNormalClosure F K (normalClosure F K L)

Proof state:
case right
F : Type u_1
K : Type u_2
L : Type u_3
inst✝⁵ : Field F
inst✝⁴ : Field K
inst✝³ : Field L
inst✝² : Algebra F K
inst✝¹ : Algebra F L
inst✝ : Algebra.IsAlgebraic F K
splits : ∀ (x : K), Splits (algebraMap F L) (minpoly F x)
⊢ normalClosure F K ↥(normalClosure F K L) = ⊤

Tactic:
simp_rw [normalClosure, ← top_le_iff]

Result:
case right
F : Type u_1
K : Type u_2
L : Type u_3
inst✝⁵ : Field F
inst✝⁴ : Field K
inst✝³ : Field L
inst✝² : Algebra F K
inst✝¹ : Algebra F L
inst✝ : Algebra.IsAlgebraic F K
splits : ∀ (x : K), Splits (algebraMap F L) (minpoly F x)
⊢ ⊤ ≤ ⨆ f, f.fieldRange

Proof state:
case left
F : Type u_1
K : Type u_2
L : Type u_3
inst✝⁵ : Field F
inst✝⁴ : Field K
inst✝³ : Field L
inst✝² : Algebra F K
inst✝¹ : Algebra F L
inst✝ : Algebra.IsAlgebraic F K
splits : ∀ (x : K), Splits (algebraMap F L) (minpoly F x)
⊢ ∀ (x : K), Splits (algebraMap F ↥(normalClosure F K L)) (minpoly F x)

Tactic:
rw [normalClosure_eq_iSup_adjoin_of_splits splits]

Result:
case left
F : Type u_1
K : Type u_2
L : Type u_3
inst✝⁵ : Field F
inst✝⁴ : Field K
inst✝³ : Field L
inst✝² : Algebra F K
inst✝¹ : Algebra F L
inst✝ : Algebra.IsAlgebraic F K
splits : ∀ (x : K), Splits (algebraMap F L) (minpoly F x)
⊢ ∀ (x : K), Splits (algebraMap F ↥(⨆ x, IntermediateField.adjoin F ((minpoly F x).rootSet L))) (minpoly F x)

Proof state:
F : Type u_1
K : Type u_2
L : Type u_3
inst✝⁵ : Field F
inst✝⁴ : Field K
inst✝³ : Field L
inst✝² : Algebra F K
inst✝¹ : Algebra F L
inst✝ : Algebra.IsAlgebraic F K
splits : ∀ (x : K), Splits (algebraMap F L) (minpoly F x)
x : K
⊢ IntermediateField.adjoin F ((minpoly F x).rootSet L) ≤ ⨆ x, IntermediateField.adjoin F ((minpoly F x).rootSet L)

Tactic:
apply le_iSup _ x

Result:
no goals

Proof state:
case left
F : Type u_1
K : Type u_2
L : Type u_3
inst✝⁵ : Field F
inst✝⁴ : Field K
inst✝³ : Field L
inst✝² : Algebra F K
inst✝¹ : Algebra F L
inst✝ : Algebra.IsAlgebraic F K
splits : ∀ (x : K), Splits (algebraMap F L) (minpoly F x)
⊢ ∀ (x : K), Splits (algebraMap F ↥(⨆ x, IntermediateField.adjoin F ((minpoly F x).rootSet L))) (minpoly F x)

Tactic:
exact fun x ↦ splits_of_splits (splits x) ((IntermediateField.subset_adjoin F _).trans <|
  SetLike.coe_subset_coe.mpr <| by apply le_iSup _ x)

Result:
no goals

Proof state:
case right
F : Type u_1
K : Type u_2
L : Type u_3
inst✝⁵ : Field F
inst✝⁴ : Field K
inst✝³ : Field L
inst✝² : Algebra F K
inst✝¹ : Algebra F L
inst✝ : Algebra.IsAlgebraic F K
splits : ∀ (x : K), Splits (algebraMap F L) (minpoly F x)
x : ↥(⨆ f, f.fieldRange)
x✝ : x ∈ ⊤
⊢ (⨆ f, f.fieldRange).val x ∈ ↑(⨆ i, IntermediateField.map (⨆ f, f.fieldRange).val i.fieldRange)

Tactic:
refine (iSup_le fun f ↦ ?_ : normalClosure F K L ≤ _) x.2

Result:
case right
F : Type u_1
K : Type u_2
L : Type u_3
inst✝⁵ : Field F
inst✝⁴ : Field K
inst✝³ : Field L
inst✝² : Algebra F K
inst✝¹ : Algebra F L
inst✝ : Algebra.IsAlgebraic F K
splits : ∀ (x : K), Splits (algebraMap F L) (minpoly F x)
x : ↥(⨆ f, f.fieldRange)
x✝ : x ∈ ⊤
f : K →ₐ[F] L
⊢ f.fieldRange ≤ ⨆ i, IntermediateField.map (⨆ f, f.fieldRange).val i.fieldRange

Proof state:
F : Type u_1
K : Type u_2
L : Type u_3
inst✝⁵ : Field F
inst✝⁴ : Field K
inst✝³ : Field L
inst✝² : Algebra F K
inst✝¹ : Algebra F L
inst✝ : Algebra.IsAlgebraic F K
splits : ∀ (x : K), Splits (algebraMap F L) (minpoly F x)
⊢ (∀ (x : K), Splits (algebraMap F ↥(normalClosure F K L)) (minpoly F x)) ∧ normalClosure F K ↥(normalClosure F K L) = ⊤

Tactic:
constructor

Result:
case left
F : Type u_1
K : Type u_2
L : Type u_3
inst✝⁵ : Field F
inst✝⁴ : Field K
inst✝³ : Field L
inst✝² : Algebra F K
inst✝¹ : Algebra F L
inst✝ : Algebra.IsAlgebraic F K
splits : ∀ (x : K), Splits (algebraMap F L) (minpoly F x)
⊢ ∀ (x : K), Splits (algebraMap F ↥(normalClosure F K L)) (minpoly F x)

case right
F : Type u_1
K : Type u_2
L : Type u_3
inst✝⁵ : Field F
inst✝⁴ : Field K
inst✝³ : Field L
inst✝² : Algebra F K
inst✝¹ : Algebra F L
inst✝ : Algebra.IsAlgebraic F K
splits : ∀ (x : K), Splits (algebraMap F L) (minpoly F x)
⊢ normalClosure F K ↥(normalClosure F K L) = ⊤

Proof state:
case right
F : Type u_1
K : Type u_2
L : Type u_3
inst✝⁵ : Field F
inst✝⁴ : Field K
inst✝³ : Field L
inst✝² : Algebra F K
inst✝¹ : Algebra F L
inst✝ : Algebra.IsAlgebraic F K
splits : ∀ (x : K), Splits (algebraMap F L) (minpoly F x)
⊢ ⊤ ≤ ⨆ f, f.fieldRange

Tactic:
refine fun x _ ↦ ((⨆ f : K →ₐ[F] L, f.fieldRange).val).injective.mem_set_image |>.mp ?_

Result:
case right
F : Type u_1
K : Type u_2
L : Type u_3
inst✝⁵ : Field F
inst✝⁴ : Field K
inst✝³ : Field L
inst✝² : Algebra F K
inst✝¹ : Algebra F L
inst✝ : Algebra.IsAlgebraic F K
splits : ∀ (x : K), Splits (algebraMap F L) (minpoly F x)
x : ↥(⨆ f, f.fieldRange)
x✝ : x ∈ ⊤
⊢ (⨆ f, f.fieldRange).val.toRingHom x ∈ ⇑(⨆ f, f.fieldRange).val.toRingHom '' ↑(⨆ f, f.fieldRange)

Proof state:
F : Type u_1
K : Type u_2
L : Type u_3
inst✝⁵ : Field F
inst✝⁴ : Field K
inst✝³ : Field L
inst✝² : Algebra F K
inst✝¹ : Algebra F L
inst✝ : Algebra.IsAlgebraic F K
splits : ∀ (x : K), Splits (algebraMap F L) (minpoly F x)
⊢ IsNormalClosure F K ↥(normalClosure F K L)

Tactic:
rw [isNormalClosure_iff]

Result:
F : Type u_1
K : Type u_2
L : Type u_3
inst✝⁵ : Field F
inst✝⁴ : Field K
inst✝³ : Field L
inst✝² : Algebra F K
inst✝¹ : Algebra F L
inst✝ : Algebra.IsAlgebraic F K
splits : ∀ (x : K), Splits (algebraMap F L) (minpoly F x)
⊢ (∀ (x : K), Splits (algebraMap F ↥(normalClosure F K L)) (minpoly F x)) ∧ normalClosure F K ↥(normalClosure F K L) = ⊤

Proof state:
case right
F : Type u_1
K : Type u_2
L : Type u_3
inst✝⁵ : Field F
inst✝⁴ : Field K
inst✝³ : Field L
inst✝² : Algebra F K
inst✝¹ : Algebra F L
inst✝ : Algebra.IsAlgebraic F K
splits : ∀ (x : K), Splits (algebraMap F L) (minpoly F x)
x : ↥(⨆ f, f.fieldRange)
x✝ : x ∈ ⊤
f : K →ₐ[F] L
⊢ f.fieldRange ≤ ⨆ i, IntermediateField.map (⨆ f, f.fieldRange).val i.fieldRange

Tactic:
refine le_iSup_of_le (f.codRestrict _ fun x ↦ f.fieldRange_le_normalClosure ⟨x, rfl⟩) ?_

Result:
case right
F : Type u_1
K : Type u_2
L : Type u_3
inst✝⁵ : Field F
inst✝⁴ : Field K
inst✝³ : Field L
inst✝² : Algebra F K
inst✝¹ : Algebra F L
inst✝ : Algebra.IsAlgebraic F K
splits : ∀ (x : K), Splits (algebraMap F L) (minpoly F x)
x : ↥(⨆ f, f.fieldRange)
x✝ : x ∈ ⊤
f : K →ₐ[F] L
⊢ f.fieldRange ≤
    IntermediateField.map (⨆ f, f.fieldRange).val (f.codRestrict (⨆ f, f.fieldRange).toSubalgebra ⋯).fieldRange

Proof state:
case right
F : Type u_1
K : Type u_2
L : Type u_3
inst✝⁵ : Field F
inst✝⁴ : Field K
inst✝³ : Field L
inst✝² : Algebra F K
inst✝¹ : Algebra F L
inst✝ : Algebra.IsAlgebraic F K
splits : ∀ (x : K), Splits (algebraMap F L) (minpoly F x)
x : ↥(⨆ f, f.fieldRange)
x✝ : x ∈ ⊤
⊢ (⨆ f, f.fieldRange).val.toRingHom x ∈ ⇑(⨆ f, f.fieldRange).val.toRingHom '' ↑(⨆ f, f.fieldRange)

Tactic:
rw [AlgHom.toRingHom_eq_coe, RingHom.coe_coe, coe_val, ← IntermediateField.coe_val,
  ← IntermediateField.coe_map, IntermediateField.map_iSup]

Result:
case right
F : Type u_1
K : Type u_2
L : Type u_3
inst✝⁵ : Field F
inst✝⁴ : Field K
inst✝³ : Field L
inst✝² : Algebra F K
inst✝¹ : Algebra F L
inst✝ : Algebra.IsAlgebraic F K
splits : ∀ (x : K), Splits (algebraMap F L) (minpoly F x)
x : ↥(⨆ f, f.fieldRange)
x✝ : x ∈ ⊤
⊢ (⨆ f, f.fieldRange).val x ∈ ↑(⨆ i, IntermediateField.map (⨆ f, f.fieldRange).val i.fieldRange)