Fermat's Last Theorem in Lean 4

← all definition modules

Definitions/Def_ModularCurve_PeriodLattice.lean

definition module

Period lattice of weight-two forms and its Hecke action

Fix a level N and let S_2(N) denote CuspForm (CongruenceSubgroup.Gamma0 N) 2 and S_2(N)^\vee its \mathbb{C}-linear dual. The first group of definitions produces periods by explicit integration along straight segments: clamp01 is t\mapsto\max(0,\min(t,1)), segmentPoint τ₀ τ₁ t is the convex combination (1-\mathrm{clamp}_{01}t)\tau_0+(\mathrm{clamp}_{01}t)\tau_1, which has positive imaginary part, so segmentPath is a continuous map \mathbb{R}\to\mathbb{H}; periodIntegrand N τ₀ τ₁ f t is f(\text{segmentPath}\,t)\cdot(\tau_1-\tau_0), continuous and hence interval integrable, additive and \mathbb{C}-homogeneous in f. Accordingly periodAlong N τ₀ τ₁ is the functional f\mapsto\int_0^1 f((1-t)\tau_0+t\tau_1)(\tau_1-\tau_0)\,dt in S_2(N)^\vee, period N γ is periodAlong N I (γ • I) for \gamma\in\Gamma_0(N) acting through \mathrm{SL}_2(\mathbb{Z}), and periodLattice N is the \mathbb{Z}-submodule of S_2(N)^\vee spanned by the range of period N. No Eichler–Shimura–Manin property of these periods is asserted here.

The second group, for N\neq 0, builds an action of the free commutative Hecke ring HeckeAlg =\mathbb{Z}[X_\ell:\ell\text{ prime}]. cuspHeckeGen N ℓ is U_\ell if \ell\mid N and T_\ell otherwise, viewed in the subalgebra CuspForm.heckeAlgebra N 2 ∅; the range of cuspHeckeGen N is exactly the set of elements whose underlying endomorphism lies in CuspForm.heckeGenerators N 2 ∅, whence the evaluation map cuspHeckeAeval N, X_\ell\mapsto cuspHeckeGen N ℓ, is surjective, and the ring map cuspHeckeRep N into \mathrm{End}_{\mathbb{C}}S_2(N) has the Hecke subalgebra as its range and commutative image. dualHeckeRep N is the transpose action t\mapsto{}^t(\text{cuspHeckeRep }N\,t) on S_2(N)^\vee, a ring homomorphism by commutativity, sending \mathbb{C}-constants a to a\cdot\mathrm{id}. The predicate PeriodLatticeHeckeStable N says each {}^tT_\ell,{}^tU_\ell preserves periodLattice N; periodLattice_stable_of propagates this to all of HeckeAlg by induction on polynomials, giving periodLatticeRestrict/periodLatticeRestrictHom. Finally periodLatticeHeckeEnd N is defined by cases: the restricted Hecke action when stability holds, and otherwise the degenerate homomorphism t\mapsto(\text{constant coefficient of }t)\cdot\mathrm{id}; periodLatticeModule N is the resulting HeckeAlg-module structure on the period lattice.

Relation to Mathlib

Mathlib supplies CuspForm, UpperHalfPlane, Module.Dual, interval integrals and CongruenceSubgroup.Gamma0; the period functionals, the period lattice and the HeckeAlg-module structure on it are the project's own, built on the project's Hecke operators CuspForm.heckeTLin/heckeULin and the subalgebra CuspForm.heckeAlgebra.

Where it is used

The period lattice with its Hecke action is the project's concrete stand-in for the integral homology of X_0(N), equivalently for J_0(N)(\mathbb{C})=S_2(N)^\vee/\Lambda_N, as a module over the free Hecke ring HeckeAlg. It is in this shape that the Eichler–Shimura package (Galois action, Frobenius quadratic relation, \mathfrak{m}-torsion representations) is formulated and used in the level-lowering step for the Frey curve.

