field_theory.primitive_element
⟷
Mathlib.FieldTheory.PrimitiveElement
The following section lists changes to this file in mathlib3 and mathlib4 that occured after the initial port. Most recent changes are shown first. Hovering over a commit will show all commits associated with the same mathlib3 commit.
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(last sync)
mathlib commit https://github.com/leanprover-community/mathlib/commit/65a1391a0106c9204fe45bc73a039f056558cb83
@@ -141,7 +141,7 @@ theorem primitive_element_inf_aux [IsSeparable F E] : ∃ γ : E, F⟮⟯ = F⟮
apply le_antisymm
· rw [adjoin_le_iff]
have α_in_Fγ : α ∈ F⟮⟯ := by
- rw [← add_sub_cancel α (c • β)]
+ rw [← add_sub_cancel_right α (c • β)]
exact F⟮⟯.sub_mem (mem_adjoin_simple_self F γ) (F⟮⟯.toSubalgebra.smul_mem β_in_Fγ c)
exact fun x hx => by cases hx <;> cases hx <;> cases hx <;> assumption
· rw [adjoin_simple_le_iff]
@@ -159,7 +159,7 @@ theorem primitive_element_inf_aux [IsSeparable F E] : ∃ γ : E, F⟮⟯ = F⟮
· have finale : β = algebraMap F⟮⟯ E (-p.coeff 0 / p.coeff 1) :=
by
rw [map_div₀, RingHom.map_neg, ← coeff_map, ← coeff_map, p_linear]
- simp [mul_sub, coeff_C, mul_div_cancel_left β (mt leading_coeff_eq_zero.mp h_ne_zero)]
+ simp [mul_sub, coeff_C, mul_div_cancel_left₀ β (mt leading_coeff_eq_zero.mp h_ne_zero)]
rw [finale]
exact Subtype.mem (-p.coeff 0 / p.coeff 1)
have h_sep : h.separable := separable_gcd_right _ (IsSeparable.separable F β).map
@@ -167,7 +167,7 @@ theorem primitive_element_inf_aux [IsSeparable F E] : ∃ γ : E, F⟮⟯ = F⟮
apply eval_gcd_eq_zero
·
rw [eval_comp, eval_sub, eval_mul, eval_C, eval_C, eval_X, eval_map, ← aeval_def, ←
- Algebra.smul_def, add_sub_cancel, minpoly.aeval]
+ Algebra.smul_def, add_sub_cancel_right, minpoly.aeval]
· rw [eval_map, ← aeval_def, minpoly.aeval]
have h_splits : splits ιEE' h :=
splits_of_splits_gcd_right ιEE' map_g_ne_zero (splitting_field.splits _)
mathlib commit https://github.com/leanprover-community/mathlib/commit/65a1391a0106c9204fe45bc73a039f056558cb83
@@ -100,8 +100,8 @@ theorem primitive_element_inf_aux_exists_c (f g : F[X]) :
let s := (sf.bind fun α' => sg.map fun β' => -(α' - α) / (β' - β)).toFinset
let s' := s.preimage ϕ fun x hx y hy h => ϕ.injective h
obtain ⟨c, hc⟩ := Infinite.exists_not_mem_finset s'
- simp_rw [Finset.mem_preimage, Multiset.mem_toFinset, Multiset.mem_bind, Multiset.mem_map] at hc
- push_neg at hc
+ simp_rw [Finset.mem_preimage, Multiset.mem_toFinset, Multiset.mem_bind, Multiset.mem_map] at hc
+ push_neg at hc
exact ⟨c, hc⟩
#align field.primitive_element_inf_aux_exists_c Field.primitive_element_inf_aux_exists_c
-/
@@ -174,12 +174,12 @@ theorem primitive_element_inf_aux [IsSeparable F E] : ∃ γ : E, F⟮⟯ = F⟮
have h_roots : ∀ x ∈ (h.map ιEE').roots, x = ιEE' β :=
by
intro x hx
- rw [mem_roots_map h_ne_zero] at hx
+ rw [mem_roots_map h_ne_zero] at hx
specialize
hc (ιEE' γ - ιEE' (ιFE c) * x)
(by
have f_root := root_left_of_root_gcd hx
- rw [eval₂_comp, eval₂_sub, eval₂_mul, eval₂_C, eval₂_C, eval₂_X, eval₂_map] at f_root
+ rw [eval₂_comp, eval₂_sub, eval₂_mul, eval₂_C, eval₂_C, eval₂_X, eval₂_map] at f_root
exact (mem_roots_map (minpoly.ne_zero hα)).mpr f_root)
specialize
hc x
mathlib commit https://github.com/leanprover-community/mathlib/commit/ce64cd319bb6b3e82f31c2d38e79080d377be451
@@ -3,10 +3,10 @@ Copyright (c) 2020 Thomas Browning, Patrick Lutz. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Thomas Browning, Patrick Lutz
-/
-import Mathbin.FieldTheory.SplittingField.Construction
-import Mathbin.FieldTheory.IsAlgClosed.Basic
-import Mathbin.FieldTheory.Separable
-import Mathbin.RingTheory.IntegralDomain
+import FieldTheory.SplittingField.Construction
+import FieldTheory.IsAlgClosed.Basic
+import FieldTheory.Separable
+import RingTheory.IntegralDomain
#align_import field_theory.primitive_element from "leanprover-community/mathlib"@"2a0ce625dbb0ffbc7d1316597de0b25c1ec75303"
mathlib commit https://github.com/leanprover-community/mathlib/commit/8ea5598db6caeddde6cb734aa179cc2408dbd345
@@ -2,17 +2,14 @@
Copyright (c) 2020 Thomas Browning, Patrick Lutz. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Thomas Browning, Patrick Lutz
-
-! This file was ported from Lean 3 source module field_theory.primitive_element
-! leanprover-community/mathlib commit 2a0ce625dbb0ffbc7d1316597de0b25c1ec75303
-! Please do not edit these lines, except to modify the commit id
-! if you have ported upstream changes.
-/
import Mathbin.FieldTheory.SplittingField.Construction
import Mathbin.FieldTheory.IsAlgClosed.Basic
import Mathbin.FieldTheory.Separable
import Mathbin.RingTheory.IntegralDomain
+#align_import field_theory.primitive_element from "leanprover-community/mathlib"@"2a0ce625dbb0ffbc7d1316597de0b25c1ec75303"
+
/-!
# Primitive Element Theorem
mathlib commit https://github.com/leanprover-community/mathlib/commit/9240e8be927a0955b9a82c6c85ef499ee3a626b8
@@ -222,7 +222,7 @@ theorem exists_primitive_element : ∃ α : E, F⟮⟯ = ⊤ :=
by
rcases isEmpty_or_nonempty (Fintype F) with (F_inf | ⟨⟨F_finite⟩⟩)
· let P : IntermediateField F E → Prop := fun K => ∃ α : E, F⟮⟯ = K
- have base : P ⊥ := ⟨0, adjoin_zero⟩
+ have base : P ⊥ := ⟨0, adjoinZero⟩
have ih : ∀ (K : IntermediateField F E) (x : E), P K → P (K⟮⟯.restrictScalars F) :=
by
intro K β hK
mathlib commit https://github.com/leanprover-community/mathlib/commit/2a0ce625dbb0ffbc7d1316597de0b25c1ec75303
@@ -58,6 +58,7 @@ variable (F : Type _) [Field F] (E : Type _) [Field E] [Algebra F E]
/- ./././Mathport/Syntax/Translate/Expr.lean:192:11: unsupported (impossible) -/
/- ./././Mathport/Syntax/Translate/Expr.lean:192:11: unsupported (impossible) -/
+#print Field.exists_primitive_element_of_finite_top /-
/-- **Primitive element theorem** assuming E is finite. -/
theorem exists_primitive_element_of_finite_top [Finite E] : ∃ α : E, F⟮⟯ = ⊤ :=
by
@@ -72,14 +73,17 @@ theorem exists_primitive_element_of_finite_top [Finite E] : ∃ α : E, F⟮⟯
rw [show x = α ^ n by norm_cast; rw [hn, Units.val_mk0]]
exact zpow_mem (mem_adjoin_simple_self F ↑α) n
#align field.exists_primitive_element_of_finite_top Field.exists_primitive_element_of_finite_top
+-/
/- ./././Mathport/Syntax/Translate/Expr.lean:192:11: unsupported (impossible) -/
+#print Field.exists_primitive_element_of_finite_bot /-
/-- Primitive element theorem for finite dimensional extension of a finite field. -/
theorem exists_primitive_element_of_finite_bot [Finite F] [FiniteDimensional F E] :
∃ α : E, F⟮⟯ = ⊤ :=
haveI : Finite E := finite_of_finite F E
exists_primitive_element_of_finite_top F E
#align field.exists_primitive_element_of_finite_bot Field.exists_primitive_element_of_finite_bot
+-/
end PrimitiveElementFinite
@@ -90,6 +94,7 @@ section PrimitiveElementInf
variable {F : Type _} [Field F] [Infinite F] {E : Type _} [Field E] (ϕ : F →+* E) (α β : E)
+#print Field.primitive_element_inf_aux_exists_c /-
theorem primitive_element_inf_aux_exists_c (f g : F[X]) :
∃ c : F, ∀ α' ∈ (f.map ϕ).roots, ∀ β' ∈ (g.map ϕ).roots, -(α' - α) / (β' - β) ≠ ϕ c :=
by
@@ -102,6 +107,7 @@ theorem primitive_element_inf_aux_exists_c (f g : F[X]) :
push_neg at hc
exact ⟨c, hc⟩
#align field.primitive_element_inf_aux_exists_c Field.primitive_element_inf_aux_exists_c
+-/
variable (F) [Algebra F E]
@@ -120,6 +126,7 @@ variable (F) [Algebra F E]
/- ./././Mathport/Syntax/Translate/Expr.lean:192:11: unsupported (impossible) -/
/- ./././Mathport/Syntax/Translate/Expr.lean:192:11: unsupported (impossible) -/
/- ./././Mathport/Syntax/Translate/Expr.lean:192:11: unsupported (impossible) -/
+#print Field.primitive_element_inf_aux /-
-- 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⟮⟯ :=
@@ -193,6 +200,7 @@ theorem primitive_element_inf_aux [IsSeparable F E] : ∃ γ : E, F⟮⟯ = F⟮
convert (gcd_map (algebraMap F⟮⟯ E)).symm
· simpa [map_comp, Polynomial.map_map, ← IsScalarTower.algebraMap_eq, h]
#align field.primitive_element_inf_aux Field.primitive_element_inf_aux
+-/
end PrimitiveElementInf
@@ -207,6 +215,7 @@ variable [IsSeparable F E]
/- ./././Mathport/Syntax/Translate/Expr.lean:192:11: unsupported (impossible) -/
/- ./././Mathport/Syntax/Translate/Expr.lean:192:11: unsupported (impossible) -/
/- ./././Mathport/Syntax/Translate/Expr.lean:192:11: unsupported (impossible) -/
+#print Field.exists_primitive_element /-
/-- Primitive element theorem: a finite separable field extension `E` of `F` has a
primitive element, i.e. there is an `α ∈ E` such that `F⟮α⟯ = (⊤ : subalgebra F E)`.-/
theorem exists_primitive_element : ∃ α : E, F⟮⟯ = ⊤ :=
@@ -225,8 +234,10 @@ theorem exists_primitive_element : ∃ α : E, F⟮⟯ = ⊤ :=
exact induction_on_adjoin P base ih ⊤
· exact exists_primitive_element_of_finite_bot F E
#align field.exists_primitive_element Field.exists_primitive_element
+-/
/- ./././Mathport/Syntax/Translate/Expr.lean:192:11: unsupported (impossible) -/
+#print Field.powerBasisOfFiniteOfSeparable /-
/-- Alternative phrasing of primitive element theorem:
a finite separable field extension has a basis `1, α, α^2, ..., α^n`.
@@ -237,11 +248,13 @@ noncomputable def powerBasisOfFiniteOfSeparable : PowerBasis F E :=
have e : F⟮⟯ = ⊤ := (exists_primitive_element F E).choose_spec
pb.map ((IntermediateField.equivOfEq e).trans IntermediateField.topEquiv)
#align field.power_basis_of_finite_of_separable Field.powerBasisOfFiniteOfSeparable
+-/
end SeparableAssumption
end Field
+#print AlgHom.card /-
@[simp]
theorem AlgHom.card (F E K : Type _) [Field F] [Field E] [Field K] [IsAlgClosed K] [Algebra F E]
[FiniteDimensional F E] [IsSeparable F E] [Algebra F K] :
@@ -253,4 +266,5 @@ theorem AlgHom.card (F E K : Type _) [Field F] [Field E] [Field K] [IsAlgClosed
(PowerBasis.finrank _).symm
infer_instance
#align alg_hom.card AlgHom.card
+-/
mathlib commit https://github.com/leanprover-community/mathlib/commit/2a0ce625dbb0ffbc7d1316597de0b25c1ec75303
@@ -4,7 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE.
Authors: Thomas Browning, Patrick Lutz
! This file was ported from Lean 3 source module field_theory.primitive_element
-! leanprover-community/mathlib commit df76f43357840485b9d04ed5dee5ab115d420e87
+! leanprover-community/mathlib commit 2a0ce625dbb0ffbc7d1316597de0b25c1ec75303
! Please do not edit these lines, except to modify the commit id
! if you have ported upstream changes.
-/
@@ -16,6 +16,9 @@ import Mathbin.RingTheory.IntegralDomain
/-!
# Primitive Element Theorem
+> THIS FILE IS SYNCHRONIZED WITH MATHLIB4.
+> Any changes to this file require a corresponding PR to mathlib4.
+
In this file we prove the primitive element theorem.
## Main results
mathlib commit https://github.com/leanprover-community/mathlib/commit/a3209ddf94136d36e5e5c624b10b2a347cc9d090
@@ -4,11 +4,11 @@ Released under Apache 2.0 license as described in the file LICENSE.
Authors: Thomas Browning, Patrick Lutz
! This file was ported from Lean 3 source module field_theory.primitive_element
-! leanprover-community/mathlib commit 70fd9563a21e7b963887c9360bd29b2393e6225a
+! leanprover-community/mathlib commit df76f43357840485b9d04ed5dee5ab115d420e87
! Please do not edit these lines, except to modify the commit id
! if you have ported upstream changes.
-/
-import Mathbin.FieldTheory.Adjoin
+import Mathbin.FieldTheory.SplittingField.Construction
import Mathbin.FieldTheory.IsAlgClosed.Basic
import Mathbin.FieldTheory.Separable
import Mathbin.RingTheory.IntegralDomain
mathlib commit https://github.com/leanprover-community/mathlib/commit/5f25c089cb34db4db112556f23c50d12da81b297
@@ -96,7 +96,7 @@ theorem primitive_element_inf_aux_exists_c (f g : F[X]) :
let s' := s.preimage ϕ fun x hx y hy h => ϕ.injective h
obtain ⟨c, hc⟩ := Infinite.exists_not_mem_finset s'
simp_rw [Finset.mem_preimage, Multiset.mem_toFinset, Multiset.mem_bind, Multiset.mem_map] at hc
- push_neg at hc
+ push_neg at hc
exact ⟨c, hc⟩
#align field.primitive_element_inf_aux_exists_c Field.primitive_element_inf_aux_exists_c
@@ -187,7 +187,7 @@ theorem primitive_element_inf_aux [IsSeparable F E] : ∃ γ : E, F⟮⟯ = F⟮
rw [← eq_X_sub_C_of_separable_of_root_eq h_sep h_root h_splits h_roots]
trans EuclideanDomain.gcd (_ : E[X]) (_ : E[X])
· dsimp only [p]
- convert(gcd_map (algebraMap F⟮⟯ E)).symm
+ convert (gcd_map (algebraMap F⟮⟯ E)).symm
· simpa [map_comp, Polynomial.map_map, ← IsScalarTower.algebraMap_eq, h]
#align field.primitive_element_inf_aux Field.primitive_element_inf_aux
@@ -244,8 +244,9 @@ theorem AlgHom.card (F E K : Type _) [Field F] [Field E] [Field K] [IsAlgClosed
[FiniteDimensional F E] [IsSeparable F E] [Algebra F K] :
Fintype.card (E →ₐ[F] K) = finrank F E :=
by
- convert(AlgHom.card_of_powerBasis (Field.powerBasisOfFiniteOfSeparable F E)
- (IsSeparable.separable _ _) (IsAlgClosed.splits_codomain _)).trans
+ convert
+ (AlgHom.card_of_powerBasis (Field.powerBasisOfFiniteOfSeparable F E) (IsSeparable.separable _ _)
+ (IsAlgClosed.splits_codomain _)).trans
(PowerBasis.finrank _).symm
infer_instance
#align alg_hom.card AlgHom.card
mathlib commit https://github.com/leanprover-community/mathlib/commit/cca40788df1b8755d5baf17ab2f27dacc2e17acb
@@ -95,8 +95,8 @@ theorem primitive_element_inf_aux_exists_c (f g : F[X]) :
let s := (sf.bind fun α' => sg.map fun β' => -(α' - α) / (β' - β)).toFinset
let s' := s.preimage ϕ fun x hx y hy h => ϕ.injective h
obtain ⟨c, hc⟩ := Infinite.exists_not_mem_finset s'
- simp_rw [Finset.mem_preimage, Multiset.mem_toFinset, Multiset.mem_bind, Multiset.mem_map] at hc
- push_neg at hc
+ simp_rw [Finset.mem_preimage, Multiset.mem_toFinset, Multiset.mem_bind, Multiset.mem_map] at hc
+ push_neg at hc
exact ⟨c, hc⟩
#align field.primitive_element_inf_aux_exists_c Field.primitive_element_inf_aux_exists_c
@@ -167,12 +167,12 @@ theorem primitive_element_inf_aux [IsSeparable F E] : ∃ γ : E, F⟮⟯ = F⟮
have h_roots : ∀ x ∈ (h.map ιEE').roots, x = ιEE' β :=
by
intro x hx
- rw [mem_roots_map h_ne_zero] at hx
+ rw [mem_roots_map h_ne_zero] at hx
specialize
hc (ιEE' γ - ιEE' (ιFE c) * x)
(by
have f_root := root_left_of_root_gcd hx
- rw [eval₂_comp, eval₂_sub, eval₂_mul, eval₂_C, eval₂_C, eval₂_X, eval₂_map] at f_root
+ rw [eval₂_comp, eval₂_sub, eval₂_mul, eval₂_C, eval₂_C, eval₂_X, eval₂_map] at f_root
exact (mem_roots_map (minpoly.ne_zero hα)).mpr f_root)
specialize
hc x
mathlib commit https://github.com/leanprover-community/mathlib/commit/917c3c072e487b3cccdbfeff17e75b40e45f66cb
@@ -40,7 +40,7 @@ exists_adjoin_simple_eq_top
noncomputable section
-open Classical Polynomial
+open scoped Classical Polynomial
open FiniteDimensional Polynomial IntermediateField
mathlib commit https://github.com/leanprover-community/mathlib/commit/917c3c072e487b3cccdbfeff17e75b40e45f66cb
@@ -66,9 +66,7 @@ theorem exists_primitive_element_of_finite_top [Finite E] : ∃ α : E, F⟮⟯
· rw [hx]
exact F⟮⟯.zero_mem
· obtain ⟨n, hn⟩ := set.mem_range.mp (hα (Units.mk0 x hx))
- rw [show x = α ^ n by
- norm_cast
- rw [hn, Units.val_mk0]]
+ rw [show x = α ^ n by norm_cast; rw [hn, Units.val_mk0]]
exact zpow_mem (mem_adjoin_simple_self F ↑α) n
#align field.exists_primitive_element_of_finite_top Field.exists_primitive_element_of_finite_top
mathlib commit https://github.com/leanprover-community/mathlib/commit/ce7e9d53d4bbc38065db3b595cd5bd73c323bc1d
@@ -189,7 +189,7 @@ theorem primitive_element_inf_aux [IsSeparable F E] : ∃ γ : E, F⟮⟯ = F⟮
rw [← eq_X_sub_C_of_separable_of_root_eq h_sep h_root h_splits h_roots]
trans EuclideanDomain.gcd (_ : E[X]) (_ : E[X])
· dsimp only [p]
- convert (gcd_map (algebraMap F⟮⟯ E)).symm
+ convert(gcd_map (algebraMap F⟮⟯ E)).symm
· simpa [map_comp, Polynomial.map_map, ← IsScalarTower.algebraMap_eq, h]
#align field.primitive_element_inf_aux Field.primitive_element_inf_aux
@@ -246,9 +246,8 @@ theorem AlgHom.card (F E K : Type _) [Field F] [Field E] [Field K] [IsAlgClosed
[FiniteDimensional F E] [IsSeparable F E] [Algebra F K] :
Fintype.card (E →ₐ[F] K) = finrank F E :=
by
- convert
- (AlgHom.card_of_powerBasis (Field.powerBasisOfFiniteOfSeparable F E) (IsSeparable.separable _ _)
- (IsAlgClosed.splits_codomain _)).trans
+ convert(AlgHom.card_of_powerBasis (Field.powerBasisOfFiniteOfSeparable F E)
+ (IsSeparable.separable _ _) (IsAlgClosed.splits_codomain _)).trans
(PowerBasis.finrank _).symm
infer_instance
#align alg_hom.card AlgHom.card
mathlib commit https://github.com/leanprover-community/mathlib/commit/bd9851ca476957ea4549eb19b40e7b5ade9428cc
deprecated
attributeWhy these changes?
@@ -290,7 +290,7 @@ theorem FiniteDimensional.of_finite_intermediateField
rw [htop] at hfin
exact topEquiv.toLinearEquiv.finiteDimensional
-@[deprecated] -- Since 2024/02/02
+@[deprecated] -- Since 2024-02-02
alias finiteDimensional_of_finite_intermediateField := FiniteDimensional.of_finite_intermediateField
theorem exists_primitive_element_of_finite_intermediateField
@@ -311,7 +311,7 @@ theorem FiniteDimensional.of_exists_primitive_element (halg : Algebra.IsAlgebrai
rw [hprim] at hfin
exact topEquiv.toLinearEquiv.finiteDimensional
-@[deprecated] -- Since 2024/02/02
+@[deprecated] -- Since 2024-02-02
alias finiteDimensional_of_exists_primitive_element := FiniteDimensional.of_exists_primitive_element
-- A finite simple extension has only finitely many intermediate fields
mul
-div
cancellation lemmas (#11530)
Lemma names around cancellation of multiplication and division are a mess.
This PR renames a handful of them according to the following table (each big row contains the multiplicative statement, then the three rows contain the GroupWithZero
lemma name, the Group
lemma, the AddGroup
lemma name).
| Statement | New name | Old name | |
@@ -115,7 +115,7 @@ theorem primitive_element_inf_aux [IsSeparable F E] : ∃ γ : E, F⟮α, β⟯
apply le_antisymm
· rw [adjoin_le_iff]
have α_in_Fγ : α ∈ F⟮γ⟯ := by
- rw [← add_sub_cancel α (c • β)]
+ rw [← add_sub_cancel_right α (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]
@@ -132,7 +132,7 @@ theorem primitive_element_inf_aux [IsSeparable F E] : ∃ γ : E, F⟮α, β⟯
have finale : β = algebraMap F⟮γ⟯ E (-p.coeff 0 / p.coeff 1) := by
rw [map_div₀, RingHom.map_neg, ← coeff_map, ← coeff_map, p_linear]
-- Porting note: had to add `-map_add` to avoid going in the wrong direction.
- simp [mul_sub, coeff_C, mul_div_cancel_left β (mt leadingCoeff_eq_zero.mp h_ne_zero),
+ simp [mul_sub, coeff_C, mul_div_cancel_left₀ β (mt leadingCoeff_eq_zero.mp h_ne_zero),
-map_add]
-- Porting note: an alternative solution is:
-- simp_rw [Polynomial.coeff_C_mul, Polynomial.coeff_sub, mul_sub,
@@ -145,7 +145,7 @@ theorem primitive_element_inf_aux [IsSeparable F E] : ∃ γ : E, F⟮α, β⟯
have h_root : h.eval β = 0 := by
apply eval_gcd_eq_zero
· rw [eval_comp, eval_sub, eval_mul, eval_C, eval_C, eval_X, eval_map, ← aeval_def, ←
- Algebra.smul_def, add_sub_cancel, minpoly.aeval]
+ Algebra.smul_def, add_sub_cancel_right, minpoly.aeval]
· rw [eval_map, ← aeval_def, minpoly.aeval]
have h_splits : Splits ιEE' h :=
splits_of_splits_gcd_right ιEE' map_g_ne_zero (SplittingField.splits _)
@@ -194,7 +194,7 @@ private theorem primitive_element_inf_aux_of_finite_intermediateField
rw [smul_smul, inv_mul_eq_div, div_self (sub_ne_zero.2 hneq), one_smul] at β_in_K
have α_in_K : α ∈ F⟮α + x • β⟯ := by
convert ← sub_mem αxβ_in_K (smul_mem _ β_in_K)
- apply add_sub_cancel
+ apply add_sub_cancel_right
rintro x (rfl | rfl) <;> assumption
· rw [adjoin_simple_le_iff]
have α_in_Fαβ : α ∈ F⟮α, β⟯ := subset_adjoin F {α, β} (Set.mem_insert α {β})
apply foo.mpr
by rw [foo]
(#11515)
Sometimes, that line can be golfed into the next line. Inspired by a comment of @loefflerd; any decisions are my own.
@@ -56,7 +56,7 @@ variable (F : Type*) [Field F] (E : Type*) [Field E] [Algebra F E]
theorem exists_primitive_element_of_finite_top [Finite E] : ∃ α : E, F⟮α⟯ = ⊤ := by
obtain ⟨α, hα⟩ := @IsCyclic.exists_generator Eˣ _ _
use α
- apply eq_top_iff.mpr
+ rw [eq_top_iff]
rintro x -
by_cases hx : x = 0
· rw [hx]
Empty lines were removed by executing the following Python script twice
import os
import re
# Loop through each file in the repository
for dir_path, dirs, files in os.walk('.'):
for filename in files:
if filename.endswith('.lean'):
file_path = os.path.join(dir_path, filename)
# Open the file and read its contents
with open(file_path, 'r') as file:
content = file.read()
# Use a regular expression to replace sequences of "variable" lines separated by empty lines
# with sequences without empty lines
modified_content = re.sub(r'(variable.*\n)\n(variable(?! .* in))', r'\1\2', content)
# Write the modified content back to the file
with open(file_path, 'w') as file:
file.write(modified_content)
@@ -97,7 +97,6 @@ theorem primitive_element_inf_aux_exists_c (f g : F[X]) :
#align field.primitive_element_inf_aux_exists_c Field.primitive_element_inf_aux_exists_c
variable (F)
-
variable [Algebra F E]
/-- This is the heart of the proof of the primitive element theorem. It shows that if `F` is
@@ -205,7 +204,6 @@ private theorem primitive_element_inf_aux_of_finite_intermediateField
end PrimitiveElementInf
variable (F E : Type*) [Field F] [Field E]
-
variable [Algebra F E]
section SeparableAssumption
This is a very large PR, but it has been reviewed piecemeal already in PRs to the bump/v4.7.0
branch as we update to intermediate nightlies.
Co-authored-by: Scott Morrison <scott.morrison@gmail.com> Co-authored-by: Kyle Miller <kmill31415@gmail.com> Co-authored-by: damiano <adomani@gmail.com>
@@ -90,7 +90,7 @@ theorem primitive_element_inf_aux_exists_c (f g : F[X]) :
let s := (sf.bind fun α' => sg.map fun β' => -(α' - α) / (β' - β)).toFinset
let s' := s.preimage ϕ fun x _ y _ h => ϕ.injective h
obtain ⟨c, hc⟩ := Infinite.exists_not_mem_finset s'
- simp_rw [s, Finset.mem_preimage, Multiset.mem_toFinset, Multiset.mem_bind, Multiset.mem_map]
+ simp_rw [s', s, Finset.mem_preimage, Multiset.mem_toFinset, Multiset.mem_bind, Multiset.mem_map]
at hc
push_neg at hc
exact ⟨c, hc⟩
@@ -90,7 +90,8 @@ theorem primitive_element_inf_aux_exists_c (f g : F[X]) :
let s := (sf.bind fun α' => sg.map fun β' => -(α' - α) / (β' - β)).toFinset
let s' := s.preimage ϕ fun x _ y _ h => ϕ.injective h
obtain ⟨c, hc⟩ := Infinite.exists_not_mem_finset s'
- simp_rw [Finset.mem_preimage, Multiset.mem_toFinset, Multiset.mem_bind, Multiset.mem_map] at hc
+ simp_rw [s, Finset.mem_preimage, Multiset.mem_toFinset, Multiset.mem_bind, Multiset.mem_map]
+ at hc
push_neg at hc
exact ⟨c, hc⟩
#align field.primitive_element_inf_aux_exists_c Field.primitive_element_inf_aux_exists_c
@@ -162,11 +163,11 @@ theorem primitive_element_inf_aux [IsSeparable F E] : ∃ γ : E, F⟮α, β⟯
by_contra a
apply hc
apply (div_eq_iff (sub_ne_zero.mpr a)).mpr
- simp only [Algebra.smul_def, RingHom.map_add, RingHom.map_mul, RingHom.comp_apply]
+ simp only [γ, Algebra.smul_def, RingHom.map_add, RingHom.map_mul, RingHom.comp_apply]
ring
rw [← eq_X_sub_C_of_separable_of_root_eq h_sep h_root h_splits h_roots]
trans EuclideanDomain.gcd (?_ : E[X]) (?_ : E[X])
- · dsimp only
+ · dsimp only [γ]
convert (gcd_map (algebraMap F⟮γ⟯ E)).symm
· simp only [map_comp, Polynomial.map_map, ← IsScalarTower.algebraMap_eq, Polynomial.map_sub,
map_C, AdjoinSimple.algebraMap_gen, map_add, Polynomial.map_mul, map_X]
@@ -186,6 +187,7 @@ private theorem primitive_element_inf_aux_of_finite_intermediateField
· rw [adjoin_le_iff]
have αxβ_in_K : α + x • β ∈ F⟮α + x • β⟯ := mem_adjoin_simple_self F _
have αyβ_in_K : α + y • β ∈ F⟮α + y • β⟯ := mem_adjoin_simple_self F _
+ dsimp [f] at *
simp only [← heq] at αyβ_in_K
have β_in_K := sub_mem αxβ_in_K αyβ_in_K
rw [show (α + x • β) - (α + y • β) = (x - y) • β by rw [sub_smul]; abel1] at β_in_K
@@ -267,12 +269,12 @@ theorem isAlgebraic_of_adjoin_eq_adjoin {α : E} {m n : ℕ} (hneq : m ≠ n)
have hndvd : ¬ n ∣ n * s.natDegree + m := by
rw [← Nat.dvd_add_iff_right (n.dvd_mul_right s.natDegree)]
exact Nat.not_dvd_of_pos_of_lt hm hmn
- simp only [coeff_sub, coeff_X_pow_mul, s.coeff_expand_mul' hn, coeff_natDegree,
+ simp only [f, coeff_sub, coeff_X_pow_mul, s.coeff_expand_mul' hn, coeff_natDegree,
coeff_expand hn r, hndvd, ite_false, sub_zero]
exact leadingCoeff_ne_zero.2 hzero
intro h
simp only [h, coeff_zero, ne_eq, not_true_eq_false] at this
- · simp only [map_sub, map_mul, map_pow, aeval_X, expand_aeval, h]
+ · simp only [f, map_sub, map_mul, map_pow, aeval_X, expand_aeval, h]
theorem isAlgebraic_of_finite_intermediateField
[Finite (IntermediateField F E)] : Algebra.IsAlgebraic F E := fun α ↦
have
, replace
and suffices
(#10640)
No changes to tactic file, it's just boring fixes throughout the library.
This follows on from #6964.
Co-authored-by: sgouezel <sebastien.gouezel@univ-rennes1.fr> Co-authored-by: Eric Wieser <wieser.eric@gmail.com>
@@ -110,8 +110,8 @@ theorem primitive_element_inf_aux [IsSeparable F E] : ∃ γ : E, F⟮α, β⟯
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 γ
+ suffices β_in_Fγ : β ∈ F⟮γ⟯ by
+ use γ
apply le_antisymm
· rw [adjoin_le_iff]
have α_in_Fγ : α ∈ F⟮γ⟯ := by
@@ -128,8 +128,8 @@ theorem primitive_element_inf_aux [IsSeparable F E] : ∃ γ : E, F⟮α, β⟯
have map_g_ne_zero : g.map ιFE ≠ 0 := map_ne_zero (minpoly.ne_zero hβ)
have h_ne_zero : h ≠ 0 :=
mt EuclideanDomain.gcd_eq_zero_iff.mp (not_and.mpr fun _ => map_g_ne_zero)
- suffices p_linear : p.map (algebraMap F⟮γ⟯ E) = C h.leadingCoeff * (X - C β)
- · have finale : β = algebraMap F⟮γ⟯ E (-p.coeff 0 / p.coeff 1) := by
+ suffices p_linear : p.map (algebraMap F⟮γ⟯ E) = C h.leadingCoeff * (X - C β) by
+ have finale : β = algebraMap F⟮γ⟯ E (-p.coeff 0 / p.coeff 1) := by
rw [map_div₀, RingHom.map_neg, ← coeff_map, ← coeff_map, p_linear]
-- Porting note: had to add `-map_add` to avoid going in the wrong direction.
simp [mul_sub, coeff_C, mul_div_cancel_left β (mt leadingCoeff_eq_zero.mp h_ne_zero),
Rename lemmas to enable new-style dot notation or drop repeating FiniteDimensional.finiteDimensional_*
.
Restore old names as deprecated aliases.
@@ -279,7 +279,7 @@ theorem isAlgebraic_of_finite_intermediateField
have ⟨_m, _n, hneq, heq⟩ := Finite.exists_ne_map_eq_of_infinite fun n ↦ F⟮α ^ n⟯
isAlgebraic_of_adjoin_eq_adjoin F E hneq heq
-theorem finiteDimensional_of_finite_intermediateField
+theorem FiniteDimensional.of_finite_intermediateField
[Finite (IntermediateField F E)] : FiniteDimensional F E := by
let IF := { K : IntermediateField F E // ∃ x, K = F⟮x⟯ }
haveI : ∀ K : IF, FiniteDimensional F K.1 := fun ⟨_, x, rfl⟩ ↦ adjoin.finiteDimensional
@@ -290,9 +290,12 @@ theorem finiteDimensional_of_finite_intermediateField
rw [htop] at hfin
exact topEquiv.toLinearEquiv.finiteDimensional
+@[deprecated] -- Since 2024/02/02
+alias finiteDimensional_of_finite_intermediateField := FiniteDimensional.of_finite_intermediateField
+
theorem exists_primitive_element_of_finite_intermediateField
[Finite (IntermediateField F E)] (K : IntermediateField F E) : ∃ α : E, F⟮α⟯ = K := by
- haveI := finiteDimensional_of_finite_intermediateField F E
+ haveI := FiniteDimensional.of_finite_intermediateField F E
rcases finite_or_infinite F with (_ | _)
· obtain ⟨α, h⟩ := exists_primitive_element_of_finite_bot F K
exact ⟨α, by simpa only [lift_adjoin_simple, lift_top] using congr_arg lift h⟩
@@ -301,17 +304,20 @@ theorem exists_primitive_element_of_finite_intermediateField
simp_rw [adjoin_simple_adjoin_simple, eq_comm]
exact primitive_element_inf_aux_of_finite_intermediateField F α β
-theorem finiteDimensional_of_exists_primitive_element (halg : Algebra.IsAlgebraic F E)
+theorem FiniteDimensional.of_exists_primitive_element (halg : Algebra.IsAlgebraic F E)
(h : ∃ α : E, F⟮α⟯ = ⊤) : FiniteDimensional F E := by
obtain ⟨α, hprim⟩ := h
have hfin := adjoin.finiteDimensional (halg α).isIntegral
rw [hprim] at hfin
exact topEquiv.toLinearEquiv.finiteDimensional
+@[deprecated] -- Since 2024/02/02
+alias finiteDimensional_of_exists_primitive_element := FiniteDimensional.of_exists_primitive_element
+
-- A finite simple extension has only finitely many intermediate fields
theorem finite_intermediateField_of_exists_primitive_element (halg : Algebra.IsAlgebraic F E)
(h : ∃ α : E, F⟮α⟯ = ⊤) : Finite (IntermediateField F E) := by
- haveI := finiteDimensional_of_exists_primitive_element F E halg h
+ haveI := FiniteDimensional.of_exists_primitive_element F E halg h
obtain ⟨α, hprim⟩ := h
-- Let `f` be the minimal polynomial of `α ∈ E` over `F`
let f : F[X] := minpoly F α
f ^ n
(#9617)
This involves moving lemmas from Algebra.GroupPower.Ring
to Algebra.GroupWithZero.Basic
and changing some 0 < n
assumptions to n ≠ 0
.
From LeanAPAP
@@ -253,26 +253,26 @@ theorem isAlgebraic_of_adjoin_eq_adjoin {α : E} {m n : ℕ} (hneq : m ≠ n)
obtain ⟨y, h⟩ := mem_bot.1 (heq.symm ▸ mem_adjoin_simple_self F (α ^ n))
refine ⟨X ^ n - C y, X_pow_sub_C_ne_zero hmn y, ?_⟩
simp only [map_sub, map_pow, aeval_X, aeval_C, h, sub_self]
- replace hm : 0 < m := Nat.pos_of_ne_zero hm
obtain ⟨r, s, h⟩ := (mem_adjoin_simple_iff F _).1 (heq ▸ mem_adjoin_simple_self F (α ^ m))
by_cases hzero : aeval (α ^ n) s = 0
· simp only [hzero, div_zero, pow_eq_zero_iff hm] at h
exact h.symm ▸ isAlgebraic_zero
- · rw [eq_div_iff hzero, ← sub_eq_zero] at h
- replace hzero : s ≠ 0 := by rintro rfl; simp only [map_zero, not_true_eq_false] at hzero
- let f : F[X] := X ^ m * expand F n s - expand F n r
- refine ⟨f, ?_, ?_⟩
- · have : f.coeff (n * s.natDegree + m) ≠ 0 := by
- have hn : 0 < n := by linarith only [hm, hmn]
- have hndvd : ¬ n ∣ n * s.natDegree + m := by
- rw [← Nat.dvd_add_iff_right (n.dvd_mul_right s.natDegree)]
- exact Nat.not_dvd_of_pos_of_lt hm hmn
- simp only [coeff_sub, coeff_X_pow_mul, s.coeff_expand_mul' hn, coeff_natDegree,
- coeff_expand hn r, hndvd, ite_false, sub_zero]
- exact leadingCoeff_ne_zero.2 hzero
- intro h
- simp only [h, coeff_zero, ne_eq, not_true_eq_false] at this
- · simp only [map_sub, map_mul, map_pow, aeval_X, expand_aeval, h]
+ replace hm : 0 < m := Nat.pos_of_ne_zero hm
+ rw [eq_div_iff hzero, ← sub_eq_zero] at h
+ replace hzero : s ≠ 0 := by rintro rfl; simp only [map_zero, not_true_eq_false] at hzero
+ let f : F[X] := X ^ m * expand F n s - expand F n r
+ refine ⟨f, ?_, ?_⟩
+ · have : f.coeff (n * s.natDegree + m) ≠ 0 := by
+ have hn : 0 < n := by linarith only [hm, hmn]
+ have hndvd : ¬ n ∣ n * s.natDegree + m := by
+ rw [← Nat.dvd_add_iff_right (n.dvd_mul_right s.natDegree)]
+ exact Nat.not_dvd_of_pos_of_lt hm hmn
+ simp only [coeff_sub, coeff_X_pow_mul, s.coeff_expand_mul' hn, coeff_natDegree,
+ coeff_expand hn r, hndvd, ite_false, sub_zero]
+ exact leadingCoeff_ne_zero.2 hzero
+ intro h
+ simp only [h, coeff_zero, ne_eq, not_true_eq_false] at this
+ · simp only [map_sub, map_mul, map_pow, aeval_X, expand_aeval, h]
theorem isAlgebraic_of_finite_intermediateField
[Finite (IntermediateField F E)] : Algebra.IsAlgebraic F E := fun α ↦
@@ -4,7 +4,6 @@ Released under Apache 2.0 license as described in the file LICENSE.
Authors: Thomas Browning, Patrick Lutz
-/
import Mathlib.FieldTheory.IsAlgClosed.AlgebraicClosure
-import Mathlib.FieldTheory.NormalClosure
import Mathlib.RingTheory.IntegralDomain
#align_import field_theory.primitive_element from "leanprover-community/mathlib"@"df76f43357840485b9d04ed5dee5ab115d420e87"
generalize image_rootSet
, adjoin_rootSet_eq_range
and splits_comp_of_splits
in Data/Polynomial/Splits and use the last one to golf splits_of_algHom
, splits_of_isScalarTower
(introduced in # 8609).
add three new lemmas mem_range_x_of_minpoly_splits
to simplify the construction of IntermediateField.algHomEquivAlgHomOfIsAlgClosed
and Algebra.IsAlgebraic.algHomEquivAlgHomOfIsAlgClosed
, remove the IsAlgClosed
condition and rename. They could be moved to an earlier file but I refrain from doing that. (#find_home says it's already in the right place)
golf primitive_element_iff_algHom_eq_of_eval
from # 8609, using a new lemma IsIntegral.minpoly_splits_tower_top
for the last step.
make integralClosure_algEquiv_restrict
(from # 8714) computable and rename to AlgEquiv.mapIntegralClosure
to follow camelCase naming convention and enable dot notation.
Co-authored-by: Xavier-François Roblot <46200072+xroblot@users.noreply.github.com> Co-authored-by: Junyan Xu <junyanxu.math@gmail.com>
@@ -360,7 +360,7 @@ theorem AlgHom.card (K : Type*) [Field K] [IsAlgClosed K] [Algebra F K] :
theorem AlgHom.card_of_splits (L : Type*) [Field L] [Algebra F L]
(hL : ∀ x : E, (minpoly F x).Splits (algebraMap F L)) :
Fintype.card (E →ₐ[F] L) = finrank F E := by
- rw [← Fintype.ofEquiv_card <| Algebra.IsAlgebraic.algHomEquivAlgHomOfIsAlgClosed
+ rw [← Fintype.ofEquiv_card <| Algebra.IsAlgebraic.algHomEquivAlgHomOfSplits
(AlgebraicClosure L) (Algebra.IsAlgebraic.of_finite F E) _ hL]
convert AlgHom.card F E (AlgebraicClosure L)
@@ -397,34 +397,14 @@ theorem primitive_element_iff_algHom_eq_of_eval' (α : E) :
theorem primitive_element_iff_algHom_eq_of_eval (α : E)
(φ : E →ₐ[F] A) : F⟮α⟯ = ⊤ ↔ ∀ ψ : E →ₐ[F] A, φ α = ψ α → φ = ψ := by
- rw [Field.primitive_element_iff_algHom_eq_of_eval' F A hA]
- refine ⟨fun h _ eq => h eq, fun h φ₀ ψ₀ h' => ?_⟩
- let K := normalClosure F E A
- have : IsNormalClosure F E K := by
- refine Algebra.IsAlgebraic.isNormalClosure_normalClosure ?_ hA
- exact Algebra.IsAlgebraic.of_finite F E
- have hK_mem : ∀ (ψ : E →ₐ[F] A) (x : E), ψ x ∈ K :=
- fun ψ x => AlgHom.fieldRange_le_normalClosure ψ ⟨x, rfl⟩
- let res : (E →ₐ[F] A) → (E →ₐ[F] K) := fun ψ => AlgHom.codRestrict ψ K.toSubalgebra (hK_mem ψ)
- rsuffices ⟨σ, hσ⟩ : ∃ σ : K →ₐ[F] A, σ (⟨φ₀ α, hK_mem _ _⟩) = φ α
- · suffices res φ₀ = res ψ₀ by
- ext x
- exact Subtype.mk_eq_mk.mp (AlgHom.congr_fun this x)
- have eq₁ : φ = AlgHom.comp σ (res φ₀) := h (AlgHom.comp σ (res φ₀)) hσ.symm
- have eq₂ : φ = AlgHom.comp σ (res ψ₀) := by
- refine h (AlgHom.comp σ (res ψ₀)) ?_
- simp_rw [← hσ, h']
- rfl
- ext1 x
- exact (RingHom.injective σ.toRingHom) <| AlgHom.congr_fun (eq₁.symm.trans eq₂) x
- refine IntermediateField.exists_algHom_of_splits_of_aeval ?_ ?_
- · refine fun x => ⟨IsAlgebraic.isIntegral (IsAlgebraic.of_finite F x), ?_⟩
- refine Polynomial.splits_of_algHom ?_ K.toSubalgebra.val
- exact Normal.splits (IsNormalClosure.normal (K := E)) x
- · rw [aeval_algHom_apply, _root_.map_eq_zero]
- convert minpoly.aeval F α
- letI : Algebra E K := (res φ₀).toAlgebra
- exact minpoly.algebraMap_eq (algebraMap E K).injective α
+ refine ⟨fun h ψ hψ ↦ (Field.primitive_element_iff_algHom_eq_of_eval' F A hA α).mp h hψ,
+ fun h ↦ eq_of_le_of_finrank_eq' le_top ?_⟩
+ letI : Algebra F⟮α⟯ A := (φ.comp F⟮α⟯.val).toAlgebra
+ haveI := isSeparable_tower_top_of_isSeparable F F⟮α⟯ E
+ rw [IntermediateField.finrank_top, ← AlgHom.card_of_splits _ _ A, Fintype.card_eq_one_iff]
+ · exact ⟨{ __ := φ, commutes' := fun _ ↦ rfl }, fun ψ ↦ AlgHom.restrictScalars_injective F <|
+ Eq.symm <| h _ (ψ.commutes <| AdjoinSimple.gen F α).symm⟩
+ · exact fun x ↦ (IsIntegral.of_finite F x).minpoly_splits_tower_top (hA x)
end Field
See the Zulip thread
@@ -3,9 +3,8 @@ Copyright (c) 2020 Thomas Browning, Patrick Lutz. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Thomas Browning, Patrick Lutz
-/
-import Mathlib.FieldTheory.SplittingField.Construction
-import Mathlib.FieldTheory.IsAlgClosed.Basic
-import Mathlib.FieldTheory.Separable
+import Mathlib.FieldTheory.IsAlgClosed.AlgebraicClosure
+import Mathlib.FieldTheory.NormalClosure
import Mathlib.RingTheory.IntegralDomain
#align_import field_theory.primitive_element from "leanprover-community/mathlib"@"df76f43357840485b9d04ed5dee5ab115d420e87"
@@ -348,10 +347,85 @@ end FiniteIntermediateField
end Field
+variable (F E : Type*) [Field F] [Field E] [Algebra F E] [FiniteDimensional F E] [IsSeparable F E]
+
@[simp]
-theorem AlgHom.card (F E K : Type*) [Field F] [Field E] [Field K] [IsAlgClosed K] [Algebra F E]
- [FiniteDimensional F E] [IsSeparable F E] [Algebra F K] :
+theorem AlgHom.card (K : Type*) [Field K] [IsAlgClosed K] [Algebra F K] :
Fintype.card (E →ₐ[F] K) = finrank F E := by
convert (AlgHom.card_of_powerBasis (L := K) (Field.powerBasisOfFiniteOfSeparable F E)
(IsSeparable.separable _ _) (IsAlgClosed.splits_codomain _)).trans (PowerBasis.finrank _).symm
#align alg_hom.card AlgHom.card
+
+@[simp]
+theorem AlgHom.card_of_splits (L : Type*) [Field L] [Algebra F L]
+ (hL : ∀ x : E, (minpoly F x).Splits (algebraMap F L)) :
+ Fintype.card (E →ₐ[F] L) = finrank F E := by
+ rw [← Fintype.ofEquiv_card <| Algebra.IsAlgebraic.algHomEquivAlgHomOfIsAlgClosed
+ (AlgebraicClosure L) (Algebra.IsAlgebraic.of_finite F E) _ hL]
+ convert AlgHom.card F E (AlgebraicClosure L)
+
+section iff
+
+namespace Field
+
+open FiniteDimensional IntermediateField Polynomial Algebra Set
+
+variable (F : Type*) {E : Type*} [Field F] [Field E] [Algebra F E] [FiniteDimensional F E]
+
+theorem primitive_element_iff_minpoly_natDegree_eq (α : E) :
+ F⟮α⟯ = ⊤ ↔ (minpoly F α).natDegree = finrank F E := by
+ rw [← adjoin.finrank (IsIntegral.of_finite F α), ← finrank_top F E]
+ refine ⟨fun h => ?_, fun h => eq_of_le_of_finrank_eq le_top h⟩
+ exact congr_arg (fun K : IntermediateField F E => finrank F K) h
+
+theorem primitive_element_iff_minpoly_degree_eq (α : E) :
+ F⟮α⟯ = ⊤ ↔ (minpoly F α).degree = finrank F E := by
+ rw [degree_eq_iff_natDegree_eq, primitive_element_iff_minpoly_natDegree_eq]
+ exact minpoly.ne_zero_of_finite F α
+
+variable [IsSeparable F E] (A : Type*) [Field A] [Algebra F A]
+ (hA : ∀ x : E, (minpoly F x).Splits (algebraMap F A))
+
+theorem primitive_element_iff_algHom_eq_of_eval' (α : E) :
+ F⟮α⟯ = ⊤ ↔ Function.Injective fun φ : E →ₐ[F] A ↦ φ α := by
+ classical
+ simp_rw [primitive_element_iff_minpoly_natDegree_eq, ← card_rootSet_eq_natDegree (K := A)
+ (IsSeparable.separable F α) (hA _), ← toFinset_card,
+ ← (Algebra.IsAlgebraic.of_finite F E).range_eval_eq_rootSet_minpoly_of_splits _ hA α,
+ ← AlgHom.card_of_splits F E A hA, Fintype.card, toFinset_range, Finset.card_image_iff,
+ Finset.coe_univ, ← injective_iff_injOn_univ]
+
+theorem primitive_element_iff_algHom_eq_of_eval (α : E)
+ (φ : E →ₐ[F] A) : F⟮α⟯ = ⊤ ↔ ∀ ψ : E →ₐ[F] A, φ α = ψ α → φ = ψ := by
+ rw [Field.primitive_element_iff_algHom_eq_of_eval' F A hA]
+ refine ⟨fun h _ eq => h eq, fun h φ₀ ψ₀ h' => ?_⟩
+ let K := normalClosure F E A
+ have : IsNormalClosure F E K := by
+ refine Algebra.IsAlgebraic.isNormalClosure_normalClosure ?_ hA
+ exact Algebra.IsAlgebraic.of_finite F E
+ have hK_mem : ∀ (ψ : E →ₐ[F] A) (x : E), ψ x ∈ K :=
+ fun ψ x => AlgHom.fieldRange_le_normalClosure ψ ⟨x, rfl⟩
+ let res : (E →ₐ[F] A) → (E →ₐ[F] K) := fun ψ => AlgHom.codRestrict ψ K.toSubalgebra (hK_mem ψ)
+ rsuffices ⟨σ, hσ⟩ : ∃ σ : K →ₐ[F] A, σ (⟨φ₀ α, hK_mem _ _⟩) = φ α
+ · suffices res φ₀ = res ψ₀ by
+ ext x
+ exact Subtype.mk_eq_mk.mp (AlgHom.congr_fun this x)
+ have eq₁ : φ = AlgHom.comp σ (res φ₀) := h (AlgHom.comp σ (res φ₀)) hσ.symm
+ have eq₂ : φ = AlgHom.comp σ (res ψ₀) := by
+ refine h (AlgHom.comp σ (res ψ₀)) ?_
+ simp_rw [← hσ, h']
+ rfl
+ ext1 x
+ exact (RingHom.injective σ.toRingHom) <| AlgHom.congr_fun (eq₁.symm.trans eq₂) x
+ refine IntermediateField.exists_algHom_of_splits_of_aeval ?_ ?_
+ · refine fun x => ⟨IsAlgebraic.isIntegral (IsAlgebraic.of_finite F x), ?_⟩
+ refine Polynomial.splits_of_algHom ?_ K.toSubalgebra.val
+ exact Normal.splits (IsNormalClosure.normal (K := E)) x
+ · rw [aeval_algHom_apply, _root_.map_eq_zero]
+ convert minpoly.aeval F α
+ letI : Algebra E K := (res φ₀).toAlgebra
+ exact minpoly.algebraMap_eq (algebraMap E K).injective α
+
+end Field
+
+end iff
Initially I just wanted to add more dot notations for IsIntegral and IsAlgebraic (done in #8437); then I noticed near-duplicates
Algebra.isIntegral_of_finite [Field R] [Ring A]
and
RingHom.IsIntegral.of_finite [CommRing R] [CommRing A]
so I went on to generalize the latter to cover the former, and generalized everything in the IntegralClosure file to the noncommutative case whenever possible.
In the process I noticed more golfs, which result in this PR. Most notably, isIntegral_of_mem_of_FG is now proven using Cayley-Hamilton and doesn't depend on the Noetherian case isIntegral_of_noetherian; the latter is now proven using the former. In total the golfs makes mathlib 227 lines leaner (+487 -714).
The main changes are in the single file RingTheory/IntegralClosure:
Change the definition of Algebra.IsIntegral
which makes it unfold to IsIntegral
rather than RingHom.IsIntegralElem
because the former has much more APIs.
Fix lemma names involving is_integral
which are actually about IsIntegralElem
:
RingHom.is_integral_map
→ RingHom.isIntegralElem_map
RingHom.is_integral_of_mem_closure
→ RingHom.IsIntegralElem.of_mem_closure
RingHom.is_integral_zero/one
→ RingHom.isIntegralElem_zero/one
RingHom.is_integral_add/neg/sub/mul/of_mul_unit
→ RingHom.IsIntegralElem.add/neg/sub/mul/of_mul_unit
Add a lemma Algebra.IsIntegral.of_injective
.
Move isIntegral_of_(submodule_)noetherian
down and golf them.
Remove (Algebra.)isIntegral_of_finite
that work only over fields, in favor of the more general (Algebra.)isIntegral.of_finite
.
Merge duplicate lemmas isIntegral_of_isScalarTower
and isIntegral_tower_top_of_isIntegral
into IsIntegral.tower_top
.
Golf IsIntegral.of_mem_of_fg
by first proving IsIntegral.of_finite
using Cayley-Hamilton.
Add a docstring mentioning the Kurosh problem at Algebra.IsIntegral.finite
. The negative solution to the problem means the theorem doesn't generalize to noncommutative algebras.
Golf IsIntegral.tmul
and isField_of_isIntegral_of_isField(')
.
Combine isIntegral_trans_aux
into isIntegral_trans
and golf.
Add Algebra
namespace to isIntegral_sup
.
rename lemmas for dot notation:
RingHom.isIntegral_trans
→ RingHom.IsIntegral.trans
RingHom.isIntegral_quotient/tower_bot/top_of_isIntegral
→ RingHom.IsIntegral.quotient/tower_bot/top
isIntegral_of_mem_closure'
→ IsIntegral.of_mem_closure'
(and the '' version)
isIntegral_of_surjective
→ Algebra.isIntegral_of_surjective
The next changed file is RingTheory/Algebraic:
Rename:
of_larger_base
→ tower_top
(for consistency with IsIntegral
)
Algebra.isAlgebraic_of_finite
→ Algebra.IsAlgebraic.of_finite
Algebra.isAlgebraic_trans
→ Algebra.IsAlgebraic.trans
Add new lemmasAlgebra.IsIntegral.isAlgebraic
, isAlgebraic_algHom_iff
, and Algebra.IsAlgebraic.of_injective
to streamline some proofs.
The generalization from CommRing to Ring requires an additional lemma scaleRoots_eval₂_mul_of_commute
in Polynomial/ScaleRoots.
A lemma Algebra.lmul_injective
is added to Algebra/Bilinear (in order to golf the proof of IsIntegral.of_mem_of_fg
).
In all other files, I merely fix the changed names, or use newly available dot notations.
Co-authored-by: Junyan Xu <junyanxu.math@gmail.com>
@@ -284,8 +284,8 @@ theorem isAlgebraic_of_finite_intermediateField
theorem finiteDimensional_of_finite_intermediateField
[Finite (IntermediateField F E)] : FiniteDimensional F E := by
let IF := { K : IntermediateField F E // ∃ x, K = F⟮x⟯ }
- haveI : ∀ K : IF, FiniteDimensional F K.1 := fun ⟨_, x, rfl⟩ ↦ adjoin.finiteDimensional <|
- isAlgebraic_iff_isIntegral.1 (isAlgebraic_of_finite_intermediateField F E x)
+ haveI : ∀ K : IF, FiniteDimensional F K.1 := fun ⟨_, x, rfl⟩ ↦ adjoin.finiteDimensional
+ (isAlgebraic_of_finite_intermediateField F E x).isIntegral
have hfin := finiteDimensional_iSup_of_finite (t := fun K : IF ↦ K.1)
have htop : ⨆ K : IF, K.1 = ⊤ := le_top.antisymm fun x _ ↦
le_iSup (fun K : IF ↦ K.1) ⟨F⟮x⟯, x, rfl⟩ <| mem_adjoin_simple_self F x
@@ -306,7 +306,7 @@ theorem exists_primitive_element_of_finite_intermediateField
theorem finiteDimensional_of_exists_primitive_element (halg : Algebra.IsAlgebraic F E)
(h : ∃ α : E, F⟮α⟯ = ⊤) : FiniteDimensional F E := by
obtain ⟨α, hprim⟩ := h
- have hfin := adjoin.finiteDimensional <| isAlgebraic_iff_isIntegral.1 (halg α)
+ have hfin := adjoin.finiteDimensional (halg α).isIntegral
rw [hprim] at hfin
exact topEquiv.toLinearEquiv.finiteDimensional
@@ -324,7 +324,7 @@ theorem finite_intermediateField_of_exists_primitive_element (halg : Algebra.IsA
-- If `K` is an intermediate field of `E/F`, let `g` be the minimal polynomial of `α` over `K`
-- which is a monic factor of `f`
let g : IntermediateField F E → G := fun K ↦
- ⟨(minpoly K α).map (algebraMap K E), (minpoly.monic <| IsIntegral.of_finite K α).map _, by
+ ⟨(minpoly K α).map (algebraMap K E), (minpoly.monic <| .of_finite K α).map _, by
convert Polynomial.map_dvd (algebraMap K E) (minpoly.dvd_map_of_isScalarTower F K α)
rw [Polynomial.map_map]; rfl⟩
-- The map `K ↦ g` is injective
This is the supremum of
along with some minor fixes from failures on nightly-testing as Mathlib master
is merged into it.
Note that some PRs for changes that are already compatible with the current toolchain and will be necessary have already been split out: #8380.
I am hopeful that in future we will be able to progressively merge adaptation PRs into a bump/v4.X.0
branch, so we never end up with a "big merge" like this. However one of these adaptation PRs (#8056) predates my new scheme for combined CI, and it wasn't possible to keep that PR viable in the meantime.
In particular this includes adjustments for the Lean PRs
We can get rid of all the
local macro_rules | `($x ^ $y) => `(HPow.hPow $x $y) -- Porting note: See issue [lean4#2220](https://github.com/leanprover/lean4/pull/2220)
macros across Mathlib (and in any projects that want to write natural number powers of reals).
Changes the default behaviour of simp
to (config := {decide := false})
. This makes simp
(and consequentially norm_num
) less powerful, but also more consistent, and less likely to blow up in long failures. This requires a variety of changes: changing some previously by simp
or norm_num
to decide
or rfl
, or adding (config := {decide := true})
.
This changed the behaviour of simp
so that simp [f]
will only unfold "fully applied" occurrences of f
. The old behaviour can be recovered with simp (config := { unfoldPartialApp := true })
. We may in future add a syntax for this, e.g. simp [!f]
; please provide feedback! In the meantime, we have made the following changes:
(config := { unfoldPartialApp := true })
in some places, to recover the old behaviour@[eqns]
to manually adjust the equation lemmas for a particular definition, recovering the old behaviour just for that definition. See #8371, where we do this for Function.comp
and Function.flip
.This change in Lean may require further changes down the line (e.g. adding the !f
syntax, and/or upstreaming the special treatment for Function.comp
and Function.flip
, and/or removing this special treatment). Please keep an open and skeptical mind about these changes!
Co-authored-by: leanprover-community-mathlib4-bot <leanprover-community-mathlib4-bot@users.noreply.github.com> Co-authored-by: Scott Morrison <scott.morrison@gmail.com> Co-authored-by: Eric Wieser <wieser.eric@gmail.com> Co-authored-by: Mauricio Collares <mauricio@collares.org>
@@ -65,7 +65,7 @@ theorem exists_primitive_element_of_finite_top [Finite E] : ∃ α : E, F⟮α
exact F⟮α.val⟯.zero_mem
· obtain ⟨n, hn⟩ := Set.mem_range.mp (hα (Units.mk0 x hx))
simp only at hn
- rw [show x = α ^ n by norm_cast; rw [hn, Units.val_mk0], Units.val_zpow_eq_zpow_val]
+ rw [show x = α ^ n by norm_cast; rw [hn, Units.val_mk0]]
exact zpow_mem (mem_adjoin_simple_self F (E := E) ↑α) n
#align field.exists_primitive_element_of_finite_top Field.exists_primitive_element_of_finite_top
@@ -261,7 +261,7 @@ theorem isAlgebraic_of_adjoin_eq_adjoin {α : E} {m n : ℕ} (hneq : m ≠ n)
· simp only [hzero, div_zero, pow_eq_zero_iff hm] at h
exact h.symm ▸ isAlgebraic_zero
· rw [eq_div_iff hzero, ← sub_eq_zero] at h
- replace hzero : s ≠ 0 := by rintro rfl; simp only [map_zero] at hzero
+ replace hzero : s ≠ 0 := by rintro rfl; simp only [map_zero, not_true_eq_false] at hzero
let f : F[X] := X ^ m * expand F n s - expand F n r
refine ⟨f, ?_, ?_⟩
· have : f.coeff (n * s.natDegree + m) ≠ 0 := by
@@ -273,7 +273,7 @@ theorem isAlgebraic_of_adjoin_eq_adjoin {α : E} {m n : ℕ} (hneq : m ≠ n)
coeff_expand hn r, hndvd, ite_false, sub_zero]
exact leadingCoeff_ne_zero.2 hzero
intro h
- simp only [h, coeff_zero, ne_eq] at this
+ simp only [h, coeff_zero, ne_eq, not_true_eq_false] at this
· simp only [map_sub, map_mul, map_pow, aeval_X, expand_aeval, h]
theorem isAlgebraic_of_finite_intermediateField
This PR tests a string-based tool for renaming declarations.
Inspired by this Zulip thread, I am trying to reduce the diff of #8406.
This PR makes the following renames:
| From | To |
@@ -324,7 +324,7 @@ theorem finite_intermediateField_of_exists_primitive_element (halg : Algebra.IsA
-- If `K` is an intermediate field of `E/F`, let `g` be the minimal polynomial of `α` over `K`
-- which is a monic factor of `f`
let g : IntermediateField F E → G := fun K ↦
- ⟨(minpoly K α).map (algebraMap K E), (minpoly.monic <| isIntegral_of_finite K α).map _, by
+ ⟨(minpoly K α).map (algebraMap K E), (minpoly.monic <| IsIntegral.of_finite K α).map _, by
convert Polynomial.map_dvd (algebraMap K E) (minpoly.dvd_map_of_isScalarTower F K α)
rw [Polynomial.map_map]; rfl⟩
-- The map `K ↦ g` is injective
Added Field.exists_primitive_element_iff_finite_intermediateField
: a finite extension E / F
has a primitive element if and only if the intermediate fields between E / F
are finitely many.
Also known as Steinitz Theorem https://en.wikipedia.org/wiki/Primitive_element_theorem#The_theorems.
Co-authored-by: Junyan Xu <junyanxu.math@gmail.com> Co-authored-by: Eric Wieser <wieser.eric@gmail.com> Co-authored-by: Junyan Xu <junyanxumath@gmail.com> Co-authored-by: Mario Carneiro <di.gama@gmail.com>
@@ -20,6 +20,10 @@ In this file we prove the primitive element theorem.
- `exists_primitive_element`: a finite separable extension `E / F` has a primitive element, i.e.
there is an `α : E` such that `F⟮α⟯ = (⊤ : Subalgebra F E)`.
+- `exists_primitive_element_iff_finite_intermediateField`: a finite extension `E / F` has a
+ primitive element if and only if there exist only finitely many intermediate fields between `E`
+ and `F`.
+
## Implementation notes
In declaration names, `primitive_element` abbreviates `adjoin_simple_eq_top`:
@@ -52,7 +56,7 @@ variable (F : Type*) [Field F] (E : Type*) [Field E] [Algebra F E]
/-- **Primitive element theorem** assuming E is finite. -/
theorem exists_primitive_element_of_finite_top [Finite E] : ∃ α : E, F⟮α⟯ = ⊤ := by
- obtain ⟨α, hα⟩ := @IsCyclic.exists_generator (Units E) _ _
+ obtain ⟨α, hα⟩ := @IsCyclic.exists_generator Eˣ _ _
use α
apply eq_top_iff.mpr
rintro x -
@@ -97,8 +101,8 @@ variable (F)
variable [Algebra 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.
+/-- 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 β
@@ -115,11 +119,7 @@ theorem primitive_element_inf_aux [IsSeparable F E] : ∃ γ : E, F⟮α, β⟯
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)
- exact fun x hx => by
- -- Porting note: was `by cases hx <;> cases hx <;> cases hx <;> assumption`
- cases' hx with hx hx
- · rwa [← hx] at α_in_Fγ
- · cases hx; norm_cast
+ rintro x (rfl | rfl) <;> assumption
· rw [adjoin_simple_le_iff]
have α_in_Fαβ : α ∈ F⟮α, β⟯ := subset_adjoin F {α, β} (Set.mem_insert α {β})
have β_in_Fαβ : β ∈ F⟮α, β⟯ := subset_adjoin F {α, β} (Set.mem_insert_of_mem α rfl)
@@ -170,22 +170,50 @@ theorem primitive_element_inf_aux [IsSeparable F E] : ∃ γ : E, F⟮α, β⟯
trans EuclideanDomain.gcd (?_ : E[X]) (?_ : E[X])
· dsimp only
convert (gcd_map (algebraMap F⟮γ⟯ E)).symm
- · simp [map_comp, Polynomial.map_map, ← IsScalarTower.algebraMap_eq]
+ · simp only [map_comp, Polynomial.map_map, ← IsScalarTower.algebraMap_eq, Polynomial.map_sub,
+ map_C, AdjoinSimple.algebraMap_gen, map_add, Polynomial.map_mul, map_X]
congr
#align field.primitive_element_inf_aux Field.primitive_element_inf_aux
+-- If `F` is infinite and `E/F` has only finitely many intermediate fields, then for any
+-- `α` and `β` in `E`, `F⟮α, β⟯` is generated by a single element.
+-- Marked as private since it's a special case of
+-- `exists_primitive_element_of_finite_intermediateField`.
+private theorem primitive_element_inf_aux_of_finite_intermediateField
+ [Finite (IntermediateField F E)] : ∃ γ : E, F⟮α, β⟯ = F⟮γ⟯ := by
+ let f : F → IntermediateField F E := fun x ↦ F⟮α + x • β⟯
+ obtain ⟨x, y, hneq, heq⟩ := Finite.exists_ne_map_eq_of_infinite f
+ use α + x • β
+ apply le_antisymm
+ · rw [adjoin_le_iff]
+ have αxβ_in_K : α + x • β ∈ F⟮α + x • β⟯ := mem_adjoin_simple_self F _
+ have αyβ_in_K : α + y • β ∈ F⟮α + y • β⟯ := mem_adjoin_simple_self F _
+ simp only [← heq] at αyβ_in_K
+ have β_in_K := sub_mem αxβ_in_K αyβ_in_K
+ rw [show (α + x • β) - (α + y • β) = (x - y) • β by rw [sub_smul]; abel1] at β_in_K
+ replace β_in_K := smul_mem _ β_in_K (x := (x - y)⁻¹)
+ rw [smul_smul, inv_mul_eq_div, div_self (sub_ne_zero.2 hneq), one_smul] at β_in_K
+ have α_in_K : α ∈ F⟮α + x • β⟯ := by
+ convert ← sub_mem αxβ_in_K (smul_mem _ β_in_K)
+ apply add_sub_cancel
+ rintro x (rfl | rfl) <;> assumption
+ · rw [adjoin_simple_le_iff]
+ have α_in_Fαβ : α ∈ F⟮α, β⟯ := subset_adjoin F {α, β} (Set.mem_insert α {β})
+ have β_in_Fαβ : β ∈ F⟮α, β⟯ := subset_adjoin F {α, β} (Set.mem_insert_of_mem α rfl)
+ exact F⟮α, β⟯.add_mem α_in_Fαβ (F⟮α, β⟯.smul_mem β_in_Fαβ)
+
end PrimitiveElementInf
variable (F E : Type*) [Field F] [Field E]
-variable [Algebra F E] [FiniteDimensional F E]
+variable [Algebra F E]
section SeparableAssumption
-variable [IsSeparable F E]
+variable [FiniteDimensional F E] [IsSeparable F E]
-/-- Primitive element theorem: a finite separable field extension `E` of `F` has a
- primitive element, i.e. there is an `α ∈ E` such that `F⟮α⟯ = (⊤ : Subalgebra F E)`.-/
+/-- **Primitive element theorem**: a finite separable field extension `E` of `F` has a
+ primitive element, i.e. there is an `α ∈ E` such that `F⟮α⟯ = (⊤ : Subalgebra F E)`. -/
theorem exists_primitive_element : ∃ α : E, F⟮α⟯ = ⊤ := by
rcases isEmpty_or_nonempty (Fintype F) with (F_inf | ⟨⟨F_finite⟩⟩)
· let P : IntermediateField F E → Prop := fun K => ∃ α : E, F⟮α⟯ = K
@@ -214,6 +242,110 @@ noncomputable def powerBasisOfFiniteOfSeparable : PowerBasis F E :=
end SeparableAssumption
+section FiniteIntermediateField
+
+-- TODO: show a more generalized result: [F⟮α⟯ : F⟮α ^ m⟯] = m if m > 0 and α transcendental.
+theorem isAlgebraic_of_adjoin_eq_adjoin {α : E} {m n : ℕ} (hneq : m ≠ n)
+ (heq : F⟮α ^ m⟯ = F⟮α ^ n⟯) : IsAlgebraic F α := by
+ wlog hmn : m < n
+ · exact this F E hneq.symm heq.symm (hneq.lt_or_lt.resolve_left hmn)
+ by_cases hm : m = 0
+ · rw [hm] at heq hmn
+ simp only [pow_zero, adjoin_one] at heq
+ obtain ⟨y, h⟩ := mem_bot.1 (heq.symm ▸ mem_adjoin_simple_self F (α ^ n))
+ refine ⟨X ^ n - C y, X_pow_sub_C_ne_zero hmn y, ?_⟩
+ simp only [map_sub, map_pow, aeval_X, aeval_C, h, sub_self]
+ replace hm : 0 < m := Nat.pos_of_ne_zero hm
+ obtain ⟨r, s, h⟩ := (mem_adjoin_simple_iff F _).1 (heq ▸ mem_adjoin_simple_self F (α ^ m))
+ by_cases hzero : aeval (α ^ n) s = 0
+ · simp only [hzero, div_zero, pow_eq_zero_iff hm] at h
+ exact h.symm ▸ isAlgebraic_zero
+ · rw [eq_div_iff hzero, ← sub_eq_zero] at h
+ replace hzero : s ≠ 0 := by rintro rfl; simp only [map_zero] at hzero
+ let f : F[X] := X ^ m * expand F n s - expand F n r
+ refine ⟨f, ?_, ?_⟩
+ · have : f.coeff (n * s.natDegree + m) ≠ 0 := by
+ have hn : 0 < n := by linarith only [hm, hmn]
+ have hndvd : ¬ n ∣ n * s.natDegree + m := by
+ rw [← Nat.dvd_add_iff_right (n.dvd_mul_right s.natDegree)]
+ exact Nat.not_dvd_of_pos_of_lt hm hmn
+ simp only [coeff_sub, coeff_X_pow_mul, s.coeff_expand_mul' hn, coeff_natDegree,
+ coeff_expand hn r, hndvd, ite_false, sub_zero]
+ exact leadingCoeff_ne_zero.2 hzero
+ intro h
+ simp only [h, coeff_zero, ne_eq] at this
+ · simp only [map_sub, map_mul, map_pow, aeval_X, expand_aeval, h]
+
+theorem isAlgebraic_of_finite_intermediateField
+ [Finite (IntermediateField F E)] : Algebra.IsAlgebraic F E := fun α ↦
+ have ⟨_m, _n, hneq, heq⟩ := Finite.exists_ne_map_eq_of_infinite fun n ↦ F⟮α ^ n⟯
+ isAlgebraic_of_adjoin_eq_adjoin F E hneq heq
+
+theorem finiteDimensional_of_finite_intermediateField
+ [Finite (IntermediateField F E)] : FiniteDimensional F E := by
+ let IF := { K : IntermediateField F E // ∃ x, K = F⟮x⟯ }
+ haveI : ∀ K : IF, FiniteDimensional F K.1 := fun ⟨_, x, rfl⟩ ↦ adjoin.finiteDimensional <|
+ isAlgebraic_iff_isIntegral.1 (isAlgebraic_of_finite_intermediateField F E x)
+ have hfin := finiteDimensional_iSup_of_finite (t := fun K : IF ↦ K.1)
+ have htop : ⨆ K : IF, K.1 = ⊤ := le_top.antisymm fun x _ ↦
+ le_iSup (fun K : IF ↦ K.1) ⟨F⟮x⟯, x, rfl⟩ <| mem_adjoin_simple_self F x
+ rw [htop] at hfin
+ exact topEquiv.toLinearEquiv.finiteDimensional
+
+theorem exists_primitive_element_of_finite_intermediateField
+ [Finite (IntermediateField F E)] (K : IntermediateField F E) : ∃ α : E, F⟮α⟯ = K := by
+ haveI := finiteDimensional_of_finite_intermediateField F E
+ rcases finite_or_infinite F with (_ | _)
+ · obtain ⟨α, h⟩ := exists_primitive_element_of_finite_bot F K
+ exact ⟨α, by simpa only [lift_adjoin_simple, lift_top] using congr_arg lift h⟩
+ · apply induction_on_adjoin (fun K ↦ ∃ α : E, F⟮α⟯ = K) ⟨0, adjoin_zero⟩
+ rintro K β ⟨α, rfl⟩
+ simp_rw [adjoin_simple_adjoin_simple, eq_comm]
+ exact primitive_element_inf_aux_of_finite_intermediateField F α β
+
+theorem finiteDimensional_of_exists_primitive_element (halg : Algebra.IsAlgebraic F E)
+ (h : ∃ α : E, F⟮α⟯ = ⊤) : FiniteDimensional F E := by
+ obtain ⟨α, hprim⟩ := h
+ have hfin := adjoin.finiteDimensional <| isAlgebraic_iff_isIntegral.1 (halg α)
+ rw [hprim] at hfin
+ exact topEquiv.toLinearEquiv.finiteDimensional
+
+-- A finite simple extension has only finitely many intermediate fields
+theorem finite_intermediateField_of_exists_primitive_element (halg : Algebra.IsAlgebraic F E)
+ (h : ∃ α : E, F⟮α⟯ = ⊤) : Finite (IntermediateField F E) := by
+ haveI := finiteDimensional_of_exists_primitive_element F E halg h
+ obtain ⟨α, hprim⟩ := h
+ -- Let `f` be the minimal polynomial of `α ∈ E` over `F`
+ let f : F[X] := minpoly F α
+ let G := { g : E[X] // g.Monic ∧ g ∣ f.map (algebraMap F E) }
+ -- Then `f` has only finitely many monic factors
+ have hfin : Finite G := @Finite.of_fintype _ <| fintypeSubtypeMonicDvd
+ (f.map (algebraMap F E)) <| map_ne_zero (minpoly.ne_zero_of_finite F α)
+ -- If `K` is an intermediate field of `E/F`, let `g` be the minimal polynomial of `α` over `K`
+ -- which is a monic factor of `f`
+ let g : IntermediateField F E → G := fun K ↦
+ ⟨(minpoly K α).map (algebraMap K E), (minpoly.monic <| isIntegral_of_finite K α).map _, by
+ convert Polynomial.map_dvd (algebraMap K E) (minpoly.dvd_map_of_isScalarTower F K α)
+ rw [Polynomial.map_map]; rfl⟩
+ -- The map `K ↦ g` is injective
+ have hinj : Function.Injective g := fun K K' heq ↦ by
+ rw [Subtype.mk.injEq] at heq
+ apply_fun fun f : E[X] ↦ adjoin F (f.frange : Set E) at heq
+ simpa only [adjoin_minpoly_coeff_of_exists_primitive_element F hprim] using heq
+ -- Therefore there are only finitely many intermediate fields
+ exact Finite.of_injective g hinj
+
+/-- **Steinitz theorem**: an algebraic extension `E` of `F` has a
+ primitive element (i.e. there is an `α ∈ E` such that `F⟮α⟯ = (⊤ : Subalgebra F E)`)
+ if and only if there exist only finitely many intermediate fields between `E` and `F`. -/
+theorem exists_primitive_element_iff_finite_intermediateField :
+ (Algebra.IsAlgebraic F E ∧ ∃ α : E, F⟮α⟯ = ⊤) ↔ Finite (IntermediateField F E) :=
+ ⟨fun ⟨halg, h⟩ ↦ finite_intermediateField_of_exists_primitive_element F E halg h,
+ fun _ ↦ ⟨isAlgebraic_of_finite_intermediateField F E,
+ exists_primitive_element_of_finite_intermediateField F E _⟩⟩
+
+end FiniteIntermediateField
+
end Field
@[simp]
Type _
and Sort _
(#6499)
We remove all possible occurences of Type _
and Sort _
in favor of Type*
and Sort*
.
This has nice performance benefits.
@@ -45,7 +45,7 @@ namespace Field
section PrimitiveElementFinite
-variable (F : Type _) [Field F] (E : Type _) [Field E] [Algebra F E]
+variable (F : Type*) [Field F] (E : Type*) [Field E] [Algebra F E]
/-! ### Primitive element theorem for finite fields -/
@@ -79,7 +79,7 @@ end PrimitiveElementFinite
section PrimitiveElementInf
-variable {F : Type _} [Field F] [Infinite F] {E : Type _} [Field E] (ϕ : F →+* E) (α β : E)
+variable {F : Type*} [Field F] [Infinite F] {E : Type*} [Field E] (ϕ : F →+* E) (α β : E)
theorem primitive_element_inf_aux_exists_c (f g : F[X]) :
∃ c : F, ∀ α' ∈ (f.map ϕ).roots, ∀ β' ∈ (g.map ϕ).roots, -(α' - α) / (β' - β) ≠ ϕ c := by
@@ -176,7 +176,7 @@ theorem primitive_element_inf_aux [IsSeparable F E] : ∃ γ : E, F⟮α, β⟯
end PrimitiveElementInf
-variable (F E : Type _) [Field F] [Field E]
+variable (F E : Type*) [Field F] [Field E]
variable [Algebra F E] [FiniteDimensional F E]
@@ -217,7 +217,7 @@ end SeparableAssumption
end Field
@[simp]
-theorem AlgHom.card (F E K : Type _) [Field F] [Field E] [Field K] [IsAlgClosed K] [Algebra F E]
+theorem AlgHom.card (F E K : Type*) [Field F] [Field E] [Field K] [IsAlgClosed K] [Algebra F E]
[FiniteDimensional F E] [IsSeparable F E] [Algebra F K] :
Fintype.card (E →ₐ[F] K) = finrank F E := by
convert (AlgHom.card_of_powerBasis (L := K) (Field.powerBasisOfFiniteOfSeparable F E)
@@ -194,7 +194,7 @@ theorem exists_primitive_element : ∃ α : E, F⟮α⟯ = ⊤ := by
intro K β hK
cases' hK with α hK
rw [← hK, adjoin_simple_adjoin_simple]
- haveI : Infinite F := is_empty_fintype.mp F_inf
+ haveI : Infinite F := isEmpty_fintype.mp F_inf
cases' primitive_element_inf_aux F α β with γ hγ
exact ⟨γ, hγ.symm⟩
exact induction_on_adjoin P base ih ⊤
@@ -2,17 +2,14 @@
Copyright (c) 2020 Thomas Browning, Patrick Lutz. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Thomas Browning, Patrick Lutz
-
-! This file was ported from Lean 3 source module field_theory.primitive_element
-! leanprover-community/mathlib commit df76f43357840485b9d04ed5dee5ab115d420e87
-! Please do not edit these lines, except to modify the commit id
-! if you have ported upstream changes.
-/
import Mathlib.FieldTheory.SplittingField.Construction
import Mathlib.FieldTheory.IsAlgClosed.Basic
import Mathlib.FieldTheory.Separable
import Mathlib.RingTheory.IntegralDomain
+#align_import field_theory.primitive_element from "leanprover-community/mathlib"@"df76f43357840485b9d04ed5dee5ab115d420e87"
+
/-!
# Primitive Element Theorem
The unported dependencies are