Fermat's Last Theorem in Lean 4

← all definition modules

Definitions/Def_ModularCurve_QAdicPlaceMod.lean

definition module

The cusp at infinity as a place over any coefficient field

Fix a field K. The module works inside K((q)), with \bar j = jqModC K the Laurent series q^{-1}\cdot\mathrm{ofPowerSeries}(\mathrm{jNum}_K), where \mathrm{jNum} is the integral power series E_4^3\cdot(\eta\text{-product})^{-24} with constant term 1, base-changed to K; jqNModC K N is its image under qExpand K N (the ring endomorphism q\mapsto q^N of Laurent series), and modularFunctionFieldC K N is the intermediate field K(\bar j,\bar j_N)\subseteq K((q)). First come order computations: \bar j\neq 0 and \mathrm{ord}_q(\bar j)=-1; for any nonzero f and any p\neq 0, \mathrm{ord}_q(\mathrm{qExpand}\,p\,f)=p\,\mathrm{ord}_q(f); hence \bar j_N\neq0 and \mathrm{ord}_q(\bar j_N)=-N.

The main construction is qInftyPlaceMod: for an intermediate field F of K((q))/K containing \bar j, it is the place of F over K (a valuation subring of F containing the image of K, proper, and a principal ideal ring) whose valuation subring is qIntegersBar K F, the set of f\in F whose underlying Laurent series has nonnegative order. Properness comes from \bar j\notin qIntegersBar K F; principality is obtained by exhibiting uniformizerMod, the element \bar j^{-1} of order 1, as an irreducible element for which every nonzero non-unit is a unit times a power, so the subring is a discrete valuation ring. Further lemmas identify the associated order function, \mathrm{ord}_{v}(f)=\mathrm{ord}_q(f) for all f\in F, show that the constant coefficient realises every residue class (each f of nonnegative order is congruent to its q^0-coefficient modulo the maximal ideal), and conclude \deg v=[\,\kappa(v):K\,]=1.

Specialising to F=K(\bar j,\bar j_N) gives cuspInftyGeom K N, with \mathrm{ord}_\infty(\bar j)=-1, \mathrm{ord}_\infty(\bar j_N)=-N and \deg_\infty=1, and in particular the type of places of this function field is nonempty. Two final lemmas record the instance K=\overline{\mathbb F}_2, N=3: there \mathrm{ord}_\infty(\bar j)=-1, hence is nonzero.

Relation to Mathlib

Built on Mathlib's LaurentSeries/HahnSeries.order, ValuationSubring and IsDiscreteValuationRing, but the notions used here — the Place structure of a function field over a base field (valuation subring containing the base, proper, principal), the subring qIntegersBar of series of nonnegative order, and the q-expansion model of the modular function field — are the project's own; this is the arbitrary-coefficient-field counterpart of the characteristic-zero construction qInftyPlaceBar, with jq over \mathbb{Q} replaced by jqModC K.

Where it is used

These places supply the cusp \infty on the geometric fibres of the modular curves of level N, with its order function and the fact that it is K-rational of degree one, which is what the divisor-theoretic arguments about the special fibre and its Hecke action require as input.

References

  1. F. Diamond and J. Shurman, A First Course in Modular Forms, Graduate Texts in Mathematics 228, Springer, 2005
  2. G. Shimura, Introduction to the Arithmetic Theory of Automorphic Functions, Princeton University Press, 1971

References are suggested automatically and have not been individually verified.

English text generated automatically from the Lean source; the Lean statement is authoritative.

Source file: Definitions/Def_ModularCurve_QAdicPlaceMod.lean

Imports

Theorems imported by this definition module

Imported by

Declarations

Source

import Mathlib
import Definitions.Def_ModularCurve_QAdicPlace
import Definitions.Def_ModularCurve_JqCoeff
import Theorems.Thm_ModularCurve_coeff_jqModC_neg_one
import Theorems.Thm_ModularCurve_coeff_jqModC_pow_of_lt

set_option autoImplicit false

noncomputable section

open HahnSeries AlgebraicCurve

