Definitions/Def_ModularCurve_PDPairing.lean
Cup-product pairing on parabolic cohomology, degeneracy maps, Hecke operators
For a group \Phi and two additive characters \varphi,\psi:\mathrm{Additive}\,\Phi\to R with values in a commutative ring, omega is the 2-cocycle \omega(g,g')=\varphi(g)\psi(g')-\psi(g)\varphi(g') (shown to vanish on 1 and on g^{-1},g, to satisfy the cocycle identity and to be antisymmetric in (\varphi,\psi)), CentralExt φ ψ is the group structure on R\times\Phi with product (r,g)(r',g')=(r+r'-\omega(g,g'),gg'), and CentralExt.snd is its projection to \Phi. When \Phi is free, sect is the homomorphic section sending each free generator a to (0,a), and hPrim φ ψ g is the first coordinate of \mathrm{sect}(g): the unique function with h(gg')=h(g)+h(g')-\omega(g,g') vanishing on the chosen generators (hPrim_unique), additive and R-homogeneous in \varphi and antisymmetric. For a finite-index \Phi\le\mathrm{SL}_2(\mathbb Z), Cusp Φ is the (finite) set of orbits of \langle T\rangle on \mathrm{SL}_2(\mathbb Z)/\Phi, cuspGen q the element g^{-1}T^{n}g\in\Phi built from a chosen representative g and the minimal period n of the orbit, cuspSum f =\sum_q f(\mathrm{cuspGen}\,q), and pairF Φ φ ψ =\tfrac12\,\mathrm{cuspSum}(h_{\varphi,\psi}) for free \Phi and 2 invertible in R. Descent: resInf restricts characters of \Gamma to \Gamma\cap\Lambda (free by Nielsen–Schreier when \Lambda is), and pairD divides \mathrm{pairF}(\Gamma\cap\Lambda) of the restrictions by [\Gamma:\Gamma\cap\Lambda]. Over \mathbb Z, pairZFun N φ ψ is the natural-number quotient 48/[\Gamma_0(N):\Gamma_0(N)\cap\Gamma(4)] times the cusp sum of h for the restrictions to \Gamma_0(N)\cap\Gamma(4); it is bilinear and antisymmetric, and pairZ N bundles it as a \mathbb Z-bilinear form on parabolicHoms ℤ (Gamma0 N) ℤ, the submodule of homomorphisms killing all \gamma with \mathrm{tr}(\gamma)^2=4. Alongside: conjUpperMat/conjLowerMat, conjugation by \mathrm{diag}(1,\ell) and its inverse on matrices with the relevant entry divisible by \ell; the degeneracy embedding iotaDeg0 : \Gamma_0(M')\to\Gamma_0(M) for M\mid M', d\mid M'/M, injective with finite-index range containing \Gamma(M'd)\cap\Gamma_0(M), with pullback iDeg0 and transfer jDeg0 on characters; Gamma0Upper ℓ (upper right entry \equiv 0 \bmod \ell), a finite-index congruence subgroup, its intersection Gamma0HUpper with \Gamma_0(M), the conjugation map conjL0 into \Gamma_0(M) and the operator heckeT0 sending \varphi to the transfer of \varphi\circ\mathrm{conjL0}; and coresAdd, the additive form of the group transfer, with its additivity and R-homogeneity.
Relation to Mathlib
Mathlib supplies MonoidHom.transfer and Subgroup.leftTransversals.diff only multiplicatively; coresAdd repackages the transfer for additive coefficient groups, and transfer_one/transfer_mul record its additivity in the character. Gamma0Upper is the upper-triangular counterpart of Mathlib's CongruenceSubgroup.Gamma0. The cocycle omega, the central extension CentralExt, the primitive hPrim, the cusp set and the pairings are the project's own; the ambient groups \Gamma_0, \Gamma and the freeness machinery (IsFreeGroup, Nielsen–Schreier) are Mathlib's.
Where it is used
These definitions provide the antisymmetric cup-product pairing on parabolic cohomology of \Gamma_0(N) with integral coefficients, together with the degeneracy maps between levels and the Hecke operators acting on it, as used in the modular-curve input to level lowering.
References
- K. S. Brown, Cohomology of Groups, Graduate Texts in Mathematics 87, Springer, 1982
- J.-P. Serre, Trees, Springer, 1980
- 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.
- 672 lines
- 89 declarations
- used in the statements of 8 theorems and imported by 14 proofs
- imports 1 definition modules
Source file: Definitions/Def_ModularCurve_PDPairing.lean
Imports
Imported by
Declarations
- theorem
ModularCurve.PDPairing.leftTransversals_diff_one - theorem
ModularCurve.PDPairing.leftTransversals_diff_mul - theorem
ModularCurve.PDPairing.transfer_one - theorem
ModularCurve.PDPairing.transfer_mul - theorem
ModularCurve.PDPairing.toMultiplicativeRight_zero - theorem
ModularCurve.PDPairing.toMultiplicativeRight_add - theorem
ModularCurve.PDPairing.toAdditiveLeft_one - theorem
ModularCurve.PDPairing.toAdditiveLeft_mul - def
ModularCurve.PDPairing.coresAdd - theorem
ModularCurve.PDPairing.coresAdd_zero - theorem
ModularCurve.PDPairing.coresAdd_add - theorem
ModularCurve.PDPairing.coresAdd_smul - def
ModularCurve.PDPairing.conjUpperMat - theorem
ModularCurve.PDPairing.conjUpperMat_apply_11 - theorem
ModularCurve.PDPairing.conjUpperMat_apply_10 - theorem
ModularCurve.PDPairing.conjUpperMat_mul - def
ModularCurve.PDPairing.conjLowerMat - theorem
ModularCurve.PDPairing.conjLowerMat_mul - theorem
ModularCurve.PDPairing.conjLowerMat_conjUpperMat - theorem
ModularCurve.PDPairing.exists_eq0 - theorem
ModularCurve.PDPairing.dvd_entry0 - theorem
ModularCurve.PDPairing.conjLowerMat_mem0 - def
ModularCurve.PDPairing.iotaDeg0 - def
ModularCurve.PDPairing.iDeg0 - theorem
ModularCurve.PDPairing.Gamma_subgroupOf_le_range_iotaDeg0 - instance
ModularCurve.PDPairing.iotaDeg0_range_finiteIndex - theorem
ModularCurve.PDPairing.iotaDeg0_injective - def
ModularCurve.PDPairing.pushChar0 - def
ModularCurve.PDPairing.jDeg0 - def
ModularCurve.PDPairing.Gamma0Upper - theorem
ModularCurve.PDPairing.mem_Gamma0Upper - theorem
ModularCurve.PDPairing.Gamma0Upper_isCongruenceSubgroup - instance
ModularCurve.PDPairing.Gamma0Upper_finiteIndex - abbrev
ModularCurve.PDPairing.Gamma0HUpper - theorem
ModularCurve.PDPairing.dvd_of_mem_Gamma0HUpper - theorem
ModularCurve.PDPairing.conjUpperMat_mem0 - def
ModularCurve.PDPairing.conjL0 - def
ModularCurve.PDPairing.heckeT0 - theorem
ModularCurve.PDPairing.heckeT0_apply - def
ModularCurve.PDPairing.omega - theorem
ModularCurve.PDPairing.omega_one_left - theorem
ModularCurve.PDPairing.omega_one_right - theorem
ModularCurve.PDPairing.omega_inv_self - theorem
ModularCurve.PDPairing.omega_self_inv - theorem
ModularCurve.PDPairing.omega_cocycle - theorem
ModularCurve.PDPairing.omega_swap - def
ModularCurve.PDPairing.CentralExt - theorem
ModularCurve.PDPairing.CentralExt.mul_def - theorem
ModularCurve.PDPairing.CentralExt.one_def - theorem
ModularCurve.PDPairing.CentralExt.inv_def - def
ModularCurve.PDPairing.CentralExt.snd - theorem
ModularCurve.PDPairing.CentralExt.snd_apply - def
ModularCurve.PDPairing.sect - theorem
ModularCurve.PDPairing.snd_comp_sect - theorem
ModularCurve.PDPairing.sect_snd - def
ModularCurve.PDPairing.hPrim - theorem
ModularCurve.PDPairing.hPrim_mul - theorem
ModularCurve.PDPairing.hPrim_one - def
ModularCurve.PDPairing.CentralExt.lift - theorem
ModularCurve.PDPairing.CentralExt.lift_apply - theorem
ModularCurve.PDPairing.hPrim_unique - theorem
ModularCurve.PDPairing.hPrim_of - theorem
ModularCurve.PDPairing.omega_add_left - theorem
ModularCurve.PDPairing.omega_smul_left - theorem
ModularCurve.PDPairing.hPrim_add_left - theorem
ModularCurve.PDPairing.hPrim_smul_left - theorem
ModularCurve.PDPairing.hPrim_swap - abbrev
ModularCurve.PDPairing.Cusp - def
ModularCurve.PDPairing.cuspGen - def
ModularCurve.PDPairing.cuspSum - theorem
ModularCurve.PDPairing.cuspSum_add - theorem
ModularCurve.PDPairing.cuspSum_smul - def
ModularCurve.PDPairing.pairF - instance
ModularCurve.PDPairing.isFreeGroup_inf - def
ModularCurve.PDPairing.resInf - def
ModularCurve.PDPairing.pairD - def
ModularCurve.PDPairing.pairZFun - theorem
ModularCurve.PDPairing.pairZFun_add_left - theorem
ModularCurve.PDPairing.pairZFun_smul_left - theorem
ModularCurve.PDPairing.pairZFun_swap - theorem
ModularCurve.PDPairing.pairZFun_add_right - theorem
ModularCurve.PDPairing.pairZFun_smul_right - def
ModularCurve.PDPairing.pairZ - theorem
ModularCurve.PDPairing.pairZ_apply
Source
import Mathlib.NumberTheory.ModularForms.CongruenceSubgroups ↗ import Mathlib.GroupTheory.Transfer ↗ import Mathlib.GroupTheory.FreeGroup.NielsenSchreier ↗ import Definitions.Def_ModularCurve_PeriodMap set_option autoImplicit false namespace ModularCurve.PDPairing open Matrix CongruenceSubgroup Matrix.SpecialLinearGroup open scoped MatrixGroups section Cores variable {G : Type*} [Group G] {K : Subgroup G} {C : Type*} [CommGroup C] theorem leftTransversals_diff_one [K.FiniteIndex] (S T : K.LeftTransversal) : Subgroup.leftTransversals.diff (1 : K →* C) S T = 1 := by simp [Subgroup.leftTransversals.diff] theorem leftTransversals_diff_mul [K.FiniteIndex] (ϕ ψ : K →* C) (S T : K.LeftTransversal) : Subgroup.leftTransversals.diff (ϕ * ψ) S T = Subgroup.leftTransversals.diff ϕ S T * Subgroup.leftTransversals.diff ψ S T := by simp only [Subgroup.leftTransversals.diff, MonoidHom.mul_apply, Finset.prod_mul_distrib] theorem transfer_one [K.FiniteIndex] : MonoidHom.transfer (1 : K →* C) = 1 := by ext g rw [MonoidHom.transfer_def _ default, leftTransversals_diff_one] rfl theorem transfer_mul [K.FiniteIndex] (ϕ ψ : K →* C) : MonoidHom.transfer (ϕ * ψ) = MonoidHom.transfer ϕ * MonoidHom.transfer ψ := by ext g rw [MonoidHom.mul_apply, MonoidHom.transfer_def _ default, MonoidHom.transfer_def _ default, MonoidHom.transfer_def _ default, leftTransversals_diff_mul] theorem toMultiplicativeRight_zero {α β : Type*} [MulOneClass α] [AddCommGroup β] : AddMonoidHom.toMultiplicativeRight (0 : Additive α →+ β) = 1 := by ext a simp theorem toMultiplicativeRight_add {α β : Type*} [MulOneClass α] [AddCommGroup β] (φ ψ : Additive α →+ β) : AddMonoidHom.toMultiplicativeRight (φ + ψ) = AddMonoidHom.toMultiplicativeRight φ * AddMonoidHom.toMultiplicativeRight ψ := by ext a simp [ofAdd_add] theorem toAdditiveLeft_one {α β : Type*} [MulOneClass α] [AddCommGroup β] : MonoidHom.toAdditiveLeft (1 : α →* Multiplicative β) = 0 := by ext a simp theorem toAdditiveLeft_mul {α β : Type*} [MulOneClass α] [AddCommGroup β] (f g : α →* Multiplicative β) : MonoidHom.toAdditiveLeft (f * g) = MonoidHom.toAdditiveLeft f + MonoidHom.toAdditiveLeft g := by ext a simp [toAdd_mul] noncomputable def coresAdd (K : Subgroup G) [K.FiniteIndex] {B : Type*} [AddCommGroup B] (φ : Additive ↥K →+ B) : Additive G →+ B := MonoidHom.toAdditiveLeft (MonoidHom.transfer (AddMonoidHom.toMultiplicativeRight φ)) theorem coresAdd_zero (K : Subgroup G) [K.FiniteIndex] {B : Type*} [AddCommGroup B] : coresAdd K (0 : Additive ↥K →+ B) = 0 := by simp only [coresAdd, toMultiplicativeRight_zero, transfer_one, toAdditiveLeft_one] theorem coresAdd_add (K : Subgroup G) [K.FiniteIndex] {B : Type*} [AddCommGroup B] (φ ψ : Additive ↥K →+ B) : coresAdd K (φ + ψ) = coresAdd K φ + coresAdd K ψ := by simp only [coresAdd, toMultiplicativeRight_add, transfer_mul, toAdditiveLeft_mul] theorem coresAdd_smul (K : Subgroup G) [K.FiniteIndex] {R B : Type*} [Semiring R] [AddCommGroup B] [Module R B] (r : R) (φ : Additive ↥K →+ B) : coresAdd K (r • φ) = r • coresAdd K φ := by ext g simp only [coresAdd, MonoidHom.toAdditiveLeft_apply_apply, AddMonoidHom.smul_apply, MonoidHom.transfer_def _ default, Subgroup.leftTransversals.diff, toAdd_prod, AddMonoidHom.toMultiplicativeRight_apply_apply, toAdd_ofAdd, Finset.smul_sum] end Cores section ConjMats variable (ℓ d : ℕ) def conjUpperMat (A : SL(2, ℤ)) (h : (ℓ : ℤ) ∣ A 0 1) : SL(2, ℤ) := ⟨!![A 0 0, A 0 1 / ℓ; A 1 0 * ℓ, A 1 1], by rw [Matrix.det_fin_two_of] have hdet := Matrix.SpecialLinearGroup.det_coe A rw [Matrix.det_fin_two] at hdet have hbc : A 0 1 / ℓ * (A 1 0 * ℓ) = A 0 1 * A 1 0 := by rw [mul_comm (A 1 0) _, ← mul_assoc, Int.ediv_mul_cancel h] rw [hbc] exact hdet⟩ @[simp] theorem conjUpperMat_apply_11 (A : SL(2, ℤ)) (h : (ℓ : ℤ) ∣ A 0 1) : (conjUpperMat ℓ A h) 1 1 = A 1 1 := by simp [conjUpperMat] @[simp] theorem conjUpperMat_apply_10 (A : SL(2, ℤ)) (h : (ℓ : ℤ) ∣ A 0 1) : (conjUpperMat ℓ A h) 1 0 = A 1 0 * ℓ := by simp [conjUpperMat] theorem conjUpperMat_mul (A B : SL(2, ℤ)) (hA : (ℓ : ℤ) ∣ A 0 1) (hB : (ℓ : ℤ) ∣ B 0 1) (hAB : (ℓ : ℤ) ∣ (A * B) 0 1) : conjUpperMat ℓ (A * B) hAB = conjUpperMat ℓ A hA * conjUpperMat ℓ B hB := by have h1 : A 0 1 / ℓ * (B 1 0 * ℓ) = A 0 1 * B 1 0 := by rw [mul_comm (B 1 0) _, ← mul_assoc, Int.ediv_mul_cancel hA] have h2 : (A 0 0 * B 0 1 + A 0 1 * B 1 1) / ℓ = A 0 0 * (B 0 1 / ℓ) + A 0 1 / ℓ * B 1 1 := by rw [Int.add_ediv_of_dvd_right (Dvd.dvd.mul_right hA _), Int.mul_ediv_assoc _ hB, mul_comm (A 0 1) (B 1 1), Int.mul_ediv_assoc _ hA, mul_comm (B 1 1)] have h3 : A 1 0 * ℓ * (B 0 1 / ℓ) = A 1 0 * B 0 1 := by rw [mul_assoc, Int.mul_ediv_cancel' hB] have hmul : ∀ i j, (A * B) i j = A i 0 * B 0 j + A i 1 * B 1 j := fun i j => by simp [Matrix.mul_apply, Fin.sum_univ_two] apply Matrix.SpecialLinearGroup.ext intro i j fin_cases i <;> fin_cases j <;> simp [conjUpperMat, Matrix.mul_apply, Fin.sum_univ_two, hmul, h2] · exact h1.symm · ring · exact h3.symm def conjLowerMat (A : SL(2, ℤ)) (h : (d : ℤ) ∣ A 1 0) : SL(2, ℤ) := ⟨!![A 0 0, A 0 1 * d; A 1 0 / d, A 1 1], by rw [Matrix.det_fin_two_of] have hdet := Matrix.SpecialLinearGroup.det_coe A rw [Matrix.det_fin_two] at hdet have hbc : A 0 1 * d * (A 1 0 / d) = A 0 1 * A 1 0 := by rw [mul_assoc, mul_comm (d : ℤ) _, Int.ediv_mul_cancel h] rw [hbc] exact hdet⟩ theorem conjLowerMat_mul (A B : SL(2, ℤ)) (hA : (d : ℤ) ∣ A 1 0) (hB : (d : ℤ) ∣ B 1 0) (hAB : (d : ℤ) ∣ (A * B) 1 0) : conjLowerMat d (A * B) hAB = conjLowerMat d A hA * conjLowerMat d B hB := by have h1 : A 0 1 * d * (B 1 0 / d) = A 0 1 * B 1 0 := by rw [mul_assoc, Int.mul_ediv_cancel' hB] have h2 : (A 1 0 * B 0 0 + A 1 1 * B 1 0) / d = A 1 0 / d * B 0 0 + A 1 1 * (B 1 0 / d) := by rw [Int.add_ediv_of_dvd_right (Dvd.dvd.mul_left hB _), Int.mul_ediv_assoc _ hB, mul_comm (A 1 0) (B 0 0), Int.mul_ediv_assoc _ hA, mul_comm (B 0 0)] have h3 : A 1 0 / d * (B 0 1 * d) = A 1 0 * B 0 1 := by rw [mul_comm (B 0 1) _, ← mul_assoc, Int.ediv_mul_cancel hA] have hmul : ∀ i j, (A * B) i j = A i 0 * B 0 j + A i 1 * B 1 j := fun i j => by simp [Matrix.mul_apply, Fin.sum_univ_two] apply Matrix.SpecialLinearGroup.ext intro i j fin_cases i <;> fin_cases j <;> simp [conjLowerMat, Matrix.mul_apply, Fin.sum_univ_two, hmul, h2] all_goals first | exact h1.symm | exact h3.symm | ring theorem conjLowerMat_conjUpperMat [NeZero d] (A : SL(2, ℤ)) (hb : (d : ℤ) ∣ A 0 1) (hc : (d : ℤ) ∣ (conjUpperMat d A hb) 1 0) : conjLowerMat d (conjUpperMat d A hb) hc = A := by have hd : (d : ℤ) ≠ 0 := by exact_mod_cast (NeZero.ne d) apply Matrix.SpecialLinearGroup.ext intro i j fin_cases i <;> fin_cases j <;> simp [conjLowerMat, conjUpperMat, Int.ediv_mul_cancel hb, Int.mul_ediv_cancel _ hd] end ConjMats section Gamma0Legs variable (M M' d : ℕ) theorem exists_eq0 (hMM' : M ∣ M') (hdd : d ∣ M' / M) : ∃ e : ℕ, M' = M * (d * e) := by obtain ⟨e, he⟩ := hdd refine ⟨e, ?_⟩ rw [← he, Nat.mul_div_cancel' hMM'] theorem dvd_entry0 (hMM' : M ∣ M') (hdd : d ∣ M' / M) (γ : ↥(Gamma0 M')) : (d : ℤ) ∣ (γ : SL(2, ℤ)) 1 0 := by have hM' : ((M' : ℕ) : ℤ) ∣ (γ : SL(2, ℤ)) 1 0 := (ZMod.intCast_zmod_eq_zero_iff_dvd _ _).mp (Gamma0_mem.mp γ.2) obtain ⟨e, he⟩ := exists_eq0 M M' d hMM' hdd refine dvd_trans ?_ hM' rw [he] push_cast exact Dvd.intro_left ((M : ℤ) * e) (by ring) theorem conjLowerMat_mem0 [NeZero d] (hMM' : M ∣ M') (hdd : d ∣ M' / M) (γ : ↥(Gamma0 M')) : conjLowerMat d (γ : SL(2, ℤ)) (dvd_entry0 M M' d hMM' hdd γ) ∈ Gamma0 M := by have hM' : ((M' : ℕ) : ℤ) ∣ (γ : SL(2, ℤ)) 1 0 := (ZMod.intCast_zmod_eq_zero_iff_dvd _ _).mp (Gamma0_mem.mp γ.2) obtain ⟨e, he⟩ := exists_eq0 M M' d hMM' hdd obtain ⟨t, ht⟩ := hM' have hd0 : (d : ℤ) ≠ 0 := by exact_mod_cast NeZero.ne d have hquot : (γ : SL(2, ℤ)) 1 0 / (d : ℤ) = (M : ℤ) * (e * t) := by apply Int.ediv_eq_of_eq_mul_right hd0 rw [ht, he] push_cast ring rw [Gamma0_mem] show (((!![(γ : SL(2, ℤ)) 0 0, (γ : SL(2, ℤ)) 0 1 * d; (γ : SL(2, ℤ)) 1 0 / d, (γ : SL(2, ℤ)) 1 1] : Matrix (Fin 2) (Fin 2) ℤ) 1 0 : ℤ) : ZMod M) = 0 simp only [Matrix.of_apply, Matrix.cons_val', Matrix.cons_val_zero, Matrix.cons_val_one, Matrix.cons_val_fin_one] rw [hquot] push_cast rw [ZMod.natCast_self, zero_mul] def iotaDeg0 [NeZero d] (hMM' : M ∣ M') (hdd : d ∣ M' / M) : ↥(Gamma0 M') →* ↥(Gamma0 M) where toFun γ := ⟨conjLowerMat d (γ : SL(2, ℤ)) (dvd_entry0 M M' d hMM' hdd γ), conjLowerMat_mem0 M M' d hMM' hdd γ⟩ map_one' := by apply Subtype.ext apply Matrix.SpecialLinearGroup.ext intro i j fin_cases i <;> fin_cases j <;> simp [conjLowerMat] map_mul' γ δ := Subtype.ext (conjLowerMat_mul d (γ : SL(2, ℤ)) (δ : SL(2, ℤ)) (dvd_entry0 M M' d hMM' hdd γ) (dvd_entry0 M M' d hMM' hdd δ) (dvd_entry0 M M' d hMM' hdd (γ * δ))) def iDeg0 (R : Type*) [Semiring R] (A : Type*) [AddCommGroup A] [Module R A] [NeZero d] (hMM' : M ∣ M') (hdd : d ∣ M' / M) : (Additive ↥(Gamma0 M) →+ A) →ₗ[R] (Additive ↥(Gamma0 M') →+ A) where toFun φ := φ.comp (MonoidHom.toAdditive (iotaDeg0 M M' d hMM' hdd)) map_add' := by intro φ ψ; ext; rfl map_smul' := by intro r φ; ext; rfl theorem Gamma_subgroupOf_le_range_iotaDeg0 [NeZero M'] [NeZero d] (hMM' : M ∣ M') (hdd : d ∣ M' / M) : (Gamma (M' * d)).subgroupOf (Gamma0 M) ≤ (iotaDeg0 M M' d hMM' hdd).range := by intro γ hγ rw [Subgroup.mem_subgroupOf, Gamma_mem] at hγ obtain ⟨_, h01, h10, _⟩ := hγ have hMd : ((M' * d : ℕ) : ℤ) ∣ (γ : SL(2, ℤ)) 0 1 := (ZMod.intCast_zmod_eq_zero_iff_dvd _ _).mp h01 have hMd' : ((M' * d : ℕ) : ℤ) ∣ (γ : SL(2, ℤ)) 1 0 := (ZMod.intCast_zmod_eq_zero_iff_dvd _ _).mp h10 have hb : (d : ℤ) ∣ (γ : SL(2, ℤ)) 0 1 := dvd_trans (by push_cast; exact Dvd.intro_left _ rfl) hMd set A : SL(2, ℤ) := conjUpperMat d (γ : SL(2, ℤ)) hb with hAdef have hA0 : A ∈ Gamma0 M' := by rw [Gamma0_mem] have : A 1 0 = (γ : SL(2, ℤ)) 1 0 * d := by simp [hAdef, conjUpperMat] rw [this, ZMod.intCast_zmod_eq_zero_iff_dvd] exact Dvd.dvd.mul_right (dvd_trans (by push_cast; exact Dvd.intro _ rfl) hMd') _ have hc : (d : ℤ) ∣ (conjUpperMat d (γ : SL(2, ℤ)) hb) 1 0 := by rw [conjUpperMat_apply_10] exact dvd_mul_left _ _ refine ⟨⟨A, hA0⟩, Subtype.ext ?_⟩ exact conjLowerMat_conjUpperMat d (γ : SL(2, ℤ)) hb hc instance iotaDeg0_range_finiteIndex [NeZero M'] [NeZero d] (hMM' : M ∣ M') (hdd : d ∣ M' / M) : ((iotaDeg0 M M' d hMM' hdd).range).FiniteIndex := by haveI : NeZero (M' * d) := ⟨mul_ne_zero (NeZero.ne M') (NeZero.ne d)⟩ haveI : ((Gamma (M' * d)).subgroupOf (Gamma0 M)).FiniteIndex := inferInstance exact Subgroup.finiteIndex_of_le (Gamma_subgroupOf_le_range_iotaDeg0 M M' d hMM' hdd) theorem iotaDeg0_injective [NeZero d] (hMM' : M ∣ M') (hdd : d ∣ M' / M) : Function.Injective (iotaDeg0 M M' d hMM' hdd) := by intro γ δ hγδ have hmat : conjLowerMat d (γ : SL(2, ℤ)) (dvd_entry0 M M' d hMM' hdd γ) = conjLowerMat d (δ : SL(2, ℤ)) (dvd_entry0 M M' d hMM' hdd δ) := congrArg Subtype.val hγδ have e : ∀ i j, (conjLowerMat d (γ : SL(2, ℤ)) (dvd_entry0 M M' d hMM' hdd γ)) i j = (conjLowerMat d (δ : SL(2, ℤ)) (dvd_entry0 M M' d hMM' hdd δ)) i j := fun i j => by rw [hmat] have hd : (d : ℤ) ≠ 0 := by exact_mod_cast (NeZero.ne d) apply Subtype.ext apply Matrix.SpecialLinearGroup.ext intro i j fin_cases i <;> fin_cases j · simpa [conjLowerMat] using e 0 0 · have h01 := e 0 1 simp only [conjLowerMat, Matrix.of_apply, Matrix.cons_val', Matrix.cons_val_zero, Matrix.cons_val_one, Matrix.cons_val_fin_one] at h01 exact mul_right_cancel₀ hd h01 · have h10 := e 1 0 simp only [conjLowerMat, Matrix.of_apply, Matrix.cons_val', Matrix.cons_val_zero, Matrix.cons_val_one, Matrix.cons_val_fin_one] at h10 calc (γ : SL(2, ℤ)) 1 0 = d * ((γ : SL(2, ℤ)) 1 0 / d) := (Int.mul_ediv_cancel' (dvd_entry0 M M' d hMM' hdd γ)).symm _ = d * ((δ : SL(2, ℤ)) 1 0 / d) := by rw [h10] _ = (δ : SL(2, ℤ)) 1 0 := Int.mul_ediv_cancel' (dvd_entry0 M M' d hMM' hdd δ) · simpa [conjLowerMat] using e 1 1 noncomputable def pushChar0 (A : Type*) [AddCommGroup A] [NeZero d] (hMM' : M ∣ M') (hdd : d ∣ M' / M) (φ : Additive ↥(Gamma0 M') →+ A) : Additive ↥((iotaDeg0 M M' d hMM' hdd).range) →+ A := φ.comp (MonoidHom.toAdditive ((iotaDeg0 M M' d hMM' hdd).ofInjective (iotaDeg0_injective M M' d hMM' hdd)).symm.toMonoidHom) noncomputable def jDeg0 (R : Type*) [Semiring R] (A : Type*) [AddCommGroup A] [Module R A] [NeZero M'] [NeZero d] (hMM' : M ∣ M') (hdd : d ∣ M' / M) : (Additive ↥(Gamma0 M') →+ A) →ₗ[R] (Additive ↥(Gamma0 M) →+ A) where toFun φ := coresAdd _ (pushChar0 M M' d A hMM' hdd φ) map_add' φ ψ := by have : pushChar0 M M' d A hMM' hdd (φ + ψ) = pushChar0 M M' d A hMM' hdd φ + pushChar0 M M' d A hMM' hdd ψ := by ext; rfl rw [this, coresAdd_add] map_smul' r φ := by have : pushChar0 M M' d A hMM' hdd (r • φ) = r • pushChar0 M M' d A hMM' hdd φ := by ext; rfl rw [this, coresAdd_smul] rfl end Gamma0Legs section Gamma0Hecke variable (M : ℕ) def Gamma0Upper (ℓ : ℕ) : Subgroup SL(2, ℤ) where carrier := { g | (g 0 1 : ZMod ℓ) = 0 } one_mem' := by simp mul_mem' := by intro a b ha hb simp only [Set.mem_setOf_eq] at * have h := (Matrix.two_mul_expl a.1 b.1).2.1 simp only [coe_mul] at * rw [h] simp [ha, hb] inv_mem' := by intro a ha simp only [Set.mem_setOf_eq] at * rw [SL2_inv_expl a] simp only [cons_val_zero, cons_val_one, Int.cast_neg, neg_eq_zero] at * exact ha @[simp] theorem mem_Gamma0Upper {ℓ : ℕ} {A : SL(2, ℤ)} : A ∈ Gamma0Upper ℓ ↔ (A 0 1 : ZMod ℓ) = 0 := Iff.rfl theorem Gamma0Upper_isCongruenceSubgroup (ℓ : ℕ) [NeZero ℓ] : IsCongruenceSubgroup (Gamma0Upper ℓ) := by refine ⟨ℓ, NeZero.ne _, fun A hA => ?_⟩ rw [mem_Gamma0Upper] exact (Gamma_mem.mp hA).2.1 instance Gamma0Upper_finiteIndex (ℓ : ℕ) [NeZero ℓ] : (Gamma0Upper ℓ).FiniteIndex := (Gamma0Upper_isCongruenceSubgroup ℓ).finiteIndex variable (ℓ : ℕ) abbrev Gamma0HUpper : Subgroup ↥(Gamma0 M) := (Gamma0Upper ℓ).subgroupOf (Gamma0 M) theorem dvd_of_mem_Gamma0HUpper (γ : ↥(Gamma0HUpper M ℓ)) : (ℓ : ℤ) ∣ (γ : SL(2, ℤ)) 0 1 := by have h : ((γ : ↥(Gamma0 M)) : SL(2, ℤ)) ∈ Gamma0Upper ℓ := Subgroup.mem_subgroupOf.mp γ.2 rw [mem_Gamma0Upper] at h exact (ZMod.intCast_zmod_eq_zero_iff_dvd _ _).mp h theorem conjUpperMat_mem0 (γ : ↥(Gamma0HUpper M ℓ)) : conjUpperMat ℓ (γ : SL(2, ℤ)) (dvd_of_mem_Gamma0HUpper M ℓ γ) ∈ Gamma0 M := by rw [Gamma0_mem, conjUpperMat_apply_10, Int.cast_mul, Gamma0_mem.mp (γ : ↥(Gamma0 M)).2, zero_mul] def conjL0 : ↥(Gamma0HUpper M ℓ) →* ↥(Gamma0 M) where toFun γ := ⟨conjUpperMat ℓ (γ : SL(2, ℤ)) (dvd_of_mem_Gamma0HUpper M ℓ γ), conjUpperMat_mem0 M ℓ γ⟩ map_one' := by apply Subtype.ext apply Matrix.SpecialLinearGroup.ext intro i j fin_cases i <;> fin_cases j <;> simp [conjUpperMat] map_mul' γ δ := Subtype.ext (conjUpperMat_mul ℓ (γ : SL(2, ℤ)) (δ : SL(2, ℤ)) (dvd_of_mem_Gamma0HUpper M ℓ γ) (dvd_of_mem_Gamma0HUpper M ℓ δ) (dvd_of_mem_Gamma0HUpper M ℓ (γ * δ))) variable (A : Type*) [AddCommGroup A] noncomputable def heckeT0 [NeZero ℓ] : (Additive ↥(Gamma0 M) →+ A) →+ (Additive ↥(Gamma0 M) →+ A) where toFun φ := MonoidHom.toAdditiveLeft (MonoidHom.transfer ((AddMonoidHom.toMultiplicativeRight φ).comp (conjL0 M ℓ))) map_zero' := by simp only [toMultiplicativeRight_zero, MonoidHom.one_comp, transfer_one, toAdditiveLeft_one] map_add' φ ψ := by simp only [toMultiplicativeRight_add, MonoidHom.mul_comp, transfer_mul, toAdditiveLeft_mul] theorem heckeT0_apply [NeZero ℓ] (φ : Additive ↥(Gamma0 M) →+ A) : heckeT0 M ℓ A φ = MonoidHom.toAdditiveLeft (MonoidHom.transfer ((AddMonoidHom.toMultiplicativeRight φ).comp (conjL0 M ℓ))) := rfl end Gamma0Hecke section Prim variable {Φ : Type*} [Group Φ] {R : Type*} [CommRing R] def omega (φ ψ : Additive Φ →+ R) (g g' : Φ) : R := φ (Additive.ofMul g) * ψ (Additive.ofMul g') - ψ (Additive.ofMul g) * φ (Additive.ofMul g') theorem omega_one_left (φ ψ : Additive Φ →+ R) (g : Φ) : omega φ ψ 1 g = 0 := by simp [omega] theorem omega_one_right (φ ψ : Additive Φ →+ R) (g : Φ) : omega φ ψ g 1 = 0 := by simp [omega] theorem omega_inv_self (φ ψ : Additive Φ →+ R) (g : Φ) : omega φ ψ g⁻¹ g = 0 := by simp only [omega, ofMul_inv, map_neg] ring theorem omega_self_inv (φ ψ : Additive Φ →+ R) (g : Φ) : omega φ ψ g g⁻¹ = 0 := by simp only [omega, ofMul_inv, map_neg] ring theorem omega_cocycle (φ ψ : Additive Φ →+ R) (g h k : Φ) : omega φ ψ g h + omega φ ψ (g * h) k = omega φ ψ h k + omega φ ψ g (h * k) := by simp only [omega, ofMul_mul, map_add] ring theorem omega_swap (φ ψ : Additive Φ →+ R) (g h : Φ) : omega ψ φ g h = - omega φ ψ g h := by simp only [omega] ring def CentralExt (_φ _ψ : Additive Φ →+ R) : Type _ := R × Φ namespace CentralExt variable (φ ψ : Additive Φ →+ R) instance : Mul (CentralExt φ ψ) := ⟨fun x y => (x.1 + y.1 - omega φ ψ x.2 y.2, x.2 * y.2)⟩ instance : One (CentralExt φ ψ) := ⟨((0 : R), (1 : Φ))⟩ instance : Inv (CentralExt φ ψ) := ⟨fun x => (-x.1, x.2⁻¹)⟩ theorem mul_def (x y : CentralExt φ ψ) : x * y = (x.1 + y.1 - omega φ ψ x.2 y.2, x.2 * y.2) := rfl theorem one_def : (1 : CentralExt φ ψ) = ((0 : R), (1 : Φ)) := rfl theorem inv_def (x : CentralExt φ ψ) : x⁻¹ = (-x.1, x.2⁻¹) := rfl instance : Group (CentralExt φ ψ) where mul_assoc x y z := by change ((x.1 + y.1 - omega φ ψ x.2 y.2) + z.1 - omega φ ψ (x.2 * y.2) z.2, (x.2 * y.2) * z.2) = (x.1 + (y.1 + z.1 - omega φ ψ y.2 z.2) - omega φ ψ x.2 (y.2 * z.2), x.2 * (y.2 * z.2)) have hc := omega_cocycle φ ψ x.2 y.2 z.2 refine Prod.ext ?_ (mul_assoc _ _ _) change (x.1 + y.1 - omega φ ψ x.2 y.2) + z.1 - omega φ ψ (x.2 * y.2) z.2 = x.1 + (y.1 + z.1 - omega φ ψ y.2 z.2) - omega φ ψ x.2 (y.2 * z.2) linear_combination (-1 : R) * hc one_mul x := by change ((0 : R) + x.1 - omega φ ψ 1 x.2, (1 : Φ) * x.2) = x rw [omega_one_left, sub_zero, zero_add, one_mul] exact Prod.mk.eta mul_one x := by change (x.1 + 0 - omega φ ψ x.2 1, x.2 * 1) = x rw [omega_one_right, sub_zero, add_zero, mul_one] exact Prod.mk.eta inv_mul_cancel x := by change (-x.1 + x.1 - omega φ ψ x.2⁻¹ x.2, x.2⁻¹ * x.2) = ((0 : R), (1 : Φ)) rw [omega_inv_self, sub_zero, neg_add_cancel, inv_mul_cancel] def snd : CentralExt φ ψ →* Φ where toFun x := x.2 map_one' := rfl map_mul' _ _ := rfl @[simp] theorem snd_apply (x : CentralExt φ ψ) : snd φ ψ x = x.2 := rfl end CentralExt variable [IsFreeGroup Φ] noncomputable def sect (φ ψ : Additive Φ →+ R) : Φ →* CentralExt φ ψ := IsFreeGroup.lift (fun a => (((0 : R), IsFreeGroup.of a) : CentralExt φ ψ)) theorem snd_comp_sect (φ ψ : Additive Φ →+ R) : (CentralExt.snd φ ψ).comp (sect φ ψ) = MonoidHom.id Φ := by apply IsFreeGroup.ext_hom intro a simp [sect] @[simp] theorem sect_snd (φ ψ : Additive Φ →+ R) (g : Φ) : (sect φ ψ g).2 = g := by have h := congrArg (fun f : Φ →* Φ => f g) (snd_comp_sect φ ψ) simpa using h noncomputable def hPrim (φ ψ : Additive Φ →+ R) (g : Φ) : R := (sect φ ψ g).1 theorem hPrim_mul (φ ψ : Additive Φ →+ R) (g g' : Φ) : hPrim φ ψ (g * g') = hPrim φ ψ g + hPrim φ ψ g' - omega φ ψ g g' := by have h := map_mul (sect φ ψ) g g' have h1 := congrArg Prod.fst h simp only [CentralExt.mul_def, sect_snd] at h1 exact h1 theorem hPrim_one (φ ψ : Additive Φ →+ R) : hPrim φ ψ 1 = 0 := by have h := map_one (sect φ ψ) exact congrArg Prod.fst h def CentralExt.lift (φ ψ : Additive Φ →+ R) (H : Φ → R) (hH : ∀ g g', H (g * g') = H g + H g' - omega φ ψ g g') : Φ →* CentralExt φ ψ where toFun g := (H g, g) map_one' := by have h := hH 1 1 rw [one_mul, omega_one_left, sub_zero] at h have h1 : H 1 = 0 := by linear_combination -h rw [h1] rfl map_mul' g g' := by rw [CentralExt.mul_def] exact Prod.ext (hH g g') rfl omit [IsFreeGroup Φ] in @[simp] theorem CentralExt.lift_apply (φ ψ : Additive Φ →+ R) (H : Φ → R) (hH : ∀ g g', H (g * g') = H g + H g' - omega φ ψ g g') (g : Φ) : CentralExt.lift φ ψ H hH g = (H g, g) := rfl theorem hPrim_unique (φ ψ : Additive Φ →+ R) (H : Φ → R) (hH : ∀ g g', H (g * g') = H g + H g' - omega φ ψ g g') (h0 : ∀ a : IsFreeGroup.Generators Φ, H (IsFreeGroup.of a) = 0) (g : Φ) : H g = hPrim φ ψ g := by have key : CentralExt.lift φ ψ H hH = sect φ ψ := by apply IsFreeGroup.ext_hom intro a rw [CentralExt.lift_apply, h0 a] simp [sect] exact congrArg Prod.fst (congrArg (fun f : Φ →* CentralExt φ ψ => f g) key) theorem hPrim_of (φ ψ : Additive Φ →+ R) (a : IsFreeGroup.Generators Φ) : hPrim φ ψ (IsFreeGroup.of a) = 0 := by simp [hPrim, sect] omit [IsFreeGroup Φ] in theorem omega_add_left (φ₁ φ₂ ψ : Additive Φ →+ R) (g g' : Φ) : omega (φ₁ + φ₂) ψ g g' = omega φ₁ ψ g g' + omega φ₂ ψ g g' := by simp only [omega, AddMonoidHom.add_apply] ring omit [IsFreeGroup Φ] in theorem omega_smul_left (r : R) (φ ψ : Additive Φ →+ R) (g g' : Φ) : omega (r • φ) ψ g g' = r * omega φ ψ g g' := by simp only [omega, AddMonoidHom.smul_apply, smul_eq_mul] ring theorem hPrim_add_left (φ₁ φ₂ ψ : Additive Φ →+ R) (g : Φ) : hPrim (φ₁ + φ₂) ψ g = hPrim φ₁ ψ g + hPrim φ₂ ψ g := by symm refine hPrim_unique (φ₁ + φ₂) ψ (fun g => hPrim φ₁ ψ g + hPrim φ₂ ψ g) ?_ ?_ g · intro g g' rw [hPrim_mul, hPrim_mul, omega_add_left] ring · intro a rw [hPrim_of, hPrim_of, add_zero] theorem hPrim_smul_left (r : R) (φ ψ : Additive Φ →+ R) (g : Φ) : hPrim (r • φ) ψ g = r * hPrim φ ψ g := by symm refine hPrim_unique (r • φ) ψ (fun g => r * hPrim φ ψ g) ?_ ?_ g · intro g g' rw [hPrim_mul, omega_smul_left] ring · intro a rw [hPrim_of, mul_zero] theorem hPrim_swap (φ ψ : Additive Φ →+ R) (g : Φ) : hPrim ψ φ g = - hPrim φ ψ g := by refine (hPrim_unique ψ φ (fun g => - hPrim φ ψ g) ?_ ?_ g).symm · intro g g' rw [hPrim_mul, omega_swap] ring · intro a rw [hPrim_of, neg_zero] end Prim section Cusps open MulAction variable (Φ : Subgroup SL(2, ℤ)) [Φ.FiniteIndex] {R : Type*} [CommRing R] abbrev Cusp : Type := Quotient (orbitRel (Subgroup.zpowers ModularGroup.T) (SL(2, ℤ) ⧸ Φ)) noncomputable instance : Fintype (Cusp Φ) := Fintype.ofFinite _ noncomputable def cuspGen (q : Cusp Φ) : Φ := ⟨q.out.out⁻¹ * ModularGroup.T ^ Function.minimalPeriod (ModularGroup.T • ·) q.out * q.out.out, QuotientGroup.out_conj_pow_minimalPeriod_mem Φ ModularGroup.T q.out⟩ noncomputable def cuspSum (f : Φ → R) : R := ∑ q : Cusp Φ, f (cuspGen Φ q) theorem cuspSum_add (f g : Φ → R) : cuspSum Φ (f + g) = cuspSum Φ f + cuspSum Φ g := by simp [cuspSum, Finset.sum_add_distrib] theorem cuspSum_smul (r : R) (f : Φ → R) : cuspSum Φ (r • f) = r * cuspSum Φ f := by simp [cuspSum, Finset.mul_sum] noncomputable def pairF [IsFreeGroup Φ] [Invertible (2 : R)] (φ ψ : Additive Φ →+ R) : R := ⅟(2 : R) * cuspSum Φ (hPrim φ ψ) end Cusps section Descent variable (Λ : Subgroup SL(2, ℤ)) [Λ.FiniteIndex] [IsFreeGroup Λ] variable (Γ : Subgroup SL(2, ℤ)) [Γ.FiniteIndex] {R : Type*} [CommRing R] instance isFreeGroup_inf : IsFreeGroup ↥(Γ ⊓ Λ) := IsFreeGroup.ofMulEquiv (Subgroup.subgroupOfEquivOfLe (inf_le_right : Γ ⊓ Λ ≤ Λ)) example : (Γ ⊓ Λ).FiniteIndex := inferInstance def resInf (φ : Additive Γ →+ R) : Additive ↥(Γ ⊓ Λ) →+ R := φ.comp (MonoidHom.toAdditive (Subgroup.inclusion (inf_le_left : Γ ⊓ Λ ≤ Γ))) noncomputable def pairD [Invertible (2 : R)] [Invertible (((Γ ⊓ Λ).relIndex Γ : ℕ) : R)] (φ ψ : Additive Γ →+ R) : R := ⅟(((Γ ⊓ Λ).relIndex Γ : ℕ) : R) * pairF (Γ ⊓ Λ) (resInf Λ Γ φ) (resInf Λ Γ ψ) end Descent section LevelZ open ModularCurve.Period variable (N : ℕ) [NeZero N] [IsFreeGroup ↥(Gamma 4)] noncomputable def pairZFun (φ ψ : Additive ↥(Gamma0 N) →+ ℤ) : ℤ := ((48 / (Gamma0 N ⊓ Gamma 4).relIndex (Gamma0 N) : ℕ) : ℤ) * cuspSum (Gamma0 N ⊓ Gamma 4) (hPrim (resInf (Gamma 4) (Gamma0 N) φ) (resInf (Gamma 4) (Gamma0 N) ψ)) theorem pairZFun_add_left (φ₁ φ₂ ψ : Additive ↥(Gamma0 N) →+ ℤ) : pairZFun N (φ₁ + φ₂) ψ = pairZFun N φ₁ ψ + pairZFun N φ₂ ψ := by have h : hPrim (resInf (Gamma 4) (Gamma0 N) (φ₁ + φ₂)) (resInf (Gamma 4) (Gamma0 N) ψ) = hPrim (resInf (Gamma 4) (Gamma0 N) φ₁) (resInf (Gamma 4) (Gamma0 N) ψ) + hPrim (resInf (Gamma 4) (Gamma0 N) φ₂) (resInf (Gamma 4) (Gamma0 N) ψ) := by funext g rw [Pi.add_apply, ← hPrim_add_left] rfl rw [pairZFun, pairZFun, pairZFun, h, cuspSum_add, mul_add] theorem pairZFun_smul_left (r : ℤ) (φ ψ : Additive ↥(Gamma0 N) →+ ℤ) : pairZFun N (r • φ) ψ = r * pairZFun N φ ψ := by have h : hPrim (resInf (Gamma 4) (Gamma0 N) (r • φ)) (resInf (Gamma 4) (Gamma0 N) ψ) = r • hPrim (resInf (Gamma 4) (Gamma0 N) φ) (resInf (Gamma 4) (Gamma0 N) ψ) := by funext g rw [Pi.smul_apply, smul_eq_mul, ← hPrim_smul_left] rfl rw [pairZFun, pairZFun, h, cuspSum_smul] ring theorem pairZFun_swap (φ ψ : Additive ↥(Gamma0 N) →+ ℤ) : pairZFun N ψ φ = - pairZFun N φ ψ := by have h : hPrim (resInf (Gamma 4) (Gamma0 N) ψ) (resInf (Gamma 4) (Gamma0 N) φ) = (-1 : ℤ) • hPrim (resInf (Gamma 4) (Gamma0 N) φ) (resInf (Gamma 4) (Gamma0 N) ψ) := by funext g rw [Pi.smul_apply, smul_eq_mul, hPrim_swap] ring rw [pairZFun, pairZFun, h, cuspSum_smul] ring theorem pairZFun_add_right (φ ψ₁ ψ₂ : Additive ↥(Gamma0 N) →+ ℤ) : pairZFun N φ (ψ₁ + ψ₂) = pairZFun N φ ψ₁ + pairZFun N φ ψ₂ := by rw [pairZFun_swap, pairZFun_add_left, neg_add, ← pairZFun_swap, ← pairZFun_swap] theorem pairZFun_smul_right (r : ℤ) (φ ψ : Additive ↥(Gamma0 N) →+ ℤ) : pairZFun N φ (r • ψ) = r * pairZFun N φ ψ := by rw [pairZFun_swap, pairZFun_smul_left, pairZFun_swap] ring noncomputable def pairZ : parabolicHoms ℤ (Gamma0 N) ℤ →ₗ[ℤ] parabolicHoms ℤ (Gamma0 N) ℤ →ₗ[ℤ] ℤ := LinearMap.mk₂ ℤ (fun x y => pairZFun N (x : Additive ↥(Gamma0 N) →+ ℤ) (y : Additive ↥(Gamma0 N) →+ ℤ)) (fun x₁ x₂ y => by rw [Submodule.coe_add, pairZFun_add_left]) (fun r x y => by rw [Submodule.coe_smul, pairZFun_smul_left, smul_eq_mul]) (fun x y₁ y₂ => by rw [Submodule.coe_add, pairZFun_add_right]) (fun r x y => by rw [Submodule.coe_smul, pairZFun_smul_right, smul_eq_mul]) @[simp] theorem pairZ_apply (x y : parabolicHoms ℤ (Gamma0 N) ℤ) : pairZ N x y = pairZFun N (x : Additive ↥(Gamma0 N) →+ ℤ) (y : Additive ↥(Gamma0 N) →+ ℤ) := rfl end LevelZ end ModularCurve.PDPairing
Statements phrased using this module (8)
- Hecke self-adjointness of the integer pairing on parabolic classes
ModularCurve.PDPairing.pairZFun_heckeT0_comm0 below · depth 12 - Degeneracy maps are adjoint for the integer parabolic pairing
ModularCurve.PDPairing.pairZFun_jDeg0_iDeg00 below · depth 12 - Non-degeneracy of pairZ modulo a prime p≥ 5
ModularCurve.PDPairing.pairZ_nondegenerate_mod0 below · depth 12 - Parabolic pairings as a fixed multiple of mod-3 perfect forms
ModularCurve.PDPairing.exists_forall_smul_eq_pairZ_and_perfect_mod_three2 below · depth 13 - The two transfer Hecke operators agree at H=top
ModularCurve.PDPairing.heckeT0_apply_eq_heckeT_top_apply2 below · depth 14 - Base change of the parabolic lattice of Γ₀(N)
CohCarrier.exists_linearMap_baseChange_parabolicHoms_gamma0_range_eq_parabolicHoms_top5 below · depth 19 - Invariance of cusp sums under conjugation by GL₂⁺(ℝ)
ModularCurve.CupPairing.cuspSum_comp_eq_of_conjRel1 below · depth 22 - Cusp sums over Γ'≤Γ split along cusps of Γ
ModularCurve.CupPairing.cuspSum_eq_sum_finsum_of_le0 below · depth 22