l3lab/ntp-mathlib huggingface dataset:
theorem of_separable_splitting_field [sp : p.IsSplittingField F E] (hp : p.Separable) :
    IsGalois F E := by
  haveI hFE : FiniteDimensional F E := Polynomial.IsSplittingField.finiteDimensional E p
  letI := Classical.decEq E
  let s := p.rootSet E
  have adjoin_root : IntermediateField.adjoin F s = ⊤ := by
    apply IntermediateField.toSubalgebra_injective
    rw [IntermediateField.top_toSubalgebra, ← top_le_iff, ← sp.adjoin_rootSet]
    apply IntermediateField.algebra_adjoin_le_adjoin
  let P : IntermediateField F E → Prop := fun K => Fintype.card (K →ₐ[F] E) = finrank F K
  suffices P (IntermediateField.adjoin F s) by
    rw [adjoin_root] at this
    apply of_card_aut_eq_finrank
    rw [← Eq.trans this (LinearEquiv.finrank_eq IntermediateField.topEquiv.toLinearEquiv)]
    exact Fintype.card_congr ((algEquivEquivAlgHom F E).toEquiv.trans
      (IntermediateField.topEquiv.symm.arrowCongr AlgEquiv.refl))
  apply IntermediateField.induction_on_adjoin_finset _ P
  · have key := IntermediateField.card_algHom_adjoin_integral F (K := E)
      (show IsIntegral F (0 : E) from isIntegral_zero)
    rw [minpoly.zero, Polynomial.natDegree_X] at key
    specialize key Polynomial.separable_X (Polynomial.splits_X (algebraMap F E))
    rw [← @Subalgebra.finrank_bot F E _ _ _, ← IntermediateField.bot_toSubalgebra] at key
    refine' Eq.trans _ key
    -- Porting note: use unification instead of synthesis for one argument of `card_congr`
    apply @Fintype.card_congr _ _ _ (_) _
    rw [IntermediateField.adjoin_zero]
  

Proof state:
case ih
F : Type u_1
inst✝² : Field F
E : Type u_2
inst✝¹ : Field E
inst✝ : Algebra F E
p : F[X]
sp : Polynomial.IsSplittingField F E p
hp : Polynomial.Separable p
hFE : FiniteDimensional F E
this : DecidableEq E := Classical.decEq E
s : Set E := Polynomial.rootSet p E
adjoin_root : IntermediateField.adjoin F s = ⊤
P : IntermediateField F E → Prop := fun K => Fintype.card (↥K →ₐ[F] E) = finrank F ↥K
⊢ ∀ (K : IntermediateField F E),
    ∀ x ∈ Multiset.toFinset (Polynomial.aroots p E), P K → P (IntermediateField.restrictScalars F (↥K)⟮x⟯)

Next tactic:
intro K x hx hK
theorem of_separable_splitting_field [sp : p.IsSplittingField F E] (hp : p.Separable) :
    IsGalois F E := by
  haveI hFE : FiniteDimensional F E := Polynomial.IsSplittingField.finiteDimensional E p
  letI := Classical.decEq E
  let s := p.rootSet E
  have adjoin_root : IntermediateField.adjoin F s = ⊤ := by
    apply IntermediateField.toSubalgebra_injective
    rw [IntermediateField.top_toSubalgebra, ← top_le_iff, ← sp.adjoin_rootSet]
    apply IntermediateField.algebra_adjoin_le_adjoin
  let P : IntermediateField F E → Prop := fun K => Fintype.card (K →ₐ[F] E) = finrank F K
  suffices P (IntermediateField.adjoin F s) by
    rw [adjoin_root] at this
    apply of_card_aut_eq_finrank
    rw [← Eq.trans this (LinearEquiv.finrank_eq IntermediateField.topEquiv.toLinearEquiv)]
    exact Fintype.card_congr ((algEquivEquivAlgHom F E).toEquiv.trans
      (IntermediateField.topEquiv.symm.arrowCongr AlgEquiv.refl))
  apply IntermediateField.induction_on_adjoin_finset _ P
  · have key := IntermediateField.card_algHom_adjoin_integral F (K := E)
      (show IsIntegral F (0 : E) from isIntegral_zero)
    rw [minpoly.zero, Polynomial.natDegree_X] at key
    specialize key Polynomial.separable_X (Polynomial.splits_X (algebraMap F E))
    rw [← @Subalgebra.finrank_bot F E _ _ _, ← IntermediateField.bot_toSubalgebra] at key
    refine' Eq.trans _ key
    -- Porting note: use unification instead of synthesis for one argument of `card_congr`
    apply @Fintype.card_congr _ _ _ (_) _
    rw [IntermediateField.adjoin_zero]
  intro K x hx hK
  

