File: Mathlib/NumberTheory/Modular.lean

full_name: «_aux_Mathlib_NumberTheory_Modular___macroRules_termSL(_,_)_1»
code: local notation "SL(" n ", " R ")" => SpecialLinearGroup (Fin n) R
goal: Lean.Macro

full_name: _aux_Mathlib_NumberTheory_Modular___unexpand_Matrix_SpecialLinearGroup_1
code: local notation "SL(" n ", " R ")" => SpecialLinearGroup (Fin n) R
goal: Lean.PrettyPrinter.Unexpander

full_name: «_aux_Mathlib_NumberTheory_Modular___macroRules_term↑ₘ__1»
code: macro "↑ₘ" t:term:80 : term => `(term| ($t : Matrix (Fin 2) (Fin 2) ℤ))
goal: Lean.Macro

full_name: term↑ₘ_._@.Mathlib.NumberTheory.Modular._hyg.608
code: macro "↑ₘ" t:term:80 : term => `(term| ($t : Matrix (Fin 2) (Fin 2) ℤ))
goal: Lean.ParserDescr

full_name: ModularGroup.bottom_row_coprime
code: /-- The two numbers `c`, `d` in the "bottom_row" of `g=[[*,*],[c,d]]` in `SL(2, ℤ)` are coprime. -/
theorem bottom_row_coprime {R : Type*} [CommRing R] (g : SL(2, R)) :
    IsCoprime ((↑g : Matrix (Fin 2) (Fin 2) R) 1 0) ((↑g : Matrix (Fin 2) (Fin 2) R) 1 1) 
goal: IsCoprime (↑g 1 0) (↑g 1 1)

full_name: ModularGroup.bottom_row_surj
code: /-- Every pair `![c, d]` of coprime integers is the "bottom_row" of some element `g=[[*,*],[c,d]]`
of `SL(2,ℤ)`. -/
theorem bottom_row_surj {R : Type*} [CommRing R] :
    Set.SurjOn (fun g : SL(2, R) => (↑g : Matrix (Fin 2) (Fin 2) R) 1) Set.univ
      {cd | IsCoprime (cd 0) (cd 1)} 
goal: Set.SurjOn (fun g => ↑g 1) Set.univ {cd | IsCoprime (cd 0) (cd 1)}

full_name: ModularGroup.tendsto_normSq_coprime_pair
code: /-- The function `(c,d) → |cz+d|^2` is proper, that is, preimages of bounded-above sets are finite.
-/
theorem tendsto_normSq_coprime_pair :
    Filter.Tendsto (fun p : Fin 2 → ℤ => normSq ((p 0 : ℂ) * z + p 1)) cofinite atTop 
goal: Filter.Tendsto (fun p => Complex.normSq (↑(p 0) * ↑z + ↑(p 1))) Filter.cofinite Filter.atTop

full_name: ModularGroup.lcRow0
code: /-- Given `coprime_pair` `p=(c,d)`, the matrix `[[a,b],[*,*]]` is sent to `a*c+b*d`.
  This is the linear map version of this operation.
-/
def lcRow0 (p : Fin 2 → ℤ) : Matrix (Fin 2) (Fin 2) ℝ →ₗ[ℝ] ℝ 
goal: Matrix (Fin 2) (Fin 2) ℝ →ₗ[ℝ] ℝ

full_name: ModularGroup.lcRow0_apply
code: @[simp]
theorem lcRow0_apply (p : Fin 2 → ℤ) (g : Matrix (Fin 2) (Fin 2) ℝ) :
    lcRow0 p g = p 0 * g 0 0 + p 1 * g 0 1 
goal: (ModularGroup.lcRow0 p) g = ↑(p 0) * g 0 0 + ↑(p 1) * g 0 1

full_name: ModularGroup.lcRow0Extend_apply
code: /-- Linear map sending the matrix [a, b; c, d] to the matrix [ac₀ + bd₀, - ad₀ + bc₀; c, d], for
some fixed `(c₀, d₀)`. -/
@[simps!]
def lcRow0Extend {cd : Fin 2 → ℤ} (hcd : IsCoprime (cd 0) (cd 1)) :
    Matrix (Fin 2) (Fin 2) ℝ ≃ₗ[ℝ] Matrix (Fin 2) (Fin 2) ℝ 