set_option synthInstance.maxHeartbeats 400000

namespace ModularCurve

variable (K : Type*) [Field K]

section OrderJqModC

theorem jqModC_ne_zero_def : jqModC K ≠ 0 := by
  intro h
  have h1 : (jqModC K).coeff (-1 : ℤ) = 1 := coeff_jqModC_neg_one K
  rw [h, HahnSeries.coeff_zero] at h1
  exact zero_ne_one h1

theorem order_jqModC_def : (jqModC K).order = -1 := by
  refine le_antisymm (HahnSeries.order_le_of_coeff_ne_zero ?_) ?_
  · rw [coeff_jqModC_neg_one]
    exact one_ne_zero
  · by_contra hlt
    rw [not_le] at hlt
    refine HahnSeries.coeff_order_eq_zero.not.mpr (jqModC_ne_zero_def K) ?_
    have h := coeff_jqModC_pow_of_lt K (b := 1) (m := (jqModC K).order)
      (by simpa using hlt)
    simpa using h

theorem order_qExpandC (p : ℕ) [NeZero p] {f : LaurentSeries K} (hf : f ≠ 0) :
    (qExpand K p f).order = (p : ℤ) * f.order := by
  have hp : (0 : ℤ) < (p : ℤ) := by exact_mod_cast Nat.pos_of_ne_zero (NeZero.ne p)
  have hcoeff : (qExpand K p f).coeff ((p : ℤ) * f.order) = f.coeff f.order := by
    rw [qExpand_coeff_mul]
  have hcoeff' : (qExpand K p f).coeff ((p : ℤ) * f.order) ≠ 0 := by
    rw [hcoeff]
    exact HahnSeries.coeff_order_eq_zero.not.mpr hf
  have hne : qExpand K p f ≠ 0 := HahnSeries.ne_zero_of_coeff_ne_zero hcoeff'
  have hbelow : ∀ k : ℤ, k < (p : ℤ) * f.order → (qExpand K p f).coeff k = 0 := by
    intro k hk
    by_cases hdvd : (p : ℤ) ∣ k
    · obtain ⟨j, rfl⟩ := hdvd
      rw [qExpand_coeff_mul]
      exact HahnSeries.coeff_eq_zero_of_lt_order (lt_of_mul_lt_mul_left hk hp.le)
    · exact qExpand_coeff_of_not_dvd p f hdvd
  refine le_antisymm (HahnSeries.order_le_of_coeff_ne_zero hcoeff') ?_
  by_contra hlt
  rw [not_le] at hlt
  exact hne (HahnSeries.coeff_order_eq_zero.mp (hbelow _ hlt))

theorem jqNModC_ne_zero (N : ℕ) [NeZero N] : jqNModC K N ≠ 0 := by
  intro h
  have := order_qExpandC K N (jqModC_ne_zero_def K)
  rw [show qExpand K N (jqModC K) = jqNModC K N from rfl, h, HahnSeries.order_zero,
    order_jqModC_def] at this
  have hN : (N : ℤ) ≠ 0 := by exact_mod_cast NeZero.ne N
  omega

theorem order_jqNModC (N : ℕ) [NeZero N] : (jqNModC K N).order = -(N : ℤ) := by
  rw [show jqNModC K N = qExpand K N (jqModC K) from rfl,
    order_qExpandC K N (jqModC_ne_zero_def K), order_jqModC_def]
  ring

end OrderJqModC

section QAdicPlaceMod

variable (F : IntermediateField K (LaurentSeries K))

variable {F} in

def jModElt (hF : jqModC K ∈ F) : F := ⟨jqModC K, hF⟩

variable {F} in
@[simp]
theorem qSeriesBar_jModElt (hF : jqModC K ∈ F) :
    qSeriesBar K F (jModElt K hF) = jqModC K := rfl

variable {F} in
theorem jModElt_ne_zero (hF : jqModC K ∈ F) : jModElt K hF ≠ 0 := by
  intro h
  exact jqModC_ne_zero_def K (by simpa [jModElt, Subtype.ext_iff] using h)

variable {F} in

theorem jModElt_notMem_qIntegersBar (hF : jqModC K ∈ F) :
    jModElt K hF ∉ qIntegersBar K F := by
  rw [mem_qIntegersBar_iff, qSeriesBar_jModElt, order_jqModC_def]
  omega

variable {F} in
theorem qIntegersBar_ne_top_of_jqModC_mem (hF : jqModC K ∈ F) : qIntegersBar K F ≠ ⊤ := by
  intro h
  exact jModElt_notMem_qIntegersBar K hF (h ▸ ValuationSubring.mem_top _)

variable {F} in

def jModInvElt (hF : jqModC K ∈ F) : F := (jModElt K hF)⁻¹

variable {F} in
theorem qSeriesBar_jModInvElt (hF : jqModC K ∈ F) :
    qSeriesBar K F (jModInvElt K hF) = (jqModC K)⁻¹ := by
  rw [jModInvElt, qSeriesBar_inv, qSeriesBar_jModElt]

variable {F} in
theorem jModInvElt_ne_zero (hF : jqModC K ∈ F) : jModInvElt K hF ≠ 0 :=
  inv_ne_zero (jModElt_ne_zero K hF)

variable {F} in

theorem order_jModInvElt (hF : jqModC K ∈ F) :
    (qSeriesBar K F (jModInvElt K hF)).order = 1 := by
  rw [qSeriesBar_jModInvElt, order_inv_of_ne_zero_bar (jqModC_ne_zero_def K), order_jqModC_def]
  omega

variable {F} in
theorem jModInvElt_mem_qIntegersBar (hF : jqModC K ∈ F) :
    jModInvElt K hF ∈ qIntegersBar K F := by
  rw [mem_qIntegersBar_iff, order_jModInvElt]
  omega

variable {F} in

def uniformizerMod (hF : jqModC K ∈ F) : qIntegersBar K F :=
jModInvElt K hF, jModInvElt_mem_qIntegersBar K hF⟩

variable {F} in
@[simp]
theorem coe_uniformizerMod (hF : jqModC K ∈ F) :
    ((uniformizerMod K hF : qIntegersBar K F) : F) = jModInvElt K hF := rfl

variable {F} in
theorem uniformizerMod_ne_zero (hF : jqModC K ∈ F) :
    ((uniformizerMod K hF : qIntegersBar K F) : F) ≠ 0 :=
  jModInvElt_ne_zero K hF

variable {F} in

theorem irreducible_uniformizerMod (hF : jqModC K ∈ F) :
    Irreducible (uniformizerMod K hF) := by
  constructor
  · rw [isUnit_qIntegersBar_iff (uniformizerMod_ne_zero K hF), coe_uniformizerMod,
      order_jModInvElt]
    omega
  · rintro a b hab
    have hab' : jModInvElt K hF = (a : F) * (b : F) := by
      have := congrArg (fun z : qIntegersBar K F => (z : F)) hab
      simpa using this
    have ha0 : (a : F) ≠ 0 := by
      intro h
      exact jModInvElt_ne_zero K hF (by rw [hab', h, zero_mul])
    have hb0 : (b : F) ≠ 0 := by
      intro h
      exact jModInvElt_ne_zero K hF (by rw [hab', h, mul_zero])
    have hsum : (qSeriesBar K F (a : F)).order + (qSeriesBar K F (b : F)).order = 1 := by
      rw [← order_qSeriesBar_mul ha0 hb0, ← hab', order_jModInvElt]
    have ha' : (0 : ℤ) ≤ (qSeriesBar K F (a : F)).order := a.2
    have hb' : (0 : ℤ) ≤ (qSeriesBar K F (b : F)).order := b.2
    rcases eq_or_lt_of_le ha' with ha0' | hapos
    · exact Or.inl ((isUnit_qIntegersBar_iff ha0).mpr ha0'.symm)
    rcases eq_or_lt_of_le hb' with hb0' | hbpos
    · exact Or.inr ((isUnit_qIntegersBar_iff hb0).mpr hb0'.symm)
    omega

variable {F} in

theorem qIntegersBar_isPrincipalIdealRing_of_jqModC_mem (hF : jqModC K ∈ F) :
    IsPrincipalIdealRing (qIntegersBar K F) := by
  refine (IsDiscreteValuationRing.ofHasUnitMulPowIrreducibleFactorization
uniformizerMod K hF, irreducible_uniformizerMod K hF, ?_⟩).toIsPrincipalIdealRing
  rintro x hx
  have hf : (x : F) ≠ 0 := fun h => hx (Subtype.ext h)
  have hmnonneg : (0 : ℤ) ≤ (qSeriesBar K F (x : F)).order := x.2
  set n : ℕ := (qSeriesBar K F (x : F)).order.toNat with hn
  have hmn : (n : ℤ) = (qSeriesBar K F (x : F)).order := Int.toNat_of_nonneg hmnonneg
  refine ⟨n, ?_⟩
  have hπn : (jModInvElt K hF) ^ n ≠ 0 := pow_ne_zero _ (jModInvElt_ne_zero K hF)
  have hdiv0 : (x : F) / (jModInvElt K hF) ^ n ≠ 0 := div_ne_zero hf hπn
  have hπorder : (qSeriesBar K F ((jModInvElt K hF) ^ n)).order = n := by
    rw [qSeriesBar_pow, order_pow_of_ne_zero_bar (qSeriesBar_ne_zero (jModInvElt_ne_zero K hF)),
      order_jModInvElt, mul_one]
  have hu0 : (qSeriesBar K F ((x : F) / (jModInvElt K hF) ^ n)).order = 0 := by
    rw [div_eq_mul_inv, order_qSeriesBar_mul hf (inv_ne_zero hπn), qSeriesBar_inv,
      order_inv_of_ne_zero_bar (qSeriesBar_ne_zero hπn), hπorder, ← hmn]
    ring
  have humem : (x : F) / (jModInvElt K hF) ^ n ∈ qIntegersBar K F := by
    rw [mem_qIntegersBar_iff, hu0]
  have hu : IsUnit (⟨(x : F) / (jModInvElt K hF) ^ n, humem⟩ : qIntegersBar K F) :=
    (isUnit_qIntegersBar_iff hdiv0).mpr hu0
  refine ⟨hu.unit, ?_⟩
  refine Subtype.ext ?_
  have hcoe : ((hu.unit : qIntegersBar K F) : F) = (x : F) / (jModInvElt K hF) ^ n := by
    rw [IsUnit.unit_spec]
  push_cast
  rw [hcoe, mul_comm, coe_uniformizerMod, div_mul_cancel₀]
  exact hπn

variable {F} in

def qInftyPlaceMod (hF : jqModC K ∈ F) : Place K F where
  toValuationSubring := qIntegersBar K F
  algebraMap_mem' := fun a => by
    rw [mem_qIntegersBar_iff, qSeriesBar_algebraMap]
    rcases eq_or_ne a 0 with rfl | ha
    · simp only [HahnSeries.single_eq_zero, HahnSeries.order_zero, le_refl]
    · rw [HahnSeries.order_single ha]
  ne_top' := qIntegersBar_ne_top_of_jqModC_mem K hF
  isPrincipalIdealRing' := qIntegersBar_isPrincipalIdealRing_of_jqModC_mem K hF

variable {F} in
@[simp]
theorem qInftyPlaceMod_toValuationSubring (hF : jqModC K ∈ F) :
    (qInftyPlaceMod K hF).toValuationSubring = qIntegersBar K F := rfl

variable {F} in

theorem ord_qInftyPlaceMod (hF : jqModC K ∈ F) (f : F) :
    (qInftyPlaceMod K hF).ord f = (qSeriesBar K F f).order := by
  rcases eq_or_ne f 0 with rfl | hf
  · rw [Place.ord_zero, qSeriesBar_zero, HahnSeries.order_zero]
  set n : ℤ := (qSeriesBar K F f).order with hn
  have hjn : (jModInvElt K hF) ^ n ≠ 0 := zpow_ne_zero _ (jModInvElt_ne_zero K hF)
  have huord : (qSeriesBar K F (f / (jModInvElt K hF) ^ n)).order = 0 := by
    rw [qSeriesBar_div, qSeriesBar_zpow,
      order_div_of_ne_zero_bar (qSeriesBar_ne_zero hf)
        (zpow_ne_zero _ (qSeriesBar_ne_zero (jModInvElt_ne_zero K hF))),
      order_zpow_of_ne_zero_bar (qSeriesBar_ne_zero (jModInvElt_ne_zero K hF)),
      order_jModInvElt, mul_one, ← hn]
    ring
  have humem : f / (jModInvElt K hF) ^ n ∈ qIntegersBar K F := by
    rw [mem_qIntegersBar_iff, huord]
  have hune : f / (jModInvElt K hF) ^ n ≠ 0 := div_ne_zero hf hjn
  have huu : IsUnit (⟨f / (jModInvElt K hF) ^ n, humem⟩ : qIntegersBar K F) :=
    (isUnit_qIntegersBar_iff hune).mpr huord
  have hdecomp : f = ((huu.unit : qIntegersBar K F) : F)
      * (((uniformizerMod K hF : qIntegersBar K F) : F) ^ n) := by
    have hcoe : ((huu.unit : qIntegersBar K F) : F) = f / (jModInvElt K hF) ^ n := by
      rw [IsUnit.unit_spec]
    rw [hcoe, coe_uniformizerMod]
    exact (div_mul_cancel₀ f hjn).symm
  rw [hdecomp]
  exact (qInftyPlaceMod K hF).ord_unit_smul_zpow huu.unit (irreducible_uniformizerMod K hF) n

variable {F} in

theorem algebraMap_coeff_zero_sub_not_isUnit_mod (hF : jqModC K ∈ F)
    (f : (qInftyPlaceMod K hF).toValuationSubring) :
    ¬IsUnit (algebraMap K (qInftyPlaceMod K hF).toValuationSubring
      ((qSeriesBar K F (f : F)).coeff 0) - f) := by
  set c : K := (qSeriesBar K F (f : F)).coeff 0 with hc
  have hcoe : qSeriesBar K F
      ((algebraMap K (qInftyPlaceMod K hF).toValuationSubring c - f : _) : F)
      = HahnSeries.single (0 : ℤ) c - qSeriesBar K F (f : F) := by
    have h1 : ((algebraMap K (qInftyPlaceMod K hF).toValuationSubring c - f : _) : F)
        = algebraMap K F c - (f : F) := by
      push_cast
      rw [Place.coe_algebraMap]
    rw [h1, qSeriesBar_sub, qSeriesBar_algebraMap]
  have hgcoeff : ∀ k : ℤ, k ≤ 0
      (qSeriesBar K F
        ((algebraMap K (qInftyPlaceMod K hF).toValuationSubring c - f : _) : F)).coeff k
        = 0 := by
    intro k hk
    rw [hcoe, HahnSeries.coeff_sub]
    rcases lt_or_eq_of_le hk with hk' | hk'
    · rw [HahnSeries.coeff_single_of_ne (by omega : k ≠ 0),
        HahnSeries.coeff_eq_zero_of_lt_order (lt_of_lt_of_le hk' f.2), sub_zero]
    · subst hk'
      rw [HahnSeries.coeff_single_same, hc, sub_self]
  intro hunit
  rcases eq_or_ne
    (((algebraMap K (qInftyPlaceMod K hF).toValuationSubring c - f : _) : F)) 0
    with hg0 | hg0
  · have hzero : (algebraMap K (qInftyPlaceMod K hF).toValuationSubring c - f : _) = 0 :=
      Subtype.ext hg0
    rw [hzero] at hunit
    exact not_isUnit_zero hunit
  · have horder := (isUnit_qIntegersBar_iff hg0).mp hunit
    have hne := HahnSeries.coeff_order_eq_zero.not.mpr (qSeriesBar_ne_zero hg0)
    rw [horder] at hne
    exact hne (hgcoeff 0 le_rfl)

variable {F} in

theorem surjective_algebraMap_residueField_mod (hF : jqModC K ∈ F) :
    Function.Surjective (algebraMap K (qInftyPlaceMod K hF).ResidueField) := by
  intro y
  obtain ⟨f, rfl⟩ := Ideal.Quotient.mk_surjective
    (I := IsLocalRing.maximalIdeal (qInftyPlaceMod K hF).toValuationSubring) y
  refine ⟨(qSeriesBar K F (f : F)).coeff 0, ?_⟩
  have hmem : algebraMap K (qInftyPlaceMod K hF).toValuationSubring
      ((qSeriesBar K F (f : F)).coeff 0) - f ∈
      IsLocalRing.maximalIdeal (qInftyPlaceMod K hF).toValuationSubring := by
    rw [IsLocalRing.mem_maximalIdeal, mem_nonunits_iff]
    exact algebraMap_coeff_zero_sub_not_isUnit_mod K hF f
  exact (Ideal.Quotient.mk_eq_mk_iff_sub_mem
    (I := IsLocalRing.maximalIdeal (qInftyPlaceMod K hF).toValuationSubring)
    (algebraMap K (qInftyPlaceMod K hF).toValuationSubring
      ((qSeriesBar K F (f : F)).coeff 0)) f).mpr hmem

variable {F} in

theorem deg_qInftyPlaceMod (hF : jqModC K ∈ F) : (qInftyPlaceMod K hF).deg = 1 := by
  have hsurj := surjective_algebraMap_residueField_mod K hF
  have hinj : Function.Injective (algebraMap K (qInftyPlaceMod K hF).ResidueField) :=
    (algebraMap K (qInftyPlaceMod K hF).ResidueField).injective
  have e : K ≃ₐ[K] (qInftyPlaceMod K hF).ResidueField :=
    AlgEquiv.ofBijective (Algebra.ofId K _) ⟨hinj, hsurj⟩
  show Module.finrank K (qInftyPlaceMod K hF).ResidueField = 1
  rw [← e.toLinearEquiv.finrank_eq, Module.finrank_self]

end QAdicPlaceMod

section LevelN

variable (N : ℕ) [NeZero N]

def cuspInftyGeom : Place K (modularFunctionFieldC K N) :=
  qInftyPlaceMod K (jqModC_mem K N)

theorem nonempty_place_modularFunctionFieldC :
    Nonempty (Place K (modularFunctionFieldC K N)) :=
cuspInftyGeom K N⟩

theorem ord_cuspInftyGeom_jq :
    (cuspInftyGeom K N).ord ⟨jqModC K, jqModC_mem K N⟩ = -1 := by
  rw [cuspInftyGeom, ord_qInftyPlaceMod]
  exact order_jqModC_def K

theorem ord_cuspInftyGeom_jqN :
    (cuspInftyGeom K N).ord ⟨jqNModC K N, jqNModC_mem K N⟩ = -(N : ℤ) := by
  rw [cuspInftyGeom, ord_qInftyPlaceMod]
  exact order_jqNModC K N

theorem deg_cuspInftyGeom : (cuspInftyGeom K N).deg = 1 :=
  deg_qInftyPlaceMod K (jqModC_mem K N)

end LevelN

section Gates

theorem gate_ord_cuspInftyGeom_fbar_two :
    (cuspInftyGeom (AlgebraicClosure (ZMod 2)) 3).ord
jqModC _, jqModC_mem _ 3⟩ = -1 :=
  ord_cuspInftyGeom_jq _ 3

theorem gate_ord_cuspInftyGeom_fbar_two_ne_zero :
    (cuspInftyGeom (AlgebraicClosure (ZMod 2)) 3).ord
jqModC _, jqModC_mem _ 3⟩ ≠ 0 := by
  rw [gate_ord_cuspInftyGeom_fbar_two]
  omega

end Gates

end ModularCurve

Statements phrased using this module (5)