References

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

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_PeriodLattice.lean

Imports

Imported by

Declarations

Source

import Mathlib
import Definitions.Def_CuspForm_HeckeAlgebra
import Definitions.Def_HeckeGalois_EichlerShimura

set_option autoImplicit false

noncomputable section

open UpperHalfPlane

open scoped MatrixGroups

namespace ModularCurve

section Period

def clamp01 (t : ℝ) : ℝ := max 0 (min t 1)

theorem clamp01_nonneg (t : ℝ) : 0clamp01 t := le_max_left _ _

theorem clamp01_le_one (t : ℝ) : clamp01 t ≤ 1 := max_le zero_le_one (min_le_right _ _)

theorem continuous_clamp01 : Continuous clamp01 :=
  continuous_const.max (continuous_id.min continuous_const)

theorem clamp01_of_mem {t : ℝ} (ht : t ∈ Set.Icc (0 : ℝ) 1) : clamp01 t = t := by
  rw [clamp01, min_eq_left ht.2, max_eq_right ht.1]

def segmentPoint (τ₀ τ₁ : ℍ) (t : ℝ) : ℂ :=
  (1 - clamp01 t) • (τ₀ : ℂ) + clamp01 t • (τ₁ : ℂ)

theorem segmentPoint_im_pos (τ₀ τ₁ : ℍ) (t : ℝ) : 0 < (segmentPoint τ₀ τ₁ t).im := by
  have h0 := clamp01_nonneg t
  have h1 := clamp01_le_one t
  simp only [segmentPoint, Complex.add_im, Complex.smul_im, smul_eq_mul]
  rcases eq_or_lt_of_le h1 with h | h
  · rw [h]; simpa using τ₁.im_pos
  · exact add_pos_of_pos_of_nonneg (mul_pos (by linarith) τ₀.im_pos)
      (mul_nonneg h0 τ₁.im_pos.le)

theorem continuous_segmentPoint (τ₀ τ₁ : ℍ) : Continuous (segmentPoint τ₀ τ₁) :=
  ((continuous_const.sub continuous_clamp01).smul continuous_const).add
    (continuous_clamp01.smul continuous_const)

def segmentPath (τ₀ τ₁ : ℍ) (t : ℝ) : ℍ :=
  UpperHalfPlane.mk (segmentPoint τ₀ τ₁ t) (segmentPoint_im_pos τ₀ τ₁ t)

@[simp] theorem coe_segmentPath (τ₀ τ₁ : ℍ) (t : ℝ) :
    ((segmentPath τ₀ τ₁ t : ℍ) : ℂ) = segmentPoint τ₀ τ₁ t := rfl

theorem continuous_segmentPath (τ₀ τ₁ : ℍ) : Continuous (segmentPath τ₀ τ₁) :=
  (continuous_segmentPoint τ₀ τ₁).upperHalfPlaneMk _

variable (N : ℕ)

def periodIntegrand (τ₀ τ₁ : ℍ) (f : CuspForm (CongruenceSubgroup.Gamma0 N) 2) (t : ℝ) : ℂ :=
  f (segmentPath τ₀ τ₁ t) * ((τ₁ : ℂ) - τ₀)

