l3lab/ntp-mathlib huggingface dataset:
theorem transfer_eq_pow [FiniteIndex H] (g : G)
    (key : ∀ (k : ℕ) (g₀ : G), g₀⁻¹ * g ^ k * g₀ ∈ H → g₀⁻¹ * g ^ k * g₀ = g ^ k) :
    transfer ϕ g = ϕ ⟨g ^ H.index, transfer_eq_pow_aux g key⟩ := by
  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 _ -- porting note: this used to be in the `rw`
    refine' congrArg ϕ (Subtype.coe_injective _)
    simp only -- porting note: added `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]
    

Proof state:
G : Type u_1
inst✝² : Group G
H : Subgroup G
A : Type u_2
inst✝¹ : CommGroup A
ϕ : ↥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 => ↑{ val := g, property := (_ : g ∈ zpowers g) } • x)
                            (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 (↥(zpowers g)) (Quotient.out' i)))
          (Finset.toList Finset.univ)))

Next tactic:
simp only [Subgroup.val_list_prod, List.map_map, ← minimalPeriod_eq_card]
theorem transfer_eq_pow [FiniteIndex H] (g : G)
    (key : ∀ (k : ℕ) (g₀ : G), g₀⁻¹ * g ^ k * g₀ ∈ H → g₀⁻¹ * g ^ k * g₀ = g ^ k) :
    transfer ϕ g = ϕ ⟨g ^ H.index, transfer_eq_pow_aux g key⟩ := by
  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 _ -- porting note: this used to be in the `rw`
    refine' congrArg ϕ (Subtype.coe_injective _)
    simp only -- porting note: added `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]
    

Proof state:
G : Type u_1
inst✝² : Group G
H : Subgroup G
A : Type u_2
inst✝¹ : CommGroup A
ϕ : ↥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 => ↑{ val := g, property := (_ : g ∈ zpowers g) } • x)
                          (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))

Next tactic:
congr
theorem transfer_eq_pow [FiniteIndex H] (g : G)
    (key : ∀ (k : ℕ) (g₀ : G), g₀⁻¹ * g ^ k * g₀ ∈ H → g₀⁻¹ * g ^ k * g₀ = g ^ k) :
    transfer ϕ g = ϕ ⟨g ^ H.index, transfer_eq_pow_aux g key⟩ := by
  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 _ -- porting note: this used to be in the `rw`
    refine' congrArg ϕ (Subtype.coe_injective _)
    simp only -- porting note: added `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
    

Proof state:
case e_a.e_f
G : Type u_1
inst✝² : Group G
H : Subgroup G
A : Type u_2
inst✝¹ : CommGroup A
ϕ : ↥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 => ↑{ val := g, property := (_ : g ∈ zpowers g) } • x)
                      (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)

Next tactic:
funext
theorem transfer_eq_pow [FiniteIndex H] (g : G)
    (key : ∀ (k : ℕ) (g₀ : G), g₀⁻¹ * g ^ k * g₀ ∈ H → g₀⁻¹ * g ^ k * g₀ = g ^ k) :
    transfer ϕ g = ϕ ⟨g ^ H.index, transfer_eq_pow_aux g key⟩ := by
  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 _ -- porting note: this used to be in the `rw`
    refine' congrArg ϕ (Subtype.coe_injective _)
    simp only -- porting note: added `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
    

