Theorem: MonoidHom.transfer_eq_pow
File: Mathlib/GroupTheory/Transfer.lean

tactic: classical
  letI := H.fintypeQuotientOfFiniteIndex
  change ∀ (k g₀) (hk : g₀⁻¹ * g ^ k * g₀ ∈ H), ↑(⟨g₀⁻¹ * g ^ k * g₀, hk⟩ : H) = g ^ k at key
  rw [transfer_eq_prod_quotient_orbitRel_zpowers_quot, ← Finset.prod_to_list]
  refine' (List.prod_map_hom _ _ _).trans _ refine' congrArg ϕ (Subtype.coe_injective _)
  simp only rw [H.coe_mk, ← (zpowers g).coe_mk g (mem_zpowers g), ← (zpowers g).coe_pow,
    index_eq_card, Fintype.card_congr (selfEquivSigmaOrbits (zpowers g) (G ⧸ H)),
    Fintype.card_sigma, ← Finset.prod_pow_eq_pow_sum, ← Finset.prod_to_list]
  simp only [Subgroup.val_list_prod, List.map_map, ← minimalPeriod_eq_card]
  congr
  funext
  apply key
state_before: G : Type u_1
inst✝² : Group G
H : Subgroup G
A : Type u_2
inst✝¹ : CommGroup A
ϕ : { x // x ∈ H } →* A
T : ↑(leftTransversals ↑H)
inst✝ : FiniteIndex H
g : G
key : ∀ (k : ℕ) (g₀ : G), g₀⁻¹ * g ^ k * g₀ ∈ H → g₀⁻¹ * g ^ k * g₀ = g ^ k
⊢ ↑(transfer ϕ) g = ↑ϕ { val := g ^ index H, property := (_ : g ^ index H ∈ H) }

tactic: letI := H.fintypeQuotientOfFiniteIndex
state_before: G : Type u_1
inst✝² : Group G
H : Subgroup G
A : Type u_2
inst✝¹ : CommGroup A
ϕ : { x // x ∈ H } →* A
T : ↑(leftTransversals ↑H)
inst✝ : FiniteIndex H
g : G
key : ∀ (k : ℕ) (g₀ : G), g₀⁻¹ * g ^ k * g₀ ∈ H → g₀⁻¹ * g ^ k * g₀ = g ^ k
⊢ ↑(transfer ϕ) g = ↑ϕ { val := g ^ index H, property := (_ : g ^ index H ∈ H) }

tactic: change ∀ (k g₀) (hk : g₀⁻¹ * g ^ k * g₀ ∈ H), ↑(⟨g₀⁻¹ * g ^ k * g₀, hk⟩ : H) = g ^ k at key
state_before: G : Type u_1
inst✝² : Group G
H : Subgroup G
A : Type u_2
inst✝¹ : CommGroup A
ϕ : { x // x ∈ H } →* A
T : ↑(leftTransversals ↑H)
inst✝ : FiniteIndex H
g : G
key : ∀ (k : ℕ) (g₀ : G), g₀⁻¹ * g ^ k * g₀ ∈ H → g₀⁻¹ * g ^ k * g₀ = g ^ k
this : Fintype (G ⧸ H) := fintypeQuotientOfFiniteIndex H
⊢ ↑(transfer ϕ) g = ↑ϕ { val := g ^ index H, property := (_ : g ^ index H ∈ H) }

tactic: rw [transfer_eq_prod_quotient_orbitRel_zpowers_quot, ← Finset.prod_to_list]
state_before: G : Type u_1
inst✝² : Group G
H : Subgroup G
A : Type u_2
inst✝¹ : CommGroup A
ϕ : { x // x ∈ H } →* A
T : ↑(leftTransversals ↑H)
inst✝ : FiniteIndex H
g : G
this : Fintype (G ⧸ H) := fintypeQuotientOfFiniteIndex H
key : ∀ (k : ℕ) (g₀ : G) (hk : g₀⁻¹ * g ^ k * g₀ ∈ H), ↑{ val := g₀⁻¹ * g ^ k * g₀, property := hk } = g ^ k
⊢ ↑(transfer ϕ) g = ↑ϕ { val := g ^ index H, property := (_ : g ^ index H ∈ H) }

tactic: refine' (List.prod_map_hom _ _ _).trans _
state_before: G : Type u_1
inst✝² : Group G
H : Subgroup G
A : Type u_2
inst✝¹ : CommGroup A
ϕ : { x // x ∈ H } →* A
T : ↑(leftTransversals ↑H)
inst✝ : FiniteIndex H
g : G
this : Fintype (G ⧸ H) := fintypeQuotientOfFiniteIndex H
key : ∀ (k : ℕ) (g₀ : G) (hk : g₀⁻¹ * g ^ k * g₀ ∈ H), ↑{ val := g₀⁻¹ * g ^ k * g₀, property := hk } = g ^ k
⊢ List.prod
      (List.map
        (fun q =>
          ↑ϕ
            {
              val :=
                (Quotient.out' (Quotient.out' q))⁻¹ *
                    g ^ Function.minimalPeriod ((fun x x_1 => x • x_1) g) (Quotient.out' q) *
                  Quotient.out' (Quotient.out' q),
              property :=
                (_ :
                  (Quotient.out' (Quotient.out' q))⁻¹ *
                        g ^ Function.minimalPeriod ((fun x x_1 => x • x_1) g) (Quotient.out' q) *
                      Quotient.out' (Quotient.out' q) ∈
                    H) })
        (Finset.toList Finset.univ)) =
    ↑ϕ { val := g ^ index H, property := (_ : g ^ index H ∈ H) }

tactic: refine' congrArg ϕ (Subtype.coe_injective _)
state_before: G : Type u_1
inst✝² : Group G
H : Subgroup G
A : Type u_2
inst✝¹ : CommGroup A
ϕ : { x // x ∈ H } →* A
T : ↑(leftTransversals ↑H)
inst✝ : FiniteIndex H
g : G
this : Fintype (G ⧸ H) := fintypeQuotientOfFiniteIndex H
key : ∀ (k : ℕ) (g₀ : G) (hk : g₀⁻¹ * g ^ k * g₀ ∈ H), ↑{ val := g₀⁻¹ * g ^ k * g₀, property := hk } = g ^ k
⊢ ↑ϕ
      (List.prod
        (List.map
          (fun q =>
            {
              val :=
                (Quotient.out' (Quotient.out' q))⁻¹ *
                    g ^ Function.minimalPeriod ((fun x x_1 => x • x_1) g) (Quotient.out' q) *
                  Quotient.out' (Quotient.out' q),
              property :=
                (_ :
                  (Quotient.out' (Quotient.out' q))⁻¹ *
                        g ^ Function.minimalPeriod ((fun x x_1 => x • x_1) g) (Quotient.out' q) *
                      Quotient.out' (Quotient.out' q) ∈
                    H) })
          (Finset.toList Finset.univ))) =
    ↑ϕ { val := g ^ index H, property := (_ : g ^ index H ∈ H) }

tactic: simp only
state_before: G : Type u_1
inst✝² : Group G
H : Subgroup G
A : Type u_2
inst✝¹ : CommGroup A
ϕ : { x // x ∈ H } →* A
T : ↑(leftTransversals ↑H)
inst✝ : FiniteIndex H
g : G
this : Fintype (G ⧸ H) := fintypeQuotientOfFiniteIndex H
key : ∀ (k : ℕ) (g₀ : G) (hk : g₀⁻¹ * g ^ k * g₀ ∈ H), ↑{ val := g₀⁻¹ * g ^ k * g₀, property := hk } = g ^ k
⊢ (fun a => ↑a)
      (List.prod
        (List.map
          (fun q =>
            {
              val :=
                (Quotient.out' (Quotient.out' q))⁻¹ *
                    g ^ Function.minimalPeriod ((fun x x_1 => x • x_1) g) (Quotient.out' q) *
                  Quotient.out' (Quotient.out' q),
              property :=
                (_ :
                  (Quotient.out' (Quotient.out' q))⁻¹ *
                        g ^ Function.minimalPeriod ((fun x x_1 => x • x_1) g) (Quotient.out' q) *
                      Quotient.out' (Quotient.out' q) ∈
                    H) })
          (Finset.toList Finset.univ))) =
    (fun a => ↑a) { val := g ^ index H, property := (_ : g ^ index H ∈ H) }

tactic: rw [H.coe_mk, ← (zpowers g).coe_mk g (mem_zpowers g), ← (zpowers g).coe_pow,
  index_eq_card, Fintype.card_congr (selfEquivSigmaOrbits (zpowers g) (G ⧸ H)),
  Fintype.card_sigma, ← Finset.prod_pow_eq_pow_sum, ← Finset.prod_to_list]
state_before: G : Type u_1
inst✝² : Group G
H : Subgroup G
A : Type u_2
inst✝¹ : CommGroup A
ϕ : { x // x ∈ H } →* A
T : ↑(leftTransversals ↑H)
inst✝ : FiniteIndex H
g : G
this : Fintype (G ⧸ H) := fintypeQuotientOfFiniteIndex H
key : ∀ (k : ℕ) (g₀ : G) (hk : g₀⁻¹ * g ^ k * g₀ ∈ H), ↑{ val := g₀⁻¹ * g ^ k * g₀, property := hk } = g ^ k
⊢ ↑(List.prod
        (List.map
          (fun q =>
            {
              val :=
                (Quotient.out' (Quotient.out' q))⁻¹ * g ^ Function.minimalPeriod (fun x => g • x) (Quotient.out' q) *
                  Quotient.out' (Quotient.out' q),
              property :=
                (_ :
                  (Quotient.out' (Quotient.out' q))⁻¹ *
                        g ^ Function.minimalPeriod ((fun x x_1 => x • x_1) g) (Quotient.out' q) *
                      Quotient.out' (Quotient.out' q) ∈
                    H) })
          (Finset.toList Finset.univ))) =
    g ^ index H

