Skip to content

Commit 4a0fab5

Browse files
feat(Analysis/Normed): Krasner's lemma (leanprover-community#26390)
This PR continues the work from leanprover-community#18444. Original PR: leanprover-community#18444 Co-authored-by: Jiedong Jiang <emailboxofjjd@163.com> Co-authored-by: jjdishere <emailboxofjjd@163.com> Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
1 parent ca2cb3b commit 4a0fab5

File tree

8 files changed

+252
-3
lines changed

8 files changed

+252
-3
lines changed

Mathlib.lean

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1987,6 +1987,7 @@ public import Mathlib.Analysis.Normed.Algebra.Unitization
19871987
public import Mathlib.Analysis.Normed.Algebra.UnitizationL1
19881988
public import Mathlib.Analysis.Normed.Field.Basic
19891989
public import Mathlib.Analysis.Normed.Field.Instances
1990+
public import Mathlib.Analysis.Normed.Field.Krasner
19901991
public import Mathlib.Analysis.Normed.Field.Lemmas
19911992
public import Mathlib.Analysis.Normed.Field.ProperSpace
19921993
public import Mathlib.Analysis.Normed.Field.TransferInstance

Mathlib/Algebra/Field/Subfield/Basic.lean

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,13 @@ theorem mem_map {f : K →+* L} {s : Subfield K} {y : L} : y ∈ s.map f ↔ ∃
160160
unfold map
161161
simp only [mem_mk, Subring.mem_map, mem_toSubring]
162162

163+
-- Higher priority to apply before `mem_map`.
164+
@[simp 1100]
165+
theorem map_mem_map (f : K →+* L) {s : Subfield K} {x : K} : f x ∈ s.map f ↔ x ∈ s :=
166+
calc
167+
_ ↔ f x ∈ (s.map f : Set L) := Iff.rfl
168+
_ ↔ _ := by simp [Function.Injective.mem_set_image (f := f) f.injective]
169+
163170
theorem map_map (g : L →+* M) (f : K →+* L) : (s.map f).map g = s.map (g.comp f) :=
164171
SetLike.ext' <| Set.image_image _ _ _
165172

Mathlib/Analysis/Normed/Algebra/Basic.lean

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,19 @@ normed algebra, character space, continuous functional calculus
3030

3131
@[expose] public section
3232

33+
namespace IntermediateField
34+
35+
variable {K L : Type*} [NontriviallyNormedField K] [NormedField L] [NormedAlgebra K L]
36+
37+
set_option backward.isDefEq.respectTransparency false in
38+
instance (F : IntermediateField K L) : NontriviallyNormedField F where
39+
__ := SubfieldClass.toNormedField F
40+
non_trivial := by
41+
obtain ⟨k, hk⟩ := @NontriviallyNormedField.non_trivial K _
42+
use algebraMap K F k
43+
simp [hk]
44+
45+
end IntermediateField
3346