Proof state:
case ih
F : Type u_1
inst✝² : Field F
E : Type u_2
inst✝¹ : Field E
inst✝ : Algebra F E
p : F[X]
sp : Polynomial.IsSplittingField F E p
hp : Polynomial.Separable p
hFE : FiniteDimensional F E
this : DecidableEq E := Classical.decEq E
s : Set E := Polynomial.rootSet p E
adjoin_root : IntermediateField.adjoin F s = ⊤
P : IntermediateField F E → Prop := fun K => Fintype.card (↥K →ₐ[F] E) = finrank F ↥K
K : IntermediateField F E
x : E
hx : x ∈ Multiset.toFinset (Polynomial.aroots p E)
hK : P K
⊢ P (IntermediateField.restrictScalars F (↥K)⟮x⟯)

Next tactic:
simp only at *
theorem of_separable_splitting_field [sp : p.IsSplittingField F E] (hp : p.Separable) :
    IsGalois F E := by
  haveI hFE : FiniteDimensional F E := Polynomial.IsSplittingField.finiteDimensional E p
  letI := Classical.decEq E
  let s := p.rootSet E
  have adjoin_root : IntermediateField.adjoin F s = ⊤ := by
    apply IntermediateField.toSubalgebra_injective
    rw [IntermediateField.top_toSubalgebra, ← top_le_iff, ← sp.adjoin_rootSet]
    apply IntermediateField.algebra_adjoin_le_adjoin
  let P : IntermediateField F E → Prop := fun K => Fintype.card (K →ₐ[F] E) = finrank F K
  suffices P (IntermediateField.adjoin F s) by
    rw [adjoin_root] at this
    apply of_card_aut_eq_finrank
    rw [← Eq.trans this (LinearEquiv.finrank_eq IntermediateField.topEquiv.toLinearEquiv)]
    exact Fintype.card_congr ((algEquivEquivAlgHom F E).toEquiv.trans
      (IntermediateField.topEquiv.symm.arrowCongr AlgEquiv.refl))
  apply IntermediateField.induction_on_adjoin_finset _ P
  · have key := IntermediateField.card_algHom_adjoin_integral F (K := E)
      (show IsIntegral F (0 : E) from isIntegral_zero)
    rw [minpoly.zero, Polynomial.natDegree_X] at key
    specialize key Polynomial.separable_X (Polynomial.splits_X (algebraMap F E))
    rw [← @Subalgebra.finrank_bot F E _ _ _, ← IntermediateField.bot_toSubalgebra] at key
    refine' Eq.trans _ key
    -- Porting note: use unification instead of synthesis for one argument of `card_congr`
    apply @Fintype.card_congr _ _ _ (_) _
    rw [IntermediateField.adjoin_zero]
  intro K x hx hK
  simp only at *
  -- Porting note: need to specify two implicit arguments of `finrank_mul_finrank`
  

Proof state:
case ih
F : Type u_1
inst✝² : Field F
E : Type u_2
inst✝¹ : Field E
inst✝ : Algebra F E
p : F[X]
sp : Polynomial.IsSplittingField F E p
hp : Polynomial.Separable p
hFE : FiniteDimensional F E
this : DecidableEq E := Classical.decEq E
s : Set E := Polynomial.rootSet p E
adjoin_root : IntermediateField.adjoin F (Polynomial.rootSet p E) = ⊤
P : IntermediateField F E → Prop := fun K => Fintype.card (↥K →ₐ[F] E) = finrank F ↥K
K : IntermediateField F E
x : E
hx : x ∈ Multiset.toFinset (Polynomial.aroots p E)
hK : Fintype.card (↥K →ₐ[F] E) = finrank F ↥K
⊢ Fintype.card (↥(IntermediateField.restrictScalars F (↥K)⟮x⟯) →ₐ[F] E) =
    finrank F ↥(IntermediateField.restrictScalars F (↥K)⟮x⟯)