tactic: simp only [Subgroup.val_list_prod, List.map_map, ← minimalPeriod_eq_card]
state_before: G : Type u_1
inst✝² : Group G
H : Subgroup G
A : Type u_2
inst✝¹ : CommGroup A
ϕ : { x // x ∈ H } →* A
T : ↑(leftTransversals ↑H)
inst✝ : FiniteIndex H
g : G
this : Fintype (G ⧸ H) := fintypeQuotientOfFiniteIndex H
key : ∀ (k : ℕ) (g₀ : G) (hk : g₀⁻¹ * g ^ k * g₀ ∈ H), ↑{ val := g₀⁻¹ * g ^ k * g₀, property := hk } = g ^ k
⊢ ↑(List.prod
        (List.map
          (fun q =>
            {
              val :=
                (Quotient.out' (Quotient.out' q))⁻¹ *
                    ↑{ val := g, property := (_ : g ∈ zpowers g) } ^
                      Function.minimalPeriod (fun x => ↑{ val := g, property := (_ : g ∈ zpowers g) } • x)
                        (Quotient.out' q) *
                  Quotient.out' (Quotient.out' q),
              property :=
                (_ :
                  (Quotient.out' (Quotient.out' q))⁻¹ *
                        ↑{ val := g, property := (_ : g ∈ zpowers g) } ^
                          Function.minimalPeriod ((fun x x_1 => x • x_1) ↑{ val := g, property := (_ : g ∈ zpowers g) })
                            (Quotient.out' q) *
                      Quotient.out' (Quotient.out' q) ∈
                    H) })
          (Finset.toList Finset.univ))) =
    ↑(List.prod
        (List.map
          (fun i =>
            { val := g, property := (_ : g ∈ zpowers g) } ^
              Fintype.card ↑(orbit { x // x ∈ zpowers g } (Quotient.out' i)))
          (Finset.toList Finset.univ)))

tactic: congr
state_before: G : Type u_1
inst✝² : Group G
H : Subgroup G
A : Type u_2
inst✝¹ : CommGroup A
ϕ : { x // x ∈ H } →* A
T : ↑(leftTransversals ↑H)
inst✝ : FiniteIndex H
g : G
this : Fintype (G ⧸ H) := fintypeQuotientOfFiniteIndex H
key : ∀ (k : ℕ) (g₀ : G) (hk : g₀⁻¹ * g ^ k * g₀ ∈ H), ↑{ val := g₀⁻¹ * g ^ k * g₀, property := hk } = g ^ k
⊢ List.prod
      (List.map
        (Subtype.val ∘ fun q =>
          {
            val :=
              (Quotient.out' (Quotient.out' q))⁻¹ * g ^ Function.minimalPeriod (fun x => g • x) (Quotient.out' q) *
                Quotient.out' (Quotient.out' q),
            property :=
              (_ :
                (Quotient.out' (Quotient.out' q))⁻¹ *
                      ↑{ val := g, property := (_ : g ∈ zpowers g) } ^
                        Function.minimalPeriod ((fun x x_1 => x • x_1) ↑{ val := g, property := (_ : g ∈ zpowers g) })
                          (Quotient.out' q) *
                    Quotient.out' (Quotient.out' q) ∈
                  H) })
        (Finset.toList Finset.univ)) =
    List.prod
      (List.map
        (Subtype.val ∘ fun i =>
          { val := g, property := (_ : g ∈ zpowers g) } ^ Function.minimalPeriod (fun x => g • x) (Quotient.out' i))
        (Finset.toList Finset.univ))

tactic: funext
state_before: case e_a.e_f
G : Type u_1
inst✝² : Group G
H : Subgroup G
A : Type u_2
inst✝¹ : CommGroup A
ϕ : { x // x ∈ H } →* A
T : ↑(leftTransversals ↑H)
inst✝ : FiniteIndex H
g : G
this : Fintype (G ⧸ H) := fintypeQuotientOfFiniteIndex H
key : ∀ (k : ℕ) (g₀ : G) (hk : g₀⁻¹ * g ^ k * g₀ ∈ H), ↑{ val := g₀⁻¹ * g ^ k * g₀, property := hk } = g ^ k
⊢ (Subtype.val ∘ fun q =>
      {
        val :=
          (Quotient.out' (Quotient.out' q))⁻¹ * g ^ Function.minimalPeriod (fun x => g • x) (Quotient.out' q) *
            Quotient.out' (Quotient.out' q),
        property :=
          (_ :
            (Quotient.out' (Quotient.out' q))⁻¹ *
                  ↑{ val := g, property := (_ : g ∈ zpowers g) } ^
                    Function.minimalPeriod ((fun x x_1 => x • x_1) ↑{ val := g, property := (_ : g ∈ zpowers g) })
                      (Quotient.out' q) *
                Quotient.out' (Quotient.out' q) ∈
              H) }) =
    Subtype.val ∘ fun i =>
      { val := g, property := (_ : g ∈ zpowers g) } ^ Function.minimalPeriod (fun x => g • x) (Quotient.out' i)

tactic: apply key
state_before: case e_a.e_f.h
G : Type u_1
inst✝² : Group G
H : Subgroup G
A : Type u_2
inst✝¹ : CommGroup A
ϕ : { x // x ∈ H } →* A
T : ↑(leftTransversals ↑H)
inst✝ : FiniteIndex H
g : G
this : Fintype (G ⧸ H) := fintypeQuotientOfFiniteIndex H
key : ∀ (k : ℕ) (g₀ : G) (hk : g₀⁻¹ * g ^ k * g₀ ∈ H), ↑{ val := g₀⁻¹ * g ^ k * g₀, property := hk } = g ^ k
x✝ : Quotient (orbitRel { x // x ∈ zpowers g } (G ⧸ H))
⊢ (Subtype.val ∘ fun q =>
        {
          val :=
            (Quotient.out' (Quotient.out' q))⁻¹ * g ^ Function.minimalPeriod (fun x => g • x) (Quotient.out' q) *
              Quotient.out' (Quotient.out' q),
          property :=
            (_ :
              (Quotient.out' (Quotient.out' q))⁻¹ *
                    ↑{ val := g, property := (_ : g ∈ zpowers g) } ^
                      Function.minimalPeriod ((fun x x_1 => x • x_1) ↑{ val := g, property := (_ : g ∈ zpowers g) })
                        (Quotient.out' q) *
                  Quotient.out' (Quotient.out' q) ∈
                H) })
      x✝ =
    (Subtype.val ∘ fun i =>
        { val := g, property := (_ : g ∈ zpowers g) } ^ Function.minimalPeriod (fun x => g • x) (Quotient.out' i))
      x✝