Sphere Packing in R^8

7. Modular Forms🔗

In this section, we recall and develop some theory of (quasi)modular forms.

Let \mathbb{H} be the upper half-plane \{z \in \mathbb{C} \mid \Im(z) > 0\}.

The modular group \Gamma_1:=\mathrm{SL}_2(\mathbb{Z}) acts on \mathbb{H} by linear fractional transformations \begin{pmatrix}a&b\\c&d\end{pmatrix}z:=\frac{az+b}{cz+d}.

Proof
Definition7.2
XL∃∀N
Used by 2
Hover a use site to preview it.
Preview
Definition 7.3
Loading preview
Hover a use site to preview it.

The level N principal congruence subgroup of \Gamma_1 is \Gamma(N):=\left\{\left.\left(\begin{smallmatrix}a&b\\c&d\end{smallmatrix}\right)\in\Gamma_1\right|\left(\begin{smallmatrix}a&b\\c&d\end{smallmatrix}\right)\equiv\left(\begin{smallmatrix}1&0\\0&1\end{smallmatrix}\right)\;\mathrm{mod}\;N\right\}.

A subgroup \Gamma \subset \Gamma_1 is a congruence subgroup if \Gamma(N) \subset \Gamma for some N \in \mathbb{N}. Uses Definition 7.2.

Definition7.4

Define the matrices S = \begin{pmatrix} 0 & -1 \\ 1 & 0 \end{pmatrix} \in \Gamma_1 T = \begin{pmatrix} 1 & 1 \\ 0 & 1 \end{pmatrix} \in \Gamma_1 \alpha = \begin{pmatrix} 1 & 2 \\ 0 & 1 \end{pmatrix} \in \Gamma_2 \subset \Gamma_1 \beta = \begin{pmatrix} 1 & 0 \\ 2 & 1 \end{pmatrix} \in \Gamma_2 \subset \Gamma_1. It is easily verifiable that \alpha = T^2 and \beta = -S\alpha^{-1}S = -ST^{-2}S. Uses Definition 7.2.

Lean code for Definition7.44 definitions
  • def ModularGroup.S : Matrix.SpecialLinearGroupMatrix.SpecialLinearGroup.{u, v} (n : Type u) [DecidableEq n] [Fintype n] (R : Type v) [CommRing R] : Type (max 0 u v)`SpecialLinearGroup n R` is the group of `n` by `n` `R`-matrices with determinant equal to 1.
     (FinFin (n : ℕ) : TypeNatural numbers less than some upper bound.
    
    In particular, a `Fin n` is a natural number `i` with the constraint that `i < n`. It is the
    canonical type with `n` elements.
     2) Int : TypeThe integers.
    
    This type is special-cased by the compiler and overridden with an efficient implementation. The
    runtime has a special representation for `Int` that stores “small” signed numbers directly, while
    larger numbers use a fast arbitrary-precision arithmetic library (usually
    [GMP](https://gmplib.org/)). A “small number” is an integer that can be encoded with one fewer bits
    than the platform's pointer size (i.e. 63 bits on 64-bit architectures and 31 bits on 32-bit
    architectures).
    
    def ModularGroup.S :
      Matrix.SpecialLinearGroupMatrix.SpecialLinearGroup.{u, v} (n : Type u) [DecidableEq n] [Fintype n] (R : Type v) [CommRing R] : Type (max 0 u v)`SpecialLinearGroup n R` is the group of `n` by `n` `R`-matrices with determinant equal to 1.
     (FinFin (n : ℕ) : TypeNatural numbers less than some upper bound.
    
    In particular, a `Fin n` is a natural number `i` with the constraint that `i < n`. It is the
    canonical type with `n` elements.
     2) Int : TypeThe integers.
    
    This type is special-cased by the compiler and overridden with an efficient implementation. The
    runtime has a special representation for `Int` that stores “small” signed numbers directly, while
    larger numbers use a fast arbitrary-precision arithmetic library (usually
    [GMP](https://gmplib.org/)). A “small number” is an integer that can be encoded with one fewer bits
    than the platform's pointer size (i.e. 63 bits on 64-bit architectures and 31 bits on 32-bit
    architectures).
    
    The matrix `S = [[0, -1], [1, 0]]` as an element of `SL(2, ℤ)`.
    
    This element acts naturally on the Euclidean plane as a rotation about the origin by `π / 2`.
    
    This element also acts naturally on the hyperbolic plane as rotation about `i` by `π`. It
    represents the Mobiüs transformation `z ↦ -1/z` and is an involutive elliptic isometry. 
    complete
  • def ModularGroup.T : Matrix.SpecialLinearGroupMatrix.SpecialLinearGroup.{u, v} (n : Type u) [DecidableEq n] [Fintype n] (R : Type v) [CommRing R] : Type (max 0 u v)`SpecialLinearGroup n R` is the group of `n` by `n` `R`-matrices with determinant equal to 1.
     (FinFin (n : ℕ) : TypeNatural numbers less than some upper bound.
    
    In particular, a `Fin n` is a natural number `i` with the constraint that `i < n`. It is the
    canonical type with `n` elements.
     2) Int : TypeThe integers.
    
    This type is special-cased by the compiler and overridden with an efficient implementation. The
    runtime has a special representation for `Int` that stores “small” signed numbers directly, while
    larger numbers use a fast arbitrary-precision arithmetic library (usually
    [GMP](https://gmplib.org/)). A “small number” is an integer that can be encoded with one fewer bits
    than the platform's pointer size (i.e. 63 bits on 64-bit architectures and 31 bits on 32-bit
    architectures).
    
    def ModularGroup.T :
      Matrix.SpecialLinearGroupMatrix.SpecialLinearGroup.{u, v} (n : Type u) [DecidableEq n] [Fintype n] (R : Type v) [CommRing R] : Type (max 0 u v)`SpecialLinearGroup n R` is the group of `n` by `n` `R`-matrices with determinant equal to 1.
     (FinFin (n : ℕ) : TypeNatural numbers less than some upper bound.
    
    In particular, a `Fin n` is a natural number `i` with the constraint that `i < n`. It is the
    canonical type with `n` elements.
     2) Int : TypeThe integers.
    
    This type is special-cased by the compiler and overridden with an efficient implementation. The
    runtime has a special representation for `Int` that stores “small” signed numbers directly, while
    larger numbers use a fast arbitrary-precision arithmetic library (usually
    [GMP](https://gmplib.org/)). A “small number” is an integer that can be encoded with one fewer bits
    than the platform's pointer size (i.e. 63 bits on 64-bit architectures and 31 bits on 32-bit
    architectures).
    
    The matrix `T = [[1, 1], [0, 1]]` as an element of `SL(2, ℤ)`. 
    complete
  • def α : (CongruenceSubgroup.GammaCongruenceSubgroup.Gamma (N : ℕ) : Subgroup (Matrix.SpecialLinearGroup (Fin 2) ℤ)The full level `N` congruence subgroup of `SL(2, ℤ)` of matrices that reduce to the identity
    modulo `N`.  2)
    def α : (CongruenceSubgroup.GammaCongruenceSubgroup.Gamma (N : ℕ) : Subgroup (Matrix.SpecialLinearGroup (Fin 2) ℤ)The full level `N` congruence subgroup of `SL(2, ℤ)` of matrices that reduce to the identity
    modulo `N`.  2)
    complete
  • def β : (CongruenceSubgroup.GammaCongruenceSubgroup.Gamma (N : ℕ) : Subgroup (Matrix.SpecialLinearGroup (Fin 2) ℤ)The full level `N` congruence subgroup of `SL(2, ℤ)` of matrices that reduce to the identity
    modulo `N`.  2)
    def β : (CongruenceSubgroup.GammaCongruenceSubgroup.Gamma (N : ℕ) : Subgroup (Matrix.SpecialLinearGroup (Fin 2) ℤ)The full level `N` congruence subgroup of `SL(2, ℤ)` of matrices that reduce to the identity
    modulo `N`.  2)
    complete
Lean code for Lemma7.51 theorem
  • theorem SL2Z_generate : Top.top.{u_1} {α : Type u_1} [self : Top α] : αThe top (`⊤`, `\top`) element 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `⊤` in identifiers is `top`. =Eq.{u_1} {α : Sort u_1} : α → α → PropThe equality relation. It has one introduction rule, `Eq.refl`.
    We use `a = b` as notation for `Eq a b`.
    A fundamental property of equality is that it is an equivalence relation.
    ```
    variable (α : Type) (a b c d : α)
    variable (hab : a = b) (hcb : c = b) (hcd : c = d)
    
    example : a = d :=
      Eq.trans (Eq.trans hab (Eq.symm hcb)) hcd
    ```
    Equality is much more than an equivalence relation, however. It has the important property that every assertion
    respects the equivalence, in the sense that we can substitute equal expressions without changing the truth value.
    That is, given `h1 : a = b` and `h2 : p a`, we can construct a proof for `p b` using substitution: `Eq.subst h1 h2`.
    Example:
    ```
    example (α : Type) (a b : α) (p : α → Prop)
            (h1 : a = b) (h2 : p a) : p b :=
      Eq.subst h1 h2
    
    example (α : Type) (a b : α) (p : α → Prop)
        (h1 : a = b) (h2 : p a) : p b :=
      h1 ▸ h2
    ```
    The triangle in the second presentation is a macro built on top of `Eq.subst` and `Eq.symm`, and you can enter it by typing `\t`.
    For more information: [Equality](https://lean-lang.org/theorem_proving_in_lean4/quantifiers_and_equality.html#equality)
    
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `=` in identifiers is `eq`. Subgroup.closureSubgroup.closure.{u_1} {G : Type u_1} [Group G] (k : Set G) : Subgroup GThe `Subgroup` generated by a set.  {Insert.insert.{u, v} {α : outParam (Type u)} {γ : Type v} [self : Insert α γ] : α → γ → γ`insert x xs` inserts the element `x` into the collection `xs`. ModularGroup.SModularGroup.S : Matrix.SpecialLinearGroup (Fin 2) ℤThe matrix `S = [[0, -1], [1, 0]]` as an element of `SL(2, ℤ)`.
    
    This element acts naturally on the Euclidean plane as a rotation about the origin by `π / 2`.
    
    This element also acts naturally on the hyperbolic plane as rotation about `i` by `π`. It
    represents the Mobiüs transformation `z ↦ -1/z` and is an involutive elliptic isometry. ,Insert.insert.{u, v} {α : outParam (Type u)} {γ : Type v} [self : Insert α γ] : α → γ → γ`insert x xs` inserts the element `x` into the collection `xs`.  ModularGroup.TModularGroup.T : Matrix.SpecialLinearGroup (Fin 2) ℤThe matrix `T = [[1, 1], [0, 1]]` as an element of `SL(2, ℤ)`. }Insert.insert.{u, v} {α : outParam (Type u)} {γ : Type v} [self : Insert α γ] : α → γ → γ`insert x xs` inserts the element `x` into the collection `xs`. 
    theorem SL2Z_generate :
      Top.top.{u_1} {α : Type u_1} [self : Top α] : αThe top (`⊤`, `\top`) element 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `⊤` in identifiers is `top`. =Eq.{u_1} {α : Sort u_1} : α → α → PropThe equality relation. It has one introduction rule, `Eq.refl`.
    We use `a = b` as notation for `Eq a b`.
    A fundamental property of equality is that it is an equivalence relation.
    ```
    variable (α : Type) (a b c d : α)
    variable (hab : a = b) (hcb : c = b) (hcd : c = d)
    
    example : a = d :=
      Eq.trans (Eq.trans hab (Eq.symm hcb)) hcd
    ```
    Equality is much more than an equivalence relation, however. It has the important property that every assertion
    respects the equivalence, in the sense that we can substitute equal expressions without changing the truth value.
    That is, given `h1 : a = b` and `h2 : p a`, we can construct a proof for `p b` using substitution: `Eq.subst h1 h2`.
    Example:
    ```
    example (α : Type) (a b : α) (p : α → Prop)
            (h1 : a = b) (h2 : p a) : p b :=
      Eq.subst h1 h2
    
    example (α : Type) (a b : α) (p : α → Prop)
        (h1 : a = b) (h2 : p a) : p b :=
      h1 ▸ h2
    ```
    The triangle in the second presentation is a macro built on top of `Eq.subst` and `Eq.symm`, and you can enter it by typing `\t`.
    For more information: [Equality](https://lean-lang.org/theorem_proving_in_lean4/quantifiers_and_equality.html#equality)
    
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `=` in identifiers is `eq`.
        Subgroup.closureSubgroup.closure.{u_1} {G : Type u_1} [Group G] (k : Set G) : Subgroup GThe `Subgroup` generated by a set. 
          {Insert.insert.{u, v} {α : outParam (Type u)} {γ : Type v} [self : Insert α γ] : α → γ → γ`insert x xs` inserts the element `x` into the collection `xs`. ModularGroup.SModularGroup.S : Matrix.SpecialLinearGroup (Fin 2) ℤThe matrix `S = [[0, -1], [1, 0]]` as an element of `SL(2, ℤ)`.
    
    This element acts naturally on the Euclidean plane as a rotation about the origin by `π / 2`.
    
    This element also acts naturally on the hyperbolic plane as rotation about `i` by `π`. It
    represents the Mobiüs transformation `z ↦ -1/z` and is an involutive elliptic isometry. ,Insert.insert.{u, v} {α : outParam (Type u)} {γ : Type v} [self : Insert α γ] : α → γ → γ`insert x xs` inserts the element `x` into the collection `xs`.  ModularGroup.TModularGroup.T : Matrix.SpecialLinearGroup (Fin 2) ℤThe matrix `T = [[1, 1], [0, 1]]` as an element of `SL(2, ℤ)`. }Insert.insert.{u, v} {α : outParam (Type u)} {γ : Type v} [self : Insert α γ] : α → γ → γ`insert x xs` inserts the element `x` into the collection `xs`. 
    complete

We have \Gamma(2) = \langle \alpha, \beta, -I \rangle. Uses Definition 7.4.

Lean code for Lemma7.61 theorem
  • theorem Γ2_generate : Top.top.{u_1} {α : Type u_1} [self : Top α] : αThe top (`⊤`, `\top`) element 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `⊤` in identifiers is `top`. =Eq.{u_1} {α : Sort u_1} : α → α → PropThe equality relation. It has one introduction rule, `Eq.refl`.
    We use `a = b` as notation for `Eq a b`.
    A fundamental property of equality is that it is an equivalence relation.
    ```
    variable (α : Type) (a b c d : α)
    variable (hab : a = b) (hcb : c = b) (hcd : c = d)
    
    example : a = d :=
      Eq.trans (Eq.trans hab (Eq.symm hcb)) hcd
    ```
    Equality is much more than an equivalence relation, however. It has the important property that every assertion
    respects the equivalence, in the sense that we can substitute equal expressions without changing the truth value.
    That is, given `h1 : a = b` and `h2 : p a`, we can construct a proof for `p b` using substitution: `Eq.subst h1 h2`.
    Example:
    ```
    example (α : Type) (a b : α) (p : α → Prop)
            (h1 : a = b) (h2 : p a) : p b :=
      Eq.subst h1 h2
    
    example (α : Type) (a b : α) (p : α → Prop)
        (h1 : a = b) (h2 : p a) : p b :=
      h1 ▸ h2
    ```
    The triangle in the second presentation is a macro built on top of `Eq.subst` and `Eq.symm`, and you can enter it by typing `\t`.
    For more information: [Equality](https://lean-lang.org/theorem_proving_in_lean4/quantifiers_and_equality.html#equality)
    
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `=` in identifiers is `eq`. Subgroup.closureSubgroup.closure.{u_1} {G : Type u_1} [Group G] (k : Set G) : Subgroup GThe `Subgroup` generated by a set.  {Insert.insert.{u, v} {α : outParam (Type u)} {γ : Type v} [self : Insert α γ] : α → γ → γ`insert x xs` inserts the element `x` into the collection `xs`. αα : ↥(CongruenceSubgroup.Gamma 2),Insert.insert.{u, v} {α : outParam (Type u)} {γ : Type v} [self : Insert α γ] : α → γ → γ`insert x xs` inserts the element `x` into the collection `xs`.  ββ : ↥(CongruenceSubgroup.Gamma 2),Insert.insert.{u, v} {α : outParam (Type u)} {γ : Type v} [self : Insert α γ] : α → γ → γ`insert x xs` inserts the element `x` into the collection `xs`.  negInegI : ↥(CongruenceSubgroup.Gamma 2)}Insert.insert.{u, v} {α : outParam (Type u)} {γ : Type v} [self : Insert α γ] : α → γ → γ`insert x xs` inserts the element `x` into the collection `xs`. 
    theorem Γ2_generate :
      Top.top.{u_1} {α : Type u_1} [self : Top α] : αThe top (`⊤`, `\top`) element 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `⊤` in identifiers is `top`. =Eq.{u_1} {α : Sort u_1} : α → α → PropThe equality relation. It has one introduction rule, `Eq.refl`.
    We use `a = b` as notation for `Eq a b`.
    A fundamental property of equality is that it is an equivalence relation.
    ```
    variable (α : Type) (a b c d : α)
    variable (hab : a = b) (hcb : c = b) (hcd : c = d)
    
    example : a = d :=
      Eq.trans (Eq.trans hab (Eq.symm hcb)) hcd
    ```
    Equality is much more than an equivalence relation, however. It has the important property that every assertion
    respects the equivalence, in the sense that we can substitute equal expressions without changing the truth value.
    That is, given `h1 : a = b` and `h2 : p a`, we can construct a proof for `p b` using substitution: `Eq.subst h1 h2`.
    Example:
    ```
    example (α : Type) (a b : α) (p : α → Prop)
            (h1 : a = b) (h2 : p a) : p b :=
      Eq.subst h1 h2
    
    example (α : Type) (a b : α) (p : α → Prop)
        (h1 : a = b) (h2 : p a) : p b :=
      h1 ▸ h2
    ```
    The triangle in the second presentation is a macro built on top of `Eq.subst` and `Eq.symm`, and you can enter it by typing `\t`.
    For more information: [Equality](https://lean-lang.org/theorem_proving_in_lean4/quantifiers_and_equality.html#equality)
    
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `=` in identifiers is `eq`. Subgroup.closureSubgroup.closure.{u_1} {G : Type u_1} [Group G] (k : Set G) : Subgroup GThe `Subgroup` generated by a set.  {Insert.insert.{u, v} {α : outParam (Type u)} {γ : Type v} [self : Insert α γ] : α → γ → γ`insert x xs` inserts the element `x` into the collection `xs`. αα : ↥(CongruenceSubgroup.Gamma 2),Insert.insert.{u, v} {α : outParam (Type u)} {γ : Type v} [self : Insert α γ] : α → γ → γ`insert x xs` inserts the element `x` into the collection `xs`.  ββ : ↥(CongruenceSubgroup.Gamma 2),Insert.insert.{u, v} {α : outParam (Type u)} {γ : Type v} [self : Insert α γ] : α → γ → γ`insert x xs` inserts the element `x` into the collection `xs`.  negInegI : ↥(CongruenceSubgroup.Gamma 2)}Insert.insert.{u, v} {α : outParam (Type u)} {γ : Type v} [self : Insert α γ] : α → γ → γ`insert x xs` inserts the element `x` into the collection `xs`. 
    complete

Let z\in\mathbb{H}, k\in\mathbb{Z}, and \left(\begin{smallmatrix}a&b\\c&d\end{smallmatrix}\right)\in\mathrm{SL}_2(\mathbb{Z}). We omit many of the proofs below when they exist in Mathlib already.

Definition7.7

The automorphy factor of weight k is defined as j_k(z,\left(\begin{smallmatrix}a&b\\c&d\end{smallmatrix}\right)):=(cz+d)^{-k}.

Lean code for Definition7.71 definition
  • def UpperHalfPlane.denom (gGL (Fin 2) ℝ : GLMatrix.GeneralLinearGroup.{u, v} (n : Type u) (R : Type v) [DecidableEq n] [Fintype n] [Semiring R] : Type (max v u)`GL n R` is the group of `n` by `n` `R`-matrices with unit determinant.
    Defined as a subtype of matrices  (FinFin (n : ℕ) : TypeNatural numbers less than some upper bound.
    
    In particular, a `Fin n` is a natural number `i` with the constraint that `i < n`. It is the
    canonical type with `n` elements.
     2) Real : TypeThe type `ℝ` of real numbers constructed as equivalence classes of Cauchy sequences of rational
    numbers. ) (z : Complex : TypeComplex numbers consist of two `Real`s: a real part `re` and an imaginary part `im`. ) : Complex : TypeComplex numbers consist of two `Real`s: a real part `re` and an imaginary part `im`. 
    def UpperHalfPlane.denom (gGL (Fin 2) ℝ : GLMatrix.GeneralLinearGroup.{u, v} (n : Type u) (R : Type v) [DecidableEq n] [Fintype n] [Semiring R] : Type (max v u)`GL n R` is the group of `n` by `n` `R`-matrices with unit determinant.
    Defined as a subtype of matrices  (FinFin (n : ℕ) : TypeNatural numbers less than some upper bound.
    
    In particular, a `Fin n` is a natural number `i` with the constraint that `i < n`. It is the
    canonical type with `n` elements.
     2) Real : TypeThe type `ℝ` of real numbers constructed as equivalence classes of Cauchy sequences of rational
    numbers. )
      (z : Complex : TypeComplex numbers consist of two `Real`s: a real part `re` and an imaginary part `im`. ) : Complex : TypeComplex numbers consist of two `Real`s: a real part `re` and an imaginary part `im`. 
    Denominator of the formula for a fractional linear transformation 
    complete

The automorphy factor satisfies the chain rule j_k(z,\gamma_1\gamma_2)=j_k(z,\gamma_1)\,j_k(\gamma_2z,\gamma_1). Uses Definition 7.7.

Lean code for Lemma7.81 theorem
  • theorem UpperHalfPlane.denom_cocycle (gGL (Fin 2) ℝ hGL (Fin 2) ℝ : GLMatrix.GeneralLinearGroup.{u, v} (n : Type u) (R : Type v) [DecidableEq n] [Fintype n] [Semiring R] : Type (max v u)`GL n R` is the group of `n` by `n` `R`-matrices with unit determinant.
    Defined as a subtype of matrices  (FinFin (n : ℕ) : TypeNatural numbers less than some upper bound.
    
    In particular, a `Fin n` is a natural number `i` with the constraint that `i < n`. It is the
    canonical type with `n` elements.
     2) Real : TypeThe type `ℝ` of real numbers constructed as equivalence classes of Cauchy sequences of rational
    numbers. ) {z : Complex : TypeComplex numbers consist of two `Real`s: a real part `re` and an imaginary part `im`. }
      (hzz.im ≠ 0 : z.imComplex.im (self : ℂ) : ℝThe imaginary part of a complex number.  Ne.{u} {α : Sort u} (a b : α) : Prop`a ≠ b`, or `Ne a b` is defined as `¬ (a = b)` or `a = b → False`,
    and asserts that `a` and `b` are not equal.
    
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `≠` in identifiers is `ne`. 0) :
      UpperHalfPlane.denomUpperHalfPlane.denom (g : GL (Fin 2) ℝ) (z : ℂ) : ℂDenominator of the formula for a fractional linear transformation  (HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`.gGL (Fin 2) ℝ *HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`. hGL (Fin 2) ℝ)HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`. z =Eq.{u_1} {α : Sort u_1} : α → α → PropThe equality relation. It has one introduction rule, `Eq.refl`.
    We use `a = b` as notation for `Eq a b`.
    A fundamental property of equality is that it is an equivalence relation.
    ```
    variable (α : Type) (a b c d : α)
    variable (hab : a = b) (hcb : c = b) (hcd : c = d)
    
    example : a = d :=
      Eq.trans (Eq.trans hab (Eq.symm hcb)) hcd
    ```
    Equality is much more than an equivalence relation, however. It has the important property that every assertion
    respects the equivalence, in the sense that we can substitute equal expressions without changing the truth value.
    That is, given `h1 : a = b` and `h2 : p a`, we can construct a proof for `p b` using substitution: `Eq.subst h1 h2`.
    Example:
    ```
    example (α : Type) (a b : α) (p : α → Prop)
            (h1 : a = b) (h2 : p a) : p b :=
      Eq.subst h1 h2
    
    example (α : Type) (a b : α) (p : α → Prop)
        (h1 : a = b) (h2 : p a) : p b :=
      h1 ▸ h2
    ```
    The triangle in the second presentation is a macro built on top of `Eq.subst` and `Eq.symm`, and you can enter it by typing `\t`.
    For more information: [Equality](https://lean-lang.org/theorem_proving_in_lean4/quantifiers_and_equality.html#equality)
    
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `=` in identifiers is `eq`.
        UpperHalfPlane.denomUpperHalfPlane.denom (g : GL (Fin 2) ℝ) (z : ℂ) : ℂDenominator of the formula for a fractional linear transformation  gGL (Fin 2) ℝ
            (HDiv.hDiv.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HDiv α β γ] : α → β → γ`a / b` computes the result of dividing `a` by `b`.
    The meaning of this notation is type-dependent.
    * For most types like `Nat`, `Int`, `Rat`, `Real`, `a / 0` is defined to be `0`.
    * For `Nat`, `a / b` rounds downwards.
    * For `Int`, `a / b` rounds downwards if `b` is positive or upwards if `b` is negative.
      It is implemented as `Int.ediv`, the unique function satisfying
      `a % b + b * (a / b) = a` and `0 ≤ a % b < natAbs b` for `b ≠ 0`.
      Other rounding conventions are available using the functions
      `Int.fdiv` (floor rounding) and `Int.tdiv` (truncation rounding).
    * For `Float`, `a / 0` follows the IEEE 754 semantics for division,
      usually resulting in `inf` or `nan`. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `/` in identifiers is `div`.UpperHalfPlane.numUpperHalfPlane.num (g : GL (Fin 2) ℝ) (z : ℂ) : ℂNumerator of the formula for a fractional linear transformation  hGL (Fin 2) ℝ z /HDiv.hDiv.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HDiv α β γ] : α → β → γ`a / b` computes the result of dividing `a` by `b`.
    The meaning of this notation is type-dependent.
    * For most types like `Nat`, `Int`, `Rat`, `Real`, `a / 0` is defined to be `0`.
    * For `Nat`, `a / b` rounds downwards.
    * For `Int`, `a / b` rounds downwards if `b` is positive or upwards if `b` is negative.
      It is implemented as `Int.ediv`, the unique function satisfying
      `a % b + b * (a / b) = a` and `0 ≤ a % b < natAbs b` for `b ≠ 0`.
      Other rounding conventions are available using the functions
      `Int.fdiv` (floor rounding) and `Int.tdiv` (truncation rounding).
    * For `Float`, `a / 0` follows the IEEE 754 semantics for division,
      usually resulting in `inf` or `nan`. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `/` in identifiers is `div`. UpperHalfPlane.denomUpperHalfPlane.denom (g : GL (Fin 2) ℝ) (z : ℂ) : ℂDenominator of the formula for a fractional linear transformation  hGL (Fin 2) ℝ z)HDiv.hDiv.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HDiv α β γ] : α → β → γ`a / b` computes the result of dividing `a` by `b`.
    The meaning of this notation is type-dependent.
    * For most types like `Nat`, `Int`, `Rat`, `Real`, `a / 0` is defined to be `0`.
    * For `Nat`, `a / b` rounds downwards.
    * For `Int`, `a / b` rounds downwards if `b` is positive or upwards if `b` is negative.
      It is implemented as `Int.ediv`, the unique function satisfying
      `a % b + b * (a / b) = a` and `0 ≤ a % b < natAbs b` for `b ≠ 0`.
      Other rounding conventions are available using the functions
      `Int.fdiv` (floor rounding) and `Int.tdiv` (truncation rounding).
    * For `Float`, `a / 0` follows the IEEE 754 semantics for division,
      usually resulting in `inf` or `nan`. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `/` in identifiers is `div`. *HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`.
          UpperHalfPlane.denomUpperHalfPlane.denom (g : GL (Fin 2) ℝ) (z : ℂ) : ℂDenominator of the formula for a fractional linear transformation  hGL (Fin 2) ℝ z
    theorem UpperHalfPlane.denom_cocycle
      (gGL (Fin 2) ℝ hGL (Fin 2) ℝ : GLMatrix.GeneralLinearGroup.{u, v} (n : Type u) (R : Type v) [DecidableEq n] [Fintype n] [Semiring R] : Type (max v u)`GL n R` is the group of `n` by `n` `R`-matrices with unit determinant.
    Defined as a subtype of matrices  (FinFin (n : ℕ) : TypeNatural numbers less than some upper bound.
    
    In particular, a `Fin n` is a natural number `i` with the constraint that `i < n`. It is the
    canonical type with `n` elements.
     2) Real : TypeThe type `ℝ` of real numbers constructed as equivalence classes of Cauchy sequences of rational
    numbers. ) {z : Complex : TypeComplex numbers consist of two `Real`s: a real part `re` and an imaginary part `im`. }
      (hzz.im ≠ 0 : z.imComplex.im (self : ℂ) : ℝThe imaginary part of a complex number.  Ne.{u} {α : Sort u} (a b : α) : Prop`a ≠ b`, or `Ne a b` is defined as `¬ (a = b)` or `a = b → False`,
    and asserts that `a` and `b` are not equal.
    
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `≠` in identifiers is `ne`. 0) :
      UpperHalfPlane.denomUpperHalfPlane.denom (g : GL (Fin 2) ℝ) (z : ℂ) : ℂDenominator of the formula for a fractional linear transformation  (HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`.gGL (Fin 2) ℝ *HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`. hGL (Fin 2) ℝ)HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`. z =Eq.{u_1} {α : Sort u_1} : α → α → PropThe equality relation. It has one introduction rule, `Eq.refl`.
    We use `a = b` as notation for `Eq a b`.
    A fundamental property of equality is that it is an equivalence relation.
    ```
    variable (α : Type) (a b c d : α)
    variable (hab : a = b) (hcb : c = b) (hcd : c = d)
    
    example : a = d :=
      Eq.trans (Eq.trans hab (Eq.symm hcb)) hcd
    ```
    Equality is much more than an equivalence relation, however. It has the important property that every assertion
    respects the equivalence, in the sense that we can substitute equal expressions without changing the truth value.
    That is, given `h1 : a = b` and `h2 : p a`, we can construct a proof for `p b` using substitution: `Eq.subst h1 h2`.
    Example:
    ```
    example (α : Type) (a b : α) (p : α → Prop)
            (h1 : a = b) (h2 : p a) : p b :=
      Eq.subst h1 h2
    
    example (α : Type) (a b : α) (p : α → Prop)
        (h1 : a = b) (h2 : p a) : p b :=
      h1 ▸ h2
    ```
    The triangle in the second presentation is a macro built on top of `Eq.subst` and `Eq.symm`, and you can enter it by typing `\t`.
    For more information: [Equality](https://lean-lang.org/theorem_proving_in_lean4/quantifiers_and_equality.html#equality)
    
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `=` in identifiers is `eq`.
        UpperHalfPlane.denomUpperHalfPlane.denom (g : GL (Fin 2) ℝ) (z : ℂ) : ℂDenominator of the formula for a fractional linear transformation  gGL (Fin 2) ℝ
            (HDiv.hDiv.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HDiv α β γ] : α → β → γ`a / b` computes the result of dividing `a` by `b`.
    The meaning of this notation is type-dependent.
    * For most types like `Nat`, `Int`, `Rat`, `Real`, `a / 0` is defined to be `0`.
    * For `Nat`, `a / b` rounds downwards.
    * For `Int`, `a / b` rounds downwards if `b` is positive or upwards if `b` is negative.
      It is implemented as `Int.ediv`, the unique function satisfying
      `a % b + b * (a / b) = a` and `0 ≤ a % b < natAbs b` for `b ≠ 0`.
      Other rounding conventions are available using the functions
      `Int.fdiv` (floor rounding) and `Int.tdiv` (truncation rounding).
    * For `Float`, `a / 0` follows the IEEE 754 semantics for division,
      usually resulting in `inf` or `nan`. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `/` in identifiers is `div`.UpperHalfPlane.numUpperHalfPlane.num (g : GL (Fin 2) ℝ) (z : ℂ) : ℂNumerator of the formula for a fractional linear transformation  hGL (Fin 2) ℝ z /HDiv.hDiv.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HDiv α β γ] : α → β → γ`a / b` computes the result of dividing `a` by `b`.
    The meaning of this notation is type-dependent.
    * For most types like `Nat`, `Int`, `Rat`, `Real`, `a / 0` is defined to be `0`.
    * For `Nat`, `a / b` rounds downwards.
    * For `Int`, `a / b` rounds downwards if `b` is positive or upwards if `b` is negative.
      It is implemented as `Int.ediv`, the unique function satisfying
      `a % b + b * (a / b) = a` and `0 ≤ a % b < natAbs b` for `b ≠ 0`.
      Other rounding conventions are available using the functions
      `Int.fdiv` (floor rounding) and `Int.tdiv` (truncation rounding).
    * For `Float`, `a / 0` follows the IEEE 754 semantics for division,
      usually resulting in `inf` or `nan`. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `/` in identifiers is `div`.
              UpperHalfPlane.denomUpperHalfPlane.denom (g : GL (Fin 2) ℝ) (z : ℂ) : ℂDenominator of the formula for a fractional linear transformation  hGL (Fin 2) ℝ z)HDiv.hDiv.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HDiv α β γ] : α → β → γ`a / b` computes the result of dividing `a` by `b`.
    The meaning of this notation is type-dependent.
    * For most types like `Nat`, `Int`, `Rat`, `Real`, `a / 0` is defined to be `0`.
    * For `Nat`, `a / b` rounds downwards.
    * For `Int`, `a / b` rounds downwards if `b` is positive or upwards if `b` is negative.
      It is implemented as `Int.ediv`, the unique function satisfying
      `a % b + b * (a / b) = a` and `0 ≤ a % b < natAbs b` for `b ≠ 0`.
      Other rounding conventions are available using the functions
      `Int.fdiv` (floor rounding) and `Int.tdiv` (truncation rounding).
    * For `Float`, `a / 0` follows the IEEE 754 semantics for division,
      usually resulting in `inf` or `nan`. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `/` in identifiers is `div`. *HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`.
          UpperHalfPlane.denomUpperHalfPlane.denom (g : GL (Fin 2) ℝ) (z : ℂ) : ℂDenominator of the formula for a fractional linear transformation  hGL (Fin 2) ℝ z
    complete
Proof

Let F be a function on \mathbb{H} and \gamma \in \mathrm{SL}_2(\mathbb{Z}). Then the slash operator acts on F by (F|_k\gamma)(z):=j_k(z,\gamma)\,F(\gamma z). Uses Definition 7.7 and Lemma 7.1.

The chain rule implies F|_k\gamma_1\gamma_2=(F|_k\gamma_1)|_k\gamma_2. Uses Lemma 7.8.

Lean code for Lemma7.101 theorem
  • theorem SlashAction.slash_mul.{u_1, u_2, u_3} {βType u_1 : Type u_1A type universe. `Type ≡ Type 0`, `Type u ≡ Sort (u + 1)`. } {GType u_2 : Type u_2A type universe. `Type ≡ Type 0`, `Type u ≡ Sort (u + 1)`. }
      {αType u_3 : Type u_3A type universe. `Type ≡ Type 0`, `Type u ≡ Sort (u + 1)`. } {inst✝Monoid G : MonoidMonoid.{u} (M : Type u) : Type uA `Monoid` is a `Semigroup` with an element `1` such that `1 * a = a * 1 = a`.  GType u_2} {inst✝¹AddMonoid α : AddMonoidAddMonoid.{u} (M : Type u) : Type uAn `AddMonoid` is an `AddSemigroup` with an element `0` such that `0 + a = a + 0 = a`.  αType u_3}
      [selfSlashAction β G α : SlashActionSlashAction.{u_1, u_2, u_3} (β : Type u_1) (G : Type u_2) (α : Type u_3) [Monoid G] [AddMonoid α] :
      Type (max (max u_1 u_2) u_3)A general version of the slash action of the space of modular forms. This is the same data as a
    family of `DistribMulAction Gᵒᵖ α` indexed by `k`.  βType u_1 GType u_2 αType u_3] (kβ : βType u_1) (gG hG : GType u_2) (aα : αType u_3) :
      SlashAction.mapSlashAction.map.{u_1, u_2, u_3} {β : Type u_1} {G : Type u_2} {α : Type u_3} {inst✝ : Monoid G} {inst✝¹ : AddMonoid α}
      [self : SlashAction β G α] : β → G → α → α kβ (HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`.gG *HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`. hG)HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`. aα =Eq.{u_1} {α : Sort u_1} : α → α → PropThe equality relation. It has one introduction rule, `Eq.refl`.
    We use `a = b` as notation for `Eq a b`.
    A fundamental property of equality is that it is an equivalence relation.
    ```
    variable (α : Type) (a b c d : α)
    variable (hab : a = b) (hcb : c = b) (hcd : c = d)
    
    example : a = d :=
      Eq.trans (Eq.trans hab (Eq.symm hcb)) hcd
    ```
    Equality is much more than an equivalence relation, however. It has the important property that every assertion
    respects the equivalence, in the sense that we can substitute equal expressions without changing the truth value.
    That is, given `h1 : a = b` and `h2 : p a`, we can construct a proof for `p b` using substitution: `Eq.subst h1 h2`.
    Example:
    ```
    example (α : Type) (a b : α) (p : α → Prop)
            (h1 : a = b) (h2 : p a) : p b :=
      Eq.subst h1 h2
    
    example (α : Type) (a b : α) (p : α → Prop)
        (h1 : a = b) (h2 : p a) : p b :=
      h1 ▸ h2
    ```
    The triangle in the second presentation is a macro built on top of `Eq.subst` and `Eq.symm`, and you can enter it by typing `\t`.
    For more information: [Equality](https://lean-lang.org/theorem_proving_in_lean4/quantifiers_and_equality.html#equality)
    
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `=` in identifiers is `eq`.
        SlashAction.mapSlashAction.map.{u_1, u_2, u_3} {β : Type u_1} {G : Type u_2} {α : Type u_3} {inst✝ : Monoid G} {inst✝¹ : AddMonoid α}
      [self : SlashAction β G α] : β → G → α → α kβ hG (SlashAction.mapSlashAction.map.{u_1, u_2, u_3} {β : Type u_1} {G : Type u_2} {α : Type u_3} {inst✝ : Monoid G} {inst✝¹ : AddMonoid α}
      [self : SlashAction β G α] : β → G → α → α kβ gG aα)
    theorem SlashAction.slash_mul.{u_1, u_2, u_3}
      {βType u_1 : Type u_1A type universe. `Type ≡ Type 0`, `Type u ≡ Sort (u + 1)`. } {GType u_2 : Type u_2A type universe. `Type ≡ Type 0`, `Type u ≡ Sort (u + 1)`. }
      {αType u_3 : Type u_3A type universe. `Type ≡ Type 0`, `Type u ≡ Sort (u + 1)`. } {inst✝Monoid G : MonoidMonoid.{u} (M : Type u) : Type uA `Monoid` is a `Semigroup` with an element `1` such that `1 * a = a * 1 = a`.  GType u_2}
      {inst✝¹AddMonoid α : AddMonoidAddMonoid.{u} (M : Type u) : Type uAn `AddMonoid` is an `AddSemigroup` with an element `0` such that `0 + a = a + 0 = a`.  αType u_3}
      [selfSlashAction β G α : SlashActionSlashAction.{u_1, u_2, u_3} (β : Type u_1) (G : Type u_2) (α : Type u_3) [Monoid G] [AddMonoid α] :
      Type (max (max u_1 u_2) u_3)A general version of the slash action of the space of modular forms. This is the same data as a
    family of `DistribMulAction Gᵒᵖ α` indexed by `k`.  βType u_1 GType u_2 αType u_3] (kβ : βType u_1)
      (gG hG : GType u_2) (aα : αType u_3) :
      SlashAction.mapSlashAction.map.{u_1, u_2, u_3} {β : Type u_1} {G : Type u_2} {α : Type u_3} {inst✝ : Monoid G} {inst✝¹ : AddMonoid α}
      [self : SlashAction β G α] : β → G → α → α kβ (HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`.gG *HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`. hG)HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`. aα =Eq.{u_1} {α : Sort u_1} : α → α → PropThe equality relation. It has one introduction rule, `Eq.refl`.
    We use `a = b` as notation for `Eq a b`.
    A fundamental property of equality is that it is an equivalence relation.
    ```
    variable (α : Type) (a b c d : α)
    variable (hab : a = b) (hcb : c = b) (hcd : c = d)
    
    example : a = d :=
      Eq.trans (Eq.trans hab (Eq.symm hcb)) hcd
    ```
    Equality is much more than an equivalence relation, however. It has the important property that every assertion
    respects the equivalence, in the sense that we can substitute equal expressions without changing the truth value.
    That is, given `h1 : a = b` and `h2 : p a`, we can construct a proof for `p b` using substitution: `Eq.subst h1 h2`.
    Example:
    ```
    example (α : Type) (a b : α) (p : α → Prop)
            (h1 : a = b) (h2 : p a) : p b :=
      Eq.subst h1 h2
    
    example (α : Type) (a b : α) (p : α → Prop)
        (h1 : a = b) (h2 : p a) : p b :=
      h1 ▸ h2
    ```
    The triangle in the second presentation is a macro built on top of `Eq.subst` and `Eq.symm`, and you can enter it by typing `\t`.
    For more information: [Equality](https://lean-lang.org/theorem_proving_in_lean4/quantifiers_and_equality.html#equality)
    
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `=` in identifiers is `eq`.
        SlashAction.mapSlashAction.map.{u_1, u_2, u_3} {β : Type u_1} {G : Type u_2} {α : Type u_3} {inst✝ : Monoid G} {inst✝¹ : AddMonoid α}
      [self : SlashAction β G α] : β → G → α → α kβ hG
          (SlashAction.mapSlashAction.map.{u_1, u_2, u_3} {β : Type u_1} {G : Type u_2} {α : Type u_3} {inst✝ : Monoid G} {inst✝¹ : AddMonoid α}
      [self : SlashAction β G α] : β → G → α → α kβ gG aα)
    complete
Proof
Lean code for Lemma7.111 theorem
  • theorem modular_slash_negI_of_even (fUpperHalfPlane → ℂ : UpperHalfPlaneUpperHalfPlane : TypeThe open upper half plane, denoted as `ℍ` within the `UpperHalfPlane` namespace   Complex : TypeComplex numbers consist of two `Real`s: a real part `re` and an imaginary part `im`. ) (k : Int : TypeThe integers.
    
    This type is special-cased by the compiler and overridden with an efficient implementation. The
    runtime has a special representation for `Int` that stores “small” signed numbers directly, while
    larger numbers use a fast arbitrary-precision arithmetic library (usually
    [GMP](https://gmplib.org/)). A “small number” is an integer that can be encoded with one fewer bits
    than the platform's pointer size (i.e. 63 bits on 64-bit architectures and 31 bits on 32-bit
    architectures).
    )
      (hkEven k : EvenEven.{u_2} {α : Type u_2} [Add α] (a : α) : PropAn element `a` of a type `α` with addition satisfies `Even a` if `a = r + r`,
    for some `r : α`.  k) : SlashAction.mapSlashAction.map.{u_1, u_2, u_3} {β : Type u_1} {G : Type u_2} {α : Type u_3} {inst✝ : Monoid G} {inst✝¹ : AddMonoid α}
      [self : SlashAction β G α] : β → G → α → α k (↑negInegI : ↥(CongruenceSubgroup.Gamma 2)) fUpperHalfPlane → ℂ =Eq.{u_1} {α : Sort u_1} : α → α → PropThe equality relation. It has one introduction rule, `Eq.refl`.
    We use `a = b` as notation for `Eq a b`.
    A fundamental property of equality is that it is an equivalence relation.
    ```
    variable (α : Type) (a b c d : α)
    variable (hab : a = b) (hcb : c = b) (hcd : c = d)
    
    example : a = d :=
      Eq.trans (Eq.trans hab (Eq.symm hcb)) hcd
    ```
    Equality is much more than an equivalence relation, however. It has the important property that every assertion
    respects the equivalence, in the sense that we can substitute equal expressions without changing the truth value.
    That is, given `h1 : a = b` and `h2 : p a`, we can construct a proof for `p b` using substitution: `Eq.subst h1 h2`.
    Example:
    ```
    example (α : Type) (a b : α) (p : α → Prop)
            (h1 : a = b) (h2 : p a) : p b :=
      Eq.subst h1 h2
    
    example (α : Type) (a b : α) (p : α → Prop)
        (h1 : a = b) (h2 : p a) : p b :=
      h1 ▸ h2
    ```
    The triangle in the second presentation is a macro built on top of `Eq.subst` and `Eq.symm`, and you can enter it by typing `\t`.
    For more information: [Equality](https://lean-lang.org/theorem_proving_in_lean4/quantifiers_and_equality.html#equality)
    
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `=` in identifiers is `eq`. fUpperHalfPlane → ℂ
    theorem modular_slash_negI_of_even
      (fUpperHalfPlane → ℂ : UpperHalfPlaneUpperHalfPlane : TypeThe open upper half plane, denoted as `ℍ` within the `UpperHalfPlane` namespace   Complex : TypeComplex numbers consist of two `Real`s: a real part `re` and an imaginary part `im`. ) (k : Int : TypeThe integers.
    
    This type is special-cased by the compiler and overridden with an efficient implementation. The
    runtime has a special representation for `Int` that stores “small” signed numbers directly, while
    larger numbers use a fast arbitrary-precision arithmetic library (usually
    [GMP](https://gmplib.org/)). A “small number” is an integer that can be encoded with one fewer bits
    than the platform's pointer size (i.e. 63 bits on 64-bit architectures and 31 bits on 32-bit
    architectures).
    )
      (hkEven k : EvenEven.{u_2} {α : Type u_2} [Add α] (a : α) : PropAn element `a` of a type `α` with addition satisfies `Even a` if `a = r + r`,
    for some `r : α`.  k) :
      SlashAction.mapSlashAction.map.{u_1, u_2, u_3} {β : Type u_1} {G : Type u_2} {α : Type u_3} {inst✝ : Monoid G} {inst✝¹ : AddMonoid α}
      [self : SlashAction β G α] : β → G → α → α k (↑negInegI : ↥(CongruenceSubgroup.Gamma 2)) fUpperHalfPlane → ℂ =Eq.{u_1} {α : Sort u_1} : α → α → PropThe equality relation. It has one introduction rule, `Eq.refl`.
    We use `a = b` as notation for `Eq a b`.
    A fundamental property of equality is that it is an equivalence relation.
    ```
    variable (α : Type) (a b c d : α)
    variable (hab : a = b) (hcb : c = b) (hcd : c = d)
    
    example : a = d :=
      Eq.trans (Eq.trans hab (Eq.symm hcb)) hcd
    ```
    Equality is much more than an equivalence relation, however. It has the important property that every assertion
    respects the equivalence, in the sense that we can substitute equal expressions without changing the truth value.
    That is, given `h1 : a = b` and `h2 : p a`, we can construct a proof for `p b` using substitution: `Eq.subst h1 h2`.
    Example:
    ```
    example (α : Type) (a b : α) (p : α → Prop)
            (h1 : a = b) (h2 : p a) : p b :=
      Eq.subst h1 h2
    
    example (α : Type) (a b : α) (p : α → Prop)
        (h1 : a = b) (h2 : p a) : p b :=
      h1 ▸ h2
    ```
    The triangle in the second presentation is a macro built on top of `Eq.subst` and `Eq.symm`, and you can enter it by typing `\t`.
    For more information: [Equality](https://lean-lang.org/theorem_proving_in_lean4/quantifiers_and_equality.html#equality)
    
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `=` in identifiers is `eq`. fUpperHalfPlane → ℂ
    complete
Proof

Follows from the definition of the slash operator: (F|_{k}(-I))(z) = (-1)^{-k}F((-I)z) = F(z).

Let \Gamma be a subgroup of \mathrm{SL}_2(\mathbb{Z}). A modular form of level \Gamma and weight k \in \mathbb{Z} is a function f : \mathbb{H} \to \mathbb{C} such that:

  1. for all \gamma \in \Gamma, we have f\mid_k \gamma = f

  2. f is holomorphic on \mathbb{H}

  3. for all \gamma \in \mathrm{SL}_2(\mathbb{Z}), there exist A, B \in \mathbb{R} such that for all z \in \mathbb{H} with A \le \mathrm{Im}(z), we have |(f \mid_k \gamma) (z) |\le B. This defines a complex vector space denoted by M_k(\Gamma). Uses Definition 7.3.

Lean code for Definition7.121 definition
  • abbrev BlueprintDocAliases.ModularForm (ΓSubgroup (GL (Fin 2) ℝ) : SubgroupSubgroup.{u_3} (G : Type u_3) [Group G] : Type u_3A subgroup of a group `G` is a subset containing 1, closed under multiplication
    and closed under multiplicative inverse.  (GLMatrix.GeneralLinearGroup.{u, v} (n : Type u) (R : Type v) [DecidableEq n] [Fintype n] [Semiring R] : Type (max v u)`GL n R` is the group of `n` by `n` `R`-matrices with unit determinant.
    Defined as a subtype of matrices  (FinFin (n : ℕ) : TypeNatural numbers less than some upper bound.
    
    In particular, a `Fin n` is a natural number `i` with the constraint that `i < n`. It is the
    canonical type with `n` elements.
     2) Real : TypeThe type `ℝ` of real numbers constructed as equivalence classes of Cauchy sequences of rational
    numbers. )) (k : Int : TypeThe integers.
    
    This type is special-cased by the compiler and overridden with an efficient implementation. The
    runtime has a special representation for `Int` that stores “small” signed numbers directly, while
    larger numbers use a fast arbitrary-precision arithmetic library (usually
    [GMP](https://gmplib.org/)). A “small number” is an integer that can be encoded with one fewer bits
    than the platform's pointer size (i.e. 63 bits on 64-bit architectures and 31 bits on 32-bit
    architectures).
    ) :
      TypeA type universe. `Type ≡ Type 0`, `Type u ≡ Sort (u + 1)`. 
    abbrev BlueprintDocAliases.ModularForm
      (ΓSubgroup (GL (Fin 2) ℝ) : SubgroupSubgroup.{u_3} (G : Type u_3) [Group G] : Type u_3A subgroup of a group `G` is a subset containing 1, closed under multiplication
    and closed under multiplicative inverse.  (GLMatrix.GeneralLinearGroup.{u, v} (n : Type u) (R : Type v) [DecidableEq n] [Fintype n] [Semiring R] : Type (max v u)`GL n R` is the group of `n` by `n` `R`-matrices with unit determinant.
    Defined as a subtype of matrices  (FinFin (n : ℕ) : TypeNatural numbers less than some upper bound.
    
    In particular, a `Fin n` is a natural number `i` with the constraint that `i < n`. It is the
    canonical type with `n` elements.
     2) Real : TypeThe type `ℝ` of real numbers constructed as equivalence classes of Cauchy sequences of rational
    numbers. )) (k : Int : TypeThe integers.
    
    This type is special-cased by the compiler and overridden with an efficient implementation. The
    runtime has a special representation for `Int` that stores “small” signed numbers directly, while
    larger numbers use a fast arbitrary-precision arithmetic library (usually
    [GMP](https://gmplib.org/)). A “small number” is an integer that can be encoded with one fewer bits
    than the platform's pointer size (i.e. 63 bits on 64-bit architectures and 31 bits on 32-bit
    architectures).
    ) :
      TypeA type universe. `Type ≡ Type 0`, `Type u ≡ Sort (u + 1)`. 
    Modular forms of a given level and weight. 
    complete

For an even integer k\geq 4 define the weight-k Eisenstein series by E_k(z):=\frac{1}{2}\sum_{(c,d)\in\Z^2, (c,d)=1}(cz+d)^{-k}.

Lean code for Definition7.131 definition
  • def ModularForm.eisensteinSeries_MF {k : Int : TypeThe integers.
    
    This type is special-cased by the compiler and overridden with an efficient implementation. The
    runtime has a special representation for `Int` that stores “small” signed numbers directly, while
    larger numbers use a fast arbitrary-precision arithmetic library (usually
    [GMP](https://gmplib.org/)). A “small number” is an integer that can be encoded with one fewer bits
    than the platform's pointer size (i.e. 63 bits on 64-bit architectures and 31 bits on 32-bit
    architectures).
    } {N : Nat : TypeThe natural numbers, starting at zero.
    
    This type is special-cased by both the kernel and the compiler, and overridden with an efficient
    implementation. Both use a fast arbitrary-precision arithmetic library (usually
    [GMP](https://gmplib.org/)); at runtime, `Nat` values that are sufficiently small are unboxed.
    } [NeZeroNeZero.{u_1} {R : Type u_1} [Zero R] (n : R) : PropA type-class version of `n ≠ 0`.   N] (hk3 ≤ k : 3 LE.le.{u} {α : Type u} [self : LE α] : α → α → PropThe less-equal relation: `x ≤ y` 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `≤` in identifiers is `le`.
    
     * The recommended spelling of `<=` in identifiers is `le` (prefer `≤` over `<=`). k)
      (aFin 2 → ZMod N : FinFin (n : ℕ) : TypeNatural numbers less than some upper bound.
    
    In particular, a `Fin n` is a natural number `i` with the constraint that `i < n`. It is the
    canonical type with `n` elements.
     2  ZModZMod : ℕ → TypeThe integers modulo `n : ℕ`.  N) :
      ModularFormModularForm (Γ : Subgroup (GL (Fin 2) ℝ)) (k : ℤ) : TypeThese are `SlashInvariantForm`'s that are holomorphic and bounded at infinity. 
        (Subgroup.mapSubgroup.map.{u_1, u_5} {G : Type u_1} [Group G] {N : Type u_5} [Group N] (f : G →* N) (H : Subgroup G) : Subgroup NThe image of a subgroup along a monoid homomorphism is a subgroup.  (Matrix.SpecialLinearGroup.mapGLMatrix.SpecialLinearGroup.mapGL.{u, v, u_1} {n : Type u} [DecidableEq n] [Fintype n] {R : Type v} [CommRing R]
      (S : Type u_1) [CommRing S] [Algebra R S] : Matrix.SpecialLinearGroup n R →* GL n S`mapGL` is the map from the special linear group over `R` to the general linear group over
    `S`, where `S` is an `R`-algebra.  Real : TypeThe type `ℝ` of real numbers constructed as equivalence classes of Cauchy sequences of rational
    numbers. )
          (CongruenceSubgroup.GammaCongruenceSubgroup.Gamma (N : ℕ) : Subgroup (Matrix.SpecialLinearGroup (Fin 2) ℤ)The full level `N` congruence subgroup of `SL(2, ℤ)` of matrices that reduce to the identity
    modulo `N`.  N))
        k
    def ModularForm.eisensteinSeries_MF {k : Int : TypeThe integers.
    
    This type is special-cased by the compiler and overridden with an efficient implementation. The
    runtime has a special representation for `Int` that stores “small” signed numbers directly, while
    larger numbers use a fast arbitrary-precision arithmetic library (usually
    [GMP](https://gmplib.org/)). A “small number” is an integer that can be encoded with one fewer bits
    than the platform's pointer size (i.e. 63 bits on 64-bit architectures and 31 bits on 32-bit
    architectures).
    }
      {N : Nat : TypeThe natural numbers, starting at zero.
    
    This type is special-cased by both the kernel and the compiler, and overridden with an efficient
    implementation. Both use a fast arbitrary-precision arithmetic library (usually
    [GMP](https://gmplib.org/)); at runtime, `Nat` values that are sufficiently small are unboxed.
    } [NeZeroNeZero.{u_1} {R : Type u_1} [Zero R] (n : R) : PropA type-class version of `n ≠ 0`.   N] (hk3 ≤ k : 3 LE.le.{u} {α : Type u} [self : LE α] : α → α → PropThe less-equal relation: `x ≤ y` 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `≤` in identifiers is `le`.
    
     * The recommended spelling of `<=` in identifiers is `le` (prefer `≤` over `<=`). k)
      (aFin 2 → ZMod N : FinFin (n : ℕ) : TypeNatural numbers less than some upper bound.
    
    In particular, a `Fin n` is a natural number `i` with the constraint that `i < n`. It is the
    canonical type with `n` elements.
     2  ZModZMod : ℕ → TypeThe integers modulo `n : ℕ`.  N) :
      ModularFormModularForm (Γ : Subgroup (GL (Fin 2) ℝ)) (k : ℤ) : TypeThese are `SlashInvariantForm`'s that are holomorphic and bounded at infinity. 
        (Subgroup.mapSubgroup.map.{u_1, u_5} {G : Type u_1} [Group G] {N : Type u_5} [Group N] (f : G →* N) (H : Subgroup G) : Subgroup NThe image of a subgroup along a monoid homomorphism is a subgroup. 
          (Matrix.SpecialLinearGroup.mapGLMatrix.SpecialLinearGroup.mapGL.{u, v, u_1} {n : Type u} [DecidableEq n] [Fintype n] {R : Type v} [CommRing R]
      (S : Type u_1) [CommRing S] [Algebra R S] : Matrix.SpecialLinearGroup n R →* GL n S`mapGL` is the map from the special linear group over `R` to the general linear group over
    `S`, where `S` is an `R`-algebra.  Real : TypeThe type `ℝ` of real numbers constructed as equivalence classes of Cauchy sequences of rational
    numbers. )
          (CongruenceSubgroup.GammaCongruenceSubgroup.Gamma (N : ℕ) : Subgroup (Matrix.SpecialLinearGroup (Fin 2) ℤ)The full level `N` congruence subgroup of `SL(2, ℤ)` of matrices that reduce to the identity
    modulo `N`.  N))
        k
    **Alias** of `ModularForm.eisensteinSeriesMF`.
    
    ---
    
    This defines Eisenstein series as modular forms of weight `k`, level `Γ(N)` and congruence
    condition given by `a : Fin 2 → ZMod N`. 
    complete

For all k, E_k\in M_k(\Gamma_1). Especially, we have E_k \left(-\frac{1}{z}\right) = z^k E_k(z). Uses Definition 7.12 and Definition 7.13.

Lean code for Lemma7.141 definition
  • def EisensteinSeries.eisensteinSeries_SIF {N : Nat : TypeThe natural numbers, starting at zero.
    
    This type is special-cased by both the kernel and the compiler, and overridden with an efficient
    implementation. Both use a fast arbitrary-precision arithmetic library (usually
    [GMP](https://gmplib.org/)); at runtime, `Nat` values that are sufficiently small are unboxed.
    } (aFin 2 → ZMod N : FinFin (n : ℕ) : TypeNatural numbers less than some upper bound.
    
    In particular, a `Fin n` is a natural number `i` with the constraint that `i < n`. It is the
    canonical type with `n` elements.
     2  ZModZMod : ℕ → TypeThe integers modulo `n : ℕ`.  N)
      (k : Int : TypeThe integers.
    
    This type is special-cased by the compiler and overridden with an efficient implementation. The
    runtime has a special representation for `Int` that stores “small” signed numbers directly, while
    larger numbers use a fast arbitrary-precision arithmetic library (usually
    [GMP](https://gmplib.org/)). A “small number” is an integer that can be encoded with one fewer bits
    than the platform's pointer size (i.e. 63 bits on 64-bit architectures and 31 bits on 32-bit
    architectures).
    ) :
      SlashInvariantFormSlashInvariantForm (Γ : outParam (Subgroup (GL (Fin 2) ℝ))) (k : outParam ℤ) : TypeFunctions `ℍ → ℂ` that are invariant under the `SlashAction`. 
        (Subgroup.mapSubgroup.map.{u_1, u_5} {G : Type u_1} [Group G] {N : Type u_5} [Group N] (f : G →* N) (H : Subgroup G) : Subgroup NThe image of a subgroup along a monoid homomorphism is a subgroup.  (Matrix.SpecialLinearGroup.mapGLMatrix.SpecialLinearGroup.mapGL.{u, v, u_1} {n : Type u} [DecidableEq n] [Fintype n] {R : Type v} [CommRing R]
      (S : Type u_1) [CommRing S] [Algebra R S] : Matrix.SpecialLinearGroup n R →* GL n S`mapGL` is the map from the special linear group over `R` to the general linear group over
    `S`, where `S` is an `R`-algebra.  Real : TypeThe type `ℝ` of real numbers constructed as equivalence classes of Cauchy sequences of rational
    numbers. )
          (CongruenceSubgroup.GammaCongruenceSubgroup.Gamma (N : ℕ) : Subgroup (Matrix.SpecialLinearGroup (Fin 2) ℤ)The full level `N` congruence subgroup of `SL(2, ℤ)` of matrices that reduce to the identity
    modulo `N`.  N))
        k
    def EisensteinSeries.eisensteinSeries_SIF
      {N : Nat : TypeThe natural numbers, starting at zero.
    
    This type is special-cased by both the kernel and the compiler, and overridden with an efficient
    implementation. Both use a fast arbitrary-precision arithmetic library (usually
    [GMP](https://gmplib.org/)); at runtime, `Nat` values that are sufficiently small are unboxed.
    } (aFin 2 → ZMod N : FinFin (n : ℕ) : TypeNatural numbers less than some upper bound.
    
    In particular, a `Fin n` is a natural number `i` with the constraint that `i < n`. It is the
    canonical type with `n` elements.
     2  ZModZMod : ℕ → TypeThe integers modulo `n : ℕ`.  N) (k : Int : TypeThe integers.
    
    This type is special-cased by the compiler and overridden with an efficient implementation. The
    runtime has a special representation for `Int` that stores “small” signed numbers directly, while
    larger numbers use a fast arbitrary-precision arithmetic library (usually
    [GMP](https://gmplib.org/)). A “small number” is an integer that can be encoded with one fewer bits
    than the platform's pointer size (i.e. 63 bits on 64-bit architectures and 31 bits on 32-bit
    architectures).
    ) :
      SlashInvariantFormSlashInvariantForm (Γ : outParam (Subgroup (GL (Fin 2) ℝ))) (k : outParam ℤ) : TypeFunctions `ℍ → ℂ` that are invariant under the `SlashAction`. 
        (Subgroup.mapSubgroup.map.{u_1, u_5} {G : Type u_1} [Group G] {N : Type u_5} [Group N] (f : G →* N) (H : Subgroup G) : Subgroup NThe image of a subgroup along a monoid homomorphism is a subgroup. 
          (Matrix.SpecialLinearGroup.mapGLMatrix.SpecialLinearGroup.mapGL.{u, v, u_1} {n : Type u} [DecidableEq n] [Fintype n] {R : Type v} [CommRing R]
      (S : Type u_1) [CommRing S] [Algebra R S] : Matrix.SpecialLinearGroup n R →* GL n S`mapGL` is the map from the special linear group over `R` to the general linear group over
    `S`, where `S` is an `R`-algebra.  Real : TypeThe type `ℝ` of real numbers constructed as equivalence classes of Cauchy sequences of rational
    numbers. )
          (CongruenceSubgroup.GammaCongruenceSubgroup.Gamma (N : ℕ) : Subgroup (Matrix.SpecialLinearGroup (Fin 2) ℤ)The full level `N` congruence subgroup of `SL(2, ℤ)` of matrices that reduce to the identity
    modulo `N`.  N))
        k
    **Alias** of `EisensteinSeries.eisensteinSeriesSIF`.
    
    ---
    
    The `SlashInvariantForm` defined by an Eisenstein series of weight `k : ℤ`, level `Γ(N)`,
    and congruence condition given by `a : Fin 2 → ZMod N`. 
    complete
Proof

This follows from the fact that the sum converges absolutely. Applying the slash operator with \gamma = \left(\begin{smallmatrix} 0 & -1 \\ 1 & 0 \end{smallmatrix}\right) gives eqn:Ek-trans-S.

Let \Gamma be a finite-index subgroup of \mathrm{SL}_2(\mathbb{Z}) and let f \in \mathcal{M}_k(\Gamma) be a modular form of weight k. Then the Fourier coefficients a_n(f) have polynomial growth, i.e. |a_n(f)| = O(n^k).

Proof

Note that the assumption on polynomial growth holds when f is a holomorphic modular form, where the proof can be found in Serre (1973) for the case of level-one modular forms. This has been done in Lean 4 by David Loeffler.

The Eisenstein series possesses the Fourier expansion E_k(z)=1+\frac{2}{\zeta(1-k)}\sum_{n=1}^\infty \sigma_{k-1}(n)\,e^{2\pi i z}, where \sigma_{k-1}(n)=\sum_{d|n} d^{k-1}. In particular, E_4(z)= 1+240\sum_{n=1}^\infty \sigma_3(n)\,e^{2\pi i n z} E_6(z)= 1-504\sum_{n=1}^\infty \sigma_5(n)\,e^{2\pi i n z}. Uses Definition 7.13.

Lean code for Lemma7.161 theorem
  • theorem E_k_q_expansion (k : Nat : TypeThe natural numbers, starting at zero.
    
    This type is special-cased by both the kernel and the compiler, and overridden with an efficient
    implementation. Both use a fast arbitrary-precision arithmetic library (usually
    [GMP](https://gmplib.org/)); at runtime, `Nat` values that are sufficiently small are unboxed.
    ) (hk3 ≤ ↑k : 3 LE.le.{u} {α : Type u} [self : LE α] : α → α → PropThe less-equal relation: `x ≤ y` 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `≤` in identifiers is `le`.
    
     * The recommended spelling of `<=` in identifiers is `le` (prefer `≤` over `<=`). k) (hk2Even k : EvenEven.{u_2} {α : Type u_2} [Add α] (a : α) : PropAn element `a` of a type `α` with addition satisfies `Even a` if `a = r + r`,
    for some `r : α`.  k)
      (zUpperHalfPlane : UpperHalfPlaneUpperHalfPlane : TypeThe open upper half plane, denoted as `ℍ` within the `UpperHalfPlane` namespace ) :
      (EE (k : ℤ) (hk : 3 ≤ k) : ModularForm (Subgroup.map (Matrix.SpecialLinearGroup.mapGL ℝ) (CongruenceSubgroup.Gamma 1)) k (↑k) hk3 ≤ ↑k) zUpperHalfPlane =Eq.{u_1} {α : Sort u_1} : α → α → PropThe equality relation. It has one introduction rule, `Eq.refl`.
    We use `a = b` as notation for `Eq a b`.
    A fundamental property of equality is that it is an equivalence relation.
    ```
    variable (α : Type) (a b c d : α)
    variable (hab : a = b) (hcb : c = b) (hcd : c = d)
    
    example : a = d :=
      Eq.trans (Eq.trans hab (Eq.symm hcb)) hcd
    ```
    Equality is much more than an equivalence relation, however. It has the important property that every assertion
    respects the equivalence, in the sense that we can substitute equal expressions without changing the truth value.
    That is, given `h1 : a = b` and `h2 : p a`, we can construct a proof for `p b` using substitution: `Eq.subst h1 h2`.
    Example:
    ```
    example (α : Type) (a b : α) (p : α → Prop)
            (h1 : a = b) (h2 : p a) : p b :=
      Eq.subst h1 h2
    
    example (α : Type) (a b : α) (p : α → Prop)
        (h1 : a = b) (h2 : p a) : p b :=
      h1 ▸ h2
    ```
    The triangle in the second presentation is a macro built on top of `Eq.subst` and `Eq.symm`, and you can enter it by typing `\t`.
    For more information: [Equality](https://lean-lang.org/theorem_proving_in_lean4/quantifiers_and_equality.html#equality)
    
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `=` in identifiers is `eq`.
        1 +HAdd.hAdd.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HAdd α β γ] : α → β → γ`a + b` computes the sum of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `+` in identifiers is `add`.
          1 /HDiv.hDiv.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HDiv α β γ] : α → β → γ`a / b` computes the result of dividing `a` by `b`.
    The meaning of this notation is type-dependent.
    * For most types like `Nat`, `Int`, `Rat`, `Real`, `a / 0` is defined to be `0`.
    * For `Nat`, `a / b` rounds downwards.
    * For `Int`, `a / b` rounds downwards if `b` is positive or upwards if `b` is negative.
      It is implemented as `Int.ediv`, the unique function satisfying
      `a % b + b * (a / b) = a` and `0 ≤ a % b < natAbs b` for `b ≠ 0`.
      Other rounding conventions are available using the functions
      `Int.fdiv` (floor rounding) and `Int.tdiv` (truncation rounding).
    * For `Float`, `a / 0` follows the IEEE 754 semantics for division,
      usually resulting in `inf` or `nan`. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `/` in identifiers is `div`. riemannZetariemannZeta (a : ℂ) : ℂThe Riemann zeta function `ζ(s)`.  k *HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`.
              (HDiv.hDiv.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HDiv α β γ] : α → β → γ`a / b` computes the result of dividing `a` by `b`.
    The meaning of this notation is type-dependent.
    * For most types like `Nat`, `Int`, `Rat`, `Real`, `a / 0` is defined to be `0`.
    * For `Nat`, `a / b` rounds downwards.
    * For `Int`, `a / b` rounds downwards if `b` is positive or upwards if `b` is negative.
      It is implemented as `Int.ediv`, the unique function satisfying
      `a % b + b * (a / b) = a` and `0 ≤ a % b < natAbs b` for `b ≠ 0`.
      Other rounding conventions are available using the functions
      `Int.fdiv` (floor rounding) and `Int.tdiv` (truncation rounding).
    * For `Float`, `a / 0` follows the IEEE 754 semantics for division,
      usually resulting in `inf` or `nan`. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `/` in identifiers is `div`.(HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`.-2 *HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`. Real.piReal.pi : ℝThe number π = 3.14159265... Defined here using choice as twice a zero of cos in [1,2],
    from which one can derive all its properties. For explicit bounds on π,
    see `Mathlib/Analysis/Real/Pi/Bounds.lean`.
    
    Denoted `π`, once the `Real` namespace is opened.  *HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`. Complex.IComplex.I : ℂThe imaginary unit. )HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`. ^HPow.hPow.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HPow α β γ] : α → β → γ`a ^ b` computes `a` to the power of `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `^` in identifiers is `pow`. k /HDiv.hDiv.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HDiv α β γ] : α → β → γ`a / b` computes the result of dividing `a` by `b`.
    The meaning of this notation is type-dependent.
    * For most types like `Nat`, `Int`, `Rat`, `Real`, `a / 0` is defined to be `0`.
    * For `Nat`, `a / b` rounds downwards.
    * For `Int`, `a / b` rounds downwards if `b` is positive or upwards if `b` is negative.
      It is implemented as `Int.ediv`, the unique function satisfying
      `a % b + b * (a / b) = a` and `0 ≤ a % b < natAbs b` for `b ≠ 0`.
      Other rounding conventions are available using the functions
      `Int.fdiv` (floor rounding) and `Int.tdiv` (truncation rounding).
    * For `Float`, `a / 0` follows the IEEE 754 semantics for division,
      usually resulting in `inf` or `nan`. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `/` in identifiers is `div`. (HSub.hSub.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HSub α β γ] : α → β → γ`a - b` computes the difference of `a` and `b`.
    The meaning of this notation is type-dependent.
    * For natural numbers, this operator saturates at 0: `a - b = 0` when `a ≤ b`. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `-` in identifiers is `sub` (when used as a binary operator).k -HSub.hSub.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HSub α β γ] : α → β → γ`a - b` computes the difference of `a` and `b`.
    The meaning of this notation is type-dependent.
    * For natural numbers, this operator saturates at 0: `a - b = 0` when `a ≤ b`. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `-` in identifiers is `sub` (when used as a binary operator). 1)HSub.hSub.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HSub α β γ] : α → β → γ`a - b` computes the difference of `a` and `b`.
    The meaning of this notation is type-dependent.
    * For natural numbers, this operator saturates at 0: `a - b = 0` when `a ≤ b`. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `-` in identifiers is `sub` (when used as a binary operator)..factorialNat.factorial : ℕ → ℕ`Nat.factorial n` is the factorial of `n`. )HDiv.hDiv.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HDiv α β γ] : α → β → γ`a / b` computes the result of dividing `a` by `b`.
    The meaning of this notation is type-dependent.
    * For most types like `Nat`, `Int`, `Rat`, `Real`, `a / 0` is defined to be `0`.
    * For `Nat`, `a / b` rounds downwards.
    * For `Int`, `a / b` rounds downwards if `b` is positive or upwards if `b` is negative.
      It is implemented as `Int.ediv`, the unique function satisfying
      `a % b + b * (a / b) = a` and `0 ≤ a % b < natAbs b` for `b ≠ 0`.
      Other rounding conventions are available using the functions
      `Int.fdiv` (floor rounding) and `Int.tdiv` (truncation rounding).
    * For `Float`, `a / 0` follows the IEEE 754 semantics for division,
      usually resulting in `inf` or `nan`. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `/` in identifiers is `div`. *HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`.
            ∑'tsum.{u_4, u_5} {α : Type u_4} {β : Type u_5} [AddCommMonoid α] [TopologicalSpace α] (f : β → α)
      (L : SummationFilter β := SummationFilter.unconditional β) : α`∑' i, f i` is the unconditional sum of `f` if it exists, or 0 otherwise.
    
    More generally, if `L` is a `SummationFilter`, `∑'[L] i, f i` is the sum of `f` with respect to
    `L` if it exists, and `0` otherwise.
    
    (Note that even if the unconditional sum exists, it might not be unique if the topology is not
    separated. When the support of `f` is finite, we make the most reasonable choice, to use the sum
    over the support. Otherwise, we choose arbitrarily an `a` satisfying `HasSum f a`. Similar remarks
    apply to more general summation filters.)
     (nℕ+ : ℕ+PNat : Type`ℕ+` is the type of positive natural numbers. It is defined as a subtype,
    and the VM representation of `ℕ+` is the same as `ℕ` because the proof
    is not stored. ),tsum.{u_4, u_5} {α : Type u_4} {β : Type u_5} [AddCommMonoid α] [TopologicalSpace α] (f : β → α)
      (L : SummationFilter β := SummationFilter.unconditional β) : α`∑' i, f i` is the unconditional sum of `f` if it exists, or 0 otherwise.
    
    More generally, if `L` is a `SummationFilter`, `∑'[L] i, f i` is the sum of `f` with respect to
    `L` if it exists, and `0` otherwise.
    
    (Note that even if the unconditional sum exists, it might not be unique if the topology is not
    separated. When the support of `f` is finite, we make the most reasonable choice, to use the sum
    over the support. Otherwise, we choose arbitrarily an `a` satisfying `HasSum f a`. Similar remarks
    apply to more general summation filters.)
    
              ((ArithmeticFunction.sigmaArithmeticFunction.sigma (k : ℕ) : ArithmeticFunction ℕ`σ k n` is the sum of the `k`th powers of the divisors of `n`  (HSub.hSub.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HSub α β γ] : α → β → γ`a - b` computes the difference of `a` and `b`.
    The meaning of this notation is type-dependent.
    * For natural numbers, this operator saturates at 0: `a - b = 0` when `a ≤ b`. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `-` in identifiers is `sub` (when used as a binary operator).k -HSub.hSub.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HSub α β γ] : α → β → γ`a - b` computes the difference of `a` and `b`.
    The meaning of this notation is type-dependent.
    * For natural numbers, this operator saturates at 0: `a - b = 0` when `a ≤ b`. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `-` in identifiers is `sub` (when used as a binary operator). 1)HSub.hSub.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HSub α β γ] : α → β → γ`a - b` computes the difference of `a` and `b`.
    The meaning of this notation is type-dependent.
    * For natural numbers, this operator saturates at 0: `a - b = 0` when `a ≤ b`. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `-` in identifiers is `sub` (when used as a binary operator).) nℕ+) *HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`.
                Complex.expComplex.exp (z : ℂ) : ℂThe complex exponential function, defined via its Taylor series  (HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`.2 *HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`. Real.piReal.pi : ℝThe number π = 3.14159265... Defined here using choice as twice a zero of cos in [1,2],
    from which one can derive all its properties. For explicit bounds on π,
    see `Mathlib/Analysis/Real/Pi/Bounds.lean`.
    
    Denoted `π`, once the `Real` namespace is opened.  *HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`. Complex.IComplex.I : ℂThe imaginary unit.  *HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`. zUpperHalfPlane *HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`. nℕ+)HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`.
    theorem E_k_q_expansion (k : Nat : TypeThe natural numbers, starting at zero.
    
    This type is special-cased by both the kernel and the compiler, and overridden with an efficient
    implementation. Both use a fast arbitrary-precision arithmetic library (usually
    [GMP](https://gmplib.org/)); at runtime, `Nat` values that are sufficiently small are unboxed.
    ) (hk3 ≤ ↑k : 3 LE.le.{u} {α : Type u} [self : LE α] : α → α → PropThe less-equal relation: `x ≤ y` 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `≤` in identifiers is `le`.
    
     * The recommended spelling of `<=` in identifiers is `le` (prefer `≤` over `<=`). k)
      (hk2Even k : EvenEven.{u_2} {α : Type u_2} [Add α] (a : α) : PropAn element `a` of a type `α` with addition satisfies `Even a` if `a = r + r`,
    for some `r : α`.  k) (zUpperHalfPlane : UpperHalfPlaneUpperHalfPlane : TypeThe open upper half plane, denoted as `ℍ` within the `UpperHalfPlane` namespace ) :
      (EE (k : ℤ) (hk : 3 ≤ k) : ModularForm (Subgroup.map (Matrix.SpecialLinearGroup.mapGL ℝ) (CongruenceSubgroup.Gamma 1)) k (↑k) hk3 ≤ ↑k) zUpperHalfPlane =Eq.{u_1} {α : Sort u_1} : α → α → PropThe equality relation. It has one introduction rule, `Eq.refl`.
    We use `a = b` as notation for `Eq a b`.
    A fundamental property of equality is that it is an equivalence relation.
    ```
    variable (α : Type) (a b c d : α)
    variable (hab : a = b) (hcb : c = b) (hcd : c = d)
    
    example : a = d :=
      Eq.trans (Eq.trans hab (Eq.symm hcb)) hcd
    ```
    Equality is much more than an equivalence relation, however. It has the important property that every assertion
    respects the equivalence, in the sense that we can substitute equal expressions without changing the truth value.
    That is, given `h1 : a = b` and `h2 : p a`, we can construct a proof for `p b` using substitution: `Eq.subst h1 h2`.
    Example:
    ```
    example (α : Type) (a b : α) (p : α → Prop)
            (h1 : a = b) (h2 : p a) : p b :=
      Eq.subst h1 h2
    
    example (α : Type) (a b : α) (p : α → Prop)
        (h1 : a = b) (h2 : p a) : p b :=
      h1 ▸ h2
    ```
    The triangle in the second presentation is a macro built on top of `Eq.subst` and `Eq.symm`, and you can enter it by typing `\t`.
    For more information: [Equality](https://lean-lang.org/theorem_proving_in_lean4/quantifiers_and_equality.html#equality)
    
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `=` in identifiers is `eq`.
        1 +HAdd.hAdd.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HAdd α β γ] : α → β → γ`a + b` computes the sum of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `+` in identifiers is `add`.
          1 /HDiv.hDiv.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HDiv α β γ] : α → β → γ`a / b` computes the result of dividing `a` by `b`.
    The meaning of this notation is type-dependent.
    * For most types like `Nat`, `Int`, `Rat`, `Real`, `a / 0` is defined to be `0`.
    * For `Nat`, `a / b` rounds downwards.
    * For `Int`, `a / b` rounds downwards if `b` is positive or upwards if `b` is negative.
      It is implemented as `Int.ediv`, the unique function satisfying
      `a % b + b * (a / b) = a` and `0 ≤ a % b < natAbs b` for `b ≠ 0`.
      Other rounding conventions are available using the functions
      `Int.fdiv` (floor rounding) and `Int.tdiv` (truncation rounding).
    * For `Float`, `a / 0` follows the IEEE 754 semantics for division,
      usually resulting in `inf` or `nan`. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `/` in identifiers is `div`. riemannZetariemannZeta (a : ℂ) : ℂThe Riemann zeta function `ζ(s)`.  k *HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`.
              (HDiv.hDiv.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HDiv α β γ] : α → β → γ`a / b` computes the result of dividing `a` by `b`.
    The meaning of this notation is type-dependent.
    * For most types like `Nat`, `Int`, `Rat`, `Real`, `a / 0` is defined to be `0`.
    * For `Nat`, `a / b` rounds downwards.
    * For `Int`, `a / b` rounds downwards if `b` is positive or upwards if `b` is negative.
      It is implemented as `Int.ediv`, the unique function satisfying
      `a % b + b * (a / b) = a` and `0 ≤ a % b < natAbs b` for `b ≠ 0`.
      Other rounding conventions are available using the functions
      `Int.fdiv` (floor rounding) and `Int.tdiv` (truncation rounding).
    * For `Float`, `a / 0` follows the IEEE 754 semantics for division,
      usually resulting in `inf` or `nan`. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `/` in identifiers is `div`.(HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`.-2 *HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`. Real.piReal.pi : ℝThe number π = 3.14159265... Defined here using choice as twice a zero of cos in [1,2],
    from which one can derive all its properties. For explicit bounds on π,
    see `Mathlib/Analysis/Real/Pi/Bounds.lean`.
    
    Denoted `π`, once the `Real` namespace is opened.  *HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`. Complex.IComplex.I : ℂThe imaginary unit. )HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`. ^HPow.hPow.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HPow α β γ] : α → β → γ`a ^ b` computes `a` to the power of `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `^` in identifiers is `pow`.
                  k /HDiv.hDiv.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HDiv α β γ] : α → β → γ`a / b` computes the result of dividing `a` by `b`.
    The meaning of this notation is type-dependent.
    * For most types like `Nat`, `Int`, `Rat`, `Real`, `a / 0` is defined to be `0`.
    * For `Nat`, `a / b` rounds downwards.
    * For `Int`, `a / b` rounds downwards if `b` is positive or upwards if `b` is negative.
      It is implemented as `Int.ediv`, the unique function satisfying
      `a % b + b * (a / b) = a` and `0 ≤ a % b < natAbs b` for `b ≠ 0`.
      Other rounding conventions are available using the functions
      `Int.fdiv` (floor rounding) and `Int.tdiv` (truncation rounding).
    * For `Float`, `a / 0` follows the IEEE 754 semantics for division,
      usually resulting in `inf` or `nan`. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `/` in identifiers is `div`.
                (HSub.hSub.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HSub α β γ] : α → β → γ`a - b` computes the difference of `a` and `b`.
    The meaning of this notation is type-dependent.
    * For natural numbers, this operator saturates at 0: `a - b = 0` when `a ≤ b`. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `-` in identifiers is `sub` (when used as a binary operator).k -HSub.hSub.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HSub α β γ] : α → β → γ`a - b` computes the difference of `a` and `b`.
    The meaning of this notation is type-dependent.
    * For natural numbers, this operator saturates at 0: `a - b = 0` when `a ≤ b`. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `-` in identifiers is `sub` (when used as a binary operator). 1)HSub.hSub.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HSub α β γ] : α → β → γ`a - b` computes the difference of `a` and `b`.
    The meaning of this notation is type-dependent.
    * For natural numbers, this operator saturates at 0: `a - b = 0` when `a ≤ b`. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `-` in identifiers is `sub` (when used as a binary operator)..factorialNat.factorial : ℕ → ℕ`Nat.factorial n` is the factorial of `n`. )HDiv.hDiv.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HDiv α β γ] : α → β → γ`a / b` computes the result of dividing `a` by `b`.
    The meaning of this notation is type-dependent.
    * For most types like `Nat`, `Int`, `Rat`, `Real`, `a / 0` is defined to be `0`.
    * For `Nat`, `a / b` rounds downwards.
    * For `Int`, `a / b` rounds downwards if `b` is positive or upwards if `b` is negative.
      It is implemented as `Int.ediv`, the unique function satisfying
      `a % b + b * (a / b) = a` and `0 ≤ a % b < natAbs b` for `b ≠ 0`.
      Other rounding conventions are available using the functions
      `Int.fdiv` (floor rounding) and `Int.tdiv` (truncation rounding).
    * For `Float`, `a / 0` follows the IEEE 754 semantics for division,
      usually resulting in `inf` or `nan`. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `/` in identifiers is `div`. *HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`.
            ∑'tsum.{u_4, u_5} {α : Type u_4} {β : Type u_5} [AddCommMonoid α] [TopologicalSpace α] (f : β → α)
      (L : SummationFilter β := SummationFilter.unconditional β) : α`∑' i, f i` is the unconditional sum of `f` if it exists, or 0 otherwise.
    
    More generally, if `L` is a `SummationFilter`, `∑'[L] i, f i` is the sum of `f` with respect to
    `L` if it exists, and `0` otherwise.
    
    (Note that even if the unconditional sum exists, it might not be unique if the topology is not
    separated. When the support of `f` is finite, we make the most reasonable choice, to use the sum
    over the support. Otherwise, we choose arbitrarily an `a` satisfying `HasSum f a`. Similar remarks
    apply to more general summation filters.)
     (nℕ+ : ℕ+PNat : Type`ℕ+` is the type of positive natural numbers. It is defined as a subtype,
    and the VM representation of `ℕ+` is the same as `ℕ` because the proof
    is not stored. ),tsum.{u_4, u_5} {α : Type u_4} {β : Type u_5} [AddCommMonoid α] [TopologicalSpace α] (f : β → α)
      (L : SummationFilter β := SummationFilter.unconditional β) : α`∑' i, f i` is the unconditional sum of `f` if it exists, or 0 otherwise.
    
    More generally, if `L` is a `SummationFilter`, `∑'[L] i, f i` is the sum of `f` with respect to
    `L` if it exists, and `0` otherwise.
    
    (Note that even if the unconditional sum exists, it might not be unique if the topology is not
    separated. When the support of `f` is finite, we make the most reasonable choice, to use the sum
    over the support. Otherwise, we choose arbitrarily an `a` satisfying `HasSum f a`. Similar remarks
    apply to more general summation filters.)
    
              ((ArithmeticFunction.sigmaArithmeticFunction.sigma (k : ℕ) : ArithmeticFunction ℕ`σ k n` is the sum of the `k`th powers of the divisors of `n` 
                      (HSub.hSub.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HSub α β γ] : α → β → γ`a - b` computes the difference of `a` and `b`.
    The meaning of this notation is type-dependent.
    * For natural numbers, this operator saturates at 0: `a - b = 0` when `a ≤ b`. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `-` in identifiers is `sub` (when used as a binary operator).k -HSub.hSub.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HSub α β γ] : α → β → γ`a - b` computes the difference of `a` and `b`.
    The meaning of this notation is type-dependent.
    * For natural numbers, this operator saturates at 0: `a - b = 0` when `a ≤ b`. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `-` in identifiers is `sub` (when used as a binary operator). 1)HSub.hSub.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HSub α β γ] : α → β → γ`a - b` computes the difference of `a` and `b`.
    The meaning of this notation is type-dependent.
    * For natural numbers, this operator saturates at 0: `a - b = 0` when `a ≤ b`. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `-` in identifiers is `sub` (when used as a binary operator).)
                    nℕ+) *HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`.
                Complex.expComplex.exp (z : ℂ) : ℂThe complex exponential function, defined via its Taylor series 
                  (HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`.2 *HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`. Real.piReal.pi : ℝThe number π = 3.14159265... Defined here using choice as twice a zero of cos in [1,2],
    from which one can derive all its properties. For explicit bounds on π,
    see `Mathlib/Analysis/Real/Pi/Bounds.lean`.
    
    Denoted `π`, once the `Real` namespace is opened.  *HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`. Complex.IComplex.I : ℂThe imaginary unit.  *HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`.
                      zUpperHalfPlane *HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`.
                    nℕ+)HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`.
    complete
Proof
Lean code for Definition7.171 theorem
  • theorem E₂_eq (zUpperHalfPlane : UpperHalfPlaneUpperHalfPlane : TypeThe open upper half plane, denoted as `ℍ` within the `UpperHalfPlane` namespace ) :
      E₂E₂ : UpperHalfPlane → ℂCompatibility alias for Mathlib's `EisensteinSeries.E2`.  zUpperHalfPlane =Eq.{u_1} {α : Sort u_1} : α → α → PropThe equality relation. It has one introduction rule, `Eq.refl`.
    We use `a = b` as notation for `Eq a b`.
    A fundamental property of equality is that it is an equivalence relation.
    ```
    variable (α : Type) (a b c d : α)
    variable (hab : a = b) (hcb : c = b) (hcd : c = d)
    
    example : a = d :=
      Eq.trans (Eq.trans hab (Eq.symm hcb)) hcd
    ```
    Equality is much more than an equivalence relation, however. It has the important property that every assertion
    respects the equivalence, in the sense that we can substitute equal expressions without changing the truth value.
    That is, given `h1 : a = b` and `h2 : p a`, we can construct a proof for `p b` using substitution: `Eq.subst h1 h2`.
    Example:
    ```
    example (α : Type) (a b : α) (p : α → Prop)
            (h1 : a = b) (h2 : p a) : p b :=
      Eq.subst h1 h2
    
    example (α : Type) (a b : α) (p : α → Prop)
        (h1 : a = b) (h2 : p a) : p b :=
      h1 ▸ h2
    ```
    The triangle in the second presentation is a macro built on top of `Eq.subst` and `Eq.symm`, and you can enter it by typing `\t`.
    For more information: [Equality](https://lean-lang.org/theorem_proving_in_lean4/quantifiers_and_equality.html#equality)
    
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `=` in identifiers is `eq`.
        1 -HSub.hSub.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HSub α β γ] : α → β → γ`a - b` computes the difference of `a` and `b`.
    The meaning of this notation is type-dependent.
    * For natural numbers, this operator saturates at 0: `a - b = 0` when `a ≤ b`. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `-` in identifiers is `sub` (when used as a binary operator).
          24 *HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`.
            ∑'tsum.{u_4, u_5} {α : Type u_4} {β : Type u_5} [AddCommMonoid α] [TopologicalSpace α] (f : β → α)
      (L : SummationFilter β := SummationFilter.unconditional β) : α`∑' i, f i` is the unconditional sum of `f` if it exists, or 0 otherwise.
    
    More generally, if `L` is a `SummationFilter`, `∑'[L] i, f i` is the sum of `f` with respect to
    `L` if it exists, and `0` otherwise.
    
    (Note that even if the unconditional sum exists, it might not be unique if the topology is not
    separated. When the support of `f` is finite, we make the most reasonable choice, to use the sum
    over the support. Otherwise, we choose arbitrarily an `a` satisfying `HasSum f a`. Similar remarks
    apply to more general summation filters.)
     (nℕ+ : ℕ+PNat : Type`ℕ+` is the type of positive natural numbers. It is defined as a subtype,
    and the VM representation of `ℕ+` is the same as `ℕ` because the proof
    is not stored. ),tsum.{u_4, u_5} {α : Type u_4} {β : Type u_5} [AddCommMonoid α] [TopologicalSpace α] (f : β → α)
      (L : SummationFilter β := SummationFilter.unconditional β) : α`∑' i, f i` is the unconditional sum of `f` if it exists, or 0 otherwise.
    
    More generally, if `L` is a `SummationFilter`, `∑'[L] i, f i` is the sum of `f` with respect to
    `L` if it exists, and `0` otherwise.
    
    (Note that even if the unconditional sum exists, it might not be unique if the topology is not
    separated. When the support of `f` is finite, we make the most reasonable choice, to use the sum
    over the support. Otherwise, we choose arbitrarily an `a` satisfying `HasSum f a`. Similar remarks
    apply to more general summation filters.)
    
              nℕ+ *HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`. Complex.expComplex.exp (z : ℂ) : ℂThe complex exponential function, defined via its Taylor series  (HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`.2 *HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`. Real.piReal.pi : ℝThe number π = 3.14159265... Defined here using choice as twice a zero of cos in [1,2],
    from which one can derive all its properties. For explicit bounds on π,
    see `Mathlib/Analysis/Real/Pi/Bounds.lean`.
    
    Denoted `π`, once the `Real` namespace is opened.  *HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`. Complex.IComplex.I : ℂThe imaginary unit.  *HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`. nℕ+ *HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`. zUpperHalfPlane)HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`. /HDiv.hDiv.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HDiv α β γ] : α → β → γ`a / b` computes the result of dividing `a` by `b`.
    The meaning of this notation is type-dependent.
    * For most types like `Nat`, `Int`, `Rat`, `Real`, `a / 0` is defined to be `0`.
    * For `Nat`, `a / b` rounds downwards.
    * For `Int`, `a / b` rounds downwards if `b` is positive or upwards if `b` is negative.
      It is implemented as `Int.ediv`, the unique function satisfying
      `a % b + b * (a / b) = a` and `0 ≤ a % b < natAbs b` for `b ≠ 0`.
      Other rounding conventions are available using the functions
      `Int.fdiv` (floor rounding) and `Int.tdiv` (truncation rounding).
    * For `Float`, `a / 0` follows the IEEE 754 semantics for division,
      usually resulting in `inf` or `nan`. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `/` in identifiers is `div`.
                (HSub.hSub.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HSub α β γ] : α → β → γ`a - b` computes the difference of `a` and `b`.
    The meaning of this notation is type-dependent.
    * For natural numbers, this operator saturates at 0: `a - b = 0` when `a ≤ b`. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `-` in identifiers is `sub` (when used as a binary operator).1 -HSub.hSub.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HSub α β γ] : α → β → γ`a - b` computes the difference of `a` and `b`.
    The meaning of this notation is type-dependent.
    * For natural numbers, this operator saturates at 0: `a - b = 0` when `a ≤ b`. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `-` in identifiers is `sub` (when used as a binary operator). Complex.expComplex.exp (z : ℂ) : ℂThe complex exponential function, defined via its Taylor series  (HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`.2 *HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`. Real.piReal.pi : ℝThe number π = 3.14159265... Defined here using choice as twice a zero of cos in [1,2],
    from which one can derive all its properties. For explicit bounds on π,
    see `Mathlib/Analysis/Real/Pi/Bounds.lean`.
    
    Denoted `π`, once the `Real` namespace is opened.  *HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`. Complex.IComplex.I : ℂThe imaginary unit.  *HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`. nℕ+ *HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`. zUpperHalfPlane)HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`.)HSub.hSub.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HSub α β γ] : α → β → γ`a - b` computes the difference of `a` and `b`.
    The meaning of this notation is type-dependent.
    * For natural numbers, this operator saturates at 0: `a - b = 0` when `a ≤ b`. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `-` in identifiers is `sub` (when used as a binary operator).
    theorem E₂_eq (zUpperHalfPlane : UpperHalfPlaneUpperHalfPlane : TypeThe open upper half plane, denoted as `ℍ` within the `UpperHalfPlane` namespace ) :
      E₂E₂ : UpperHalfPlane → ℂCompatibility alias for Mathlib's `EisensteinSeries.E2`.  zUpperHalfPlane =Eq.{u_1} {α : Sort u_1} : α → α → PropThe equality relation. It has one introduction rule, `Eq.refl`.
    We use `a = b` as notation for `Eq a b`.
    A fundamental property of equality is that it is an equivalence relation.
    ```
    variable (α : Type) (a b c d : α)
    variable (hab : a = b) (hcb : c = b) (hcd : c = d)
    
    example : a = d :=
      Eq.trans (Eq.trans hab (Eq.symm hcb)) hcd
    ```
    Equality is much more than an equivalence relation, however. It has the important property that every assertion
    respects the equivalence, in the sense that we can substitute equal expressions without changing the truth value.
    That is, given `h1 : a = b` and `h2 : p a`, we can construct a proof for `p b` using substitution: `Eq.subst h1 h2`.
    Example:
    ```
    example (α : Type) (a b : α) (p : α → Prop)
            (h1 : a = b) (h2 : p a) : p b :=
      Eq.subst h1 h2
    
    example (α : Type) (a b : α) (p : α → Prop)
        (h1 : a = b) (h2 : p a) : p b :=
      h1 ▸ h2
    ```
    The triangle in the second presentation is a macro built on top of `Eq.subst` and `Eq.symm`, and you can enter it by typing `\t`.
    For more information: [Equality](https://lean-lang.org/theorem_proving_in_lean4/quantifiers_and_equality.html#equality)
    
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `=` in identifiers is `eq`.
        1 -HSub.hSub.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HSub α β γ] : α → β → γ`a - b` computes the difference of `a` and `b`.
    The meaning of this notation is type-dependent.
    * For natural numbers, this operator saturates at 0: `a - b = 0` when `a ≤ b`. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `-` in identifiers is `sub` (when used as a binary operator).
          24 *HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`.
            ∑'tsum.{u_4, u_5} {α : Type u_4} {β : Type u_5} [AddCommMonoid α] [TopologicalSpace α] (f : β → α)
      (L : SummationFilter β := SummationFilter.unconditional β) : α`∑' i, f i` is the unconditional sum of `f` if it exists, or 0 otherwise.
    
    More generally, if `L` is a `SummationFilter`, `∑'[L] i, f i` is the sum of `f` with respect to
    `L` if it exists, and `0` otherwise.
    
    (Note that even if the unconditional sum exists, it might not be unique if the topology is not
    separated. When the support of `f` is finite, we make the most reasonable choice, to use the sum
    over the support. Otherwise, we choose arbitrarily an `a` satisfying `HasSum f a`. Similar remarks
    apply to more general summation filters.)
     (nℕ+ : ℕ+PNat : Type`ℕ+` is the type of positive natural numbers. It is defined as a subtype,
    and the VM representation of `ℕ+` is the same as `ℕ` because the proof
    is not stored. ),tsum.{u_4, u_5} {α : Type u_4} {β : Type u_5} [AddCommMonoid α] [TopologicalSpace α] (f : β → α)
      (L : SummationFilter β := SummationFilter.unconditional β) : α`∑' i, f i` is the unconditional sum of `f` if it exists, or 0 otherwise.
    
    More generally, if `L` is a `SummationFilter`, `∑'[L] i, f i` is the sum of `f` with respect to
    `L` if it exists, and `0` otherwise.
    
    (Note that even if the unconditional sum exists, it might not be unique if the topology is not
    separated. When the support of `f` is finite, we make the most reasonable choice, to use the sum
    over the support. Otherwise, we choose arbitrarily an `a` satisfying `HasSum f a`. Similar remarks
    apply to more general summation filters.)
    
              nℕ+ *HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`.
                  Complex.expComplex.exp (z : ℂ) : ℂThe complex exponential function, defined via its Taylor series 
                    (HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`.2 *HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`. Real.piReal.pi : ℝThe number π = 3.14159265... Defined here using choice as twice a zero of cos in [1,2],
    from which one can derive all its properties. For explicit bounds on π,
    see `Mathlib/Analysis/Real/Pi/Bounds.lean`.
    
    Denoted `π`, once the `Real` namespace is opened.  *HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`.
                          Complex.IComplex.I : ℂThe imaginary unit.  *HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`.
                        nℕ+ *HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`.
                      zUpperHalfPlane)HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`. /HDiv.hDiv.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HDiv α β γ] : α → β → γ`a / b` computes the result of dividing `a` by `b`.
    The meaning of this notation is type-dependent.
    * For most types like `Nat`, `Int`, `Rat`, `Real`, `a / 0` is defined to be `0`.
    * For `Nat`, `a / b` rounds downwards.
    * For `Int`, `a / b` rounds downwards if `b` is positive or upwards if `b` is negative.
      It is implemented as `Int.ediv`, the unique function satisfying
      `a % b + b * (a / b) = a` and `0 ≤ a % b < natAbs b` for `b ≠ 0`.
      Other rounding conventions are available using the functions
      `Int.fdiv` (floor rounding) and `Int.tdiv` (truncation rounding).
    * For `Float`, `a / 0` follows the IEEE 754 semantics for division,
      usually resulting in `inf` or `nan`. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `/` in identifiers is `div`.
                (HSub.hSub.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HSub α β γ] : α → β → γ`a - b` computes the difference of `a` and `b`.
    The meaning of this notation is type-dependent.
    * For natural numbers, this operator saturates at 0: `a - b = 0` when `a ≤ b`. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `-` in identifiers is `sub` (when used as a binary operator).1 -HSub.hSub.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HSub α β γ] : α → β → γ`a - b` computes the difference of `a` and `b`.
    The meaning of this notation is type-dependent.
    * For natural numbers, this operator saturates at 0: `a - b = 0` when `a ≤ b`. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `-` in identifiers is `sub` (when used as a binary operator).
                  Complex.expComplex.exp (z : ℂ) : ℂThe complex exponential function, defined via its Taylor series 
                    (HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`.2 *HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`. Real.piReal.pi : ℝThe number π = 3.14159265... Defined here using choice as twice a zero of cos in [1,2],
    from which one can derive all its properties. For explicit bounds on π,
    see `Mathlib/Analysis/Real/Pi/Bounds.lean`.
    
    Denoted `π`, once the `Real` namespace is opened.  *HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`.
                          Complex.IComplex.I : ℂThe imaginary unit.  *HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`.
                        nℕ+ *HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`.
                      zUpperHalfPlane)HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`.)HSub.hSub.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HSub α β γ] : α → β → γ`a - b` computes the difference of `a` and `b`.
    The meaning of this notation is type-dependent.
    * For natural numbers, this operator saturates at 0: `a - b = 0` when `a ≤ b`. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `-` in identifiers is `sub` (when used as a binary operator).
    complete

This function is not modular; however, it satisfies z^{-2}\,E_2\left(-\frac{1}{z}\right) = E_2(z) -\frac{6i}{\pi}\, \frac{1}{z}. Uses Definition 7.17.

Lean code for Lemma7.181 theorem
  • theorem E₂_transform (zUpperHalfPlane : UpperHalfPlaneUpperHalfPlane : TypeThe open upper half plane, denoted as `ℍ` within the `UpperHalfPlane` namespace ) :
      SlashAction.mapSlashAction.map.{u_1, u_2, u_3} {β : Type u_1} {G : Type u_2} {α : Type u_3} {inst✝ : Monoid G} {inst✝¹ : AddMonoid α}
      [self : SlashAction β G α] : β → G → α → α 2 ModularGroup.SModularGroup.S : Matrix.SpecialLinearGroup (Fin 2) ℤThe matrix `S = [[0, -1], [1, 0]]` as an element of `SL(2, ℤ)`.
    
    This element acts naturally on the Euclidean plane as a rotation about the origin by `π / 2`.
    
    This element also acts naturally on the hyperbolic plane as rotation about `i` by `π`. It
    represents the Mobiüs transformation `z ↦ -1/z` and is an involutive elliptic isometry.  E₂E₂ : UpperHalfPlane → ℂCompatibility alias for Mathlib's `EisensteinSeries.E2`.  zUpperHalfPlane =Eq.{u_1} {α : Sort u_1} : α → α → PropThe equality relation. It has one introduction rule, `Eq.refl`.
    We use `a = b` as notation for `Eq a b`.
    A fundamental property of equality is that it is an equivalence relation.
    ```
    variable (α : Type) (a b c d : α)
    variable (hab : a = b) (hcb : c = b) (hcd : c = d)
    
    example : a = d :=
      Eq.trans (Eq.trans hab (Eq.symm hcb)) hcd
    ```
    Equality is much more than an equivalence relation, however. It has the important property that every assertion
    respects the equivalence, in the sense that we can substitute equal expressions without changing the truth value.
    That is, given `h1 : a = b` and `h2 : p a`, we can construct a proof for `p b` using substitution: `Eq.subst h1 h2`.
    Example:
    ```
    example (α : Type) (a b : α) (p : α → Prop)
            (h1 : a = b) (h2 : p a) : p b :=
      Eq.subst h1 h2
    
    example (α : Type) (a b : α) (p : α → Prop)
        (h1 : a = b) (h2 : p a) : p b :=
      h1 ▸ h2
    ```
    The triangle in the second presentation is a macro built on top of `Eq.subst` and `Eq.symm`, and you can enter it by typing `\t`.
    For more information: [Equality](https://lean-lang.org/theorem_proving_in_lean4/quantifiers_and_equality.html#equality)
    
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `=` in identifiers is `eq`.
        E₂E₂ : UpperHalfPlane → ℂCompatibility alias for Mathlib's `EisensteinSeries.E2`.  zUpperHalfPlane +HAdd.hAdd.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HAdd α β γ] : α → β → γ`a + b` computes the sum of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `+` in identifiers is `add`. 6 /HDiv.hDiv.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HDiv α β γ] : α → β → γ`a / b` computes the result of dividing `a` by `b`.
    The meaning of this notation is type-dependent.
    * For most types like `Nat`, `Int`, `Rat`, `Real`, `a / 0` is defined to be `0`.
    * For `Nat`, `a / b` rounds downwards.
    * For `Int`, `a / b` rounds downwards if `b` is positive or upwards if `b` is negative.
      It is implemented as `Int.ediv`, the unique function satisfying
      `a % b + b * (a / b) = a` and `0 ≤ a % b < natAbs b` for `b ≠ 0`.
      Other rounding conventions are available using the functions
      `Int.fdiv` (floor rounding) and `Int.tdiv` (truncation rounding).
    * For `Float`, `a / 0` follows the IEEE 754 semantics for division,
      usually resulting in `inf` or `nan`. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `/` in identifiers is `div`. (HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`.Real.piReal.pi : ℝThe number π = 3.14159265... Defined here using choice as twice a zero of cos in [1,2],
    from which one can derive all its properties. For explicit bounds on π,
    see `Mathlib/Analysis/Real/Pi/Bounds.lean`.
    
    Denoted `π`, once the `Real` namespace is opened.  *HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`. Complex.IComplex.I : ℂThe imaginary unit.  *HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`. zUpperHalfPlane)HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`.
    theorem E₂_transform (zUpperHalfPlane : UpperHalfPlaneUpperHalfPlane : TypeThe open upper half plane, denoted as `ℍ` within the `UpperHalfPlane` namespace ) :
      SlashAction.mapSlashAction.map.{u_1, u_2, u_3} {β : Type u_1} {G : Type u_2} {α : Type u_3} {inst✝ : Monoid G} {inst✝¹ : AddMonoid α}
      [self : SlashAction β G α] : β → G → α → α 2 ModularGroup.SModularGroup.S : Matrix.SpecialLinearGroup (Fin 2) ℤThe matrix `S = [[0, -1], [1, 0]]` as an element of `SL(2, ℤ)`.
    
    This element acts naturally on the Euclidean plane as a rotation about the origin by `π / 2`.
    
    This element also acts naturally on the hyperbolic plane as rotation about `i` by `π`. It
    represents the Mobiüs transformation `z ↦ -1/z` and is an involutive elliptic isometry.  E₂E₂ : UpperHalfPlane → ℂCompatibility alias for Mathlib's `EisensteinSeries.E2`.  zUpperHalfPlane =Eq.{u_1} {α : Sort u_1} : α → α → PropThe equality relation. It has one introduction rule, `Eq.refl`.
    We use `a = b` as notation for `Eq a b`.
    A fundamental property of equality is that it is an equivalence relation.
    ```
    variable (α : Type) (a b c d : α)
    variable (hab : a = b) (hcb : c = b) (hcd : c = d)
    
    example : a = d :=
      Eq.trans (Eq.trans hab (Eq.symm hcb)) hcd
    ```
    Equality is much more than an equivalence relation, however. It has the important property that every assertion
    respects the equivalence, in the sense that we can substitute equal expressions without changing the truth value.
    That is, given `h1 : a = b` and `h2 : p a`, we can construct a proof for `p b` using substitution: `Eq.subst h1 h2`.
    Example:
    ```
    example (α : Type) (a b : α) (p : α → Prop)
            (h1 : a = b) (h2 : p a) : p b :=
      Eq.subst h1 h2
    
    example (α : Type) (a b : α) (p : α → Prop)
        (h1 : a = b) (h2 : p a) : p b :=
      h1 ▸ h2
    ```
    The triangle in the second presentation is a macro built on top of `Eq.subst` and `Eq.symm`, and you can enter it by typing `\t`.
    For more information: [Equality](https://lean-lang.org/theorem_proving_in_lean4/quantifiers_and_equality.html#equality)
    
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `=` in identifiers is `eq`.
        E₂E₂ : UpperHalfPlane → ℂCompatibility alias for Mathlib's `EisensteinSeries.E2`.  zUpperHalfPlane +HAdd.hAdd.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HAdd α β γ] : α → β → γ`a + b` computes the sum of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `+` in identifiers is `add`. 6 /HDiv.hDiv.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HDiv α β γ] : α → β → γ`a / b` computes the result of dividing `a` by `b`.
    The meaning of this notation is type-dependent.
    * For most types like `Nat`, `Int`, `Rat`, `Real`, `a / 0` is defined to be `0`.
    * For `Nat`, `a / b` rounds downwards.
    * For `Int`, `a / b` rounds downwards if `b` is positive or upwards if `b` is negative.
      It is implemented as `Int.ediv`, the unique function satisfying
      `a % b + b * (a / b) = a` and `0 ≤ a % b < natAbs b` for `b ≠ 0`.
      Other rounding conventions are available using the functions
      `Int.fdiv` (floor rounding) and `Int.tdiv` (truncation rounding).
    * For `Float`, `a / 0` follows the IEEE 754 semantics for division,
      usually resulting in `inf` or `nan`. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `/` in identifiers is `div`. (HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`.Real.piReal.pi : ℝThe number π = 3.14159265... Defined here using choice as twice a zero of cos in [1,2],
    from which one can derive all its properties. For explicit bounds on π,
    see `Mathlib/Analysis/Real/Pi/Bounds.lean`.
    
    Denoted `π`, once the `Real` namespace is opened.  *HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`. Complex.IComplex.I : ℂThe imaginary unit.  *HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`. zUpperHalfPlane)HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`.
    complete
Proof

This is exercise 1.2.8 of Diamond and Shurman (2005).

We have (cz + d)^{-2} E_2\left(\frac{az + b}{cx + d}\right) = E_2(z) - \frac{6ic}{\pi (cz + d)}, \quad \begin{pmatrix} a & b \\ c & d\end{pmatrix} \in \mathrm{SL}_{2}(\mathbb{Z}). Uses Lemma 7.18 and Definition 7.17.

Lean code for Lemma7.191 theorem
  • theorem G₂_transform (γMatrix.SpecialLinearGroup (Fin 2) ℤ : Matrix.SpecialLinearGroupMatrix.SpecialLinearGroup.{u, v} (n : Type u) [DecidableEq n] [Fintype n] (R : Type v) [CommRing R] : Type (max 0 u v)`SpecialLinearGroup n R` is the group of `n` by `n` `R`-matrices with determinant equal to 1.
     (FinFin (n : ℕ) : TypeNatural numbers less than some upper bound.
    
    In particular, a `Fin n` is a natural number `i` with the constraint that `i < n`. It is the
    canonical type with `n` elements.
     2) Int : TypeThe integers.
    
    This type is special-cased by the compiler and overridden with an efficient implementation. The
    runtime has a special representation for `Int` that stores “small” signed numbers directly, while
    larger numbers use a fast arbitrary-precision arithmetic library (usually
    [GMP](https://gmplib.org/)). A “small number” is an integer that can be encoded with one fewer bits
    than the platform's pointer size (i.e. 63 bits on 64-bit architectures and 31 bits on 32-bit
    architectures).
    ) :
      SlashAction.mapSlashAction.map.{u_1, u_2, u_3} {β : Type u_1} {G : Type u_2} {α : Type u_3} {inst✝ : Monoid G} {inst✝¹ : AddMonoid α}
      [self : SlashAction β G α] : β → G → α → α 2 γMatrix.SpecialLinearGroup (Fin 2) ℤ G₂G₂ : UpperHalfPlane → ℂCompatibility alias for Mathlib's `EisensteinSeries.G2`.  =Eq.{u_1} {α : Sort u_1} : α → α → PropThe equality relation. It has one introduction rule, `Eq.refl`.
    We use `a = b` as notation for `Eq a b`.
    A fundamental property of equality is that it is an equivalence relation.
    ```
    variable (α : Type) (a b c d : α)
    variable (hab : a = b) (hcb : c = b) (hcd : c = d)
    
    example : a = d :=
      Eq.trans (Eq.trans hab (Eq.symm hcb)) hcd
    ```
    Equality is much more than an equivalence relation, however. It has the important property that every assertion
    respects the equivalence, in the sense that we can substitute equal expressions without changing the truth value.
    That is, given `h1 : a = b` and `h2 : p a`, we can construct a proof for `p b` using substitution: `Eq.subst h1 h2`.
    Example:
    ```
    example (α : Type) (a b : α) (p : α → Prop)
            (h1 : a = b) (h2 : p a) : p b :=
      Eq.subst h1 h2
    
    example (α : Type) (a b : α) (p : α → Prop)
        (h1 : a = b) (h2 : p a) : p b :=
      h1 ▸ h2
    ```
    The triangle in the second presentation is a macro built on top of `Eq.subst` and `Eq.symm`, and you can enter it by typing `\t`.
    For more information: [Equality](https://lean-lang.org/theorem_proving_in_lean4/quantifiers_and_equality.html#equality)
    
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `=` in identifiers is `eq`. G₂G₂ : UpperHalfPlane → ℂCompatibility alias for Mathlib's `EisensteinSeries.G2`.  -HSub.hSub.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HSub α β γ] : α → β → γ`a - b` computes the difference of `a` and `b`.
    The meaning of this notation is type-dependent.
    * For natural numbers, this operator saturates at 0: `a - b = 0` when `a ≤ b`. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `-` in identifiers is `sub` (when used as a binary operator). D₂D₂ (γ : Matrix.SpecialLinearGroup (Fin 2) ℤ) : UpperHalfPlane → ℂCompatibility alias for Mathlib's `EisensteinSeries.D2`.  γMatrix.SpecialLinearGroup (Fin 2) ℤ
    theorem G₂_transform
      (γMatrix.SpecialLinearGroup (Fin 2) ℤ :
        Matrix.SpecialLinearGroupMatrix.SpecialLinearGroup.{u, v} (n : Type u) [DecidableEq n] [Fintype n] (R : Type v) [CommRing R] : Type (max 0 u v)`SpecialLinearGroup n R` is the group of `n` by `n` `R`-matrices with determinant equal to 1.
     (FinFin (n : ℕ) : TypeNatural numbers less than some upper bound.
    
    In particular, a `Fin n` is a natural number `i` with the constraint that `i < n`. It is the
    canonical type with `n` elements.
     2) Int : TypeThe integers.
    
    This type is special-cased by the compiler and overridden with an efficient implementation. The
    runtime has a special representation for `Int` that stores “small” signed numbers directly, while
    larger numbers use a fast arbitrary-precision arithmetic library (usually
    [GMP](https://gmplib.org/)). A “small number” is an integer that can be encoded with one fewer bits
    than the platform's pointer size (i.e. 63 bits on 64-bit architectures and 31 bits on 32-bit
    architectures).
    ) :
      SlashAction.mapSlashAction.map.{u_1, u_2, u_3} {β : Type u_1} {G : Type u_2} {α : Type u_3} {inst✝ : Monoid G} {inst✝¹ : AddMonoid α}
      [self : SlashAction β G α] : β → G → α → α 2 γMatrix.SpecialLinearGroup (Fin 2) ℤ G₂G₂ : UpperHalfPlane → ℂCompatibility alias for Mathlib's `EisensteinSeries.G2`.  =Eq.{u_1} {α : Sort u_1} : α → α → PropThe equality relation. It has one introduction rule, `Eq.refl`.
    We use `a = b` as notation for `Eq a b`.
    A fundamental property of equality is that it is an equivalence relation.
    ```
    variable (α : Type) (a b c d : α)
    variable (hab : a = b) (hcb : c = b) (hcd : c = d)
    
    example : a = d :=
      Eq.trans (Eq.trans hab (Eq.symm hcb)) hcd
    ```
    Equality is much more than an equivalence relation, however. It has the important property that every assertion
    respects the equivalence, in the sense that we can substitute equal expressions without changing the truth value.
    That is, given `h1 : a = b` and `h2 : p a`, we can construct a proof for `p b` using substitution: `Eq.subst h1 h2`.
    Example:
    ```
    example (α : Type) (a b : α) (p : α → Prop)
            (h1 : a = b) (h2 : p a) : p b :=
      Eq.subst h1 h2
    
    example (α : Type) (a b : α) (p : α → Prop)
        (h1 : a = b) (h2 : p a) : p b :=
      h1 ▸ h2
    ```
    The triangle in the second presentation is a macro built on top of `Eq.subst` and `Eq.symm`, and you can enter it by typing `\t`.
    For more information: [Equality](https://lean-lang.org/theorem_proving_in_lean4/quantifiers_and_equality.html#equality)
    
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `=` in identifiers is `eq`. G₂G₂ : UpperHalfPlane → ℂCompatibility alias for Mathlib's `EisensteinSeries.G2`.  -HSub.hSub.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HSub α β γ] : α → β → γ`a - b` computes the difference of `a` and `b`.
    The meaning of this notation is type-dependent.
    * For natural numbers, this operator saturates at 0: `a - b = 0` when `a ≤ b`. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `-` in identifiers is `sub` (when used as a binary operator). D₂D₂ (γ : Matrix.SpecialLinearGroup (Fin 2) ℤ) : UpperHalfPlane → ℂCompatibility alias for Mathlib's `EisensteinSeries.D2`.  γMatrix.SpecialLinearGroup (Fin 2) ℤ
    complete
Proof

Use the fact that \mathrm{SL}_2(\mathbb{Z}) is generated by S and T. Then eqn:E2-transform-general follows from eqn:E2-S-transform together with E_2|_T = E_2.

The Dedekind eta function is defined as \eta(z) = q^{1/24} \prod_{n \ge 1} (1 - q^n) where q = e^{2\pi i z}.

Lean code for Definition7.201 definition
  • def ModularForm.eta (z : Complex : TypeComplex numbers consist of two `Real`s: a real part `re` and an imaginary part `im`. ) : Complex : TypeComplex numbers consist of two `Real`s: a real part `re` and an imaginary part `im`. 
    def ModularForm.eta (z : Complex : TypeComplex numbers consist of two `Real`s: a real part `re` and an imaginary part `im`. ) : Complex : TypeComplex numbers consist of two `Real`s: a real part `re` and an imaginary part `im`. 
    The eta function, whose value at z is `q^ 1 / 24 * ∏' 1 - q ^ (n + 1)` for `q = e ^ 2 π i z`. 
    complete
Lean code for Lemma7.211 theorem
  • theorem eta_equality :
      Set.EqOnSet.EqOn.{u, v} {α : Type u} {β : Type v} (f₁ f₂ : α → β) (s : Set α) : PropTwo functions `f₁ f₂ : α → β` are equal on `s` if `f₁ x = f₂ x` for all `x ∈ s`.  (Function.comp.{u, v, w} {α : Sort u} {β : Sort v} {δ : Sort w} (f : β → δ) (g : α → β) : α → δFunction composition, usually written with the infix operator `∘`. A new function is created from
    two existing functions, where one function's output is used as input to the other.
    
    Examples:
     * `Function.comp List.reverse (List.drop 2) [3, 2, 4, 1] = [1, 4]`
     * `(List.reverse ∘ List.drop 2) [3, 2, 4, 1] = [1, 4]`
    
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `∘` in identifiers is `comp`.ModularForm.etaModularForm.eta (z : ℂ) : ℂThe eta function, whose value at z is `q^ 1 / 24 * ∏' 1 - q ^ (n + 1)` for `q = e ^ 2 π i z`.  Function.comp.{u, v, w} {α : Sort u} {β : Sort v} {δ : Sort w} (f : β → δ) (g : α → β) : α → δFunction composition, usually written with the infix operator `∘`. A new function is created from
    two existing functions, where one function's output is used as input to the other.
    
    Examples:
     * `Function.comp List.reverse (List.drop 2) [3, 2, 4, 1] = [1, 4]`
     * `(List.reverse ∘ List.drop 2) [3, 2, 4, 1] = [1, 4]`
    
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `∘` in identifiers is `comp`. fun z  -1 /HDiv.hDiv.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HDiv α β γ] : α → β → γ`a / b` computes the result of dividing `a` by `b`.
    The meaning of this notation is type-dependent.
    * For most types like `Nat`, `Int`, `Rat`, `Real`, `a / 0` is defined to be `0`.
    * For `Nat`, `a / b` rounds downwards.
    * For `Int`, `a / b` rounds downwards if `b` is positive or upwards if `b` is negative.
      It is implemented as `Int.ediv`, the unique function satisfying
      `a % b + b * (a / b) = a` and `0 ≤ a % b < natAbs b` for `b ≠ 0`.
      Other rounding conventions are available using the functions
      `Int.fdiv` (floor rounding) and `Int.tdiv` (truncation rounding).
    * For `Float`, `a / 0` follows the IEEE 754 semantics for division,
      usually resulting in `inf` or `nan`. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `/` in identifiers is `div`. z)Function.comp.{u, v, w} {α : Sort u} {β : Sort v} {δ : Sort w} (f : β → δ) (g : α → β) : α → δFunction composition, usually written with the infix operator `∘`. A new function is created from
    two existing functions, where one function's output is used as input to the other.
    
    Examples:
     * `Function.comp List.reverse (List.drop 2) [3, 2, 4, 1] = [1, 4]`
     * `(List.reverse ∘ List.drop 2) [3, 2, 4, 1] = [1, 4]`
    
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `∘` in identifiers is `comp`.
        (HSMul.hSMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HSMul α β γ] : α → β → γ`a • b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent, but it is intended to be used for left actions. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `•` in identifiers is `smul`.(csqrtcsqrt : ℂ → ℂ Complex.IComplex.I : ℂThe imaginary unit. )⁻¹Inv.inv.{u} {α : Type u} [self : Inv α] : α → α`a⁻¹` computes the inverse of `a`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `⁻¹` in identifiers is `inv`. HSMul.hSMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HSMul α β γ] : α → β → γ`a • b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent, but it is intended to be used for left actions. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `•` in identifiers is `smul`. (HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`.csqrtcsqrt : ℂ → ℂ *HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`. ModularForm.etaModularForm.eta (z : ℂ) : ℂThe eta function, whose value at z is `q^ 1 / 24 * ∏' 1 - q ^ (n + 1)` for `q = e ^ 2 π i z`. )HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`.)HSMul.hSMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HSMul α β γ] : α → β → γ`a • b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent, but it is intended to be used for left actions. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `•` in identifiers is `smul`. {setOf.{u} {α : Type u} (p : α → Prop) : Set αTurn a predicate `p : α → Prop` into a set, also written as `{x | p x}` z |setOf.{u} {α : Type u} (p : α → Prop) : Set αTurn a predicate `p : α → Prop` into a set, also written as `{x | p x}`  0 <LT.lt.{u} {α : Type u} [self : LT α] : α → α → PropThe less-than relation: `x < y` 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `<` in identifiers is `lt`. z.imComplex.im (self : ℂ) : ℝThe imaginary part of a complex number. }setOf.{u} {α : Type u} (p : α → Prop) : Set αTurn a predicate `p : α → Prop` into a set, also written as `{x | p x}` 
    theorem eta_equality :
      Set.EqOnSet.EqOn.{u, v} {α : Type u} {β : Type v} (f₁ f₂ : α → β) (s : Set α) : PropTwo functions `f₁ f₂ : α → β` are equal on `s` if `f₁ x = f₂ x` for all `x ∈ s`. 
        (Function.comp.{u, v, w} {α : Sort u} {β : Sort v} {δ : Sort w} (f : β → δ) (g : α → β) : α → δFunction composition, usually written with the infix operator `∘`. A new function is created from
    two existing functions, where one function's output is used as input to the other.
    
    Examples:
     * `Function.comp List.reverse (List.drop 2) [3, 2, 4, 1] = [1, 4]`
     * `(List.reverse ∘ List.drop 2) [3, 2, 4, 1] = [1, 4]`
    
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `∘` in identifiers is `comp`.ModularForm.etaModularForm.eta (z : ℂ) : ℂThe eta function, whose value at z is `q^ 1 / 24 * ∏' 1 - q ^ (n + 1)` for `q = e ^ 2 π i z`.  Function.comp.{u, v, w} {α : Sort u} {β : Sort v} {δ : Sort w} (f : β → δ) (g : α → β) : α → δFunction composition, usually written with the infix operator `∘`. A new function is created from
    two existing functions, where one function's output is used as input to the other.
    
    Examples:
     * `Function.comp List.reverse (List.drop 2) [3, 2, 4, 1] = [1, 4]`
     * `(List.reverse ∘ List.drop 2) [3, 2, 4, 1] = [1, 4]`
    
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `∘` in identifiers is `comp`. fun z  -1 /HDiv.hDiv.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HDiv α β γ] : α → β → γ`a / b` computes the result of dividing `a` by `b`.
    The meaning of this notation is type-dependent.
    * For most types like `Nat`, `Int`, `Rat`, `Real`, `a / 0` is defined to be `0`.
    * For `Nat`, `a / b` rounds downwards.
    * For `Int`, `a / b` rounds downwards if `b` is positive or upwards if `b` is negative.
      It is implemented as `Int.ediv`, the unique function satisfying
      `a % b + b * (a / b) = a` and `0 ≤ a % b < natAbs b` for `b ≠ 0`.
      Other rounding conventions are available using the functions
      `Int.fdiv` (floor rounding) and `Int.tdiv` (truncation rounding).
    * For `Float`, `a / 0` follows the IEEE 754 semantics for division,
      usually resulting in `inf` or `nan`. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `/` in identifiers is `div`. z)Function.comp.{u, v, w} {α : Sort u} {β : Sort v} {δ : Sort w} (f : β → δ) (g : α → β) : α → δFunction composition, usually written with the infix operator `∘`. A new function is created from
    two existing functions, where one function's output is used as input to the other.
    
    Examples:
     * `Function.comp List.reverse (List.drop 2) [3, 2, 4, 1] = [1, 4]`
     * `(List.reverse ∘ List.drop 2) [3, 2, 4, 1] = [1, 4]`
    
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `∘` in identifiers is `comp`.
        (HSMul.hSMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HSMul α β γ] : α → β → γ`a • b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent, but it is intended to be used for left actions. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `•` in identifiers is `smul`.(csqrtcsqrt : ℂ → ℂ Complex.IComplex.I : ℂThe imaginary unit. )⁻¹Inv.inv.{u} {α : Type u} [self : Inv α] : α → α`a⁻¹` computes the inverse of `a`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `⁻¹` in identifiers is `inv`. HSMul.hSMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HSMul α β γ] : α → β → γ`a • b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent, but it is intended to be used for left actions. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `•` in identifiers is `smul`.
          (HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`.csqrtcsqrt : ℂ → ℂ *HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`. ModularForm.etaModularForm.eta (z : ℂ) : ℂThe eta function, whose value at z is `q^ 1 / 24 * ∏' 1 - q ^ (n + 1)` for `q = e ^ 2 π i z`. )HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`.)HSMul.hSMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HSMul α β γ] : α → β → γ`a • b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent, but it is intended to be used for left actions. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `•` in identifiers is `smul`.
        {setOf.{u} {α : Type u} (p : α → Prop) : Set αTurn a predicate `p : α → Prop` into a set, also written as `{x | p x}` z |setOf.{u} {α : Type u} (p : α → Prop) : Set αTurn a predicate `p : α → Prop` into a set, also written as `{x | p x}`  0 <LT.lt.{u} {α : Type u} [self : LT α] : α → α → PropThe less-than relation: `x < y` 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `<` in identifiers is `lt`. z.imComplex.im (self : ℂ) : ℝThe imaginary part of a complex number. }setOf.{u} {α : Type u} (p : α → Prop) : Set αTurn a predicate `p : α → Prop` into a set, also written as `{x | p x}` 
    complete
Proof

Consider the logarithmic derivative of \eta, which is equal to \frac{\pi i}{12} E_2. The result then follows from the transformation of E_2. See Diamond and Shurman (2005), Proposition 1.2.5.

Lean code for Definition7.221 definition
  • def Δ (zUpperHalfPlane : UpperHalfPlaneUpperHalfPlane : TypeThe open upper half plane, denoted as `ℍ` within the `UpperHalfPlane` namespace ) : Complex : TypeComplex numbers consist of two `Real`s: a real part `re` and an imaginary part `im`. 
    def Δ (zUpperHalfPlane : UpperHalfPlaneUpperHalfPlane : TypeThe open upper half plane, denoted as `ℍ` within the `UpperHalfPlane` namespace ) : Complex : TypeComplex numbers consist of two `Real`s: a real part `re` and an imaginary part `im`. 
    complete

\Delta(z) \in M_{12}(\Gamma_1). Especially, \Delta\left(-\frac{1}{z}\right) = z^{12} \Delta(z). Also, it vanishes at the unique cusp, i.e. it is a cusp form of level \Gamma_1 and weight 12. Uses Definition 7.22 and Lemma 7.21.

Lean code for Lemma7.231 definition
  • def Delta :
      CuspFormCuspForm (Γ : Subgroup (GL (Fin 2) ℝ)) (k : ℤ) : TypeThese are `SlashInvariantForm`s that are holomorphic and zero at infinity. 
        (Subgroup.mapSubgroup.map.{u_1, u_5} {G : Type u_1} [Group G] {N : Type u_5} [Group N] (f : G →* N) (H : Subgroup G) : Subgroup NThe image of a subgroup along a monoid homomorphism is a subgroup.  (Matrix.SpecialLinearGroup.mapGLMatrix.SpecialLinearGroup.mapGL.{u, v, u_1} {n : Type u} [DecidableEq n] [Fintype n] {R : Type v} [CommRing R]
      (S : Type u_1) [CommRing S] [Algebra R S] : Matrix.SpecialLinearGroup n R →* GL n S`mapGL` is the map from the special linear group over `R` to the general linear group over
    `S`, where `S` is an `R`-algebra.  Real : TypeThe type `ℝ` of real numbers constructed as equivalence classes of Cauchy sequences of rational
    numbers. )
          (CongruenceSubgroup.GammaCongruenceSubgroup.Gamma (N : ℕ) : Subgroup (Matrix.SpecialLinearGroup (Fin 2) ℤ)The full level `N` congruence subgroup of `SL(2, ℤ)` of matrices that reduce to the identity
    modulo `N`.  1))
        12
    def Delta :
      CuspFormCuspForm (Γ : Subgroup (GL (Fin 2) ℝ)) (k : ℤ) : TypeThese are `SlashInvariantForm`s that are holomorphic and zero at infinity. 
        (Subgroup.mapSubgroup.map.{u_1, u_5} {G : Type u_1} [Group G] {N : Type u_5} [Group N] (f : G →* N) (H : Subgroup G) : Subgroup NThe image of a subgroup along a monoid homomorphism is a subgroup. 
          (Matrix.SpecialLinearGroup.mapGLMatrix.SpecialLinearGroup.mapGL.{u, v, u_1} {n : Type u} [DecidableEq n] [Fintype n] {R : Type v} [CommRing R]
      (S : Type u_1) [CommRing S] [Algebra R S] : Matrix.SpecialLinearGroup n R →* GL n S`mapGL` is the map from the special linear group over `R` to the general linear group over
    `S`, where `S` is an `R`-algebra.  Real : TypeThe type `ℝ` of real numbers constructed as equivalence classes of Cauchy sequences of rational
    numbers. )
          (CongruenceSubgroup.GammaCongruenceSubgroup.Gamma (N : ℕ) : Subgroup (Matrix.SpecialLinearGroup (Fin 2) ℤ)The full level `N` congruence subgroup of `SL(2, ℤ)` of matrices that reduce to the identity
    modulo `N`.  1))
        12
    complete
Proof

The fact that it is invariant under translation is clear from the definition, so we only need to check transformation under S. Now, note that \eta^{24} = \Delta, and from Lemma 7.21 we have \eta(-1/z) = \sqrt{-iz} \eta(z), so \Delta(-1/z) = z^{12} \Delta(z) as required.

Lean code for Lemma7.241 theorem
  • theorem Delta_E4_eqn : DeltaDelta : CuspForm (Subgroup.map (Matrix.SpecialLinearGroup.mapGL ℝ) (CongruenceSubgroup.Gamma 1)) 12 =Eq.{u_1} {α : Sort u_1} : α → α → PropThe equality relation. It has one introduction rule, `Eq.refl`.
    We use `a = b` as notation for `Eq a b`.
    A fundamental property of equality is that it is an equivalence relation.
    ```
    variable (α : Type) (a b c d : α)
    variable (hab : a = b) (hcb : c = b) (hcd : c = d)
    
    example : a = d :=
      Eq.trans (Eq.trans hab (Eq.symm hcb)) hcd
    ```
    Equality is much more than an equivalence relation, however. It has the important property that every assertion
    respects the equivalence, in the sense that we can substitute equal expressions without changing the truth value.
    That is, given `h1 : a = b` and `h2 : p a`, we can construct a proof for `p b` using substitution: `Eq.subst h1 h2`.
    Example:
    ```
    example (α : Type) (a b : α) (p : α → Prop)
            (h1 : a = b) (h2 : p a) : p b :=
      Eq.subst h1 h2
    
    example (α : Type) (a b : α) (p : α → Prop)
        (h1 : a = b) (h2 : p a) : p b :=
      h1 ▸ h2
    ```
    The triangle in the second presentation is a macro built on top of `Eq.subst` and `Eq.symm`, and you can enter it by typing `\t`.
    For more information: [Equality](https://lean-lang.org/theorem_proving_in_lean4/quantifiers_and_equality.html#equality)
    
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `=` in identifiers is `eq`. Delta_E4_E6_auxDelta_E4_E6_aux : CuspForm (Subgroup.map (Matrix.SpecialLinearGroup.mapGL ℝ) (CongruenceSubgroup.Gamma 1)) 12
    theorem Delta_E4_eqn : DeltaDelta : CuspForm (Subgroup.map (Matrix.SpecialLinearGroup.mapGL ℝ) (CongruenceSubgroup.Gamma 1)) 12 =Eq.{u_1} {α : Sort u_1} : α → α → PropThe equality relation. It has one introduction rule, `Eq.refl`.
    We use `a = b` as notation for `Eq a b`.
    A fundamental property of equality is that it is an equivalence relation.
    ```
    variable (α : Type) (a b c d : α)
    variable (hab : a = b) (hcb : c = b) (hcd : c = d)
    
    example : a = d :=
      Eq.trans (Eq.trans hab (Eq.symm hcb)) hcd
    ```
    Equality is much more than an equivalence relation, however. It has the important property that every assertion
    respects the equivalence, in the sense that we can substitute equal expressions without changing the truth value.
    That is, given `h1 : a = b` and `h2 : p a`, we can construct a proof for `p b` using substitution: `Eq.subst h1 h2`.
    Example:
    ```
    example (α : Type) (a b : α) (p : α → Prop)
            (h1 : a = b) (h2 : p a) : p b :=
      Eq.subst h1 h2
    
    example (α : Type) (a b : α) (p : α → Prop)
        (h1 : a = b) (h2 : p a) : p b :=
      h1 ▸ h2
    ```
    The triangle in the second presentation is a macro built on top of `Eq.subst` and `Eq.symm`, and you can enter it by typing `\t`.
    For more information: [Equality](https://lean-lang.org/theorem_proving_in_lean4/quantifiers_and_equality.html#equality)
    
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `=` in identifiers is `eq`. Delta_E4_E6_auxDelta_E4_E6_aux : CuspForm (Subgroup.map (Matrix.SpecialLinearGroup.mapGL ℝ) (CongruenceSubgroup.Gamma 1)) 12
    complete
Proof

We only need to show its a cuspform, since once we have this, dividing the rhs by \Delta would give a modular form of weight 0 which is a constant, and so we can determine the constant easily. /- source paragraph break -/ To check its a cuspform, we just look at the q-expansions of E_4 and E_6 and prove directly that the first term vanishes.

Lean code for Corollary7.251 theorem
  • theorem Delta_imag_axis_pos : ResToImagAxis.PosResToImagAxis.Pos (F : UpperHalfPlane → ℂ) : PropFunction $F : \mathbb{H} \to \mathbb{C}$ is real and positive on the imaginary axis.
     ΔΔ (z : UpperHalfPlane) : ℂ
    theorem Delta_imag_axis_pos : ResToImagAxis.PosResToImagAxis.Pos (F : UpperHalfPlane → ℂ) : PropFunction $F : \mathbb{H} \to \mathbb{C}$ is real and positive on the imaginary axis.
     ΔΔ (z : UpperHalfPlane) : ℂ
    complete
Proof

By Definition 7.22, \Delta(it) = e^{-2 \pi t} \prod_{n \ge 1} (1 - e^{-2 \pi n t})^{24} > 0.

Lean code for Corollary7.261 theorem
  • theorem Δ_ne_zero (zUpperHalfPlane : UpperHalfPlaneUpperHalfPlane : TypeThe open upper half plane, denoted as `ℍ` within the `UpperHalfPlane` namespace ) : ΔΔ (z : UpperHalfPlane) : ℂ zUpperHalfPlane Ne.{u} {α : Sort u} (a b : α) : Prop`a ≠ b`, or `Ne a b` is defined as `¬ (a = b)` or `a = b → False`,
    and asserts that `a` and `b` are not equal.
    
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `≠` in identifiers is `ne`. 0
    theorem Δ_ne_zero (zUpperHalfPlane : UpperHalfPlaneUpperHalfPlane : TypeThe open upper half plane, denoted as `ℍ` within the `UpperHalfPlane` namespace ) : ΔΔ (z : UpperHalfPlane) : ℂ zUpperHalfPlane Ne.{u} {α : Sort u} (a b : α) : Prop`a ≠ b`, or `Ne a b` is defined as `¬ (a = b)` or `a = b → False`,
    and asserts that `a` and `b` are not equal.
    
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `≠` in identifiers is `ne`. 0
    complete
Proof

This follows from the product formula.

Lean code for Theorem7.272 theorems
  • theorem ModularFormClass.levelOne_neg_weight_eq_zero.{u_1} {FType u_1 : Type u_1A type universe. `Type ≡ Type 0`, `Type u ≡ Sort (u + 1)`. }
      [FunLikeFunLike.{u_1, u_2, u_3} (F : Sort u_1) (α : Sort u_2) (β : Sort u_3) : Sort (max (max (max 1 u_1) u_2) u_3)The class `FunLike F α β` (`Fun`ction-`Like`) expresses that terms of type `F`
    have an injective coercion to functions from `α` to `β`.
    `FunLike` is the non-dependent version of `DFunLike`.
    This typeclass is used in the definition of the homomorphism typeclasses,
    such as `ZeroHomClass`, `MulHomClass`, `MonoidHomClass`, ....
     FType u_1 UpperHalfPlaneUpperHalfPlane : TypeThe open upper half plane, denoted as `ℍ` within the `UpperHalfPlane` namespace  Complex : TypeComplex numbers consist of two `Real`s: a real part `re` and an imaginary part `im`. ] {k : Int : TypeThe integers.
    
    This type is special-cased by the compiler and overridden with an efficient implementation. The
    runtime has a special representation for `Int` that stores “small” signed numbers directly, while
    larger numbers use a fast arbitrary-precision arithmetic library (usually
    [GMP](https://gmplib.org/)). A “small number” is an integer that can be encoded with one fewer bits
    than the platform's pointer size (i.e. 63 bits on 64-bit architectures and 31 bits on 32-bit
    architectures).
    }
      [ModularFormClassModularFormClass.{u_2} (F : Type u_2) (Γ : outParam (Subgroup (GL (Fin 2) ℝ))) (k : outParam ℤ)
      [FunLike F UpperHalfPlane ℂ] : Prop`ModularFormClass F Γ k` says that `F` is a type of bundled functions that extend
    `SlashInvariantFormClass` by requiring that the functions be holomorphic and bounded
    at all cusps.  FType u_1
          (Subgroup.mapSubgroup.map.{u_1, u_5} {G : Type u_1} [Group G] {N : Type u_5} [Group N] (f : G →* N) (H : Subgroup G) : Subgroup NThe image of a subgroup along a monoid homomorphism is a subgroup.  (Matrix.SpecialLinearGroup.mapGLMatrix.SpecialLinearGroup.mapGL.{u, v, u_1} {n : Type u} [DecidableEq n] [Fintype n] {R : Type v} [CommRing R]
      (S : Type u_1) [CommRing S] [Algebra R S] : Matrix.SpecialLinearGroup n R →* GL n S`mapGL` is the map from the special linear group over `R` to the general linear group over
    `S`, where `S` is an `R`-algebra.  Real : TypeThe type `ℝ` of real numbers constructed as equivalence classes of Cauchy sequences of rational
    numbers. )
            (CongruenceSubgroup.GammaCongruenceSubgroup.Gamma (N : ℕ) : Subgroup (Matrix.SpecialLinearGroup (Fin 2) ℤ)The full level `N` congruence subgroup of `SL(2, ℤ)` of matrices that reduce to the identity
    modulo `N`.  1))
          k]
      (hkk < 0 : k <LT.lt.{u} {α : Type u} [self : LT α] : α → α → PropThe less-than relation: `x < y` 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `<` in identifiers is `lt`. 0) (fF : FType u_1) : fF =Eq.{u_1} {α : Sort u_1} : α → α → PropThe equality relation. It has one introduction rule, `Eq.refl`.
    We use `a = b` as notation for `Eq a b`.
    A fundamental property of equality is that it is an equivalence relation.
    ```
    variable (α : Type) (a b c d : α)
    variable (hab : a = b) (hcb : c = b) (hcd : c = d)
    
    example : a = d :=
      Eq.trans (Eq.trans hab (Eq.symm hcb)) hcd
    ```
    Equality is much more than an equivalence relation, however. It has the important property that every assertion
    respects the equivalence, in the sense that we can substitute equal expressions without changing the truth value.
    That is, given `h1 : a = b` and `h2 : p a`, we can construct a proof for `p b` using substitution: `Eq.subst h1 h2`.
    Example:
    ```
    example (α : Type) (a b : α) (p : α → Prop)
            (h1 : a = b) (h2 : p a) : p b :=
      Eq.subst h1 h2
    
    example (α : Type) (a b : α) (p : α → Prop)
        (h1 : a = b) (h2 : p a) : p b :=
      h1 ▸ h2
    ```
    The triangle in the second presentation is a macro built on top of `Eq.subst` and `Eq.symm`, and you can enter it by typing `\t`.
    For more information: [Equality](https://lean-lang.org/theorem_proving_in_lean4/quantifiers_and_equality.html#equality)
    
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `=` in identifiers is `eq`. 0
    theorem ModularFormClass.levelOne_neg_weight_eq_zero.{u_1}
      {FType u_1 : Type u_1A type universe. `Type ≡ Type 0`, `Type u ≡ Sort (u + 1)`. }
      [FunLikeFunLike.{u_1, u_2, u_3} (F : Sort u_1) (α : Sort u_2) (β : Sort u_3) : Sort (max (max (max 1 u_1) u_2) u_3)The class `FunLike F α β` (`Fun`ction-`Like`) expresses that terms of type `F`
    have an injective coercion to functions from `α` to `β`.
    `FunLike` is the non-dependent version of `DFunLike`.
    This typeclass is used in the definition of the homomorphism typeclasses,
    such as `ZeroHomClass`, `MulHomClass`, `MonoidHomClass`, ....
     FType u_1 UpperHalfPlaneUpperHalfPlane : TypeThe open upper half plane, denoted as `ℍ` within the `UpperHalfPlane` namespace  Complex : TypeComplex numbers consist of two `Real`s: a real part `re` and an imaginary part `im`. ] {k : Int : TypeThe integers.
    
    This type is special-cased by the compiler and overridden with an efficient implementation. The
    runtime has a special representation for `Int` that stores “small” signed numbers directly, while
    larger numbers use a fast arbitrary-precision arithmetic library (usually
    [GMP](https://gmplib.org/)). A “small number” is an integer that can be encoded with one fewer bits
    than the platform's pointer size (i.e. 63 bits on 64-bit architectures and 31 bits on 32-bit
    architectures).
    }
      [ModularFormClassModularFormClass.{u_2} (F : Type u_2) (Γ : outParam (Subgroup (GL (Fin 2) ℝ))) (k : outParam ℤ)
      [FunLike F UpperHalfPlane ℂ] : Prop`ModularFormClass F Γ k` says that `F` is a type of bundled functions that extend
    `SlashInvariantFormClass` by requiring that the functions be holomorphic and bounded
    at all cusps.  FType u_1
          (Subgroup.mapSubgroup.map.{u_1, u_5} {G : Type u_1} [Group G] {N : Type u_5} [Group N] (f : G →* N) (H : Subgroup G) : Subgroup NThe image of a subgroup along a monoid homomorphism is a subgroup. 
            (Matrix.SpecialLinearGroup.mapGLMatrix.SpecialLinearGroup.mapGL.{u, v, u_1} {n : Type u} [DecidableEq n] [Fintype n] {R : Type v} [CommRing R]
      (S : Type u_1) [CommRing S] [Algebra R S] : Matrix.SpecialLinearGroup n R →* GL n S`mapGL` is the map from the special linear group over `R` to the general linear group over
    `S`, where `S` is an `R`-algebra. 
              Real : TypeThe type `ℝ` of real numbers constructed as equivalence classes of Cauchy sequences of rational
    numbers. )
            (CongruenceSubgroup.GammaCongruenceSubgroup.Gamma (N : ℕ) : Subgroup (Matrix.SpecialLinearGroup (Fin 2) ℤ)The full level `N` congruence subgroup of `SL(2, ℤ)` of matrices that reduce to the identity
    modulo `N`.  1))
          k]
      (hkk < 0 : k <LT.lt.{u} {α : Type u} [self : LT α] : α → α → PropThe less-than relation: `x < y` 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `<` in identifiers is `lt`. 0) (fF : FType u_1) : fF =Eq.{u_1} {α : Sort u_1} : α → α → PropThe equality relation. It has one introduction rule, `Eq.refl`.
    We use `a = b` as notation for `Eq a b`.
    A fundamental property of equality is that it is an equivalence relation.
    ```
    variable (α : Type) (a b c d : α)
    variable (hab : a = b) (hcb : c = b) (hcd : c = d)
    
    example : a = d :=
      Eq.trans (Eq.trans hab (Eq.symm hcb)) hcd
    ```
    Equality is much more than an equivalence relation, however. It has the important property that every assertion
    respects the equivalence, in the sense that we can substitute equal expressions without changing the truth value.
    That is, given `h1 : a = b` and `h2 : p a`, we can construct a proof for `p b` using substitution: `Eq.subst h1 h2`.
    Example:
    ```
    example (α : Type) (a b : α) (p : α → Prop)
            (h1 : a = b) (h2 : p a) : p b :=
      Eq.subst h1 h2
    
    example (α : Type) (a b : α) (p : α → Prop)
        (h1 : a = b) (h2 : p a) : p b :=
      h1 ▸ h2
    ```
    The triangle in the second presentation is a macro built on top of `Eq.subst` and `Eq.symm`, and you can enter it by typing `\t`.
    For more information: [Equality](https://lean-lang.org/theorem_proving_in_lean4/quantifiers_and_equality.html#equality)
    
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `=` in identifiers is `eq`. 0
    complete
  • theorem ModularForm.levelOne_weight_zero_rank_one :
      Module.rankModule.rank.{u_1, u_2} (R : Type u_1) (M : Type u_2) [Semiring R] [AddCommMonoid M] [Module R M] : Cardinal.{u_2}The rank of a module, defined as a term of type `Cardinal`.
    
    We define this as the supremum of the cardinalities of linearly independent subsets.
    The supremum may not be attained, see https://mathoverflow.net/a/263053.
    
    For a free module over any ring satisfying the strong rank condition
    (e.g. left-Noetherian rings, commutative rings, and in particular division rings and fields),
    this is the same as the dimension of the space (i.e. the cardinality of any basis).
    
    In particular this agrees with the usual notion of the dimension of a vector space.
    
    See also `Module.finrank` for a `ℕ`-valued function which returns the correct value
    for a finite-dimensional vector space (but 0 for an infinite-dimensional vector space).
    
    
    [Stacks Tag 09G3](https://stacks.math.columbia.edu/tag/09G3) (first part) Complex : TypeComplex numbers consist of two `Real`s: a real part `re` and an imaginary part `im`. 
          (ModularFormModularForm (Γ : Subgroup (GL (Fin 2) ℝ)) (k : ℤ) : TypeThese are `SlashInvariantForm`'s that are holomorphic and bounded at infinity. 
            (Subgroup.mapSubgroup.map.{u_1, u_5} {G : Type u_1} [Group G] {N : Type u_5} [Group N] (f : G →* N) (H : Subgroup G) : Subgroup NThe image of a subgroup along a monoid homomorphism is a subgroup.  (Matrix.SpecialLinearGroup.mapGLMatrix.SpecialLinearGroup.mapGL.{u, v, u_1} {n : Type u} [DecidableEq n] [Fintype n] {R : Type v} [CommRing R]
      (S : Type u_1) [CommRing S] [Algebra R S] : Matrix.SpecialLinearGroup n R →* GL n S`mapGL` is the map from the special linear group over `R` to the general linear group over
    `S`, where `S` is an `R`-algebra.  Real : TypeThe type `ℝ` of real numbers constructed as equivalence classes of Cauchy sequences of rational
    numbers. )
              (CongruenceSubgroup.GammaCongruenceSubgroup.Gamma (N : ℕ) : Subgroup (Matrix.SpecialLinearGroup (Fin 2) ℤ)The full level `N` congruence subgroup of `SL(2, ℤ)` of matrices that reduce to the identity
    modulo `N`.  1))
            0) =Eq.{u_1} {α : Sort u_1} : α → α → PropThe equality relation. It has one introduction rule, `Eq.refl`.
    We use `a = b` as notation for `Eq a b`.
    A fundamental property of equality is that it is an equivalence relation.
    ```
    variable (α : Type) (a b c d : α)
    variable (hab : a = b) (hcb : c = b) (hcd : c = d)
    
    example : a = d :=
      Eq.trans (Eq.trans hab (Eq.symm hcb)) hcd
    ```
    Equality is much more than an equivalence relation, however. It has the important property that every assertion
    respects the equivalence, in the sense that we can substitute equal expressions without changing the truth value.
    That is, given `h1 : a = b` and `h2 : p a`, we can construct a proof for `p b` using substitution: `Eq.subst h1 h2`.
    Example:
    ```
    example (α : Type) (a b : α) (p : α → Prop)
            (h1 : a = b) (h2 : p a) : p b :=
      Eq.subst h1 h2
    
    example (α : Type) (a b : α) (p : α → Prop)
        (h1 : a = b) (h2 : p a) : p b :=
      h1 ▸ h2
    ```
    The triangle in the second presentation is a macro built on top of `Eq.subst` and `Eq.symm`, and you can enter it by typing `\t`.
    For more information: [Equality](https://lean-lang.org/theorem_proving_in_lean4/quantifiers_and_equality.html#equality)
    
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `=` in identifiers is `eq`.
        1
    theorem ModularForm.levelOne_weight_zero_rank_one :
      Module.rankModule.rank.{u_1, u_2} (R : Type u_1) (M : Type u_2) [Semiring R] [AddCommMonoid M] [Module R M] : Cardinal.{u_2}The rank of a module, defined as a term of type `Cardinal`.
    
    We define this as the supremum of the cardinalities of linearly independent subsets.
    The supremum may not be attained, see https://mathoverflow.net/a/263053.
    
    For a free module over any ring satisfying the strong rank condition
    (e.g. left-Noetherian rings, commutative rings, and in particular division rings and fields),
    this is the same as the dimension of the space (i.e. the cardinality of any basis).
    
    In particular this agrees with the usual notion of the dimension of a vector space.
    
    See also `Module.finrank` for a `ℕ`-valued function which returns the correct value
    for a finite-dimensional vector space (but 0 for an infinite-dimensional vector space).
    
    
    [Stacks Tag 09G3](https://stacks.math.columbia.edu/tag/09G3) (first part) Complex : TypeComplex numbers consist of two `Real`s: a real part `re` and an imaginary part `im`. 
          (ModularFormModularForm (Γ : Subgroup (GL (Fin 2) ℝ)) (k : ℤ) : TypeThese are `SlashInvariantForm`'s that are holomorphic and bounded at infinity. 
            (Subgroup.mapSubgroup.map.{u_1, u_5} {G : Type u_1} [Group G] {N : Type u_5} [Group N] (f : G →* N) (H : Subgroup G) : Subgroup NThe image of a subgroup along a monoid homomorphism is a subgroup. 
              (Matrix.SpecialLinearGroup.mapGLMatrix.SpecialLinearGroup.mapGL.{u, v, u_1} {n : Type u} [DecidableEq n] [Fintype n] {R : Type v} [CommRing R]
      (S : Type u_1) [CommRing S] [Algebra R S] : Matrix.SpecialLinearGroup n R →* GL n S`mapGL` is the map from the special linear group over `R` to the general linear group over
    `S`, where `S` is an `R`-algebra. 
                Real : TypeThe type `ℝ` of real numbers constructed as equivalence classes of Cauchy sequences of rational
    numbers. )
              (CongruenceSubgroup.GammaCongruenceSubgroup.Gamma (N : ℕ) : Subgroup (Matrix.SpecialLinearGroup (Fin 2) ℤ)The full level `N` congruence subgroup of `SL(2, ℤ)` of matrices that reduce to the identity
    modulo `N`.  1))
            0) =Eq.{u_1} {α : Sort u_1} : α → α → PropThe equality relation. It has one introduction rule, `Eq.refl`.
    We use `a = b` as notation for `Eq a b`.
    A fundamental property of equality is that it is an equivalence relation.
    ```
    variable (α : Type) (a b c d : α)
    variable (hab : a = b) (hcb : c = b) (hcd : c = d)
    
    example : a = d :=
      Eq.trans (Eq.trans hab (Eq.symm hcb)) hcd
    ```
    Equality is much more than an equivalence relation, however. It has the important property that every assertion
    respects the equivalence, in the sense that we can substitute equal expressions without changing the truth value.
    That is, given `h1 : a = b` and `h2 : p a`, we can construct a proof for `p b` using substitution: `Eq.subst h1 h2`.
    Example:
    ```
    example (α : Type) (a b : α) (p : α → Prop)
            (h1 : a = b) (h2 : p a) : p b :=
      Eq.subst h1 h2
    
    example (α : Type) (a b : α) (p : α → Prop)
        (h1 : a = b) (h2 : p a) : p b :=
      h1 ▸ h2
    ```
    The triangle in the second presentation is a macro built on top of `Eq.subst` and `Eq.symm`, and you can enter it by typing `\t`.
    For more information: [Equality](https://lean-lang.org/theorem_proving_in_lean4/quantifiers_and_equality.html#equality)
    
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `=` in identifiers is `eq`.
        1
    complete
Proof

The proof makes use of the maximum modulus principle. Since this is already formalized, we skip the details here, but see the Lean proof for them.

Let k \in \Z with k \ge 0 and even. Then \dim M_k(\Gamma_1) = \lfloor k / 12 \rfloor if k \equiv 2 \mod 12, and \dim M_k(\Gamma_1) = \lfloor k / 12 \rfloor + 1 if k \not\equiv 2 \mod 12. Uses Definition 7.12, Lemma 7.24, and Definition 7.22.

Lean code for Theorem7.281 theorem
  • theorem ModularForm.dimension_level_one (k : Nat : TypeThe natural numbers, starting at zero.
    
    This type is special-cased by both the kernel and the compiler, and overridden with an efficient
    implementation. Both use a fast arbitrary-precision arithmetic library (usually
    [GMP](https://gmplib.org/)); at runtime, `Nat` values that are sufficiently small are unboxed.
    ) (hk3 ≤ ↑k : 3 LE.le.{u} {α : Type u} [self : LE α] : α → α → PropThe less-equal relation: `x ≤ y` 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `≤` in identifiers is `le`.
    
     * The recommended spelling of `<=` in identifiers is `le` (prefer `≤` over `<=`). k) (hk2Even k : EvenEven.{u_2} {α : Type u_2} [Add α] (a : α) : PropAn element `a` of a type `α` with addition satisfies `Even a` if `a = r + r`,
    for some `r : α`.  k) :
      Module.rankModule.rank.{u_1, u_2} (R : Type u_1) (M : Type u_2) [Semiring R] [AddCommMonoid M] [Module R M] : Cardinal.{u_2}The rank of a module, defined as a term of type `Cardinal`.
    
    We define this as the supremum of the cardinalities of linearly independent subsets.
    The supremum may not be attained, see https://mathoverflow.net/a/263053.
    
    For a free module over any ring satisfying the strong rank condition
    (e.g. left-Noetherian rings, commutative rings, and in particular division rings and fields),
    this is the same as the dimension of the space (i.e. the cardinality of any basis).
    
    In particular this agrees with the usual notion of the dimension of a vector space.
    
    See also `Module.finrank` for a `ℕ`-valued function which returns the correct value
    for a finite-dimensional vector space (but 0 for an infinite-dimensional vector space).
    
    
    [Stacks Tag 09G3](https://stacks.math.columbia.edu/tag/09G3) (first part) Complex : TypeComplex numbers consist of two `Real`s: a real part `re` and an imaginary part `im`. 
          (ModularFormModularForm (Γ : Subgroup (GL (Fin 2) ℝ)) (k : ℤ) : TypeThese are `SlashInvariantForm`'s that are holomorphic and bounded at infinity. 
            (Subgroup.mapSubgroup.map.{u_1, u_5} {G : Type u_1} [Group G] {N : Type u_5} [Group N] (f : G →* N) (H : Subgroup G) : Subgroup NThe image of a subgroup along a monoid homomorphism is a subgroup.  (Matrix.SpecialLinearGroup.mapGLMatrix.SpecialLinearGroup.mapGL.{u, v, u_1} {n : Type u} [DecidableEq n] [Fintype n] {R : Type v} [CommRing R]
      (S : Type u_1) [CommRing S] [Algebra R S] : Matrix.SpecialLinearGroup n R →* GL n S`mapGL` is the map from the special linear group over `R` to the general linear group over
    `S`, where `S` is an `R`-algebra.  Real : TypeThe type `ℝ` of real numbers constructed as equivalence classes of Cauchy sequences of rational
    numbers. )
              (CongruenceSubgroup.GammaCongruenceSubgroup.Gamma (N : ℕ) : Subgroup (Matrix.SpecialLinearGroup (Fin 2) ℤ)The full level `N` congruence subgroup of `SL(2, ℤ)` of matrices that reduce to the identity
    modulo `N`.  1))
            k) =Eq.{u_1} {α : Sort u_1} : α → α → PropThe equality relation. It has one introduction rule, `Eq.refl`.
    We use `a = b` as notation for `Eq a b`.
    A fundamental property of equality is that it is an equivalence relation.
    ```
    variable (α : Type) (a b c d : α)
    variable (hab : a = b) (hcb : c = b) (hcd : c = d)
    
    example : a = d :=
      Eq.trans (Eq.trans hab (Eq.symm hcb)) hcd
    ```
    Equality is much more than an equivalence relation, however. It has the important property that every assertion
    respects the equivalence, in the sense that we can substitute equal expressions without changing the truth value.
    That is, given `h1 : a = b` and `h2 : p a`, we can construct a proof for `p b` using substitution: `Eq.subst h1 h2`.
    Example:
    ```
    example (α : Type) (a b : α) (p : α → Prop)
            (h1 : a = b) (h2 : p a) : p b :=
      Eq.subst h1 h2
    
    example (α : Type) (a b : α) (p : α → Prop)
        (h1 : a = b) (h2 : p a) : p b :=
      h1 ▸ h2
    ```
    The triangle in the second presentation is a macro built on top of `Eq.subst` and `Eq.symm`, and you can enter it by typing `\t`.
    For more information: [Equality](https://lean-lang.org/theorem_proving_in_lean4/quantifiers_and_equality.html#equality)
    
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `=` in identifiers is `eq`.
        (ite.{u} {α : Sort u} (c : Prop) [h : Decidable c] (t e : α) : α`if c then t else e` is notation for `ite c t e`, "if-then-else", which decides to
    return `t` or `e` depending on whether `c` is true or false. The explicit argument
    `c : Prop` does not have any actual computational content, but there is an additional
    `[Decidable c]` argument synthesized by typeclass inference which actually
    determines how to evaluate `c` to true or false. Write `if h : c then t else e`
    instead for a "dependent if-then-else" `dite`, which allows `t`/`e` to use the fact
    that `c` is true/false.
    ifite.{u} {α : Sort u} (c : Prop) [h : Decidable c] (t e : α) : α`if c then t else e` is notation for `ite c t e`, "if-then-else", which decides to
    return `t` or `e` depending on whether `c` is true or false. The explicit argument
    `c : Prop` does not have any actual computational content, but there is an additional
    `[Decidable c]` argument synthesized by typeclass inference which actually
    determines how to evaluate `c` to true or false. Write `if h : c then t else e`
    instead for a "dependent if-then-else" `dite`, which allows `t`/`e` to use the fact
    that `c` is true/false.
     12 Dvd.dvd.{u_1} {α : Type u_1} [self : Dvd α] : α → α → PropDivisibility. `a ∣ b` (typed as `\|`) means that there is some `c` such that `b = a * c`. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `∣` in identifiers is `dvd`. k -HSub.hSub.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HSub α β γ] : α → β → γ`a - b` computes the difference of `a` and `b`.
    The meaning of this notation is type-dependent.
    * For natural numbers, this operator saturates at 0: `a - b = 0` when `a ≤ b`. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `-` in identifiers is `sub` (when used as a binary operator). 2 thenite.{u} {α : Sort u} (c : Prop) [h : Decidable c] (t e : α) : α`if c then t else e` is notation for `ite c t e`, "if-then-else", which decides to
    return `t` or `e` depending on whether `c` is true or false. The explicit argument
    `c : Prop` does not have any actual computational content, but there is an additional
    `[Decidable c]` argument synthesized by typeclass inference which actually
    determines how to evaluate `c` to true or false. Write `if h : c then t else e`
    instead for a "dependent if-then-else" `dite`, which allows `t`/`e` to use the fact
    that `c` is true/false.
     Nat.floor.{u_2} {α : Type u_2} [Semiring α] [PartialOrder α] [FloorSemiring α] : α → ℕ`⌊a⌋₊` is the greatest natural `n` such that `n ≤ a`. If `a` is negative, then `⌊a⌋₊ = 0`. k /HDiv.hDiv.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HDiv α β γ] : α → β → γ`a / b` computes the result of dividing `a` by `b`.
    The meaning of this notation is type-dependent.
    * For most types like `Nat`, `Int`, `Rat`, `Real`, `a / 0` is defined to be `0`.
    * For `Nat`, `a / b` rounds downwards.
    * For `Int`, `a / b` rounds downwards if `b` is positive or upwards if `b` is negative.
      It is implemented as `Int.ediv`, the unique function satisfying
      `a % b + b * (a / b) = a` and `0 ≤ a % b < natAbs b` for `b ≠ 0`.
      Other rounding conventions are available using the functions
      `Int.fdiv` (floor rounding) and `Int.tdiv` (truncation rounding).
    * For `Float`, `a / 0` follows the IEEE 754 semantics for division,
      usually resulting in `inf` or `nan`. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `/` in identifiers is `div`. 12⌋₊Nat.floor.{u_2} {α : Type u_2} [Semiring α] [PartialOrder α] [FloorSemiring α] : α → ℕ`⌊a⌋₊` is the greatest natural `n` such that `n ≤ a`. If `a` is negative, then `⌊a⌋₊ = 0`.  elseite.{u} {α : Sort u} (c : Prop) [h : Decidable c] (t e : α) : α`if c then t else e` is notation for `ite c t e`, "if-then-else", which decides to
    return `t` or `e` depending on whether `c` is true or false. The explicit argument
    `c : Prop` does not have any actual computational content, but there is an additional
    `[Decidable c]` argument synthesized by typeclass inference which actually
    determines how to evaluate `c` to true or false. Write `if h : c then t else e`
    instead for a "dependent if-then-else" `dite`, which allows `t`/`e` to use the fact
    that `c` is true/false.
     Nat.floor.{u_2} {α : Type u_2} [Semiring α] [PartialOrder α] [FloorSemiring α] : α → ℕ`⌊a⌋₊` is the greatest natural `n` such that `n ≤ a`. If `a` is negative, then `⌊a⌋₊ = 0`. k /HDiv.hDiv.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HDiv α β γ] : α → β → γ`a / b` computes the result of dividing `a` by `b`.
    The meaning of this notation is type-dependent.
    * For most types like `Nat`, `Int`, `Rat`, `Real`, `a / 0` is defined to be `0`.
    * For `Nat`, `a / b` rounds downwards.
    * For `Int`, `a / b` rounds downwards if `b` is positive or upwards if `b` is negative.
      It is implemented as `Int.ediv`, the unique function satisfying
      `a % b + b * (a / b) = a` and `0 ≤ a % b < natAbs b` for `b ≠ 0`.
      Other rounding conventions are available using the functions
      `Int.fdiv` (floor rounding) and `Int.tdiv` (truncation rounding).
    * For `Float`, `a / 0` follows the IEEE 754 semantics for division,
      usually resulting in `inf` or `nan`. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `/` in identifiers is `div`. 12⌋₊Nat.floor.{u_2} {α : Type u_2} [Semiring α] [PartialOrder α] [FloorSemiring α] : α → ℕ`⌊a⌋₊` is the greatest natural `n` such that `n ≤ a`. If `a` is negative, then `⌊a⌋₊ = 0`.  +HAdd.hAdd.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HAdd α β γ] : α → β → γ`a + b` computes the sum of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `+` in identifiers is `add`. 1)ite.{u} {α : Sort u} (c : Prop) [h : Decidable c] (t e : α) : α`if c then t else e` is notation for `ite c t e`, "if-then-else", which decides to
    return `t` or `e` depending on whether `c` is true or false. The explicit argument
    `c : Prop` does not have any actual computational content, but there is an additional
    `[Decidable c]` argument synthesized by typeclass inference which actually
    determines how to evaluate `c` to true or false. Write `if h : c then t else e`
    instead for a "dependent if-then-else" `dite`, which allows `t`/`e` to use the fact
    that `c` is true/false.
    
    theorem ModularForm.dimension_level_one (k : Nat : TypeThe natural numbers, starting at zero.
    
    This type is special-cased by both the kernel and the compiler, and overridden with an efficient
    implementation. Both use a fast arbitrary-precision arithmetic library (usually
    [GMP](https://gmplib.org/)); at runtime, `Nat` values that are sufficiently small are unboxed.
    )
      (hk3 ≤ ↑k : 3 LE.le.{u} {α : Type u} [self : LE α] : α → α → PropThe less-equal relation: `x ≤ y` 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `≤` in identifiers is `le`.
    
     * The recommended spelling of `<=` in identifiers is `le` (prefer `≤` over `<=`). k) (hk2Even k : EvenEven.{u_2} {α : Type u_2} [Add α] (a : α) : PropAn element `a` of a type `α` with addition satisfies `Even a` if `a = r + r`,
    for some `r : α`.  k) :
      Module.rankModule.rank.{u_1, u_2} (R : Type u_1) (M : Type u_2) [Semiring R] [AddCommMonoid M] [Module R M] : Cardinal.{u_2}The rank of a module, defined as a term of type `Cardinal`.
    
    We define this as the supremum of the cardinalities of linearly independent subsets.
    The supremum may not be attained, see https://mathoverflow.net/a/263053.
    
    For a free module over any ring satisfying the strong rank condition
    (e.g. left-Noetherian rings, commutative rings, and in particular division rings and fields),
    this is the same as the dimension of the space (i.e. the cardinality of any basis).
    
    In particular this agrees with the usual notion of the dimension of a vector space.
    
    See also `Module.finrank` for a `ℕ`-valued function which returns the correct value
    for a finite-dimensional vector space (but 0 for an infinite-dimensional vector space).
    
    
    [Stacks Tag 09G3](https://stacks.math.columbia.edu/tag/09G3) (first part) Complex : TypeComplex numbers consist of two `Real`s: a real part `re` and an imaginary part `im`. 
          (ModularFormModularForm (Γ : Subgroup (GL (Fin 2) ℝ)) (k : ℤ) : TypeThese are `SlashInvariantForm`'s that are holomorphic and bounded at infinity. 
            (Subgroup.mapSubgroup.map.{u_1, u_5} {G : Type u_1} [Group G] {N : Type u_5} [Group N] (f : G →* N) (H : Subgroup G) : Subgroup NThe image of a subgroup along a monoid homomorphism is a subgroup. 
              (Matrix.SpecialLinearGroup.mapGLMatrix.SpecialLinearGroup.mapGL.{u, v, u_1} {n : Type u} [DecidableEq n] [Fintype n] {R : Type v} [CommRing R]
      (S : Type u_1) [CommRing S] [Algebra R S] : Matrix.SpecialLinearGroup n R →* GL n S`mapGL` is the map from the special linear group over `R` to the general linear group over
    `S`, where `S` is an `R`-algebra. 
                Real : TypeThe type `ℝ` of real numbers constructed as equivalence classes of Cauchy sequences of rational
    numbers. )
              (CongruenceSubgroup.GammaCongruenceSubgroup.Gamma (N : ℕ) : Subgroup (Matrix.SpecialLinearGroup (Fin 2) ℤ)The full level `N` congruence subgroup of `SL(2, ℤ)` of matrices that reduce to the identity
    modulo `N`.  1))
            k) =Eq.{u_1} {α : Sort u_1} : α → α → PropThe equality relation. It has one introduction rule, `Eq.refl`.
    We use `a = b` as notation for `Eq a b`.
    A fundamental property of equality is that it is an equivalence relation.
    ```
    variable (α : Type) (a b c d : α)
    variable (hab : a = b) (hcb : c = b) (hcd : c = d)
    
    example : a = d :=
      Eq.trans (Eq.trans hab (Eq.symm hcb)) hcd
    ```
    Equality is much more than an equivalence relation, however. It has the important property that every assertion
    respects the equivalence, in the sense that we can substitute equal expressions without changing the truth value.
    That is, given `h1 : a = b` and `h2 : p a`, we can construct a proof for `p b` using substitution: `Eq.subst h1 h2`.
    Example:
    ```
    example (α : Type) (a b : α) (p : α → Prop)
            (h1 : a = b) (h2 : p a) : p b :=
      Eq.subst h1 h2
    
    example (α : Type) (a b : α) (p : α → Prop)
        (h1 : a = b) (h2 : p a) : p b :=
      h1 ▸ h2
    ```
    The triangle in the second presentation is a macro built on top of `Eq.subst` and `Eq.symm`, and you can enter it by typing `\t`.
    For more information: [Equality](https://lean-lang.org/theorem_proving_in_lean4/quantifiers_and_equality.html#equality)
    
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `=` in identifiers is `eq`.
        (ite.{u} {α : Sort u} (c : Prop) [h : Decidable c] (t e : α) : α`if c then t else e` is notation for `ite c t e`, "if-then-else", which decides to
    return `t` or `e` depending on whether `c` is true or false. The explicit argument
    `c : Prop` does not have any actual computational content, but there is an additional
    `[Decidable c]` argument synthesized by typeclass inference which actually
    determines how to evaluate `c` to true or false. Write `if h : c then t else e`
    instead for a "dependent if-then-else" `dite`, which allows `t`/`e` to use the fact
    that `c` is true/false.
    ifite.{u} {α : Sort u} (c : Prop) [h : Decidable c] (t e : α) : α`if c then t else e` is notation for `ite c t e`, "if-then-else", which decides to
    return `t` or `e` depending on whether `c` is true or false. The explicit argument
    `c : Prop` does not have any actual computational content, but there is an additional
    `[Decidable c]` argument synthesized by typeclass inference which actually
    determines how to evaluate `c` to true or false. Write `if h : c then t else e`
    instead for a "dependent if-then-else" `dite`, which allows `t`/`e` to use the fact
    that `c` is true/false.
     12 Dvd.dvd.{u_1} {α : Type u_1} [self : Dvd α] : α → α → PropDivisibility. `a ∣ b` (typed as `\|`) means that there is some `c` such that `b = a * c`. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `∣` in identifiers is `dvd`. k -HSub.hSub.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HSub α β γ] : α → β → γ`a - b` computes the difference of `a` and `b`.
    The meaning of this notation is type-dependent.
    * For natural numbers, this operator saturates at 0: `a - b = 0` when `a ≤ b`. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `-` in identifiers is `sub` (when used as a binary operator). 2 thenite.{u} {α : Sort u} (c : Prop) [h : Decidable c] (t e : α) : α`if c then t else e` is notation for `ite c t e`, "if-then-else", which decides to
    return `t` or `e` depending on whether `c` is true or false. The explicit argument
    `c : Prop` does not have any actual computational content, but there is an additional
    `[Decidable c]` argument synthesized by typeclass inference which actually
    determines how to evaluate `c` to true or false. Write `if h : c then t else e`
    instead for a "dependent if-then-else" `dite`, which allows `t`/`e` to use the fact
    that `c` is true/false.
     Nat.floor.{u_2} {α : Type u_2} [Semiring α] [PartialOrder α] [FloorSemiring α] : α → ℕ`⌊a⌋₊` is the greatest natural `n` such that `n ≤ a`. If `a` is negative, then `⌊a⌋₊ = 0`. k /HDiv.hDiv.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HDiv α β γ] : α → β → γ`a / b` computes the result of dividing `a` by `b`.
    The meaning of this notation is type-dependent.
    * For most types like `Nat`, `Int`, `Rat`, `Real`, `a / 0` is defined to be `0`.
    * For `Nat`, `a / b` rounds downwards.
    * For `Int`, `a / b` rounds downwards if `b` is positive or upwards if `b` is negative.
      It is implemented as `Int.ediv`, the unique function satisfying
      `a % b + b * (a / b) = a` and `0 ≤ a % b < natAbs b` for `b ≠ 0`.
      Other rounding conventions are available using the functions
      `Int.fdiv` (floor rounding) and `Int.tdiv` (truncation rounding).
    * For `Float`, `a / 0` follows the IEEE 754 semantics for division,
      usually resulting in `inf` or `nan`. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `/` in identifiers is `div`. 12⌋₊Nat.floor.{u_2} {α : Type u_2} [Semiring α] [PartialOrder α] [FloorSemiring α] : α → ℕ`⌊a⌋₊` is the greatest natural `n` such that `n ≤ a`. If `a` is negative, then `⌊a⌋₊ = 0`. 
          elseite.{u} {α : Sort u} (c : Prop) [h : Decidable c] (t e : α) : α`if c then t else e` is notation for `ite c t e`, "if-then-else", which decides to
    return `t` or `e` depending on whether `c` is true or false. The explicit argument
    `c : Prop` does not have any actual computational content, but there is an additional
    `[Decidable c]` argument synthesized by typeclass inference which actually
    determines how to evaluate `c` to true or false. Write `if h : c then t else e`
    instead for a "dependent if-then-else" `dite`, which allows `t`/`e` to use the fact
    that `c` is true/false.
     Nat.floor.{u_2} {α : Type u_2} [Semiring α] [PartialOrder α] [FloorSemiring α] : α → ℕ`⌊a⌋₊` is the greatest natural `n` such that `n ≤ a`. If `a` is negative, then `⌊a⌋₊ = 0`. k /HDiv.hDiv.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HDiv α β γ] : α → β → γ`a / b` computes the result of dividing `a` by `b`.
    The meaning of this notation is type-dependent.
    * For most types like `Nat`, `Int`, `Rat`, `Real`, `a / 0` is defined to be `0`.
    * For `Nat`, `a / b` rounds downwards.
    * For `Int`, `a / b` rounds downwards if `b` is positive or upwards if `b` is negative.
      It is implemented as `Int.ediv`, the unique function satisfying
      `a % b + b * (a / b) = a` and `0 ≤ a % b < natAbs b` for `b ≠ 0`.
      Other rounding conventions are available using the functions
      `Int.fdiv` (floor rounding) and `Int.tdiv` (truncation rounding).
    * For `Float`, `a / 0` follows the IEEE 754 semantics for division,
      usually resulting in `inf` or `nan`. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `/` in identifiers is `div`. 12⌋₊Nat.floor.{u_2} {α : Type u_2} [Semiring α] [PartialOrder α] [FloorSemiring α] : α → ℕ`⌊a⌋₊` is the greatest natural `n` such that `n ≤ a`. If `a` is negative, then `⌊a⌋₊ = 0`.  +HAdd.hAdd.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HAdd α β γ] : α → β → γ`a + b` computes the sum of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `+` in identifiers is `add`. 1)ite.{u} {α : Sort u} (c : Prop) [h : Decidable c] (t e : α) : α`if c then t else e` is notation for `ite c t e`, "if-then-else", which decides to
    return `t` or `e` depending on whether `c` is true or false. The explicit argument
    `c : Prop` does not have any actual computational content, but there is an additional
    `[Decidable c]` argument synthesized by typeclass inference which actually
    determines how to evaluate `c` to true or false. Write `if h : c then t else e`
    instead for a "dependent if-then-else" `dite`, which allows `t`/`e` to use the fact
    that `c` is true/false.
    
    complete
Proof

First we note that for 2 < k we have \dim(M_k(\Gamma_1)) = 1 + \dim S_k(\Gamma_1). This follows since we know the E_k are in M_k so by scaling appropriately, any non-cuspform f \in M_k we would have f - aE_k \in S_k for some a. /- source paragraph break -/ Next, note that S_k(\Gamma_1) is isomorphic to M_{k-12}(\Gamma_1), since if f \in S_k then f/\Delta is now a modular form (using the product expansion of \Delta and its non-vanishing on \mathfrak{H}) of weight k-12. Note its important that f is a cuspform so that the quotient by \Delta is a modular form. /- source paragraph break -/ So we only need to know the dimensions of M_k(\Gamma_1) for 0 \le k \le 12. For k = 0 we have \dim M_0(\Gamma_1) = 1 by Theorem 7.27. For k = 4 we have \dim M_4(\Gamma_1) = 1 since if there was a cuspform f of weight 4 then f/\Delta would be a modular form of negative weight, i.e. zero, so f=0. Similarly for k=6,8,10. For k=12 we have \dim S_{12}(\Gamma_1) = 1 since the discriminant form is a cusp form of weight 12 and any other cusp form of weight 12 would be a scalar multiple of \Delta (since their ratio would be a modular form of weight 0). So we have \dim M_{12}(\Gamma_1) = 2. /- source paragraph break -/ Finally we need to check that \dim M_2(\Gamma_1) = 0. Firstly, there can't be any cuspforms here by the same argument as above. So we need to check that there are no modular forms of weight 2. If we did have one, call it f then f^2 would be a non-cuspform of weight 4 and so f^2 = a E_4, where in fact a=a_0(f)^2 (since (f^2-a_0(f)E_4) is now a cuspform of weight 4 which means its zero). Similarly, f^3 = a_0(f)^3 E_6. But now taking powers to make them weight 12 forms we see that a_0(f)^6(E_4^3 - E_6^2) = 0 = 1728 a_0(f)^6 \Delta, but a_0(f) \ne 0 (since its assumed to not be a cuspform), this would mean \Delta =0 which we know can't happen.

Lean code for Theorem7.291 theorem, incomplete
  • theorem dim_gen_cong_levels (k : Int : TypeThe integers.
    
    This type is special-cased by the compiler and overridden with an efficient implementation. The
    runtime has a special representation for `Int` that stores “small” signed numbers directly, while
    larger numbers use a fast arbitrary-precision arithmetic library (usually
    [GMP](https://gmplib.org/)). A “small number” is an integer that can be encoded with one fewer bits
    than the platform's pointer size (i.e. 63 bits on 64-bit architectures and 31 bits on 32-bit
    architectures).
    )
      (ΓSubgroup (Matrix.SpecialLinearGroup (Fin 2) ℤ) : SubgroupSubgroup.{u_3} (G : Type u_3) [Group G] : Type u_3A subgroup of a group `G` is a subset containing 1, closed under multiplication
    and closed under multiplicative inverse.  (Matrix.SpecialLinearGroupMatrix.SpecialLinearGroup.{u, v} (n : Type u) [DecidableEq n] [Fintype n] (R : Type v) [CommRing R] : Type (max 0 u v)`SpecialLinearGroup n R` is the group of `n` by `n` `R`-matrices with determinant equal to 1.
     (FinFin (n : ℕ) : TypeNatural numbers less than some upper bound.
    
    In particular, a `Fin n` is a natural number `i` with the constraint that `i < n`. It is the
    canonical type with `n` elements.
     2) Int : TypeThe integers.
    
    This type is special-cased by the compiler and overridden with an efficient implementation. The
    runtime has a special representation for `Int` that stores “small” signed numbers directly, while
    larger numbers use a fast arbitrary-precision arithmetic library (usually
    [GMP](https://gmplib.org/)). A “small number” is an integer that can be encoded with one fewer bits
    than the platform's pointer size (i.e. 63 bits on 64-bit architectures and 31 bits on 32-bit
    architectures).
    ))
      (Γ.index ≠ 0 : ΓSubgroup (Matrix.SpecialLinearGroup (Fin 2) ℤ).indexSubgroup.index.{u_1} {G : Type u_1} [Group G] (H : Subgroup G) : ℕThe index of a subgroup as a natural number. Returns `0` if the index is infinite.  Ne.{u} {α : Sort u} (a b : α) : Prop`a ≠ b`, or `Ne a b` is defined as `¬ (a = b)` or `a = b → False`,
    and asserts that `a` and `b` are not equal.
    
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `≠` in identifiers is `ne`. 0) :
      FiniteDimensionalFiniteDimensional.{u_1, u_2} (K : Type u_1) (V : Type u_2) [DivisionRing K] [AddCommGroup V] [Module K V] : Prop`FiniteDimensional` vector spaces are defined to be finite modules.
    Use `Module.Basis.finiteDimensional_of_finite` to prove finite dimension from another definition.  Complex : TypeComplex numbers consist of two `Real`s: a real part `re` and an imaginary part `im`. 
        (ModularFormModularForm (Γ : Subgroup (GL (Fin 2) ℝ)) (k : ℤ) : TypeThese are `SlashInvariantForm`'s that are holomorphic and bounded at infinity.  (Subgroup.mapSubgroup.map.{u_1, u_5} {G : Type u_1} [Group G] {N : Type u_5} [Group N] (f : G →* N) (H : Subgroup G) : Subgroup NThe image of a subgroup along a monoid homomorphism is a subgroup.  (Matrix.SpecialLinearGroup.mapGLMatrix.SpecialLinearGroup.mapGL.{u, v, u_1} {n : Type u} [DecidableEq n] [Fintype n] {R : Type v} [CommRing R]
      (S : Type u_1) [CommRing S] [Algebra R S] : Matrix.SpecialLinearGroup n R →* GL n S`mapGL` is the map from the special linear group over `R` to the general linear group over
    `S`, where `S` is an `R`-algebra.  Real : TypeThe type `ℝ` of real numbers constructed as equivalence classes of Cauchy sequences of rational
    numbers. ) ΓSubgroup (Matrix.SpecialLinearGroup (Fin 2) ℤ)) k)
    theorem dim_gen_cong_levels (k : Int : TypeThe integers.
    
    This type is special-cased by the compiler and overridden with an efficient implementation. The
    runtime has a special representation for `Int` that stores “small” signed numbers directly, while
    larger numbers use a fast arbitrary-precision arithmetic library (usually
    [GMP](https://gmplib.org/)). A “small number” is an integer that can be encoded with one fewer bits
    than the platform's pointer size (i.e. 63 bits on 64-bit architectures and 31 bits on 32-bit
    architectures).
    )
      (ΓSubgroup (Matrix.SpecialLinearGroup (Fin 2) ℤ) :
        SubgroupSubgroup.{u_3} (G : Type u_3) [Group G] : Type u_3A subgroup of a group `G` is a subset containing 1, closed under multiplication
    and closed under multiplicative inverse. 
          (Matrix.SpecialLinearGroupMatrix.SpecialLinearGroup.{u, v} (n : Type u) [DecidableEq n] [Fintype n] (R : Type v) [CommRing R] : Type (max 0 u v)`SpecialLinearGroup n R` is the group of `n` by `n` `R`-matrices with determinant equal to 1.
     (FinFin (n : ℕ) : TypeNatural numbers less than some upper bound.
    
    In particular, a `Fin n` is a natural number `i` with the constraint that `i < n`. It is the
    canonical type with `n` elements.
     2)
            Int : TypeThe integers.
    
    This type is special-cased by the compiler and overridden with an efficient implementation. The
    runtime has a special representation for `Int` that stores “small” signed numbers directly, while
    larger numbers use a fast arbitrary-precision arithmetic library (usually
    [GMP](https://gmplib.org/)). A “small number” is an integer that can be encoded with one fewer bits
    than the platform's pointer size (i.e. 63 bits on 64-bit architectures and 31 bits on 32-bit
    architectures).
    ))
      (Γ.index ≠ 0 : ΓSubgroup (Matrix.SpecialLinearGroup (Fin 2) ℤ).indexSubgroup.index.{u_1} {G : Type u_1} [Group G] (H : Subgroup G) : ℕThe index of a subgroup as a natural number. Returns `0` if the index is infinite.  Ne.{u} {α : Sort u} (a b : α) : Prop`a ≠ b`, or `Ne a b` is defined as `¬ (a = b)` or `a = b → False`,
    and asserts that `a` and `b` are not equal.
    
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `≠` in identifiers is `ne`. 0) :
      FiniteDimensionalFiniteDimensional.{u_1, u_2} (K : Type u_1) (V : Type u_2) [DivisionRing K] [AddCommGroup V] [Module K V] : Prop`FiniteDimensional` vector spaces are defined to be finite modules.
    Use `Module.Basis.finiteDimensional_of_finite` to prove finite dimension from another definition.  Complex : TypeComplex numbers consist of two `Real`s: a real part `re` and an imaginary part `im`. 
        (ModularFormModularForm (Γ : Subgroup (GL (Fin 2) ℝ)) (k : ℤ) : TypeThese are `SlashInvariantForm`'s that are holomorphic and bounded at infinity. 
          (Subgroup.mapSubgroup.map.{u_1, u_5} {G : Type u_1} [Group G] {N : Type u_5} [Group N] (f : G →* N) (H : Subgroup G) : Subgroup NThe image of a subgroup along a monoid homomorphism is a subgroup. 
            (Matrix.SpecialLinearGroup.mapGLMatrix.SpecialLinearGroup.mapGL.{u, v, u_1} {n : Type u} [DecidableEq n] [Fintype n] {R : Type v} [CommRing R]
      (S : Type u_1) [CommRing S] [Algebra R S] : Matrix.SpecialLinearGroup n R →* GL n S`mapGL` is the map from the special linear group over `R` to the general linear group over
    `S`, where `S` is an `R`-algebra. 
              Real : TypeThe type `ℝ` of real numbers constructed as equivalence classes of Cauchy sequences of rational
    numbers. )
            ΓSubgroup (Matrix.SpecialLinearGroup (Fin 2) ℤ))
          k)
    contains sorry in proof
Proof

We know that \dim(M_k(\Gamma_1)) is finite-dimensional, hence there is some r_k such that any element of M_k(\Gamma_1) vanishing at infinity to degree greater than r_k must be zero. Now take f \in M_k(\Gamma) vanishing to degree n at infinity, and set F = \prod_\gamma f\mid_k \gamma, where the product is over a set of representatives of \Gamma_1 \backslash \Gamma. Then F is a modular form of weight kd where d = [\Gamma_1 : \Gamma], and it vanishes at infinity to degree at least n. So if n > r_{kd}, then F=0, and hence f=0.

We have \dim M_2(\mathrm{SL}_{2}(\mathbb{Z})) = 0 \dim M_4(\mathrm{SL}_{2}(\mathbb{Z})) = \dim M_6(\mathrm{SL}_{2}(\mathbb{Z})) = \dim M_8(\mathrm{SL}_{2}(\mathbb{Z})) = 1 \dim S_4(\mathrm{SL}_{2}(\mathbb{Z})) = \dim S_6(\mathrm{SL}_{2}(\mathbb{Z})) = \dim S_8(\mathrm{SL}_{2}(\mathbb{Z})) = 0. Uses Definition 7.12 and Theorem 7.28.

Proof
Definition7.31
L∃∀N
Used by 2
Hover a use site to preview it.
Preview
Definition 7.32
Loading preview
Hover a use site to preview it.

We define three different theta functions, the "Thetanullwerte", \Theta_2,\Theta_3,\Theta_4, by \Theta_{2}(z) = \theta_{10}(z) = \sum_{n\in\mathbb{Z}}e^{\pi i (n+\frac12)^2 z} \Theta_{3}(z) = \theta_{00}(z) = \sum_{n\in\mathbb{Z}}e^{\pi i n^2 z} \Theta_{4}(z) = \theta_{01}(z) = \sum_{n\in\mathbb{Z}}(-1)^n\,e^{\pi i n^2 z}.

Lean code for Definition7.313 definitions
  • def Θ₂ (τUpperHalfPlane : UpperHalfPlaneUpperHalfPlane : TypeThe open upper half plane, denoted as `ℍ` within the `UpperHalfPlane` namespace ) : Complex : TypeComplex numbers consist of two `Real`s: a real part `re` and an imaginary part `im`. 
    def Θ₂ (τUpperHalfPlane : UpperHalfPlaneUpperHalfPlane : TypeThe open upper half plane, denoted as `ℍ` within the `UpperHalfPlane` namespace ) : Complex : TypeComplex numbers consist of two `Real`s: a real part `re` and an imaginary part `im`. 
    complete
  • def Θ₃ (τUpperHalfPlane : UpperHalfPlaneUpperHalfPlane : TypeThe open upper half plane, denoted as `ℍ` within the `UpperHalfPlane` namespace ) : Complex : TypeComplex numbers consist of two `Real`s: a real part `re` and an imaginary part `im`. 
    def Θ₃ (τUpperHalfPlane : UpperHalfPlaneUpperHalfPlane : TypeThe open upper half plane, denoted as `ℍ` within the `UpperHalfPlane` namespace ) : Complex : TypeComplex numbers consist of two `Real`s: a real part `re` and an imaginary part `im`. 
    complete
  • def Θ₄ (τUpperHalfPlane : UpperHalfPlaneUpperHalfPlane : TypeThe open upper half plane, denoted as `ℍ` within the `UpperHalfPlane` namespace ) : Complex : TypeComplex numbers consist of two `Real`s: a real part `re` and an imaginary part `im`. 
    def Θ₄ (τUpperHalfPlane : UpperHalfPlaneUpperHalfPlane : TypeThe open upper half plane, denoted as `ℍ` within the `UpperHalfPlane` namespace ) : Complex : TypeComplex numbers consist of two `Real`s: a real part `re` and an imaginary part `im`. 
    complete

Define H_2 = \Theta_2^4, H_3 = \Theta_3^4, H_4 = \Theta_4^4. Uses Definition 7.31.

Lean code for Definition7.323 definitions
  • def H₂ (τUpperHalfPlane : UpperHalfPlaneUpperHalfPlane : TypeThe open upper half plane, denoted as `ℍ` within the `UpperHalfPlane` namespace ) : Complex : TypeComplex numbers consist of two `Real`s: a real part `re` and an imaginary part `im`. 
    def H₂ (τUpperHalfPlane : UpperHalfPlaneUpperHalfPlane : TypeThe open upper half plane, denoted as `ℍ` within the `UpperHalfPlane` namespace ) : Complex : TypeComplex numbers consist of two `Real`s: a real part `re` and an imaginary part `im`. 
    complete
  • def H₃ (τUpperHalfPlane : UpperHalfPlaneUpperHalfPlane : TypeThe open upper half plane, denoted as `ℍ` within the `UpperHalfPlane` namespace ) : Complex : TypeComplex numbers consist of two `Real`s: a real part `re` and an imaginary part `im`. 
    def H₃ (τUpperHalfPlane : UpperHalfPlaneUpperHalfPlane : TypeThe open upper half plane, denoted as `ℍ` within the `UpperHalfPlane` namespace ) : Complex : TypeComplex numbers consist of two `Real`s: a real part `re` and an imaginary part `im`. 
    complete
  • def H₄ (τUpperHalfPlane : UpperHalfPlaneUpperHalfPlane : TypeThe open upper half plane, denoted as `ℍ` within the `UpperHalfPlane` namespace ) : Complex : TypeComplex numbers consist of two `Real`s: a real part `re` and an imaginary part `im`. 
    def H₄ (τUpperHalfPlane : UpperHalfPlaneUpperHalfPlane : TypeThe open upper half plane, denoted as `ℍ` within the `UpperHalfPlane` namespace ) : Complex : TypeComplex numbers consist of two `Real`s: a real part `re` and an imaginary part `im`. 
    complete

These elements act on the theta functions in the following way. H_2 | S = -H_4,\quad H_3 | S = -H_3,\quad H_4 | S = -H_2 and H_2 | T = -H_2,\quad H_3 | T = H_4,\quad H_4 | T = H_3. Uses Definition 7.31 and Definition 7.32.

Lean code for Lemma7.336 theorems
  • theorem H₂_T_action : SlashAction.mapSlashAction.map.{u_1, u_2, u_3} {β : Type u_1} {G : Type u_2} {α : Type u_3} {inst✝ : Monoid G} {inst✝¹ : AddMonoid α}
      [self : SlashAction β G α] : β → G → α → α 2 ModularGroup.TModularGroup.T : Matrix.SpecialLinearGroup (Fin 2) ℤThe matrix `T = [[1, 1], [0, 1]]` as an element of `SL(2, ℤ)`.  H₂H₂ (τ : UpperHalfPlane) : ℂ =Eq.{u_1} {α : Sort u_1} : α → α → PropThe equality relation. It has one introduction rule, `Eq.refl`.
    We use `a = b` as notation for `Eq a b`.
    A fundamental property of equality is that it is an equivalence relation.
    ```
    variable (α : Type) (a b c d : α)
    variable (hab : a = b) (hcb : c = b) (hcd : c = d)
    
    example : a = d :=
      Eq.trans (Eq.trans hab (Eq.symm hcb)) hcd
    ```
    Equality is much more than an equivalence relation, however. It has the important property that every assertion
    respects the equivalence, in the sense that we can substitute equal expressions without changing the truth value.
    That is, given `h1 : a = b` and `h2 : p a`, we can construct a proof for `p b` using substitution: `Eq.subst h1 h2`.
    Example:
    ```
    example (α : Type) (a b : α) (p : α → Prop)
            (h1 : a = b) (h2 : p a) : p b :=
      Eq.subst h1 h2
    
    example (α : Type) (a b : α) (p : α → Prop)
        (h1 : a = b) (h2 : p a) : p b :=
      h1 ▸ h2
    ```
    The triangle in the second presentation is a macro built on top of `Eq.subst` and `Eq.symm`, and you can enter it by typing `\t`.
    For more information: [Equality](https://lean-lang.org/theorem_proving_in_lean4/quantifiers_and_equality.html#equality)
    
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `=` in identifiers is `eq`. -Neg.neg.{u} {α : Type u} [self : Neg α] : α → α`-a` computes the negative or opposite of `a`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `-` in identifiers is `neg` (when used as a unary operator).H₂H₂ (τ : UpperHalfPlane) : ℂ
    theorem H₂_T_action :
      SlashAction.mapSlashAction.map.{u_1, u_2, u_3} {β : Type u_1} {G : Type u_2} {α : Type u_3} {inst✝ : Monoid G} {inst✝¹ : AddMonoid α}
      [self : SlashAction β G α] : β → G → α → α 2 ModularGroup.TModularGroup.T : Matrix.SpecialLinearGroup (Fin 2) ℤThe matrix `T = [[1, 1], [0, 1]]` as an element of `SL(2, ℤ)`.  H₂H₂ (τ : UpperHalfPlane) : ℂ =Eq.{u_1} {α : Sort u_1} : α → α → PropThe equality relation. It has one introduction rule, `Eq.refl`.
    We use `a = b` as notation for `Eq a b`.
    A fundamental property of equality is that it is an equivalence relation.
    ```
    variable (α : Type) (a b c d : α)
    variable (hab : a = b) (hcb : c = b) (hcd : c = d)
    
    example : a = d :=
      Eq.trans (Eq.trans hab (Eq.symm hcb)) hcd
    ```
    Equality is much more than an equivalence relation, however. It has the important property that every assertion
    respects the equivalence, in the sense that we can substitute equal expressions without changing the truth value.
    That is, given `h1 : a = b` and `h2 : p a`, we can construct a proof for `p b` using substitution: `Eq.subst h1 h2`.
    Example:
    ```
    example (α : Type) (a b : α) (p : α → Prop)
            (h1 : a = b) (h2 : p a) : p b :=
      Eq.subst h1 h2
    
    example (α : Type) (a b : α) (p : α → Prop)
        (h1 : a = b) (h2 : p a) : p b :=
      h1 ▸ h2
    ```
    The triangle in the second presentation is a macro built on top of `Eq.subst` and `Eq.symm`, and you can enter it by typing `\t`.
    For more information: [Equality](https://lean-lang.org/theorem_proving_in_lean4/quantifiers_and_equality.html#equality)
    
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `=` in identifiers is `eq`.
        -Neg.neg.{u} {α : Type u} [self : Neg α] : α → α`-a` computes the negative or opposite of `a`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `-` in identifiers is `neg` (when used as a unary operator).H₂H₂ (τ : UpperHalfPlane) : ℂ
    These three transformation laws follow directly from tsum definition. 
    complete
  • theorem H₃_T_action : SlashAction.mapSlashAction.map.{u_1, u_2, u_3} {β : Type u_1} {G : Type u_2} {α : Type u_3} {inst✝ : Monoid G} {inst✝¹ : AddMonoid α}
      [self : SlashAction β G α] : β → G → α → α 2 ModularGroup.TModularGroup.T : Matrix.SpecialLinearGroup (Fin 2) ℤThe matrix `T = [[1, 1], [0, 1]]` as an element of `SL(2, ℤ)`.  H₃H₃ (τ : UpperHalfPlane) : ℂ =Eq.{u_1} {α : Sort u_1} : α → α → PropThe equality relation. It has one introduction rule, `Eq.refl`.
    We use `a = b` as notation for `Eq a b`.
    A fundamental property of equality is that it is an equivalence relation.
    ```
    variable (α : Type) (a b c d : α)
    variable (hab : a = b) (hcb : c = b) (hcd : c = d)
    
    example : a = d :=
      Eq.trans (Eq.trans hab (Eq.symm hcb)) hcd
    ```
    Equality is much more than an equivalence relation, however. It has the important property that every assertion
    respects the equivalence, in the sense that we can substitute equal expressions without changing the truth value.
    That is, given `h1 : a = b` and `h2 : p a`, we can construct a proof for `p b` using substitution: `Eq.subst h1 h2`.
    Example:
    ```
    example (α : Type) (a b : α) (p : α → Prop)
            (h1 : a = b) (h2 : p a) : p b :=
      Eq.subst h1 h2
    
    example (α : Type) (a b : α) (p : α → Prop)
        (h1 : a = b) (h2 : p a) : p b :=
      h1 ▸ h2
    ```
    The triangle in the second presentation is a macro built on top of `Eq.subst` and `Eq.symm`, and you can enter it by typing `\t`.
    For more information: [Equality](https://lean-lang.org/theorem_proving_in_lean4/quantifiers_and_equality.html#equality)
    
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `=` in identifiers is `eq`. H₄H₄ (τ : UpperHalfPlane) : ℂ
    theorem H₃_T_action :
      SlashAction.mapSlashAction.map.{u_1, u_2, u_3} {β : Type u_1} {G : Type u_2} {α : Type u_3} {inst✝ : Monoid G} {inst✝¹ : AddMonoid α}
      [self : SlashAction β G α] : β → G → α → α 2 ModularGroup.TModularGroup.T : Matrix.SpecialLinearGroup (Fin 2) ℤThe matrix `T = [[1, 1], [0, 1]]` as an element of `SL(2, ℤ)`.  H₃H₃ (τ : UpperHalfPlane) : ℂ =Eq.{u_1} {α : Sort u_1} : α → α → PropThe equality relation. It has one introduction rule, `Eq.refl`.
    We use `a = b` as notation for `Eq a b`.
    A fundamental property of equality is that it is an equivalence relation.
    ```
    variable (α : Type) (a b c d : α)
    variable (hab : a = b) (hcb : c = b) (hcd : c = d)
    
    example : a = d :=
      Eq.trans (Eq.trans hab (Eq.symm hcb)) hcd
    ```
    Equality is much more than an equivalence relation, however. It has the important property that every assertion
    respects the equivalence, in the sense that we can substitute equal expressions without changing the truth value.
    That is, given `h1 : a = b` and `h2 : p a`, we can construct a proof for `p b` using substitution: `Eq.subst h1 h2`.
    Example:
    ```
    example (α : Type) (a b : α) (p : α → Prop)
            (h1 : a = b) (h2 : p a) : p b :=
      Eq.subst h1 h2
    
    example (α : Type) (a b : α) (p : α → Prop)
        (h1 : a = b) (h2 : p a) : p b :=
      h1 ▸ h2
    ```
    The triangle in the second presentation is a macro built on top of `Eq.subst` and `Eq.symm`, and you can enter it by typing `\t`.
    For more information: [Equality](https://lean-lang.org/theorem_proving_in_lean4/quantifiers_and_equality.html#equality)
    
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `=` in identifiers is `eq`. H₄H₄ (τ : UpperHalfPlane) : ℂ
    complete
  • theorem H₄_T_action : SlashAction.mapSlashAction.map.{u_1, u_2, u_3} {β : Type u_1} {G : Type u_2} {α : Type u_3} {inst✝ : Monoid G} {inst✝¹ : AddMonoid α}
      [self : SlashAction β G α] : β → G → α → α 2 ModularGroup.TModularGroup.T : Matrix.SpecialLinearGroup (Fin 2) ℤThe matrix `T = [[1, 1], [0, 1]]` as an element of `SL(2, ℤ)`.  H₄H₄ (τ : UpperHalfPlane) : ℂ =Eq.{u_1} {α : Sort u_1} : α → α → PropThe equality relation. It has one introduction rule, `Eq.refl`.
    We use `a = b` as notation for `Eq a b`.
    A fundamental property of equality is that it is an equivalence relation.
    ```
    variable (α : Type) (a b c d : α)
    variable (hab : a = b) (hcb : c = b) (hcd : c = d)
    
    example : a = d :=
      Eq.trans (Eq.trans hab (Eq.symm hcb)) hcd
    ```
    Equality is much more than an equivalence relation, however. It has the important property that every assertion
    respects the equivalence, in the sense that we can substitute equal expressions without changing the truth value.
    That is, given `h1 : a = b` and `h2 : p a`, we can construct a proof for `p b` using substitution: `Eq.subst h1 h2`.
    Example:
    ```
    example (α : Type) (a b : α) (p : α → Prop)
            (h1 : a = b) (h2 : p a) : p b :=
      Eq.subst h1 h2
    
    example (α : Type) (a b : α) (p : α → Prop)
        (h1 : a = b) (h2 : p a) : p b :=
      h1 ▸ h2
    ```
    The triangle in the second presentation is a macro built on top of `Eq.subst` and `Eq.symm`, and you can enter it by typing `\t`.
    For more information: [Equality](https://lean-lang.org/theorem_proving_in_lean4/quantifiers_and_equality.html#equality)
    
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `=` in identifiers is `eq`. H₃H₃ (τ : UpperHalfPlane) : ℂ
    theorem H₄_T_action :
      SlashAction.mapSlashAction.map.{u_1, u_2, u_3} {β : Type u_1} {G : Type u_2} {α : Type u_3} {inst✝ : Monoid G} {inst✝¹ : AddMonoid α}
      [self : SlashAction β G α] : β → G → α → α 2 ModularGroup.TModularGroup.T : Matrix.SpecialLinearGroup (Fin 2) ℤThe matrix `T = [[1, 1], [0, 1]]` as an element of `SL(2, ℤ)`.  H₄H₄ (τ : UpperHalfPlane) : ℂ =Eq.{u_1} {α : Sort u_1} : α → α → PropThe equality relation. It has one introduction rule, `Eq.refl`.
    We use `a = b` as notation for `Eq a b`.
    A fundamental property of equality is that it is an equivalence relation.
    ```
    variable (α : Type) (a b c d : α)
    variable (hab : a = b) (hcb : c = b) (hcd : c = d)
    
    example : a = d :=
      Eq.trans (Eq.trans hab (Eq.symm hcb)) hcd
    ```
    Equality is much more than an equivalence relation, however. It has the important property that every assertion
    respects the equivalence, in the sense that we can substitute equal expressions without changing the truth value.
    That is, given `h1 : a = b` and `h2 : p a`, we can construct a proof for `p b` using substitution: `Eq.subst h1 h2`.
    Example:
    ```
    example (α : Type) (a b : α) (p : α → Prop)
            (h1 : a = b) (h2 : p a) : p b :=
      Eq.subst h1 h2
    
    example (α : Type) (a b : α) (p : α → Prop)
        (h1 : a = b) (h2 : p a) : p b :=
      h1 ▸ h2
    ```
    The triangle in the second presentation is a macro built on top of `Eq.subst` and `Eq.symm`, and you can enter it by typing `\t`.
    For more information: [Equality](https://lean-lang.org/theorem_proving_in_lean4/quantifiers_and_equality.html#equality)
    
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `=` in identifiers is `eq`. H₃H₃ (τ : UpperHalfPlane) : ℂ
    complete
  • theorem H₂_S_action : SlashAction.mapSlashAction.map.{u_1, u_2, u_3} {β : Type u_1} {G : Type u_2} {α : Type u_3} {inst✝ : Monoid G} {inst✝¹ : AddMonoid α}
      [self : SlashAction β G α] : β → G → α → α 2 ModularGroup.SModularGroup.S : Matrix.SpecialLinearGroup (Fin 2) ℤThe matrix `S = [[0, -1], [1, 0]]` as an element of `SL(2, ℤ)`.
    
    This element acts naturally on the Euclidean plane as a rotation about the origin by `π / 2`.
    
    This element also acts naturally on the hyperbolic plane as rotation about `i` by `π`. It
    represents the Mobiüs transformation `z ↦ -1/z` and is an involutive elliptic isometry.  H₂H₂ (τ : UpperHalfPlane) : ℂ =Eq.{u_1} {α : Sort u_1} : α → α → PropThe equality relation. It has one introduction rule, `Eq.refl`.
    We use `a = b` as notation for `Eq a b`.
    A fundamental property of equality is that it is an equivalence relation.
    ```
    variable (α : Type) (a b c d : α)
    variable (hab : a = b) (hcb : c = b) (hcd : c = d)
    
    example : a = d :=
      Eq.trans (Eq.trans hab (Eq.symm hcb)) hcd
    ```
    Equality is much more than an equivalence relation, however. It has the important property that every assertion
    respects the equivalence, in the sense that we can substitute equal expressions without changing the truth value.
    That is, given `h1 : a = b` and `h2 : p a`, we can construct a proof for `p b` using substitution: `Eq.subst h1 h2`.
    Example:
    ```
    example (α : Type) (a b : α) (p : α → Prop)
            (h1 : a = b) (h2 : p a) : p b :=
      Eq.subst h1 h2
    
    example (α : Type) (a b : α) (p : α → Prop)
        (h1 : a = b) (h2 : p a) : p b :=
      h1 ▸ h2
    ```
    The triangle in the second presentation is a macro built on top of `Eq.subst` and `Eq.symm`, and you can enter it by typing `\t`.
    For more information: [Equality](https://lean-lang.org/theorem_proving_in_lean4/quantifiers_and_equality.html#equality)
    
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `=` in identifiers is `eq`. -Neg.neg.{u} {α : Type u} [self : Neg α] : α → α`-a` computes the negative or opposite of `a`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `-` in identifiers is `neg` (when used as a unary operator).H₄H₄ (τ : UpperHalfPlane) : ℂ
    theorem H₂_S_action :
      SlashAction.mapSlashAction.map.{u_1, u_2, u_3} {β : Type u_1} {G : Type u_2} {α : Type u_3} {inst✝ : Monoid G} {inst✝¹ : AddMonoid α}
      [self : SlashAction β G α] : β → G → α → α 2 ModularGroup.SModularGroup.S : Matrix.SpecialLinearGroup (Fin 2) ℤThe matrix `S = [[0, -1], [1, 0]]` as an element of `SL(2, ℤ)`.
    
    This element acts naturally on the Euclidean plane as a rotation about the origin by `π / 2`.
    
    This element also acts naturally on the hyperbolic plane as rotation about `i` by `π`. It
    represents the Mobiüs transformation `z ↦ -1/z` and is an involutive elliptic isometry.  H₂H₂ (τ : UpperHalfPlane) : ℂ =Eq.{u_1} {α : Sort u_1} : α → α → PropThe equality relation. It has one introduction rule, `Eq.refl`.
    We use `a = b` as notation for `Eq a b`.
    A fundamental property of equality is that it is an equivalence relation.
    ```
    variable (α : Type) (a b c d : α)
    variable (hab : a = b) (hcb : c = b) (hcd : c = d)
    
    example : a = d :=
      Eq.trans (Eq.trans hab (Eq.symm hcb)) hcd
    ```
    Equality is much more than an equivalence relation, however. It has the important property that every assertion
    respects the equivalence, in the sense that we can substitute equal expressions without changing the truth value.
    That is, given `h1 : a = b` and `h2 : p a`, we can construct a proof for `p b` using substitution: `Eq.subst h1 h2`.
    Example:
    ```
    example (α : Type) (a b : α) (p : α → Prop)
            (h1 : a = b) (h2 : p a) : p b :=
      Eq.subst h1 h2
    
    example (α : Type) (a b : α) (p : α → Prop)
        (h1 : a = b) (h2 : p a) : p b :=
      h1 ▸ h2
    ```
    The triangle in the second presentation is a macro built on top of `Eq.subst` and `Eq.symm`, and you can enter it by typing `\t`.
    For more information: [Equality](https://lean-lang.org/theorem_proving_in_lean4/quantifiers_and_equality.html#equality)
    
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `=` in identifiers is `eq`.
        -Neg.neg.{u} {α : Type u} [self : Neg α] : α → α`-a` computes the negative or opposite of `a`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `-` in identifiers is `neg` (when used as a unary operator).H₄H₄ (τ : UpperHalfPlane) : ℂ
    Use jacobiTheta₂_functional_equation 
    complete
  • theorem H₃_S_action : SlashAction.mapSlashAction.map.{u_1, u_2, u_3} {β : Type u_1} {G : Type u_2} {α : Type u_3} {inst✝ : Monoid G} {inst✝¹ : AddMonoid α}
      [self : SlashAction β G α] : β → G → α → α 2 ModularGroup.SModularGroup.S : Matrix.SpecialLinearGroup (Fin 2) ℤThe matrix `S = [[0, -1], [1, 0]]` as an element of `SL(2, ℤ)`.
    
    This element acts naturally on the Euclidean plane as a rotation about the origin by `π / 2`.
    
    This element also acts naturally on the hyperbolic plane as rotation about `i` by `π`. It
    represents the Mobiüs transformation `z ↦ -1/z` and is an involutive elliptic isometry.  H₃H₃ (τ : UpperHalfPlane) : ℂ =Eq.{u_1} {α : Sort u_1} : α → α → PropThe equality relation. It has one introduction rule, `Eq.refl`.
    We use `a = b` as notation for `Eq a b`.
    A fundamental property of equality is that it is an equivalence relation.
    ```
    variable (α : Type) (a b c d : α)
    variable (hab : a = b) (hcb : c = b) (hcd : c = d)
    
    example : a = d :=
      Eq.trans (Eq.trans hab (Eq.symm hcb)) hcd
    ```
    Equality is much more than an equivalence relation, however. It has the important property that every assertion
    respects the equivalence, in the sense that we can substitute equal expressions without changing the truth value.
    That is, given `h1 : a = b` and `h2 : p a`, we can construct a proof for `p b` using substitution: `Eq.subst h1 h2`.
    Example:
    ```
    example (α : Type) (a b : α) (p : α → Prop)
            (h1 : a = b) (h2 : p a) : p b :=
      Eq.subst h1 h2
    
    example (α : Type) (a b : α) (p : α → Prop)
        (h1 : a = b) (h2 : p a) : p b :=
      h1 ▸ h2
    ```
    The triangle in the second presentation is a macro built on top of `Eq.subst` and `Eq.symm`, and you can enter it by typing `\t`.
    For more information: [Equality](https://lean-lang.org/theorem_proving_in_lean4/quantifiers_and_equality.html#equality)
    
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `=` in identifiers is `eq`. -Neg.neg.{u} {α : Type u} [self : Neg α] : α → α`-a` computes the negative or opposite of `a`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `-` in identifiers is `neg` (when used as a unary operator).H₃H₃ (τ : UpperHalfPlane) : ℂ
    theorem H₃_S_action :
      SlashAction.mapSlashAction.map.{u_1, u_2, u_3} {β : Type u_1} {G : Type u_2} {α : Type u_3} {inst✝ : Monoid G} {inst✝¹ : AddMonoid α}
      [self : SlashAction β G α] : β → G → α → α 2 ModularGroup.SModularGroup.S : Matrix.SpecialLinearGroup (Fin 2) ℤThe matrix `S = [[0, -1], [1, 0]]` as an element of `SL(2, ℤ)`.
    
    This element acts naturally on the Euclidean plane as a rotation about the origin by `π / 2`.
    
    This element also acts naturally on the hyperbolic plane as rotation about `i` by `π`. It
    represents the Mobiüs transformation `z ↦ -1/z` and is an involutive elliptic isometry.  H₃H₃ (τ : UpperHalfPlane) : ℂ =Eq.{u_1} {α : Sort u_1} : α → α → PropThe equality relation. It has one introduction rule, `Eq.refl`.
    We use `a = b` as notation for `Eq a b`.
    A fundamental property of equality is that it is an equivalence relation.
    ```
    variable (α : Type) (a b c d : α)
    variable (hab : a = b) (hcb : c = b) (hcd : c = d)
    
    example : a = d :=
      Eq.trans (Eq.trans hab (Eq.symm hcb)) hcd
    ```
    Equality is much more than an equivalence relation, however. It has the important property that every assertion
    respects the equivalence, in the sense that we can substitute equal expressions without changing the truth value.
    That is, given `h1 : a = b` and `h2 : p a`, we can construct a proof for `p b` using substitution: `Eq.subst h1 h2`.
    Example:
    ```
    example (α : Type) (a b : α) (p : α → Prop)
            (h1 : a = b) (h2 : p a) : p b :=
      Eq.subst h1 h2
    
    example (α : Type) (a b : α) (p : α → Prop)
        (h1 : a = b) (h2 : p a) : p b :=
      h1 ▸ h2
    ```
    The triangle in the second presentation is a macro built on top of `Eq.subst` and `Eq.symm`, and you can enter it by typing `\t`.
    For more information: [Equality](https://lean-lang.org/theorem_proving_in_lean4/quantifiers_and_equality.html#equality)
    
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `=` in identifiers is `eq`.
        -Neg.neg.{u} {α : Type u} [self : Neg α] : α → α`-a` computes the negative or opposite of `a`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `-` in identifiers is `neg` (when used as a unary operator).H₃H₃ (τ : UpperHalfPlane) : ℂ
    complete
  • theorem H₄_S_action : SlashAction.mapSlashAction.map.{u_1, u_2, u_3} {β : Type u_1} {G : Type u_2} {α : Type u_3} {inst✝ : Monoid G} {inst✝¹ : AddMonoid α}
      [self : SlashAction β G α] : β → G → α → α 2 ModularGroup.SModularGroup.S : Matrix.SpecialLinearGroup (Fin 2) ℤThe matrix `S = [[0, -1], [1, 0]]` as an element of `SL(2, ℤ)`.
    
    This element acts naturally on the Euclidean plane as a rotation about the origin by `π / 2`.
    
    This element also acts naturally on the hyperbolic plane as rotation about `i` by `π`. It
    represents the Mobiüs transformation `z ↦ -1/z` and is an involutive elliptic isometry.  H₄H₄ (τ : UpperHalfPlane) : ℂ =Eq.{u_1} {α : Sort u_1} : α → α → PropThe equality relation. It has one introduction rule, `Eq.refl`.
    We use `a = b` as notation for `Eq a b`.
    A fundamental property of equality is that it is an equivalence relation.
    ```
    variable (α : Type) (a b c d : α)
    variable (hab : a = b) (hcb : c = b) (hcd : c = d)
    
    example : a = d :=
      Eq.trans (Eq.trans hab (Eq.symm hcb)) hcd
    ```
    Equality is much more than an equivalence relation, however. It has the important property that every assertion
    respects the equivalence, in the sense that we can substitute equal expressions without changing the truth value.
    That is, given `h1 : a = b` and `h2 : p a`, we can construct a proof for `p b` using substitution: `Eq.subst h1 h2`.
    Example:
    ```
    example (α : Type) (a b : α) (p : α → Prop)
            (h1 : a = b) (h2 : p a) : p b :=
      Eq.subst h1 h2
    
    example (α : Type) (a b : α) (p : α → Prop)
        (h1 : a = b) (h2 : p a) : p b :=
      h1 ▸ h2
    ```
    The triangle in the second presentation is a macro built on top of `Eq.subst` and `Eq.symm`, and you can enter it by typing `\t`.
    For more information: [Equality](https://lean-lang.org/theorem_proving_in_lean4/quantifiers_and_equality.html#equality)
    
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `=` in identifiers is `eq`. -Neg.neg.{u} {α : Type u} [self : Neg α] : α → α`-a` computes the negative or opposite of `a`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `-` in identifiers is `neg` (when used as a unary operator).H₂H₂ (τ : UpperHalfPlane) : ℂ
    theorem H₄_S_action :
      SlashAction.mapSlashAction.map.{u_1, u_2, u_3} {β : Type u_1} {G : Type u_2} {α : Type u_3} {inst✝ : Monoid G} {inst✝¹ : AddMonoid α}
      [self : SlashAction β G α] : β → G → α → α 2 ModularGroup.SModularGroup.S : Matrix.SpecialLinearGroup (Fin 2) ℤThe matrix `S = [[0, -1], [1, 0]]` as an element of `SL(2, ℤ)`.
    
    This element acts naturally on the Euclidean plane as a rotation about the origin by `π / 2`.
    
    This element also acts naturally on the hyperbolic plane as rotation about `i` by `π`. It
    represents the Mobiüs transformation `z ↦ -1/z` and is an involutive elliptic isometry.  H₄H₄ (τ : UpperHalfPlane) : ℂ =Eq.{u_1} {α : Sort u_1} : α → α → PropThe equality relation. It has one introduction rule, `Eq.refl`.
    We use `a = b` as notation for `Eq a b`.
    A fundamental property of equality is that it is an equivalence relation.
    ```
    variable (α : Type) (a b c d : α)
    variable (hab : a = b) (hcb : c = b) (hcd : c = d)
    
    example : a = d :=
      Eq.trans (Eq.trans hab (Eq.symm hcb)) hcd
    ```
    Equality is much more than an equivalence relation, however. It has the important property that every assertion
    respects the equivalence, in the sense that we can substitute equal expressions without changing the truth value.
    That is, given `h1 : a = b` and `h2 : p a`, we can construct a proof for `p b` using substitution: `Eq.subst h1 h2`.
    Example:
    ```
    example (α : Type) (a b : α) (p : α → Prop)
            (h1 : a = b) (h2 : p a) : p b :=
      Eq.subst h1 h2
    
    example (α : Type) (a b : α) (p : α → Prop)
        (h1 : a = b) (h2 : p a) : p b :=
      h1 ▸ h2
    ```
    The triangle in the second presentation is a macro built on top of `Eq.subst` and `Eq.symm`, and you can enter it by typing `\t`.
    For more information: [Equality](https://lean-lang.org/theorem_proving_in_lean4/quantifiers_and_equality.html#equality)
    
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `=` in identifiers is `eq`.
        -Neg.neg.{u} {α : Type u} [self : Neg α] : α → α`-a` computes the negative or opposite of `a`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `-` in identifiers is `neg` (when used as a unary operator).H₂H₂ (τ : UpperHalfPlane) : ℂ
    complete
Proof

The last three identities easily follow from the definition. For example, eqn:H2-transform-T follows from \Theta_{2}(z + 1) = \sum_{n\in\Z}e^{\pi i (n+\frac12)^2 (z + 1)} = \sum_{n \in \Z} e^{\pi i (n + \frac{1}{2})^{2}} e^{\pi i (n + \frac{1}{2})^{2} z} = \sum_{n \in \Z} e^{\pi i (n^2 + n + \frac{1}{4})} e^{\pi i (n + \frac{1}{2})^{2} z} = \sum_{n \in \Z} (-1)^{n^2 + n}e^{\pi i / 4} e^{\pi i (n + \frac{1}{2})^{2} z} = e^{\pi i / 4} \Theta_{2}(z), and taking fourth powers. The identities eqn:H2-transform-S and eqn:H4-transform-S are equivalent under z \leftrightarrow -1/z, so it is enough to show eqn:H2-transform-S and eqn:H3-transform-S. These identities follow from the identities of the two-variable Jacobi theta function, which is defined as \theta(z, \tau) = \sum_{n \in \mathbb{Z}} e^{2 \pi i n z + \pi i n^2 \tau}. This function specializes to the theta functions as \Theta_{2}(\tau) = e^{\pi i \tau / 4} \theta(-\tau / 2, \tau), \Theta_{3}(\tau) = \theta(0, \tau), \Theta_{4}(\tau) = \theta(1/2, \tau), and Poisson summation gives \theta(z, \tau) = \frac{1}{\sqrt{-i \tau}} e^{-\frac{\pi i z^2}{\tau}} \theta\left(\frac{z}{\tau}, -\frac{1}{\tau}\right). Applying these specializations yields the identities. For example, eqn:H4-transform-S follows from \Theta_{4}(\tau) = \theta\left(\frac{1}{2}, \tau\right) = \frac{1}{\sqrt{-i\tau}} e^{- \frac{\pi i }{4 \tau}} \theta\left(\frac{1}{2 \tau}, -\frac{1}{\tau}\right) = \frac{1}{\sqrt{-i\tau}} \Theta_{2}\left(-\frac{1}{\tau}\right), and taking fourth powers.

Lemma7.34
L∃∀N
Used by 2
Hover a use site to preview it.
Preview
Lemma 7.35
Loading preview
Hover a use site to preview it.

H_{2}, H_{3}, and H_{4} are slash invariant under \Gamma(2), that is, for all \gamma \in \Gamma(2) and i \in \{2, 3, 4\}, we have H_i|\gamma = H_i|\gamma^{-1} = H_i. Uses Lemma 7.10, Lemma 7.11, Lemma 7.33, and Lemma 7.6.

Lean code for Lemma7.343 definitions
  • def H₂_SIF :
      SlashInvariantFormSlashInvariantForm (Γ : outParam (Subgroup (GL (Fin 2) ℝ))) (k : outParam ℤ) : TypeFunctions `ℍ → ℂ` that are invariant under the `SlashAction`. 
        (Subgroup.mapSubgroup.map.{u_1, u_5} {G : Type u_1} [Group G] {N : Type u_5} [Group N] (f : G →* N) (H : Subgroup G) : Subgroup NThe image of a subgroup along a monoid homomorphism is a subgroup.  (Matrix.SpecialLinearGroup.mapGLMatrix.SpecialLinearGroup.mapGL.{u, v, u_1} {n : Type u} [DecidableEq n] [Fintype n] {R : Type v} [CommRing R]
      (S : Type u_1) [CommRing S] [Algebra R S] : Matrix.SpecialLinearGroup n R →* GL n S`mapGL` is the map from the special linear group over `R` to the general linear group over
    `S`, where `S` is an `R`-algebra.  Real : TypeThe type `ℝ` of real numbers constructed as equivalence classes of Cauchy sequences of rational
    numbers. )
          (CongruenceSubgroup.GammaCongruenceSubgroup.Gamma (N : ℕ) : Subgroup (Matrix.SpecialLinearGroup (Fin 2) ℤ)The full level `N` congruence subgroup of `SL(2, ℤ)` of matrices that reduce to the identity
    modulo `N`.  2))
        2
    def H₂_SIF :
      SlashInvariantFormSlashInvariantForm (Γ : outParam (Subgroup (GL (Fin 2) ℝ))) (k : outParam ℤ) : TypeFunctions `ℍ → ℂ` that are invariant under the `SlashAction`. 
        (Subgroup.mapSubgroup.map.{u_1, u_5} {G : Type u_1} [Group G] {N : Type u_5} [Group N] (f : G →* N) (H : Subgroup G) : Subgroup NThe image of a subgroup along a monoid homomorphism is a subgroup. 
          (Matrix.SpecialLinearGroup.mapGLMatrix.SpecialLinearGroup.mapGL.{u, v, u_1} {n : Type u} [DecidableEq n] [Fintype n] {R : Type v} [CommRing R]
      (S : Type u_1) [CommRing S] [Algebra R S] : Matrix.SpecialLinearGroup n R →* GL n S`mapGL` is the map from the special linear group over `R` to the general linear group over
    `S`, where `S` is an `R`-algebra.  Real : TypeThe type `ℝ` of real numbers constructed as equivalence classes of Cauchy sequences of rational
    numbers. )
          (CongruenceSubgroup.GammaCongruenceSubgroup.Gamma (N : ℕ) : Subgroup (Matrix.SpecialLinearGroup (Fin 2) ℤ)The full level `N` congruence subgroup of `SL(2, ℤ)` of matrices that reduce to the identity
    modulo `N`.  2))
        2
    H₂, H₃, H₄ are modular forms of weight 2 and level Γ(2) 
    complete
  • def H₃_SIF :
      SlashInvariantFormSlashInvariantForm (Γ : outParam (Subgroup (GL (Fin 2) ℝ))) (k : outParam ℤ) : TypeFunctions `ℍ → ℂ` that are invariant under the `SlashAction`. 
        (Subgroup.mapSubgroup.map.{u_1, u_5} {G : Type u_1} [Group G] {N : Type u_5} [Group N] (f : G →* N) (H : Subgroup G) : Subgroup NThe image of a subgroup along a monoid homomorphism is a subgroup.  (Matrix.SpecialLinearGroup.mapGLMatrix.SpecialLinearGroup.mapGL.{u, v, u_1} {n : Type u} [DecidableEq n] [Fintype n] {R : Type v} [CommRing R]
      (S : Type u_1) [CommRing S] [Algebra R S] : Matrix.SpecialLinearGroup n R →* GL n S`mapGL` is the map from the special linear group over `R` to the general linear group over
    `S`, where `S` is an `R`-algebra.  Real : TypeThe type `ℝ` of real numbers constructed as equivalence classes of Cauchy sequences of rational
    numbers. )
          (CongruenceSubgroup.GammaCongruenceSubgroup.Gamma (N : ℕ) : Subgroup (Matrix.SpecialLinearGroup (Fin 2) ℤ)The full level `N` congruence subgroup of `SL(2, ℤ)` of matrices that reduce to the identity
    modulo `N`.  2))
        2
    def H₃_SIF :
      SlashInvariantFormSlashInvariantForm (Γ : outParam (Subgroup (GL (Fin 2) ℝ))) (k : outParam ℤ) : TypeFunctions `ℍ → ℂ` that are invariant under the `SlashAction`. 
        (Subgroup.mapSubgroup.map.{u_1, u_5} {G : Type u_1} [Group G] {N : Type u_5} [Group N] (f : G →* N) (H : Subgroup G) : Subgroup NThe image of a subgroup along a monoid homomorphism is a subgroup. 
          (Matrix.SpecialLinearGroup.mapGLMatrix.SpecialLinearGroup.mapGL.{u, v, u_1} {n : Type u} [DecidableEq n] [Fintype n] {R : Type v} [CommRing R]
      (S : Type u_1) [CommRing S] [Algebra R S] : Matrix.SpecialLinearGroup n R →* GL n S`mapGL` is the map from the special linear group over `R` to the general linear group over
    `S`, where `S` is an `R`-algebra.  Real : TypeThe type `ℝ` of real numbers constructed as equivalence classes of Cauchy sequences of rational
    numbers. )
          (CongruenceSubgroup.GammaCongruenceSubgroup.Gamma (N : ℕ) : Subgroup (Matrix.SpecialLinearGroup (Fin 2) ℤ)The full level `N` congruence subgroup of `SL(2, ℤ)` of matrices that reduce to the identity
    modulo `N`.  2))
        2
    complete
  • def H₄_SIF :
      SlashInvariantFormSlashInvariantForm (Γ : outParam (Subgroup (GL (Fin 2) ℝ))) (k : outParam ℤ) : TypeFunctions `ℍ → ℂ` that are invariant under the `SlashAction`. 
        (Subgroup.mapSubgroup.map.{u_1, u_5} {G : Type u_1} [Group G] {N : Type u_5} [Group N] (f : G →* N) (H : Subgroup G) : Subgroup NThe image of a subgroup along a monoid homomorphism is a subgroup.  (Matrix.SpecialLinearGroup.mapGLMatrix.SpecialLinearGroup.mapGL.{u, v, u_1} {n : Type u} [DecidableEq n] [Fintype n] {R : Type v} [CommRing R]
      (S : Type u_1) [CommRing S] [Algebra R S] : Matrix.SpecialLinearGroup n R →* GL n S`mapGL` is the map from the special linear group over `R` to the general linear group over
    `S`, where `S` is an `R`-algebra.  Real : TypeThe type `ℝ` of real numbers constructed as equivalence classes of Cauchy sequences of rational
    numbers. )
          (CongruenceSubgroup.GammaCongruenceSubgroup.Gamma (N : ℕ) : Subgroup (Matrix.SpecialLinearGroup (Fin 2) ℤ)The full level `N` congruence subgroup of `SL(2, ℤ)` of matrices that reduce to the identity
    modulo `N`.  2))
        2
    def H₄_SIF :
      SlashInvariantFormSlashInvariantForm (Γ : outParam (Subgroup (GL (Fin 2) ℝ))) (k : outParam ℤ) : TypeFunctions `ℍ → ℂ` that are invariant under the `SlashAction`. 
        (Subgroup.mapSubgroup.map.{u_1, u_5} {G : Type u_1} [Group G] {N : Type u_5} [Group N] (f : G →* N) (H : Subgroup G) : Subgroup NThe image of a subgroup along a monoid homomorphism is a subgroup. 
          (Matrix.SpecialLinearGroup.mapGLMatrix.SpecialLinearGroup.mapGL.{u, v, u_1} {n : Type u} [DecidableEq n] [Fintype n] {R : Type v} [CommRing R]
      (S : Type u_1) [CommRing S] [Algebra R S] : Matrix.SpecialLinearGroup n R →* GL n S`mapGL` is the map from the special linear group over `R` to the general linear group over
    `S`, where `S` is an `R`-algebra.  Real : TypeThe type `ℝ` of real numbers constructed as equivalence classes of Cauchy sequences of rational
    numbers. )
          (CongruenceSubgroup.GammaCongruenceSubgroup.Gamma (N : ℕ) : Subgroup (Matrix.SpecialLinearGroup (Fin 2) ℤ)The full level `N` congruence subgroup of `SL(2, ℤ)` of matrices that reduce to the identity
    modulo `N`.  2))
        2
    complete
Proof

By Lemma 7.6 and Lemma 7.10, it suffices to show that the H_i are invariant under slash actions with respect to \alpha, \beta, and -I. Invariance under -I follows from Lemma 7.11. The rest follows from Lemma 7.10, Lemma 7.33, and the matrix identities \alpha = T^2 and \beta = -S\alpha^{-1}S = -ST^{-2}S. For example, invariance for H_2 follows from H_2|\alpha = H_2 |T^{2} = -H_2 |T = H_2 and H_2|\beta = H_2 |(-S\alpha^{-1}S) = H_2 | (S\alpha^{-1}S) =-H_4 |(\alpha^{-1}S) = -H_4 |S = H_2.

Lemma7.35

For all \gamma \in \Gamma_1, the slash-translates H_{2}|_2 \gamma, H_{3}|_2 \gamma, and H_{4}|_2 \gamma are holomorphic at i\infty. Uses Lemma 7.34 and Lemma 7.5.

Lean code for Lemma7.351 theorem
  • theorem isBoundedAtImInfty_H_slash (γMatrix.SpecialLinearGroup (Fin 2) ℤ : Matrix.SpecialLinearGroupMatrix.SpecialLinearGroup.{u, v} (n : Type u) [DecidableEq n] [Fintype n] (R : Type v) [CommRing R] : Type (max 0 u v)`SpecialLinearGroup n R` is the group of `n` by `n` `R`-matrices with determinant equal to 1.
     (FinFin (n : ℕ) : TypeNatural numbers less than some upper bound.
    
    In particular, a `Fin n` is a natural number `i` with the constraint that `i < n`. It is the
    canonical type with `n` elements.
     2) Int : TypeThe integers.
    
    This type is special-cased by the compiler and overridden with an efficient implementation. The
    runtime has a special representation for `Int` that stores “small” signed numbers directly, while
    larger numbers use a fast arbitrary-precision arithmetic library (usually
    [GMP](https://gmplib.org/)). A “small number” is an integer that can be encoded with one fewer bits
    than the platform's pointer size (i.e. 63 bits on 64-bit architectures and 31 bits on 32-bit
    architectures).
    ) :
      UpperHalfPlane.IsBoundedAtImInftyUpperHalfPlane.IsBoundedAtImInfty.{u_1} {α : Type u_1} [Norm α] (f : UpperHalfPlane → α) : PropA function `f : ℍ → α` is bounded at infinity if it is bounded along `atImInfty`.  (SlashAction.mapSlashAction.map.{u_1, u_2, u_3} {β : Type u_1} {G : Type u_2} {α : Type u_3} {inst✝ : Monoid G} {inst✝¹ : AddMonoid α}
      [self : SlashAction β G α] : β → G → α → α 2 γMatrix.SpecialLinearGroup (Fin 2) ℤ H₂H₂ (τ : UpperHalfPlane) : ℂ) And (a b : Prop) : Prop`And a b`, or `a ∧ b`, is the conjunction of propositions. It can be
    constructed and destructed like a pair: if `ha : a` and `hb : b` then
    `⟨ha, hb⟩ : a ∧ b`, and if `h : a ∧ b` then `h.left : a` and `h.right : b`.
    
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `∧` in identifiers is `and`.
    
     * The recommended spelling of `/\` in identifiers is `and` (prefer `∧` over `/\`).
        UpperHalfPlane.IsBoundedAtImInftyUpperHalfPlane.IsBoundedAtImInfty.{u_1} {α : Type u_1} [Norm α] (f : UpperHalfPlane → α) : PropA function `f : ℍ → α` is bounded at infinity if it is bounded along `atImInfty`.  (SlashAction.mapSlashAction.map.{u_1, u_2, u_3} {β : Type u_1} {G : Type u_2} {α : Type u_3} {inst✝ : Monoid G} {inst✝¹ : AddMonoid α}
      [self : SlashAction β G α] : β → G → α → α 2 γMatrix.SpecialLinearGroup (Fin 2) ℤ H₃H₃ (τ : UpperHalfPlane) : ℂ) And (a b : Prop) : Prop`And a b`, or `a ∧ b`, is the conjunction of propositions. It can be
    constructed and destructed like a pair: if `ha : a` and `hb : b` then
    `⟨ha, hb⟩ : a ∧ b`, and if `h : a ∧ b` then `h.left : a` and `h.right : b`.
    
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `∧` in identifiers is `and`.
    
     * The recommended spelling of `/\` in identifiers is `and` (prefer `∧` over `/\`).
          UpperHalfPlane.IsBoundedAtImInftyUpperHalfPlane.IsBoundedAtImInfty.{u_1} {α : Type u_1} [Norm α] (f : UpperHalfPlane → α) : PropA function `f : ℍ → α` is bounded at infinity if it is bounded along `atImInfty`.  (SlashAction.mapSlashAction.map.{u_1, u_2, u_3} {β : Type u_1} {G : Type u_2} {α : Type u_3} {inst✝ : Monoid G} {inst✝¹ : AddMonoid α}
      [self : SlashAction β G α] : β → G → α → α 2 γMatrix.SpecialLinearGroup (Fin 2) ℤ H₄H₄ (τ : UpperHalfPlane) : ℂ)
    theorem isBoundedAtImInfty_H_slash
      (γMatrix.SpecialLinearGroup (Fin 2) ℤ :
        Matrix.SpecialLinearGroupMatrix.SpecialLinearGroup.{u, v} (n : Type u) [DecidableEq n] [Fintype n] (R : Type v) [CommRing R] : Type (max 0 u v)`SpecialLinearGroup n R` is the group of `n` by `n` `R`-matrices with determinant equal to 1.
     (FinFin (n : ℕ) : TypeNatural numbers less than some upper bound.
    
    In particular, a `Fin n` is a natural number `i` with the constraint that `i < n`. It is the
    canonical type with `n` elements.
     2) Int : TypeThe integers.
    
    This type is special-cased by the compiler and overridden with an efficient implementation. The
    runtime has a special representation for `Int` that stores “small” signed numbers directly, while
    larger numbers use a fast arbitrary-precision arithmetic library (usually
    [GMP](https://gmplib.org/)). A “small number” is an integer that can be encoded with one fewer bits
    than the platform's pointer size (i.e. 63 bits on 64-bit architectures and 31 bits on 32-bit
    architectures).
    ) :
      UpperHalfPlane.IsBoundedAtImInftyUpperHalfPlane.IsBoundedAtImInfty.{u_1} {α : Type u_1} [Norm α] (f : UpperHalfPlane → α) : PropA function `f : ℍ → α` is bounded at infinity if it is bounded along `atImInfty`. 
          (SlashAction.mapSlashAction.map.{u_1, u_2, u_3} {β : Type u_1} {G : Type u_2} {α : Type u_3} {inst✝ : Monoid G} {inst✝¹ : AddMonoid α}
      [self : SlashAction β G α] : β → G → α → α 2 γMatrix.SpecialLinearGroup (Fin 2) ℤ H₂H₂ (τ : UpperHalfPlane) : ℂ) And (a b : Prop) : Prop`And a b`, or `a ∧ b`, is the conjunction of propositions. It can be
    constructed and destructed like a pair: if `ha : a` and `hb : b` then
    `⟨ha, hb⟩ : a ∧ b`, and if `h : a ∧ b` then `h.left : a` and `h.right : b`.
    
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `∧` in identifiers is `and`.
    
     * The recommended spelling of `/\` in identifiers is `and` (prefer `∧` over `/\`).
        UpperHalfPlane.IsBoundedAtImInftyUpperHalfPlane.IsBoundedAtImInfty.{u_1} {α : Type u_1} [Norm α] (f : UpperHalfPlane → α) : PropA function `f : ℍ → α` is bounded at infinity if it is bounded along `atImInfty`. 
            (SlashAction.mapSlashAction.map.{u_1, u_2, u_3} {β : Type u_1} {G : Type u_2} {α : Type u_3} {inst✝ : Monoid G} {inst✝¹ : AddMonoid α}
      [self : SlashAction β G α] : β → G → α → α 2 γMatrix.SpecialLinearGroup (Fin 2) ℤ H₃H₃ (τ : UpperHalfPlane) : ℂ) And (a b : Prop) : Prop`And a b`, or `a ∧ b`, is the conjunction of propositions. It can be
    constructed and destructed like a pair: if `ha : a` and `hb : b` then
    `⟨ha, hb⟩ : a ∧ b`, and if `h : a ∧ b` then `h.left : a` and `h.right : b`.
    
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `∧` in identifiers is `and`.
    
     * The recommended spelling of `/\` in identifiers is `and` (prefer `∧` over `/\`).
          UpperHalfPlane.IsBoundedAtImInftyUpperHalfPlane.IsBoundedAtImInfty.{u_1} {α : Type u_1} [Norm α] (f : UpperHalfPlane → α) : PropA function `f : ℍ → α` is bounded at infinity if it is bounded along `atImInfty`. 
            (SlashAction.mapSlashAction.map.{u_1, u_2, u_3} {β : Type u_1} {G : Type u_2} {α : Type u_3} {inst✝ : Monoid G} {inst✝¹ : AddMonoid α}
      [self : SlashAction β G α] : β → G → α → α 2 γMatrix.SpecialLinearGroup (Fin 2) ℤ H₄H₄ (τ : UpperHalfPlane) : ℂ)
    complete
Proof

We want to show that for \gamma \in \Gamma_1, \|H_2|_2\gamma(z)\| is bounded as z \in \mathbb{H} \to i\infty. By Lemma 7.33, Lemma 7.6, and induction on group elements, the set \{\pm H_2, \pm H_3, \pm H_4\} is closed under the action of \Gamma_1. Hence it suffices to prove that H_2,H_3,H_4 are bounded at i\infty. For z \in \mathbb{H} with \Im(z) \ge A, \|H_2(z)\| = \left\|\sum_{n \in \Z} \exp\left(\pi i \left(n + \frac{1}{2}\right)^2 z\right)\right\|^4 \leq \left(\sum_{n \in \Z} \left\|\exp\left(\pi i \left(n + \frac{1}{2}\right)^2 z\right)\right\|\right)^4 = \left(\sum_{n \in \Z} \left\|\exp\left(-\pi \left(n + \frac{1}{2}\right)^2 \Im(z)\right)\right\|\right)^4 \leq \left(\sum_{n \in \Z} \left\|\exp\left(-\pi \left(n + \frac{1}{2}\right)^2 A\right)\right\|\right)^4. The final term is convergent because it equals \exp(-\pi A / 4)\theta(iA / 2, iA). The proofs for H_3 and H_4 are similar.

Lemma7.36
L∃∀N
Used by 2
Hover a use site to preview it.
Preview
Lemma 7.40
Loading preview
Hover a use site to preview it.

H_{2}, H_{3}, and H_{4} belong to M_2(\Gamma(2)). Uses Lemma 7.34 and Lemma 7.35.

Lean code for Lemma7.363 definitions
  • def H₂_MF :
      ModularFormModularForm (Γ : Subgroup (GL (Fin 2) ℝ)) (k : ℤ) : TypeThese are `SlashInvariantForm`'s that are holomorphic and bounded at infinity. 
        (Subgroup.mapSubgroup.map.{u_1, u_5} {G : Type u_1} [Group G] {N : Type u_5} [Group N] (f : G →* N) (H : Subgroup G) : Subgroup NThe image of a subgroup along a monoid homomorphism is a subgroup.  (Matrix.SpecialLinearGroup.mapGLMatrix.SpecialLinearGroup.mapGL.{u, v, u_1} {n : Type u} [DecidableEq n] [Fintype n] {R : Type v} [CommRing R]
      (S : Type u_1) [CommRing S] [Algebra R S] : Matrix.SpecialLinearGroup n R →* GL n S`mapGL` is the map from the special linear group over `R` to the general linear group over
    `S`, where `S` is an `R`-algebra.  Real : TypeThe type `ℝ` of real numbers constructed as equivalence classes of Cauchy sequences of rational
    numbers. )
          (CongruenceSubgroup.GammaCongruenceSubgroup.Gamma (N : ℕ) : Subgroup (Matrix.SpecialLinearGroup (Fin 2) ℤ)The full level `N` congruence subgroup of `SL(2, ℤ)` of matrices that reduce to the identity
    modulo `N`.  2))
        2
    def H₂_MF :
      ModularFormModularForm (Γ : Subgroup (GL (Fin 2) ℝ)) (k : ℤ) : TypeThese are `SlashInvariantForm`'s that are holomorphic and bounded at infinity. 
        (Subgroup.mapSubgroup.map.{u_1, u_5} {G : Type u_1} [Group G] {N : Type u_5} [Group N] (f : G →* N) (H : Subgroup G) : Subgroup NThe image of a subgroup along a monoid homomorphism is a subgroup. 
          (Matrix.SpecialLinearGroup.mapGLMatrix.SpecialLinearGroup.mapGL.{u, v, u_1} {n : Type u} [DecidableEq n] [Fintype n] {R : Type v} [CommRing R]
      (S : Type u_1) [CommRing S] [Algebra R S] : Matrix.SpecialLinearGroup n R →* GL n S`mapGL` is the map from the special linear group over `R` to the general linear group over
    `S`, where `S` is an `R`-algebra.  Real : TypeThe type `ℝ` of real numbers constructed as equivalence classes of Cauchy sequences of rational
    numbers. )
          (CongruenceSubgroup.GammaCongruenceSubgroup.Gamma (N : ℕ) : Subgroup (Matrix.SpecialLinearGroup (Fin 2) ℤ)The full level `N` congruence subgroup of `SL(2, ℤ)` of matrices that reduce to the identity
    modulo `N`.  2))
        2
    complete
  • def H₃_MF :
      ModularFormModularForm (Γ : Subgroup (GL (Fin 2) ℝ)) (k : ℤ) : TypeThese are `SlashInvariantForm`'s that are holomorphic and bounded at infinity. 
        (Subgroup.mapSubgroup.map.{u_1, u_5} {G : Type u_1} [Group G] {N : Type u_5} [Group N] (f : G →* N) (H : Subgroup G) : Subgroup NThe image of a subgroup along a monoid homomorphism is a subgroup.  (Matrix.SpecialLinearGroup.mapGLMatrix.SpecialLinearGroup.mapGL.{u, v, u_1} {n : Type u} [DecidableEq n] [Fintype n] {R : Type v} [CommRing R]
      (S : Type u_1) [CommRing S] [Algebra R S] : Matrix.SpecialLinearGroup n R →* GL n S`mapGL` is the map from the special linear group over `R` to the general linear group over
    `S`, where `S` is an `R`-algebra.  Real : TypeThe type `ℝ` of real numbers constructed as equivalence classes of Cauchy sequences of rational
    numbers. )
          (CongruenceSubgroup.GammaCongruenceSubgroup.Gamma (N : ℕ) : Subgroup (Matrix.SpecialLinearGroup (Fin 2) ℤ)The full level `N` congruence subgroup of `SL(2, ℤ)` of matrices that reduce to the identity
    modulo `N`.  2))
        2
    def H₃_MF :
      ModularFormModularForm (Γ : Subgroup (GL (Fin 2) ℝ)) (k : ℤ) : TypeThese are `SlashInvariantForm`'s that are holomorphic and bounded at infinity. 
        (Subgroup.mapSubgroup.map.{u_1, u_5} {G : Type u_1} [Group G] {N : Type u_5} [Group N] (f : G →* N) (H : Subgroup G) : Subgroup NThe image of a subgroup along a monoid homomorphism is a subgroup. 
          (Matrix.SpecialLinearGroup.mapGLMatrix.SpecialLinearGroup.mapGL.{u, v, u_1} {n : Type u} [DecidableEq n] [Fintype n] {R : Type v} [CommRing R]
      (S : Type u_1) [CommRing S] [Algebra R S] : Matrix.SpecialLinearGroup n R →* GL n S`mapGL` is the map from the special linear group over `R` to the general linear group over
    `S`, where `S` is an `R`-algebra.  Real : TypeThe type `ℝ` of real numbers constructed as equivalence classes of Cauchy sequences of rational
    numbers. )
          (CongruenceSubgroup.GammaCongruenceSubgroup.Gamma (N : ℕ) : Subgroup (Matrix.SpecialLinearGroup (Fin 2) ℤ)The full level `N` congruence subgroup of `SL(2, ℤ)` of matrices that reduce to the identity
    modulo `N`.  2))
        2
    complete
  • def H₄_MF :
      ModularFormModularForm (Γ : Subgroup (GL (Fin 2) ℝ)) (k : ℤ) : TypeThese are `SlashInvariantForm`'s that are holomorphic and bounded at infinity. 
        (Subgroup.mapSubgroup.map.{u_1, u_5} {G : Type u_1} [Group G] {N : Type u_5} [Group N] (f : G →* N) (H : Subgroup G) : Subgroup NThe image of a subgroup along a monoid homomorphism is a subgroup.  (Matrix.SpecialLinearGroup.mapGLMatrix.SpecialLinearGroup.mapGL.{u, v, u_1} {n : Type u} [DecidableEq n] [Fintype n] {R : Type v} [CommRing R]
      (S : Type u_1) [CommRing S] [Algebra R S] : Matrix.SpecialLinearGroup n R →* GL n S`mapGL` is the map from the special linear group over `R` to the general linear group over
    `S`, where `S` is an `R`-algebra.  Real : TypeThe type `ℝ` of real numbers constructed as equivalence classes of Cauchy sequences of rational
    numbers. )
          (CongruenceSubgroup.GammaCongruenceSubgroup.Gamma (N : ℕ) : Subgroup (Matrix.SpecialLinearGroup (Fin 2) ℤ)The full level `N` congruence subgroup of `SL(2, ℤ)` of matrices that reduce to the identity
    modulo `N`.  2))
        2
    def H₄_MF :
      ModularFormModularForm (Γ : Subgroup (GL (Fin 2) ℝ)) (k : ℤ) : TypeThese are `SlashInvariantForm`'s that are holomorphic and bounded at infinity. 
        (Subgroup.mapSubgroup.map.{u_1, u_5} {G : Type u_1} [Group G] {N : Type u_5} [Group N] (f : G →* N) (H : Subgroup G) : Subgroup NThe image of a subgroup along a monoid homomorphism is a subgroup. 
          (Matrix.SpecialLinearGroup.mapGLMatrix.SpecialLinearGroup.mapGL.{u, v, u_1} {n : Type u} [DecidableEq n] [Fintype n] {R : Type v} [CommRing R]
      (S : Type u_1) [CommRing S] [Algebra R S] : Matrix.SpecialLinearGroup n R →* GL n S`mapGL` is the map from the special linear group over `R` to the general linear group over
    `S`, where `S` is an `R`-algebra.  Real : TypeThe type `ℝ` of real numbers constructed as equivalence classes of Cauchy sequences of rational
    numbers. )
          (CongruenceSubgroup.GammaCongruenceSubgroup.Gamma (N : ℕ) : Subgroup (Matrix.SpecialLinearGroup (Fin 2) ℤ)The full level `N` congruence subgroup of `SL(2, ℤ)` of matrices that reduce to the identity
    modulo `N`.  2))
        2
    complete
Proof

From Lemma 7.34 and Lemma 7.35, it remains ot prove that H_2, H_3 and H_4 are holomorphic on \mathbb{H}. fill in proof.

Lemma7.37

H_2 admits a Fourier series of the form H_2(z) = \sum_{n \ge 1} c_{H_2}(n) e^{\pi i n z} for some c_{H_2}(n) \in \mathbb{R}_{\ge 0}, with c_{H_2}(1) = 16 and c_{H_2}(n) = O(n^k) for some k \in \mathbb{N}. Uses Definition 7.32.

Proof

We have H_2(z) = \Theta_2(z)^4 = \left(\sum_{n \in \Z} e^{\pi i (n + \frac{1}{2})^{2} z}\right)^{4} = \left(2\sum_{n \ge 0} e^{\pi i (n + \frac{1}{2})^{2} z}\right)^{4}$, and then \left(2 e^{\pi i z / 4} + 2 \sum_{n \ge 1} e^{\pi i (n^2 + n + \frac{1}{4}) z}\right)^{4} = 16 e^{\pi i z}\left(1 + \sum_{n \ge 1} e^{\pi i (n^2 + n)z}\right)^{4}$, so H_2(z)=16 e^{\pi i z} + \sum_{n \ge 2} c_{H_2}(n) e^{\pi i n z} = \sum_{n \ge 1} c_{H_2}(n) e^{\pi i n z}$.

Lemma7.38

H_3 admits a Fourier series of the form H_3(z) = \sum_{n \ge 0} c_{H_3}(n) e^{\pi i n z} for some c_{H_3}(n) \in \R_{\ge 0} with c_{H_3}(0) = 1 and c_{H_3}(n) = O(n^k) for some k \in \N. Especially, H_3 is not cuspidal. Uses Definition 7.32.

Proof

We have H_3(z) = \Theta_3(z)^{4} = \left(\sum_{n \in \Z} e^{\pi i n^2 z}\right)^{4} = \left(1 + 2 \sum_{n \ge 1} e^{\pi i n^2 z}\right)^{4} = 1 + O(e^{\pi i z}).

Lemma7.39

H_4 admits a Fourier series of the form H_4(z) = \sum_{n \ge 0} c_{H_4}(n) e^{\pi i n z} for some c_{H_4}(n) \in \R with c_{H_4}(0) = 1 and c_{H_4}(n) = O(n^k) for some k \in \N. Especially, H_4 is not cuspidal. Uses Definition 7.32.

Lemma7.40
L∃∀N
Used by 3
Hover a use site to preview it.

These three theta functions satisfy the Jacobi identity H_{2} + H_{4} = H_{3} \Leftrightarrow \Theta_{2}^4 + \Theta_{4}^4 = \Theta_{3}^4. Uses Lemma 7.36 and Corollary 7.30.

Lean code for Lemma7.401 theorem
  • theorem jacobi_identity : H₂H₂ (τ : UpperHalfPlane) : ℂ +HAdd.hAdd.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HAdd α β γ] : α → β → γ`a + b` computes the sum of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `+` in identifiers is `add`. H₄H₄ (τ : UpperHalfPlane) : ℂ =Eq.{u_1} {α : Sort u_1} : α → α → PropThe equality relation. It has one introduction rule, `Eq.refl`.
    We use `a = b` as notation for `Eq a b`.
    A fundamental property of equality is that it is an equivalence relation.
    ```
    variable (α : Type) (a b c d : α)
    variable (hab : a = b) (hcb : c = b) (hcd : c = d)
    
    example : a = d :=
      Eq.trans (Eq.trans hab (Eq.symm hcb)) hcd
    ```
    Equality is much more than an equivalence relation, however. It has the important property that every assertion
    respects the equivalence, in the sense that we can substitute equal expressions without changing the truth value.
    That is, given `h1 : a = b` and `h2 : p a`, we can construct a proof for `p b` using substitution: `Eq.subst h1 h2`.
    Example:
    ```
    example (α : Type) (a b : α) (p : α → Prop)
            (h1 : a = b) (h2 : p a) : p b :=
      Eq.subst h1 h2
    
    example (α : Type) (a b : α) (p : α → Prop)
        (h1 : a = b) (h2 : p a) : p b :=
      h1 ▸ h2
    ```
    The triangle in the second presentation is a macro built on top of `Eq.subst` and `Eq.symm`, and you can enter it by typing `\t`.
    For more information: [Equality](https://lean-lang.org/theorem_proving_in_lean4/quantifiers_and_equality.html#equality)
    
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `=` in identifiers is `eq`. H₃H₃ (τ : UpperHalfPlane) : ℂ
    theorem jacobi_identity : H₂H₂ (τ : UpperHalfPlane) : ℂ +HAdd.hAdd.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HAdd α β γ] : α → β → γ`a + b` computes the sum of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `+` in identifiers is `add`. H₄H₄ (τ : UpperHalfPlane) : ℂ =Eq.{u_1} {α : Sort u_1} : α → α → PropThe equality relation. It has one introduction rule, `Eq.refl`.
    We use `a = b` as notation for `Eq a b`.
    A fundamental property of equality is that it is an equivalence relation.
    ```
    variable (α : Type) (a b c d : α)
    variable (hab : a = b) (hcb : c = b) (hcd : c = d)
    
    example : a = d :=
      Eq.trans (Eq.trans hab (Eq.symm hcb)) hcd
    ```
    Equality is much more than an equivalence relation, however. It has the important property that every assertion
    respects the equivalence, in the sense that we can substitute equal expressions without changing the truth value.
    That is, given `h1 : a = b` and `h2 : p a`, we can construct a proof for `p b` using substitution: `Eq.subst h1 h2`.
    Example:
    ```
    example (α : Type) (a b : α) (p : α → Prop)
            (h1 : a = b) (h2 : p a) : p b :=
      Eq.subst h1 h2
    
    example (α : Type) (a b : α) (p : α → Prop)
        (h1 : a = b) (h2 : p a) : p b :=
      h1 ▸ h2
    ```
    The triangle in the second presentation is a macro built on top of `Eq.subst` and `Eq.symm`, and you can enter it by typing `\t`.
    For more information: [Equality](https://lean-lang.org/theorem_proving_in_lean4/quantifiers_and_equality.html#equality)
    
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `=` in identifiers is `eq`. H₃H₃ (τ : UpperHalfPlane) : ℂ
    Jacobi identity: `H₂ + H₄ = H₃` (Blueprint Lemma 6.41). 
    complete
Proof

Let f = (H_2 + H_4 - H_3)^{2}. Obviously, f is a modular form of weight 4 and level \Gamma(2). Using the transformation rules of H_2,H_3,H_4, we have f|_{S} = (-H_4 - H_2 + H_3)^{2} = f and f|_{T} = (-H_2 + H_3 - H_4)^{2} = f, so f is actually a modular form of level 1. By considering the limit as z \to i\infty, f is a cusp form, and hence f = 0 by eqn:dimS4.

Lemma7.41
XL∃∀N
Used by 2
Hover a use site to preview it.
Preview
Lemma 8.19
Loading preview
Hover a use site to preview it.

We have E_4 = \frac{1}{2}(H_{2}^{2} + H_{3}^{2} + H_{4}^{2}) = H_{2}^{2} + H_{2}H_{4} + H_{4}^{2} E_6 = \frac{1}{2} (H_{2} + H_{3})(H_{3} + H_{4}) (H_{4} - H_{2}) = \frac{1}{2}(H_2 + 2H_4)(2H_2 + H_4)(H_4 - H_2) \Delta = \frac{1}{256} (H_{2}H_{3}H_{4})^2. Uses Lemma 7.33, Lemma 7.36, and Lemma 7.23.

Proof

We can prove these similarly as Lemma Lemma 7.40. The right-hand sides of eqn:e4theta, eqn:e6theta, and eqn:disctheta are all modular forms of level \Gamma_1 and of the desired weights, where eqn:disctheta is a cusp form since H_2 is. Now the identities follow from the dimension calculations \dim M_4(\Gamma_1) = \dim M_6(\Gamma_1) = \dim S_{12}(\Gamma_1) = 1 and comparing the first nonzero q-coefficients.

Corollary7.42
L∃∀N
Used by 2
Hover a use site to preview it.
Preview
Lemma 9.6
Loading preview
Hover a use site to preview it.

All three functions t \mapsto H_2(it), H_3(it), H_4(it) are positive for t > 0. Uses Lemma 7.40 and Lemma 7.33.

Lean code for Corollary7.422 theorems
  • theorem H₂_imag_axis_pos : ResToImagAxis.PosResToImagAxis.Pos (F : UpperHalfPlane → ℂ) : PropFunction $F : \mathbb{H} \to \mathbb{C}$ is real and positive on the imaginary axis.
     H₂H₂ (τ : UpperHalfPlane) : ℂ
    theorem H₂_imag_axis_pos : ResToImagAxis.PosResToImagAxis.Pos (F : UpperHalfPlane → ℂ) : PropFunction $F : \mathbb{H} \to \mathbb{C}$ is real and positive on the imaginary axis.
     H₂H₂ (τ : UpperHalfPlane) : ℂ
    `H₂(it) > 0` for all `t > 0`.
    Blueprint: Lemma 6.43 - H₂ is positive on the imaginary axis.
    Proof strategy: Each term exp(-π(n+1/2)²t) > 0, so Θ₂(it) > 0, hence H₂ = Θ₂^4 > 0.
    
    complete
  • theorem H₄_imag_axis_pos : ResToImagAxis.PosResToImagAxis.Pos (F : UpperHalfPlane → ℂ) : PropFunction $F : \mathbb{H} \to \mathbb{C}$ is real and positive on the imaginary axis.
     H₄H₄ (τ : UpperHalfPlane) : ℂ
    theorem H₄_imag_axis_pos : ResToImagAxis.PosResToImagAxis.Pos (F : UpperHalfPlane → ℂ) : PropFunction $F : \mathbb{H} \to \mathbb{C}$ is real and positive on the imaginary axis.
     H₄H₄ (τ : UpperHalfPlane) : ℂ
    `H₄(it) > 0` for all `t > 0`.
    Blueprint: Corollary 6.43 - H₄ is positive on the imaginary axis.
    
    Proof strategy: Use the modular S-transformation relating H₄ and H₂.
    From H₄_S_action: (H₄ ∣[2] S) = -H₂
    From ResToImagAxis.SlashActionS: relates values at t and 1/t.
    This gives H₂(i/t) = t² * H₄(it), so H₄(it) > 0 follows from H₂(i/t) > 0.
    
    complete
Proof

By Lemma Lemma 7.40 and the transformation law eqn:H2-transform-S, it is enough to prove the positivity for \Theta_2(it), which is clear from its definition: \Theta_{2}(it) = \sum_{n \in \mathbb{Z}} e^{- \pi (n + \frac{1}{2})^{2} t} > 0.

Definition7.43
L∃∀N
Used by 2
Hover a use site to preview it.
Preview
Lemma 7.44
Loading preview
Hover a use site to preview it.

Let F be a quasimodular form. We define the (normalized) derivative of F as F' = DF := \frac{1}{2\pi i} \frac{\dd}{\dd z} F.

Lean code for Definition7.431 definition
  • def D (FUpperHalfPlane → ℂ : UpperHalfPlaneUpperHalfPlane : TypeThe open upper half plane, denoted as `ℍ` within the `UpperHalfPlane` namespace   Complex : TypeComplex numbers consist of two `Real`s: a real part `re` and an imaginary part `im`. ) : UpperHalfPlaneUpperHalfPlane : TypeThe open upper half plane, denoted as `ℍ` within the `UpperHalfPlane` namespace   Complex : TypeComplex numbers consist of two `Real`s: a real part `re` and an imaginary part `im`. 
    def D (FUpperHalfPlane → ℂ : UpperHalfPlaneUpperHalfPlane : TypeThe open upper half plane, denoted as `ℍ` within the `UpperHalfPlane` namespace   Complex : TypeComplex numbers consist of two `Real`s: a real part `re` and an imaginary part `im`. ) :
      UpperHalfPlaneUpperHalfPlane : TypeThe open upper half plane, denoted as `ℍ` within the `UpperHalfPlane` namespace   Complex : TypeComplex numbers consist of two `Real`s: a real part `re` and an imaginary part `im`. 
    complete
Lemma7.44
L∃∀Nused by 1

We have an equality of operators D = q \frac{\dd}{\dd q}. In particular, if F(z) = \sum_{n \ge n_0} a_n q^n, then F'(z) = \sum_{n \ge n_0} n a_n q^n. Uses Definition 7.43.

Lean code for Lemma7.441 theorem
  • theorem D_qexp_tsum_pnat (aℕ+ → ℂ : ℕ+PNat : Type`ℕ+` is the type of positive natural numbers. It is defined as a subtype,
    and the VM representation of `ℕ+` is the same as `ℕ` because the proof
    is not stored.   Complex : TypeComplex numbers consist of two `Real`s: a real part `re` and an imaginary part `im`. ) (zUpperHalfPlane : UpperHalfPlaneUpperHalfPlane : TypeThe open upper half plane, denoted as `ℍ` within the `UpperHalfPlane` namespace )
      (hsumSummable fun n ↦ a n * Complex.exp (2 * ↑Real.pi * Complex.I * ↑↑n * ↑z) :
        SummableSummable.{u_1, u_2} {α : Type u_1} {β : Type u_2} [AddCommMonoid α] [TopologicalSpace α] (f : β → α)
      (L : SummationFilter β := SummationFilter.unconditional β) : Prop`Summable f` means that `f` has some (infinite) sum with respect to `L`. Use `tsum` to get the
    value.  fun nℕ+ 
          aℕ+ → ℂ nℕ+ *HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`. Complex.expComplex.exp (z : ℂ) : ℂThe complex exponential function, defined via its Taylor series  (HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`.2 *HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`. Real.piReal.pi : ℝThe number π = 3.14159265... Defined here using choice as twice a zero of cos in [1,2],
    from which one can derive all its properties. For explicit bounds on π,
    see `Mathlib/Analysis/Real/Pi/Bounds.lean`.
    
    Denoted `π`, once the `Real` namespace is opened.  *HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`. Complex.IComplex.I : ℂThe imaginary unit.  *HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`. nℕ+ *HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`. zUpperHalfPlane)HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`.)
      (hsum_deriv∀ K ⊆ {w | 0 < w.im},
      IsCompact K →
        ∃ u,
          Summable u ∧
            ∀ (n : ℕ+) (k : ↑K),
              ‖a n * (2 * ↑Real.pi * Complex.I * ↑↑n) * Complex.exp (2 * ↑Real.pi * Complex.I * ↑↑n * ↑k)‖ ≤ u n :
         KSet ℂ  {setOf.{u} {α : Type u} (p : α → Prop) : Set αTurn a predicate `p : α → Prop` into a set, also written as `{x | p x}` w |setOf.{u} {α : Type u} (p : α → Prop) : Set αTurn a predicate `p : α → Prop` into a set, also written as `{x | p x}`  0 <LT.lt.{u} {α : Type u} [self : LT α] : α → α → PropThe less-than relation: `x < y` 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `<` in identifiers is `lt`. w.imComplex.im (self : ℂ) : ℝThe imaginary part of a complex number. }setOf.{u} {α : Type u} (p : α → Prop) : Set αTurn a predicate `p : α → Prop` into a set, also written as `{x | p x}` ,
          IsCompactIsCompact.{u_1} {X : Type u_1} [TopologicalSpace X] (s : Set X) : PropA set `s` is compact if for every nontrivial filter `f` that contains `s`,
    there exists `a ∈ s` such that every set of `f` meets every neighborhood of `a`.  KSet ℂ 
             uℕ+ → ℝ,
              SummableSummable.{u_1, u_2} {α : Type u_1} {β : Type u_2} [AddCommMonoid α] [TopologicalSpace α] (f : β → α)
      (L : SummationFilter β := SummationFilter.unconditional β) : Prop`Summable f` means that `f` has some (infinite) sum with respect to `L`. Use `tsum` to get the
    value.  uℕ+ → ℝ And (a b : Prop) : Prop`And a b`, or `a ∧ b`, is the conjunction of propositions. It can be
    constructed and destructed like a pair: if `ha : a` and `hb : b` then
    `⟨ha, hb⟩ : a ∧ b`, and if `h : a ∧ b` then `h.left : a` and `h.right : b`.
    
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `∧` in identifiers is `and`.
    
     * The recommended spelling of `/\` in identifiers is `and` (prefer `∧` over `/\`).
                 (nℕ+ : ℕ+PNat : Type`ℕ+` is the type of positive natural numbers. It is defined as a subtype,
    and the VM representation of `ℕ+` is the same as `ℕ` because the proof
    is not stored. ) (k↑K : KSet ℂ),
                  Norm.norm.{u_8} {E : Type u_8} [self : Norm E] : E → ℝthe `ℝ`-valued norm function. aℕ+ → ℂ nℕ+ *HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`. (HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`.2 *HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`. Real.piReal.pi : ℝThe number π = 3.14159265... Defined here using choice as twice a zero of cos in [1,2],
    from which one can derive all its properties. For explicit bounds on π,
    see `Mathlib/Analysis/Real/Pi/Bounds.lean`.
    
    Denoted `π`, once the `Real` namespace is opened.  *HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`. Complex.IComplex.I : ℂThe imaginary unit.  *HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`. nℕ+)HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`. *HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`.
                        Complex.expComplex.exp (z : ℂ) : ℂThe complex exponential function, defined via its Taylor series  (HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`.2 *HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`. Real.piReal.pi : ℝThe number π = 3.14159265... Defined here using choice as twice a zero of cos in [1,2],
    from which one can derive all its properties. For explicit bounds on π,
    see `Mathlib/Analysis/Real/Pi/Bounds.lean`.
    
    Denoted `π`, once the `Real` namespace is opened.  *HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`. Complex.IComplex.I : ℂThe imaginary unit.  *HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`. nℕ+ *HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`. k↑K)HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`.Norm.norm.{u_8} {E : Type u_8} [self : Norm E] : E → ℝthe `ℝ`-valued norm function.  LE.le.{u} {α : Type u} [self : LE α] : α → α → PropThe less-equal relation: `x ≤ y` 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `≤` in identifiers is `le`.
    
     * The recommended spelling of `<=` in identifiers is `le` (prefer `≤` over `<=`).
                    uℕ+ → ℝ nℕ+) :
      DD (F : UpperHalfPlane → ℂ) : UpperHalfPlane → ℂ
          (fun wUpperHalfPlane 
            ∑'tsum.{u_4, u_5} {α : Type u_4} {β : Type u_5} [AddCommMonoid α] [TopologicalSpace α] (f : β → α)
      (L : SummationFilter β := SummationFilter.unconditional β) : α`∑' i, f i` is the unconditional sum of `f` if it exists, or 0 otherwise.
    
    More generally, if `L` is a `SummationFilter`, `∑'[L] i, f i` is the sum of `f` with respect to
    `L` if it exists, and `0` otherwise.
    
    (Note that even if the unconditional sum exists, it might not be unique if the topology is not
    separated. When the support of `f` is finite, we make the most reasonable choice, to use the sum
    over the support. Otherwise, we choose arbitrarily an `a` satisfying `HasSum f a`. Similar remarks
    apply to more general summation filters.)
     (nℕ+ : ℕ+PNat : Type`ℕ+` is the type of positive natural numbers. It is defined as a subtype,
    and the VM representation of `ℕ+` is the same as `ℕ` because the proof
    is not stored. ),tsum.{u_4, u_5} {α : Type u_4} {β : Type u_5} [AddCommMonoid α] [TopologicalSpace α] (f : β → α)
      (L : SummationFilter β := SummationFilter.unconditional β) : α`∑' i, f i` is the unconditional sum of `f` if it exists, or 0 otherwise.
    
    More generally, if `L` is a `SummationFilter`, `∑'[L] i, f i` is the sum of `f` with respect to
    `L` if it exists, and `0` otherwise.
    
    (Note that even if the unconditional sum exists, it might not be unique if the topology is not
    separated. When the support of `f` is finite, we make the most reasonable choice, to use the sum
    over the support. Otherwise, we choose arbitrarily an `a` satisfying `HasSum f a`. Similar remarks
    apply to more general summation filters.)
    
              aℕ+ → ℂ nℕ+ *HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`. Complex.expComplex.exp (z : ℂ) : ℂThe complex exponential function, defined via its Taylor series  (HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`.2 *HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`. Real.piReal.pi : ℝThe number π = 3.14159265... Defined here using choice as twice a zero of cos in [1,2],
    from which one can derive all its properties. For explicit bounds on π,
    see `Mathlib/Analysis/Real/Pi/Bounds.lean`.
    
    Denoted `π`, once the `Real` namespace is opened.  *HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`. Complex.IComplex.I : ℂThe imaginary unit.  *HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`. nℕ+ *HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`. wUpperHalfPlane)HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`.)
          zUpperHalfPlane =Eq.{u_1} {α : Sort u_1} : α → α → PropThe equality relation. It has one introduction rule, `Eq.refl`.
    We use `a = b` as notation for `Eq a b`.
    A fundamental property of equality is that it is an equivalence relation.
    ```
    variable (α : Type) (a b c d : α)
    variable (hab : a = b) (hcb : c = b) (hcd : c = d)
    
    example : a = d :=
      Eq.trans (Eq.trans hab (Eq.symm hcb)) hcd
    ```
    Equality is much more than an equivalence relation, however. It has the important property that every assertion
    respects the equivalence, in the sense that we can substitute equal expressions without changing the truth value.
    That is, given `h1 : a = b` and `h2 : p a`, we can construct a proof for `p b` using substitution: `Eq.subst h1 h2`.
    Example:
    ```
    example (α : Type) (a b : α) (p : α → Prop)
            (h1 : a = b) (h2 : p a) : p b :=
      Eq.subst h1 h2
    
    example (α : Type) (a b : α) (p : α → Prop)
        (h1 : a = b) (h2 : p a) : p b :=
      h1 ▸ h2
    ```
    The triangle in the second presentation is a macro built on top of `Eq.subst` and `Eq.symm`, and you can enter it by typing `\t`.
    For more information: [Equality](https://lean-lang.org/theorem_proving_in_lean4/quantifiers_and_equality.html#equality)
    
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `=` in identifiers is `eq`.
        ∑'tsum.{u_4, u_5} {α : Type u_4} {β : Type u_5} [AddCommMonoid α] [TopologicalSpace α] (f : β → α)
      (L : SummationFilter β := SummationFilter.unconditional β) : α`∑' i, f i` is the unconditional sum of `f` if it exists, or 0 otherwise.
    
    More generally, if `L` is a `SummationFilter`, `∑'[L] i, f i` is the sum of `f` with respect to
    `L` if it exists, and `0` otherwise.
    
    (Note that even if the unconditional sum exists, it might not be unique if the topology is not
    separated. When the support of `f` is finite, we make the most reasonable choice, to use the sum
    over the support. Otherwise, we choose arbitrarily an `a` satisfying `HasSum f a`. Similar remarks
    apply to more general summation filters.)
     (nℕ+ : ℕ+PNat : Type`ℕ+` is the type of positive natural numbers. It is defined as a subtype,
    and the VM representation of `ℕ+` is the same as `ℕ` because the proof
    is not stored. ),tsum.{u_4, u_5} {α : Type u_4} {β : Type u_5} [AddCommMonoid α] [TopologicalSpace α] (f : β → α)
      (L : SummationFilter β := SummationFilter.unconditional β) : α`∑' i, f i` is the unconditional sum of `f` if it exists, or 0 otherwise.
    
    More generally, if `L` is a `SummationFilter`, `∑'[L] i, f i` is the sum of `f` with respect to
    `L` if it exists, and `0` otherwise.
    
    (Note that even if the unconditional sum exists, it might not be unique if the topology is not
    separated. When the support of `f` is finite, we make the most reasonable choice, to use the sum
    over the support. Otherwise, we choose arbitrarily an `a` satisfying `HasSum f a`. Similar remarks
    apply to more general summation filters.)
    
          nℕ+ *HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`. aℕ+ → ℂ nℕ+ *HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`. Complex.expComplex.exp (z : ℂ) : ℂThe complex exponential function, defined via its Taylor series  (HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`.2 *HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`. Real.piReal.pi : ℝThe number π = 3.14159265... Defined here using choice as twice a zero of cos in [1,2],
    from which one can derive all its properties. For explicit bounds on π,
    see `Mathlib/Analysis/Real/Pi/Bounds.lean`.
    
    Denoted `π`, once the `Real` namespace is opened.  *HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`. Complex.IComplex.I : ℂThe imaginary unit.  *HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`. nℕ+ *HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`. zUpperHalfPlane)HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`.
    theorem D_qexp_tsum_pnat (aℕ+ → ℂ : ℕ+PNat : Type`ℕ+` is the type of positive natural numbers. It is defined as a subtype,
    and the VM representation of `ℕ+` is the same as `ℕ` because the proof
    is not stored.   Complex : TypeComplex numbers consist of two `Real`s: a real part `re` and an imaginary part `im`. )
      (zUpperHalfPlane : UpperHalfPlaneUpperHalfPlane : TypeThe open upper half plane, denoted as `ℍ` within the `UpperHalfPlane` namespace )
      (hsumSummable fun n ↦ a n * Complex.exp (2 * ↑Real.pi * Complex.I * ↑↑n * ↑z) :
        SummableSummable.{u_1, u_2} {α : Type u_1} {β : Type u_2} [AddCommMonoid α] [TopologicalSpace α] (f : β → α)
      (L : SummationFilter β := SummationFilter.unconditional β) : Prop`Summable f` means that `f` has some (infinite) sum with respect to `L`. Use `tsum` to get the
    value.  fun nℕ+ 
          aℕ+ → ℂ nℕ+ *HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`.
            Complex.expComplex.exp (z : ℂ) : ℂThe complex exponential function, defined via its Taylor series 
              (HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`.2 *HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`. Real.piReal.pi : ℝThe number π = 3.14159265... Defined here using choice as twice a zero of cos in [1,2],
    from which one can derive all its properties. For explicit bounds on π,
    see `Mathlib/Analysis/Real/Pi/Bounds.lean`.
    
    Denoted `π`, once the `Real` namespace is opened.  *HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`. Complex.IComplex.I : ℂThe imaginary unit.  *HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`.
                  nℕ+ *HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`.
                zUpperHalfPlane)HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`.)
      (hsum_deriv∀ K ⊆ {w | 0 < w.im},
      IsCompact K →
        ∃ u,
          Summable u ∧
            ∀ (n : ℕ+) (k : ↑K),
              ‖a n * (2 * ↑Real.pi * Complex.I * ↑↑n) * Complex.exp (2 * ↑Real.pi * Complex.I * ↑↑n * ↑k)‖ ≤ u n :
         KSet ℂ  {setOf.{u} {α : Type u} (p : α → Prop) : Set αTurn a predicate `p : α → Prop` into a set, also written as `{x | p x}` w |setOf.{u} {α : Type u} (p : α → Prop) : Set αTurn a predicate `p : α → Prop` into a set, also written as `{x | p x}`  0 <LT.lt.{u} {α : Type u} [self : LT α] : α → α → PropThe less-than relation: `x < y` 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `<` in identifiers is `lt`. w.imComplex.im (self : ℂ) : ℝThe imaginary part of a complex number. }setOf.{u} {α : Type u} (p : α → Prop) : Set αTurn a predicate `p : α → Prop` into a set, also written as `{x | p x}` ,
          IsCompactIsCompact.{u_1} {X : Type u_1} [TopologicalSpace X] (s : Set X) : PropA set `s` is compact if for every nontrivial filter `f` that contains `s`,
    there exists `a ∈ s` such that every set of `f` meets every neighborhood of `a`.  KSet ℂ 
             uℕ+ → ℝ,
              SummableSummable.{u_1, u_2} {α : Type u_1} {β : Type u_2} [AddCommMonoid α] [TopologicalSpace α] (f : β → α)
      (L : SummationFilter β := SummationFilter.unconditional β) : Prop`Summable f` means that `f` has some (infinite) sum with respect to `L`. Use `tsum` to get the
    value.  uℕ+ → ℝ And (a b : Prop) : Prop`And a b`, or `a ∧ b`, is the conjunction of propositions. It can be
    constructed and destructed like a pair: if `ha : a` and `hb : b` then
    `⟨ha, hb⟩ : a ∧ b`, and if `h : a ∧ b` then `h.left : a` and `h.right : b`.
    
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `∧` in identifiers is `and`.
    
     * The recommended spelling of `/\` in identifiers is `and` (prefer `∧` over `/\`).
                 (nℕ+ : ℕ+PNat : Type`ℕ+` is the type of positive natural numbers. It is defined as a subtype,
    and the VM representation of `ℕ+` is the same as `ℕ` because the proof
    is not stored. ) (k↑K : KSet ℂ),
                  Norm.norm.{u_8} {E : Type u_8} [self : Norm E] : E → ℝthe `ℝ`-valued norm function. aℕ+ → ℂ nℕ+ *HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`.
                          (HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`.2 *HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`. Real.piReal.pi : ℝThe number π = 3.14159265... Defined here using choice as twice a zero of cos in [1,2],
    from which one can derive all its properties. For explicit bounds on π,
    see `Mathlib/Analysis/Real/Pi/Bounds.lean`.
    
    Denoted `π`, once the `Real` namespace is opened.  *HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`.
                              Complex.IComplex.I : ℂThe imaginary unit.  *HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`.
                            nℕ+)HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`. *HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`.
                        Complex.expComplex.exp (z : ℂ) : ℂThe complex exponential function, defined via its Taylor series 
                          (HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`.2 *HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`. Real.piReal.pi : ℝThe number π = 3.14159265... Defined here using choice as twice a zero of cos in [1,2],
    from which one can derive all its properties. For explicit bounds on π,
    see `Mathlib/Analysis/Real/Pi/Bounds.lean`.
    
    Denoted `π`, once the `Real` namespace is opened.  *HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`.
                                Complex.IComplex.I : ℂThe imaginary unit.  *HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`.
                              nℕ+ *HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`.
                            k↑K)HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`.Norm.norm.{u_8} {E : Type u_8} [self : Norm E] : E → ℝthe `ℝ`-valued norm function.  LE.le.{u} {α : Type u} [self : LE α] : α → α → PropThe less-equal relation: `x ≤ y` 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `≤` in identifiers is `le`.
    
     * The recommended spelling of `<=` in identifiers is `le` (prefer `≤` over `<=`).
                    uℕ+ → ℝ nℕ+) :
      DD (F : UpperHalfPlane → ℂ) : UpperHalfPlane → ℂ
          (fun wUpperHalfPlane 
            ∑'tsum.{u_4, u_5} {α : Type u_4} {β : Type u_5} [AddCommMonoid α] [TopologicalSpace α] (f : β → α)
      (L : SummationFilter β := SummationFilter.unconditional β) : α`∑' i, f i` is the unconditional sum of `f` if it exists, or 0 otherwise.
    
    More generally, if `L` is a `SummationFilter`, `∑'[L] i, f i` is the sum of `f` with respect to
    `L` if it exists, and `0` otherwise.
    
    (Note that even if the unconditional sum exists, it might not be unique if the topology is not
    separated. When the support of `f` is finite, we make the most reasonable choice, to use the sum
    over the support. Otherwise, we choose arbitrarily an `a` satisfying `HasSum f a`. Similar remarks
    apply to more general summation filters.)
     (nℕ+ : ℕ+PNat : Type`ℕ+` is the type of positive natural numbers. It is defined as a subtype,
    and the VM representation of `ℕ+` is the same as `ℕ` because the proof
    is not stored. ),tsum.{u_4, u_5} {α : Type u_4} {β : Type u_5} [AddCommMonoid α] [TopologicalSpace α] (f : β → α)
      (L : SummationFilter β := SummationFilter.unconditional β) : α`∑' i, f i` is the unconditional sum of `f` if it exists, or 0 otherwise.
    
    More generally, if `L` is a `SummationFilter`, `∑'[L] i, f i` is the sum of `f` with respect to
    `L` if it exists, and `0` otherwise.
    
    (Note that even if the unconditional sum exists, it might not be unique if the topology is not
    separated. When the support of `f` is finite, we make the most reasonable choice, to use the sum
    over the support. Otherwise, we choose arbitrarily an `a` satisfying `HasSum f a`. Similar remarks
    apply to more general summation filters.)
    
              aℕ+ → ℂ nℕ+ *HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`.
                Complex.expComplex.exp (z : ℂ) : ℂThe complex exponential function, defined via its Taylor series 
                  (HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`.2 *HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`. Real.piReal.pi : ℝThe number π = 3.14159265... Defined here using choice as twice a zero of cos in [1,2],
    from which one can derive all its properties. For explicit bounds on π,
    see `Mathlib/Analysis/Real/Pi/Bounds.lean`.
    
    Denoted `π`, once the `Real` namespace is opened.  *HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`. Complex.IComplex.I : ℂThe imaginary unit.  *HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`.
                      nℕ+ *HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`.
                    wUpperHalfPlane)HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`.)
          zUpperHalfPlane =Eq.{u_1} {α : Sort u_1} : α → α → PropThe equality relation. It has one introduction rule, `Eq.refl`.
    We use `a = b` as notation for `Eq a b`.
    A fundamental property of equality is that it is an equivalence relation.
    ```
    variable (α : Type) (a b c d : α)
    variable (hab : a = b) (hcb : c = b) (hcd : c = d)
    
    example : a = d :=
      Eq.trans (Eq.trans hab (Eq.symm hcb)) hcd
    ```
    Equality is much more than an equivalence relation, however. It has the important property that every assertion
    respects the equivalence, in the sense that we can substitute equal expressions without changing the truth value.
    That is, given `h1 : a = b` and `h2 : p a`, we can construct a proof for `p b` using substitution: `Eq.subst h1 h2`.
    Example:
    ```
    example (α : Type) (a b : α) (p : α → Prop)
            (h1 : a = b) (h2 : p a) : p b :=
      Eq.subst h1 h2
    
    example (α : Type) (a b : α) (p : α → Prop)
        (h1 : a = b) (h2 : p a) : p b :=
      h1 ▸ h2
    ```
    The triangle in the second presentation is a macro built on top of `Eq.subst` and `Eq.symm`, and you can enter it by typing `\t`.
    For more information: [Equality](https://lean-lang.org/theorem_proving_in_lean4/quantifiers_and_equality.html#equality)
    
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `=` in identifiers is `eq`.
        ∑'tsum.{u_4, u_5} {α : Type u_4} {β : Type u_5} [AddCommMonoid α] [TopologicalSpace α] (f : β → α)
      (L : SummationFilter β := SummationFilter.unconditional β) : α`∑' i, f i` is the unconditional sum of `f` if it exists, or 0 otherwise.
    
    More generally, if `L` is a `SummationFilter`, `∑'[L] i, f i` is the sum of `f` with respect to
    `L` if it exists, and `0` otherwise.
    
    (Note that even if the unconditional sum exists, it might not be unique if the topology is not
    separated. When the support of `f` is finite, we make the most reasonable choice, to use the sum
    over the support. Otherwise, we choose arbitrarily an `a` satisfying `HasSum f a`. Similar remarks
    apply to more general summation filters.)
     (nℕ+ : ℕ+PNat : Type`ℕ+` is the type of positive natural numbers. It is defined as a subtype,
    and the VM representation of `ℕ+` is the same as `ℕ` because the proof
    is not stored. ),tsum.{u_4, u_5} {α : Type u_4} {β : Type u_5} [AddCommMonoid α] [TopologicalSpace α] (f : β → α)
      (L : SummationFilter β := SummationFilter.unconditional β) : α`∑' i, f i` is the unconditional sum of `f` if it exists, or 0 otherwise.
    
    More generally, if `L` is a `SummationFilter`, `∑'[L] i, f i` is the sum of `f` with respect to
    `L` if it exists, and `0` otherwise.
    
    (Note that even if the unconditional sum exists, it might not be unique if the topology is not
    separated. When the support of `f` is finite, we make the most reasonable choice, to use the sum
    over the support. Otherwise, we choose arbitrarily an `a` satisfying `HasSum f a`. Similar remarks
    apply to more general summation filters.)
    
          nℕ+ *HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`. aℕ+ → ℂ nℕ+ *HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`.
            Complex.expComplex.exp (z : ℂ) : ℂThe complex exponential function, defined via its Taylor series 
              (HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`.2 *HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`. Real.piReal.pi : ℝThe number π = 3.14159265... Defined here using choice as twice a zero of cos in [1,2],
    from which one can derive all its properties. For explicit bounds on π,
    see `Mathlib/Analysis/Real/Pi/Bounds.lean`.
    
    Denoted `π`, once the `Real` namespace is opened.  *HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`. Complex.IComplex.I : ℂThe imaginary unit.  *HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`.
                  nℕ+ *HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`.
                zUpperHalfPlane)HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`.
    Simplified version of `D_qexp_tsum` for ℕ+-indexed series (starting from n=1).
    This is the form most commonly used for Eisenstein series q-expansions.
    
    **Thin layer implementation:** Extends `a : ℕ+ → ℂ` to `ℕ → ℂ` with `a' 0 = 0`,
    uses `tsum_pNat` and `nat_pos_tsum2` to convert between sums,
    then applies `D_qexp_tsum`.
    
    complete
Proof

This follows directly from the definition Definition 7.43, since \frac{1}{2 \pi i}\frac{\dd}{\dd z}e^{2\pi i n z} = n e^{2\pi i n z}.

For k \in \mathbb{R}, define the weight-k Serre derivative \partial_k of a modular form F by \partial_k F := F' - \frac{k}{12} E_2 F. Uses Definition 7.43 and Definition 7.17.

Lean code for Definition7.451 definition
  • def serre_D (k : Complex : TypeComplex numbers consist of two `Real`s: a real part `re` and an imaginary part `im`. ) : (UpperHalfPlaneUpperHalfPlane : TypeThe open upper half plane, denoted as `ℍ` within the `UpperHalfPlane` namespace   Complex : TypeComplex numbers consist of two `Real`s: a real part `re` and an imaginary part `im`. )  UpperHalfPlaneUpperHalfPlane : TypeThe open upper half plane, denoted as `ℍ` within the `UpperHalfPlane` namespace   Complex : TypeComplex numbers consist of two `Real`s: a real part `re` and an imaginary part `im`. 
    def serre_D (k : Complex : TypeComplex numbers consist of two `Real`s: a real part `re` and an imaginary part `im`. ) :
      (UpperHalfPlaneUpperHalfPlane : TypeThe open upper half plane, denoted as `ℍ` within the `UpperHalfPlane` namespace   Complex : TypeComplex numbers consist of two `Real`s: a real part `re` and an imaginary part `im`. ) 
        UpperHalfPlaneUpperHalfPlane : TypeThe open upper half plane, denoted as `ℍ` within the `UpperHalfPlane` namespace   Complex : TypeComplex numbers consist of two `Real`s: a real part `re` and an imaginary part `im`. 
    Serre derivative of weight $k$.
    Note that the definition makes sense for any analytic function $F : \mathbb{H} \to \mathbb{C}$.
    
    complete
Theorem7.46
L∃∀Nused by 1

Serre derivative \partial_k is equivariant with the slash action of \mathrm{SL}_{2}(\mathbb{Z}) in the sense that \partial_{k} (F|_{k}\gamma) = (\partial_{k} F)|_{k+2}\gamma, \quad \forall \gamma \in \mathrm{SL}_{2}(\mathbb{Z}). Uses Definition 7.45, Definition 7.17, and Lemma 7.19.

Lean code for Theorem7.461 theorem
  • theorem serre_D_slash_equivariant (k : Int : TypeThe integers.
    
    This type is special-cased by the compiler and overridden with an efficient implementation. The
    runtime has a special representation for `Int` that stores “small” signed numbers directly, while
    larger numbers use a fast arbitrary-precision arithmetic library (usually
    [GMP](https://gmplib.org/)). A “small number” is an integer that can be encoded with one fewer bits
    than the platform's pointer size (i.e. 63 bits on 64-bit architectures and 31 bits on 32-bit
    architectures).
    ) (FUpperHalfPlane → ℂ : UpperHalfPlaneUpperHalfPlane : TypeThe open upper half plane, denoted as `ℍ` within the `UpperHalfPlane` namespace   Complex : TypeComplex numbers consist of two `Real`s: a real part `re` and an imaginary part `im`. )
      (hFMDiff F : MDiff FUpperHalfPlane → ℂ) (γMatrix.SpecialLinearGroup (Fin 2) ℤ : Matrix.SpecialLinearGroupMatrix.SpecialLinearGroup.{u, v} (n : Type u) [DecidableEq n] [Fintype n] (R : Type v) [CommRing R] : Type (max 0 u v)`SpecialLinearGroup n R` is the group of `n` by `n` `R`-matrices with determinant equal to 1.
     (FinFin (n : ℕ) : TypeNatural numbers less than some upper bound.
    
    In particular, a `Fin n` is a natural number `i` with the constraint that `i < n`. It is the
    canonical type with `n` elements.
     2) Int : TypeThe integers.
    
    This type is special-cased by the compiler and overridden with an efficient implementation. The
    runtime has a special representation for `Int` that stores “small” signed numbers directly, while
    larger numbers use a fast arbitrary-precision arithmetic library (usually
    [GMP](https://gmplib.org/)). A “small number” is an integer that can be encoded with one fewer bits
    than the platform's pointer size (i.e. 63 bits on 64-bit architectures and 31 bits on 32-bit
    architectures).
    ) :
      SlashAction.mapSlashAction.map.{u_1, u_2, u_3} {β : Type u_1} {G : Type u_2} {α : Type u_3} {inst✝ : Monoid G} {inst✝¹ : AddMonoid α}
      [self : SlashAction β G α] : β → G → α → α (HAdd.hAdd.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HAdd α β γ] : α → β → γ`a + b` computes the sum of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `+` in identifiers is `add`.k +HAdd.hAdd.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HAdd α β γ] : α → β → γ`a + b` computes the sum of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `+` in identifiers is `add`. 2)HAdd.hAdd.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HAdd α β γ] : α → β → γ`a + b` computes the sum of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `+` in identifiers is `add`. γMatrix.SpecialLinearGroup (Fin 2) ℤ (serre_Dserre_D (k : ℂ) : (UpperHalfPlane → ℂ) → UpperHalfPlane → ℂSerre derivative of weight $k$.
    Note that the definition makes sense for any analytic function $F : \mathbb{H} \to \mathbb{C}$.
     (↑k) FUpperHalfPlane → ℂ) =Eq.{u_1} {α : Sort u_1} : α → α → PropThe equality relation. It has one introduction rule, `Eq.refl`.
    We use `a = b` as notation for `Eq a b`.
    A fundamental property of equality is that it is an equivalence relation.
    ```
    variable (α : Type) (a b c d : α)
    variable (hab : a = b) (hcb : c = b) (hcd : c = d)
    
    example : a = d :=
      Eq.trans (Eq.trans hab (Eq.symm hcb)) hcd
    ```
    Equality is much more than an equivalence relation, however. It has the important property that every assertion
    respects the equivalence, in the sense that we can substitute equal expressions without changing the truth value.
    That is, given `h1 : a = b` and `h2 : p a`, we can construct a proof for `p b` using substitution: `Eq.subst h1 h2`.
    Example:
    ```
    example (α : Type) (a b : α) (p : α → Prop)
            (h1 : a = b) (h2 : p a) : p b :=
      Eq.subst h1 h2
    
    example (α : Type) (a b : α) (p : α → Prop)
        (h1 : a = b) (h2 : p a) : p b :=
      h1 ▸ h2
    ```
    The triangle in the second presentation is a macro built on top of `Eq.subst` and `Eq.symm`, and you can enter it by typing `\t`.
    For more information: [Equality](https://lean-lang.org/theorem_proving_in_lean4/quantifiers_and_equality.html#equality)
    
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `=` in identifiers is `eq`.
        serre_Dserre_D (k : ℂ) : (UpperHalfPlane → ℂ) → UpperHalfPlane → ℂSerre derivative of weight $k$.
    Note that the definition makes sense for any analytic function $F : \mathbb{H} \to \mathbb{C}$.
     (↑k) (SlashAction.mapSlashAction.map.{u_1, u_2, u_3} {β : Type u_1} {G : Type u_2} {α : Type u_3} {inst✝ : Monoid G} {inst✝¹ : AddMonoid α}
      [self : SlashAction β G α] : β → G → α → α k γMatrix.SpecialLinearGroup (Fin 2) ℤ FUpperHalfPlane → ℂ)
    theorem serre_D_slash_equivariant (k : Int : TypeThe integers.
    
    This type is special-cased by the compiler and overridden with an efficient implementation. The
    runtime has a special representation for `Int` that stores “small” signed numbers directly, while
    larger numbers use a fast arbitrary-precision arithmetic library (usually
    [GMP](https://gmplib.org/)). A “small number” is an integer that can be encoded with one fewer bits
    than the platform's pointer size (i.e. 63 bits on 64-bit architectures and 31 bits on 32-bit
    architectures).
    )
      (FUpperHalfPlane → ℂ : UpperHalfPlaneUpperHalfPlane : TypeThe open upper half plane, denoted as `ℍ` within the `UpperHalfPlane` namespace   Complex : TypeComplex numbers consist of two `Real`s: a real part `re` and an imaginary part `im`. ) (hFMDiff F : MDiff FUpperHalfPlane → ℂ)
      (γMatrix.SpecialLinearGroup (Fin 2) ℤ :
        Matrix.SpecialLinearGroupMatrix.SpecialLinearGroup.{u, v} (n : Type u) [DecidableEq n] [Fintype n] (R : Type v) [CommRing R] : Type (max 0 u v)`SpecialLinearGroup n R` is the group of `n` by `n` `R`-matrices with determinant equal to 1.
     (FinFin (n : ℕ) : TypeNatural numbers less than some upper bound.
    
    In particular, a `Fin n` is a natural number `i` with the constraint that `i < n`. It is the
    canonical type with `n` elements.
     2) Int : TypeThe integers.
    
    This type is special-cased by the compiler and overridden with an efficient implementation. The
    runtime has a special representation for `Int` that stores “small” signed numbers directly, while
    larger numbers use a fast arbitrary-precision arithmetic library (usually
    [GMP](https://gmplib.org/)). A “small number” is an integer that can be encoded with one fewer bits
    than the platform's pointer size (i.e. 63 bits on 64-bit architectures and 31 bits on 32-bit
    architectures).
    ) :
      SlashAction.mapSlashAction.map.{u_1, u_2, u_3} {β : Type u_1} {G : Type u_2} {α : Type u_3} {inst✝ : Monoid G} {inst✝¹ : AddMonoid α}
      [self : SlashAction β G α] : β → G → α → α (HAdd.hAdd.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HAdd α β γ] : α → β → γ`a + b` computes the sum of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `+` in identifiers is `add`.k +HAdd.hAdd.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HAdd α β γ] : α → β → γ`a + b` computes the sum of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `+` in identifiers is `add`. 2)HAdd.hAdd.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HAdd α β γ] : α → β → γ`a + b` computes the sum of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `+` in identifiers is `add`. γMatrix.SpecialLinearGroup (Fin 2) ℤ
          (serre_Dserre_D (k : ℂ) : (UpperHalfPlane → ℂ) → UpperHalfPlane → ℂSerre derivative of weight $k$.
    Note that the definition makes sense for any analytic function $F : \mathbb{H} \to \mathbb{C}$.
     (↑k) FUpperHalfPlane → ℂ) =Eq.{u_1} {α : Sort u_1} : α → α → PropThe equality relation. It has one introduction rule, `Eq.refl`.
    We use `a = b` as notation for `Eq a b`.
    A fundamental property of equality is that it is an equivalence relation.
    ```
    variable (α : Type) (a b c d : α)
    variable (hab : a = b) (hcb : c = b) (hcd : c = d)
    
    example : a = d :=
      Eq.trans (Eq.trans hab (Eq.symm hcb)) hcd
    ```
    Equality is much more than an equivalence relation, however. It has the important property that every assertion
    respects the equivalence, in the sense that we can substitute equal expressions without changing the truth value.
    That is, given `h1 : a = b` and `h2 : p a`, we can construct a proof for `p b` using substitution: `Eq.subst h1 h2`.
    Example:
    ```
    example (α : Type) (a b : α) (p : α → Prop)
            (h1 : a = b) (h2 : p a) : p b :=
      Eq.subst h1 h2
    
    example (α : Type) (a b : α) (p : α → Prop)
        (h1 : a = b) (h2 : p a) : p b :=
      h1 ▸ h2
    ```
    The triangle in the second presentation is a macro built on top of `Eq.subst` and `Eq.symm`, and you can enter it by typing `\t`.
    For more information: [Equality](https://lean-lang.org/theorem_proving_in_lean4/quantifiers_and_equality.html#equality)
    
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `=` in identifiers is `eq`.
        serre_Dserre_D (k : ℂ) : (UpperHalfPlane → ℂ) → UpperHalfPlane → ℂSerre derivative of weight $k$.
    Note that the definition makes sense for any analytic function $F : \mathbb{H} \to \mathbb{C}$.
     (↑k) (SlashAction.mapSlashAction.map.{u_1, u_2, u_3} {β : Type u_1} {G : Type u_2} {α : Type u_3} {inst✝ : Monoid G} {inst✝¹ : AddMonoid α}
      [self : SlashAction β G α] : β → G → α → α k γMatrix.SpecialLinearGroup (Fin 2) ℤ FUpperHalfPlane → ℂ)
    Serre derivative is equivariant under the slash action. More precisely, if `F` is invariant
    under the slash action of weight `k`, then `serre_D k F` is invariant under the slash action
    of weight `k + 2`.
    
    complete
Proof

Let G = \partial_kF = F' - \frac{k}{12}E_2F. From F \in M_k(\Gamma), we have (F|_{k}\gamma)(z) := (cz + d)^{-k} F\left(\frac{az + b}{cz + d}\right), \quad \gamma = \begin{pmatrix}a & b \\ c & d\end{pmatrix} \in \Gamma. By taking the derivative of the above equation, we get \begin{aligned} \frac{\dd}{\dd z}(F|_{k} \gamma)(z) &= -kc (cz + d)^{-k - 1} F\left(\frac{az + b}{cz + d}\right) + (cz + d)^{-k} (cz + d)^{-2} \frac{\dd F}{\dd z}\left(\frac{az + b}{cz + d}\right) \\ &= -kc (cz + d)^{-k - 1} F\left(\frac{az + b}{cz + d}\right) + (cz + d)^{-k - 2} \frac{\dd F}{\dd z}\left(\frac{az + b}{cz + d}\right) \\ &= -kc (cz + d)^{-k - 1} F\left(\frac{az + b}{cz + d}\right) + 2 \pi i (cz + d)^{-k - 2} F'\left(\frac{az + b}{cz + d}\right) \\ \Leftrightarrow (F|_{k} \gamma)'(z) &= -\frac{kc}{2 \pi i} (cz + d)^{-k - 1} F\left(\frac{az + b}{cz + d}\right) + (cz + d)^{-k - 2} F'\left(\frac{az + b}{cz + d}\right). \end{aligned} Combined with eqn:E2-transform-general, we get \begin{aligned} ((\partial_k F)|_{k+2}\gamma)(z) &= (cz + d)^{-k-2} \left(F'\left(\frac{az + b}{cz + d}\right) - \frac{k}{12}E_2\left(\frac{az + b}{cz + d}\right)F\left(\frac{az + b}{cz + d}\right)\right) \\ &= (cz + d)^{-k-2} F'\left(\frac{az + b}{cz + d}\right) - \frac{k}{12} \left(E_2(z) - \frac{6ic}{\pi(cz + d)}\right) \cdot (cz + d)^{-k} F\left(\frac{az + b}{cz + d}\right) \\ &= (F|_{k}\gamma)'(z) - \frac{k}{12} E_2(z) (F|_{k}\gamma)(z) \\ &= \partial_{k} (F|_{k}\gamma)(z). \end{aligned}

Theorem7.47
L∃∀Nused by 1

Let F be a modular form of weight k and level \Gamma. Then \partial_{k}F is a modular form of weight k + 2 of the same level. Uses Definition 7.45, Definition 7.12, and Theorem 7.46.

Lean code for Theorem7.471 theorem
  • theorem serre_D_slash_invariant (k : Int : TypeThe integers.
    
    This type is special-cased by the compiler and overridden with an efficient implementation. The
    runtime has a special representation for `Int` that stores “small” signed numbers directly, while
    larger numbers use a fast arbitrary-precision arithmetic library (usually
    [GMP](https://gmplib.org/)). A “small number” is an integer that can be encoded with one fewer bits
    than the platform's pointer size (i.e. 63 bits on 64-bit architectures and 31 bits on 32-bit
    architectures).
    ) (FUpperHalfPlane → ℂ : UpperHalfPlaneUpperHalfPlane : TypeThe open upper half plane, denoted as `ℍ` within the `UpperHalfPlane` namespace   Complex : TypeComplex numbers consist of two `Real`s: a real part `re` and an imaginary part `im`. ) (hFMDiff F : MDiff FUpperHalfPlane → ℂ)
      (γMatrix.SpecialLinearGroup (Fin 2) ℤ : Matrix.SpecialLinearGroupMatrix.SpecialLinearGroup.{u, v} (n : Type u) [DecidableEq n] [Fintype n] (R : Type v) [CommRing R] : Type (max 0 u v)`SpecialLinearGroup n R` is the group of `n` by `n` `R`-matrices with determinant equal to 1.
     (FinFin (n : ℕ) : TypeNatural numbers less than some upper bound.
    
    In particular, a `Fin n` is a natural number `i` with the constraint that `i < n`. It is the
    canonical type with `n` elements.
     2) Int : TypeThe integers.
    
    This type is special-cased by the compiler and overridden with an efficient implementation. The
    runtime has a special representation for `Int` that stores “small” signed numbers directly, while
    larger numbers use a fast arbitrary-precision arithmetic library (usually
    [GMP](https://gmplib.org/)). A “small number” is an integer that can be encoded with one fewer bits
    than the platform's pointer size (i.e. 63 bits on 64-bit architectures and 31 bits on 32-bit
    architectures).
    )
      (hSlashAction.map k γ F = F : SlashAction.mapSlashAction.map.{u_1, u_2, u_3} {β : Type u_1} {G : Type u_2} {α : Type u_3} {inst✝ : Monoid G} {inst✝¹ : AddMonoid α}
      [self : SlashAction β G α] : β → G → α → α k γMatrix.SpecialLinearGroup (Fin 2) ℤ FUpperHalfPlane → ℂ =Eq.{u_1} {α : Sort u_1} : α → α → PropThe equality relation. It has one introduction rule, `Eq.refl`.
    We use `a = b` as notation for `Eq a b`.
    A fundamental property of equality is that it is an equivalence relation.
    ```
    variable (α : Type) (a b c d : α)
    variable (hab : a = b) (hcb : c = b) (hcd : c = d)
    
    example : a = d :=
      Eq.trans (Eq.trans hab (Eq.symm hcb)) hcd
    ```
    Equality is much more than an equivalence relation, however. It has the important property that every assertion
    respects the equivalence, in the sense that we can substitute equal expressions without changing the truth value.
    That is, given `h1 : a = b` and `h2 : p a`, we can construct a proof for `p b` using substitution: `Eq.subst h1 h2`.
    Example:
    ```
    example (α : Type) (a b : α) (p : α → Prop)
            (h1 : a = b) (h2 : p a) : p b :=
      Eq.subst h1 h2
    
    example (α : Type) (a b : α) (p : α → Prop)
        (h1 : a = b) (h2 : p a) : p b :=
      h1 ▸ h2
    ```
    The triangle in the second presentation is a macro built on top of `Eq.subst` and `Eq.symm`, and you can enter it by typing `\t`.
    For more information: [Equality](https://lean-lang.org/theorem_proving_in_lean4/quantifiers_and_equality.html#equality)
    
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `=` in identifiers is `eq`. FUpperHalfPlane → ℂ) :
      SlashAction.mapSlashAction.map.{u_1, u_2, u_3} {β : Type u_1} {G : Type u_2} {α : Type u_3} {inst✝ : Monoid G} {inst✝¹ : AddMonoid α}
      [self : SlashAction β G α] : β → G → α → α (HAdd.hAdd.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HAdd α β γ] : α → β → γ`a + b` computes the sum of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `+` in identifiers is `add`.k +HAdd.hAdd.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HAdd α β γ] : α → β → γ`a + b` computes the sum of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `+` in identifiers is `add`. 2)HAdd.hAdd.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HAdd α β γ] : α → β → γ`a + b` computes the sum of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `+` in identifiers is `add`. γMatrix.SpecialLinearGroup (Fin 2) ℤ (serre_Dserre_D (k : ℂ) : (UpperHalfPlane → ℂ) → UpperHalfPlane → ℂSerre derivative of weight $k$.
    Note that the definition makes sense for any analytic function $F : \mathbb{H} \to \mathbb{C}$.
     (↑k) FUpperHalfPlane → ℂ) =Eq.{u_1} {α : Sort u_1} : α → α → PropThe equality relation. It has one introduction rule, `Eq.refl`.
    We use `a = b` as notation for `Eq a b`.
    A fundamental property of equality is that it is an equivalence relation.
    ```
    variable (α : Type) (a b c d : α)
    variable (hab : a = b) (hcb : c = b) (hcd : c = d)
    
    example : a = d :=
      Eq.trans (Eq.trans hab (Eq.symm hcb)) hcd
    ```
    Equality is much more than an equivalence relation, however. It has the important property that every assertion
    respects the equivalence, in the sense that we can substitute equal expressions without changing the truth value.
    That is, given `h1 : a = b` and `h2 : p a`, we can construct a proof for `p b` using substitution: `Eq.subst h1 h2`.
    Example:
    ```
    example (α : Type) (a b : α) (p : α → Prop)
            (h1 : a = b) (h2 : p a) : p b :=
      Eq.subst h1 h2
    
    example (α : Type) (a b : α) (p : α → Prop)
        (h1 : a = b) (h2 : p a) : p b :=
      h1 ▸ h2
    ```
    The triangle in the second presentation is a macro built on top of `Eq.subst` and `Eq.symm`, and you can enter it by typing `\t`.
    For more information: [Equality](https://lean-lang.org/theorem_proving_in_lean4/quantifiers_and_equality.html#equality)
    
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `=` in identifiers is `eq`. serre_Dserre_D (k : ℂ) : (UpperHalfPlane → ℂ) → UpperHalfPlane → ℂSerre derivative of weight $k$.
    Note that the definition makes sense for any analytic function $F : \mathbb{H} \to \mathbb{C}$.
     (↑k) FUpperHalfPlane → ℂ
    theorem serre_D_slash_invariant (k : Int : TypeThe integers.
    
    This type is special-cased by the compiler and overridden with an efficient implementation. The
    runtime has a special representation for `Int` that stores “small” signed numbers directly, while
    larger numbers use a fast arbitrary-precision arithmetic library (usually
    [GMP](https://gmplib.org/)). A “small number” is an integer that can be encoded with one fewer bits
    than the platform's pointer size (i.e. 63 bits on 64-bit architectures and 31 bits on 32-bit
    architectures).
    )
      (FUpperHalfPlane → ℂ : UpperHalfPlaneUpperHalfPlane : TypeThe open upper half plane, denoted as `ℍ` within the `UpperHalfPlane` namespace   Complex : TypeComplex numbers consist of two `Real`s: a real part `re` and an imaginary part `im`. ) (hFMDiff F : MDiff FUpperHalfPlane → ℂ)
      (γMatrix.SpecialLinearGroup (Fin 2) ℤ :
        Matrix.SpecialLinearGroupMatrix.SpecialLinearGroup.{u, v} (n : Type u) [DecidableEq n] [Fintype n] (R : Type v) [CommRing R] : Type (max 0 u v)`SpecialLinearGroup n R` is the group of `n` by `n` `R`-matrices with determinant equal to 1.
     (FinFin (n : ℕ) : TypeNatural numbers less than some upper bound.
    
    In particular, a `Fin n` is a natural number `i` with the constraint that `i < n`. It is the
    canonical type with `n` elements.
     2) Int : TypeThe integers.
    
    This type is special-cased by the compiler and overridden with an efficient implementation. The
    runtime has a special representation for `Int` that stores “small” signed numbers directly, while
    larger numbers use a fast arbitrary-precision arithmetic library (usually
    [GMP](https://gmplib.org/)). A “small number” is an integer that can be encoded with one fewer bits
    than the platform's pointer size (i.e. 63 bits on 64-bit architectures and 31 bits on 32-bit
    architectures).
    )
      (hSlashAction.map k γ F = F : SlashAction.mapSlashAction.map.{u_1, u_2, u_3} {β : Type u_1} {G : Type u_2} {α : Type u_3} {inst✝ : Monoid G} {inst✝¹ : AddMonoid α}
      [self : SlashAction β G α] : β → G → α → α k γMatrix.SpecialLinearGroup (Fin 2) ℤ FUpperHalfPlane → ℂ =Eq.{u_1} {α : Sort u_1} : α → α → PropThe equality relation. It has one introduction rule, `Eq.refl`.
    We use `a = b` as notation for `Eq a b`.
    A fundamental property of equality is that it is an equivalence relation.
    ```
    variable (α : Type) (a b c d : α)
    variable (hab : a = b) (hcb : c = b) (hcd : c = d)
    
    example : a = d :=
      Eq.trans (Eq.trans hab (Eq.symm hcb)) hcd
    ```
    Equality is much more than an equivalence relation, however. It has the important property that every assertion
    respects the equivalence, in the sense that we can substitute equal expressions without changing the truth value.
    That is, given `h1 : a = b` and `h2 : p a`, we can construct a proof for `p b` using substitution: `Eq.subst h1 h2`.
    Example:
    ```
    example (α : Type) (a b : α) (p : α → Prop)
            (h1 : a = b) (h2 : p a) : p b :=
      Eq.subst h1 h2
    
    example (α : Type) (a b : α) (p : α → Prop)
        (h1 : a = b) (h2 : p a) : p b :=
      h1 ▸ h2
    ```
    The triangle in the second presentation is a macro built on top of `Eq.subst` and `Eq.symm`, and you can enter it by typing `\t`.
    For more information: [Equality](https://lean-lang.org/theorem_proving_in_lean4/quantifiers_and_equality.html#equality)
    
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `=` in identifiers is `eq`. FUpperHalfPlane → ℂ) :
      SlashAction.mapSlashAction.map.{u_1, u_2, u_3} {β : Type u_1} {G : Type u_2} {α : Type u_3} {inst✝ : Monoid G} {inst✝¹ : AddMonoid α}
      [self : SlashAction β G α] : β → G → α → α (HAdd.hAdd.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HAdd α β γ] : α → β → γ`a + b` computes the sum of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `+` in identifiers is `add`.k +HAdd.hAdd.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HAdd α β γ] : α → β → γ`a + b` computes the sum of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `+` in identifiers is `add`. 2)HAdd.hAdd.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HAdd α β γ] : α → β → γ`a + b` computes the sum of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `+` in identifiers is `add`. γMatrix.SpecialLinearGroup (Fin 2) ℤ
          (serre_Dserre_D (k : ℂ) : (UpperHalfPlane → ℂ) → UpperHalfPlane → ℂSerre derivative of weight $k$.
    Note that the definition makes sense for any analytic function $F : \mathbb{H} \to \mathbb{C}$.
     (↑k) FUpperHalfPlane → ℂ) =Eq.{u_1} {α : Sort u_1} : α → α → PropThe equality relation. It has one introduction rule, `Eq.refl`.
    We use `a = b` as notation for `Eq a b`.
    A fundamental property of equality is that it is an equivalence relation.
    ```
    variable (α : Type) (a b c d : α)
    variable (hab : a = b) (hcb : c = b) (hcd : c = d)
    
    example : a = d :=
      Eq.trans (Eq.trans hab (Eq.symm hcb)) hcd
    ```
    Equality is much more than an equivalence relation, however. It has the important property that every assertion
    respects the equivalence, in the sense that we can substitute equal expressions without changing the truth value.
    That is, given `h1 : a = b` and `h2 : p a`, we can construct a proof for `p b` using substitution: `Eq.subst h1 h2`.
    Example:
    ```
    example (α : Type) (a b : α) (p : α → Prop)
            (h1 : a = b) (h2 : p a) : p b :=
      Eq.subst h1 h2
    
    example (α : Type) (a b : α) (p : α → Prop)
        (h1 : a = b) (h2 : p a) : p b :=
      h1 ▸ h2
    ```
    The triangle in the second presentation is a macro built on top of `Eq.subst` and `Eq.symm`, and you can enter it by typing `\t`.
    For more information: [Equality](https://lean-lang.org/theorem_proving_in_lean4/quantifiers_and_equality.html#equality)
    
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `=` in identifiers is `eq`.
        serre_Dserre_D (k : ℂ) : (UpperHalfPlane → ℂ) → UpperHalfPlane → ℂSerre derivative of weight $k$.
    Note that the definition makes sense for any analytic function $F : \mathbb{H} \to \mathbb{C}$.
     (↑k) FUpperHalfPlane → ℂ
    complete
Proof

Immediate from Theorem Theorem 7.46 since F|_k\gamma = F for all \gamma \in \Gamma.

Theorem7.48
L∃∀N

We have E_2' = \frac{E_2^2 - E_4}{12} E_4' = \frac{E_2 E_4 - E_6}{3} E_6' = \frac{E_2 E_6 - E_4^2}{2}. Uses Theorem 7.47, Definition 7.45, Lemma 7.19, and Corollary 7.30.

Lean code for Theorem7.486 theorems
  • theorem ramanujan_E₂ : DD (F : UpperHalfPlane → ℂ) : UpperHalfPlane → ℂ E₂E₂ : UpperHalfPlane → ℂCompatibility alias for Mathlib's `EisensteinSeries.E2`.  =Eq.{u_1} {α : Sort u_1} : α → α → PropThe equality relation. It has one introduction rule, `Eq.refl`.
    We use `a = b` as notation for `Eq a b`.
    A fundamental property of equality is that it is an equivalence relation.
    ```
    variable (α : Type) (a b c d : α)
    variable (hab : a = b) (hcb : c = b) (hcd : c = d)
    
    example : a = d :=
      Eq.trans (Eq.trans hab (Eq.symm hcb)) hcd
    ```
    Equality is much more than an equivalence relation, however. It has the important property that every assertion
    respects the equivalence, in the sense that we can substitute equal expressions without changing the truth value.
    That is, given `h1 : a = b` and `h2 : p a`, we can construct a proof for `p b` using substitution: `Eq.subst h1 h2`.
    Example:
    ```
    example (α : Type) (a b : α) (p : α → Prop)
            (h1 : a = b) (h2 : p a) : p b :=
      Eq.subst h1 h2
    
    example (α : Type) (a b : α) (p : α → Prop)
        (h1 : a = b) (h2 : p a) : p b :=
      h1 ▸ h2
    ```
    The triangle in the second presentation is a macro built on top of `Eq.subst` and `Eq.symm`, and you can enter it by typing `\t`.
    For more information: [Equality](https://lean-lang.org/theorem_proving_in_lean4/quantifiers_and_equality.html#equality)
    
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `=` in identifiers is `eq`. 12⁻¹Inv.inv.{u} {α : Type u} [self : Inv α] : α → α`a⁻¹` computes the inverse of `a`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `⁻¹` in identifiers is `inv`. *HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`. (HSub.hSub.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HSub α β γ] : α → β → γ`a - b` computes the difference of `a` and `b`.
    The meaning of this notation is type-dependent.
    * For natural numbers, this operator saturates at 0: `a - b = 0` when `a ≤ b`. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `-` in identifiers is `sub` (when used as a binary operator).E₂E₂ : UpperHalfPlane → ℂCompatibility alias for Mathlib's `EisensteinSeries.E2`.  *HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`. E₂E₂ : UpperHalfPlane → ℂCompatibility alias for Mathlib's `EisensteinSeries.E2`.  -HSub.hSub.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HSub α β γ] : α → β → γ`a - b` computes the difference of `a` and `b`.
    The meaning of this notation is type-dependent.
    * For natural numbers, this operator saturates at 0: `a - b = 0` when `a ≤ b`. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `-` in identifiers is `sub` (when used as a binary operator). E₄E₄ : ModularForm (Subgroup.map (Matrix.SpecialLinearGroup.mapGL ℝ) (CongruenceSubgroup.Gamma 1)) 4.toFunSlashInvariantForm.toFun {Γ : outParam (Subgroup (GL (Fin 2) ℝ))} {k : outParam ℤ} (self : SlashInvariantForm Γ k) :
      UpperHalfPlane → ℂThe underlying function `ℍ → ℂ`.
    
    Do NOT use directly. Use the coercion instead. )HSub.hSub.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HSub α β γ] : α → β → γ`a - b` computes the difference of `a` and `b`.
    The meaning of this notation is type-dependent.
    * For natural numbers, this operator saturates at 0: `a - b = 0` when `a ≤ b`. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `-` in identifiers is `sub` (when used as a binary operator).
    theorem ramanujan_E₂ :
      DD (F : UpperHalfPlane → ℂ) : UpperHalfPlane → ℂ E₂E₂ : UpperHalfPlane → ℂCompatibility alias for Mathlib's `EisensteinSeries.E2`.  =Eq.{u_1} {α : Sort u_1} : α → α → PropThe equality relation. It has one introduction rule, `Eq.refl`.
    We use `a = b` as notation for `Eq a b`.
    A fundamental property of equality is that it is an equivalence relation.
    ```
    variable (α : Type) (a b c d : α)
    variable (hab : a = b) (hcb : c = b) (hcd : c = d)
    
    example : a = d :=
      Eq.trans (Eq.trans hab (Eq.symm hcb)) hcd
    ```
    Equality is much more than an equivalence relation, however. It has the important property that every assertion
    respects the equivalence, in the sense that we can substitute equal expressions without changing the truth value.
    That is, given `h1 : a = b` and `h2 : p a`, we can construct a proof for `p b` using substitution: `Eq.subst h1 h2`.
    Example:
    ```
    example (α : Type) (a b : α) (p : α → Prop)
            (h1 : a = b) (h2 : p a) : p b :=
      Eq.subst h1 h2
    
    example (α : Type) (a b : α) (p : α → Prop)
        (h1 : a = b) (h2 : p a) : p b :=
      h1 ▸ h2
    ```
    The triangle in the second presentation is a macro built on top of `Eq.subst` and `Eq.symm`, and you can enter it by typing `\t`.
    For more information: [Equality](https://lean-lang.org/theorem_proving_in_lean4/quantifiers_and_equality.html#equality)
    
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `=` in identifiers is `eq`. 12⁻¹Inv.inv.{u} {α : Type u} [self : Inv α] : α → α`a⁻¹` computes the inverse of `a`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `⁻¹` in identifiers is `inv`. *HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`. (HSub.hSub.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HSub α β γ] : α → β → γ`a - b` computes the difference of `a` and `b`.
    The meaning of this notation is type-dependent.
    * For natural numbers, this operator saturates at 0: `a - b = 0` when `a ≤ b`. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `-` in identifiers is `sub` (when used as a binary operator).E₂E₂ : UpperHalfPlane → ℂCompatibility alias for Mathlib's `EisensteinSeries.E2`.  *HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`. E₂E₂ : UpperHalfPlane → ℂCompatibility alias for Mathlib's `EisensteinSeries.E2`.  -HSub.hSub.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HSub α β γ] : α → β → γ`a - b` computes the difference of `a` and `b`.
    The meaning of this notation is type-dependent.
    * For natural numbers, this operator saturates at 0: `a - b = 0` when `a ≤ b`. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `-` in identifiers is `sub` (when used as a binary operator). E₄E₄ : ModularForm (Subgroup.map (Matrix.SpecialLinearGroup.mapGL ℝ) (CongruenceSubgroup.Gamma 1)) 4.toFunSlashInvariantForm.toFun {Γ : outParam (Subgroup (GL (Fin 2) ℝ))} {k : outParam ℤ} (self : SlashInvariantForm Γ k) :
      UpperHalfPlane → ℂThe underlying function `ℍ → ℂ`.
    
    Do NOT use directly. Use the coercion instead. )HSub.hSub.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HSub α β γ] : α → β → γ`a - b` computes the difference of `a` and `b`.
    The meaning of this notation is type-dependent.
    * For natural numbers, this operator saturates at 0: `a - b = 0` when `a ≤ b`. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `-` in identifiers is `sub` (when used as a binary operator).
    complete
  • theorem ramanujan_E₄ : DD (F : UpperHalfPlane → ℂ) : UpperHalfPlane → ℂ E₄E₄ : ModularForm (Subgroup.map (Matrix.SpecialLinearGroup.mapGL ℝ) (CongruenceSubgroup.Gamma 1)) 4.toFunSlashInvariantForm.toFun {Γ : outParam (Subgroup (GL (Fin 2) ℝ))} {k : outParam ℤ} (self : SlashInvariantForm Γ k) :
      UpperHalfPlane → ℂThe underlying function `ℍ → ℂ`.
    
    Do NOT use directly. Use the coercion instead.  =Eq.{u_1} {α : Sort u_1} : α → α → PropThe equality relation. It has one introduction rule, `Eq.refl`.
    We use `a = b` as notation for `Eq a b`.
    A fundamental property of equality is that it is an equivalence relation.
    ```
    variable (α : Type) (a b c d : α)
    variable (hab : a = b) (hcb : c = b) (hcd : c = d)
    
    example : a = d :=
      Eq.trans (Eq.trans hab (Eq.symm hcb)) hcd
    ```
    Equality is much more than an equivalence relation, however. It has the important property that every assertion
    respects the equivalence, in the sense that we can substitute equal expressions without changing the truth value.
    That is, given `h1 : a = b` and `h2 : p a`, we can construct a proof for `p b` using substitution: `Eq.subst h1 h2`.
    Example:
    ```
    example (α : Type) (a b : α) (p : α → Prop)
            (h1 : a = b) (h2 : p a) : p b :=
      Eq.subst h1 h2
    
    example (α : Type) (a b : α) (p : α → Prop)
        (h1 : a = b) (h2 : p a) : p b :=
      h1 ▸ h2
    ```
    The triangle in the second presentation is a macro built on top of `Eq.subst` and `Eq.symm`, and you can enter it by typing `\t`.
    For more information: [Equality](https://lean-lang.org/theorem_proving_in_lean4/quantifiers_and_equality.html#equality)
    
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `=` in identifiers is `eq`. 3⁻¹Inv.inv.{u} {α : Type u} [self : Inv α] : α → α`a⁻¹` computes the inverse of `a`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `⁻¹` in identifiers is `inv`. *HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`. (HSub.hSub.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HSub α β γ] : α → β → γ`a - b` computes the difference of `a` and `b`.
    The meaning of this notation is type-dependent.
    * For natural numbers, this operator saturates at 0: `a - b = 0` when `a ≤ b`. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `-` in identifiers is `sub` (when used as a binary operator).E₂E₂ : UpperHalfPlane → ℂCompatibility alias for Mathlib's `EisensteinSeries.E2`.  *HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`. E₄E₄ : ModularForm (Subgroup.map (Matrix.SpecialLinearGroup.mapGL ℝ) (CongruenceSubgroup.Gamma 1)) 4.toFunSlashInvariantForm.toFun {Γ : outParam (Subgroup (GL (Fin 2) ℝ))} {k : outParam ℤ} (self : SlashInvariantForm Γ k) :
      UpperHalfPlane → ℂThe underlying function `ℍ → ℂ`.
    
    Do NOT use directly. Use the coercion instead.  -HSub.hSub.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HSub α β γ] : α → β → γ`a - b` computes the difference of `a` and `b`.
    The meaning of this notation is type-dependent.
    * For natural numbers, this operator saturates at 0: `a - b = 0` when `a ≤ b`. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `-` in identifiers is `sub` (when used as a binary operator). E₆E₆ : ModularForm (Subgroup.map (Matrix.SpecialLinearGroup.mapGL ℝ) (CongruenceSubgroup.Gamma 1)) 6.toFunSlashInvariantForm.toFun {Γ : outParam (Subgroup (GL (Fin 2) ℝ))} {k : outParam ℤ} (self : SlashInvariantForm Γ k) :
      UpperHalfPlane → ℂThe underlying function `ℍ → ℂ`.
    
    Do NOT use directly. Use the coercion instead. )HSub.hSub.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HSub α β γ] : α → β → γ`a - b` computes the difference of `a` and `b`.
    The meaning of this notation is type-dependent.
    * For natural numbers, this operator saturates at 0: `a - b = 0` when `a ≤ b`. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `-` in identifiers is `sub` (when used as a binary operator).
    theorem ramanujan_E₄ :
      DD (F : UpperHalfPlane → ℂ) : UpperHalfPlane → ℂ E₄E₄ : ModularForm (Subgroup.map (Matrix.SpecialLinearGroup.mapGL ℝ) (CongruenceSubgroup.Gamma 1)) 4.toFunSlashInvariantForm.toFun {Γ : outParam (Subgroup (GL (Fin 2) ℝ))} {k : outParam ℤ} (self : SlashInvariantForm Γ k) :
      UpperHalfPlane → ℂThe underlying function `ℍ → ℂ`.
    
    Do NOT use directly. Use the coercion instead.  =Eq.{u_1} {α : Sort u_1} : α → α → PropThe equality relation. It has one introduction rule, `Eq.refl`.
    We use `a = b` as notation for `Eq a b`.
    A fundamental property of equality is that it is an equivalence relation.
    ```
    variable (α : Type) (a b c d : α)
    variable (hab : a = b) (hcb : c = b) (hcd : c = d)
    
    example : a = d :=
      Eq.trans (Eq.trans hab (Eq.symm hcb)) hcd
    ```
    Equality is much more than an equivalence relation, however. It has the important property that every assertion
    respects the equivalence, in the sense that we can substitute equal expressions without changing the truth value.
    That is, given `h1 : a = b` and `h2 : p a`, we can construct a proof for `p b` using substitution: `Eq.subst h1 h2`.
    Example:
    ```
    example (α : Type) (a b : α) (p : α → Prop)
            (h1 : a = b) (h2 : p a) : p b :=
      Eq.subst h1 h2
    
    example (α : Type) (a b : α) (p : α → Prop)
        (h1 : a = b) (h2 : p a) : p b :=
      h1 ▸ h2
    ```
    The triangle in the second presentation is a macro built on top of `Eq.subst` and `Eq.symm`, and you can enter it by typing `\t`.
    For more information: [Equality](https://lean-lang.org/theorem_proving_in_lean4/quantifiers_and_equality.html#equality)
    
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `=` in identifiers is `eq`.
        3⁻¹Inv.inv.{u} {α : Type u} [self : Inv α] : α → α`a⁻¹` computes the inverse of `a`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `⁻¹` in identifiers is `inv`. *HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`. (HSub.hSub.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HSub α β γ] : α → β → γ`a - b` computes the difference of `a` and `b`.
    The meaning of this notation is type-dependent.
    * For natural numbers, this operator saturates at 0: `a - b = 0` when `a ≤ b`. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `-` in identifiers is `sub` (when used as a binary operator).E₂E₂ : UpperHalfPlane → ℂCompatibility alias for Mathlib's `EisensteinSeries.E2`.  *HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`. E₄E₄ : ModularForm (Subgroup.map (Matrix.SpecialLinearGroup.mapGL ℝ) (CongruenceSubgroup.Gamma 1)) 4.toFunSlashInvariantForm.toFun {Γ : outParam (Subgroup (GL (Fin 2) ℝ))} {k : outParam ℤ} (self : SlashInvariantForm Γ k) :
      UpperHalfPlane → ℂThe underlying function `ℍ → ℂ`.
    
    Do NOT use directly. Use the coercion instead.  -HSub.hSub.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HSub α β γ] : α → β → γ`a - b` computes the difference of `a` and `b`.
    The meaning of this notation is type-dependent.
    * For natural numbers, this operator saturates at 0: `a - b = 0` when `a ≤ b`. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `-` in identifiers is `sub` (when used as a binary operator). E₆E₆ : ModularForm (Subgroup.map (Matrix.SpecialLinearGroup.mapGL ℝ) (CongruenceSubgroup.Gamma 1)) 6.toFunSlashInvariantForm.toFun {Γ : outParam (Subgroup (GL (Fin 2) ℝ))} {k : outParam ℤ} (self : SlashInvariantForm Γ k) :
      UpperHalfPlane → ℂThe underlying function `ℍ → ℂ`.
    
    Do NOT use directly. Use the coercion instead. )HSub.hSub.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HSub α β γ] : α → β → γ`a - b` computes the difference of `a` and `b`.
    The meaning of this notation is type-dependent.
    * For natural numbers, this operator saturates at 0: `a - b = 0` when `a ≤ b`. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `-` in identifiers is `sub` (when used as a binary operator).
    complete
  • theorem ramanujan_E₆ : DD (F : UpperHalfPlane → ℂ) : UpperHalfPlane → ℂ E₆E₆ : ModularForm (Subgroup.map (Matrix.SpecialLinearGroup.mapGL ℝ) (CongruenceSubgroup.Gamma 1)) 6.toFunSlashInvariantForm.toFun {Γ : outParam (Subgroup (GL (Fin 2) ℝ))} {k : outParam ℤ} (self : SlashInvariantForm Γ k) :
      UpperHalfPlane → ℂThe underlying function `ℍ → ℂ`.
    
    Do NOT use directly. Use the coercion instead.  =Eq.{u_1} {α : Sort u_1} : α → α → PropThe equality relation. It has one introduction rule, `Eq.refl`.
    We use `a = b` as notation for `Eq a b`.
    A fundamental property of equality is that it is an equivalence relation.
    ```
    variable (α : Type) (a b c d : α)
    variable (hab : a = b) (hcb : c = b) (hcd : c = d)
    
    example : a = d :=
      Eq.trans (Eq.trans hab (Eq.symm hcb)) hcd
    ```
    Equality is much more than an equivalence relation, however. It has the important property that every assertion
    respects the equivalence, in the sense that we can substitute equal expressions without changing the truth value.
    That is, given `h1 : a = b` and `h2 : p a`, we can construct a proof for `p b` using substitution: `Eq.subst h1 h2`.
    Example:
    ```
    example (α : Type) (a b : α) (p : α → Prop)
            (h1 : a = b) (h2 : p a) : p b :=
      Eq.subst h1 h2
    
    example (α : Type) (a b : α) (p : α → Prop)
        (h1 : a = b) (h2 : p a) : p b :=
      h1 ▸ h2
    ```
    The triangle in the second presentation is a macro built on top of `Eq.subst` and `Eq.symm`, and you can enter it by typing `\t`.
    For more information: [Equality](https://lean-lang.org/theorem_proving_in_lean4/quantifiers_and_equality.html#equality)
    
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `=` in identifiers is `eq`. 2⁻¹Inv.inv.{u} {α : Type u} [self : Inv α] : α → α`a⁻¹` computes the inverse of `a`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `⁻¹` in identifiers is `inv`. *HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`. (HSub.hSub.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HSub α β γ] : α → β → γ`a - b` computes the difference of `a` and `b`.
    The meaning of this notation is type-dependent.
    * For natural numbers, this operator saturates at 0: `a - b = 0` when `a ≤ b`. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `-` in identifiers is `sub` (when used as a binary operator).E₂E₂ : UpperHalfPlane → ℂCompatibility alias for Mathlib's `EisensteinSeries.E2`.  *HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`. E₆E₆ : ModularForm (Subgroup.map (Matrix.SpecialLinearGroup.mapGL ℝ) (CongruenceSubgroup.Gamma 1)) 6.toFunSlashInvariantForm.toFun {Γ : outParam (Subgroup (GL (Fin 2) ℝ))} {k : outParam ℤ} (self : SlashInvariantForm Γ k) :
      UpperHalfPlane → ℂThe underlying function `ℍ → ℂ`.
    
    Do NOT use directly. Use the coercion instead.  -HSub.hSub.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HSub α β γ] : α → β → γ`a - b` computes the difference of `a` and `b`.
    The meaning of this notation is type-dependent.
    * For natural numbers, this operator saturates at 0: `a - b = 0` when `a ≤ b`. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `-` in identifiers is `sub` (when used as a binary operator). E₄E₄ : ModularForm (Subgroup.map (Matrix.SpecialLinearGroup.mapGL ℝ) (CongruenceSubgroup.Gamma 1)) 4.toFunSlashInvariantForm.toFun {Γ : outParam (Subgroup (GL (Fin 2) ℝ))} {k : outParam ℤ} (self : SlashInvariantForm Γ k) :
      UpperHalfPlane → ℂThe underlying function `ℍ → ℂ`.
    
    Do NOT use directly. Use the coercion instead.  *HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`. E₄E₄ : ModularForm (Subgroup.map (Matrix.SpecialLinearGroup.mapGL ℝ) (CongruenceSubgroup.Gamma 1)) 4.toFunSlashInvariantForm.toFun {Γ : outParam (Subgroup (GL (Fin 2) ℝ))} {k : outParam ℤ} (self : SlashInvariantForm Γ k) :
      UpperHalfPlane → ℂThe underlying function `ℍ → ℂ`.
    
    Do NOT use directly. Use the coercion instead. )HSub.hSub.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HSub α β γ] : α → β → γ`a - b` computes the difference of `a` and `b`.
    The meaning of this notation is type-dependent.
    * For natural numbers, this operator saturates at 0: `a - b = 0` when `a ≤ b`. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `-` in identifiers is `sub` (when used as a binary operator).
    theorem ramanujan_E₆ :
      DD (F : UpperHalfPlane → ℂ) : UpperHalfPlane → ℂ E₆E₆ : ModularForm (Subgroup.map (Matrix.SpecialLinearGroup.mapGL ℝ) (CongruenceSubgroup.Gamma 1)) 6.toFunSlashInvariantForm.toFun {Γ : outParam (Subgroup (GL (Fin 2) ℝ))} {k : outParam ℤ} (self : SlashInvariantForm Γ k) :
      UpperHalfPlane → ℂThe underlying function `ℍ → ℂ`.
    
    Do NOT use directly. Use the coercion instead.  =Eq.{u_1} {α : Sort u_1} : α → α → PropThe equality relation. It has one introduction rule, `Eq.refl`.
    We use `a = b` as notation for `Eq a b`.
    A fundamental property of equality is that it is an equivalence relation.
    ```
    variable (α : Type) (a b c d : α)
    variable (hab : a = b) (hcb : c = b) (hcd : c = d)
    
    example : a = d :=
      Eq.trans (Eq.trans hab (Eq.symm hcb)) hcd
    ```
    Equality is much more than an equivalence relation, however. It has the important property that every assertion
    respects the equivalence, in the sense that we can substitute equal expressions without changing the truth value.
    That is, given `h1 : a = b` and `h2 : p a`, we can construct a proof for `p b` using substitution: `Eq.subst h1 h2`.
    Example:
    ```
    example (α : Type) (a b : α) (p : α → Prop)
            (h1 : a = b) (h2 : p a) : p b :=
      Eq.subst h1 h2
    
    example (α : Type) (a b : α) (p : α → Prop)
        (h1 : a = b) (h2 : p a) : p b :=
      h1 ▸ h2
    ```
    The triangle in the second presentation is a macro built on top of `Eq.subst` and `Eq.symm`, and you can enter it by typing `\t`.
    For more information: [Equality](https://lean-lang.org/theorem_proving_in_lean4/quantifiers_and_equality.html#equality)
    
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `=` in identifiers is `eq`.
        2⁻¹Inv.inv.{u} {α : Type u} [self : Inv α] : α → α`a⁻¹` computes the inverse of `a`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `⁻¹` in identifiers is `inv`. *HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`.
          (HSub.hSub.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HSub α β γ] : α → β → γ`a - b` computes the difference of `a` and `b`.
    The meaning of this notation is type-dependent.
    * For natural numbers, this operator saturates at 0: `a - b = 0` when `a ≤ b`. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `-` in identifiers is `sub` (when used as a binary operator).E₂E₂ : UpperHalfPlane → ℂCompatibility alias for Mathlib's `EisensteinSeries.E2`.  *HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`. E₆E₆ : ModularForm (Subgroup.map (Matrix.SpecialLinearGroup.mapGL ℝ) (CongruenceSubgroup.Gamma 1)) 6.toFunSlashInvariantForm.toFun {Γ : outParam (Subgroup (GL (Fin 2) ℝ))} {k : outParam ℤ} (self : SlashInvariantForm Γ k) :
      UpperHalfPlane → ℂThe underlying function `ℍ → ℂ`.
    
    Do NOT use directly. Use the coercion instead.  -HSub.hSub.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HSub α β γ] : α → β → γ`a - b` computes the difference of `a` and `b`.
    The meaning of this notation is type-dependent.
    * For natural numbers, this operator saturates at 0: `a - b = 0` when `a ≤ b`. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `-` in identifiers is `sub` (when used as a binary operator).
            E₄E₄ : ModularForm (Subgroup.map (Matrix.SpecialLinearGroup.mapGL ℝ) (CongruenceSubgroup.Gamma 1)) 4.toFunSlashInvariantForm.toFun {Γ : outParam (Subgroup (GL (Fin 2) ℝ))} {k : outParam ℤ} (self : SlashInvariantForm Γ k) :
      UpperHalfPlane → ℂThe underlying function `ℍ → ℂ`.
    
    Do NOT use directly. Use the coercion instead.  *HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`. E₄E₄ : ModularForm (Subgroup.map (Matrix.SpecialLinearGroup.mapGL ℝ) (CongruenceSubgroup.Gamma 1)) 4.toFunSlashInvariantForm.toFun {Γ : outParam (Subgroup (GL (Fin 2) ℝ))} {k : outParam ℤ} (self : SlashInvariantForm Γ k) :
      UpperHalfPlane → ℂThe underlying function `ℍ → ℂ`.
    
    Do NOT use directly. Use the coercion instead. )HSub.hSub.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HSub α β γ] : α → β → γ`a - b` computes the difference of `a` and `b`.
    The meaning of this notation is type-dependent.
    * For natural numbers, this operator saturates at 0: `a - b = 0` when `a ≤ b`. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `-` in identifiers is `sub` (when used as a binary operator).
    complete
  • theorem ramanujan_E₂' : serre_Dserre_D (k : ℂ) : (UpperHalfPlane → ℂ) → UpperHalfPlane → ℂSerre derivative of weight $k$.
    Note that the definition makes sense for any analytic function $F : \mathbb{H} \to \mathbb{C}$.
     1 E₂E₂ : UpperHalfPlane → ℂCompatibility alias for Mathlib's `EisensteinSeries.E2`.  =Eq.{u_1} {α : Sort u_1} : α → α → PropThe equality relation. It has one introduction rule, `Eq.refl`.
    We use `a = b` as notation for `Eq a b`.
    A fundamental property of equality is that it is an equivalence relation.
    ```
    variable (α : Type) (a b c d : α)
    variable (hab : a = b) (hcb : c = b) (hcd : c = d)
    
    example : a = d :=
      Eq.trans (Eq.trans hab (Eq.symm hcb)) hcd
    ```
    Equality is much more than an equivalence relation, however. It has the important property that every assertion
    respects the equivalence, in the sense that we can substitute equal expressions without changing the truth value.
    That is, given `h1 : a = b` and `h2 : p a`, we can construct a proof for `p b` using substitution: `Eq.subst h1 h2`.
    Example:
    ```
    example (α : Type) (a b : α) (p : α → Prop)
            (h1 : a = b) (h2 : p a) : p b :=
      Eq.subst h1 h2
    
    example (α : Type) (a b : α) (p : α → Prop)
        (h1 : a = b) (h2 : p a) : p b :=
      h1 ▸ h2
    ```
    The triangle in the second presentation is a macro built on top of `Eq.subst` and `Eq.symm`, and you can enter it by typing `\t`.
    For more information: [Equality](https://lean-lang.org/theorem_proving_in_lean4/quantifiers_and_equality.html#equality)
    
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `=` in identifiers is `eq`. -Neg.neg.{u} {α : Type u} [self : Neg α] : α → α`-a` computes the negative or opposite of `a`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `-` in identifiers is `neg` (when used as a unary operator).12⁻¹Inv.inv.{u} {α : Type u} [self : Inv α] : α → α`a⁻¹` computes the inverse of `a`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `⁻¹` in identifiers is `inv`. *HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`. E₄E₄ : ModularForm (Subgroup.map (Matrix.SpecialLinearGroup.mapGL ℝ) (CongruenceSubgroup.Gamma 1)) 4.toFunSlashInvariantForm.toFun {Γ : outParam (Subgroup (GL (Fin 2) ℝ))} {k : outParam ℤ} (self : SlashInvariantForm Γ k) :
      UpperHalfPlane → ℂThe underlying function `ℍ → ℂ`.
    
    Do NOT use directly. Use the coercion instead. 
    theorem ramanujan_E₂' :
      serre_Dserre_D (k : ℂ) : (UpperHalfPlane → ℂ) → UpperHalfPlane → ℂSerre derivative of weight $k$.
    Note that the definition makes sense for any analytic function $F : \mathbb{H} \to \mathbb{C}$.
     1 E₂E₂ : UpperHalfPlane → ℂCompatibility alias for Mathlib's `EisensteinSeries.E2`.  =Eq.{u_1} {α : Sort u_1} : α → α → PropThe equality relation. It has one introduction rule, `Eq.refl`.
    We use `a = b` as notation for `Eq a b`.
    A fundamental property of equality is that it is an equivalence relation.
    ```
    variable (α : Type) (a b c d : α)
    variable (hab : a = b) (hcb : c = b) (hcd : c = d)
    
    example : a = d :=
      Eq.trans (Eq.trans hab (Eq.symm hcb)) hcd
    ```
    Equality is much more than an equivalence relation, however. It has the important property that every assertion
    respects the equivalence, in the sense that we can substitute equal expressions without changing the truth value.
    That is, given `h1 : a = b` and `h2 : p a`, we can construct a proof for `p b` using substitution: `Eq.subst h1 h2`.
    Example:
    ```
    example (α : Type) (a b : α) (p : α → Prop)
            (h1 : a = b) (h2 : p a) : p b :=
      Eq.subst h1 h2
    
    example (α : Type) (a b : α) (p : α → Prop)
        (h1 : a = b) (h2 : p a) : p b :=
      h1 ▸ h2
    ```
    The triangle in the second presentation is a macro built on top of `Eq.subst` and `Eq.symm`, and you can enter it by typing `\t`.
    For more information: [Equality](https://lean-lang.org/theorem_proving_in_lean4/quantifiers_and_equality.html#equality)
    
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `=` in identifiers is `eq`. -Neg.neg.{u} {α : Type u} [self : Neg α] : α → α`-a` computes the negative or opposite of `a`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `-` in identifiers is `neg` (when used as a unary operator).12⁻¹Inv.inv.{u} {α : Type u} [self : Inv α] : α → α`a⁻¹` computes the inverse of `a`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `⁻¹` in identifiers is `inv`. *HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`. E₄E₄ : ModularForm (Subgroup.map (Matrix.SpecialLinearGroup.mapGL ℝ) (CongruenceSubgroup.Gamma 1)) 4.toFunSlashInvariantForm.toFun {Γ : outParam (Subgroup (GL (Fin 2) ℝ))} {k : outParam ℤ} (self : SlashInvariantForm Γ k) :
      UpperHalfPlane → ℂThe underlying function `ℍ → ℂ`.
    
    Do NOT use directly. Use the coercion instead. 
    Serre derivative of E₂: `serre_D 1 E₂ = - 12⁻¹ * E₄`.
    
    This is the hardest identity because E₂ is not modular.
    The proof uses:
    1. `serre_DE₂_slash_invariant`: serre_D 1 E₂ is weight-4 slash-invariant
    2. Bounded at infinity: serre_D 1 E₂ = D E₂ - (1/12) E₂², both terms bounded
    3. Dimension formula: weight-4 forms are 1-dimensional, spanned by E₄
    4. Constant term: serre_D 1 E₂(iy) → -1/12 as y → ∞
    
    complete
  • theorem ramanujan_E₄' : serre_Dserre_D (k : ℂ) : (UpperHalfPlane → ℂ) → UpperHalfPlane → ℂSerre derivative of weight $k$.
    Note that the definition makes sense for any analytic function $F : \mathbb{H} \to \mathbb{C}$.
     4 E₄E₄ : ModularForm (Subgroup.map (Matrix.SpecialLinearGroup.mapGL ℝ) (CongruenceSubgroup.Gamma 1)) 4.toFunSlashInvariantForm.toFun {Γ : outParam (Subgroup (GL (Fin 2) ℝ))} {k : outParam ℤ} (self : SlashInvariantForm Γ k) :
      UpperHalfPlane → ℂThe underlying function `ℍ → ℂ`.
    
    Do NOT use directly. Use the coercion instead.  =Eq.{u_1} {α : Sort u_1} : α → α → PropThe equality relation. It has one introduction rule, `Eq.refl`.
    We use `a = b` as notation for `Eq a b`.
    A fundamental property of equality is that it is an equivalence relation.
    ```
    variable (α : Type) (a b c d : α)
    variable (hab : a = b) (hcb : c = b) (hcd : c = d)
    
    example : a = d :=
      Eq.trans (Eq.trans hab (Eq.symm hcb)) hcd
    ```
    Equality is much more than an equivalence relation, however. It has the important property that every assertion
    respects the equivalence, in the sense that we can substitute equal expressions without changing the truth value.
    That is, given `h1 : a = b` and `h2 : p a`, we can construct a proof for `p b` using substitution: `Eq.subst h1 h2`.
    Example:
    ```
    example (α : Type) (a b : α) (p : α → Prop)
            (h1 : a = b) (h2 : p a) : p b :=
      Eq.subst h1 h2
    
    example (α : Type) (a b : α) (p : α → Prop)
        (h1 : a = b) (h2 : p a) : p b :=
      h1 ▸ h2
    ```
    The triangle in the second presentation is a macro built on top of `Eq.subst` and `Eq.symm`, and you can enter it by typing `\t`.
    For more information: [Equality](https://lean-lang.org/theorem_proving_in_lean4/quantifiers_and_equality.html#equality)
    
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `=` in identifiers is `eq`. -Neg.neg.{u} {α : Type u} [self : Neg α] : α → α`-a` computes the negative or opposite of `a`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `-` in identifiers is `neg` (when used as a unary operator).3⁻¹Inv.inv.{u} {α : Type u} [self : Inv α] : α → α`a⁻¹` computes the inverse of `a`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `⁻¹` in identifiers is `inv`. *HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`. E₆E₆ : ModularForm (Subgroup.map (Matrix.SpecialLinearGroup.mapGL ℝ) (CongruenceSubgroup.Gamma 1)) 6.toFunSlashInvariantForm.toFun {Γ : outParam (Subgroup (GL (Fin 2) ℝ))} {k : outParam ℤ} (self : SlashInvariantForm Γ k) :
      UpperHalfPlane → ℂThe underlying function `ℍ → ℂ`.
    
    Do NOT use directly. Use the coercion instead. 
    theorem ramanujan_E₄' :
      serre_Dserre_D (k : ℂ) : (UpperHalfPlane → ℂ) → UpperHalfPlane → ℂSerre derivative of weight $k$.
    Note that the definition makes sense for any analytic function $F : \mathbb{H} \to \mathbb{C}$.
     4 E₄E₄ : ModularForm (Subgroup.map (Matrix.SpecialLinearGroup.mapGL ℝ) (CongruenceSubgroup.Gamma 1)) 4.toFunSlashInvariantForm.toFun {Γ : outParam (Subgroup (GL (Fin 2) ℝ))} {k : outParam ℤ} (self : SlashInvariantForm Γ k) :
      UpperHalfPlane → ℂThe underlying function `ℍ → ℂ`.
    
    Do NOT use directly. Use the coercion instead.  =Eq.{u_1} {α : Sort u_1} : α → α → PropThe equality relation. It has one introduction rule, `Eq.refl`.
    We use `a = b` as notation for `Eq a b`.
    A fundamental property of equality is that it is an equivalence relation.
    ```
    variable (α : Type) (a b c d : α)
    variable (hab : a = b) (hcb : c = b) (hcd : c = d)
    
    example : a = d :=
      Eq.trans (Eq.trans hab (Eq.symm hcb)) hcd
    ```
    Equality is much more than an equivalence relation, however. It has the important property that every assertion
    respects the equivalence, in the sense that we can substitute equal expressions without changing the truth value.
    That is, given `h1 : a = b` and `h2 : p a`, we can construct a proof for `p b` using substitution: `Eq.subst h1 h2`.
    Example:
    ```
    example (α : Type) (a b : α) (p : α → Prop)
            (h1 : a = b) (h2 : p a) : p b :=
      Eq.subst h1 h2
    
    example (α : Type) (a b : α) (p : α → Prop)
        (h1 : a = b) (h2 : p a) : p b :=
      h1 ▸ h2
    ```
    The triangle in the second presentation is a macro built on top of `Eq.subst` and `Eq.symm`, and you can enter it by typing `\t`.
    For more information: [Equality](https://lean-lang.org/theorem_proving_in_lean4/quantifiers_and_equality.html#equality)
    
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `=` in identifiers is `eq`. -Neg.neg.{u} {α : Type u} [self : Neg α] : α → α`-a` computes the negative or opposite of `a`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `-` in identifiers is `neg` (when used as a unary operator).3⁻¹Inv.inv.{u} {α : Type u} [self : Inv α] : α → α`a⁻¹` computes the inverse of `a`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `⁻¹` in identifiers is `inv`. *HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`. E₆E₆ : ModularForm (Subgroup.map (Matrix.SpecialLinearGroup.mapGL ℝ) (CongruenceSubgroup.Gamma 1)) 6.toFunSlashInvariantForm.toFun {Γ : outParam (Subgroup (GL (Fin 2) ℝ))} {k : outParam ℤ} (self : SlashInvariantForm Γ k) :
      UpperHalfPlane → ℂThe underlying function `ℍ → ℂ`.
    
    Do NOT use directly. Use the coercion instead. 
    Serre derivative of E₄: `serre_D 4 E₄ = - 3⁻¹ * E₆`.
    
    Uses the dimension argument:
    1. serre_D 4 E₄ is weight-6 slash-invariant (by serre_D_slash_invariant)
    2. serre_D 4 E₄ is bounded at infinity (serre_DE₄_isBoundedAtImInfty)
    3. Weight-6 modular forms are 1-dimensional (weight_six_one_dimensional)
    4. Constant term is -1/3 (from D E₄ → 0, E₂ → 1, E₄ → 1)
    
    complete
  • theorem ramanujan_E₆' : serre_Dserre_D (k : ℂ) : (UpperHalfPlane → ℂ) → UpperHalfPlane → ℂSerre derivative of weight $k$.
    Note that the definition makes sense for any analytic function $F : \mathbb{H} \to \mathbb{C}$.
     6 E₆E₆ : ModularForm (Subgroup.map (Matrix.SpecialLinearGroup.mapGL ℝ) (CongruenceSubgroup.Gamma 1)) 6.toFunSlashInvariantForm.toFun {Γ : outParam (Subgroup (GL (Fin 2) ℝ))} {k : outParam ℤ} (self : SlashInvariantForm Γ k) :
      UpperHalfPlane → ℂThe underlying function `ℍ → ℂ`.
    
    Do NOT use directly. Use the coercion instead.  =Eq.{u_1} {α : Sort u_1} : α → α → PropThe equality relation. It has one introduction rule, `Eq.refl`.
    We use `a = b` as notation for `Eq a b`.
    A fundamental property of equality is that it is an equivalence relation.
    ```
    variable (α : Type) (a b c d : α)
    variable (hab : a = b) (hcb : c = b) (hcd : c = d)
    
    example : a = d :=
      Eq.trans (Eq.trans hab (Eq.symm hcb)) hcd
    ```
    Equality is much more than an equivalence relation, however. It has the important property that every assertion
    respects the equivalence, in the sense that we can substitute equal expressions without changing the truth value.
    That is, given `h1 : a = b` and `h2 : p a`, we can construct a proof for `p b` using substitution: `Eq.subst h1 h2`.
    Example:
    ```
    example (α : Type) (a b : α) (p : α → Prop)
            (h1 : a = b) (h2 : p a) : p b :=
      Eq.subst h1 h2
    
    example (α : Type) (a b : α) (p : α → Prop)
        (h1 : a = b) (h2 : p a) : p b :=
      h1 ▸ h2
    ```
    The triangle in the second presentation is a macro built on top of `Eq.subst` and `Eq.symm`, and you can enter it by typing `\t`.
    For more information: [Equality](https://lean-lang.org/theorem_proving_in_lean4/quantifiers_and_equality.html#equality)
    
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `=` in identifiers is `eq`. -Neg.neg.{u} {α : Type u} [self : Neg α] : α → α`-a` computes the negative or opposite of `a`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `-` in identifiers is `neg` (when used as a unary operator).2⁻¹Inv.inv.{u} {α : Type u} [self : Inv α] : α → α`a⁻¹` computes the inverse of `a`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `⁻¹` in identifiers is `inv`. *HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`. E₄E₄ : ModularForm (Subgroup.map (Matrix.SpecialLinearGroup.mapGL ℝ) (CongruenceSubgroup.Gamma 1)) 4.toFunSlashInvariantForm.toFun {Γ : outParam (Subgroup (GL (Fin 2) ℝ))} {k : outParam ℤ} (self : SlashInvariantForm Γ k) :
      UpperHalfPlane → ℂThe underlying function `ℍ → ℂ`.
    
    Do NOT use directly. Use the coercion instead.  *HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`. E₄E₄ : ModularForm (Subgroup.map (Matrix.SpecialLinearGroup.mapGL ℝ) (CongruenceSubgroup.Gamma 1)) 4.toFunSlashInvariantForm.toFun {Γ : outParam (Subgroup (GL (Fin 2) ℝ))} {k : outParam ℤ} (self : SlashInvariantForm Γ k) :
      UpperHalfPlane → ℂThe underlying function `ℍ → ℂ`.
    
    Do NOT use directly. Use the coercion instead. 
    theorem ramanujan_E₆' :
      serre_Dserre_D (k : ℂ) : (UpperHalfPlane → ℂ) → UpperHalfPlane → ℂSerre derivative of weight $k$.
    Note that the definition makes sense for any analytic function $F : \mathbb{H} \to \mathbb{C}$.
     6 E₆E₆ : ModularForm (Subgroup.map (Matrix.SpecialLinearGroup.mapGL ℝ) (CongruenceSubgroup.Gamma 1)) 6.toFunSlashInvariantForm.toFun {Γ : outParam (Subgroup (GL (Fin 2) ℝ))} {k : outParam ℤ} (self : SlashInvariantForm Γ k) :
      UpperHalfPlane → ℂThe underlying function `ℍ → ℂ`.
    
    Do NOT use directly. Use the coercion instead.  =Eq.{u_1} {α : Sort u_1} : α → α → PropThe equality relation. It has one introduction rule, `Eq.refl`.
    We use `a = b` as notation for `Eq a b`.
    A fundamental property of equality is that it is an equivalence relation.
    ```
    variable (α : Type) (a b c d : α)
    variable (hab : a = b) (hcb : c = b) (hcd : c = d)
    
    example : a = d :=
      Eq.trans (Eq.trans hab (Eq.symm hcb)) hcd
    ```
    Equality is much more than an equivalence relation, however. It has the important property that every assertion
    respects the equivalence, in the sense that we can substitute equal expressions without changing the truth value.
    That is, given `h1 : a = b` and `h2 : p a`, we can construct a proof for `p b` using substitution: `Eq.subst h1 h2`.
    Example:
    ```
    example (α : Type) (a b : α) (p : α → Prop)
            (h1 : a = b) (h2 : p a) : p b :=
      Eq.subst h1 h2
    
    example (α : Type) (a b : α) (p : α → Prop)
        (h1 : a = b) (h2 : p a) : p b :=
      h1 ▸ h2
    ```
    The triangle in the second presentation is a macro built on top of `Eq.subst` and `Eq.symm`, and you can enter it by typing `\t`.
    For more information: [Equality](https://lean-lang.org/theorem_proving_in_lean4/quantifiers_and_equality.html#equality)
    
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `=` in identifiers is `eq`.
        -Neg.neg.{u} {α : Type u} [self : Neg α] : α → α`-a` computes the negative or opposite of `a`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `-` in identifiers is `neg` (when used as a unary operator).2⁻¹Inv.inv.{u} {α : Type u} [self : Inv α] : α → α`a⁻¹` computes the inverse of `a`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `⁻¹` in identifiers is `inv`. *HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`. E₄E₄ : ModularForm (Subgroup.map (Matrix.SpecialLinearGroup.mapGL ℝ) (CongruenceSubgroup.Gamma 1)) 4.toFunSlashInvariantForm.toFun {Γ : outParam (Subgroup (GL (Fin 2) ℝ))} {k : outParam ℤ} (self : SlashInvariantForm Γ k) :
      UpperHalfPlane → ℂThe underlying function `ℍ → ℂ`.
    
    Do NOT use directly. Use the coercion instead.  *HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`. E₄E₄ : ModularForm (Subgroup.map (Matrix.SpecialLinearGroup.mapGL ℝ) (CongruenceSubgroup.Gamma 1)) 4.toFunSlashInvariantForm.toFun {Γ : outParam (Subgroup (GL (Fin 2) ℝ))} {k : outParam ℤ} (self : SlashInvariantForm Γ k) :
      UpperHalfPlane → ℂThe underlying function `ℍ → ℂ`.
    
    Do NOT use directly. Use the coercion instead. 
    Serre derivative of E₆: `serre_D 6 E₆ = - 2⁻¹ * E₄²`.
    
    Uses the dimension argument:
    1. serre_D 6 E₆ is weight-8 slash-invariant (by serre_D_slash_invariant)
    2. Weight-8 modular forms are 1-dimensional, spanned by E₄²
    3. Constant term is -1/2 (from D E₆ → 0, E₂ → 1, E₆ → 1)
    
    complete
Proof

In terms of Serre derivatives, these are equivalent to \partial_{1}E_2 = -\frac{1}{12} E_4 \partial_{4}E_4 = -\frac{1}{3} E_6 \partial_{6}E_6 = -\frac{1}{2} E_4^2. By Theorem Theorem 7.47, all the Serre derivatives are, in fact, modular. To be precise, the modularity of \partial_4 E_4 and \partial_6 E_6 directly follows from Theorem Theorem 7.47, and that of \partial_1E_2 follows from eqn:E2-transform-general. Differentiating and squaring then gives us the following: E_2'|_{4}\gamma = E_2' - \frac{ic}{\pi(cz + d)} E_2 - \frac{3c^2}{\pi^2 (cz + d)^2} E_2^2|_{4}\gamma = E_2^2 - \frac{12ic}{\pi(cz + d)} E_2 - \frac{36c^2}{\pi^2 (cz + d)^2}. Hence, eqn:DE2 -\frac{1}{12} eqn:E2sq-transform is a modular form of weight 4. By Corollary 7.30, they should be multiples of E_4, E_6, E_4^2, and the proportionality constants can be determined by observing the constant terms of q-expansions.

Corollary7.49
XL∃∀Nused by 1

We have \Delta' = E_2 \Delta. Uses Theorem 7.48 and Definition 7.22.

Proof

By Theorem 7.48, \Delta' = \frac{3 E_4^2 E_4' - 2 E_6 E_6'}{1728} = \frac{1}{1728} \left(3 E_4^2 \cdot \frac{E_2 E_4 - E_6}{3} - 2 E_6 \cdot \frac{E_2 E_6 - E_4^2}{2}\right) = \frac{E_2(E_4^3 - E_6^2)}{1728} = E_2\Delta.

Lemma7.50
XL∃∀Nused by 1

We have H_2' = \frac{1}{6} (H_{2}^{2} + 2 H_{2} H_{4} + E_2 H_2) H_3' = \frac{1}{6} (H_{2}^{2} - H_{4}^{2} + E_2 H_3) H_4' = -\frac{1}{6} (2H_{2} H_{4} + H_{4}^{2} - E_2 H_4) or equivalently, \partial_{2} H_{2} = \frac{1}{6} (H_{2}^{2} + 2 H_{2} H_{4}) \partial_{2} H_{3} = \frac{1}{6} (H_{2}^{2} - H_{4}^{2}) \partial_{2} H_{4} = -\frac{1}{6} (2H_{2} H_{4} + H_{4}^{2}). Uses Definition 7.45, Lemma 7.33, and Lemma 7.40.

Proof

Equivalences are obvious from the definition of the Serre derivative. Define f_{2}, f_{3}, f_{4} be the differences of the left and right hand sides of eqn:H2-serre-der, eqn:H3-serre-der, eqn:H4-serre-der. \begin{aligned} f_{2} &:= \partial_{2} H_{2} - \frac{1}{6} H_{2}(H_{2} + 2H_{4}) \\ f_{3} &:= \partial_{2} H_{3} - \frac{1}{6} (H_{2}^2 - H_{4}^2) \\ f_{4} &:= \partial_{2} H_{4} + \frac{1}{6} H_{4}(2H_{2} + H_{4}). \end{aligned} Then these are a priori modular forms of weight 4 and level \Gamma(2), and our goal is to prove that they are actually zeros. By Jacobi's identity eqn:jacobi-identity, we have f_2 + f_4 = f_3. Also, the transformation rules of H_2,H_3,H_4 give f_{2}|_{S} = -f_{4} f_{2}|_{T} = -f_{2} f_{4}|_{S} = -f_{2} f_{4}|_{T} = f_{3} = f_{2} + f_{4}. Now define g := (2 H_2 + H_4) f_2 + (H_2 + 2 H_4) f_4 h := f_{2}^{2} + f_{2}f_{4} + f_{4}^{2}. Then one can check that both g and h are invariant under the actions of S and T, hence they are modular forms of level 1. Also, by analyzing the limit of g and h as z \to i \infty, one can see that g and h are cusp forms, hence g = h = 0 by eqn:dimS6 and eqn:dimS8. This implies 3 E_4 f_2^{2} = 3 (H_2^2 + H_2 H_4 + H_4^2) f_2^{2} = ((2 H_2 + H_4)^{2} - (2H_2 + H_4)(H_2 + 2H_4) + (H_2 + 2H_4)^{2}) f_2^{2} = (2 H_2 + H_4)^{2} (f_2^2 + f_2 f_4 + f_4^2) = 0 and by considering q-series (E_4 has an invertible q-series), we get f_2 = 0.

Theorem7.51
L∃∀N
Used by 2
Hover a use site to preview it.
Preview
Lemma 9.8
Loading preview
Hover a use site to preview it.

The Serre derivative satisfies the following product rule: for any quasimodular forms F and G, \partial_{w_1 + w_2} (FG) = (\partial_{w_1}F)G + F (\partial_{w_2}G). Uses Definition 7.45.

Lean code for Theorem7.511 theorem
  • theorem serre_D_mul (k₁ k₂ : Int : TypeThe integers.
    
    This type is special-cased by the compiler and overridden with an efficient implementation. The
    runtime has a special representation for `Int` that stores “small” signed numbers directly, while
    larger numbers use a fast arbitrary-precision arithmetic library (usually
    [GMP](https://gmplib.org/)). A “small number” is an integer that can be encoded with one fewer bits
    than the platform's pointer size (i.e. 63 bits on 64-bit architectures and 31 bits on 32-bit
    architectures).
    ) (FUpperHalfPlane → ℂ GUpperHalfPlane → ℂ : UpperHalfPlaneUpperHalfPlane : TypeThe open upper half plane, denoted as `ℍ` within the `UpperHalfPlane` namespace   Complex : TypeComplex numbers consist of two `Real`s: a real part `re` and an imaginary part `im`. ) (hFMDiff F : MDiff FUpperHalfPlane → ℂ)
      (hGMDiff G : MDiff GUpperHalfPlane → ℂ) :
      serre_Dserre_D (k : ℂ) : (UpperHalfPlane → ℂ) → UpperHalfPlane → ℂSerre derivative of weight $k$.
    Note that the definition makes sense for any analytic function $F : \mathbb{H} \to \mathbb{C}$.
     (HAdd.hAdd.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HAdd α β γ] : α → β → γ`a + b` computes the sum of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `+` in identifiers is `add`.k₁ +HAdd.hAdd.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HAdd α β γ] : α → β → γ`a + b` computes the sum of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `+` in identifiers is `add`. k₂)HAdd.hAdd.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HAdd α β γ] : α → β → γ`a + b` computes the sum of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `+` in identifiers is `add`. (HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`.FUpperHalfPlane → ℂ *HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`. GUpperHalfPlane → ℂ)HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`. =Eq.{u_1} {α : Sort u_1} : α → α → PropThe equality relation. It has one introduction rule, `Eq.refl`.
    We use `a = b` as notation for `Eq a b`.
    A fundamental property of equality is that it is an equivalence relation.
    ```
    variable (α : Type) (a b c d : α)
    variable (hab : a = b) (hcb : c = b) (hcd : c = d)
    
    example : a = d :=
      Eq.trans (Eq.trans hab (Eq.symm hcb)) hcd
    ```
    Equality is much more than an equivalence relation, however. It has the important property that every assertion
    respects the equivalence, in the sense that we can substitute equal expressions without changing the truth value.
    That is, given `h1 : a = b` and `h2 : p a`, we can construct a proof for `p b` using substitution: `Eq.subst h1 h2`.
    Example:
    ```
    example (α : Type) (a b : α) (p : α → Prop)
            (h1 : a = b) (h2 : p a) : p b :=
      Eq.subst h1 h2
    
    example (α : Type) (a b : α) (p : α → Prop)
        (h1 : a = b) (h2 : p a) : p b :=
      h1 ▸ h2
    ```
    The triangle in the second presentation is a macro built on top of `Eq.subst` and `Eq.symm`, and you can enter it by typing `\t`.
    For more information: [Equality](https://lean-lang.org/theorem_proving_in_lean4/quantifiers_and_equality.html#equality)
    
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `=` in identifiers is `eq`.
        serre_Dserre_D (k : ℂ) : (UpperHalfPlane → ℂ) → UpperHalfPlane → ℂSerre derivative of weight $k$.
    Note that the definition makes sense for any analytic function $F : \mathbb{H} \to \mathbb{C}$.
     (↑k₁) FUpperHalfPlane → ℂ *HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`. GUpperHalfPlane → ℂ +HAdd.hAdd.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HAdd α β γ] : α → β → γ`a + b` computes the sum of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `+` in identifiers is `add`. FUpperHalfPlane → ℂ *HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`. serre_Dserre_D (k : ℂ) : (UpperHalfPlane → ℂ) → UpperHalfPlane → ℂSerre derivative of weight $k$.
    Note that the definition makes sense for any analytic function $F : \mathbb{H} \to \mathbb{C}$.
     (↑k₂) GUpperHalfPlane → ℂ
    theorem serre_D_mul (k₁ k₂ : Int : TypeThe integers.
    
    This type is special-cased by the compiler and overridden with an efficient implementation. The
    runtime has a special representation for `Int` that stores “small” signed numbers directly, while
    larger numbers use a fast arbitrary-precision arithmetic library (usually
    [GMP](https://gmplib.org/)). A “small number” is an integer that can be encoded with one fewer bits
    than the platform's pointer size (i.e. 63 bits on 64-bit architectures and 31 bits on 32-bit
    architectures).
    )
      (FUpperHalfPlane → ℂ GUpperHalfPlane → ℂ : UpperHalfPlaneUpperHalfPlane : TypeThe open upper half plane, denoted as `ℍ` within the `UpperHalfPlane` namespace   Complex : TypeComplex numbers consist of two `Real`s: a real part `re` and an imaginary part `im`. )
      (hFMDiff F : MDiff FUpperHalfPlane → ℂ) (hGMDiff G : MDiff GUpperHalfPlane → ℂ) :
      serre_Dserre_D (k : ℂ) : (UpperHalfPlane → ℂ) → UpperHalfPlane → ℂSerre derivative of weight $k$.
    Note that the definition makes sense for any analytic function $F : \mathbb{H} \to \mathbb{C}$.
     (HAdd.hAdd.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HAdd α β γ] : α → β → γ`a + b` computes the sum of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `+` in identifiers is `add`.k₁ +HAdd.hAdd.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HAdd α β γ] : α → β → γ`a + b` computes the sum of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `+` in identifiers is `add`. k₂)HAdd.hAdd.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HAdd α β γ] : α → β → γ`a + b` computes the sum of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `+` in identifiers is `add`. (HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`.FUpperHalfPlane → ℂ *HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`. GUpperHalfPlane → ℂ)HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`. =Eq.{u_1} {α : Sort u_1} : α → α → PropThe equality relation. It has one introduction rule, `Eq.refl`.
    We use `a = b` as notation for `Eq a b`.
    A fundamental property of equality is that it is an equivalence relation.
    ```
    variable (α : Type) (a b c d : α)
    variable (hab : a = b) (hcb : c = b) (hcd : c = d)
    
    example : a = d :=
      Eq.trans (Eq.trans hab (Eq.symm hcb)) hcd
    ```
    Equality is much more than an equivalence relation, however. It has the important property that every assertion
    respects the equivalence, in the sense that we can substitute equal expressions without changing the truth value.
    That is, given `h1 : a = b` and `h2 : p a`, we can construct a proof for `p b` using substitution: `Eq.subst h1 h2`.
    Example:
    ```
    example (α : Type) (a b : α) (p : α → Prop)
            (h1 : a = b) (h2 : p a) : p b :=
      Eq.subst h1 h2
    
    example (α : Type) (a b : α) (p : α → Prop)
        (h1 : a = b) (h2 : p a) : p b :=
      h1 ▸ h2
    ```
    The triangle in the second presentation is a macro built on top of `Eq.subst` and `Eq.symm`, and you can enter it by typing `\t`.
    For more information: [Equality](https://lean-lang.org/theorem_proving_in_lean4/quantifiers_and_equality.html#equality)
    
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `=` in identifiers is `eq`.
        serre_Dserre_D (k : ℂ) : (UpperHalfPlane → ℂ) → UpperHalfPlane → ℂSerre derivative of weight $k$.
    Note that the definition makes sense for any analytic function $F : \mathbb{H} \to \mathbb{C}$.
     (↑k₁) FUpperHalfPlane → ℂ *HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`. GUpperHalfPlane → ℂ +HAdd.hAdd.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HAdd α β γ] : α → β → γ`a + b` computes the sum of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `+` in identifiers is `add`.
          FUpperHalfPlane → ℂ *HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`. serre_Dserre_D (k : ℂ) : (UpperHalfPlane → ℂ) → UpperHalfPlane → ℂSerre derivative of weight $k$.
    Note that the definition makes sense for any analytic function $F : \mathbb{H} \to \mathbb{C}$.
     (↑k₂) GUpperHalfPlane → ℂ
    complete
Proof

It follows from the definition: \partial_{w_1 + w_2} (FG) = (FG)' - \frac{w_1 + w_2}{12} E_2 (FG) = F'G + FG' - \frac{w_1 + w_2}{12} E_2(FG) = \left(F' - \frac{w_1}{12}E_2 F\right)G + F \left(G' - \frac{w_2}{12}E_2 G\right) = (\partial_{w_1}F)G + F(\partial_{w_2}G).

We also have the following useful theorem for proving positivity of quasimodular forms on the imaginary axis, which is Proposition 3.5 and Corollary 3.6 of Lee (2024).

Theorem7.52
XL∃∀Nused by 1

Let F be a holomorphic quasimodular cusp form with real Fourier coefficients. Assume that there exists k such that (\partial_{k}F)(it) > 0 for all t > 0. If the first Fourier coefficient of F is positive, then F(it) > 0 for all t > 0. Uses Definition 7.45 and Corollary 7.49.

Proof

By eqn:logder-disc-E2 we have \frac{\dd}{\dd t} \left( \frac{F(it)}{\Delta(it)^{\frac{k}{12}}}\right) = (-2 \pi) \frac{F'(it) \Delta(it)^{\frac{k}{12}} - F(it) \frac{k}{12} E_{2}(it) \Delta(it)^{\frac{k}{12}}}{\Delta(it)^{\frac{k}{6}}} = (-2 \pi) \frac{(\partial_{k} F)(it)}{\Delta(it)^{\frac{k}{12}}} < 0. Hence the function t \mapsto \frac{F(it)}{\Delta(it)^{\frac{k}{12}}} is monotone decreasing. Because the first nonzero Fourier coefficient of F is positive, F(it) > 0 for sufficiently large t: F = \sum_{n \geq n_{0}} a_{n} q^{n} \Rightarrow e^{2 \pi n_{0} t} F(it) = a_{n_{0}} + e^{-2 \pi t}\sum_{n\geq n_{0} + 1} a_{n} e^{-2 \pi (n - n_{0} - 1)t}, and \lim_{t \to \infty} e^{2 \pi n_{0}t} F(it) = a_{n_0} > 0. The result follows.