Next tactic:
rw [of_separable_splitting_field_aux hp K (Multiset.mem_toFinset.mp hx), hK,
    @finrank_mul_finrank _ _ _ _ _ _ _ K⟮x⟯.module _ K⟮x⟯.isScalarTower _]
theorem of_separable_splitting_field [sp : p.IsSplittingField F E] (hp : p.Separable) :
    IsGalois F E := by
  haveI hFE : FiniteDimensional F E := Polynomial.IsSplittingField.finiteDimensional E p
  letI := Classical.decEq E
  let s := p.rootSet E
  have adjoin_root : IntermediateField.adjoin F s = ⊤ := by
    apply IntermediateField.toSubalgebra_injective
    rw [IntermediateField.top_toSubalgebra, ← top_le_iff, ← sp.adjoin_rootSet]
    apply IntermediateField.algebra_adjoin_le_adjoin
  let P : IntermediateField F E → Prop := fun K => Fintype.card (K →ₐ[F] E) = finrank F K
  suffices P (IntermediateField.adjoin F s) by
    rw [adjoin_root] at this
    apply of_card_aut_eq_finrank
    rw [← Eq.trans this (LinearEquiv.finrank_eq IntermediateField.topEquiv.toLinearEquiv)]
    exact Fintype.card_congr ((algEquivEquivAlgHom F E).toEquiv.trans
      (IntermediateField.topEquiv.symm.arrowCongr AlgEquiv.refl))
  apply IntermediateField.induction_on_adjoin_finset _ P
  · have key := IntermediateField.card_algHom_adjoin_integral F (K := E)
      (show IsIntegral F (0 : E) from isIntegral_zero)
    rw [minpoly.zero, Polynomial.natDegree_X] at key
    specialize key Polynomial.separable_X (Polynomial.splits_X (algebraMap F E))
    rw [← @Subalgebra.finrank_bot F E _ _ _, ← IntermediateField.bot_toSubalgebra] at key
    refine' Eq.trans _ key
    -- Porting note: use unification instead of synthesis for one argument of `card_congr`
    apply @Fintype.card_congr _ _ _ (_) _
    rw [IntermediateField.adjoin_zero]
  intro K x hx hK
  simp only at *
  -- Porting note: need to specify two implicit arguments of `finrank_mul_finrank`
  rw [of_separable_splitting_field_aux hp K (Multiset.mem_toFinset.mp hx), hK,
    @finrank_mul_finrank _ _ _ _ _ _ _ K⟮x⟯.module _ K⟮x⟯.isScalarTower _]
  

Proof state:
case ih
F : Type u_1
inst✝² : Field F
E : Type u_2
inst✝¹ : Field E
inst✝ : Algebra F E
p : F[X]
sp : Polynomial.IsSplittingField F E p
hp : Polynomial.Separable p
hFE : FiniteDimensional F E
this : DecidableEq E := Classical.decEq E
s : Set E := Polynomial.rootSet p E
adjoin_root : IntermediateField.adjoin F (Polynomial.rootSet p E) = ⊤
P : IntermediateField F E → Prop := fun K => Fintype.card (↥K →ₐ[F] E) = finrank F ↥K
K : IntermediateField F E
x : E
hx : x ∈ Multiset.toFinset (Polynomial.aroots p E)
hK : Fintype.card (↥K →ₐ[F] E) = finrank F ↥K
⊢ finrank F ↥(↥K)⟮x⟯ = finrank F ↥(IntermediateField.restrictScalars F (↥K)⟮x⟯)

