|
| 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