goal: ∀ (a : Fin 2),
  (ModularGroup.lcRow0Extend hcd) f i a =
    (![(LinearMap.GeneralLinearGroup.generalLinearEquiv ℝ (Fin 2 → ℝ))
            (Matrix.GeneralLinearGroup.toLinear (Matrix.planeConformalMatrix (↑(cd 0)) (-↑(cd 1)) ⋯)),
          LinearEquiv.refl ℝ (Fin 2 → ℝ)]
        i)
      (f i) a

full_name: ModularGroup.lcRow0Extend_symm_apply
code: /-- Linear map sending the matrix [a, b; c, d] to the matrix [ac₀ + bd₀, - ad₀ + bc₀; c, d], for
some fixed `(c₀, d₀)`. -/
@[simps!]
def lcRow0Extend {cd : Fin 2 → ℤ} (hcd : IsCoprime (cd 0) (cd 1)) :
    Matrix (Fin 2) (Fin 2) ℝ ≃ₗ[ℝ] Matrix (Fin 2) (Fin 2) ℝ 
goal: ∀ (a : Fin 2),
  (ModularGroup.lcRow0Extend hcd).symm f i a =
    (![(LinearMap.GeneralLinearGroup.generalLinearEquiv ℝ (Fin 2 → ℝ))
              (Matrix.GeneralLinearGroup.toLinear (Matrix.planeConformalMatrix (↑(cd 0)) (-↑(cd 1)) ⋯)),
            LinearEquiv.refl ℝ (Fin 2 → ℝ)]
          i).symm
      (f i) a

full_name: ModularGroup.lcRow0Extend
code: /-- Linear map sending the matrix [a, b; c, d] to the matrix [ac₀ + bd₀, - ad₀ + bc₀; c, d], for
some fixed `(c₀, d₀)`. -/
@[simps!]
def lcRow0Extend {cd : Fin 2 → ℤ} (hcd : IsCoprime (cd 0) (cd 1)) :
    Matrix (Fin 2) (Fin 2) ℝ ≃ₗ[ℝ] Matrix (Fin 2) (Fin 2) ℝ 
goal: Matrix (Fin 2) (Fin 2) ℝ ≃ₗ[ℝ] Matrix (Fin 2) (Fin 2) ℝ