Next tactic:
symm
theorem of_separable_splitting_field [sp : p.IsSplittingField F E] (hp : p.Separable) :
    IsGalois F E := by
  haveI hFE : FiniteDimensional F E := Polynomial.IsSplittingField.finiteDimensional E p
  letI := Classical.decEq E
  let s := p.rootSet E
  have adjoin_root : IntermediateField.adjoin F s = ⊤ := by
    apply IntermediateField.toSubalgebra_injective
    rw [IntermediateField.top_toSubalgebra, ← top_le_iff, ← sp.adjoin_rootSet]
    apply IntermediateField.algebra_adjoin_le_adjoin
  let P : IntermediateField F E → Prop := fun K => Fintype.card (K →ₐ[F] E) = finrank F K
  suffices P (IntermediateField.adjoin F s) by
    rw [adjoin_root] at this
    apply of_card_aut_eq_finrank
    rw [← Eq.trans this (LinearEquiv.finrank_eq IntermediateField.topEquiv.toLinearEquiv)]
    exact Fintype.card_congr ((algEquivEquivAlgHom F E).toEquiv.trans
      (IntermediateField.topEquiv.symm.arrowCongr AlgEquiv.refl))
  apply IntermediateField.induction_on_adjoin_finset _ P
  · have key := IntermediateField.card_algHom_adjoin_integral F (K := E)
      (show IsIntegral F (0 : E) from isIntegral_zero)
    rw [minpoly.zero, Polynomial.natDegree_X] at key
    specialize key Polynomial.separable_X (Polynomial.splits_X (algebraMap F E))
    rw [← @Subalgebra.finrank_bot F E _ _ _, ← IntermediateField.bot_toSubalgebra] at key
    refine' Eq.trans _ key
    -- Porting note: use unification instead of synthesis for one argument of `card_congr`
    apply @Fintype.card_congr _ _ _ (_) _
    rw [IntermediateField.adjoin_zero]
  intro K x hx hK
  simp only at *
  -- Porting note: need to specify two implicit arguments of `finrank_mul_finrank`
  rw [of_separable_splitting_field_aux hp K (Multiset.mem_toFinset.mp hx), hK,
    @finrank_mul_finrank _ _ _ _ _ _ _ K⟮x⟯.module _ K⟮x⟯.isScalarTower _]
  symm
  

Proof state:
case ih
F : Type u_1
inst✝² : Field F
E : Type u_2
inst✝¹ : Field E
inst✝ : Algebra F E
p : F[X]
sp : Polynomial.IsSplittingField F E p
hp : Polynomial.Separable p
hFE : FiniteDimensional F E
this : DecidableEq E := Classical.decEq E
s : Set E := Polynomial.rootSet p E
adjoin_root : IntermediateField.adjoin F (Polynomial.rootSet p E) = ⊤
P : IntermediateField F E → Prop := fun K => Fintype.card (↥K →ₐ[F] E) = finrank F ↥K
K : IntermediateField F E
x : E
hx : x ∈ Multiset.toFinset (Polynomial.aroots p E)
hK : Fintype.card (↥K →ₐ[F] E) = finrank F ↥K
⊢ finrank F ↥(IntermediateField.restrictScalars F (↥K)⟮x⟯) = finrank F ↥(↥K)⟮x⟯

Next tactic:
refine' LinearEquiv.finrank_eq _
theorem of_separable_splitting_field [sp : p.IsSplittingField F E] (hp : p.Separable) :
    IsGalois F E := by
  haveI hFE : FiniteDimensional F E := Polynomial.IsSplittingField.finiteDimensional E p
  letI := Classical.decEq E
  let s := p.rootSet E
  have adjoin_root : IntermediateField.adjoin F s = ⊤ := by
    apply IntermediateField.toSubalgebra_injective
    rw [IntermediateField.top_toSubalgebra, ← top_le_iff, ← sp.adjoin_rootSet]
    apply IntermediateField.algebra_adjoin_le_adjoin
  let P : IntermediateField F E → Prop := fun K => Fintype.card (K →ₐ[F] E) = finrank F K
  suffices P (IntermediateField.adjoin F s) by
    rw [adjoin_root] at this
    apply of_card_aut_eq_finrank
    rw [← Eq.trans this (LinearEquiv.finrank_eq IntermediateField.topEquiv.toLinearEquiv)]
    exact Fintype.card_congr ((algEquivEquivAlgHom F E).toEquiv.trans
      (IntermediateField.topEquiv.symm.arrowCongr AlgEquiv.refl))
  apply IntermediateField.induction_on_adjoin_finset _ P
  · have key := IntermediateField.card_algHom_adjoin_integral F (K := E)
      (show IsIntegral F (0 : E) from isIntegral_zero)
    rw [minpoly.zero, Polynomial.natDegree_X] at key
    specialize key Polynomial.separable_X (Polynomial.splits_X (algebraMap F E))
    rw [← @Subalgebra.finrank_bot F E _ _ _, ← IntermediateField.bot_toSubalgebra] at key
    refine' Eq.trans _ key
    -- Porting note: use unification instead of synthesis for one argument of `card_congr`
    apply @Fintype.card_congr _ _ _ (_) _
    rw [IntermediateField.adjoin_zero]
  intro K x hx hK
  simp only at *
  -- Porting note: need to specify two implicit arguments of `finrank_mul_finrank`
  rw [of_separable_splitting_field_aux hp K (Multiset.mem_toFinset.mp hx), hK,
    @finrank_mul_finrank _ _ _ _ _ _ _ K⟮x⟯.module _ K⟮x⟯.isScalarTower _]
  symm
  refine' LinearEquiv.finrank_eq _
  

