Documentation

TauCeti.NumberTheory.HeckeRing.Basic

Hecke rings: the double coset API #

Basic API for the double cosets HeckeCoset indexing a Hecke coset module, following Shimura, Chapter 3. This file provides representatives of double cosets, the characterisation of when two elements give the same double coset, and the quotient Γ₁ ⧸ (Γ₁ ∩ gΓ₂g⁻¹) indexing the left cosets inside a double coset Γ₁gΓ₂, which is used to define the Hecke product in later files and is finite for a Hecke triple. It also houses the basis-element API of the coset module: HeckeCosetModule.single with its evaluation, summation, and additivity laws, the induction_linear principle, and the transported Module instance — placed at this layer so every later file (convolution, one, and the coset actions) can build on one shared vocabulary. Finally it defines the degree of a double coset, the number of left cosets in its decomposition, together with its relative-index form, since that count is read straight off DecompQuotient.

The coset vocabulary is vendored from the in-review mathlib4 PR #41253 (Chris Birkbeck), per the ModularForms roadmap's dependency policy; migrate to Mathlib and delete it when that stack merges. The degree section is instead ported from the AINTLIB LeanModularForms project (LeanModularForms/HeckeRIngs/AbstractHeckeRing/Degree.lean, Chris Birkbeck, https://github.com/CBirkbeck/AINTLIB/tree/main/projects/LeanModularForms).

Main definitions #

Main results #

References #

def HeckeCoset.toSet {G : Type u_1} [Group G] {Δ : Submonoid G} {H₁ H₂ : Subgroup G} (D : HeckeCoset Δ H₁ H₂) :
Set G

The underlying set H₁gH₂ of a double coset, well-defined on the quotient.

The @[simp] lemma toSet_mk evaluates it at a representative and toSet_eq_doubleCoset_rep at the chosen rep. Mathlib's DoubleCoset.quotToDoubleCoset is the analogue for the double cosets of the whole group G rather than of the submonoid Δ.