full_name: ModularGroup.tendsto_lcRow0
code: /-- The map `lcRow0` is proper, that is, preimages of cocompact sets are finite in
`[[* , *], [c, d]]`. -/
theorem tendsto_lcRow0 {cd : Fin 2 → ℤ} (hcd : IsCoprime (cd 0) (cd 1)) :
    Tendsto (fun g : { g : SL(2, ℤ) // (↑ₘg) 1 = cd } => lcRow0 cd ↑(↑g : SL(2, ℝ))) cofinite
      (cocompact ℝ) 
goal: Filter.Tendsto (fun g => (ModularGroup.lcRow0 cd) ↑((Matrix.SpecialLinearGroup.map (Int.castRingHom ℝ)) ↑g))
  Filter.cofinite (Filter.cocompact ℝ)

full_name: ModularGroup.smul_eq_lcRow0_add
code: /-- This replaces `(g•z).re = a/c + *` in the standard theory with the following novel identity:
  `g • z = (a c + b d) / (c^2 + d^2) + (d z - c) / ((c^2 + d^2) (c z + d))`
  which does not need to be decomposed depending on whether `c = 0`. -/
theorem smul_eq_lcRow0_add {p : Fin 2 → ℤ} (hp : IsCoprime (p 0) (p 1)) (hg : (↑ₘg) 1 = p) :
    ↑(g • z) =
      (lcRow0 p ↑(g : SL(2, ℝ)) : ℂ) / ((p 0 : ℂ) ^ 2 + (p 1 : ℂ) ^ 2) +
        ((p 1 : ℂ) * z - p 0) / (((p 0 : ℂ) ^ 2 + (p 1 : ℂ) ^ 2) * (p 0 * z + p 1)) 
goal: ↑(g • z) =
  ↑((ModularGroup.lcRow0 p) ↑((Matrix.SpecialLinearGroup.map (Int.castRingHom ℝ)) g)) / (↑(p 0) ^ 2 + ↑(p 1) ^ 2) +
    (↑(p 1) * ↑z - ↑(p 0)) / ((↑(p 0) ^ 2 + ↑(p 1) ^ 2) * (↑(p 0) * ↑z + ↑(p 1)))

full_name: ModularGroup.tendsto_abs_re_smul
code: theorem tendsto_abs_re_smul {p : Fin 2 → ℤ} (hp : IsCoprime (p 0) (p 1)) :
    Tendsto
      (fun g : { g : SL(2, ℤ) // (↑ₘg) 1 = p } => |((g : SL(2, ℤ)) • z).re|) cofinite atTop 
goal: Filter.Tendsto (fun g => |(↑g • z).re|) Filter.cofinite Filter.atTop

full_name: ModularGroup.exists_max_im
code: /-- For `z : ℍ`, there is a `g : SL(2,ℤ)` maximizing `(g•z).im` -/
theorem exists_max_im : ∃ g : SL(2, ℤ), ∀ g' : SL(2, ℤ), (g' • z).im ≤ (g • z).im 
goal: ∃ g, ∀ (g' : SL(2, ℤ)), (g' • z).im ≤ (g • z).im

full_name: ModularGroup.exists_row_one_eq_and_min_re
code: /-- Given `z : ℍ` and a bottom row `(c,d)`, among the `g : SL(2,ℤ)` with this bottom row, minimize
  `|(g•z).re|`.  -/
theorem exists_row_one_eq_and_min_re {cd : Fin 2 → ℤ} (hcd : IsCoprime (cd 0) (cd 1)) :
    ∃ g : SL(2, ℤ), (↑ₘg) 1 = cd ∧ ∀ g' : SL(2, ℤ), (↑ₘg) 1 = (↑ₘg') 1 →
      |(g • z).re| ≤ |(g' • z).re| 
goal: ∃ g, ↑g 1 = cd ∧ ∀ (g' : SL(2, ℤ)), ↑g 1 = ↑g' 1 → |(g • z).re| ≤ |(g' • z).re|

full_name: ModularGroup.coe_T_zpow_smul_eq
code: theorem coe_T_zpow_smul_eq {n : ℤ} : (↑(T ^ n • z) : ℂ) = z + n 
goal: ↑(ModularGroup.T ^ n • z) = ↑z + ↑n

full_name: ModularGroup.re_T_zpow_smul
code: theorem re_T_zpow_smul (n : ℤ) : (T ^ n • z).re = z.re + n 
goal: (ModularGroup.T ^ n • z).re = z.re + ↑n

full_name: ModularGroup.im_T_zpow_smul
code: theorem im_T_zpow_smul (n : ℤ) : (T ^ n • z).im = z.im 
goal: (ModularGroup.T ^ n • z).im = z.im

full_name: ModularGroup.re_T_smul
code: theorem re_T_smul : (T • z).re = z.re + 1 
goal: (ModularGroup.T • z).re = z.re + 1

full_name: ModularGroup.im_T_smul
code: theorem im_T_smul : (T • z).im = z.im 
goal: (ModularGroup.T • z).im = z.im

full_name: ModularGroup.re_T_inv_smul
code: theorem re_T_inv_smul : (T⁻¹ • z).re = z.re - 1 
goal: (ModularGroup.T⁻¹ • z).re = z.re - 1

full_name: ModularGroup.im_T_inv_smul
code: theorem im_T_inv_smul : (T⁻¹ • z).im = z.im 
goal: (ModularGroup.T⁻¹ • z).im = z.im

full_name: ModularGroup.exists_eq_T_zpow_of_c_eq_zero
code: theorem exists_eq_T_zpow_of_c_eq_zero (hc : (↑ₘg) 1 0 = 0) :
    ∃ n : ℤ, ∀ z : ℍ, g • z = T ^ n • z 
goal: ∃ n, ∀ (z : ℍ), g • z = ModularGroup.T ^ n • z

full_name: ModularGroup.g_eq_of_c_eq_one
code: theorem g_eq_of_c_eq_one (hc : (↑ₘg) 1 0 = 1) : g = T ^ (↑ₘg) 0 0 * S * T ^ (↑ₘg) 1 1 
goal: g = ModularGroup.T ^ ↑g 0 0 * ModularGroup.S * ModularGroup.T ^ ↑g 1 1

full_name: ModularGroup.normSq_S_smul_lt_one
code: /-- If `1 < |z|`, then `|S • z| < 1`. -/
theorem normSq_S_smul_lt_one (h : 1 < normSq z) : normSq ↑(S • z) < 1 
goal: Complex.normSq ↑(ModularGroup.S • z) < 1

full_name: ModularGroup.im_lt_im_S_smul
code: /-- If `|z| < 1`, then applying `S` strictly decreases `im`. -/
theorem im_lt_im_S_smul (h : normSq z < 1) : z.im < (S • z).im 
goal: z.im < (ModularGroup.S • z).im

full_name: ModularGroup.fd
code: /-- The standard (closed) fundamental domain of the action of `SL(2,ℤ)` on `ℍ`. -/
def fd : Set ℍ 
goal: Set ℍ

full_name: ModularGroup.fdo
code: /-- The standard open fundamental domain of the action of `SL(2,ℤ)` on `ℍ`. -/
def fdo : Set ℍ 
goal: Set ℍ

full_name: Modular._aux_Mathlib_NumberTheory_Modular___macroRules_Modular_term𝒟_1
code: @[inherit_doc ModularGroup.fd]
scoped[Modular] notation "𝒟" => ModularGroup.fd
goal: Lean.Macro

full_name: Modular._aux_Mathlib_NumberTheory_Modular___unexpand_ModularGroup_fd_1
code: @[inherit_doc ModularGroup.fd]
scoped[Modular] notation "𝒟" => ModularGroup.fd
goal: Lean.PrettyPrinter.Unexpander

full_name: Modular._aux_Mathlib_NumberTheory_Modular___unexpand_ModularGroup_fdo_1
code: @[inherit_doc ModularGroup.fdo]
scoped[Modular] notation "𝒟ᵒ" => ModularGroup.fdo
goal: Lean.PrettyPrinter.Unexpander

full_name: Modular.«_aux_Mathlib_NumberTheory_Modular___macroRules_Modular_term𝒟ᵒ_1»
code: @[inherit_doc ModularGroup.fdo]
scoped[Modular] notation "𝒟ᵒ" => ModularGroup.fdo
goal: Lean.Macro

full_name: ModularGroup.abs_two_mul_re_lt_one_of_mem_fdo
code: theorem abs_two_mul_re_lt_one_of_mem_fdo (h : z ∈ 𝒟ᵒ) : |2 * z.re| < 1 
goal: |2 * z.re| < 1

full_name: ModularGroup.three_lt_four_mul_im_sq_of_mem_fdo
code: theorem three_lt_four_mul_im_sq_of_mem_fdo (h : z ∈ 𝒟ᵒ) : 3 < 4 * z.im ^ 2 
goal: 3 < 4 * z.im ^ 2

full_name: ModularGroup.one_lt_normSq_T_zpow_smul
code: /-- If `z ∈ 𝒟ᵒ`, and `n : ℤ`, then `|z + n| > 1`. -/
theorem one_lt_normSq_T_zpow_smul (hz : z ∈ 𝒟ᵒ) (n : ℤ) : 1 < normSq (T ^ n • z : ℍ) 
goal: 1 < Complex.normSq ↑(ModularGroup.T ^ n • z)

full_name: ModularGroup.eq_zero_of_mem_fdo_of_T_zpow_mem_fdo
code: theorem eq_zero_of_mem_fdo_of_T_zpow_mem_fdo {n : ℤ} (hz : z ∈ 𝒟ᵒ) (hg : T ^ n • z ∈ 𝒟ᵒ) :
    n = 0 
goal: n = 0

full_name: ModularGroup.exists_smul_mem_fd
code: /-- First Fundamental Domain Lemma: Any `z : ℍ` can be moved to `𝒟` by an element of
`SL(2,ℤ)` -/
theorem exists_smul_mem_fd (z : ℍ) : ∃ g : SL(2, ℤ), g • z ∈ 𝒟 
goal: ∃ g, g • z ∈ ModularGroup.fd

full_name: ModularGroup.abs_c_le_one
code: /-- An auxiliary result en route to `ModularGroup.c_eq_zero`. -/
theorem abs_c_le_one (hz : z ∈ 𝒟ᵒ) (hg : g • z ∈ 𝒟ᵒ) : |(↑ₘg) 1 0| ≤ 1 
goal: |↑g 1 0| ≤ 1

full_name: ModularGroup.c_eq_zero
code: /-- An auxiliary result en route to `ModularGroup.eq_smul_self_of_mem_fdo_mem_fdo`. -/
theorem c_eq_zero (hz : z ∈ 𝒟ᵒ) (hg : g • z ∈ 𝒟ᵒ) : (↑ₘg) 1 0 = 0 
goal: ↑g 1 0 = 0

full_name: ModularGroup.eq_smul_self_of_mem_fdo_mem_fdo
code: /-- Second Fundamental Domain Lemma: if both `z` and `g • z` are in the open domain `𝒟ᵒ`,
where `z : ℍ` and `g : SL(2,ℤ)`, then `z = g • z`. -/
theorem eq_smul_self_of_mem_fdo_mem_fdo (hz : z ∈ 𝒟ᵒ) (hg : g • z ∈ 𝒟ᵒ) : z = g • z 
goal: z = g • z