Proof state:
case ih
F : Type u_1
inst✝² : Field F
E : Type u_2
inst✝¹ : Field E
inst✝ : Algebra F E
p : F[X]
sp : Polynomial.IsSplittingField F E p
hp : Polynomial.Separable p
hFE : FiniteDimensional F E
this : DecidableEq E := Classical.decEq E
s : Set E := Polynomial.rootSet p E
adjoin_root : IntermediateField.adjoin F (Polynomial.rootSet p E) = ⊤
P : IntermediateField F E → Prop := fun K => Fintype.card (↥K →ₐ[F] E) = finrank F ↥K
K : IntermediateField F E
x : E
hx : x ∈ Multiset.toFinset (Polynomial.aroots p E)
hK : Fintype.card (↥K →ₐ[F] E) = finrank F ↥K
⊢ ↥(IntermediateField.restrictScalars F (↥K)⟮x⟯) ≃ₗ[F] ↥(↥K)⟮x⟯

Next tactic:
rfl
/-- Equivalent characterizations of a Galois extension of finite degree-/
theorem tfae [FiniteDimensional F E] :
    List.TFAE [IsGalois F E, IntermediateField.fixedField (⊤ : Subgroup (E ≃ₐ[F] E)) = ⊥,
      Fintype.card (E ≃ₐ[F] E) = finrank F E, ∃ p: F[X], p.Separable ∧ p.IsSplittingField F E] := by
  

Proof state:
F : Type u_1
inst✝³ : Field F
E : Type u_2
inst✝² : Field E
inst✝¹ : Algebra F E
p : F[X]
inst✝ : FiniteDimensional F E
⊢ List.TFAE
    [IsGalois F E, IntermediateField.fixedField ⊤ = ⊥, Fintype.card (E ≃ₐ[F] E) = finrank F E,
      ∃ p, Polynomial.Separable p ∧ Polynomial.IsSplittingField F E p]

Next tactic:
tfae_have 1 → 2
/-- Equivalent characterizations of a Galois extension of finite degree-/
theorem tfae [FiniteDimensional F E] :
    List.TFAE [IsGalois F E, IntermediateField.fixedField (⊤ : Subgroup (E ≃ₐ[F] E)) = ⊥,
      Fintype.card (E ≃ₐ[F] E) = finrank F E, ∃ p: F[X], p.Separable ∧ p.IsSplittingField F E] := by
  tfae_have 1 → 2
  · 

Proof state:
case tfae_1_to_2
F : Type u_1
inst✝³ : Field F
E : Type u_2
inst✝² : Field E
inst✝¹ : Algebra F E
p : F[X]
inst✝ : FiniteDimensional F E
⊢ IsGalois F E → IntermediateField.fixedField ⊤ = ⊥