3447
variable {𝕜 : Type*} {A : Type*}
3548

Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
/-
2+
Copyright (c) 2025 Jiedong Jiang. All rights reserved.
3+
Released under Apache 2.0 license as described in the file LICENSE.
4+
Authors: Jiedong Jiang
5+
-/
6+
module
7+
8+
public import Mathlib.Analysis.Normed.Algebra.Ultra
9+
public import Mathlib.Analysis.Normed.Unbundled.SpectralNorm
10+
public import Mathlib.FieldTheory.Minpoly.IsConjRoot
11+
public import Mathlib.FieldTheory.SeparableDegree
12+
public import Mathlib.Analysis.Normed.Algebra.Basic
13+
14+
/-!
15+
# Krasner's Lemma
16+
17+
In this file, we prove Krasner's lemma.
18+
19+
## Main definitions
20+
21+
* `IsKrasner K L` : Given a field extension `L / K` where `L` is a normed field,
22+
`IsKrasner K L` is the abstraction of the conclusion of Krasner's lemma. That is, `IsKrasner K L`
23+
means that given two elements `x y : L`, such that `x` is separable over `K`, all conjugate roots
24+
of `x` live in `L`, `y` is integral over `K`, and the distance between `x` and `y` is less than
25+
the distance between `x` and any other conjugate root of `x`, then `x` is in the field
26+
generated by `K` and `y`.
27+
28+
## Main results
29+
30+
* `IsKrasner.of_complete` : If `K` is a complete normed field, such that
31+
the norm of `L` extends the norm on `K`, then `IsKrasner K L` holds for every
32+
algebraic extension `L` over `K`. This implies the classical Krasner's lemma by taking `L` as the
33+
separable closure of `K`.
34+
35+
## Reference
36+
37+
For the classical statement of Krasner's lemma, please see the
38+
[wikipedia page](https://en.wikipedia.org/wiki/Krasner%27s_lemma).
39+
40+
## Tags
41+
Krasner's lemma, normed field
42+
-/
43+
44+
@[expose] public section
45+
46+
open IntermediateField
47+
48+
variable (K L : Type*) [NormedField L]
49+
50+
/--
51+
Given a field extension `L / K` where `L` is a normed field, `IsKrasner K L` is the abstraction
52+
of the conclusion of Krasner's lemma. That is, `IsKrasner K L` means that given two elements
53+
`x y : L`, such that `x` is separable over `K`, all conjugate roots of `x` live in `L`,
54+
`y` is integral over `K`, and the distance between `x` and `y` is less than the distance between
55+
`x` and any other conjugate root of `x`, then `x` is in the field generated by `K` and `y`.
56+
-/
57+
class IsKrasner [Field K] [Algebra K L] : Prop where
58+
krasner' {x y : L} : IsSeparable K x → ((minpoly K x).map (algebraMap K L)).Splits →
59+
IsIntegral K y → (∀ x' : L, IsConjRoot K x x' → x ≠ x' → ‖x - y‖ < ‖x - x'‖) → x ∈ K⟮y⟯
60+
61+
namespace IsKrasner
62+
63+
variable {K L} in
64+
theorem krasner [Field K] [Algebra K L]
65+
[IsKrasner K L] {x y : L} (hx : (minpoly K x).Separable)
66+
(sp : ((minpoly K x).map (algebraMap K L)).Splits) (hy : IsIntegral K y)
67+
(h : (∀ x' : L, IsConjRoot K x x' → x ≠ x' → ‖x - y‖ < ‖x - x'‖)) : x ∈ K⟮y⟯ :=
68+
IsKrasner.krasner' hx sp hy h
69+
70+
variable [NontriviallyNormedField K] [CompleteSpace K] [IsUltrametricDist K]
71+
[NormedAlgebra K L] [Algebra.IsAlgebraic K L]
72+
73+
set_option backward.isDefEq.respectTransparency false in
74+
/-- Krasner's lemma assuming `Normal K L`. -/
75+
theorem of_completeSpace_of_normal [Normal K L] : IsKrasner K L where
76+
krasner' {x} {y} xsep sp yint kr := by
77+
let z := x - y
78+
have := IntermediateField.adjoin.finiteDimensional yint
79+
have : IsUltrametricDist L := IsUltrametricDist.of_normedAlgebra K
80+
let y' : K⟮y⟯ := IntermediateField.AdjoinSimple.gen K y
81+
have zsep : IsSeparable K⟮y⟯ z :=
82+
Field.isSeparable_sub (IsSeparable.tower_top K⟮y⟯ xsep) (isSeparable_algebraMap y')
83+
-- It suffices to show that `z = x - y ∈ K⟮y⟯`.
84+
suffices z ∈ K⟮y⟯ by simpa [z, y'] using add_mem this y'.2
85+
have : z ∈ K⟮y⟯ ↔ z ∈ (⊥ : Subalgebra K⟮y⟯ L) := by simp [Algebra.mem_bot]
86+
rw [this]
87+
-- Suppose not, then there exists nontrivial Galois conjugates `z'` of `z` over `K⟮y⟯` in `L`.
88+
by_contra hz
89+
obtain ⟨z', hne, h1⟩ := (notMem_iff_exists_ne_and_isConjRoot zsep
90+
(minpoly_sub_algebraMap_splits y' (IsIntegral.minpoly_splits_tower_top
91+
xsep.isIntegral sp))).mp hz
92+
obtain ⟨σ, hσ⟩ := isConjRoot_iff_exists_algEquiv.mp h1
93+
apply_fun σ.symm at hσ
94+
simp only [AlgEquiv.symm_apply_apply] at hσ
95+
-- However, `‖z - z'‖ ≤ max ‖z‖ ‖z'‖ = ‖z‖ = ‖x - y‖ < ‖y - y'‖ = ‖z - z'‖`, where `y' = x - z`.
96+
-- This is a contradiction.
97+
have : ‖z - z'‖ < ‖z - z'‖ :=
98+
calc
99+
_ ≤ max ‖z‖ ‖z'‖ := by
100+
simpa [norm_neg, sub_eq_add_neg] using (IsUltrametricDist.norm_add_le_max z (- z'))
101+
_ ≤ ‖x - y‖ := by
102+
simp only [NormedAlgebra.norm_eq_spectralNorm K, hσ, sup_le_iff]
103+
rw [← AlgEquiv.restrictScalars_apply K,
104+
← spectralNorm_eq_of_equiv (σ.symm.restrictScalars K)]
105+
simp [z]
106+
_ < ‖x - (z' + y)‖ := by
107+
apply kr (z' + y)
108+
· apply IsConjRoot.of_isScalarTower (L := K⟮y⟯) xsep.isIntegral
109+
simpa [z, y'] using IsConjRoot.add_algebraMap y' h1
110+
· simpa [z, sub_eq_iff_eq_add] using hne
111+
_ = ‖z - z'‖ := by congr 1; ring
112+
simp [lt_self_iff_false] at this
113+
114+
set_option backward.isDefEq.respectTransparency false in
115+
/--
116+
If `K` is a complete nontrivially normed field and `L` is an algebraic extension of `K`
117+
such that the norm of `L` extends the norm on `K`, then `IsKrasner K L` holds.
118+
This corresponds to the classical Krasner's lemma.
119+
-/
120+
instance of_completeSpace : IsKrasner K L where
121+
krasner' {x} {y} xsep sp yint kr := by
122+
-- Reduce to the case `L = algebraic closure of K` to apply the previous lemma.
123+
let C := AlgebraicClosure K
124+
let : NontriviallyNormedField C := spectralNorm.nontriviallyNormedField K C
125+
let : NormedAlgebra K C := spectralNorm.normedAlgebra K C
126+
let iL : L →ₐ[K] C := IsAlgClosed.lift
127+
algebraize [iL.toRingHom]
128+
let : NormedAlgebra L C := spectralNorm.normedAlgebra' K L C
129+
let := IsKrasner.of_completeSpace_of_normal K C
130+
-- The norm on `L` is compatible with the norm on the algebraic closure of `K`,
131+
-- this gives the result.
132+
have norm_iL (x : L) : ‖iL x‖ = ‖x‖ := norm_algebraMap' _ _
133+
suffices this : iL x ∈ K⟮iL y⟯ by
134+
simpa [← Set.image_singleton, ← IntermediateField.adjoin_map] using this
135+
refine IsKrasner.krasner ((xsep.map _ iL.injective).of_dvd dvd_rfl) ?_ (yint.map iL) ?_
136+
· exact Polynomial.Splits.of_dvd (sp.of_isScalarTower C)
137+
(Polynomial.map_ne_zero (minpoly.ne_zero xsep.isIntegral))
138+
(Polynomial.map_dvd _ (by simpa using minpoly.dvd_map_of_isScalarTower' K K C x))
139+
· intros xC' hx' hne
140+
have : xC' ∈ (minpoly K x).rootSet C := by
141+
rwa [isConjRoot_iff_mem_minpoly_rootSet (xsep.isIntegral.map _),
142+
minpoly.algHom_eq iL iL.injective x] at hx'
143+
simp only [← sp.image_rootSet iL, Set.mem_image] at this
144+
obtain ⟨c, hc, rfl⟩ := this
145+
rw [← isConjRoot_iff_mem_minpoly_rootSet xsep.isIntegral] at hc
146+
simpa [norm_iL, ← map_sub] using kr c hc (fun h ↦ (iff_false_intro hne).mp (congrArg iL h))
147+
148+
end IsKrasner

Mathlib/Analysis/Normed/Unbundled/AlgebraNorm.lean

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,8 +179,35 @@ theorem extends_norm' (f : MulAlgebraNorm R S) (a : R) : f (a • (1 : S)) = ‖
179179
theorem extends_norm (f : MulAlgebraNorm R S) (a : R) : f (algebraMap R S a) = ‖a‖ := by
180180
rw [Algebra.algebraMap_eq_smul_one]; exact extends_norm' _ _
181181

182+
/-- The algebra norm underlying an multiplicative algebra norm. -/
183+
def toAlgebraNorm (f : MulAlgebraNorm R S) : AlgebraNorm R S where
184+
__ := f
185+
mul_le' _ _ := (f.map_mul' _ _).le
186+
187+
instance instCoeAlgebraNorm : Coe (MulAlgebraNorm R S) (AlgebraNorm R S) := ⟨toAlgebraNorm⟩
188+
189+
@[simp]
190+
lemma coe_AlgebraNorm (f : MulAlgebraNorm R S) : ⇑(f : AlgebraNorm R S) = ⇑f := rfl
191+
182192
end MulAlgebraNorm
183193

194+
namespace NormedAlgebra
195+
196+
variable (K L : Type*) [NormedField K] [NormedField L] [NormedAlgebra K L]
197+
198+
/-- Given a normed field extension `L / K`, the norm on `L` is a multiplicative `K`-algebra norm. -/
199+
def toMulAlgebraNorm : MulAlgebraNorm K L where
200+
__ := NormedField.toMulRingNorm L
201+
smul' r x := by
202+
simp only [Algebra.smul_def, AddGroupSeminorm.toFun_eq_coe, MulRingSeminorm.toFun_eq_coe,
203+
map_mul, mul_eq_mul_right_iff, map_eq_zero]
204+
exact Or.inl <| norm_algebraMap' L r
205+
206+
@[simp]
207+
lemma toMulAlgebraNorm_apply (x : L) : toMulAlgebraNorm K L x = ‖x‖ := rfl
208+
209+
end NormedAlgebra
210+
184211
namespace MulRingNorm
185212

186213
variable {R : Type*} [NonAssocRing R]

Mathlib/Analysis/Normed/Unbundled/SpectralNorm.lean

Lines changed: 40 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -800,6 +800,16 @@ theorem spectralNorm_unique_field_norm_ext [CompleteSpace K]
800800
have hgx : f x = g x := rfl
801801
rw [hgx, spectralNorm_unique hg_pow, spectralAlgNorm_def]
802802

803+
variable (K) in
804+
/-- If `K` is a field complete with respect to a nontrivial nonarchimedean multiplicative norm and
805+
`L/K` is an algebraic normed field extension, then the norm on `L` coincides with the spectral
806+
norm. -/
807+
theorem NormedAlgebra.norm_eq_spectralNorm {L : Type*} [NormedField L] [NormedAlgebra K L]
808+
[Algebra.IsAlgebraic K L] [CompleteSpace K] (x : L) : ‖x‖ = spectralNorm K L x := by
809+
rw [← toMulAlgebraNorm_apply K L x, ← spectralAlgNorm_def, ← MulAlgebraNorm.coe_AlgebraNorm,
810+
spectralNorm_unique (f := (toMulAlgebraNorm K L).toAlgebraNorm)
811+
(MulRingNorm.isPowMul (toMulAlgebraNorm K L).toMulRingNorm)]
812+
803813
/-- Given a nonzero `x : L`, and assuming that `(spectralAlgNorm h_alg hna) 1 ≤ 1`, this is
804814
the real-valued function sending `y ∈ L` to the limit of `(f (y * x^n))/((f x)^n)`,
805815
regarded as an algebra norm. -/
@@ -881,24 +891,51 @@ def nontriviallyNormedField [CompleteSpace K] : NontriviallyNormedField L where
881891
let ⟨x, hx⟩ := NontriviallyNormedField.non_trivial (α := K)
882892
⟨algebraMap K L x, hx.trans_eq <| (spectralNorm_extends _).symm⟩
883893

884-
/-- `L` with the spectral norm is a `normed_add_comm_group`. -/
894+
/-- `L` with the spectral norm is a `SeminormedRing`. -/
895+
def seminormedRing : SeminormedRing L := by
896+
letI : NormedField L := normedField K L
897+
infer_instance
898+
899+
/-- `L` with the spectral norm is a `NormedAddCommGroup`. -/
885900
def normedAddCommGroup : NormedAddCommGroup L := by
886901
haveI : NormedField L := normedField K L
887902
infer_instance
888903

889-
/-- `L` with the spectral norm is a `seminormed_add_comm_group`. -/
904+
/-- `L` with the spectral norm is a `SeminormedAddCommGroup`. -/
890905
def seminormedAddCommGroup : SeminormedAddCommGroup L := by
891906
have : NormedField L := normedField K L
892907
infer_instance
893908

894-
/-- `L` with the spectral norm is a `normed_space` over `K`. -/
909+
/-- `L` with the spectral norm is a `NormedSpace` over `K`. -/
895910
def normedSpace : @NormedSpace K L _ (seminormedAddCommGroup K L) :=
896911
letI _ := seminormedAddCommGroup K L
897912
{ (inferInstance : Module K L) with
898913
norm_smul_le r x := by
899914
change spectralAlgNorm K L (r • x) ≤ ‖r‖ * spectralAlgNorm K L x
900915
exact le_of_eq (map_smul_eq_mul _ _ _) }
901916

917+
/-- `L` with the spectral norm is a `NormedAlgebra` over `K`. -/
918+
def normedAlgebra :
919+
@NormedAlgebra K L _ (seminormedRing K L) :=
920+
letI _ := normedField K L
921+
{ normedSpace K L, (inferInstance : Algebra K L) with }
922+
923+
set_option backward.isDefEq.respectTransparency false in
924+
/-- `L` with the spectral norm is a `NormedAlgebra` over any intermedate `E`
925+
that is a normed algebra over `K`. -/
926+
def normedAlgebra' (E L : Type*) [Field L] [Algebra K L] [Algebra.IsAlgebraic K L] [NormedField E]
927+
[NormedAlgebra K E] [Algebra E L] [IsScalarTower K E L] :
928+
@NormedAlgebra E L _ (seminormedRing K L) :=
929+
letI _ := normedField K L
930+
letI _ := normedAlgebra K L
931+
letI _ := Algebra.IsAlgebraic.tower_bot K E L
932+
{ (inferInstance : Algebra E L) with
933+
norm_smul_le _ _ := by
934+
apply le_of_eq
935+
simp only [Algebra.smul_def, norm_mul, mul_eq_mul_right_iff, _root_.norm_eq_zero]
936+
simp only [NormedAlgebra.norm_eq_spectralNorm K]
937+
exact Or.inl <| (spectralNorm.eq_of_tower _).symm }
938+
902939
/-- The metric space structure on `L` induced by the spectral norm. -/
903940
def metricSpace : MetricSpace L := (normedField K L).toMetricSpace
904941

Mathlib/FieldTheory/IntermediateField/Basic.lean

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -482,6 +482,18 @@ theorem toSubfield_map (f : L →ₐ[K] L') : (S.map f).toSubfield = S.toSubfiel
482482
theorem map_id : S.map (AlgHom.id K L) = S :=
483483
SetLike.coe_injective <| Set.image_id _
484484

485+
@[simp]
486+
lemma mem_map {f : L →ₐ[K] L'} {y : L'} : y ∈ S.map f ↔ ∃ x ∈ S, f x = y :=
487+
Set.mem_image f S y
488+
489+
-- Higher priority to apply before `mem_map`.
490+
@[simp 1100]
491+
theorem map_mem_map (f : L →ₐ[K] L') {x : L} :
492+
f x ∈ map f S ↔ x ∈ S :=
493+
calc
494+
_ ↔ f x ∈ (map f S : Set L') := Iff.rfl
495+
_ ↔ _ := by simp [Function.Injective.mem_set_image (f := f) f.injective]
496+
485497
theorem map_map {K L₁ L₂ L₃ : Type*} [Field K] [Field L₁] [Algebra K L₁] [Field L₂] [Algebra K L₂]
486498
[Field L₃] [Algebra K L₃] (E : IntermediateField K L₁) (f : L₁ →ₐ[K] L₂) (g : L₂ →ₐ[K] L₃) :
487499
(E.map f).map g = E.map (g.comp f) :=

Mathlib/FieldTheory/Normal/Defs.lean

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,10 @@ theorem Normal.tower_top_of_normal [h : Normal F E] : Normal K E :=
7171
exact ⟨hx.tower_top, hhx.of_dvd (map_ne_zero (map_ne_zero (minpoly.ne_zero hx)))
7272
((map_dvd_map' _).mpr (minpoly.dvd_map_of_isScalarTower F K x))⟩
7373

74+
set_option backward.isDefEq.respectTransparency false in
75+
instance IntermediateField.normal (K : IntermediateField F E) [Normal F E] : Normal K E :=
76+
Normal.tower_top_of_normal F K E
77+
7478
theorem AlgHom.normal_bijective [h : Normal F E] (ϕ : E →ₐ[F] K) : Function.Bijective ϕ :=
7579
h.toIsAlgebraic.bijective_of_isScalarTower' ϕ
7680

0 commit comments

Comments
 (0)