Skip to content

Commit 75bcb18

Browse files
committed
chore: refactor perfect rings / fields (#6182)
The main changes are: - we replace the data-bearing `PerfectRing` typeclass with a `Prop`-valued (non-constructive) version, - we introduce a new typeclass `PerfectField`, - we add a proof that a perfect field of positive characteristic has surjective Frobenius map, - we add some basic facts such as perfection of finite rings / fields and products of perfect rings.
1 parent d1cd996 commit 75bcb18

10 files changed

Lines changed: 271 additions & 209 deletions

File tree

Mathlib.lean

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1901,6 +1901,7 @@ import Mathlib.FieldTheory.Minpoly.IsIntegrallyClosed
19011901
import Mathlib.FieldTheory.MvPolynomial
19021902
import Mathlib.FieldTheory.Normal
19031903
import Mathlib.FieldTheory.NormalClosure
1904+
import Mathlib.FieldTheory.Perfect
19041905
import Mathlib.FieldTheory.PerfectClosure
19051906
import Mathlib.FieldTheory.PolynomialGaloisGroup
19061907
import Mathlib.FieldTheory.PrimitiveElement

Mathlib/Algebra/Hom/Iterate.lean

Lines changed: 6 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,12 @@ theorem hom_coe_pow {F : Type*} [Monoid F] (c : F → M → M) (h1 : c 1 = id)
3939
| n + 1 => by rw [pow_succ, iterate_succ', hmul, hom_coe_pow c h1 hmul f n]
4040
#align hom_coe_pow hom_coe_pow
4141

42+
@[to_additive (attr := simp)]
43+
theorem iterate_map_mul {M F : Type _} [MulOneClass M]
44+
(f : F) (n : ℕ) (x y : M) [MulHomClass F M M] :
45+
f^[n] (x * y) = f^[n] x * f^[n] y :=
46+
Function.Semiconj₂.iterate (map_mul f) n x y
47+
4248
namespace MonoidHom
4349

4450
section
@@ -51,12 +57,6 @@ theorem iterate_map_one (f : M →* M) (n : ℕ) : f^[n] 1 = 1 :=
5157
#align monoid_hom.iterate_map_one MonoidHom.iterate_map_one
5258
#align add_monoid_hom.iterate_map_zero AddMonoidHom.iterate_map_zero
5359

54-
@[to_additive (attr := simp)]
55-
theorem iterate_map_mul (f : M →* M) (n : ℕ) (x y) : f^[n] (x * y) = f^[n] x * f^[n] y :=
56-
Semiconj₂.iterate f.map_mul n x y
57-
#align monoid_hom.iterate_map_mul MonoidHom.iterate_map_mul
58-
#align add_monoid_hom.iterate_map_add AddMonoidHom.iterate_map_add
59-
6060
end
6161

6262
variable [Monoid M] [Monoid N] [Group G] [Group H]
@@ -133,14 +133,6 @@ theorem iterate_map_zero : f^[n] 0 = 0 :=
133133
f.toAddMonoidHom.iterate_map_zero n
134134
#align ring_hom.iterate_map_zero RingHom.iterate_map_zero
135135

136-
theorem iterate_map_add : f^[n] (x + y) = f^[n] x + f^[n] y :=
137-
f.toAddMonoidHom.iterate_map_add n x y
138-
#align ring_hom.iterate_map_add RingHom.iterate_map_add
139-
140-
theorem iterate_map_mul : f^[n] (x * y) = f^[n] x * f^[n] y :=
141-
f.toMonoidHom.iterate_map_mul n x y
142-
#align ring_hom.iterate_map_mul RingHom.iterate_map_mul
143-
144136
theorem iterate_map_pow (a) (n m : ℕ) : f^[n] (a ^ m) = f^[n] a ^ m :=
145137
f.toMonoidHom.iterate_map_pow n a m
146138
#align ring_hom.iterate_map_pow RingHom.iterate_map_pow

Mathlib/Data/Polynomial/Derivative.lean

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -160,12 +160,6 @@ theorem derivative_X_add_C (c : R) : derivative (X + C c) = 1 := by
160160
set_option linter.uppercaseLean3 false in
161161
#align polynomial.derivative_X_add_C Polynomial.derivative_X_add_C
162162

163-
@[simp]
164-
theorem iterate_derivative_add {f g : R[X]} {k : ℕ} :
165-
derivative^[k] (f + g) = derivative^[k] f + derivative^[k] g :=
166-
derivative.toAddMonoidHom.iterate_map_add _ _ _
167-
#align polynomial.iterate_derivative_add Polynomial.iterate_derivative_add
168-
169163
--Porting note: removed `simp`: `simp` can prove it.
170164
theorem derivative_sum {s : Finset ι} {f : ι → R[X]} :
171165
derivative (∑ b in s, f b) = ∑ b in s, derivative (f b) :=

Mathlib/Data/Set/Pointwise/Iterate.lean

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,6 @@ theorem smul_eq_self_of_preimage_zpow_eq_self {G : Type*} [CommGroup G] {n : ℤ
4141
change (zpowGroupHom n)^[j] (g' * y) ∈ s
4242
replace hg' : (zpowGroupHom n)^[j] g' = 1
4343
· simpa [zpowGroupHom]
44-
rwa [MonoidHom.iterate_map_mul, hg', one_mul]
44+
rwa [iterate_map_mul, hg', one_mul]
4545
#align smul_eq_self_of_preimage_zpow_eq_self smul_eq_self_of_preimage_zpow_eq_self
4646
#align vadd_eq_self_of_preimage_zsmul_eq_self vadd_eq_self_of_preimage_zsmul_eq_self

Mathlib/FieldTheory/IsAlgClosed/Basic.lean

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE.
44
Authors: Kenny Lau
55
-/
66
import Mathlib.FieldTheory.Normal
7-
import Mathlib.FieldTheory.PerfectClosure
7+
import Mathlib.FieldTheory.Perfect
88
import Mathlib.RingTheory.Localization.Integral
99

1010
#align_import field_theory.is_alg_closed.basic from "leanprover-community/mathlib"@"00f91228655eecdcd3ac97a7fd8dbcb139fe990a"

Mathlib/FieldTheory/Perfect.lean

Lines changed: 181 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,181 @@
1+
/-
2+
Copyright (c) 2023 Oliver Nash. All rights reserved.
3+
Released under Apache 2.0 license as described in the file LICENSE.
4+
Authors: Oliver Nash
5+
-/
6+
import Mathlib.FieldTheory.Separable
7+
import Mathlib.FieldTheory.SplittingField.Construction
8+
9+
/-!
10+
11+
# Perfect fields and rings
12+
13+
In this file we define perfect fields, together with a generalisation to (commutative) rings in
14+
prime characteristic.
15+
16+
## Main definitions / statements:
17+
* `PerfectRing`: a ring of characteristic `p` (prime) is said to be perfect in the sense of Serre,
18+
if its absolute Frobenius map `x ↦ xᵖ` is bijective.
19+
* `PerfectField`: a field `K` is said to be perfect if every irreducible polynomial over `K` is
20+
separable.
21+
* `PerfectRing.toPerfectField`: a field that is perfect in the sense of Serre is a perfect field.
22+
* `PerfectField.toPerfectRing`: a perfect field of characteristic `p` (prime) is perfect in the
23+
sense of Serre.
24+
* `PerfectField.ofCharZero`: all fields of characteristic zero are perfect.
25+
* `PerfectField.ofFinite`: all finite fields are perfect.
26+
27+
-/
28+
29+
open Function Polynomial
30+
31+
/-- A perfect ring of characteristic `p` (prime) in the sense of Serre.
32+
33+
NB: This is not related to the concept with the same name introduced by Bass (related to projective
34+
covers of modules). -/
35+
class PerfectRing (R : Type _) (p : ℕ) [CommSemiring R] [Fact p.Prime] [CharP R p] : Prop where
36+
/-- A ring is perfect if the Frobenius map is bijective. -/
37+
bijective_frobenius : Bijective $ frobenius R p
38+
39+
section PerfectRing
40+
41+
variable (R : Type _) (p : ℕ) [CommSemiring R] [Fact p.Prime] [CharP R p]
42+
43+
/-- For a reduced ring, surjectivity of the Frobenius map is a sufficient condition for perfection.
44+
-/
45+
lemma PerfectRing.ofSurjective (R : Type _) (p : ℕ) [CommRing R] [Fact p.Prime] [CharP R p]
46+
[IsReduced R] (h : Surjective $ frobenius R p) : PerfectRing R p :=
47+
⟨frobenius_inj R p, h⟩
48+
#align perfect_ring.of_surjective PerfectRing.ofSurjective
49+
50+
instance PerfectRing.ofFiniteOfIsReduced (R : Type _) [CommRing R] [CharP R p]
51+
[Finite R] [IsReduced R] : PerfectRing R p :=
52+
ofSurjective _ _ $ Finite.surjective_of_injective (frobenius_inj R p)
53+
54+
variable [PerfectRing R p]
55+
56+
@[simp]
57+
theorem bijective_frobenius : Bijective (frobenius R p) := PerfectRing.bijective_frobenius
58+
59+
@[simp]
60+
theorem injective_frobenius : Injective (frobenius R p) := (bijective_frobenius R p).1
61+
62+
@[simp]
63+
theorem surjective_frobenius : Surjective (frobenius R p) := (bijective_frobenius R p).2
64+
65+
/-- The Frobenius automorphism for a perfect ring. -/
66+
@[simps! apply]
67+
noncomputable def frobeniusEquiv : R ≃+* R :=
68+
RingEquiv.ofBijective (frobenius R p) PerfectRing.bijective_frobenius
69+
#align frobenius_equiv frobeniusEquiv
70+
71+
@[simp]
72+
theorem coe_frobeniusEquiv : ⇑(frobeniusEquiv R p) = frobenius R p := rfl
73+
#align coe_frobenius_equiv coe_frobeniusEquiv
74+
75+
@[simp]
76+
theorem frobeniusEquiv_symm_apply_frobenius (x : R) :
77+
(frobeniusEquiv R p).symm (frobenius R p x) = x :=
78+
leftInverse_surjInv PerfectRing.bijective_frobenius x
79+
80+
@[simp]
81+
theorem frobenius_apply_frobeniusEquiv_symm (x : R) :
82+
frobenius R p ((frobeniusEquiv R p).symm x) = x :=
83+
surjInv_eq _ _
84+
85+
@[simp]
86+
theorem frobenius_comp_frobeniusEquiv_symm :
87+
(frobenius R p).comp (frobeniusEquiv R p).symm = RingHom.id R := by
88+
ext; simp
89+
90+
@[simp]
91+
theorem frobeniusEquiv_symm_comp_frobenius :
92+
((frobeniusEquiv R p).symm : R →+* R).comp (frobenius R p) = RingHom.id R := by
93+
ext; simp
94+
95+
@[simp]
96+
theorem frobeniusEquiv_symm_pow_p (x : R) : ((frobeniusEquiv R p).symm x) ^ p = x :=
97+
frobenius_apply_frobeniusEquiv_symm R p x
98+
99+
theorem injective_pow_p {x y : R} (h : x ^ p = y ^ p) : x = y := (frobeniusEquiv R p).injective h
100+
#align injective_pow_p injective_pow_p
101+
102+
lemma polynomial_expand_eq (f : R[X]) :
103+
expand R p f = (f.map (frobeniusEquiv R p).symm) ^ p := by
104+
rw [← (f.map (S := R) (frobeniusEquiv R p).symm).expand_char p, map_expand, map_map,
105+
frobenius_comp_frobeniusEquiv_symm, map_id]
106+
107+
@[simp]
108+
theorem not_irreducible_expand (f : R[X]) : ¬ Irreducible (expand R p f) := by
109+
have hp : Fact p.Prime := inferInstance
110+
rw [polynomial_expand_eq]
111+
exact fun hf ↦ hf.not_unit $ (of_irreducible_pow hp.out.ne_one hf).pow p
112+
113+
instance (S : Type _) [CommSemiring S] [CharP S p] [PerfectRing S p] :
114+
PerfectRing (R × S) p := by
115+
constructor
116+
have : frobenius (R × S) p = Prod.map (frobenius R p) (frobenius S p) := by
117+
ext <;> simp [frobenius_def]
118+
rw [this]
119+
exact Bijective.Prod_map (bijective_frobenius R p) (bijective_frobenius S p)
120+
121+
end PerfectRing
122+
123+
/-- A perfect field.
124+
125+
See also `PerfectRing` for a generalisation in positive characteristic. -/
126+
class PerfectField (K : Type _) [Field K] : Prop where
127+
/-- A field is perfect if every irreducible polynomial is separable. -/
128+
separable_of_irreducible : ∀ {f : K[X]}, Irreducible f → f.Separable
129+
130+
lemma PerfectRing.toPerfectField (K : Type _) (p : ℕ)
131+
[Field K] [hp : Fact p.Prime] [CharP K p] [PerfectRing K p] : PerfectField K := by
132+
refine' PerfectField.mk $ fun hf ↦ _
133+
rcases separable_or p hf with h | ⟨-, g, -, rfl⟩
134+
· assumption
135+
· exfalso; revert hf; simp
136+
137+
namespace PerfectField
138+
139+
variable (K : Type _) [Field K]
140+
141+
instance ofCharZero [CharZero K] : PerfectField K := ⟨Irreducible.separable⟩
142+
143+
instance ofFinite [Finite K] : PerfectField K := by
144+
obtain ⟨p, _instP⟩ := CharP.exists K
145+
have : Fact p.Prime := ⟨CharP.char_is_prime K p⟩
146+
exact PerfectRing.toPerfectField K p
147+
148+
variable [PerfectField K]
149+
150+
/-- A perfect field of characteristic `p` (prime) is a perfect ring. -/
151+
instance toPerfectRing (p : ℕ) [hp : Fact p.Prime] [CharP K p] : PerfectRing K p := by
152+
refine' PerfectRing.ofSurjective _ _ $ fun y ↦ _
153+
let f : K[X] := X ^ p - C y
154+
let L := f.SplittingField
155+
let ι := algebraMap K L
156+
have hf_deg : f.degree ≠ 0 := by
157+
rw [degree_X_pow_sub_C hp.out.pos y, p.cast_ne_zero]; exact hp.out.ne_zero
158+
let a : L := f.rootOfSplits ι (SplittingField.splits f) hf_deg
159+
have hfa : aeval a f = 0 := by rw [aeval_def, map_rootOfSplits _ (SplittingField.splits f) hf_deg]
160+
have ha_pow : a ^ p = ι y := by rwa [AlgHom.map_sub, aeval_X_pow, aeval_C, sub_eq_zero] at hfa
161+
let g : K[X] := minpoly K a
162+
suffices : (g.map ι).natDegree = 1
163+
· rw [g.natDegree_map, ← degree_eq_iff_natDegree_eq_of_pos Nat.one_pos] at this
164+
obtain ⟨a' : K, ha' : ι a' = a⟩ := minpoly.mem_range_of_degree_eq_one K a this
165+
refine' ⟨a', NoZeroSMulDivisors.algebraMap_injective K L _⟩
166+
rw [RingHom.map_frobenius, ha', frobenius_def, ha_pow]
167+
have hg_dvd : g.map ι ∣ (X - C a) ^ p := by
168+
convert Polynomial.map_dvd ι (minpoly.dvd K a hfa)
169+
rw [sub_pow_char, Polynomial.map_sub, Polynomial.map_pow, map_X, map_C, ← ha_pow, map_pow]
170+
have ha : IsIntegral K a := isIntegral_of_finite K a
171+
have hg_pow : g.map ι = (X - C a) ^ (g.map ι).natDegree := by
172+
obtain ⟨q, -, hq⟩ := (dvd_prime_pow (prime_X_sub_C a) p).mp hg_dvd
173+
rw [eq_of_monic_of_associated ((minpoly.monic ha).map ι) ((monic_X_sub_C a).pow q) hq,
174+
natDegree_pow, natDegree_X_sub_C, mul_one]
175+
have hg_sep : (g.map ι).Separable := (separable_of_irreducible $ minpoly.irreducible ha).map
176+
rw [hg_pow] at hg_sep
177+
refine' (Separable.of_pow (not_isUnit_X_sub_C a) _ hg_sep).2
178+
rw [g.natDegree_map ι, ← Nat.pos_iff_ne_zero, natDegree_pos_iff_degree_pos]
179+
exact minpoly.degree_pos ha
180+
181+
end PerfectField

0 commit comments

Comments
 (0)