Next tactic:
exact fun h => OrderIso.map_bot (@intermediateFieldEquivSubgroup F _ E _ _ _ h).symm
/-- Equivalent characterizations of a Galois extension of finite degree-/
theorem tfae [FiniteDimensional F E] :
    List.TFAE [IsGalois F E, IntermediateField.fixedField (⊤ : Subgroup (E ≃ₐ[F] E)) = ⊥,
      Fintype.card (E ≃ₐ[F] E) = finrank F E, ∃ p: F[X], p.Separable ∧ p.IsSplittingField F E] := by
  tfae_have 1 → 2
  · exact fun h => OrderIso.map_bot (@intermediateFieldEquivSubgroup F _ E _ _ _ h).symm
  

Proof state:
F : Type u_1
inst✝³ : Field F
E : Type u_2
inst✝² : Field E
inst✝¹ : Algebra F E
p : F[X]
inst✝ : FiniteDimensional F E
tfae_1_to_2 : IsGalois F E → IntermediateField.fixedField ⊤ = ⊥
⊢ List.TFAE
    [IsGalois F E, IntermediateField.fixedField ⊤ = ⊥, Fintype.card (E ≃ₐ[F] E) = finrank F E,
      ∃ p, Polynomial.Separable p ∧ Polynomial.IsSplittingField F E p]

Next tactic:
tfae_have 1 → 3
/-- Equivalent characterizations of a Galois extension of finite degree-/
theorem tfae [FiniteDimensional F E] :
    List.TFAE [IsGalois F E, IntermediateField.fixedField (⊤ : Subgroup (E ≃ₐ[F] E)) = ⊥,
      Fintype.card (E ≃ₐ[F] E) = finrank F E, ∃ p: F[X], p.Separable ∧ p.IsSplittingField F E] := by
  tfae_have 1 → 2
  · exact fun h => OrderIso.map_bot (@intermediateFieldEquivSubgroup F _ E _ _ _ h).symm
  tfae_have 1 → 3
  · 

Proof state:
case tfae_1_to_3
F : Type u_1
inst✝³ : Field F
E : Type u_2
inst✝² : Field E
inst✝¹ : Algebra F E
p : F[X]
inst✝ : FiniteDimensional F E
tfae_1_to_2 : IsGalois F E → IntermediateField.fixedField ⊤ = ⊥
⊢ IsGalois F E → Fintype.card (E ≃ₐ[F] E) = finrank F E

Next tactic:
intro
/-- Equivalent characterizations of a Galois extension of finite degree-/
theorem tfae [FiniteDimensional F E] :
    List.TFAE [IsGalois F E, IntermediateField.fixedField (⊤ : Subgroup (E ≃ₐ[F] E)) = ⊥,
      Fintype.card (E ≃ₐ[F] E) = finrank F E, ∃ p: F[X], p.Separable ∧ p.IsSplittingField F E] := by
  tfae_have 1 → 2
  · exact fun h => OrderIso.map_bot (@intermediateFieldEquivSubgroup F _ E _ _ _ h).symm
  tfae_have 1 → 3
  · intro; 

Proof state:
case tfae_1_to_3
F : Type u_1
inst✝³ : Field F
E : Type u_2
inst✝² : Field E
inst✝¹ : Algebra F E
p : F[X]
inst✝ : FiniteDimensional F E
tfae_1_to_2 : IsGalois F E → IntermediateField.fixedField ⊤ = ⊥
✝ : IsGalois F E
⊢ Fintype.card (E ≃ₐ[F] E) = finrank F E

Next tactic:
exact card_aut_eq_finrank F E
/-- Equivalent characterizations of a Galois extension of finite degree-/
theorem tfae [FiniteDimensional F E] :
    List.TFAE [IsGalois F E, IntermediateField.fixedField (⊤ : Subgroup (E ≃ₐ[F] E)) = ⊥,
      Fintype.card (E ≃ₐ[F] E) = finrank F E, ∃ p: F[X], p.Separable ∧ p.IsSplittingField F E] := by
  tfae_have 1 → 2
  · exact fun h => OrderIso.map_bot (@intermediateFieldEquivSubgroup F _ E _ _ _ h).symm
  tfae_have 1 → 3
  · intro; exact card_aut_eq_finrank F E
  