Equations
Instances For
    noncomputable def HeckeCoset.rep {G : Type u_1} [Group G] {Δ : Submonoid G} {H₁ H₂ : Subgroup G} (D : HeckeCoset Δ H₁ H₂) :
    ↥Δ

    The chosen representative in Δ of a double coset D, picked by Quotient.out: it lies in D.toSet (rep_mem), and mk_rep recovers D from it. The choice is arbitrary — (mk H₁ H₂ w).rep need not be w; it only spans the same double coset (doubleCoset_rep_mk).

    Equations
    Instances For
      theorem HeckeCoset.rep_def {G : Type u_1} [Group G] {Δ : Submonoid G} {H₁ H₂ : Subgroup G} (D : HeckeCoset Δ H₁ H₂) :

      The chosen representative of a double coset D is Quotient.out D.

      @[simp]
      theorem HeckeCoset.mk_rep {G : Type u_1} [Group G] {Δ : Submonoid G} {H₁ H₂ : Subgroup G} (D : HeckeCoset Δ H₁ H₂) :
      mk H₁ H₂ D.rep = D

      The double coset of a chosen representative is the double coset it was chosen from.

      theorem HeckeCoset.eq_iff {G : Type u_1} [Group G] {Δ : Submonoid G} {H₁ H₂ : Subgroup G} {g h : ↥Δ} :
      mk H₁ H₂ g = mk H₁ H₂ h ↔ DoubleCoset.doubleCoset ↑g ↑H₁ ↑H₂ = DoubleCoset.doubleCoset ↑h ↑H₁ ↑H₂

      Two elements of Δ define the same HeckeCoset iff their double cosets coincide.

      The right-hand side is an equality of subsets of the ambient group G, so g and h are identified through elements of H₁ and H₂ that need not lie in Δ. Use HeckeCoset.mk_eq_mk_of_mem for the one-directional form starting from a membership.

      @[simp]
      theorem HeckeCoset.toSet_mk {G : Type u_1} [Group G] {Δ : Submonoid G} {H₁ H₂ : Subgroup G} (g : ↥Δ) :
      (mk H₁ H₂ g).toSet = DoubleCoset.doubleCoset ↑g ↑H₁ ↑H₂

      The underlying set of the double coset of g is H₁gH₂.

      For an arbitrary double coset, rather than an explicit mk H₁ H₂ g, use toSet_eq_doubleCoset_rep.

      theorem HeckeCoset.toSet_eq_doubleCoset_rep {G : Type u_1} [Group G] {Δ : Submonoid G} {H₁ H₂ : Subgroup G} (D : HeckeCoset Δ H₁ H₂) :
      D.toSet = DoubleCoset.doubleCoset ↑D.rep ↑H₁ ↑H₂

      The underlying set of a double coset is the double coset of its chosen representative.

      For an explicit mk H₁ H₂ g use toSet_mk instead; rep_mem is the membership fact this yields.

      theorem HeckeCoset.mem_toSet_iff {G : Type u_1} [Group G] {Δ : Submonoid G} {H₁ H₂ : Subgroup G} {D : HeckeCoset Δ H₁ H₂} {g : ↥Δ} :
      ↑g ∈ D.toSet ↔ mk H₁ H₂ g = D

      Membership in the underlying set characterises the double coset: for g : Δ, the element g lies in D.toSet exactly when D is the double coset of g.

      This is the elimination rule for toSet: it turns a membership into an equation between double cosets, so a consumer need not unfold the quotient. It is the Δ-indexed analogue of Mathlib's DoubleCoset.mem_quotToDoubleCoset_iff, which characterises membership for the double cosets of the whole group G.

      theorem HeckeCoset.toSet_injective {G : Type u_1} [Group G] {Δ : Submonoid G} {H₁ H₂ : Subgroup G} :

      A double coset is determined by its underlying set.

      This is eq_iff read at the level of double cosets rather than of representatives; the Iff form D₁.toSet = D₂.toSet ↔ D₁ = D₂ is toSet_injective.eq_iff.

      theorem HeckeCoset.rep_mem {G : Type u_1} [Group G] {Δ : Submonoid G} {H₁ H₂ : Subgroup G} (D : HeckeCoset Δ H₁ H₂) :
      ↑D.rep ∈ D.toSet

      The chosen representative of a double coset lies in its underlying set.

      The membership form of toSet_eq_doubleCoset_rep, for an arbitrary double coset. At an explicit mk H₁ H₂ w, use rep_mk_mem_doubleCoset instead.

      theorem HeckeCoset.rep_mk_mem_doubleCoset {G : Type u_1} [Group G] {Δ : Submonoid G} {H₁ H₂ : Subgroup G} (w : ↥Δ) :
      ↑(mk H₁ H₂ w).rep ∈ DoubleCoset.doubleCoset ↑w ↑H₁ ↑H₂

      The chosen representative of mk H₁ H₂ w lies in the double coset of w.

      The toSet-evaluated form of rep_mem at an explicit mk H₁ H₂ w. Its mirror mem_doubleCoset_rep_mk states the same relation with the two elements exchanged: w left of the ∈ and the representative inside the doubleCoset.

      @[simp]
      theorem HeckeCoset.doubleCoset_rep_mk {G : Type u_1} [Group G] {Δ : Submonoid G} {H₁ H₂ : Subgroup G} (w : ↥Δ) :
      DoubleCoset.doubleCoset ↑(mk H₁ H₂ w).rep ↑H₁ ↑H₂ = DoubleCoset.doubleCoset ↑w ↑H₁ ↑H₂

      mk and rep name the same double coset: the chosen representative of mk H₁ H₂ w spans the double coset w was taken from.

      The cancellation holds only inside doubleCoset: (mk H₁ H₂ w).rep = w is false in general, as the representative is chosen arbitrarily from the coset. mem_doubleCoset_rep_mk and rep_mk_mem_doubleCoset are its membership forms.

      theorem HeckeCoset.mem_doubleCoset_rep_mk {G : Type u_1} [Group G] {Δ : Submonoid G} {H₁ H₂ : Subgroup G} (w : ↥Δ) :
      ↑w ∈ DoubleCoset.doubleCoset ↑(mk H₁ H₂ w).rep ↑H₁ ↑H₂

      w lies in the double coset of the chosen representative of mk H₁ H₂ w.

      The mirror of rep_mk_mem_doubleCoset, which places the representative left of the membership and w inside the double coset; both hold because doubleCoset_rep_mk identifies the two sets.

      theorem HeckeCoset.mk_eq_mk_of_mem {G : Type u_1} [Group G] {Δ : Submonoid G} {H₁ H₂ : Subgroup G} {g₁ g₂ : ↥Δ} (h : ↑g₁ ∈ DoubleCoset.doubleCoset ↑g₂ ↑H₁ ↑H₂) :
      mk H₁ H₂ g₁ = mk H₁ H₂ g₂

      mk H₁ H₂ g₁ = mk H₁ H₂ g₂ when g₁ lies in the double coset of g₂.

      The one-directional form of eq_iff, starting from a membership rather than an equality of sets. The membership is between the images in G, so call sites typically supply it as DoubleCoset.mem_doubleCoset.mpr ⟨l, hl, r, hr, _⟩ after unfolding any Δ-side coercion. Mathlib's DoubleCoset.mk_eq_of_doubleCoset_eq does not cover this: its conclusion lands in the double coset quotient of all of G, not in HeckeCoset Δ H₁ H₂.

      def HeckeCoset.map {G : Type u_1} [Group G] {Δ : Submonoid G} {H₁ H₂ : Subgroup G} {Δ' : Submonoid G} {H₁' H₂' : Subgroup G} (hΔ : Δ ≤ Δ') (h₁ : H₁ ≤ H₁') (h₂ : H₂ ≤ H₂') :
      HeckeCoset Δ H₁ H₂ → HeckeCoset Δ' H₁' H₂'

      Functoriality of HeckeCoset in its triple. Inclusions Δ ≤ Δ', H₁ ≤ H₁' and H₂ ≤ H₂' send H₁ g H₂ to H₁' g H₂': widening the coefficient subgroups can only merge double cosets, never split them.

      Compute with map_mk: the underlying element of G is unchanged, only retyped into Δ' by Submonoid.inclusion. The functor laws are map_id and map_map; all three are @[simp]. This widens subgroups inside one fixed ambient group — transporting a double coset along a homomorphism G →* G' is a different operation, carried out for the decomposition quotient by DoubleCoset.decompQuotientEquivMapOfInjective.

      Equations
      Instances For
        @[simp]
        theorem HeckeCoset.map_mk {G : Type u_1} [Group G] {Δ : Submonoid G} {H₁ H₂ : Subgroup G} {Δ' : Submonoid G} {H₁' H₂' : Subgroup G} (hΔ : Δ ≤ Δ') (h₁ : H₁ ≤ H₁') (h₂ : H₂ ≤ H₂') (g : ↥Δ) :
        map hΔ h₁ h₂ (mk H₁ H₂ g) = mk H₁' H₂' ((Submonoid.inclusion hΔ) g)

        The computation rule for map: it keeps the representative, re-typed by the inclusion hΔ.

        The representative lands in Δ', not in G, so a call site holding g : Δ needs no coercion of its own. Its neighbours map_id and map_map are instead stated for an arbitrary coset.

        @[simp]
        theorem HeckeCoset.map_id {G : Type u_1} [Group G] {Δ : Submonoid G} {H₁ H₂ : Subgroup G} (D : HeckeCoset Δ H₁ H₂) :
        map ⋯ ⋯ ⋯ D = D
        @[simp]
        theorem HeckeCoset.map_map {G : Type u_1} [Group G] {Δ : Submonoid G} {H₁ H₂ : Subgroup G} {Δ' : Submonoid G} {H₁' H₂' : Subgroup G} {Δ'' : Submonoid G} {H₁'' H₂'' : Subgroup G} (hΔ : Δ ≤ Δ') (h₁ : H₁ ≤ H₁') (h₂ : H₂ ≤ H₂') (hΔ' : Δ' ≤ Δ'') (h₁' : H₁' ≤ H₁'') (h₂' : H₂' ≤ H₂'') (D : HeckeCoset Δ H₁ H₂) :
        map hΔ' h₁' h₂' (map hΔ h₁ h₂ D) = map ⋯ ⋯ ⋯ D
        theorem HeckeCoset.induction {G : Type u_1} [Group G] {Δ : Submonoid G} {H₁ H₂ : Subgroup G} {motive : HeckeCoset Δ H₁ H₂ → Prop} (h : ∀ (g : ↥Δ), motive (mk H₁ H₂ g)) (D : HeckeCoset Δ H₁ H₂) :
        motive D

        Induction: to prove something for all double cosets, prove it for mk H₁ H₂ g.

        theorem HeckeCoset.induction₂ {G : Type u_1} [Group G] {Δ : Submonoid G} {H₁ H₂ : Subgroup G} {motive : HeckeCoset Δ H₁ H₂ → HeckeCoset Δ H₁ H₂ → Prop} (h : ∀ (g₁ g₂ : ↥Δ), motive (mk H₁ H₂ g₁) (mk H₁ H₂ g₂)) (D₁ D₂ : HeckeCoset Δ H₁ H₂) :
        motive D₁ D₂

        Two-argument induction for double cosets.

        @[simp]
        theorem HeckeCoset.toSet_one {G : Type u_1} [Group G] {Δ : Submonoid G} {H : Subgroup G} :
        toSet 1 = ↑H
        theorem HeckeCoset.rep_one_mem {G : Type u_1} [Group G] {Δ : Submonoid G} {H : Subgroup G} :
        ↑(rep 1) ∈ H

        Restriction to a smaller ambient group #

        map above moves a Hecke coset along inclusions within a fixed G. This moves one between ambient groups: when the whole triple (Δ, H₁, H₂) lies inside a subgroup H, the double cosets are the same sets read inside ↥H, so the quotient is the same quotient.

        Why it is wanted: a theorem quantified over the ambient group is applied along a homomorphism out of that group, and the available homomorphisms are frequently defined only on a subgroup — the motivating case being TauCeti.ratPosToPSL2R, whose source is GL(2, ℚ)⁺, while the Hecke cosets of interest live in GL (Fin 2) ℚ.

        noncomputable def HeckeCoset.restrict {G : Type u_1} [Group G] {Δ : Submonoid G} {H₁ H₂ H : Subgroup G} (D : HeckeCoset Δ H₁ H₂) (hΔ : Δ ≤ H.toSubmonoid) (h₁ : H₁ ≤ H) (h₂ : H₂ ≤ H) :

        Re-read a Hecke coset over a subgroup containing its whole triple. With Δ ≤ H, H₁ ≤ H and H₂ ≤ H, the double coset H₁ g H₂ of g : Δ is a subset of H, and this is that same double coset read in ↥H.

        Like map, this is induced on the quotient rather than defined through a chosen representative, so restrict_mk is its defining equation.

        Equations
        Instances For
          @[simp]
          theorem HeckeCoset.restrict_mk {G : Type u_1} [Group G] {Δ : Submonoid G} {H₁ H₂ H : Subgroup G} (g : ↥Δ) (hΔ : Δ ≤ H.toSubmonoid) (h₁ : H₁ ≤ H) (h₂ : H₂ ≤ H) :
          (mk H₁ H₂ g).restrict hΔ h₁ h₂ = mk (H₁.subgroupOf H) (H₂.subgroupOf H) ⟨⟨↑g, ⋯⟩, ⋯⟩

          Restriction of an explicitly constructed coset.

          noncomputable def HeckeCoset.restrictEquiv {G : Type u_1} [Group G] {Δ : Submonoid G} {H₁ H₂ H : Subgroup G} (hΔ : Δ ≤ H.toSubmonoid) (h₁ : H₁ ≤ H) (h₂ : H₂ ≤ H) :
          HeckeCoset Δ H₁ H₂ ≃ HeckeCoset (Submonoid.comap H.subtype Δ) (H₁.subgroupOf H) (H₂.subgroupOf H)

          Restriction is an equivalence. With the whole triple inside H, the double cosets of Δ and those of Δ.comap H.subtype are the same objects described twice, so the two quotients are canonically equivalent — restrict is the forward direction, and the inverse simply forgets that a representative lies in H.

          Equations
          • One or more equations did not get rendered due to their size.
          Instances For
            @[simp]
            theorem HeckeCoset.restrictEquiv_apply {G : Type u_1} [Group G] {Δ : Submonoid G} {H₁ H₂ H : Subgroup G} (hΔ : Δ ≤ H.toSubmonoid) (h₁ : H₁ ≤ H) (h₂ : H₂ ≤ H) (D : HeckeCoset Δ H₁ H₂) :
            (restrictEquiv hΔ h₁ h₂) D = D.restrict hΔ h₁ h₂

            restrictEquiv computes as restrict in the forward direction.

            @[simp]
            theorem HeckeCoset.restrictEquiv_symm_mk {G : Type u_1} [Group G] {Δ : Submonoid G} {H₁ H₂ H : Subgroup G} (hΔ : Δ ≤ H.toSubmonoid) (h₁ : H₁ ≤ H) (h₂ : H₂ ≤ H) (g : ↥(Submonoid.comap H.subtype Δ)) :
            (restrictEquiv hΔ h₁ h₂).symm (mk (H₁.subgroupOf H) (H₂.subgroupOf H) g) = mk H₁ H₂ ⟨↑↑g, ⋯⟩

            The inverse of restrictEquiv on an explicitly constructed coset: it simply forgets that the representative lies in H.

            @[simp]
            theorem HeckeCoset.restrictEquiv_symm_apply_restrict {G : Type u_1} [Group G] {Δ : Submonoid G} {H₁ H₂ H : Subgroup G} (hΔ : Δ ≤ H.toSubmonoid) (h₁ : H₁ ≤ H) (h₂ : H₂ ≤ H) (D : HeckeCoset Δ H₁ H₂) :
            (restrictEquiv hΔ h₁ h₂).symm (D.restrict hΔ h₁ h₂) = D

            The round trip through restrictEquiv is the identity, in the direction that starts in the ambient group.

            @[simp]
            theorem HeckeCoset.restrict_restrictEquiv_symm_apply {G : Type u_1} [Group G] {Δ : Submonoid G} {H₁ H₂ H : Subgroup G} (hΔ : Δ ≤ H.toSubmonoid) (h₁ : H₁ ≤ H) (h₂ : H₂ ≤ H) (D : HeckeCoset (Submonoid.comap H.subtype Δ) (H₁.subgroupOf H) (H₂.subgroupOf H)) :
            ((restrictEquiv hΔ h₁ h₂).symm D).restrict hΔ h₁ h₂ = D

            The round trip through restrictEquiv is the identity, in the direction that starts in the subgroup.

            theorem HeckeCoset.restrict_bijective {G : Type u_1} [Group G] {Δ : Submonoid G} {H₁ H₂ H : Subgroup G} (hΔ : Δ ≤ H.toSubmonoid) (h₁ : H₁ ≤ H) (h₂ : H₂ ≤ H) :
            Function.Bijective fun (D : HeckeCoset Δ H₁ H₂) => D.restrict hΔ h₁ h₂

            restrict is bijective.

            theorem HeckeCoset.restrict_injective {G : Type u_1} [Group G] {Δ : Submonoid G} {H₁ H₂ H : Subgroup G} (hΔ : Δ ≤ H.toSubmonoid) (h₁ : H₁ ≤ H) (h₂ : H₂ ≤ H) :
            Function.Injective fun (D : HeckeCoset Δ H₁ H₂) => D.restrict hΔ h₁ h₂

            restrict is injective.

            theorem HeckeCoset.restrict_surjective {G : Type u_1} [Group G] {Δ : Submonoid G} {H₁ H₂ H : Subgroup G} (hΔ : Δ ≤ H.toSubmonoid) (h₁ : H₁ ≤ H) (h₂ : H₂ ≤ H) :
            Function.Surjective fun (D : HeckeCoset Δ H₁ H₂) => D.restrict hΔ h₁ h₂

            restrict is surjective.

            @[reducible, inline]
            abbrev DoubleCoset.DecompQuotient {G : Type u_1} [Group G] (Γ₁ Γ₂ : Subgroup G) (g : G) :
            Type u_1

            The decomposition quotient Γ₁ ⧸ (Γ₁ ∩ gΓ₂g⁻¹), indexing the left cosets of Γ₂ inside the double coset Γ₁gΓ₂; see DoubleCoset.doubleCoset_eq_iUnion_leftCosets.

            Equations
            Instances For
              instance DoubleCoset.instNonemptyDecompQuotient {G : Type u_1} [Group G] (Γ₁ Γ₂ : Subgroup G) (g : G) :
              Nonempty (DecompQuotient Γ₁ Γ₂ g)
              theorem DoubleCoset.mk_out_mul_injective {G : Type u_1} [Group G] (Γ₁ Γ₂ : Subgroup G) (g : G) :
              Function.Injective fun (i : DecompQuotient Γ₁ Γ₂ g) => ↑(↑(Quotient.out i) * g)

              The left cosets σᵢ g Γ₂ of the decomposition of Γ₁gΓ₂ are pairwise distinct: the map i ↦ σᵢ g Γ₂ into G ⧸ Γ₂ is injective.

              theorem DoubleCoset.conj_mem_of_stabilizer {G : Type u_1} [Group G] {H₁ H₂ : Subgroup G} (g : G) (n : ↥((ConjAct.toConjAct g • H₂).subgroupOf H₁)) :
              g⁻¹ * ↑↑n * g ∈ H₂

              The conjugation criterion for the stabilizer subgroup indexing DecompQuotient: an element of (ConjAct.toConjAct g • H₂).subgroupOf H₁ conjugates by g into H₂.

              theorem DoubleCoset.map_subgroupOf_smul {G : Type u_1} [Group G] {G' : Type u_2} [Group G'] (φ : G →* G') (hφ : Function.Injective ⇑φ) (Γ₁ Γ₂ : Subgroup G) (g : G) :

              The stabilizer indexing the decomposition transports along an injective homomorphism: the image of (gΓ₂g⁻¹) ∩ Γ₁ inside φ(Γ₁) is (φ(g) φ(Γ₂) φ(g)⁻¹) ∩ φ(Γ₁). Injectivity is what gives the inclusion that is not formal: an element of φ(Γ₁) conjugating into φ(Γ₂) must come from one of Γ₁ conjugating into Γ₂.

              noncomputable def DoubleCoset.decompQuotientEquivMapOfInjective {G : Type u_1} [Group G] {G' : Type u_2} [Group G'] (φ : G →* G') (hφ : Function.Injective ⇑φ) (Γ₁ Γ₂ : Subgroup G) (g : G) :
              DecompQuotient Γ₁ Γ₂ g ≃ DecompQuotient (Subgroup.map φ Γ₁) (Subgroup.map φ Γ₂) (φ g)

              The decomposition quotient transports along an injective homomorphism. For φ injective, Γ₁ ⧸ (Γ₁ ∩ gΓ₂g⁻¹) and φ(Γ₁) ⧸ (φ(Γ₁) ∩ φ(g)φ(Γ₂)φ(g)⁻¹) are in bijection, by φ on representatives.

              This is index transport along an injective map, and nothing more: it identifies the two decomposition quotients, leaving the acting group unchanged. G and G' are arbitrary groups here, with no action in sight.

              It does not supply a fundamental-domain tiling, and the reason is specific to the modular setting rather than general: there the target acts on ℍ through a matrix group modulo scalars, so an injective φ retains -I ∈ Γ₂, whose image is a non-identity element acting trivially — and MeasureTheory.IsFundamentalDomain then holds for no set of positive measure, its disjointness being Pairwise over distinct group elements. decompQuotientEquivMapOfKerInfLe is the version for that application: it drops injectivity for a kernel condition, which is what leaves room for a faithful action downstream.

              Equations
              Instances For
                @[simp]
                theorem DoubleCoset.decompQuotientEquivMapOfInjective_mk {G : Type u_1} [Group G] {G' : Type u_2} [Group G'] (φ : G →* G') (hφ : Function.Injective ⇑φ) (Γ₁ Γ₂ : Subgroup G) (g : G) (y : ↥Γ₁) :
                (decompQuotientEquivMapOfInjective φ hφ Γ₁ Γ₂ g) ↑y = ↑((Γ₁.equivMapOfInjective φ hφ) y)
                theorem DoubleCoset.map_subgroupOf_smul_of_ker_inf_le {G : Type u_1} [Group G] {G' : Type u_2} [Group G'] (φ : G →* G') (Γ₁ Γ₂ H : Subgroup G) (g : G) (h₂ : Γ₂ ≤ H) (hconj : ∀ y ∈ Γ₁, g⁻¹ * y * g ∈ H) (hker : φ.ker ⊓ H ≤ Γ₂) :

                The stabilizer of the decomposition transports along φ. The image under φ of (gΓ₂g⁻¹ ∩ Γ₁), viewed inside Γ₁, is (φ(g)φ(Γ₂)φ(g)⁻¹ ∩ φ(Γ₁)) viewed inside φ(Γ₁).

                Injectivity of φ is not required. In its place: an ambient subgroup H containing Γ₂ and receiving g⁻¹ Γ₁ g, together with φ.ker ⊓ H ≤ Γ₂. The kernel may therefore be nontrivial, which is what lets the decomposition reach a group acting faithfully on ℍ; the injective version is map_subgroupOf_smul.

                noncomputable def DoubleCoset.decompQuotientEquivMapOfKerInfLe {G : Type u_1} [Group G] {G' : Type u_2} [Group G'] (φ : G →* G') (Γ₁ Γ₂ H : Subgroup G) (g : G) {d : G'} (hd : φ g = d) (h₂ : Γ₂ ≤ H) (hconj : ∀ y ∈ Γ₁, g⁻¹ * y * g ∈ H) (hker : φ.ker ⊓ H ≤ Γ₂) :
                DecompQuotient Γ₁ Γ₂ g ≃ DecompQuotient (Subgroup.map φ Γ₁) (Subgroup.map φ Γ₂) d

                The decomposition quotient transports without injectivity, under an ambient subgroup. The kernel is absorbed by the denominator, so the index is unchanged.

                Equations
                Instances For
                  @[simp]
                  theorem DoubleCoset.decompQuotientEquivMapOfKerInfLe_mk {G : Type u_1} [Group G] {G' : Type u_2} [Group G'] (φ : G →* G') (Γ₁ Γ₂ H : Subgroup G) (g : G) {d : G'} (hd : φ g = d) (h₂ : Γ₂ ≤ H) (hconj : ∀ y ∈ Γ₁, g⁻¹ * y * g ∈ H) (hker : φ.ker ⊓ H ≤ Γ₂) (y : ↥Γ₁) :
                  (decompQuotientEquivMapOfKerInfLe φ Γ₁ Γ₂ H g hd h₂ hconj hker) ↑y = ↑((φ.subgroupMap Γ₁) y)
                  theorem DoubleCoset.conj_mem_of_mk_eq {G : Type u_1} [Group G] {H₁ H₂ : Subgroup G} (g : G) {u₁ u₂ : ↥H₁} (h : ↑u₁ = ↑u₂) :
                  g⁻¹ * ((↑u₁)⁻¹ * ↑u₂) * g ∈ H₂

                  Equality of classes in DecompQuotient H₁ H₂ g gives the conjugation relation between their representatives: u₁⁻¹ u₂ lies in the stabilizer indexing the decomposition, so conjugating it by g lands in H₂.

                  Note the two subgroups play different roles: the representatives live in H₁, which indexes the quotient, while the conclusion lands in H₂, which is the one being conjugated. They coincide in the common case DecompQuotient H H g.

                  theorem DoubleCoset.doubleCoset_eq_iUnion_rightCosets {G : Type u_1} [Group G] (Γ₁ Γ₂ : Subgroup G) (g : G) :
                  doubleCoset g ↑Γ₁ ↑Γ₂ = ⋃ (v : DecompQuotient Γ₂ Γ₁ g⁻¹), MulOpposite.op (g * (↑(Quotient.out v))⁻¹) • ↑Γ₁

                  Shimura's decomposition of a double coset into right cosets. Γ₁gΓ₂ is the union of the right cosets Γ₁ · (g τᵥ⁻¹), where τᵥ runs over representatives of Γ₂ ⧸ (Γ₂ ∩ g⁻¹Γ₁g) — the mirror of DoubleCoset.doubleCoset_eq_iUnion_leftCosets, and of Mathlib's doubleCoset_union_rightCoset, which is indexed by all of Γ₂ and so repeats each coset.

                  The inverse on τᵥ is what converts the left-coset quotient Γ₂ ⧸ (Γ₂ ∩ g⁻¹Γ₁g) into an index for the right cosets: Γ₁ g τ = Γ₁ g τ' exactly when τ'τ⁻¹ ∈ Γ₂ ∩ g⁻¹Γ₁g.

                  It lives here rather than beside doubleCoset_eq_iUnion_leftCosets because it is phrased with DecompQuotient, which this file defines.

                  theorem DoubleCoset.doubleCoset_eq_iUnion_rightCosets_of_forall_exists {G : Type u_1} [Group G] {ι : Type u_2} (Γ₁ Γ₂ : Subgroup G) (a : G) (rep : ι → G) (hforward : ∀ g ∈ Γ₂, ∃ (i : ι), ∃ d ∈ Γ₁, a * g = d * rep i) (hreverse : ∀ (i : ι), ∃ g ∈ Γ₂, a * g = rep i) :
                  doubleCoset a ↑Γ₁ ↑Γ₂ = ⋃ (i : ι), MulOpposite.op (rep i) • ↑Γ₁

                  A right-coset decomposition criterion. Suppose every product a * g with g ∈ Γ₂ factors as d * rep i with d ∈ Γ₁, and conversely every rep i equals a * g for some g ∈ Γ₂. Then the double coset Γ₁ a Γ₂ is the union of the right cosets Γ₁ · rep i.

                  This criterion proves coverage only; injectivity of the representative family is a separate property.

                  theorem DoubleCoset.op_mul_out_inv_smul_injective {G : Type u_1} [Group G] (Γ₁ Γ₂ : Subgroup G) (g : G) :
                  Function.Injective fun (v : DecompQuotient Γ₂ Γ₁ g⁻¹) => MulOpposite.op (g * (↑(Quotient.out v))⁻¹) • ↑Γ₁

                  The right cosets of doubleCoset_eq_iUnion_rightCosets are pairwise distinct, so that union is a partition and the sum of a Γ₁-invariant function over it counts each coset once.

                  theorem DoubleCoset.doubleCoset_mul_doubleCoset_eq_iUnion_rightCosets {G : Type u_1} [Group G] {Γ₁ Γ₂ Γ₃ : Subgroup G} {δ₁ δ₂ : G} {ι : Type u_2} {κ : Type u_3} (a : ι → G) (b : κ → G) (hcover₁ : doubleCoset δ₁ ↑Γ₁ ↑Γ₂ = ⋃ (i : ι), MulOpposite.op (a i) • ↑Γ₁) (hcover₂ : doubleCoset δ₂ ↑Γ₂ ↑Γ₃ = ⋃ (j : κ), MulOpposite.op (b j) • ↑Γ₂) :
                  doubleCoset δ₁ ↑Γ₁ ↑Γ₂ * doubleCoset δ₂ ↑Γ₂ ↑Γ₃ = ⋃ (p : ι × κ), MulOpposite.op (a p.1 * b p.2) • ↑Γ₁

                  Shimura's covering identity for a product of double cosets (§3.4). If Γ₁ δ₁ Γ₂ is the union of the right cosets Γ₁ aᵢ and Γ₂ δ₂ Γ₃ is the union of the right cosets Γ₂ bⱼ, then the pointwise product Γ₁ δ₁ Γ₂ · Γ₂ δ₂ Γ₃ is the union of the right cosets Γ₁ aᵢ bⱼ.

                  The two double cosets splice because Γ₂ Γ₂ = Γ₂: an element of the product is u v with u ∈ Γ₁ δ₁ Γ₂ and v ∈ Γ₂ δ₂ Γ₃; writing v = g bⱼ with g ∈ Γ₂ moves g into u, and u g is again in Γ₁ δ₁ Γ₂, hence in some Γ₁ aᵢ.

                  ⚠ The union is not disjoint, and the family (i, j) ↦ Γ₁ aᵢ bⱼ is in general far from injective. Any repetitions here are right-coset collisions; this theorem neither counts them nor identifies them with DoubleCoset.multiplicity, which uses left-coset representatives. The identity supplies coverage only, exactly as doubleCoset_eq_iUnion_rightCosets_of_forall_exists does for a single double coset.

                  Representatives of the right cosets in a double-coset decomposition #

                  noncomputable def DoubleCoset.rightCosetRep {G : Type u_1} [Group G] {Δ : Submonoid G} {Γ₁ Γ₂ : Subgroup G} (D : HeckeCoset Δ Γ₁ Γ₂) (v : DecompQuotient Γ₂ Γ₁ (↑(Quotient.out D))⁻¹) :
                  G

                  The representative δ τᵥ⁻¹ of the v-th right coset Γ₁ aᵥ in the decomposition Γ₁ δ Γ₂ = ⊔ᵥ Γ₁ aᵥ, where δ is the chosen representative of the double coset D and τᵥ runs over the chosen representatives of Γ₂ ⧸ (Γ₂ ∩ δ⁻¹Γ₁δ).

                  This is the named form of the union in doubleCoset_eq_iUnion_rightCosets above, at g := D.out. It is pure group theory — δ τᵥ⁻¹ in any group — which is why it sits here rather than with the modular-forms slash action that consumes it.

                  The inverse is what converts the left-coset quotient Mathlib supplies into the right-coset index the decomposition needs.

                  Equations
                  Instances For
                    theorem DoubleCoset.rightCosetRep_def {G : Type u_1} [Group G] {Δ : Submonoid G} {Γ₁ Γ₂ : Subgroup G} (D : HeckeCoset Δ Γ₁ Γ₂) (v : DecompQuotient Γ₂ Γ₁ (↑(Quotient.out D))⁻¹) :

                    Defining equation for rightCosetRep. Since rightCosetRep is not @[expose], a downstream module rewrites with this instead of unfolding the body.

                    theorem DoubleCoset.doubleCoset_eq_iUnion_rightCosetRep {G : Type u_1} [Group G] {Δ : Submonoid G} {Γ₁ Γ₂ : Subgroup G} (D : HeckeCoset Δ Γ₁ Γ₂) :
                    doubleCoset ↑(Quotient.out D) ↑Γ₁ ↑Γ₂ = ⋃ (v : DecompQuotient Γ₂ Γ₁ (↑(Quotient.out D))⁻¹), MulOpposite.op (rightCosetRep D v) • ↑Γ₁

                    Shimura's decomposition of the double coset, in the rightCosetRep spelling: Γ₁ δ Γ₂ = ⋃ᵥ Γ₁ (δ τᵥ⁻¹). Since rightCosetRep is not @[expose], this is how a downstream module reads DoubleCoset.doubleCoset_eq_iUnion_rightCosets at the representatives the slash sum is defined with.

                    theorem DoubleCoset.op_rightCosetRep_smul_injective {G : Type u_1} [Group G] {Δ : Submonoid G} {Γ₁ Γ₂ : Subgroup G} (D : HeckeCoset Δ Γ₁ Γ₂) :
                    Function.Injective fun (v : DecompQuotient Γ₂ Γ₁ (↑(Quotient.out D))⁻¹) => MulOpposite.op (rightCosetRep D v) • ↑Γ₁

                    The pieces of that decomposition are pairwise distinct, in the same spelling: DoubleCoset.op_mul_out_inv_smul_injective read at rightCosetRep.

                    theorem DoubleCoset.rightCosetRep_mem_doubleCoset {G : Type u_1} [Group G] {Δ : Submonoid G} {Γ₁ Γ₂ : Subgroup G} (D : HeckeCoset Δ Γ₁ Γ₂) (v : DecompQuotient Γ₂ Γ₁ (↑(Quotient.out D))⁻¹) :
                    rightCosetRep D v ∈ doubleCoset ↑(Quotient.out D) ↑Γ₁ ↑Γ₂

                    Each representative lies in the double coset, being a member of its own piece.

                    theorem DoubleCoset.exists_rightCosetRep_smul_eq {G : Type u_1} [Group G] {Δ : Submonoid G} {Γ₁ Γ₂ : Subgroup G} (D : HeckeCoset Δ Γ₁ Γ₂) {x : G} (hx : x ∈ doubleCoset ↑(Quotient.out D) ↑Γ₁ ↑Γ₂) :
                    ∃ (v : DecompQuotient Γ₂ Γ₁ (↑(Quotient.out D))⁻¹), MulOpposite.op x • ↑Γ₁ = MulOpposite.op (rightCosetRep D v) • ↑Γ₁

                    Every member of the double coset shares its right coset with a chosen representative: it lies in one of the pieces, and two right cosets of Γ₁ that meet are equal.

                    theorem DoubleCoset.rightCosetRep_mem {G : Type u_1} [Group G] {Δ : Submonoid G} {Γ₁ Γ₂ : Subgroup G} (D : HeckeCoset Δ Γ₁ Γ₂) {Δ' : Submonoid G} (hD : ↑(Quotient.out D) ∈ Δ') (hΓ₂ : Γ₂.toSubmonoid ≤ Δ') (v : DecompQuotient Γ₂ Γ₁ (↑(Quotient.out D))⁻¹) :

                    Each representative δ τᵥ⁻¹ lies in any submonoid Δ' containing the chosen δ and the group Γ₂. Only Γ₂ and δ are constrained: nothing is asked of Γ₁, nor of Δ beyond supplying δ. The hypothesis on Γ₂ is used at τᵥ⁻¹, which lies in Γ₂ because Γ₂ is a group.

                    theorem DoubleCoset.exists_mem_out_mul_inv_eq_mul_rightCosetRep {G : Type u_1} [Group G] {Δ : Submonoid G} {Γ₁ Γ₂ : Subgroup G} (D : HeckeCoset Δ Γ₁ Γ₂) {h₂ : G} (hh₂ : h₂ ∈ Γ₂) :
                    ∃ γ₁ ∈ Γ₁, ↑(Quotient.out D) * h₂⁻¹ = γ₁ * rightCosetRep D ↑⟨h₂, hh₂⟩

                    An element δ h₂⁻¹ of the double coset is a Γ₁-multiple of the representative attached to h₂'s class. For h₂ ∈ Γ₂, δ h₂⁻¹ = γ₁ · rightCosetRep D ⟦h₂⟧ for some γ₁ ∈ Γ₁, where δ = D.out: if u is the chosen representative of ⟦h₂⟧ then δ (u⁻¹ h₂) δ⁻¹ ∈ Γ₁ (conj_mem_of_mk_eq), and γ₁ is its inverse.

                    hh₂ is part of the statement rather than a side condition: the right-hand side names the class ⟦⟨h₂, hh₂⟩⟧. Membership is a Prop, so any proof of h₂ ∈ Γ₂ names the same class. This is the per-summand step behind Shimura's Proposition 3.37: right multiplication by an element of Γ₂ permutes the right cosets Γ₁ aᵥ, and a Γ₁-invariant summand does not see γ₁.

                    theorem DoubleCoset.exists_bijective_rightCosetRep_smul_eq {G : Type u_1} [Group G] {Δ : Submonoid G} {Γ₁ Γ₂ : Subgroup G} (D : HeckeCoset Δ Γ₁ Γ₂) {ι : Type u_2} (a : ι → G) (hcover : doubleCoset ↑(Quotient.out D) ↑Γ₁ ↑Γ₂ = ⋃ (i : ι), MulOpposite.op (a i) • ↑Γ₁) (hinj : Function.Injective fun (i : ι) => MulOpposite.op (a i) • ↑Γ₁) :
                    ∃ (φ : ι → DecompQuotient Γ₂ Γ₁ (↑(Quotient.out D))⁻¹), Function.Bijective φ ∧ ∀ (i : ι), MulOpposite.op (a i) • ↑Γ₁ = MulOpposite.op (rightCosetRep D (φ i)) • ↑Γ₁

                    Two families of representatives of the same right cosets are matched by a bijection. If the cosets Γ₁ aᵢ are pairwise distinct and cover Γ₁ D.out Γ₂, then the index type ι is matched with DecompQuotient Γ₂ Γ₁ (D.out)⁻¹ — the index Shimura's decomposition sums over — by a bijection φ carrying each Γ₁ aᵢ to Γ₁ (rightCosetRep D (φ i)).

                    This is pure coset bookkeeping. It identifies the two index sets compatibly with the cosets they name, and only that: the matched representatives aᵢ and rightCosetRep D (φ i) differ by a factor of Γ₁, so a summand that can see the representative still distinguishes them. Equating two sums over the families needs, in addition, a summand depending only on the coset — for a slash term, HeckeRing.GL2.slash_eq_of_rightCoset_eq on a Γ₁-invariant function; for a representation, Representation.comp_eq_of_rightCoset_eq.

                    theorem DoubleCoset.card_filter_eq_of_rightCosetRep_smul_eq {G : Type u_1} [Group G] {Δ : Submonoid G} {Γ₁ Γ₂ : Subgroup G} (D : HeckeCoset Δ Γ₁ Γ₂) {ι : Type u_2} [Fintype ι] {a : ι → G} {m : ℕ} (hcard : ∀ x ∈ doubleCoset ↑(Quotient.out D) ↑Γ₁ ↑Γ₂, Nat.card { i : ι // MulOpposite.op (a i) • ↑Γ₁ = MulOpposite.op x • ↑Γ₁ } = m) {g : ι → DecompQuotient Γ₂ Γ₁ (↑(Quotient.out D))⁻¹} (hg : ∀ (i : ι), MulOpposite.op (a i) • ↑Γ₁ = MulOpposite.op (rightCosetRep D (g i)) • ↑Γ₁) (v : DecompQuotient Γ₂ Γ₁ (↑(Quotient.out D))⁻¹) [DecidablePred fun (i : ι) => g i = v] :
                    {i : ι | g i = v}.card = m

                    Each fibre of the naming map has m elements. Let g name, for each index i, the right coset that aᵢ lies in — Γ₁ aᵢ = Γ₁ (rightCosetRep D (g i)) — and let every right coset of the double coset be named by exactly m members of the family. Then g i = v for exactly m indices i, whatever v.

                    The hypothesis counts indices by the coset they name and the conclusion counts them by their image under g; the two agree because rightCosetRep names distinct cosets by distinct elements (op_rightCosetRep_smul_injective).

                    Like exists_bijective_rightCosetRep_smul_eq this is pure coset bookkeeping. It is the counting half of the multiplicity-weighted collapse of a sum over a family that names each right coset m times: each fibre has m elements. Reaching m • a single operator needs the other half too — that the terms on a fibre agree, which is what a summand depending only on the right coset supplies.

                    theorem IsHeckeTriple.mem_of_mem_doubleCoset {G : Type u_1} [Group G] {Δ : Submonoid G} {H₁ H₂ : Subgroup G} [IsHeckeTriple Δ H₁ H₂] {g x : G} (hg : g ∈ Δ) (hx : x ∈ DoubleCoset.doubleCoset g ↑H₁ ↑H₂) :
                    x ∈ Δ

                    Every member of the double coset H₁gH₂ of an element of Δ lies in Δ.

                    @[instance_reducible]
                    noncomputable instance IsHeckeTriple.instFintypeDecompQuotientValMemSubmonoid {G : Type u_1} [Group G] {Δ : Submonoid G} {H₁ H₂ : Subgroup G} [IsHeckeTriple Δ H₁ H₂] (g : ↥Δ) :

                    For a Hecke triple, the decomposition quotient of any g : Δ is finite: Δ commensurates H₂, which is commensurable with H₁.

                    Equations
                    theorem IsHeckeTriple.commensurable_conjAct_inv_left {G : Type u_1} [Group G] {Δ : Submonoid G} {H₁ H₂ : Subgroup G} [IsHeckeTriple Δ H₁ H₂] (g : ↥Δ) :

                    Conjugating the left subgroup by the inverse of an element of Δ gives a subgroup commensurable with the right one. This is commensurable_conjAct_right on the other flank: the commensurator is a subgroup, so it contains g⁻¹ along with g.

                    It is what makes DecompQuotient H₂ H₁ g⁻¹ — the index of Shimura's decomposition of H₁gH₂ into right cosets H₁a — finite.

                    instance IsHeckeTriple.instFiniteDecompQuotientInvValMemSubmonoid {G : Type u_1} [Group G] {Δ : Submonoid G} {H₁ H₂ : Subgroup G} [IsHeckeTriple Δ H₁ H₂] (g : ↥Δ) :

                    For a Hecke triple, the right-coset decomposition quotient of any g : Δ is finite.

                    This is the companion of the instance above on the other flank, and it is the finiteness the slash sum over Shimura's decomposition H₁gH₂ = ⊔ᵥ H₁aᵥ needs. Finite rather than Fintype: no enumeration is chosen here, and a second Fintype on a quotient of the same shape would compete with the one above.

                    noncomputable def HeckeCoset.degree {G : Type u_2} [Group G] {Δ : Submonoid G} {H₁ H₂ : Subgroup G} (D : HeckeCoset Δ H₁ H₂) :

                    The degree of a double coset: the number of left cosets σᵢgH₂ in the decomposition H₁gH₂ = ⊔ᵢ σᵢgH₂, i.e. the relative index [H₁ : H₁ ∩ gH₂g⁻¹]. Stating it needs no finiteness — Subgroup.relIndex is a Nat.card, which is 0 when the index is infinite; the Hecke-triple hypothesis enters only where the count is genuinely finite.

                    Equations
                    Instances For
                      theorem HeckeCoset.degree_eq_relIndex {G : Type u_2} [Group G] {Δ : Submonoid G} {H₁ H₂ : Subgroup G} (D : HeckeCoset Δ H₁ H₂) :

                      The degree as a relative index: deg(H₁gH₂) = [H₁ : H₁ ∩ gH₂g⁻¹]. This is the form in which concrete degree computations identify the count with a congruence-subgroup index.

                      @[simp]
                      theorem HeckeCoset.degree_mk {G : Type u_2} [Group G] {Δ : Submonoid G} {H₁ H₂ : Subgroup G} (g : ↥Δ) :
                      (mk H₁ H₂ g).degree = (ConjAct.toConjAct ↑g • H₂).relIndex H₁

                      The degree at an explicit representative: the count computed from any g, not only from the chosen rep. This is the form concrete coset calculations use, since they present a double coset as mk H H g.

                      @[simp]
                      theorem HeckeCoset.degree_one {G : Type u_2} [Group G] {Δ : Submonoid G} {H : Subgroup G} :
                      degree 1 = 1

                      The identity double coset has degree one: H·1·H = H is a single left coset.

                      theorem HeckeCoset.degree_eq_natCard_decompQuotient {G : Type u_2} [Group G] {Δ : Submonoid G} {H₁ H₂ : Subgroup G} (D : HeckeCoset Δ H₁ H₂) :

                      The degree counts the decomposition quotient. No finiteness is involved: a relative index is by definition the Nat.card of exactly this quotient, so the two sides are the same term.

                      theorem HeckeCoset.degree_eq_card_decompQuotient {G : Type u_2} [Group G] {Δ : Submonoid G} {H₁ H₂ : Subgroup G} [IsHeckeTriple Δ H₁ H₂] (D : HeckeCoset Δ H₁ H₂) :

                      Under the Hecke-triple hypothesis the decomposition quotient is finite, so the degree is its Fintype.card. The hypothesis is needed only for the Fintype instance, not for the count itself — see degree_eq_natCard_decompQuotient.

                      theorem HeckeCoset.degree_pos {G : Type u_2} [Group G] {Δ : Submonoid G} {H₁ H₂ : Subgroup G} [IsHeckeTriple Δ H₁ H₂] (D : HeckeCoset Δ H₁ H₂) :
                      0 < D.degree

                      Every double coset has positive degree.

                      noncomputable def HeckeCosetModule.single {G : Type u_2} [Group G] {Δ : Submonoid G} {H₁ H₂ : Subgroup G} (R : Type u_3) [Zero R] (D : HeckeCoset Δ H₁ H₂) (b : R) :
                      HeckeCosetModule Δ H₁ H₂ R

                      A basis element of the Hecke coset module: single R D b is the formal sum b • [D]. As for Finsupp itself, this is the type-correct way to produce elements of HeckeCosetModule Δ H₁ H₂ R. Only [Zero R] is assumed, so consumers with coefficient assumptions below Semiring (the left-coset scalar operations) can use it.

                      Equations
                      Instances For
                        theorem HeckeCosetModule.sum_single_index {G : Type u_2} [Group G] {Δ : Submonoid G} {H₁ H₂ : Subgroup G} (R : Type u_3) [Zero R] {N : Type u_4} [AddCommMonoid N] {D : HeckeCoset Δ H₁ H₂} {b : R} {F : HeckeCoset Δ H₁ H₂ → R → N} (h : F D 0 = 0) :
                        Finsupp.sum (single R D b) F = F D b

                        Finsupp.sum_single_index, as a wrapper-level equation: summing over a basis element evaluates the summand at its point.

                        @[simp]
                        theorem HeckeCosetModule.single_apply {G : Type u_2} [Group G] {Δ : Submonoid G} {H₁ H₂ : Subgroup G} (R : Type u_3) [Zero R] {D A : HeckeCoset Δ H₁ H₂} {b : R} [Decidable (D = A)] :
                        (single R D b) A = if D = A then b else 0

                        Evaluating a basis element: single R D b is b at D and 0 elsewhere.

                        @[simp]
                        theorem HeckeCosetModule.single_zero {G : Type u_2} [Group G] {Δ : Submonoid G} {H₁ H₂ : Subgroup G} (R : Type u_3) [AddCommMonoid R] (D : HeckeCoset Δ H₁ H₂) :
                        single R D 0 = 0

                        Finsupp.single_zero, as a wrapper-level equation.

                        @[simp]
                        theorem HeckeCosetModule.sum_single {G : Type u_2} [Group G] {Δ : Submonoid G} {H₁ H₂ : Subgroup G} (R : Type u_3) [AddCommMonoid R] (f : HeckeCosetModule Δ H₁ H₂ R) :

                        Every element is the sum of its basis components.

                        @[simp]
                        theorem HeckeCosetModule.single_add {G : Type u_2} [Group G] {Δ : Submonoid G} {H₁ H₂ : Subgroup G} (R : Type u_3) [AddCommMonoid R] (D : HeckeCoset Δ H₁ H₂) (b c : R) :
                        single R D (b + c) = single R D b + single R D c

                        Finsupp.single_add, as a wrapper-level equation.

                        theorem HeckeCosetModule.induction_linear {G : Type u_2} [Group G] {Δ : Submonoid G} {H₁ H₂ : Subgroup G} (R : Type u_3) [AddCommMonoid R] {p : HeckeCosetModule Δ H₁ H₂ R → Prop} (f : HeckeCosetModule Δ H₁ H₂ R) (h0 : p 0) (hadd : ∀ (f g : HeckeCosetModule Δ H₁ H₂ R), p f → p g → p (f + g)) (hsingle : ∀ (D : HeckeCoset Δ H₁ H₂) (b : R), p (single R D b)) :
                        p f

                        Finsupp.induction_linear, restated for the wrapper type HeckeCosetModule Δ H₁ H₂ R in its basis vocabulary single, in the same way that MonoidAlgebra.induction_linear restates it for MonoidAlgebra: to prove a property of all elements, prove it for 0, for sums, and for basis elements.

                        @[instance_reducible]
                        noncomputable instance HeckeCosetModule.instModule {G : Type u_2} [Group G] {Δ : Submonoid G} {H₁ H₂ : Subgroup G} (R : Type u_3) [Semiring R] :
                        Module R (HeckeCosetModule Δ H₁ H₂ R)

                        The R-module structure of the Hecke coset module, transporting the standard Finsupp module structure to the wrapper type.

                        Equations
                        @[simp]
                        theorem HeckeCosetModule.smul_single_one {G : Type u_2} [Group G] {Δ : Submonoid G} {H₁ H₂ : Subgroup G} (R : Type u_3) [Semiring R] (D : HeckeCoset Δ H₁ H₂) (b : R) :
                        b • single R D 1 = single R D b

                        Scaling the unit basis element produces the basis element of the scalar.

                        Pointwise evaluation #

                        HeckeCosetModule is a def over Finsupp, so Mathlib's Finsupp evaluation lemmas hold definitionally but neither rw nor simp can match them through the wrapper. These are the wrapper-level restatements; without them every consumer re-derives its own private copies. Each is stated at the coefficient assumptions its underlying operation actually needs: the FunLike coercion and Finsupp.support need only [Zero R], while the wrapper's 0, + and • come from its AddCommMonoid and Module instances.

                        @[simp]
                        theorem HeckeCosetModule.mem_support_iff {G : Type u_2} [Group G] {Δ : Submonoid G} {H₁ H₂ : Subgroup G} {R : Type u_3} [Zero R] {f : HeckeCosetModule Δ H₁ H₂ R} {D : HeckeCoset Δ H₁ H₂} :
                        D ∈ f.support ↔ f D ≠ 0

                        Finsupp.mem_support_iff, at the wrapper type.

                        theorem HeckeCosetModule.notMem_support_iff {G : Type u_2} [Group G] {Δ : Submonoid G} {H₁ H₂ : Subgroup G} {R : Type u_3} [Zero R] {f : HeckeCosetModule Δ H₁ H₂ R} {D : HeckeCoset Δ H₁ H₂} :
                        D ∉ f.support ↔ f D = 0

                        Finsupp.notMem_support_iff, at the wrapper type: the elimination form of mem_support_iff. Deliberately unannotated — mem_support_iff is the @[simp] normal form, and simp discharges this direction from it.

                        theorem HeckeCosetModule.sum_def {G : Type u_2} [Group G] {Δ : Submonoid G} {H₁ H₂ : Subgroup G} {R : Type u_3} [Zero R] {N : Type u_4} [AddCommMonoid N] (f : HeckeCosetModule Δ H₁ H₂ R) (F : HeckeCoset Δ H₁ H₂ → R → N) :
                        Finsupp.sum f F = ∑ D ∈ f.support, F D (f D)

                        Finsupp.sum unfolded to a Finset.sum, at the wrapper type.

                        @[simp]
                        theorem HeckeCosetModule.sum_apply {G : Type u_2} [Group G] {Δ : Submonoid G} {H₁ H₂ : Subgroup G} {R : Type u_3} [Zero R] {S : Type u_4} [AddCommMonoid S] {H₃ H₄ : Subgroup G} (f : HeckeCosetModule Δ H₁ H₂ R) (F : HeckeCoset Δ H₁ H₂ → R → HeckeCosetModule Δ H₃ H₄ S) (D : HeckeCoset Δ H₃ H₄) :
                        (Finsupp.sum f F) D = Finsupp.sum f fun (E : HeckeCoset Δ H₁ H₂) (c : R) => (F E c) D

                        Finsupp.sum_apply, at the wrapper type: evaluation commutes with a Finsupp.sum. The target coefficients are independent of the source's.

                        @[simp]
                        theorem HeckeCosetModule.zero_apply {G : Type u_2} [Group G] {Δ : Submonoid G} {H₁ H₂ : Subgroup G} {R : Type u_3} [AddCommMonoid R] (D : HeckeCoset Δ H₁ H₂) :
                        0 D = 0

                        Finsupp.zero_apply, at the wrapper type. Not @[grind =]: unlike Mathlib's Finsupp.zero_apply, where M is recoverable from (0 : α →₀ M), the wrapper's coercion leaves R and its AddCommMonoid uninstantiable, and grind rejects the pattern.

                        @[simp]
                        theorem HeckeCosetModule.add_apply {G : Type u_2} [Group G] {Δ : Submonoid G} {H₁ H₂ : Subgroup G} {R : Type u_3} [AddCommMonoid R] (f g : HeckeCosetModule Δ H₁ H₂ R) (D : HeckeCoset Δ H₁ H₂) :
                        (f + g) D = f D + g D

                        Finsupp.add_apply, at the wrapper type.

                        @[simp]
                        theorem HeckeCosetModule.smul_apply {G : Type u_2} [Group G] {Δ : Submonoid G} {H₁ H₂ : Subgroup G} {R : Type u_3} [Semiring R] (a : R) (f : HeckeCosetModule Δ H₁ H₂ R) (D : HeckeCoset Δ H₁ H₂) :
                        (a • f) D = a * f D

                        Finsupp.smul_apply, at the wrapper type.

                        theorem HeckeCosetModule.sum_smul_index {G : Type u_2} [Group G] {Δ : Submonoid G} {H₁ H₂ : Subgroup G} {R : Type u_3} [Semiring R] {N : Type u_4} [AddCommMonoid N] (a : R) (f : HeckeCosetModule Δ H₁ H₂ R) (F : HeckeCoset Δ H₁ H₂ → R → N) (h0 : ∀ (D : HeckeCoset Δ H₁ H₂), F D 0 = 0) :
                        Finsupp.sum (a • f) F = Finsupp.sum f fun (D : HeckeCoset Δ H₁ H₂) (c : R) => F D (a * c)

                        Finsupp.sum_smul_index, at the wrapper type: a scalar pushes into a Finsupp.sum.