Skip to content

Commit c4d449e

Browse files
committed
feat: port NumberTheory.FunctionField (#5332)
1 parent 4a2172e commit c4d449e

File tree

2 files changed

+284
-0
lines changed

2 files changed

+284
-0
lines changed

Mathlib.lean

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2279,6 +2279,7 @@ import Mathlib.NumberTheory.Divisors
22792279
import Mathlib.NumberTheory.Fermat4
22802280
import Mathlib.NumberTheory.FermatPsp
22812281
import Mathlib.NumberTheory.FrobeniusNumber
2282+
import Mathlib.NumberTheory.FunctionField
22822283
import Mathlib.NumberTheory.KummerDedekind
22832284
import Mathlib.NumberTheory.LSeries
22842285
import Mathlib.NumberTheory.LegendreSymbol.Basic
Lines changed: 283 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,283 @@
1+
/-
2+
Copyright (c) 2021 Anne Baanen. All rights reserved.
3+
Released under Apache 2.0 license as described in the file LICENSE.
4+
Authors: Anne Baanen, Ashvni Narayanan
5+
6+
! This file was ported from Lean 3 source module number_theory.function_field
7+
! leanprover-community/mathlib commit 70fd9563a21e7b963887c9360bd29b2393e6225a
8+
! Please do not edit these lines, except to modify the commit id
9+
! if you have ported upstream changes.
10+
-/
11+
import Mathlib.Algebra.Order.Group.TypeTags
12+
import Mathlib.FieldTheory.RatFunc
13+
import Mathlib.RingTheory.DedekindDomain.IntegralClosure
14+
import Mathlib.RingTheory.IntegrallyClosed
15+
import Mathlib.Topology.Algebra.ValuedField
16+
17+
/-!
18+
# Function fields
19+
20+
This file defines a function field and the ring of integers corresponding to it.
21+
22+
## Main definitions
23+
- `FunctionField Fq F` states that `F` is a function field over the (finite) field `Fq`,
24+
i.e. it is a finite extension of the field of rational functions in one variable over `Fq`.
25+
- `FunctionField.ringOfIntegers` defines the ring of integers corresponding to a function field
26+
as the integral closure of `Fq[X]` in the function field.
27+
- `FunctionField.inftyValuation` : The place at infinity on `Fq(t)` is the nonarchimedean
28+
valuation on `Fq(t)` with uniformizer `1/t`.
29+
- `FunctionField.FqtInfty` : The completion `Fq((t⁻¹))` of `Fq(t)` with respect to the
30+
valuation at infinity.
31+
32+
## Implementation notes
33+
The definitions that involve a field of fractions choose a canonical field of fractions,
34+
but are independent of that choice. We also omit assumptions like `Finite Fq` or
35+
`IsScalarTower Fq[X] (FractionRing Fq[X]) F` in definitions,
36+
adding them back in lemmas when they are needed.
37+
38+
## References
39+
* [D. Marcus, *Number Fields*][marcus1977number]
40+
* [J.W.S. Cassels, A. Frölich, *Algebraic Number Theory*][cassels1967algebraic]
41+
* [P. Samuel, *Algebraic Theory of Numbers*][samuel1970algebraic]
42+
43+
## Tags
44+
function field, ring of integers
45+
-/
46+
47+
48+
noncomputable section
49+
50+
open scoped nonZeroDivisors Polynomial DiscreteValuation
51+
52+
variable (Fq F : Type) [Field Fq] [Field F]
53+
54+
/-- `F` is a function field over the finite field `Fq` if it is a finite
55+
extension of the field of rational functions in one variable over `Fq`.
56+
57+
Note that `F` can be a function field over multiple, non-isomorphic, `Fq`.
58+
-/
59+
abbrev FunctionField [Algebra (RatFunc Fq) F] : Prop :=
60+
FiniteDimensional (RatFunc Fq) F
61+
#align function_field FunctionField
62+
63+
-- Porting note: Removed `protected`
64+
/-- `F` is a function field over `Fq` iff it is a finite extension of `Fq(t)`. -/
65+
theorem functionField_iff (Fqt : Type _) [Field Fqt] [Algebra Fq[X] Fqt]
66+
[IsFractionRing Fq[X] Fqt] [Algebra (RatFunc Fq) F] [Algebra Fqt F] [Algebra Fq[X] F]
67+
[IsScalarTower Fq[X] Fqt F] [IsScalarTower Fq[X] (RatFunc Fq) F] :
68+
FunctionField Fq F ↔ FiniteDimensional Fqt F := by
69+
let e := IsLocalization.algEquiv Fq[X]⁰ (RatFunc Fq) Fqt
70+
have : ∀ (c) (x : F), e c • x = c • x := by
71+
intro c x
72+
rw [Algebra.smul_def, Algebra.smul_def]
73+
congr
74+
refine' congr_fun (f := fun c => algebraMap Fqt F (e c)) _ c -- Porting note: Added `(f := _)`
75+
refine' IsLocalization.ext (nonZeroDivisors Fq[X]) _ _ _ _ _ _ _ <;> intros <;>
76+
simp only [AlgEquiv.map_one, RingHom.map_one, AlgEquiv.map_mul, RingHom.map_mul,
77+
AlgEquiv.commutes, ← IsScalarTower.algebraMap_apply]
78+
constructor <;> intro h
79+
· let b := FiniteDimensional.finBasis (RatFunc Fq) F
80+
exact FiniteDimensional.of_fintype_basis (b.mapCoeffs e this)
81+
· let b := FiniteDimensional.finBasis Fqt F
82+
refine' FiniteDimensional.of_fintype_basis (b.mapCoeffs e.symm _)
83+
intro c x; convert (this (e.symm c) x).symm; simp only [e.apply_symm_apply]
84+
#align function_field_iff functionField_iff
85+
86+
theorem algebraMap_injective [Algebra Fq[X] F] [Algebra (RatFunc Fq) F]
87+
[IsScalarTower Fq[X] (RatFunc Fq) F] : Function.Injective (⇑(algebraMap Fq[X] F)) := by
88+
rw [IsScalarTower.algebraMap_eq Fq[X] (RatFunc Fq) F]
89+
exact (algebraMap (RatFunc Fq) F).injective.comp (IsFractionRing.injective Fq[X] (RatFunc Fq))
90+
#align algebra_map_injective algebraMap_injective
91+
92+
namespace FunctionField
93+
94+
/-- The function field analogue of `NumberField.ringOfIntegers`:
95+
`FunctionField.ringOfIntegers Fq Fqt F` is the integral closure of `Fq[t]` in `F`.
96+
97+
We don't actually assume `F` is a function field over `Fq` in the definition,
98+
only when proving its properties.
99+
-/
100+
def ringOfIntegers [Algebra Fq[X] F] :=
101+
integralClosure Fq[X] F
102+
#align function_field.ring_of_integers FunctionField.ringOfIntegers
103+
104+
namespace ringOfIntegers
105+
106+
variable [Algebra Fq[X] F]
107+
108+
instance : IsDomain (ringOfIntegers Fq F) :=
109+
(ringOfIntegers Fq F).isDomain
110+
111+
instance : IsIntegralClosure (ringOfIntegers Fq F) Fq[X] F :=
112+
integralClosure.isIntegralClosure _ _
113+
114+
variable [Algebra (RatFunc Fq) F] [IsScalarTower Fq[X] (RatFunc Fq) F]
115+
116+
theorem algebraMap_injective : Function.Injective (⇑(algebraMap Fq[X] (ringOfIntegers Fq F))) := by
117+
have hinj : Function.Injective (⇑(algebraMap Fq[X] F)) := by
118+
rw [IsScalarTower.algebraMap_eq Fq[X] (RatFunc Fq) F]
119+
exact (algebraMap (RatFunc Fq) F).injective.comp (IsFractionRing.injective Fq[X] (RatFunc Fq))
120+
rw [injective_iff_map_eq_zero (algebraMap Fq[X] (↥(ringOfIntegers Fq F)))]
121+
intro p hp
122+
rw [← Subtype.coe_inj, Subalgebra.coe_zero] at hp
123+
rw [injective_iff_map_eq_zero (algebraMap Fq[X] F)] at hinj
124+
exact hinj p hp
125+
#align function_field.ring_of_integers.algebra_map_injective FunctionField.ringOfIntegers.algebraMap_injective
126+
127+
theorem not_isField : ¬IsField (ringOfIntegers Fq F) := by
128+
simpa [← (IsIntegralClosure.isIntegral_algebra Fq[X] F).isField_iff_isField
129+
(algebraMap_injective Fq F)] using
130+
Polynomial.not_isField Fq
131+
#align function_field.ring_of_integers.not_is_field FunctionField.ringOfIntegers.not_isField
132+
133+
variable [FunctionField Fq F]
134+
135+
instance : IsFractionRing (ringOfIntegers Fq F) F :=
136+
integralClosure.isFractionRing_of_finite_extension (RatFunc Fq) F
137+
138+
instance : IsIntegrallyClosed (ringOfIntegers Fq F) :=
139+
integralClosure.isIntegrallyClosedOfFiniteExtension (RatFunc Fq)
140+
141+
instance [IsSeparable (RatFunc Fq) F] : IsNoetherian Fq[X] (ringOfIntegers Fq F) :=
142+
IsIntegralClosure.isNoetherian _ (RatFunc Fq) F _
143+
144+
instance [IsSeparable (RatFunc Fq) F] : IsDedekindDomain (ringOfIntegers Fq F) :=
145+
IsIntegralClosure.isDedekindDomain Fq[X] (RatFunc Fq) F _
146+
147+
end ringOfIntegers
148+
149+
/-! ### The place at infinity on Fq(t) -/
150+
151+
152+
section InftyValuation
153+
154+
variable [DecidableEq (RatFunc Fq)]
155+
156+
/-- The valuation at infinity is the nonarchimedean valuation on `Fq(t)` with uniformizer `1/t`.
157+
Explicitly, if `f/g ∈ Fq(t)` is a nonzero quotient of polynomials, its valuation at infinity is
158+
`Multiplicative.ofAdd(degree(f) - degree(g))`. -/
159+
def inftyValuationDef (r : RatFunc Fq) : ℤₘ₀ :=
160+
if r = 0 then 0 else Multiplicative.ofAdd r.intDegree
161+
#align function_field.infty_valuation_def FunctionField.inftyValuationDef
162+
163+
theorem InftyValuation.map_zero' : inftyValuationDef Fq 0 = 0 :=
164+
if_pos rfl
165+
#align function_field.infty_valuation.map_zero' FunctionField.InftyValuation.map_zero'
166+
167+
theorem InftyValuation.map_one' : inftyValuationDef Fq 1 = 1 :=
168+
(if_neg one_ne_zero).trans <| by rw [RatFunc.intDegree_one, ofAdd_zero, WithZero.coe_one]
169+
#align function_field.infty_valuation.map_one' FunctionField.InftyValuation.map_one'
170+
171+
theorem InftyValuation.map_mul' (x y : RatFunc Fq) :
172+
inftyValuationDef Fq (x * y) = inftyValuationDef Fq x * inftyValuationDef Fq y := by
173+
rw [inftyValuationDef, inftyValuationDef, inftyValuationDef]
174+
by_cases hx : x = 0
175+
· rw [hx, MulZeroClass.zero_mul, if_pos (Eq.refl _), MulZeroClass.zero_mul]
176+
· by_cases hy : y = 0
177+
· rw [hy, MulZeroClass.mul_zero, if_pos (Eq.refl _), MulZeroClass.mul_zero]
178+
· rw [if_neg hx, if_neg hy, if_neg (mul_ne_zero hx hy), ← WithZero.coe_mul, WithZero.coe_inj,
179+
← ofAdd_add, RatFunc.intDegree_mul hx hy]
180+
#align function_field.infty_valuation.map_mul' FunctionField.InftyValuation.map_mul'
181+
182+
theorem InftyValuation.map_add_le_max' (x y : RatFunc Fq) :
183+
inftyValuationDef Fq (x + y) ≤ max (inftyValuationDef Fq x) (inftyValuationDef Fq y) := by
184+
by_cases hx : x = 0
185+
· rw [hx, zero_add]
186+
conv_rhs => rw [inftyValuationDef, if_pos (Eq.refl _)]
187+
rw [max_eq_right (WithZero.zero_le (inftyValuationDef Fq y))]
188+
· by_cases hy : y = 0
189+
· rw [hy, add_zero]
190+
conv_rhs => rw [max_comm, inftyValuationDef, if_pos (Eq.refl _)]
191+
rw [max_eq_right (WithZero.zero_le (inftyValuationDef Fq x))]
192+
· by_cases hxy : x + y = 0
193+
· rw [inftyValuationDef, if_pos hxy]; exact zero_le'
194+
· rw [inftyValuationDef, inftyValuationDef, inftyValuationDef, if_neg hx, if_neg hy,
195+
if_neg hxy]
196+
rw [le_max_iff, WithZero.coe_le_coe, Multiplicative.ofAdd_le, WithZero.coe_le_coe,
197+
Multiplicative.ofAdd_le, ← le_max_iff]
198+
exact RatFunc.intDegree_add_le hy hxy
199+
#align function_field.infty_valuation.map_add_le_max' FunctionField.InftyValuation.map_add_le_max'
200+
201+
@[simp]
202+
theorem inftyValuation_of_nonzero {x : RatFunc Fq} (hx : x ≠ 0) :
203+
inftyValuationDef Fq x = Multiplicative.ofAdd x.intDegree := by
204+
rw [inftyValuationDef, if_neg hx]
205+
#align function_field.infty_valuation_of_nonzero FunctionField.inftyValuation_of_nonzero
206+
207+
/-- The valuation at infinity on `Fq(t)`. -/
208+
def inftyValuation : Valuation (RatFunc Fq) ℤₘ₀ where
209+
toFun := inftyValuationDef Fq
210+
map_zero' := InftyValuation.map_zero' Fq
211+
map_one' := InftyValuation.map_one' Fq
212+
map_mul' := InftyValuation.map_mul' Fq
213+
map_add_le_max' := InftyValuation.map_add_le_max' Fq
214+
#align function_field.infty_valuation FunctionField.inftyValuation
215+
216+
@[simp]
217+
theorem inftyValuation_apply {x : RatFunc Fq} : inftyValuation Fq x = inftyValuationDef Fq x :=
218+
rfl
219+
#align function_field.infty_valuation_apply FunctionField.inftyValuation_apply
220+
221+
@[simp]
222+
theorem inftyValuation.C {k : Fq} (hk : k ≠ 0) :
223+
inftyValuationDef Fq (RatFunc.C k) = Multiplicative.ofAdd (0 : ℤ) := by
224+
have hCk : RatFunc.C k ≠ 0 := (map_ne_zero _).mpr hk
225+
rw [inftyValuationDef, if_neg hCk, RatFunc.intDegree_C]
226+
set_option linter.uppercaseLean3 false in
227+
#align function_field.infty_valuation.C FunctionField.inftyValuation.C
228+
229+
@[simp]
230+
theorem inftyValuation.X : inftyValuationDef Fq RatFunc.X = Multiplicative.ofAdd (1 : ℤ) := by
231+
rw [inftyValuationDef, if_neg RatFunc.X_ne_zero, RatFunc.intDegree_X]
232+
set_option linter.uppercaseLean3 false in
233+
#align function_field.infty_valuation.X FunctionField.inftyValuation.X
234+
235+
@[simp]
236+
theorem inftyValuation.polynomial {p : Fq[X]} (hp : p ≠ 0) :
237+
inftyValuationDef Fq (algebraMap Fq[X] (RatFunc Fq) p) =
238+
Multiplicative.ofAdd (p.natDegree : ℤ) := by
239+
have hp' : algebraMap Fq[X] (RatFunc Fq) p ≠ 0 := by
240+
rw [Ne.def, RatFunc.algebraMap_eq_zero_iff]; exact hp
241+
rw [inftyValuationDef, if_neg hp', RatFunc.intDegree_polynomial]
242+
#align function_field.infty_valuation.polynomial FunctionField.inftyValuation.polynomial
243+
244+
/-- The valued field `Fq(t)` with the valuation at infinity. -/
245+
def inftyValuedFqt : Valued (RatFunc Fq) ℤₘ₀ :=
246+
Valued.mk' <| inftyValuation Fq
247+
set_option linter.uppercaseLean3 false in
248+
#align function_field.infty_valued_Fqt FunctionField.inftyValuedFqt
249+
250+
theorem inftyValuedFqt.def {x : RatFunc Fq} :
251+
@Valued.v (RatFunc Fq) _ _ _ (inftyValuedFqt Fq) x = inftyValuationDef Fq x :=
252+
rfl
253+
set_option linter.uppercaseLean3 false in
254+
#align function_field.infty_valued_Fqt.def FunctionField.inftyValuedFqt.def
255+
256+
/-- The completion `Fq((t⁻¹))` of `Fq(t)` with respect to the valuation at infinity. -/
257+
def FqtInfty :=
258+
@UniformSpace.Completion (RatFunc Fq) <| (inftyValuedFqt Fq).toUniformSpace
259+
set_option linter.uppercaseLean3 false in
260+
#align function_field.Fqt_infty FunctionField.FqtInfty
261+
262+
instance : Field (FqtInfty Fq) :=
263+
letI := inftyValuedFqt Fq
264+
UniformSpace.Completion.instFieldCompletion
265+
266+
instance : Inhabited (FqtInfty Fq) :=
267+
⟨(0 : FqtInfty Fq)⟩
268+
269+
/-- The valuation at infinity on `k(t)` extends to a valuation on `FqtInfty`. -/
270+
instance valuedFqtInfty : Valued (FqtInfty Fq) ℤₘ₀ :=
271+
@Valued.valuedCompletion _ _ _ _ (inftyValuedFqt Fq)
272+
set_option linter.uppercaseLean3 false in
273+
#align function_field.valued_Fqt_infty FunctionField.valuedFqtInfty
274+
275+
theorem valuedFqtInfty.def {x : FqtInfty Fq} :
276+
Valued.v x = @Valued.extension (RatFunc Fq) _ _ _ (inftyValuedFqt Fq) x :=
277+
rfl
278+
set_option linter.uppercaseLean3 false in
279+
#align function_field.valued_Fqt_infty.def FunctionField.valuedFqtInfty.def
280+
281+
end InftyValuation
282+
283+
end FunctionField

0 commit comments

Comments
 (0)