Proof state:
F : Type u_1
inst✝³ : Field F
E : Type u_2
inst✝² : Field E
inst✝¹ : Algebra F E
p : F[X]
inst✝ : FiniteDimensional F E
tfae_1_to_2 : IsGalois F E → IntermediateField.fixedField ⊤ = ⊥
tfae_1_to_3 : IsGalois F E → Fintype.card (E ≃ₐ[F] E) = finrank F E
⊢ List.TFAE
    [IsGalois F E, IntermediateField.fixedField ⊤ = ⊥, Fintype.card (E ≃ₐ[F] E) = finrank F E,
      ∃ p, Polynomial.Separable p ∧ Polynomial.IsSplittingField F E p]

Next tactic:
tfae_have 1 → 4
/-- Equivalent characterizations of a Galois extension of finite degree-/
theorem tfae [FiniteDimensional F E] :
    List.TFAE [IsGalois F E, IntermediateField.fixedField (⊤ : Subgroup (E ≃ₐ[F] E)) = ⊥,
      Fintype.card (E ≃ₐ[F] E) = finrank F E, ∃ p: F[X], p.Separable ∧ p.IsSplittingField F E] := by
  tfae_have 1 → 2
  · exact fun h => OrderIso.map_bot (@intermediateFieldEquivSubgroup F _ E _ _ _ h).symm
  tfae_have 1 → 3
  · intro; exact card_aut_eq_finrank F E
  tfae_have 1 → 4
  · 

Proof state:
case tfae_1_to_4
F : Type u_1
inst✝³ : Field F
E : Type u_2
inst✝² : Field E
inst✝¹ : Algebra F E
p : F[X]
inst✝ : FiniteDimensional F E
tfae_1_to_2 : IsGalois F E → IntermediateField.fixedField ⊤ = ⊥
tfae_1_to_3 : IsGalois F E → Fintype.card (E ≃ₐ[F] E) = finrank F E
⊢ IsGalois F E → ∃ p, Polynomial.Separable p ∧ Polynomial.IsSplittingField F E p

Next tactic:
intro
/-- Equivalent characterizations of a Galois extension of finite degree-/
theorem tfae [FiniteDimensional F E] :
    List.TFAE [IsGalois F E, IntermediateField.fixedField (⊤ : Subgroup (E ≃ₐ[F] E)) = ⊥,
      Fintype.card (E ≃ₐ[F] E) = finrank F E, ∃ p: F[X], p.Separable ∧ p.IsSplittingField F E] := by
  tfae_have 1 → 2
  · exact fun h => OrderIso.map_bot (@intermediateFieldEquivSubgroup F _ E _ _ _ h).symm
  tfae_have 1 → 3
  · intro; exact card_aut_eq_finrank F E
  tfae_have 1 → 4
  · intro; 

Proof state:
case tfae_1_to_4
F : Type u_1
inst✝³ : Field F
E : Type u_2
inst✝² : Field E
inst✝¹ : Algebra F E
p : F[X]
inst✝ : FiniteDimensional F E
tfae_1_to_2 : IsGalois F E → IntermediateField.fixedField ⊤ = ⊥
tfae_1_to_3 : IsGalois F E → Fintype.card (E ≃ₐ[F] E) = finrank F E
✝ : IsGalois F E
⊢ ∃ p, Polynomial.Separable p ∧ Polynomial.IsSplittingField F E p

Next tactic:
exact is_separable_splitting_field F E
/-- Equivalent characterizations of a Galois extension of finite degree-/
theorem tfae [FiniteDimensional F E] :
    List.TFAE [IsGalois F E, IntermediateField.fixedField (⊤ : Subgroup (E ≃ₐ[F] E)) = ⊥,
      Fintype.card (E ≃ₐ[F] E) = finrank F E, ∃ p: F[X], p.Separable ∧ p.IsSplittingField F E] := by
  tfae_have 1 → 2
  · exact fun h => OrderIso.map_bot (@intermediateFieldEquivSubgroup F _ E _ _ _ h).symm
  tfae_have 1 → 3
  · intro; exact card_aut_eq_finrank F E
  tfae_have 1 → 4
  · intro; exact is_separable_splitting_field F E
  

