Definitions/Def_ModularCurve_KroneckerTransport.lean
Coefficient reduction of Laurent series and the Kronecker congruence
For a ring homomorphism f : R \to S of commutative rings, laurentMap f is the coefficientwise map R((q)) \to S((q)) of Laurent (Hahn) series, packaged as a ring homomorphism; its basic properties record the value on a coefficient, on a monomial HahnSeries.single k r, on the image of a power series, compatibility with the substitution operator q \mapsto q^N (qExpand), injectivity for injective f, and composition. Over \mathbb{Z}, jqInt is the integral j-expansion q^{-1}\,\mathrm{jNum}, where \mathrm{jNum} = E_4^3 \cdot \eta-unit{}^{-1} is the integral power series with constant term 1 fixed in the X_0 definitions; laurentMap along \mathbb{Z} \hookrightarrow \mathbb{Q} carries it to jq, and jqIntN N is its q \mapsto q^N substitute. The accompanying coefficient lemmas state that the coefficient of q^{-1} in jqInt is 1, that all lower coefficients vanish, and correspondingly that (\mathrm{jqInt})^b has coefficient 1 in degree -b and vanishes below. Reducing along \mathbb{Z} \to \mathbb{Z}/\ell gives jqMod ℓ and jqNMod ℓ N with the same leading-coefficient statements, and evalAtJInt, evalAtJMod ℓ are the evaluation homomorphisms \mathbb{Z}[X] \to \mathbb{Z}((q)), (\mathbb{Z}/\ell)[X] \to (\mathbb{Z}/\ell)((q)) sending X to jqInt, jqMod ℓ, compatible with reduction and with evalAtJ.
reduceModBivar ℓ is coefficientwise reduction \mathbb{Z}[X][Y] \to (\mathbb{Z}/\ell)[X][Y]. For a prime-power-free datum, KroneckerCongruence ℓ data is a predicate on a chosen modular-equation datum data : ModularPolynomialData ℓ (a structure carrying a monic bivariate \Phi, its degree \psi(\ell) in the outer variable, and the vanishing of \Phi at (j(q), j(q^\ell)) as fields): it asserts the identity \overline{\Phi} = (X^{\ell} - Y)(X - Y^{\ell}) in (\mathbb{Z}/\ell)[X][Y], with X the inner variable (the j(q) slot) and Y the outer one (the j(q^\ell) slot). Finally, for \ell prime, modularFunctionFieldMod ℓ N is the intermediate field (\mathbb{Z}/\ell)(\bar j(q), \bar j(q^N)) of (\mathbb{Z}/\ell)((q)), with its two generators exhibited as members.
Relation to Mathlib
Mathlib supplies HahnSeries.map together with its multiplicativity lemmas; laurentMap bundles these into a ring homomorphism of Laurent series rings, the analogue for Laurent series of Polynomial.mapRingHom. The Kronecker congruence and the integral and mod-\ell j-expansions are the project's own notions.
Where it is used
These definitions form the definitional layer for the Kronecker-congruence leg of the Eichler–Shimura relation: the modular equation for X_0(\ell), established over \mathbb{Q}((q)), is transported coefficientwise to characteristic \ell, where its reduction is required to factor as (X^{\ell} - Y)(X - Y^{\ell}).
References
- S. Lang, Elliptic Functions, 2nd edition, Graduate Texts in Mathematics 112, Springer, 1987, Chapter 5
- G. Shimura, Introduction to the Arithmetic Theory of Automorphic Functions, Publications of the Mathematical Society of Japan 11, 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.
- 215 lines
- 38 declarations
- used in the statements of 17 theorems and imported by 70 proofs
- imports 1 definition modules
Source file: Definitions/Def_ModularCurve_KroneckerTransport.lean
Imports
Declarations
- def
ModularCurve.laurentMap - theorem
ModularCurve.laurentMap_coeff - theorem
ModularCurve.laurentMap_single - theorem
ModularCurve.laurentMap_ofPowerSeries - theorem
ModularCurve.laurentMap_qExpand - theorem
ModularCurve.laurentMap_injective - theorem
ModularCurve.laurentMap_laurentMap - def
ModularCurve.jqInt - theorem
ModularCurve.laurentMap_jqInt - def
ModularCurve.jqIntN - theorem
ModularCurve.laurentMap_jqIntN - theorem
ModularCurve.coeff_jqInt_cast - theorem
ModularCurve.coeff_jqInt_neg_one - theorem
ModularCurve.coeff_jqInt_of_lt - theorem
ModularCurve.coeff_jqInt_pow_self - theorem
ModularCurve.coeff_jqInt_pow_of_lt - def
ModularCurve.reduceModBivar - theorem
ModularCurve.reduceModBivar_X - theorem
ModularCurve.reduceModBivar_C_X - def
ModularCurve.KroneckerCongruence - def
ModularCurve.evalAtJInt - theorem
ModularCurve.evalAtJInt_X - theorem
ModularCurve.laurentMap_comp_evalAtJInt - def
ModularCurve.jqMod - def
ModularCurve.jqNMod - theorem
ModularCurve.jqNMod_one - theorem
ModularCurve.laurentMap_jqIntN_mod - theorem
ModularCurve.coeff_jqMod - theorem
ModularCurve.coeff_jqMod_neg_one - theorem
ModularCurve.coeff_jqMod_of_lt - theorem
ModularCurve.coeff_jqMod_pow_self - theorem
ModularCurve.coeff_jqMod_pow_of_lt - def
ModularCurve.evalAtJMod - theorem
ModularCurve.evalAtJMod_X - theorem
ModularCurve.evalAtJMod_comp_map - def
ModularCurve.modularFunctionFieldMod - theorem
ModularCurve.jqMod_mem - theorem
ModularCurve.jqNMod_mem
Source
import Mathlib import Definitions.Def_ModularCurve_X0 noncomputable section open PowerSeries HahnSeries IntermediateField namespace ModularCurve section LaurentMap variable {R S T : Type*} [CommRing R] [CommRing S] [CommRing T] def laurentMap (f : R →+* S) : LaurentSeries R →+* LaurentSeries S where toFun x := x.map f map_one' := HahnSeries.map_one (R := R) (S := S) f.toMonoidWithZeroHom map_mul' _ _ := HahnSeries.map_mul (R := R) (S := S) f.toNonUnitalRingHom map_zero' := by ext k show f ((0 : LaurentSeries R).coeff k) = (0 : LaurentSeries S).coeff k rw [HahnSeries.coeff_zero, HahnSeries.coeff_zero, map_zero] map_add' x y := by ext k show f ((x + y).coeff k) = (x.map f + y.map f).coeff k rw [HahnSeries.coeff_add, HahnSeries.coeff_add, map_add] rfl @[simp] theorem laurentMap_coeff (f : R →+* S) (x : LaurentSeries R) (k : ℤ) : (laurentMap f x).coeff k = f (x.coeff k) := rfl @[simp] theorem laurentMap_single (f : R →+* S) (k : ℤ) (r : R) : laurentMap f (HahnSeries.single k r) = HahnSeries.single k (f r) := by ext g rw [laurentMap_coeff, HahnSeries.coeff_single, HahnSeries.coeff_single, apply_ite f, map_zero] theorem laurentMap_ofPowerSeries (f : R →+* S) (p : PowerSeries R) : laurentMap f (HahnSeries.ofPowerSeries ℤ R p) = HahnSeries.ofPowerSeries ℤ S (p.map f) := by ext k rw [laurentMap_coeff] rcases le_or_gt 0 k with hk | hk · lift k to ℕ using hk rw [HahnSeries.ofPowerSeries_apply_coeff, HahnSeries.ofPowerSeries_apply_coeff, PowerSeries.coeff_map] · rw [ofPowerSeries_coeff_of_neg _ hk, ofPowerSeries_coeff_of_neg _ hk, map_zero] theorem laurentMap_qExpand (f : R →+* S) (N : ℕ) [NeZero N] (x : LaurentSeries R) : laurentMap f (qExpand R N x) = qExpand S N (laurentMap f x) := by ext k rw [laurentMap_coeff] by_cases hk : (N : ℤ) ∣ k · obtain ⟨m, rfl⟩ := hk rw [qExpand_coeff_mul, qExpand_coeff_mul, laurentMap_coeff] · rw [qExpand_coeff_of_not_dvd N x hk, qExpand_coeff_of_not_dvd N _ hk, map_zero] theorem laurentMap_injective {f : R →+* S} (hf : Function.Injective f) : Function.Injective (laurentMap f) := by intro x y hxy ext k exact hf (by simpa using congrArg (fun z => z.coeff k) hxy) theorem laurentMap_laurentMap (f : R →+* S) (g : S →+* T) (x : LaurentSeries R) : laurentMap g (laurentMap f x) = laurentMap (g.comp f) x := by ext k simp end LaurentMap section IntegralJ def jqInt : LaurentSeries ℤ := HahnSeries.single (-1 : ℤ) 1 * HahnSeries.ofPowerSeries ℤ ℤ jNum theorem laurentMap_jqInt : laurentMap (Int.castRingHom ℚ) jqInt = jq := by rw [jqInt, map_mul, laurentMap_single, laurentMap_ofPowerSeries, jq, jNumQ, map_one] def jqIntN (N : ℕ) [NeZero N] : LaurentSeries ℤ := qExpand ℤ N jqInt theorem laurentMap_jqIntN (N : ℕ) [NeZero N] : laurentMap (Int.castRingHom ℚ) (jqIntN N) = jqN N := by rw [jqIntN, laurentMap_qExpand, laurentMap_jqInt, jqN] theorem coeff_jqInt_cast (k : ℤ) : ((jqInt.coeff k : ℤ) : ℚ) = jq.coeff k := by rw [← laurentMap_jqInt, laurentMap_coeff] rfl theorem coeff_jqInt_neg_one : jqInt.coeff (-1 : ℤ) = 1 := Int.cast_injective (α := ℚ) (by rw [coeff_jqInt_cast, coeff_jq_neg_one, Int.cast_one]) theorem coeff_jqInt_of_lt {k : ℤ} (hk : k < -1) : jqInt.coeff k = 0 := Int.cast_injective (α := ℚ) (by rw [coeff_jqInt_cast, coeff_jq_of_lt hk, Int.cast_zero]) theorem coeff_jqInt_pow_self (b : ℕ) : (jqInt ^ b).coeff (-(b : ℤ)) = 1 := by refine Int.cast_injective (α := ℚ) ?_ have h : ((jqInt ^ b).coeff (-(b : ℤ)) : ℚ) = (jq ^ b).coeff (-(b : ℤ)) := by rw [← laurentMap_jqInt, ← map_pow, laurentMap_coeff]; rfl rw [h, coeff_jq_pow_self, Int.cast_one] theorem coeff_jqInt_pow_of_lt {b : ℕ} {m : ℤ} (hm : m < -(b : ℤ)) : (jqInt ^ b).coeff m = 0 := by refine Int.cast_injective (α := ℚ) ?_ have h : ((jqInt ^ b).coeff m : ℚ) = (jq ^ b).coeff m := by rw [← laurentMap_jqInt, ← map_pow, laurentMap_coeff]; rfl rw [h, coeff_jq_pow_of_lt hm, Int.cast_zero] end IntegralJ section ReduceModBivar def reduceModBivar (ℓ : ℕ) : Polynomial (Polynomial ℤ) →+* Polynomial (Polynomial (ZMod ℓ)) := Polynomial.mapRingHom (Polynomial.mapRingHom (Int.castRingHom (ZMod ℓ))) @[simp] theorem reduceModBivar_X (ℓ : ℕ) : reduceModBivar ℓ Polynomial.X = Polynomial.X := by simp [reduceModBivar, Polynomial.coe_mapRingHom] @[simp] theorem reduceModBivar_C_X (ℓ : ℕ) : reduceModBivar ℓ (Polynomial.C Polynomial.X) = Polynomial.C Polynomial.X := by simp [reduceModBivar, Polynomial.coe_mapRingHom] end ReduceModBivar def KroneckerCongruence (ℓ : ℕ) [NeZero ℓ] (data : ModularPolynomialData ℓ) : Prop := reduceModBivar ℓ data.Φ = (Polynomial.C Polynomial.X ^ ℓ - Polynomial.X) * (Polynomial.C Polynomial.X - Polynomial.X ^ ℓ) section IntegralEquation def evalAtJInt : Polynomial ℤ →+* LaurentSeries ℤ := Polynomial.eval₂RingHom (Int.castRingHom (LaurentSeries ℤ)) jqInt @[simp] theorem evalAtJInt_X : evalAtJInt Polynomial.X = jqInt := Polynomial.eval₂_X _ _ theorem laurentMap_comp_evalAtJInt : (laurentMap (Int.castRingHom ℚ)).comp evalAtJInt = evalAtJ := by refine Polynomial.ringHom_ext' (Subsingleton.elim _ _) ?_ rw [RingHom.comp_apply, evalAtJInt_X, laurentMap_jqInt, evalAtJ_X] end IntegralEquation section ModEquation variable (ℓ : ℕ) def jqMod : LaurentSeries (ZMod ℓ) := laurentMap (Int.castRingHom (ZMod ℓ)) jqInt def jqNMod (N : ℕ) [NeZero N] : LaurentSeries (ZMod ℓ) := qExpand (ZMod ℓ) N (jqMod ℓ) @[simp] theorem jqNMod_one : jqNMod ℓ 1 = jqMod ℓ := qExpand_one_apply _ theorem laurentMap_jqIntN_mod (N : ℕ) [NeZero N] : laurentMap (Int.castRingHom (ZMod ℓ)) (jqIntN N) = jqNMod ℓ N := by rw [jqIntN, laurentMap_qExpand, jqNMod, jqMod] theorem coeff_jqMod (k : ℤ) : (jqMod ℓ).coeff k = (jqInt.coeff k : ZMod ℓ) := rfl theorem coeff_jqMod_neg_one : (jqMod ℓ).coeff (-1 : ℤ) = 1 := by rw [coeff_jqMod, coeff_jqInt_neg_one, Int.cast_one] theorem coeff_jqMod_of_lt {k : ℤ} (hk : k < -1) : (jqMod ℓ).coeff k = 0 := by rw [coeff_jqMod, coeff_jqInt_of_lt hk, Int.cast_zero] theorem coeff_jqMod_pow_self (b : ℕ) : ((jqMod ℓ) ^ b).coeff (-(b : ℤ)) = 1 := by have h : ((jqMod ℓ) ^ b).coeff (-(b : ℤ)) = ((jqInt ^ b).coeff (-(b : ℤ)) : ZMod ℓ) := by rw [jqMod, ← map_pow, laurentMap_coeff]; rfl rw [h, coeff_jqInt_pow_self, Int.cast_one] theorem coeff_jqMod_pow_of_lt {b : ℕ} {m : ℤ} (hm : m < -(b : ℤ)) : ((jqMod ℓ) ^ b).coeff m = 0 := by have h : ((jqMod ℓ) ^ b).coeff m = ((jqInt ^ b).coeff m : ZMod ℓ) := by rw [jqMod, ← map_pow, laurentMap_coeff]; rfl rw [h, coeff_jqInt_pow_of_lt hm, Int.cast_zero] def evalAtJMod : Polynomial (ZMod ℓ) →+* LaurentSeries (ZMod ℓ) := Polynomial.eval₂RingHom (algebraMap (ZMod ℓ) (LaurentSeries (ZMod ℓ))) (jqMod ℓ) @[simp] theorem evalAtJMod_X : evalAtJMod ℓ Polynomial.X = jqMod ℓ := Polynomial.eval₂_X _ _ theorem evalAtJMod_comp_map : (evalAtJMod ℓ).comp (Polynomial.mapRingHom (Int.castRingHom (ZMod ℓ))) = (laurentMap (Int.castRingHom (ZMod ℓ))).comp evalAtJInt := by refine Polynomial.ringHom_ext' (Subsingleton.elim _ _) ?_ rw [RingHom.comp_apply, RingHom.comp_apply, Polynomial.coe_mapRingHom, Polynomial.map_X, evalAtJMod_X, evalAtJInt_X, jqMod] end ModEquation section ModFunctionField variable (ℓ : ℕ) [Fact ℓ.Prime] def modularFunctionFieldMod (N : ℕ) [NeZero N] : IntermediateField (ZMod ℓ) (LaurentSeries (ZMod ℓ)) := IntermediateField.adjoin (ZMod ℓ) {jqMod ℓ, jqNMod ℓ N} theorem jqMod_mem (N : ℕ) [NeZero N] : jqMod ℓ ∈ modularFunctionFieldMod ℓ N := IntermediateField.subset_adjoin _ _ (Set.mem_insert _ _) theorem jqNMod_mem (N : ℕ) [NeZero N] : jqNMod ℓ N ∈ modularFunctionFieldMod ℓ N := IntermediateField.subset_adjoin _ _ (Set.mem_insert_of_mem _ rfl) end ModFunctionField end ModularCurve
Statements phrased using this module (17)
- Kronecker congruence for prime-level modular polynomial data
ModularCurve.kroneckerCongruence49 below · depth 9 - Existence of a Kronecker-congruent modular polynomial at a prime
ModularCurve.exists_kroneckerCongruence_of_prime52 below · depth 11 - Uniqueness of the Kronecker remainder modulo p
ModularCurve.existsUnique_kroneckerRemainder0 below · depth 15 - Kronecker's congruence for modular polynomials of prime level
ModularCurve.kroneckerCongruence_of_prime58 below · depth 15 - Uniqueness of the modular polynomial at prime level
ModularCurve.modularPolynomialData_phi_unique_of_prime46 below · depth 15 - Nonvanishing derivatives of Φ_ℓ at (b,b^ℓ) in characteristic ℓ
ModularCurve.derivative_evalEval_ne_zero_of_kroneckerCongruence_of_pow_sq_ne0 below · depth 16 - Kronecker congruence for the integral j-expansion: j(q^q)≡ j(q)^q (mod q)
ModularCurve.exists_qExpand_jqInt_sub_pow_eq_natCast_mul2 below · depth 19 - Kronecker congruence to second order in characteristic q
ModularCurve.laurentMap_evalAtJInt_kroneckerRemainder_eval_X_pow1 below · depth 19 - Dwork quotient satisfies the θ-identity mod q
ModularCurve.thetaL_laurentMap_dworkQuotient1 below · depth 19 - Integrality of the modular equation over ℤ((q))
ModularCurve.ModularPolynomialData.eval_int_eq_zero0 below · depth 20 - Existence of a λ-modular polynomial with Kronecker's congruence
ModularCurve.exists_lambdaKroneckerCongruence202 below · depth 21 - Uniqueness of the q-th Kronecker remainder for Ψ_q
ModularCurve.existsUnique_lambdaKroneckerRemainder0 below · depth 22 - Kronecker congruence for the λ modular equation
ModularCurve.kroneckerCongruence_lambda179 below · depth 22 - Kronecker remainder along the Frobenius graph for λ
ModularCurve.laurentMap_evalAtLambdaInt_kroneckerRemainder_eval_X_pow0 below · depth 25 - A θ-identity for the Dwork quotient of λ
ModularCurve.thetaL_laurentMap_lambdaDworkQuotient1 below · depth 25 - Simple zero of p/(jₚ-jᵖ) at a supersingular value
ModularCurve.exists_natCast_mul_inv_nodeCoord_mem_integers_ord_residue_eq_one_inftyChart196 below · depth 26 - Integrality of p/(jₚ-jᵖ) and a simple zero at supersingular a
ModularCurve.exists_natCast_mul_inv_nodeCoord_mem_integers_ord_residue_eq_one_inftyChart_univ196 below · depth 27