Skip to content

Commit 30e138d

Browse files
committed
feat: port NumberTheory.ModularForms.CongruenceSubgroups (#4296)
1 parent 1164db8 commit 30e138d

File tree

2 files changed

+254
-0
lines changed

2 files changed

+254
-0
lines changed

Mathlib.lean

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1788,6 +1788,7 @@ import Mathlib.NumberTheory.LegendreSymbol.MulCharacter
17881788
import Mathlib.NumberTheory.LegendreSymbol.ZModChar
17891789
import Mathlib.NumberTheory.LucasLehmer
17901790
import Mathlib.NumberTheory.LucasPrimality
1791+
import Mathlib.NumberTheory.ModularForms.CongruenceSubgroups
17911792
import Mathlib.NumberTheory.Multiplicity
17921793
import Mathlib.NumberTheory.Padics.PadicNorm
17931794
import Mathlib.NumberTheory.Padics.PadicNumbers
Lines changed: 253 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,253 @@
1+
/-
2+
Copyright (c) 2022 Chris Birkbeck. All rights reserved.
3+
Released under Apache 2.0 license as described in the file LICENSE.
4+
Authors: Chris Birkbeck
5+
6+
! This file was ported from Lean 3 source module number_theory.modular_forms.congruence_subgroups
7+
! leanprover-community/mathlib commit ae690b0c236e488a0043f6faa8ce3546e7f2f9c5
8+
! Please do not edit these lines, except to modify the commit id
9+
! if you have ported upstream changes.
10+
-/
11+
import Mathlib.Data.ZMod.Basic
12+
import Mathlib.GroupTheory.GroupAction.ConjAct
13+
import Mathlib.GroupTheory.Subgroup.Pointwise
14+
import Mathlib.LinearAlgebra.Matrix.SpecialLinearGroup
15+
16+
/-!
17+
# Congruence subgroups
18+
19+
This defines congruence subgroups of `SL(2, ℤ)` such as `Γ(N)`, `Γ₀(N)` and `Γ₁(N)` for `N` a
20+
natural number.
21+
22+
It also contains basic results about congruence subgroups.
23+
24+
-/
25+
26+
27+
local notation "SL(" n ", " R ")" => Matrix.SpecialLinearGroup (Fin n) R
28+
29+
attribute [-instance] Matrix.SpecialLinearGroup.instCoeFun
30+
31+
local notation:1024 "↑ₘ" A:1024 => ((A : SL(2, ℤ)) : Matrix (Fin 2) (Fin 2) ℤ)
32+
33+
open Matrix.SpecialLinearGroup Matrix
34+
35+
variable (N : ℕ)
36+
37+
local notation "SLMOD(" N ")" =>
38+
@Matrix.SpecialLinearGroup.map (Fin 2) _ _ _ _ _ _ (Int.castRingHom (ZMod N))
39+
40+
set_option linter.uppercaseLean3 false
41+
42+
@[simp]
43+
theorem SL_reduction_mod_hom_val (N : ℕ) (γ : SL(2, ℤ)) :
44+
∀ i j : Fin 2, (SLMOD(N) γ : Matrix (Fin 2) (Fin 2) (ZMod N)) i j = ((↑ₘγ i j : ℤ) : ZMod N) :=
45+
fun _ _ => rfl
46+
#align SL_reduction_mod_hom_val SL_reduction_mod_hom_val
47+
48+
/-- The full level `N` congruence subgroup of `SL(2, ℤ)` of matrices that reduce to the identity
49+
modulo `N`.-/
50+
def Gamma (N : ℕ) : Subgroup SL(2, ℤ) :=
51+
SLMOD(N).ker
52+
#align Gamma Gamma
53+
54+
theorem Gamma_mem' (N : ℕ) (γ : SL(2, ℤ)) : γ ∈ Gamma N ↔ SLMOD(N) γ = 1 :=
55+
Iff.rfl
56+
#align Gamma_mem' Gamma_mem'
57+
58+
@[simp]
59+
theorem Gamma_mem (N : ℕ) (γ : SL(2, ℤ)) : γ ∈ Gamma N ↔ ((↑ₘγ 0 0 : ℤ) : ZMod N) = 1
60+
((↑ₘγ 0 1 : ℤ) : ZMod N) = 0 ∧ ((↑ₘγ 1 0 : ℤ) : ZMod N) = 0 ∧ ((↑ₘγ 1 1 : ℤ) : ZMod N) = 1 := by
61+
rw [Gamma_mem']
62+
constructor
63+
· intro h
64+
simp [← SL_reduction_mod_hom_val N γ, h]
65+
· intro h
66+
ext i; intro j
67+
rw [SL_reduction_mod_hom_val N γ]
68+
fin_cases i <;> fin_cases j <;> simp only [h]
69+
exacts [h.1, h.2.1, h.2.2.1, h.2.2.2]
70+
#align Gamma_mem Gamma_mem
71+
72+
theorem Gamma_normal (N : ℕ) : Subgroup.Normal (Gamma N) :=
73+
SLMOD(N).normal_ker
74+
#align Gamma_normal Gamma_normal
75+
76+
theorem Gamma_one_top : Gamma 1 = ⊤ := by
77+
ext
78+
simp
79+
#align Gamma_one_top Gamma_one_top
80+
81+
theorem Gamma_zero_bot : Gamma 0 = ⊥ := by
82+
ext
83+
simp only [Gamma_mem, coe_matrix_coe, Int.coe_castRingHom, map_apply, Int.cast_id,
84+
Subgroup.mem_bot]
85+
constructor
86+
· intro h
87+
ext i; intro j
88+
fin_cases i <;> fin_cases j <;> simp only [h]
89+
exacts [h.1, h.2.1, h.2.2.1, h.2.2.2]
90+
· intro h
91+
simp [h]
92+
#align Gamma_zero_bot Gamma_zero_bot
93+
94+
/-- The congruence subgroup of `SL(2, ℤ)` of matrices whose lower left-hand entry reduces to zero
95+
modulo `N`. -/
96+
def Gamma0 (N : ℕ) : Subgroup SL(2, ℤ) where
97+
carrier := { g : SL(2, ℤ) | ((↑ₘg 1 0 : ℤ) : ZMod N) = 0 }
98+
one_mem' := by simp
99+
mul_mem' := by
100+
intro a b ha hb
101+
simp only [Set.mem_setOf_eq]
102+
have h := (Matrix.two_mul_expl a.1 b.1).2.2.1
103+
simp only [coe_matrix_coe, coe_mul, Int.coe_castRingHom, map_apply, Set.mem_setOf_eq,
104+
mul_eq_mul] at *
105+
rw [h]
106+
simp [ha, hb]
107+
inv_mem' := by
108+
intro a ha
109+
simp only [Set.mem_setOf_eq]
110+
rw [SL2_inv_expl a]
111+
simp only [cons_val_zero, cons_val_one, head_cons, coe_matrix_coe,
112+
coe_mk, Int.coe_castRingHom, map_apply, Int.cast_neg, neg_eq_zero, Set.mem_setOf_eq] at *
113+
exact ha
114+
#align Gamma0 Gamma0
115+
116+
@[simp]
117+
theorem Gamma0_mem (N : ℕ) (A : SL(2, ℤ)) : A ∈ Gamma0 N ↔ ((↑ₘA 1 0 : ℤ) : ZMod N) = 0 :=
118+
Iff.rfl
119+
#align Gamma0_mem Gamma0_mem
120+
121+
theorem Gamma0_det (N : ℕ) (A : Gamma0 N) : (A.1.1.det : ZMod N) = 1 := by simp [A.1.property]
122+
#align Gamma0_det Gamma0_det
123+
124+
/-- The group homomorphism from `Gamma0` to `ZMod N` given by mapping a matrix to its lower
125+
right-hand entry. -/
126+
def Gamma0Map (N : ℕ) : Gamma0 N →* ZMod N where
127+
toFun g := ((↑ₘg 1 1 : ℤ) : ZMod N)
128+
map_one' := by simp
129+
map_mul' := by
130+
intro A B
131+
have := (two_mul_expl A.1.1 B.1.1).2.2.2
132+
simp only [Subgroup.coe_mul, coe_matrix_coe, coe_mul, Int.coe_castRingHom, map_apply,
133+
mul_eq_mul] at *
134+
rw [this]
135+
have ha := A.property
136+
simp only [Int.cast_add, Int.cast_mul, add_left_eq_self, Gamma0_mem,
137+
coe_matrix_coe, Int.coe_castRingHom, map_apply] at *
138+
rw [ha]
139+
simp
140+
#align Gamma_0_map Gamma0Map
141+
142+
/-- The congruence subgroup `Gamma1` (as a subgroup of `Gamma0`) of matrices whose bottom
143+
row is congruent to `(0,1)` modulo `N`.-/
144+
def Gamma1' (N : ℕ) : Subgroup (Gamma0 N) :=
145+
(Gamma0Map N).ker
146+
#align Gamma1' Gamma1'
147+
148+
@[simp, nolint simpNF] -- Porting note: linter failed to synth `CommMonoid { x // x ∈ Gamma0 N }`
149+
theorem Gamma1_mem' (N : ℕ) (γ : Gamma0 N) : γ ∈ Gamma1' N ↔ (Gamma0Map N) γ = 1 :=
150+
Iff.rfl
151+
#align Gamma1_mem' Gamma1_mem'
152+
153+
theorem Gamma1_to_Gamma0_mem (N : ℕ) (A : Gamma0 N) : A ∈ Gamma1' N ↔
154+
((↑ₘA 0 0 : ℤ) : ZMod N) = 1 ∧ ((↑ₘA 1 1 : ℤ) : ZMod N) = 1 ∧ ((↑ₘA 1 0 : ℤ) : ZMod N) = 0 := by
155+
constructor
156+
· intro ha
157+
have hA := A.property
158+
rw [Gamma0_mem] at hA
159+
have adet := Gamma0_det N A
160+
rw [Matrix.det_fin_two] at adet
161+
simp only [Gamma0Map, coe_matrix_coe, Int.coe_castRingHom, map_apply, Gamma1_mem',
162+
MonoidHom.coe_mk, OneHom.coe_mk, Int.cast_sub, Int.cast_mul] at *
163+
rw [hA, ha] at adet
164+
simp only [mul_one, MulZeroClass.mul_zero, sub_zero] at adet
165+
simp only [adet, hA, ha, eq_self_iff_true, and_self_iff]
166+
· intro ha
167+
simp only [Gamma1_mem', Gamma0Map, MonoidHom.coe_mk, coe_matrix_coe,
168+
Int.coe_castRingHom, map_apply]
169+
exact ha.2.1
170+
#align Gamma1_to_Gamma0_mem Gamma1_to_Gamma0_mem
171+
172+
/-- The congruence subgroup `Gamma1` of `SL(2, ℤ)` consisting of matrices whose bottom
173+
row is congruent to `(0,1)` modulo `N`. -/
174+
def Gamma1 (N : ℕ) : Subgroup SL(2, ℤ) :=
175+
Subgroup.map ((Gamma0 N).subtype.comp (Gamma1' N).subtype) ⊤
176+
#align Gamma1 Gamma1
177+
178+
@[simp]
179+
theorem Gamma1_mem (N : ℕ) (A : SL(2, ℤ)) : A ∈ Gamma1 N ↔
180+
((↑ₘA 0 0 : ℤ) : ZMod N) = 1 ∧ ((↑ₘA 1 1 : ℤ) : ZMod N) = 1 ∧ ((↑ₘA 1 0 : ℤ) : ZMod N) = 0 := by
181+
constructor
182+
· intro ha
183+
simp_rw [Gamma1, Subgroup.mem_map] at ha
184+
obtain ⟨⟨x, hx⟩, hxx⟩ := ha
185+
rw [Gamma1_to_Gamma0_mem] at hx
186+
simp only [Subgroup.mem_top, true_and] at hxx
187+
rw [← hxx]
188+
convert hx
189+
· intro ha
190+
simp_rw [Gamma1, Subgroup.mem_map]
191+
have hA : A ∈ Gamma0 N := by simp [ha.right.right, Gamma0_mem]
192+
have HA : (⟨A, hA⟩ : Gamma0 N) ∈ Gamma1' N := by
193+
simp only [Gamma1_to_Gamma0_mem, Subgroup.coe_mk, coe_matrix_coe,
194+
Int.coe_castRingHom, map_apply]
195+
exact ha
196+
refine' ⟨(⟨(⟨A, hA⟩ : Gamma0 N), HA⟩ : (Gamma1' N : Subgroup (Gamma0 N))), _⟩
197+
simp
198+
#align Gamma1_mem Gamma1_mem
199+
200+
theorem Gamma1_in_Gamma0 (N : ℕ) : Gamma1 N ≤ Gamma0 N := by
201+
intro x HA
202+
simp only [Gamma0_mem, Gamma1_mem, coe_matrix_coe, Int.coe_castRingHom, map_apply] at *
203+
exact HA.2.2
204+
#align Gamma1_in_Gamma0 Gamma1_in_Gamma0
205+
206+
section CongruenceSubgroup
207+
208+
/-- A congruence subgroup is a subgroup of `SL(2, ℤ)` which contains some `Gamma N` for some
209+
`(N : ℕ+)`. -/
210+
def IsCongruenceSubgroup (Γ : Subgroup SL(2, ℤ)) : Prop :=
211+
∃ N : ℕ+, Gamma N ≤ Γ
212+
#align is_congruence_subgroup IsCongruenceSubgroup
213+
214+
theorem isCongruenceSubgroup_trans (H K : Subgroup SL(2, ℤ)) (h : H ≤ K)
215+
(h2 : IsCongruenceSubgroup H) : IsCongruenceSubgroup K := by
216+
obtain ⟨N, hN⟩ := h2
217+
refine' ⟨N, le_trans hN h⟩
218+
#align is_congruence_subgroup_trans isCongruenceSubgroup_trans
219+
220+
theorem Gamma_is_cong_sub (N : ℕ+) : IsCongruenceSubgroup (Gamma N) :=
221+
⟨N, by simp only [le_refl]⟩
222+
#align Gamma_is_cong_sub Gamma_is_cong_sub
223+
224+
theorem Gamma1_is_congruence (N : ℕ+) : IsCongruenceSubgroup (Gamma1 N) := by
225+
refine' ⟨N, _⟩
226+
intro A hA
227+
simp only [Gamma1_mem, Gamma_mem] at *
228+
simp only [hA, eq_self_iff_true, and_self_iff]
229+
#align Gamma1_is_congruence Gamma1_is_congruence
230+
231+
theorem Gamma0_is_congruence (N : ℕ+) : IsCongruenceSubgroup (Gamma0 N) :=
232+
isCongruenceSubgroup_trans _ _ (Gamma1_in_Gamma0 N) (Gamma1_is_congruence N)
233+
#align Gamma0_is_congruence Gamma0_is_congruence
234+
235+
end CongruenceSubgroup
236+
237+
section Conjugation
238+
239+
open Pointwise
240+
241+
theorem Gamma_cong_eq_self (N : ℕ) (g : ConjAct SL(2, ℤ)) : g • Gamma N = Gamma N := by
242+
apply Subgroup.Normal.conjAct (Gamma_normal N)
243+
#align Gamma_cong_eq_self Gamma_cong_eq_self
244+
245+
theorem conj_cong_is_cong (g : ConjAct SL(2, ℤ)) (Γ : Subgroup SL(2, ℤ))
246+
(h : IsCongruenceSubgroup Γ) : IsCongruenceSubgroup (g • Γ) := by
247+
obtain ⟨N, HN⟩ := h
248+
refine' ⟨N, _⟩
249+
rw [← Gamma_cong_eq_self N g, Subgroup.pointwise_smul_le_pointwise_smul_iff]
250+
exact HN
251+
#align conj_cong_is_cong conj_cong_is_cong
252+
253+
end Conjugation

0 commit comments

Comments
 (0)