Proof state:
F : Type u_1
inst✝³ : Field F
E : Type u_2
inst✝² : Field E
inst✝¹ : Algebra F E
p : F[X]
inst✝ : FiniteDimensional F E
tfae_1_to_2 : IsGalois F E → IntermediateField.fixedField ⊤ = ⊥
tfae_1_to_3 : IsGalois F E → Fintype.card (E ≃ₐ[F] E) = finrank F E
tfae_1_to_4 : IsGalois F E → ∃ p, Polynomial.Separable p ∧ Polynomial.IsSplittingField F E p
⊢ List.TFAE
    [IsGalois F E, IntermediateField.fixedField ⊤ = ⊥, Fintype.card (E ≃ₐ[F] E) = finrank F E,
      ∃ p, Polynomial.Separable p ∧ Polynomial.IsSplittingField F E p]

Next tactic:
tfae_have 2 → 1
/-- Equivalent characterizations of a Galois extension of finite degree-/
theorem tfae [FiniteDimensional F E] :
    List.TFAE [IsGalois F E, IntermediateField.fixedField (⊤ : Subgroup (E ≃ₐ[F] E)) = ⊥,
      Fintype.card (E ≃ₐ[F] E) = finrank F E, ∃ p: F[X], p.Separable ∧ p.IsSplittingField F E] := by
  tfae_have 1 → 2
  · exact fun h => OrderIso.map_bot (@intermediateFieldEquivSubgroup F _ E _ _ _ h).symm
  tfae_have 1 → 3
  · intro; exact card_aut_eq_finrank F E
  tfae_have 1 → 4
  · intro; exact is_separable_splitting_field F E
  tfae_have 2 → 1
  · 

Proof state:
case tfae_2_to_1
F : Type u_1
inst✝³ : Field F
E : Type u_2
inst✝² : Field E
inst✝¹ : Algebra F E
p : F[X]
inst✝ : FiniteDimensional F E
tfae_1_to_2 : IsGalois F E → IntermediateField.fixedField ⊤ = ⊥
tfae_1_to_3 : IsGalois F E → Fintype.card (E ≃ₐ[F] E) = finrank F E
tfae_1_to_4 : IsGalois F E → ∃ p, Polynomial.Separable p ∧ Polynomial.IsSplittingField F E p
⊢ IntermediateField.fixedField ⊤ = ⊥ → IsGalois F E

Next tactic:
exact of_fixedField_eq_bot F E
/-- Equivalent characterizations of a Galois extension of finite degree-/
theorem tfae [FiniteDimensional F E] :
    List.TFAE [IsGalois F E, IntermediateField.fixedField (⊤ : Subgroup (E ≃ₐ[F] E)) = ⊥,
      Fintype.card (E ≃ₐ[F] E) = finrank F E, ∃ p: F[X], p.Separable ∧ p.IsSplittingField F E] := by
  tfae_have 1 → 2
  · exact fun h => OrderIso.map_bot (@intermediateFieldEquivSubgroup F _ E _ _ _ h).symm
  tfae_have 1 → 3
  · intro; exact card_aut_eq_finrank F E
  tfae_have 1 → 4
  · intro; exact is_separable_splitting_field F E
  tfae_have 2 → 1
  · exact of_fixedField_eq_bot F E
  

Proof state:
F : Type u_1
inst✝³ : Field F
E : Type u_2
inst✝² : Field E
inst✝¹ : Algebra F E
p : F[X]
inst✝ : FiniteDimensional F E
tfae_1_to_2 : IsGalois F E → IntermediateField.fixedField ⊤ = ⊥
tfae_1_to_3 : IsGalois F E → Fintype.card (E ≃ₐ[F] E) = finrank F E
tfae_1_to_4 : IsGalois F E → ∃ p, Polynomial.Separable p ∧ Polynomial.IsSplittingField F E p
tfae_2_to_1 : IntermediateField.fixedField ⊤ = ⊥ → IsGalois F E
⊢ List.TFAE
    [IsGalois F E, IntermediateField.fixedField ⊤ = ⊥, Fintype.card (E ≃ₐ[F] E) = finrank F E,
      ∃ p, Polynomial.Separable p ∧ Polynomial.IsSplittingField F E p]

Next tactic:
tfae_have 3 → 1