l3lab/ntp-mathlib huggingface dataset:
/-- Post-composition by a *fixed* continuous linear map as a continuous linear map.
Note that in non-normed space it is not always true that composition is continuous
in both variables, so we have to fix one of them. -/
@[simps]
def postcomp [TopologicalAddGroup F] [TopologicalAddGroup G] [ContinuousConstSMul 𝕜₃ G]
    [ContinuousConstSMul 𝕜₂ F] (L : F →SL[τ] G) : (E →SL[σ] F) →SL[τ] E →SL[ρ] G
    where
  toFun f := L.comp f
  map_add' := comp_add L
  map_smul' := comp_smulₛₗ L
  cont := by
    letI : UniformSpace G := TopologicalAddGroup.toUniformSpace G
    haveI : UniformAddGroup G := comm_topologicalAddGroup_is_uniform
    letI : UniformSpace F := TopologicalAddGroup.toUniformSpace F
    haveI : UniformAddGroup F := comm_topologicalAddGroup_is_uniform
    rw [(strongTopology.embedding_coeFn _ _ _).continuous_iff]
    

Proof state:
𝕜₁ : Type u_1
𝕜₂ : Type u_2
𝕜₃ : Type u_3
inst✝²⁰ : NormedField 𝕜₁
inst✝¹⁹ : NormedField 𝕜₂
inst✝¹⁸ : NormedField 𝕜₃
σ : 𝕜₁ →+* 𝕜₂
τ : 𝕜₂ →+* 𝕜₃
ρ : 𝕜₁ →+* 𝕜₃
inst✝¹⁷ : RingHomCompTriple σ τ ρ
E : Type u_4
E' : Type u_5
F : Type u_6
F' : Type u_7
G : Type u_8
inst✝¹⁶ : AddCommGroup E
inst✝¹⁵ : Module 𝕜₁ E
inst✝¹⁴ : AddCommGroup E'
inst✝¹³ : Module ℝ E'
inst✝¹² : AddCommGroup F
inst✝¹¹ : Module 𝕜₂ F
inst✝¹⁰ : AddCommGroup F'
inst✝⁹ : Module ℝ F'
inst✝⁸ : AddCommGroup G
inst✝⁷ : Module 𝕜₃ G
inst✝⁶ : TopologicalSpace E
inst✝⁵ : TopologicalSpace F
inst✝⁴ : TopologicalSpace G
inst✝³ : TopologicalAddGroup F
inst✝² : TopologicalAddGroup G
inst✝¹ : ContinuousConstSMul 𝕜₃ G
inst✝ : ContinuousConstSMul 𝕜₂ F
L : F →SL[τ] G
this✝² : UniformSpace G := TopologicalAddGroup.toUniformSpace G
this✝¹ : UniformAddGroup G
this✝ : UniformSpace F := TopologicalAddGroup.toUniformSpace F
this : UniformAddGroup F
⊢ Continuous
    ((⇑(UniformOnFun.ofFun {S | Bornology.IsVonNBounded 𝕜₁ S}) ∘ FunLike.coe) ∘
      {
            toAddHom :=
              { toFun := fun f => comp L f,
                map_add' := (_ : ∀ (f₁ f₂ : E →SL[σ] F), comp L (f₁ + f₂) = comp L f₁ + comp L f₂) },
            map_smul' := (_ : ∀ (c : 𝕜₂) (f : E →SL[σ] F), comp L (c • f) = τ c • comp L f) }.toAddHom.toFun)

Next tactic:
exact
      (UniformOnFun.postcomp_uniformContinuous L.uniformContinuous).continuous.comp
        (strongTopology.embedding_coeFn _ _ _).continuous
/-- A pair of continuous (semi)linear equivalences generates a (semi)linear equivalence between the
spaces of continuous (semi)linear maps. -/
@[simps]
def arrowCongrSL (e₁₂ : E ≃SL[σ₁₂] F) (e₄₃ : H ≃SL[σ₄₃] G) :
    (E →SL[σ₁₄] H) ≃SL[σ₄₃] F →SL[σ₂₃] G :=
{ e₁₂.arrowCongrEquiv e₄₃ with
    -- given explicitly to help `simps`
    toFun := fun L => (e₄₃ : H →SL[σ₄₃] G).comp (L.comp (e₁₂.symm : F →SL[σ₂₁] E))
    -- given explicitly to help `simps`
    invFun := fun L => (e₄₃.symm : G →SL[σ₃₄] H).comp (L.comp (e₁₂ : E →SL[σ₁₂] F))
    map_add' := fun f g => by 

Proof state:
𝕜 : Type u_1
𝕜₂ : Type u_2
𝕜₃ : Type u_3
𝕜₄ : Type u_4
E : Type u_5
F : Type u_6
G : Type u_7
H : Type u_8
inst✝³¹ : AddCommGroup E
inst✝³⁰ : AddCommGroup F
inst✝²⁹ : AddCommGroup G
inst✝²⁸ : AddCommGroup H
inst✝²⁷ : NontriviallyNormedField 𝕜
inst✝²⁶ : NontriviallyNormedField 𝕜₂
inst✝²⁵ : NontriviallyNormedField 𝕜₃
inst✝²⁴ : NontriviallyNormedField 𝕜₄
inst✝²³ : Module 𝕜 E
inst✝²² : Module 𝕜₂ F
inst✝²¹ : Module 𝕜₃ G
inst✝²⁰ : Module 𝕜₄ H
inst✝¹⁹ : TopologicalSpace E
inst✝¹⁸ : TopologicalSpace F
inst✝¹⁷ : TopologicalSpace G
inst✝¹⁶ : TopologicalSpace H
inst✝¹⁵ : TopologicalAddGroup G
inst✝¹⁴ : TopologicalAddGroup H
inst✝¹³ : ContinuousConstSMul 𝕜₃ G
inst✝¹² : ContinuousConstSMul 𝕜₄ H
σ₁₂ : 𝕜 →+* 𝕜₂
σ₂₁ : 𝕜₂ →+* 𝕜
σ₂₃ : 𝕜₂ →+* 𝕜₃
σ₁₃ : 𝕜 →+* 𝕜₃
σ₃₄ : 𝕜₃ →+* 𝕜₄
σ₄₃ : 𝕜₄ →+* 𝕜₃
σ₂₄ : 𝕜₂ →+* 𝕜₄
σ₁₄ : 𝕜 →+* 𝕜₄
inst✝¹¹ : RingHomInvPair σ₁₂ σ₂₁
inst✝¹⁰ : RingHomInvPair σ₂₁ σ₁₂
inst✝⁹ : RingHomInvPair σ₃₄ σ₄₃
inst✝⁸ : RingHomInvPair σ₄₃ σ₃₄
inst✝⁷ : RingHomCompTriple σ₂₁ σ₁₄ σ₂₄
inst✝⁶ : RingHomCompTriple σ₂₄ σ₄₃ σ₂₃
inst✝⁵ : RingHomCompTriple σ₁₂ σ₂₃ σ₁₃
inst✝⁴ : RingHomCompTriple σ₁₃ σ₃₄ σ₁₄
inst✝³ : RingHomCompTriple σ₂₃ σ₃₄ σ₂₄
inst✝² : RingHomCompTriple σ₁₂ σ₂₄ σ₁₄
inst✝¹ : RingHomIsometric σ₁₂
inst✝ : RingHomIsometric σ₂₁
e₁₂ : E ≃SL[σ₁₂] F
e₄₃ : H ≃SL[σ₄₃] G
src✝ : (E →SL[σ₁₄] H) ≃ (F →SL[σ₂₃] G) := arrowCongrEquiv e₁₂ e₄₃
f g : E →SL[σ₁₄] H
⊢ (fun L => comp (↑e₄₃) (comp L ↑(ContinuousLinearEquiv.symm e₁₂))) (f + g) =
    (fun L => comp (↑e₄₃) (comp L ↑(ContinuousLinearEquiv.symm e₁₂))) f +
      (fun L => comp (↑e₄₃) (comp L ↑(ContinuousLinearEquiv.symm e₁₂))) g

Next tactic:
simp only [add_comp, comp_add]
/-- A pair of continuous (semi)linear equivalences generates a (semi)linear equivalence between the
spaces of continuous (semi)linear maps. -/
@[simps]
def arrowCongrSL (e₁₂ : E ≃SL[σ₁₂] F) (e₄₃ : H ≃SL[σ₄₃] G) :
    (E →SL[σ₁₄] H) ≃SL[σ₄₃] F →SL[σ₂₃] G :=
{ e₁₂.arrowCongrEquiv e₄₃ with
    -- given explicitly to help `simps`
    toFun := fun L => (e₄₃ : H →SL[σ₄₃] G).comp (L.comp (e₁₂.symm : F →SL[σ₂₁] E))
    -- given explicitly to help `simps`
    invFun := fun L => (e₄₃.symm : G →SL[σ₃₄] H).comp (L.comp (e₁₂ : E →SL[σ₁₂] F))
    map_add' := fun f g => by simp only [add_comp, comp_add]
    map_smul' := fun t f => by 

Proof state:
𝕜 : Type u_1
𝕜₂ : Type u_2
𝕜₃ : Type u_3
𝕜₄ : Type u_4
E : Type u_5
F : Type u_6
G : Type u_7
H : Type u_8
inst✝³¹ : AddCommGroup E
inst✝³⁰ : AddCommGroup F
inst✝²⁹ : AddCommGroup G
inst✝²⁸ : AddCommGroup H
inst✝²⁷ : NontriviallyNormedField 𝕜
inst✝²⁶ : NontriviallyNormedField 𝕜₂
inst✝²⁵ : NontriviallyNormedField 𝕜₃
inst✝²⁴ : NontriviallyNormedField 𝕜₄
inst✝²³ : Module 𝕜 E
inst✝²² : Module 𝕜₂ F
inst✝²¹ : Module 𝕜₃ G
inst✝²⁰ : Module 𝕜₄ H
inst✝¹⁹ : TopologicalSpace E
inst✝¹⁸ : TopologicalSpace F
inst✝¹⁷ : TopologicalSpace G
inst✝¹⁶ : TopologicalSpace H
inst✝¹⁵ : TopologicalAddGroup G
inst✝¹⁴ : TopologicalAddGroup H
inst✝¹³ : ContinuousConstSMul 𝕜₃ G
inst✝¹² : ContinuousConstSMul 𝕜₄ H
σ₁₂ : 𝕜 →+* 𝕜₂
σ₂₁ : 𝕜₂ →+* 𝕜
σ₂₃ : 𝕜₂ →+* 𝕜₃
σ₁₃ : 𝕜 →+* 𝕜₃
σ₃₄ : 𝕜₃ →+* 𝕜₄
σ₄₃ : 𝕜₄ →+* 𝕜₃
σ₂₄ : 𝕜₂ →+* 𝕜₄
σ₁₄ : 𝕜 →+* 𝕜₄
inst✝¹¹ : RingHomInvPair σ₁₂ σ₂₁
inst✝¹⁰ : RingHomInvPair σ₂₁ σ₁₂
inst✝⁹ : RingHomInvPair σ₃₄ σ₄₃
inst✝⁸ : RingHomInvPair σ₄₃ σ₃₄
inst✝⁷ : RingHomCompTriple σ₂₁ σ₁₄ σ₂₄
inst✝⁶ : RingHomCompTriple σ₂₄ σ₄₃ σ₂₃
inst✝⁵ : RingHomCompTriple σ₁₂ σ₂₃ σ₁₃
inst✝⁴ : RingHomCompTriple σ₁₃ σ₃₄ σ₁₄
inst✝³ : RingHomCompTriple σ₂₃ σ₃₄ σ₂₄
inst✝² : RingHomCompTriple σ₁₂ σ₂₄ σ₁₄
inst✝¹ : RingHomIsometric σ₁₂
inst✝ : RingHomIsometric σ₂₁
e₁₂ : E ≃SL[σ₁₂] F
e₄₃ : H ≃SL[σ₄₃] G
src✝ : (E →SL[σ₁₄] H) ≃ (F →SL[σ₂₃] G) := arrowCongrEquiv e₁₂ e₄₃
t : 𝕜₄
f : E →SL[σ₁₄] H
⊢ AddHom.toFun
      { toFun := fun L => comp (↑e₄₃) (comp L ↑(ContinuousLinearEquiv.symm e₁₂)),
        map_add' :=
          (_ :
            ∀ (f g : E →SL[σ₁₄] H),
              comp (↑e₄₃) (comp (f + g) ↑(ContinuousLinearEquiv.symm e₁₂)) =
                comp (↑e₄₃) (comp f ↑(ContinuousLinearEquiv.symm e₁₂)) +
                  comp (↑e₄₃) (comp g ↑(ContinuousLinearEquiv.symm e₁₂))) }
      (t • f) =
    σ₄₃ t •
      AddHom.toFun
        { toFun := fun L => comp (↑e₄₃) (comp L ↑(ContinuousLinearEquiv.symm e₁₂)),
          map_add' :=
            (_ :
              ∀ (f g : E →SL[σ₁₄] H),
                comp (↑e₄₃) (comp (f + g) ↑(ContinuousLinearEquiv.symm e₁₂)) =
                  comp (↑e₄₃) (comp f ↑(ContinuousLinearEquiv.symm e₁₂)) +
                    comp (↑e₄₃) (comp g ↑(ContinuousLinearEquiv.symm e₁₂))) }
        f

Next tactic:
simp only [smul_comp, comp_smulₛₗ]
/-- If `H` is a normal subgroup of `G`, then the set `{x : G | ∀ y : G, x*y*x⁻¹*y⁻¹ ∈ H}`
is a subgroup of `G` (because it is the preimage in `G` of the centre of the
quotient group `G/H`.)
-/
def upperCentralSeriesStep : Subgroup G where
  carrier := { x : G | ∀ y : G, x * y * x⁻¹ * y⁻¹ ∈ H }
  one_mem' y := by simp [Subgroup.one_mem]
  mul_mem' {a b ha hb y} := by
    

Proof state:
G : Type u_1
inst✝¹ : Group G
H : Subgroup G
inst✝ : Normal H
a b : G
ha : a ∈ {x | ∀ (y : G), x * y * x⁻¹ * y⁻¹ ∈ H}
hb : b ∈ {x | ∀ (y : G), x * y * x⁻¹ * y⁻¹ ∈ H}
y : G
⊢ a * b * y * (a * b)⁻¹ * y⁻¹ ∈ H

Next tactic:
convert Subgroup.mul_mem _ (ha (b * y * b⁻¹)) (hb y) using 1
/-- If `H` is a normal subgroup of `G`, then the set `{x : G | ∀ y : G, x*y*x⁻¹*y⁻¹ ∈ H}`
is a subgroup of `G` (because it is the preimage in `G` of the centre of the
quotient group `G/H`.)
-/
def upperCentralSeriesStep : Subgroup G where
  carrier := { x : G | ∀ y : G, x * y * x⁻¹ * y⁻¹ ∈ H }
  one_mem' y := by simp [Subgroup.one_mem]
  mul_mem' {a b ha hb y} := by
    convert Subgroup.mul_mem _ (ha (b * y * b⁻¹)) (hb y) using 1
    

Proof state:
case h.e'_4
G : Type u_1
inst✝¹ : Group G
H : Subgroup G
inst✝ : Normal H
a b : G
ha : a ∈ {x | ∀ (y : G), x * y * x⁻¹ * y⁻¹ ∈ H}
hb : b ∈ {x | ∀ (y : G), x * y * x⁻¹ * y⁻¹ ∈ H}
y : G
⊢ a * b * y * (a * b)⁻¹ * y⁻¹ = a * (b * y * b⁻¹) * a⁻¹ * (b * y * b⁻¹)⁻¹ * (b * y * b⁻¹ * y⁻¹)

Next tactic:
group
/-- If `H` is a normal subgroup of `G`, then the set `{x : G | ∀ y : G, x*y*x⁻¹*y⁻¹ ∈ H}`
is a subgroup of `G` (because it is the preimage in `G` of the centre of the
quotient group `G/H`.)
-/
def upperCentralSeriesStep : Subgroup G where
  carrier := { x : G | ∀ y : G, x * y * x⁻¹ * y⁻¹ ∈ H }
  one_mem' y := by 

Proof state:
G : Type u_1
inst✝¹ : Group G
H : Subgroup G
inst✝ : Normal H
y : G
⊢ 1 * y * 1⁻¹ * y⁻¹ ∈ H

Next tactic:
simp [Subgroup.one_mem]
/-- If `H` is a normal subgroup of `G`, then the set `{x : G | ∀ y : G, x*y*x⁻¹*y⁻¹ ∈ H}`
is a subgroup of `G` (because it is the preimage in `G` of the centre of the
quotient group `G/H`.)
-/
def upperCentralSeriesStep : Subgroup G where
  carrier := { x : G | ∀ y : G, x * y * x⁻¹ * y⁻¹ ∈ H }
  one_mem' y := by simp [Subgroup.one_mem]
  mul_mem' {a b ha hb y} := by
    convert Subgroup.mul_mem _ (ha (b * y * b⁻¹)) (hb y) using 1
    group
  inv_mem' {x hx y} := by
    

Proof state:
G : Type u_1
inst✝¹ : Group G
H : Subgroup G
inst✝ : Normal H
x : G
hx :
  x ∈
    {
          toSubsemigroup :=
            { carrier := {x | ∀ (y : G), x * y * x⁻¹ * y⁻¹ ∈ H},
              mul_mem' :=
                (_ :
                  ∀ {a b : G} {ha : a ∈ {x | ∀ (y : G), x * y * x⁻¹ * y⁻¹ ∈ H}}
                    {hb : b ∈ {x | ∀ (y : G), x * y * x⁻¹ * y⁻¹ ∈ H}} {y : G}, a * b * y * (a * b)⁻¹ * y⁻¹ ∈ H) },
          one_mem' := (_ : ∀ (y : G), 1 * y * 1⁻¹ * y⁻¹ ∈ H) }.toSubsemigroup.carrier
y : G
⊢ x⁻¹ * y * x⁻¹⁻¹ * y⁻¹ ∈ H

Next tactic:
specialize hx y⁻¹
/-- If `H` is a normal subgroup of `G`, then the set `{x : G | ∀ y : G, x*y*x⁻¹*y⁻¹ ∈ H}`
is a subgroup of `G` (because it is the preimage in `G` of the centre of the
quotient group `G/H`.)
-/
def upperCentralSeriesStep : Subgroup G where
  carrier := { x : G | ∀ y : G, x * y * x⁻¹ * y⁻¹ ∈ H }
  one_mem' y := by simp [Subgroup.one_mem]
  mul_mem' {a b ha hb y} := by
    convert Subgroup.mul_mem _ (ha (b * y * b⁻¹)) (hb y) using 1
    group
  inv_mem' {x hx y} := by
    specialize hx y⁻¹
    

Proof state:
G : Type u_1
inst✝¹ : Group G
H : Subgroup G
inst✝ : Normal H
x y : G
hx : x * y⁻¹ * x⁻¹ * y⁻¹⁻¹ ∈ H
⊢ x⁻¹ * y * x⁻¹⁻¹ * y⁻¹ ∈ H

Next tactic:
rw [mul_assoc, inv_inv] at hx ⊢
/-- If `H` is a normal subgroup of `G`, then the set `{x : G | ∀ y : G, x*y*x⁻¹*y⁻¹ ∈ H}`
is a subgroup of `G` (because it is the preimage in `G` of the centre of the
quotient group `G/H`.)
-/
def upperCentralSeriesStep : Subgroup G where
  carrier := { x : G | ∀ y : G, x * y * x⁻¹ * y⁻¹ ∈ H }
  one_mem' y := by simp [Subgroup.one_mem]
  mul_mem' {a b ha hb y} := by
    convert Subgroup.mul_mem _ (ha (b * y * b⁻¹)) (hb y) using 1
    group
  inv_mem' {x hx y} := by
    specialize hx y⁻¹
    rw [mul_assoc, inv_inv] at hx ⊢
    

Proof state:
G : Type u_1
inst✝¹ : Group G
H : Subgroup G
inst✝ : Normal H
x y : G
hx : x * y⁻¹ * (x⁻¹ * y) ∈ H
⊢ x⁻¹ * y * (x * y⁻¹) ∈ H

Next tactic:
exact Subgroup.Normal.mem_comm inferInstance hx
/-- The proof that `upperCentralSeriesStep H` is the preimage of the centre of `G/H` under
the canonical surjection. -/
theorem upperCentralSeriesStep_eq_comap_center :
    upperCentralSeriesStep H = Subgroup.comap (mk' H) (center (G ⧸ H)) := by
  

Proof state:
G : Type u_1
inst✝¹ : Group G
H : Subgroup G
inst✝ : Normal H
⊢ upperCentralSeriesStep H = comap (mk' H) (center (G ⧸ H))

Next tactic:
ext
/-- The proof that `upperCentralSeriesStep H` is the preimage of the centre of `G/H` under
the canonical surjection. -/
theorem upperCentralSeriesStep_eq_comap_center :
    upperCentralSeriesStep H = Subgroup.comap (mk' H) (center (G ⧸ H)) := by
  ext
  

Proof state:
case h
G : Type u_1
inst✝¹ : Group G
H : Subgroup G
inst✝ : Normal H
x✝ : G
⊢ x✝ ∈ upperCentralSeriesStep H ↔ x✝ ∈ comap (mk' H) (center (G ⧸ H))

Next tactic:
rw [mem_comap, mem_center_iff, forall_mk]
/-- The proof that `upperCentralSeriesStep H` is the preimage of the centre of `G/H` under
the canonical surjection. -/
theorem upperCentralSeriesStep_eq_comap_center :
    upperCentralSeriesStep H = Subgroup.comap (mk' H) (center (G ⧸ H)) := by
  ext
  rw [mem_comap, mem_center_iff, forall_mk]
  

Proof state:
case h
G : Type u_1
inst✝¹ : Group G
H : Subgroup G
inst✝ : Normal H
x✝ : G
⊢ x✝ ∈ upperCentralSeriesStep H ↔ ∀ (x : G), ↑x * (mk' H) x✝ = (mk' H) x✝ * ↑x

Next tactic:
apply forall_congr'
/-- The proof that `upperCentralSeriesStep H` is the preimage of the centre of `G/H` under
the canonical surjection. -/
theorem upperCentralSeriesStep_eq_comap_center :
    upperCentralSeriesStep H = Subgroup.comap (mk' H) (center (G ⧸ H)) := by
  ext
  rw [mem_comap, mem_center_iff, forall_mk]
  apply forall_congr'
  

Proof state:
case h.h
G : Type u_1
inst✝¹ : Group G
H : Subgroup G
inst✝ : Normal H
x✝ : G
⊢ ∀ (a : G), x✝ * a * x✝⁻¹ * a⁻¹ ∈ H ↔ ↑a * (mk' H) x✝ = (mk' H) x✝ * ↑a

Next tactic:
intro y
/-- The proof that `upperCentralSeriesStep H` is the preimage of the centre of `G/H` under
the canonical surjection. -/
theorem upperCentralSeriesStep_eq_comap_center :
    upperCentralSeriesStep H = Subgroup.comap (mk' H) (center (G ⧸ H)) := by
  ext
  rw [mem_comap, mem_center_iff, forall_mk]
  apply forall_congr'
  intro y
  

Proof state:
case h.h
G : Type u_1
inst✝¹ : Group G
H : Subgroup G
inst✝ : Normal H
x✝ y : G
⊢ x✝ * y * x✝⁻¹ * y⁻¹ ∈ H ↔ ↑y * (mk' H) x✝ = (mk' H) x✝ * ↑y

Next tactic:
rw [coe_mk', ← QuotientGroup.mk_mul, ← QuotientGroup.mk_mul, eq_comm, eq_iff_div_mem,
    div_eq_mul_inv, mul_inv_rev, mul_assoc]
instance : Normal (upperCentralSeriesStep H) := by
  

Proof state:
G : Type u_1
inst✝¹ : Group G
H : Subgroup G
inst✝ : Normal H
⊢ Normal (upperCentralSeriesStep H)

Next tactic:
rw [upperCentralSeriesStep_eq_comap_center]
instance : Normal (upperCentralSeriesStep H) := by
  rw [upperCentralSeriesStep_eq_comap_center]
  

Proof state:
G : Type u_1
inst✝¹ : Group G
H : Subgroup G
inst✝ : Normal H
⊢ Normal (comap (mk' H) (center (G ⧸ H)))

Next tactic:
infer_instance
@[simp]
theorem upperCentralSeries_one : upperCentralSeries G 1 = center G := by
  

Proof state:
G : Type u_1
inst✝¹ : Group G
H : Subgroup G
inst✝ : Normal H
⊢ upperCentralSeries G 1 = center G

Next tactic:
ext
@[simp]
theorem upperCentralSeries_one : upperCentralSeries G 1 = center G := by
  ext
  

Proof state:
case h
G : Type u_1
inst✝¹ : Group G
H : Subgroup G
inst✝ : Normal H
x✝ : G
⊢ x✝ ∈ upperCentralSeries G 1 ↔ x✝ ∈ center G

Next tactic:
simp only [upperCentralSeries, upperCentralSeriesAux, upperCentralSeriesStep,
    Subgroup.mem_center_iff, mem_mk, mem_bot, Set.mem_setOf_eq]
@[simp]
theorem upperCentralSeries_one : upperCentralSeries G 1 = center G := by
  ext
  simp only [upperCentralSeries, upperCentralSeriesAux, upperCentralSeriesStep,
    Subgroup.mem_center_iff, mem_mk, mem_bot, Set.mem_setOf_eq]
  

Proof state:
case h
G : Type u_1
inst✝¹ : Group G
H : Subgroup G
inst✝ : Normal H
x✝ : G
⊢ (∀ (y : G), x✝ * y * x✝⁻¹ * y⁻¹ = 1) ↔ ∀ (g : G), g * x✝ = x✝ * g

Next tactic:
exact forall_congr' fun y => by rw [mul_inv_eq_one, mul_inv_eq_iff_eq_mul, eq_comm]
@[simp]
theorem upperCentralSeries_one : upperCentralSeries G 1 = center G := by
  ext
  simp only [upperCentralSeries, upperCentralSeriesAux, upperCentralSeriesStep,
    Subgroup.mem_center_iff, mem_mk, mem_bot, Set.mem_setOf_eq]
  exact forall_congr' fun y => by 

Proof state:
G : Type u_1
inst✝¹ : Group G
H : Subgroup G
inst✝ : Normal H
x✝ y : G
⊢ x✝ * y * x✝⁻¹ * y⁻¹ = 1 ↔ y * x✝ = x✝ * y

Next tactic:
rw [mul_inv_eq_one, mul_inv_eq_iff_eq_mul, eq_comm]
/-- Any ascending central series for a group is bounded above by the upper central series. -/
theorem ascending_central_series_le_upper (H : ℕ → Subgroup G) (hH : IsAscendingCentralSeries H) :
    ∀ n : ℕ, H n ≤ upperCentralSeries G n
  | 0 => hH.1.symm ▸ le_refl ⊥
  | n + 1 => by
    

Proof state:
G : Type u_1
inst✝¹ : Group G
H✝ : Subgroup G
inst✝ : Normal H✝
H : ℕ → Subgroup G
hH : IsAscendingCentralSeries H
n : ℕ
⊢ H (n + 1) ≤ upperCentralSeries G (n + 1)

Next tactic:
intro x hx
/-- Any ascending central series for a group is bounded above by the upper central series. -/
theorem ascending_central_series_le_upper (H : ℕ → Subgroup G) (hH : IsAscendingCentralSeries H) :
    ∀ n : ℕ, H n ≤ upperCentralSeries G n
  | 0 => hH.1.symm ▸ le_refl ⊥
  | n + 1 => by
    intro x hx
    

Proof state:
G : Type u_1
inst✝¹ : Group G
H✝ : Subgroup G
inst✝ : Normal H✝
H : ℕ → Subgroup G
hH : IsAscendingCentralSeries H
n : ℕ
x : G
hx : x ∈ H (n + 1)
⊢ x ∈ upperCentralSeries G (n + 1)

Next tactic:
rw [mem_upperCentralSeries_succ_iff]
/-- Any ascending central series for a group is bounded above by the upper central series. -/
theorem ascending_central_series_le_upper (H : ℕ → Subgroup G) (hH : IsAscendingCentralSeries H) :
    ∀ n : ℕ, H n ≤ upperCentralSeries G n
  | 0 => hH.1.symm ▸ le_refl ⊥
  | n + 1 => by
    intro x hx
    rw [mem_upperCentralSeries_succ_iff]
    

Proof state:
G : Type u_1
inst✝¹ : Group G
H✝ : Subgroup G
inst✝ : Normal H✝
H : ℕ → Subgroup G
hH : IsAscendingCentralSeries H
n : ℕ
x : G
hx : x ∈ H (n + 1)
⊢ ∀ (y : G), x * y * x⁻¹ * y⁻¹ ∈ upperCentralSeries G n

Next tactic:
exact fun y => ascending_central_series_le_upper H hH n (hH.2 x n hx y)
theorem upperCentralSeries_mono : Monotone (upperCentralSeries G) := by
  

Proof state:
G : Type u_1
inst✝¹ : Group G
H : Subgroup G
inst✝ : Normal H
⊢ Monotone (upperCentralSeries G)

Next tactic:
refine' monotone_nat_of_le_succ _
theorem upperCentralSeries_mono : Monotone (upperCentralSeries G) := by
  refine' monotone_nat_of_le_succ _
  

Proof state:
G : Type u_1
inst✝¹ : Group G
H : Subgroup G
inst✝ : Normal H
⊢ ∀ (n : ℕ), upperCentralSeries G n ≤ upperCentralSeries G (n + 1)

Next tactic:
intro n x hx y
theorem upperCentralSeries_mono : Monotone (upperCentralSeries G) := by
  refine' monotone_nat_of_le_succ _
  intro n x hx y
  

Proof state:
G : Type u_1
inst✝¹ : Group G
H : Subgroup G
inst✝ : Normal H
n : ℕ
x : G
hx : x ∈ upperCentralSeries G n
y : G
⊢ x * y * x⁻¹ * y⁻¹ ∈ (upperCentralSeriesAux G (Nat.add n 0)).fst

Next tactic:
rw [mul_assoc, mul_assoc, ← mul_assoc y x⁻¹ y⁻¹]
theorem upperCentralSeries_mono : Monotone (upperCentralSeries G) := by
  refine' monotone_nat_of_le_succ _
  intro n x hx y
  rw [mul_assoc, mul_assoc, ← mul_assoc y x⁻¹ y⁻¹]
  

Proof state:
G : Type u_1
inst✝¹ : Group G
H : Subgroup G
inst✝ : Normal H
n : ℕ
x : G
hx : x ∈ upperCentralSeries G n
y : G
⊢ x * (y * x⁻¹ * y⁻¹) ∈ (upperCentralSeriesAux G (Nat.add n 0)).fst

Next tactic:
exact mul_mem hx (Normal.conj_mem (upperCentralSeries_normal G n) x⁻¹ (inv_mem hx) y)
/-- A group `G` is nilpotent iff there exists an ascending central series which reaches `G` in
  finitely many steps. -/
theorem nilpotent_iff_finite_ascending_central_series :
    IsNilpotent G ↔ ∃ n : ℕ, ∃ H : ℕ → Subgroup G, IsAscendingCentralSeries H ∧ H n = ⊤ := by
  

Proof state:
G : Type u_1
inst✝¹ : Group G
H : Subgroup G
inst✝ : Normal H
⊢ Group.IsNilpotent G ↔ ∃ n H, IsAscendingCentralSeries H ∧ H n = ⊤

Next tactic:
constructor
/-- A group `G` is nilpotent iff there exists an ascending central series which reaches `G` in
  finitely many steps. -/
theorem nilpotent_iff_finite_ascending_central_series :
    IsNilpotent G ↔ ∃ n : ℕ, ∃ H : ℕ → Subgroup G, IsAscendingCentralSeries H ∧ H n = ⊤ := by
  constructor
  · 

Proof state:
case mp
G : Type u_1
inst✝¹ : Group G
H : Subgroup G
inst✝ : Normal H
⊢ Group.IsNilpotent G → ∃ n H, IsAscendingCentralSeries H ∧ H n = ⊤

Next tactic:
rintro ⟨n, nH⟩
/-- A group `G` is nilpotent iff there exists an ascending central series which reaches `G` in
  finitely many steps. -/
theorem nilpotent_iff_finite_ascending_central_series :
    IsNilpotent G ↔ ∃ n : ℕ, ∃ H : ℕ → Subgroup G, IsAscendingCentralSeries H ∧ H n = ⊤ := by
  constructor
  · rintro ⟨n, nH⟩
    

Proof state:
case mp.mk.intro
G : Type u_1
inst✝¹ : Group G
H : Subgroup G
inst✝ : Normal H
n : ℕ
nH : upperCentralSeries G n = ⊤
⊢ ∃ n H, IsAscendingCentralSeries H ∧ H n = ⊤

Next tactic:
refine' ⟨_, _, upperCentralSeries_isAscendingCentralSeries G, nH⟩
/-- A group `G` is nilpotent iff there exists an ascending central series which reaches `G` in
  finitely many steps. -/
theorem nilpotent_iff_finite_ascending_central_series :
    IsNilpotent G ↔ ∃ n : ℕ, ∃ H : ℕ → Subgroup G, IsAscendingCentralSeries H ∧ H n = ⊤ := by
  constructor
  · rintro ⟨n, nH⟩
    refine' ⟨_, _, upperCentralSeries_isAscendingCentralSeries G, nH⟩
  · 

Proof state:
case mpr
G : Type u_1
inst✝¹ : Group G
H : Subgroup G
inst✝ : Normal H
⊢ (∃ n H, IsAscendingCentralSeries H ∧ H n = ⊤) → Group.IsNilpotent G

Next tactic:
rintro ⟨n, H, hH, hn⟩
/-- A group `G` is nilpotent iff there exists an ascending central series which reaches `G` in
  finitely many steps. -/
theorem nilpotent_iff_finite_ascending_central_series :
    IsNilpotent G ↔ ∃ n : ℕ, ∃ H : ℕ → Subgroup G, IsAscendingCentralSeries H ∧ H n = ⊤ := by
  constructor
  · rintro ⟨n, nH⟩
    refine' ⟨_, _, upperCentralSeries_isAscendingCentralSeries G, nH⟩
  · rintro ⟨n, H, hH, hn⟩
    

Proof state:
case mpr.intro.intro.intro
G : Type u_1
inst✝¹ : Group G
H✝ : Subgroup G
inst✝ : Normal H✝
n : ℕ
H : ℕ → Subgroup G
hH : IsAscendingCentralSeries H
hn : H n = ⊤
⊢ Group.IsNilpotent G

Next tactic:
use n
/-- A group `G` is nilpotent iff there exists an ascending central series which reaches `G` in
  finitely many steps. -/
theorem nilpotent_iff_finite_ascending_central_series :
    IsNilpotent G ↔ ∃ n : ℕ, ∃ H : ℕ → Subgroup G, IsAscendingCentralSeries H ∧ H n = ⊤ := by
  constructor
  · rintro ⟨n, nH⟩
    refine' ⟨_, _, upperCentralSeries_isAscendingCentralSeries G, nH⟩
  · rintro ⟨n, H, hH, hn⟩
    use n
    

Proof state:
case h
G : Type u_1
inst✝¹ : Group G
H✝ : Subgroup G
inst✝ : Normal H✝
n : ℕ
H : ℕ → Subgroup G
hH : IsAscendingCentralSeries H
hn : H n = ⊤
⊢ upperCentralSeries G n = ⊤

Next tactic:
rw [eq_top_iff, ← hn]
/-- A group `G` is nilpotent iff there exists an ascending central series which reaches `G` in
  finitely many steps. -/
theorem nilpotent_iff_finite_ascending_central_series :
    IsNilpotent G ↔ ∃ n : ℕ, ∃ H : ℕ → Subgroup G, IsAscendingCentralSeries H ∧ H n = ⊤ := by
  constructor
  · rintro ⟨n, nH⟩
    refine' ⟨_, _, upperCentralSeries_isAscendingCentralSeries G, nH⟩
  · rintro ⟨n, H, hH, hn⟩
    use n
    rw [eq_top_iff, ← hn]
    

Proof state:
case h
G : Type u_1
inst✝¹ : Group G
H✝ : Subgroup G
inst✝ : Normal H✝
n : ℕ
H : ℕ → Subgroup G
hH : IsAscendingCentralSeries H
hn : H n = ⊤
⊢ H n ≤ upperCentralSeries G n

Next tactic:
exact ascending_central_series_le_upper H hH n
theorem is_decending_rev_series_of_is_ascending {H : ℕ → Subgroup G} {n : ℕ} (hn : H n = ⊤)
    (hasc : IsAscendingCentralSeries H) : IsDescendingCentralSeries fun m : ℕ => H (n - m) := by
  

Proof state:
G : Type u_1
inst✝¹ : Group G
H✝ : Subgroup G
inst✝ : Normal H✝
H : ℕ → Subgroup G
n : ℕ
hn : H n = ⊤
hasc : IsAscendingCentralSeries H
⊢ IsDescendingCentralSeries fun m => H (n - m)

Next tactic:
cases' hasc with h0 hH
theorem is_decending_rev_series_of_is_ascending {H : ℕ → Subgroup G} {n : ℕ} (hn : H n = ⊤)
    (hasc : IsAscendingCentralSeries H) : IsDescendingCentralSeries fun m : ℕ => H (n - m) := by
  cases' hasc with h0 hH
  

Proof state:
case intro
G : Type u_1
inst✝¹ : Group G
H✝ : Subgroup G
inst✝ : Normal H✝
H : ℕ → Subgroup G
n : ℕ
hn : H n = ⊤
h0 : H 0 = ⊥
hH : ∀ (x : G) (n : ℕ), x ∈ H (n + 1) → ∀ (g : G), x * g * x⁻¹ * g⁻¹ ∈ H n
⊢ IsDescendingCentralSeries fun m => H (n - m)

Next tactic:
refine' ⟨hn, fun x m hx g => _⟩