Proof state:
case e_a.e_f.h
G : Type u_1
inst✝² : Group G
H : Subgroup G
A : Type u_2
inst✝¹ : CommGroup A
ϕ : ↥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 (↥(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 => ↑{ val := g, property := (_ : g ∈ zpowers g) } • x)
                        (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✝

Next tactic:
apply key
theorem transfer_center_eq_pow [FiniteIndex (center G)] (g : G) :
    transfer (MonoidHom.id (center G)) g = ⟨g ^ (center G).index, (center G).pow_index_mem g⟩ :=
  transfer_eq_pow (id (center G)) g fun k _ hk => by 

Proof state:
G : Type u_1
inst✝² : Group G
H : Subgroup G
A : Type u_2
inst✝¹ : CommGroup A
ϕ : ↥H →* A
T : ↑(leftTransversals ↑H)
inst✝ : FiniteIndex (center G)
g : G
k : ℕ
x✝ : G
hk : x✝⁻¹ * g ^ k * x✝ ∈ center G
⊢ x✝⁻¹ * g ^ k * x✝ = g ^ k

Next tactic:
rw [← mul_right_inj, ← hk.comm,
    mul_inv_cancel_right]
/-- The transfer homomorphism `G →* center G`. -/
noncomputable def transferCenterPow [FiniteIndex (center G)] : G →* center G where
  toFun g := ⟨g ^ (center G).index, (center G).pow_index_mem g⟩
  map_one' := Subtype.ext (one_pow (center G).index)
  map_mul' a b := by 

Proof state:
G : Type u_1
inst✝² : Group G
H : Subgroup G
A : Type u_2
inst✝¹ : CommGroup A
ϕ : ↥H →* A
T : ↑(leftTransversals ↑H)
inst✝ : FiniteIndex (center G)
a b : G
⊢ OneHom.toFun
      { toFun := fun g => { val := g ^ index (center G), property := (_ : g ^ index (center G) ∈ center G) },
        map_one' :=
          (_ : (fun g => { val := g ^ index (center G), property := (_ : g ^ index (center G) ∈ center G) }) 1 = 1) }
      (a * b) =
    OneHom.toFun
        { toFun := fun g => { val := g ^ index (center G), property := (_ : g ^ index (center G) ∈ center G) },
          map_one' :=
            (_ : (fun g => { val := g ^ index (center G), property := (_ : g ^ index (center G) ∈ center G) }) 1 = 1) }
        a *
      OneHom.toFun
        { toFun := fun g => { val := g ^ index (center G), property := (_ : g ^ index (center G) ∈ center G) },
          map_one' :=
            (_ : (fun g => { val := g ^ index (center G), property := (_ : g ^ index (center G) ∈ center G) }) 1 = 1) }
        b

Next tactic:
simp_rw [← show ∀ _, (_ : center G) = _ from transfer_center_eq_pow, map_mul]
/-- Auxiliary lemma in order to state `transferSylow_eq_pow`. -/
theorem transferSylow_eq_pow_aux (g : G) (hg : g ∈ P) (k : ℕ) (g₀ : G)
    (h : g₀⁻¹ * g ^ k * g₀ ∈ P) : g₀⁻¹ * g ^ k * g₀ = g ^ k := by
  

Proof state:
G : Type u_1
inst✝³ : Group G
H : Subgroup G
A : Type u_2
inst✝² : CommGroup A
ϕ : ↥H →* A
T : ↑(leftTransversals ↑H)
p : ℕ
P : Sylow p G
hP : normalizer ↑P ≤ centralizer ↑P
inst✝¹ : Fact (Nat.Prime p)
inst✝ : Finite (Sylow p G)
g : G
hg : g ∈ P
k : ℕ
g₀ : G
h : g₀⁻¹ * g ^ k * g₀ ∈ P
⊢ g₀⁻¹ * g ^ k * g₀ = g ^ k

Next tactic:
haveI : (P : Subgroup G).IsCommutative :=
    ⟨⟨fun a b => Subtype.ext (hP (le_normalizer b.2) a a.2)⟩⟩
/-- Auxiliary lemma in order to state `transferSylow_eq_pow`. -/
theorem transferSylow_eq_pow_aux (g : G) (hg : g ∈ P) (k : ℕ) (g₀ : G)
    (h : g₀⁻¹ * g ^ k * g₀ ∈ P) : g₀⁻¹ * g ^ k * g₀ = g ^ k := by
  haveI : (P : Subgroup G).IsCommutative :=
    ⟨⟨fun a b => Subtype.ext (hP (le_normalizer b.2) a a.2)⟩⟩
  

Proof state:
G : Type u_1
inst✝³ : Group G
H : Subgroup G
A : Type u_2
inst✝² : CommGroup A
ϕ : ↥H →* A
T : ↑(leftTransversals ↑H)
p : ℕ
P : Sylow p G
hP : normalizer ↑P ≤ centralizer ↑P
inst✝¹ : Fact (Nat.Prime p)
inst✝ : Finite (Sylow p G)
g : G
hg : g ∈ P
k : ℕ
g₀ : G
h : g₀⁻¹ * g ^ k * g₀ ∈ P
this : Subgroup.IsCommutative ↑P
⊢ g₀⁻¹ * g ^ k * g₀ = g ^ k

Next tactic:
replace hg := (P : Subgroup G).pow_mem hg k
/-- Auxiliary lemma in order to state `transferSylow_eq_pow`. -/
theorem transferSylow_eq_pow_aux (g : G) (hg : g ∈ P) (k : ℕ) (g₀ : G)
    (h : g₀⁻¹ * g ^ k * g₀ ∈ P) : g₀⁻¹ * g ^ k * g₀ = g ^ k := by
  haveI : (P : Subgroup G).IsCommutative :=
    ⟨⟨fun a b => Subtype.ext (hP (le_normalizer b.2) a a.2)⟩⟩
  replace hg := (P : Subgroup G).pow_mem hg k
  

Proof state:
G : Type u_1
inst✝³ : Group G
H : Subgroup G
A : Type u_2
inst✝² : CommGroup A
ϕ : ↥H →* A
T : ↑(leftTransversals ↑H)
p : ℕ
P : Sylow p G
hP : normalizer ↑P ≤ centralizer ↑P
inst✝¹ : Fact (Nat.Prime p)
inst✝ : Finite (Sylow p G)
g : G
k : ℕ
g₀ : G
h : g₀⁻¹ * g ^ k * g₀ ∈ P
this : Subgroup.IsCommutative ↑P
hg : g ^ k ∈ ↑P
⊢ g₀⁻¹ * g ^ k * g₀ = g ^ k

Next tactic:
obtain ⟨n, hn, h⟩ := P.conj_eq_normalizer_conj_of_mem (g ^ k) g₀ hg h
/-- Auxiliary lemma in order to state `transferSylow_eq_pow`. -/
theorem transferSylow_eq_pow_aux (g : G) (hg : g ∈ P) (k : ℕ) (g₀ : G)
    (h : g₀⁻¹ * g ^ k * g₀ ∈ P) : g₀⁻¹ * g ^ k * g₀ = g ^ k := by
  haveI : (P : Subgroup G).IsCommutative :=
    ⟨⟨fun a b => Subtype.ext (hP (le_normalizer b.2) a a.2)⟩⟩
  replace hg := (P : Subgroup G).pow_mem hg k
  obtain ⟨n, hn, h⟩ := P.conj_eq_normalizer_conj_of_mem (g ^ k) g₀ hg h
  

Proof state:
case intro.intro
G : Type u_1
inst✝³ : Group G
H : Subgroup G
A : Type u_2
inst✝² : CommGroup A
ϕ : ↥H →* A
T : ↑(leftTransversals ↑H)
p : ℕ
P : Sylow p G
hP : normalizer ↑P ≤ centralizer ↑P
inst✝¹ : Fact (Nat.Prime p)
inst✝ : Finite (Sylow p G)
g : G
k : ℕ
g₀ : G
h✝ : g₀⁻¹ * g ^ k * g₀ ∈ P
this : Subgroup.IsCommutative ↑P
hg : g ^ k ∈ ↑P
n : G
hn : n ∈ normalizer ↑P
h : g₀⁻¹ * g ^ k * g₀ = n⁻¹ * g ^ k * n
⊢ g₀⁻¹ * g ^ k * g₀ = g ^ k

Next tactic:
exact h.trans (Commute.inv_mul_cancel (hP hn (g ^ k) hg).symm)
/-- **Burnside's normal p-complement theorem**: If `N(P) ≤ C(P)`, then `P` has a normal
complement. -/
theorem ker_transferSylow_isComplement' : IsComplement' (transferSylow P hP).ker P := by
  

Proof state:
G : Type u_1
inst✝⁴ : Group G
H : Subgroup G
A : Type u_2
inst✝³ : CommGroup A
ϕ : ↥H →* A
T : ↑(leftTransversals ↑H)
p : ℕ
P : Sylow p G
hP : normalizer ↑P ≤ centralizer ↑P
inst✝² : Fact (Nat.Prime p)
inst✝¹ : Finite (Sylow p G)
inst✝ : FiniteIndex ↑P
⊢ IsComplement' (ker (transferSylow P hP)) ↑P

Next tactic:
have hf : Function.Bijective ((transferSylow P hP).restrict (P : Subgroup G)) :=
    (transferSylow_restrict_eq_pow P hP).symm ▸
      (P.2.powEquiv'
          (not_dvd_index_sylow P
            (mt index_eq_zero_of_relindex_eq_zero index_ne_zero_of_finite))).bijective
/-- **Burnside's normal p-complement theorem**: If `N(P) ≤ C(P)`, then `P` has a normal
complement. -/
theorem ker_transferSylow_isComplement' : IsComplement' (transferSylow P hP).ker P := by
  have hf : Function.Bijective ((transferSylow P hP).restrict (P : Subgroup G)) :=
    (transferSylow_restrict_eq_pow P hP).symm ▸
      (P.2.powEquiv'
          (not_dvd_index_sylow P
            (mt index_eq_zero_of_relindex_eq_zero index_ne_zero_of_finite))).bijective
  

Proof state:
G : Type u_1
inst✝⁴ : Group G
H : Subgroup G
A : Type u_2
inst✝³ : CommGroup A
ϕ : ↥H →* A
T : ↑(leftTransversals ↑H)
p : ℕ
P : Sylow p G
hP : normalizer ↑P ≤ centralizer ↑P
inst✝² : Fact (Nat.Prime p)
inst✝¹ : Finite (Sylow p G)
inst✝ : FiniteIndex ↑P
hf : Function.Bijective ⇑(restrict (transferSylow P hP) ↑P)
⊢ IsComplement' (ker (transferSylow P hP)) ↑P

Next tactic:
rw [Function.Bijective, ← range_top_iff_surjective, restrict_range] at hf
/-- **Burnside's normal p-complement theorem**: If `N(P) ≤ C(P)`, then `P` has a normal
complement. -/
theorem ker_transferSylow_isComplement' : IsComplement' (transferSylow P hP).ker P := by
  have hf : Function.Bijective ((transferSylow P hP).restrict (P : Subgroup G)) :=
    (transferSylow_restrict_eq_pow P hP).symm ▸
      (P.2.powEquiv'
          (not_dvd_index_sylow P
            (mt index_eq_zero_of_relindex_eq_zero index_ne_zero_of_finite))).bijective
  rw [Function.Bijective, ← range_top_iff_surjective, restrict_range] at hf
  

Proof state:
G : Type u_1
inst✝⁴ : Group G
H : Subgroup G
A : Type u_2
inst✝³ : CommGroup A
ϕ : ↥H →* A
T : ↑(leftTransversals ↑H)
p : ℕ
P : Sylow p G
hP : normalizer ↑P ≤ centralizer ↑P
inst✝² : Fact (Nat.Prime p)
inst✝¹ : Finite (Sylow p G)
inst✝ : FiniteIndex ↑P
hf : Function.Injective ⇑(restrict (transferSylow P hP) ↑P) ∧ map (transferSylow P hP) ↑P = ⊤
⊢ IsComplement' (ker (transferSylow P hP)) ↑P

Next tactic:
have := range_top_iff_surjective.mp (top_le_iff.mp (hf.2.ge.trans
    (map_le_range (transferSylow P hP) P)))
/-- **Burnside's normal p-complement theorem**: If `N(P) ≤ C(P)`, then `P` has a normal
complement. -/
theorem ker_transferSylow_isComplement' : IsComplement' (transferSylow P hP).ker P := by
  have hf : Function.Bijective ((transferSylow P hP).restrict (P : Subgroup G)) :=
    (transferSylow_restrict_eq_pow P hP).symm ▸
      (P.2.powEquiv'
          (not_dvd_index_sylow P
            (mt index_eq_zero_of_relindex_eq_zero index_ne_zero_of_finite))).bijective
  rw [Function.Bijective, ← range_top_iff_surjective, restrict_range] at hf
  have := range_top_iff_surjective.mp (top_le_iff.mp (hf.2.ge.trans
    (map_le_range (transferSylow P hP) P)))
  

Proof state:
G : Type u_1
inst✝⁴ : Group G
H : Subgroup G
A : Type u_2
inst✝³ : CommGroup A
ϕ : ↥H →* A
T : ↑(leftTransversals ↑H)
p : ℕ
P : Sylow p G
hP : normalizer ↑P ≤ centralizer ↑P
inst✝² : Fact (Nat.Prime p)
inst✝¹ : Finite (Sylow p G)
inst✝ : FiniteIndex ↑P
hf : Function.Injective ⇑(restrict (transferSylow P hP) ↑P) ∧ map (transferSylow P hP) ↑P = ⊤
this : Function.Surjective ⇑(transferSylow P hP)
⊢ IsComplement' (ker (transferSylow P hP)) ↑P

Next tactic:
rw [← (comap_injective this).eq_iff, comap_top, comap_map_eq, sup_comm, SetLike.ext'_iff,
    normal_mul, ← ker_eq_bot_iff, ← (map_injective (P : Subgroup G).subtype_injective).eq_iff,
    ker_restrict, subgroupOf_map_subtype, Subgroup.map_bot, coe_top] at hf
/-- **Burnside's normal p-complement theorem**: If `N(P) ≤ C(P)`, then `P` has a normal
complement. -/
theorem ker_transferSylow_isComplement' : IsComplement' (transferSylow P hP).ker P := by
  have hf : Function.Bijective ((transferSylow P hP).restrict (P : Subgroup G)) :=
    (transferSylow_restrict_eq_pow P hP).symm ▸
      (P.2.powEquiv'
          (not_dvd_index_sylow P
            (mt index_eq_zero_of_relindex_eq_zero index_ne_zero_of_finite))).bijective
  rw [Function.Bijective, ← range_top_iff_surjective, restrict_range] at hf
  have := range_top_iff_surjective.mp (top_le_iff.mp (hf.2.ge.trans
    (map_le_range (transferSylow P hP) P)))
  rw [← (comap_injective this).eq_iff, comap_top, comap_map_eq, sup_comm, SetLike.ext'_iff,
    normal_mul, ← ker_eq_bot_iff, ← (map_injective (P : Subgroup G).subtype_injective).eq_iff,
    ker_restrict, subgroupOf_map_subtype, Subgroup.map_bot, coe_top] at hf
  

Proof state:
G : Type u_1
inst✝⁴ : Group G
H : Subgroup G
A : Type u_2
inst✝³ : CommGroup A
ϕ : ↥H →* A
T : ↑(leftTransversals ↑H)
p : ℕ
P : Sylow p G
hP : normalizer ↑P ≤ centralizer ↑P
inst✝² : Fact (Nat.Prime p)
inst✝¹ : Finite (Sylow p G)
inst✝ : FiniteIndex ↑P
hf : ker (transferSylow P hP) ⊓ ↑P = ⊥ ∧ ↑(ker (transferSylow P hP)) * ↑↑P = Set.univ
this : Function.Surjective ⇑(transferSylow P hP)
⊢ IsComplement' (ker (transferSylow P hP)) ↑P

Next tactic:
exact isComplement'_of_disjoint_and_mul_eq_univ (disjoint_iff.2 hf.1) hf.2
theorem map_eq_C_mul_X_pow_of_forall_coeff_mem {f : R[X]} {P : Ideal R}
    (hfP : ∀ n : ℕ, ↑n < f.degree → f.coeff n ∈ P) :
    map (mk P) f = C ((mk P) f.leadingCoeff) * X ^ f.natDegree :=
  Polynomial.ext fun n => by
    

Proof state:
R : Type u_1
inst✝ : CommRing R
f : R[X]
P : Ideal R
hfP : ∀ (n : ℕ), ↑n < degree f → coeff f n ∈ P
n : ℕ
⊢ coeff (map (mk P) f) n = coeff (C ((mk P) (leadingCoeff f)) * X ^ natDegree f) n

Next tactic:
by_cases hf0 : f = 0
theorem map_eq_C_mul_X_pow_of_forall_coeff_mem {f : R[X]} {P : Ideal R}
    (hfP : ∀ n : ℕ, ↑n < f.degree → f.coeff n ∈ P) :
    map (mk P) f = C ((mk P) f.leadingCoeff) * X ^ f.natDegree :=
  Polynomial.ext fun n => by
    by_cases hf0 : f = 0
    · 

Proof state:
case pos
R : Type u_1
inst✝ : CommRing R
f : R[X]
P : Ideal R
hfP : ∀ (n : ℕ), ↑n < degree f → coeff f n ∈ P
n : ℕ
hf0 : f = 0
⊢ coeff (map (mk P) f) n = coeff (C ((mk P) (leadingCoeff f)) * X ^ natDegree f) n

Next tactic:
simp [hf0]
theorem map_eq_C_mul_X_pow_of_forall_coeff_mem {f : R[X]} {P : Ideal R}
    (hfP : ∀ n : ℕ, ↑n < f.degree → f.coeff n ∈ P) :
    map (mk P) f = C ((mk P) f.leadingCoeff) * X ^ f.natDegree :=
  Polynomial.ext fun n => by
    by_cases hf0 : f = 0
    · simp [hf0]
    

Proof state:
case neg
R : Type u_1
inst✝ : CommRing R
f : R[X]
P : Ideal R
hfP : ∀ (n : ℕ), ↑n < degree f → coeff f n ∈ P
n : ℕ
hf0 : ¬f = 0
⊢ coeff (map (mk P) f) n = coeff (C ((mk P) (leadingCoeff f)) * X ^ natDegree f) n

Next tactic:
rcases lt_trichotomy (n : WithBot ℕ) (degree f) with (h | h | h)
theorem map_eq_C_mul_X_pow_of_forall_coeff_mem {f : R[X]} {P : Ideal R}
    (hfP : ∀ n : ℕ, ↑n < f.degree → f.coeff n ∈ P) :
    map (mk P) f = C ((mk P) f.leadingCoeff) * X ^ f.natDegree :=
  Polynomial.ext fun n => by
    by_cases hf0 : f = 0
    · simp [hf0]
    rcases lt_trichotomy (n : WithBot ℕ) (degree f) with (h | h | h)
    · 

Proof state:
case neg.inl
R : Type u_1
inst✝ : CommRing R
f : R[X]
P : Ideal R
hfP : ∀ (n : ℕ), ↑n < degree f → coeff f n ∈ P
n : ℕ
hf0 : ¬f = 0
h : ↑n < degree f
⊢ coeff (map (mk P) f) n = coeff (C ((mk P) (leadingCoeff f)) * X ^ natDegree f) n

Next tactic:
erw [coeff_map, eq_zero_iff_mem.2 (hfP n h), coeff_C_mul, coeff_X_pow, if_neg,
        mul_zero]
theorem map_eq_C_mul_X_pow_of_forall_coeff_mem {f : R[X]} {P : Ideal R}
    (hfP : ∀ n : ℕ, ↑n < f.degree → f.coeff n ∈ P) :
    map (mk P) f = C ((mk P) f.leadingCoeff) * X ^ f.natDegree :=
  Polynomial.ext fun n => by
    by_cases hf0 : f = 0
    · simp [hf0]
    rcases lt_trichotomy (n : WithBot ℕ) (degree f) with (h | h | h)
    · erw [coeff_map, eq_zero_iff_mem.2 (hfP n h), coeff_C_mul, coeff_X_pow, if_neg,
        mul_zero]
      

Proof state:
case neg.inl.hnc
R : Type u_1
inst✝ : CommRing R
f : R[X]
P : Ideal R
hfP : ∀ (n : ℕ), ↑n < degree f → coeff f n ∈ P
n : ℕ
hf0 : ¬f = 0
h : ↑n < degree f
⊢ ¬n = natDegree f

Next tactic:
rintro rfl
theorem map_eq_C_mul_X_pow_of_forall_coeff_mem {f : R[X]} {P : Ideal R}
    (hfP : ∀ n : ℕ, ↑n < f.degree → f.coeff n ∈ P) :
    map (mk P) f = C ((mk P) f.leadingCoeff) * X ^ f.natDegree :=
  Polynomial.ext fun n => by
    by_cases hf0 : f = 0
    · simp [hf0]
    rcases lt_trichotomy (n : WithBot ℕ) (degree f) with (h | h | h)
    · erw [coeff_map, eq_zero_iff_mem.2 (hfP n h), coeff_C_mul, coeff_X_pow, if_neg,
        mul_zero]
      rintro rfl
      

Proof state:
case neg.inl.hnc
R : Type u_1
inst✝ : CommRing R
f : R[X]
P : Ideal R
hfP : ∀ (n : ℕ), ↑n < degree f → coeff f n ∈ P
hf0 : ¬f = 0
h : ↑(natDegree f) < degree f
⊢ False

Next tactic:
exact not_lt_of_ge degree_le_natDegree h
theorem map_eq_C_mul_X_pow_of_forall_coeff_mem {f : R[X]} {P : Ideal R}
    (hfP : ∀ n : ℕ, ↑n < f.degree → f.coeff n ∈ P) :
    map (mk P) f = C ((mk P) f.leadingCoeff) * X ^ f.natDegree :=
  Polynomial.ext fun n => by
    by_cases hf0 : f = 0
    · simp [hf0]
    rcases lt_trichotomy (n : WithBot ℕ) (degree f) with (h | h | h)
    · erw [coeff_map, eq_zero_iff_mem.2 (hfP n h), coeff_C_mul, coeff_X_pow, if_neg,
        mul_zero]
      rintro rfl
      exact not_lt_of_ge degree_le_natDegree h
    · 

Proof state:
case neg.inr.inl
R : Type u_1
inst✝ : CommRing R
f : R[X]
P : Ideal R
hfP : ∀ (n : ℕ), ↑n < degree f → coeff f n ∈ P
n : ℕ
hf0 : ¬f = 0
h : ↑n = degree f
⊢ coeff (map (mk P) f) n = coeff (C ((mk P) (leadingCoeff f)) * X ^ natDegree f) n

Next tactic:
have : natDegree f = n := natDegree_eq_of_degree_eq_some h.symm