theorem continuous_periodIntegrand (τ₀ τ₁ : ℍ) (f : CuspForm (CongruenceSubgroup.Gamma0 N) 2) :
    Continuous (periodIntegrand N τ₀ τ₁ f) :=
  ((f.holo'.continuous).comp (continuous_segmentPath τ₀ τ₁)).mul continuous_const

theorem intervalIntegrable_periodIntegrand (τ₀ τ₁ : ℍ)
    (f : CuspForm (CongruenceSubgroup.Gamma0 N) 2) (a b : ℝ) :
    IntervalIntegrable (periodIntegrand N τ₀ τ₁ f) MeasureTheory.volume a b :=
  (continuous_periodIntegrand N τ₀ τ₁ f).intervalIntegrable a b

theorem periodIntegrand_add (τ₀ τ₁ : ℍ) (f g : CuspForm (CongruenceSubgroup.Gamma0 N) 2) :
    periodIntegrand N τ₀ τ₁ (f + g) = periodIntegrand N τ₀ τ₁ f + periodIntegrand N τ₀ τ₁ g := by
  funext t
  simp [periodIntegrand, add_mul]

theorem periodIntegrand_smul (τ₀ τ₁ : ℍ) (c : ℂ) (f : CuspForm (CongruenceSubgroup.Gamma0 N) 2) :
    periodIntegrand N τ₀ τ₁ (c • f) = fun t => c * periodIntegrand N τ₀ τ₁ f t := by
  funext t
  simp [periodIntegrand, mul_assoc]

def periodAlong (τ₀ τ₁ : ℍ) : Module.Dual ℂ (CuspForm (CongruenceSubgroup.Gamma0 N) 2) where
  toFun f := ∫ t in (0 : ℝ)..1, periodIntegrand N τ₀ τ₁ f t
  map_add' f g := by
    rw [periodIntegrand_add]
    exact intervalIntegral.integral_add (intervalIntegrable_periodIntegrand N τ₀ τ₁ f 0 1)
      (intervalIntegrable_periodIntegrand N τ₀ τ₁ g 0 1)
  map_smul' c f := by
    rw [periodIntegrand_smul, RingHom.id_apply, smul_eq_mul]
    exact intervalIntegral.integral_const_mul c _

theorem periodAlong_apply (τ₀ τ₁ : ℍ) (f : CuspForm (CongruenceSubgroup.Gamma0 N) 2) :
    periodAlong N τ₀ τ₁ f = ∫ t in (0 : ℝ)..1, f (segmentPath τ₀ τ₁ t) * ((τ₁ : ℂ) - τ₀) :=
  rfl

def period (γ : CongruenceSubgroup.Gamma0 N) :
    Module.Dual ℂ (CuspForm (CongruenceSubgroup.Gamma0 N) 2) :=
  periodAlong N UpperHalfPlane.I ((γ : SL(2, ℤ)) • UpperHalfPlane.I)

theorem period_apply (γ : CongruenceSubgroup.Gamma0 N) (f : CuspForm (CongruenceSubgroup.Gamma0 N) 2) :
    period N γ f =
      ∫ t in (0 : ℝ)..1, f (segmentPath UpperHalfPlane.I ((γ : SL(2, ℤ)) • UpperHalfPlane.I) t) *
        ((((γ : SL(2, ℤ)) • UpperHalfPlane.I : ℍ) : ℂ) - (UpperHalfPlane.I : ℂ)) :=
  rfl

def periodLattice : Submodule ℤ (Module.Dual ℂ (CuspForm (CongruenceSubgroup.Gamma0 N) 2)) :=
  Submodule.span ℤ (Set.range (period N))

theorem period_mem_periodLattice (γ : CongruenceSubgroup.Gamma0 N) : period N γ ∈ periodLattice N :=
  Submodule.subset_span (Set.mem_range_self γ)

end Period

section Hecke

variable (N : ℕ) [NeZero N]

def cuspHeckeGen (ℓ : Nat.Primes) : CuspForm.heckeAlgebra N 2 (∅ : Set ℕ) :=
  if h : (ℓ : ℕ) ∣ N then CuspForm.heckeAlgebra.U (S := (∅ : Set ℕ)) ℓ.prop h (Set.notMem_empty _)
  else CuspForm.heckeAlgebra.T (S := (∅ : Set ℕ)) ℓ.prop h (Set.notMem_empty _)

theorem cuspHeckeGen_of_dvd (ℓ : Nat.Primes) (h : (ℓ : ℕ) ∣ N) :
    (cuspHeckeGen N ℓ : Module.End ℂ (CuspForm (CongruenceSubgroup.Gamma0 N) 2)) =
      CuspForm.heckeULin 2 h := by
  rw [cuspHeckeGen, dif_pos h]; rfl

theorem cuspHeckeGen_of_not_dvd (ℓ : Nat.Primes) (h : ¬ (ℓ : ℕ) ∣ N) :
    (cuspHeckeGen N ℓ : Module.End ℂ (CuspForm (CongruenceSubgroup.Gamma0 N) 2)) =
      CuspForm.heckeTLin 2 ℓ.prop h := by
  rw [cuspHeckeGen, dif_neg h]; rfl

def cuspHeckeAeval : HeckeAlg →ₐ[ℤ] CuspForm.heckeAlgebra N 2 (∅ : Set ℕ) :=
  MvPolynomial.aeval (cuspHeckeGen N)

@[simp] theorem cuspHeckeAeval_heckeGen (ℓ : Nat.Primes) :
    cuspHeckeAeval N (heckeGen ℓ) = cuspHeckeGen N ℓ :=
  MvPolynomial.aeval_X _ ℓ

theorem range_cuspHeckeGen : Set.range (cuspHeckeGen N) =
    {x : CuspForm.heckeAlgebra N 2 (∅ : Set ℕ) |
      (x : Module.End ℂ (CuspForm (CongruenceSubgroup.Gamma0 N) 2)) ∈
        CuspForm.heckeGenerators N 2 (∅ : Set ℕ)} := by
  ext x
  constructor
  · rintro ⟨ℓ, rfl⟩
    by_cases h : (ℓ : ℕ) ∣ N
    · rw [Set.mem_setOf_eq, cuspHeckeGen_of_dvd N ℓ h]
      exact CuspForm.heckeULin_mem_heckeGenerators ℓ.prop h (Set.notMem_empty _)
    · rw [Set.mem_setOf_eq, cuspHeckeGen_of_not_dvd N ℓ h]
      exact CuspForm.heckeTLin_mem_heckeGenerators ℓ.prop h (Set.notMem_empty _)
  · rintro (⟨ℓ, hℓ, hℓN, -, hx⟩ | ⟨q, hqN, hq, -, hx⟩)
    · refine ⟨⟨ℓ, hℓ⟩, Subtype.ext ?_⟩
      rw [hx]; exact cuspHeckeGen_of_not_dvd N ⟨ℓ, hℓ⟩ hℓN
    · refine ⟨⟨q, hq⟩, Subtype.ext ?_⟩
      rw [hx]; exact cuspHeckeGen_of_dvd N ⟨q, hq⟩ hqN

theorem cuspHeckeAeval_range : (cuspHeckeAeval N).range = ⊤ := by
  rw [cuspHeckeAeval, ← Algebra.adjoin_range_eq_range_aeval, range_cuspHeckeGen]
  set H := CuspForm.heckeAlgebra N 2 (∅ : Set ℕ)
  apply Subalgebra.map_injective (f := H.val) Subtype.val_injective
  rw [AlgHom.map_adjoin, Algebra.map_top, Subalgebra.range_val]
  have himg : (H.val : H → Module.End ℂ (CuspForm (CongruenceSubgroup.Gamma0 N) 2)) ''
      {x : H | (x : Module.End ℂ _) ∈ CuspForm.heckeGenerators N 2 (∅ : Set ℕ)} =
      CuspForm.heckeGenerators N 2 (∅ : Set ℕ) := by
    ext T
    constructor
    · rintro ⟨x, hx, rfl⟩; exact hx
    · intro hT
      exact ⟨⟨T, Algebra.subset_adjoin hT⟩, hT, rfl⟩
  rw [himg]
  rfl

def cuspHeckeRep : HeckeAlg →+* Module.End ℂ (CuspForm (CongruenceSubgroup.Gamma0 N) 2) :=
  ((CuspForm.heckeAlgebra N 2 (∅ : Set ℕ)).val.comp (cuspHeckeAeval N)).toRingHom

theorem cuspHeckeRep_apply (t : HeckeAlg) :
    cuspHeckeRep N t = (cuspHeckeAeval N t : Module.End ℂ (CuspForm (CongruenceSubgroup.Gamma0 N) 2)) :=
  rfl

theorem cuspHeckeRep_heckeGen (ℓ : Nat.Primes) :
    cuspHeckeRep N (heckeGen ℓ) = (cuspHeckeGen N ℓ : Module.End ℂ _) := by
  rw [cuspHeckeRep_apply, cuspHeckeAeval_heckeGen]

theorem cuspHeckeRep_mem (t : HeckeAlg) : cuspHeckeRep N t ∈ CuspForm.heckeAlgebra N 2 (∅ : Set ℕ) :=
  (cuspHeckeAeval N t).2

theorem range_cuspHeckeRep :
    Set.range (cuspHeckeRep N) = (CuspForm.heckeAlgebra N 2 (∅ : Set ℕ) : Set _) := by
  ext T
  constructor
  · rintro ⟨t, rfl⟩; exact cuspHeckeRep_mem N t
  · intro hT
    have : (⟨T, hT⟩ : CuspForm.heckeAlgebra N 2 (∅ : Set ℕ)) ∈ (cuspHeckeAeval N).range := by
      rw [cuspHeckeAeval_range]; trivial
    obtain ⟨t, ht⟩ := this
    exact ⟨t, congrArg Subtype.val ht⟩

theorem cuspHeckeRep_comm (s t : HeckeAlg) :
    cuspHeckeRep N s * cuspHeckeRep N t = cuspHeckeRep N t * cuspHeckeRep N s := by
  rw [← map_mul, ← map_mul, mul_comm]

def dualHeckeRep : HeckeAlg →+* Module.End ℂ (Module.Dual ℂ (CuspForm (CongruenceSubgroup.Gamma0 N) 2)) where
  toFun t := (cuspHeckeRep N t).dualMap
  map_one' := by rw [map_one]; exact LinearMap.dualMap_id
  map_mul' s t := by
    rw [mul_comm s t, map_mul]
    exact (LinearMap.dualMap_comp_dualMap (cuspHeckeRep N s) (cuspHeckeRep N t)).symm
  map_zero' := by
    rw [map_zero]; exact map_zero (Module.Dual.transpose (R := ℂ))
  map_add' s t := by
    rw [map_add]; exact map_add (Module.Dual.transpose (R := ℂ)) _ _

theorem dualHeckeRep_apply (t : HeckeAlg) :
    dualHeckeRep N t = (cuspHeckeRep N t).dualMap := rfl

@[simp] theorem dualHeckeRep_apply_apply (t : HeckeAlg)
    (φ : Module.Dual ℂ (CuspForm (CongruenceSubgroup.Gamma0 N) 2))
    (f : CuspForm (CongruenceSubgroup.Gamma0 N) 2) :
    dualHeckeRep N t φ f = φ (cuspHeckeRep N t f) := rfl

theorem dualHeckeRep_C (a : ℤ) (φ : Module.Dual ℂ (CuspForm (CongruenceSubgroup.Gamma0 N) 2)) :
    dualHeckeRep N (MvPolynomial.C a) φ = a • φ := by
  ext f
  rw [dualHeckeRep_apply_apply, ← MvPolynomial.algebraMap_eq, eq_intCast, map_intCast,
    Module.End.intCast_apply, map_zsmul, LinearMap.smul_apply]

def PeriodLatticeHeckeStable : Prop :=
  ∀ (ℓ : Nat.Primes) (x : Module.Dual ℂ (CuspForm (CongruenceSubgroup.Gamma0 N) 2)),
    x ∈ periodLattice N → dualHeckeRep N (heckeGen ℓ) x ∈ periodLattice N

variable {N}

theorem periodLattice_stable_of (h : PeriodLatticeHeckeStable N) (t : HeckeAlg)
    (x : Module.Dual ℂ (CuspForm (CongruenceSubgroup.Gamma0 N) 2)) (hx : x ∈ periodLattice N) :
    dualHeckeRep N t x ∈ periodLattice N := by
  induction t using MvPolynomial.induction_on generalizing x with
  | C a => rw [dualHeckeRep_C]; exact Submodule.smul_mem _ a hx
  | add p q hp hq => rw [map_add, LinearMap.add_apply]; exact Submodule.add_mem _ (hp x hx) (hq x hx)
  | mul_X p ℓ hp =>
    rw [map_mul, Module.End.mul_apply]
    exact hp _ (h ℓ x hx)

variable (N)

def periodLatticeRestrict (h : PeriodLatticeHeckeStable N) (t : HeckeAlg) :
    Module.End ℤ (periodLattice N) :=
  ((dualHeckeRep N t).toAddMonoidHom.toIntLinearMap).restrict
    (fun x hx => periodLattice_stable_of h t x hx)

@[simp] theorem coe_periodLatticeRestrict_apply (h : PeriodLatticeHeckeStable N) (t : HeckeAlg)
    (x : periodLattice N) :
    ((periodLatticeRestrict N h t x : periodLattice N) : Module.Dual ℂ _) = dualHeckeRep N t x :=
  rfl

def periodLatticeRestrictHom (h : PeriodLatticeHeckeStable N) :
    HeckeAlg →+* Module.End ℤ (periodLattice N) where
  toFun := periodLatticeRestrict N h
  map_one' := LinearMap.ext fun x => Subtype.ext (by simp)
  map_mul' s t := LinearMap.ext fun x => Subtype.ext (by simp)
  map_zero' := LinearMap.ext fun x => Subtype.ext (by simp)
  map_add' s t := LinearMap.ext fun x => Subtype.ext (by simp)

open Classical in

def periodLatticeHeckeEnd : HeckeAlg →+* Module.End ℤ (periodLattice N) :=
  if h : PeriodLatticeHeckeStable N then periodLatticeRestrictHom N h
  else (Int.castRingHom (Module.End ℤ (periodLattice N))).comp
    (MvPolynomial.eval₂Hom (Int.castRingHom ℤ) (0 : Nat.Primes → ℤ))

variable {N}

theorem coe_periodLatticeHeckeEnd_apply (h : PeriodLatticeHeckeStable N) (t : HeckeAlg)
    (x : periodLattice N) :
    ((periodLatticeHeckeEnd N t x : periodLattice N) : Module.Dual ℂ _) = dualHeckeRep N t x := by
  have e : periodLatticeHeckeEnd N = periodLatticeRestrictHom N h := dif_pos h
  rw [e]; rfl

theorem periodLatticeHeckeEnd_of_not (h : ¬ PeriodLatticeHeckeStable N) (t : HeckeAlg)
    (x : periodLattice N) :
    periodLatticeHeckeEnd N t x = MvPolynomial.constantCoeff t • x := by
  have e : periodLatticeHeckeEnd N = (Int.castRingHom (Module.End ℤ (periodLattice N))).comp
      (MvPolynomial.eval₂Hom (Int.castRingHom ℤ) (0 : Nat.Primes → ℤ)) := dif_neg h
  rw [e, RingHom.comp_apply, MvPolynomial.eval₂Hom_zero_apply]
  simp only [eq_intCast, Int.cast_id, Module.End.intCast_apply]

variable (N)

@[implicit_reducible]
def periodLatticeModule : Module HeckeAlg (periodLattice N) :=
  Module.compHom (periodLattice N) (periodLatticeHeckeEnd N)

set_option synthInstance.maxHeartbeats 200000 in
theorem periodLatticeModule_smul_def (t : HeckeAlg) (x : periodLattice N) :
    (letI : Module HeckeAlg (periodLattice N) := periodLatticeModule N; t • x) =
      periodLatticeHeckeEnd N t x :=
  rfl

end Hecke

end ModularCurve

end

Statements phrased using this module (45)