l3lab/ntp-mathlib huggingface dataset:
/-- The range of a surjective homomorphism from a nilpotent group is nilpotent -/
theorem nilpotent_of_surjective {G' : Type*} [Group G'] [h : IsNilpotent G] (f : G →* G')
    (hf : Function.Surjective f) : IsNilpotent G' := by
  rcases h with ⟨n, hn⟩
  

Proof state:
case mk.intro
G : Type u_1
inst✝² : Group G
H : Subgroup G
inst✝¹ : Normal H
G' : Type u_2
inst✝ : Group G'
f : G →* G'
hf : Function.Surjective ⇑f
n : ℕ
hn : upperCentralSeries G n = ⊤
⊢ Group.IsNilpotent G'

Next tactic:
use n
/-- The range of a surjective homomorphism from a nilpotent group is nilpotent -/
theorem nilpotent_of_surjective {G' : Type*} [Group G'] [h : IsNilpotent G] (f : G →* G')
    (hf : Function.Surjective f) : IsNilpotent G' := by
  rcases h with ⟨n, hn⟩
  use n
  

Proof state:
case h
G : Type u_1
inst✝² : Group G
H : Subgroup G
inst✝¹ : Normal H
G' : Type u_2
inst✝ : Group G'
f : G →* G'
hf : Function.Surjective ⇑f
n : ℕ
hn : upperCentralSeries G n = ⊤
⊢ upperCentralSeries G' n = ⊤

Next tactic:
apply eq_top_iff.mpr
/-- The range of a surjective homomorphism from a nilpotent group is nilpotent -/
theorem nilpotent_of_surjective {G' : Type*} [Group G'] [h : IsNilpotent G] (f : G →* G')
    (hf : Function.Surjective f) : IsNilpotent G' := by
  rcases h with ⟨n, hn⟩
  use n
  apply eq_top_iff.mpr
  

Proof state:
case h
G : Type u_1
inst✝² : Group G
H : Subgroup G
inst✝¹ : Normal H
G' : Type u_2
inst✝ : Group G'
f : G →* G'
hf : Function.Surjective ⇑f
n : ℕ
hn : upperCentralSeries G n = ⊤
⊢ ⊤ ≤ upperCentralSeries G' n

Next tactic:
calc
    ⊤ = f.range := symm (f.range_top_of_surjective hf)
    _ = Subgroup.map f ⊤ := (MonoidHom.range_eq_map _)
    _ = Subgroup.map f (upperCentralSeries G n) := by rw [hn]
    _ ≤ upperCentralSeries G' n := upperCentralSeries.map hf n
/-- The range of a surjective homomorphism from a nilpotent group is nilpotent -/
theorem nilpotent_of_surjective {G' : Type*} [Group G'] [h : IsNilpotent G] (f : G →* G')
    (hf : Function.Surjective f) : IsNilpotent G' := by
  rcases h with ⟨n, hn⟩
  use n
  apply eq_top_iff.mpr
  calc
    ⊤ = f.range := symm (f.range_top_of_surjective hf)
    _ = Subgroup.map f ⊤ := (MonoidHom.range_eq_map _)
    _ = Subgroup.map f (upperCentralSeries G n) := by 

Proof state:
G : Type u_1
inst✝² : Group G
H : Subgroup G
inst✝¹ : Normal H
G' : Type u_2
inst✝ : Group G'
f : G →* G'
hf : Function.Surjective ⇑f
n : ℕ
hn : upperCentralSeries G n = ⊤
⊢ Subgroup.map f ⊤ = Subgroup.map f (upperCentralSeries G n)

Next tactic:
rw [hn]
/-- The nilpotency class of the range of a surjective homomorphism from a
nilpotent group is less or equal the nilpotency class of the domain -/
theorem nilpotencyClass_le_of_surjective {G' : Type*} [Group G'] (f : G →* G')
    (hf : Function.Surjective f) [h : IsNilpotent G] :
    @Group.nilpotencyClass G' _ (nilpotent_of_surjective _ hf) ≤ Group.nilpotencyClass G := by
  -- Porting note: Lean needs to be told that predicates are decidable
  

Proof state:
G : Type u_1
inst✝² : Group G
H : Subgroup G
inst✝¹ : Normal H
G' : Type u_2
inst✝ : Group G'
f : G →* G'
hf : Function.Surjective ⇑f
h : Group.IsNilpotent G
⊢ nilpotencyClass G' ≤ nilpotencyClass G

Next tactic:
refine @Nat.find_mono _ _ (Classical.decPred _) (Classical.decPred _) ?_ _ _
/-- The nilpotency class of the range of a surjective homomorphism from a
nilpotent group is less or equal the nilpotency class of the domain -/
theorem nilpotencyClass_le_of_surjective {G' : Type*} [Group G'] (f : G →* G')
    (hf : Function.Surjective f) [h : IsNilpotent G] :
    @Group.nilpotencyClass G' _ (nilpotent_of_surjective _ hf) ≤ Group.nilpotencyClass G := by
  -- Porting note: Lean needs to be told that predicates are decidable
  refine @Nat.find_mono _ _ (Classical.decPred _) (Classical.decPred _) ?_ _ _
  

Proof state:
G : Type u_1
inst✝² : Group G
H : Subgroup G
inst✝¹ : Normal H
G' : Type u_2
inst✝ : Group G'
f : G →* G'
hf : Function.Surjective ⇑f
h : Group.IsNilpotent G
⊢ ∀ (n : ℕ), upperCentralSeries G n = ⊤ → upperCentralSeries G' n = ⊤

Next tactic:
intro n hn
/-- The nilpotency class of the range of a surjective homomorphism from a
nilpotent group is less or equal the nilpotency class of the domain -/
theorem nilpotencyClass_le_of_surjective {G' : Type*} [Group G'] (f : G →* G')
    (hf : Function.Surjective f) [h : IsNilpotent G] :
    @Group.nilpotencyClass G' _ (nilpotent_of_surjective _ hf) ≤ Group.nilpotencyClass G := by
  -- Porting note: Lean needs to be told that predicates are decidable
  refine @Nat.find_mono _ _ (Classical.decPred _) (Classical.decPred _) ?_ _ _
  intro n hn
  

Proof state:
G : Type u_1
inst✝² : Group G
H : Subgroup G
inst✝¹ : Normal H
G' : Type u_2
inst✝ : Group G'
f : G →* G'
hf : Function.Surjective ⇑f
h : Group.IsNilpotent G
n : ℕ
hn : upperCentralSeries G n = ⊤
⊢ upperCentralSeries G' n = ⊤

Next tactic:
apply eq_top_iff.mpr
/-- The nilpotency class of the range of a surjective homomorphism from a
nilpotent group is less or equal the nilpotency class of the domain -/
theorem nilpotencyClass_le_of_surjective {G' : Type*} [Group G'] (f : G →* G')
    (hf : Function.Surjective f) [h : IsNilpotent G] :
    @Group.nilpotencyClass G' _ (nilpotent_of_surjective _ hf) ≤ Group.nilpotencyClass G := by
  -- Porting note: Lean needs to be told that predicates are decidable
  refine @Nat.find_mono _ _ (Classical.decPred _) (Classical.decPred _) ?_ _ _
  intro n hn
  apply eq_top_iff.mpr
  

Proof state:
G : Type u_1
inst✝² : Group G
H : Subgroup G
inst✝¹ : Normal H
G' : Type u_2
inst✝ : Group G'
f : G →* G'
hf : Function.Surjective ⇑f
h : Group.IsNilpotent G
n : ℕ
hn : upperCentralSeries G n = ⊤
⊢ ⊤ ≤ upperCentralSeries G' n

Next tactic:
calc
    ⊤ = f.range := symm (f.range_top_of_surjective hf)
    _ = Subgroup.map f ⊤ := (MonoidHom.range_eq_map _)
    _ = Subgroup.map f (upperCentralSeries G n) := by rw [hn]
    _ ≤ upperCentralSeries G' n := upperCentralSeries.map hf n
/-- The nilpotency class of the range of a surjective homomorphism from a
nilpotent group is less or equal the nilpotency class of the domain -/
theorem nilpotencyClass_le_of_surjective {G' : Type*} [Group G'] (f : G →* G')
    (hf : Function.Surjective f) [h : IsNilpotent G] :
    @Group.nilpotencyClass G' _ (nilpotent_of_surjective _ hf) ≤ Group.nilpotencyClass G := by
  -- Porting note: Lean needs to be told that predicates are decidable
  refine @Nat.find_mono _ _ (Classical.decPred _) (Classical.decPred _) ?_ _ _
  intro n hn
  apply eq_top_iff.mpr
  calc
    ⊤ = f.range := symm (f.range_top_of_surjective hf)
    _ = Subgroup.map f ⊤ := (MonoidHom.range_eq_map _)
    _ = Subgroup.map f (upperCentralSeries G n) := by 

Proof state:
G : Type u_1
inst✝² : Group G
H : Subgroup G
inst✝¹ : Normal H
G' : Type u_2
inst✝ : Group G'
f : G →* G'
hf : Function.Surjective ⇑f
h : Group.IsNilpotent G
n : ℕ
hn : upperCentralSeries G n = ⊤
⊢ Subgroup.map f ⊤ = Subgroup.map f (upperCentralSeries G n)

Next tactic:
rw [hn]
private theorem comap_center_subst {H₁ H₂ : Subgroup G} [Normal H₁] [Normal H₂] (h : H₁ = H₂) :
    comap (mk' H₁) (center (G ⧸ H₁)) = comap (mk' H₂) (center (G ⧸ H₂)) := by 

Proof state:
G : Type u_1
inst✝³ : Group G
H : Subgroup G
inst✝² : Normal H
H₁ H₂ : Subgroup G
inst✝¹ : Normal H₁
inst✝ : Normal H₂
h : H₁ = H₂
⊢ comap (mk' H₁) (center (G ⧸ H₁)) = comap (mk' H₂) (center (G ⧸ H₂))

Next tactic:
subst h
private theorem comap_center_subst {H₁ H₂ : Subgroup G} [Normal H₁] [Normal H₂] (h : H₁ = H₂) :
    comap (mk' H₁) (center (G ⧸ H₁)) = comap (mk' H₂) (center (G ⧸ H₂)) := by subst h; 

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

Next tactic:
rfl
theorem comap_upperCentralSeries_quotient_center (n : ℕ) :
    comap (mk' (center G)) (upperCentralSeries (G ⧸ center G) n) = upperCentralSeries G n.succ := by
  

Proof state:
G : Type u_1
inst✝¹ : Group G
H : Subgroup G
inst✝ : Normal H
n : ℕ
⊢ comap (mk' (center G)) (upperCentralSeries (G ⧸ center G) n) = upperCentralSeries G (Nat.succ n)

Next tactic:
induction' n with n ih
theorem comap_upperCentralSeries_quotient_center (n : ℕ) :
    comap (mk' (center G)) (upperCentralSeries (G ⧸ center G) n) = upperCentralSeries G n.succ := by
  induction' n with n ih
  · 

Proof state:
case zero
G : Type u_1
inst✝¹ : Group G
H : Subgroup G
inst✝ : Normal H
⊢ comap (mk' (center G)) (upperCentralSeries (G ⧸ center G) Nat.zero) = upperCentralSeries G (Nat.succ Nat.zero)

Next tactic:
simp only [Nat.zero_eq, upperCentralSeries_zero, MonoidHom.comap_bot, ker_mk',
      (upperCentralSeries_one G).symm]
theorem comap_upperCentralSeries_quotient_center (n : ℕ) :
    comap (mk' (center G)) (upperCentralSeries (G ⧸ center G) n) = upperCentralSeries G n.succ := by
  induction' n with n ih
  · simp only [Nat.zero_eq, upperCentralSeries_zero, MonoidHom.comap_bot, ker_mk',
      (upperCentralSeries_one G).symm]
  · 

Proof state:
case succ
G : Type u_1
inst✝¹ : Group G
H : Subgroup G
inst✝ : Normal H
n : ℕ
ih : comap (mk' (center G)) (upperCentralSeries (G ⧸ center G) n) = upperCentralSeries G (Nat.succ n)
⊢ comap (mk' (center G)) (upperCentralSeries (G ⧸ center G) (Nat.succ n)) = upperCentralSeries G (Nat.succ (Nat.succ n))

Next tactic:
let Hn := upperCentralSeries (G ⧸ center G) n
theorem comap_upperCentralSeries_quotient_center (n : ℕ) :
    comap (mk' (center G)) (upperCentralSeries (G ⧸ center G) n) = upperCentralSeries G n.succ := by
  induction' n with n ih
  · simp only [Nat.zero_eq, upperCentralSeries_zero, MonoidHom.comap_bot, ker_mk',
      (upperCentralSeries_one G).symm]
  · let Hn := upperCentralSeries (G ⧸ center G) n
    

Proof state:
case succ
G : Type u_1
inst✝¹ : Group G
H : Subgroup G
inst✝ : Normal H
n : ℕ
ih : comap (mk' (center G)) (upperCentralSeries (G ⧸ center G) n) = upperCentralSeries G (Nat.succ n)
Hn : Subgroup (G ⧸ center G) := upperCentralSeries (G ⧸ center G) n
⊢ comap (mk' (center G)) (upperCentralSeries (G ⧸ center G) (Nat.succ n)) = upperCentralSeries G (Nat.succ (Nat.succ n))

Next tactic:
calc
      comap (mk' (center G)) (upperCentralSeriesStep Hn) =
          comap (mk' (center G)) (comap (mk' Hn) (center ((G ⧸ center G) ⧸ Hn))) :=
        by rw [upperCentralSeriesStep_eq_comap_center]
      _ = comap (mk' (comap (mk' (center G)) Hn)) (center (G ⧸ comap (mk' (center G)) Hn)) :=
        QuotientGroup.comap_comap_center
      _ = comap (mk' (upperCentralSeries G n.succ)) (center (G ⧸ upperCentralSeries G n.succ)) :=
        (comap_center_subst ih)
      _ = upperCentralSeriesStep (upperCentralSeries G n.succ) :=
        symm (upperCentralSeriesStep_eq_comap_center _)
theorem comap_upperCentralSeries_quotient_center (n : ℕ) :
    comap (mk' (center G)) (upperCentralSeries (G ⧸ center G) n) = upperCentralSeries G n.succ := by
  induction' n with n ih
  · simp only [Nat.zero_eq, upperCentralSeries_zero, MonoidHom.comap_bot, ker_mk',
      (upperCentralSeries_one G).symm]
  · let Hn := upperCentralSeries (G ⧸ center G) n
    calc
      comap (mk' (center G)) (upperCentralSeriesStep Hn) =
          comap (mk' (center G)) (comap (mk' Hn) (center ((G ⧸ center G) ⧸ Hn))) :=
        by 

Proof state:
G : Type u_1
inst✝¹ : Group G
H : Subgroup G
inst✝ : Normal H
n : ℕ
ih : comap (mk' (center G)) (upperCentralSeries (G ⧸ center G) n) = upperCentralSeries G (Nat.succ n)
Hn : Subgroup (G ⧸ center G) := upperCentralSeries (G ⧸ center G) n
⊢ comap (mk' (center G)) (upperCentralSeriesStep Hn) =
    comap (mk' (center G)) (comap (mk' Hn) (center ((G ⧸ center G) ⧸ Hn)))

Next tactic:
rw [upperCentralSeriesStep_eq_comap_center]
theorem nilpotencyClass_zero_iff_subsingleton [IsNilpotent G] :
    Group.nilpotencyClass G = 0 ↔ Subsingleton G := by
  -- Porting note: Lean needs to be told that predicates are decidable
  

Proof state:
G : Type u_1
inst✝² : Group G
H : Subgroup G
inst✝¹ : Normal H
inst✝ : Group.IsNilpotent G
⊢ nilpotencyClass G = 0 ↔ Subsingleton G

Next tactic:
rw [Group.nilpotencyClass, @Nat.find_eq_zero _ (Classical.decPred _), upperCentralSeries_zero,
    subsingleton_iff_bot_eq_top, Subgroup.subsingleton_iff]
/-- Quotienting the `center G` reduces the nilpotency class by 1 -/
theorem nilpotencyClass_quotient_center [hH : IsNilpotent G] :
    Group.nilpotencyClass (G ⧸ center G) = Group.nilpotencyClass G - 1 := by
  

Proof state:
G : Type u_1
inst✝¹ : Group G
H : Subgroup G
inst✝ : Normal H
hH : Group.IsNilpotent G
⊢ nilpotencyClass (G ⧸ center G) = nilpotencyClass G - 1

Next tactic:
generalize hn : Group.nilpotencyClass G = n
/-- Quotienting the `center G` reduces the nilpotency class by 1 -/
theorem nilpotencyClass_quotient_center [hH : IsNilpotent G] :
    Group.nilpotencyClass (G ⧸ center G) = Group.nilpotencyClass G - 1 := by
  generalize hn : Group.nilpotencyClass G = n
  

Proof state:
G : Type u_1
inst✝¹ : Group G
H : Subgroup G
inst✝ : Normal H
hH : Group.IsNilpotent G
n : ℕ
hn : nilpotencyClass G = n
⊢ nilpotencyClass (G ⧸ center G) = n - 1

Next tactic:
rcases n with (rfl | n)
/-- Quotienting the `center G` reduces the nilpotency class by 1 -/
theorem nilpotencyClass_quotient_center [hH : IsNilpotent G] :
    Group.nilpotencyClass (G ⧸ center G) = Group.nilpotencyClass G - 1 := by
  generalize hn : Group.nilpotencyClass G = n
  rcases n with (rfl | n)
  · 

Proof state:
case zero
G : Type u_1
inst✝¹ : Group G
H : Subgroup G
inst✝ : Normal H
hH : Group.IsNilpotent G
hn : nilpotencyClass G = Nat.zero
⊢ nilpotencyClass (G ⧸ center G) = Nat.zero - 1

Next tactic:
simp [nilpotencyClass_zero_iff_subsingleton] at *
/-- Quotienting the `center G` reduces the nilpotency class by 1 -/
theorem nilpotencyClass_quotient_center [hH : IsNilpotent G] :
    Group.nilpotencyClass (G ⧸ center G) = Group.nilpotencyClass G - 1 := by
  generalize hn : Group.nilpotencyClass G = n
  rcases n with (rfl | n)
  · simp [nilpotencyClass_zero_iff_subsingleton] at *
    

Proof state:
case zero
G : Type u_1
inst✝¹ : Group G
H : Subgroup G
inst✝ : Normal H
hH : Group.IsNilpotent G
hn : Subsingleton G
⊢ Subsingleton (G ⧸ center G)

Next tactic:
exact Quotient.instSubsingletonQuotient (leftRel (center G))
/-- Quotienting the `center G` reduces the nilpotency class by 1 -/
theorem nilpotencyClass_quotient_center [hH : IsNilpotent G] :
    Group.nilpotencyClass (G ⧸ center G) = Group.nilpotencyClass G - 1 := by
  generalize hn : Group.nilpotencyClass G = n
  rcases n with (rfl | n)
  · simp [nilpotencyClass_zero_iff_subsingleton] at *
    exact Quotient.instSubsingletonQuotient (leftRel (center G))
  · 

Proof state:
case succ
G : Type u_1
inst✝¹ : Group G
H : Subgroup G
inst✝ : Normal H
hH : Group.IsNilpotent G
n : ℕ
hn : nilpotencyClass G = Nat.succ n
⊢ nilpotencyClass (G ⧸ center G) = Nat.succ n - 1

Next tactic:
suffices Group.nilpotencyClass (G ⧸ center G) = n by simpa
/-- Quotienting the `center G` reduces the nilpotency class by 1 -/
theorem nilpotencyClass_quotient_center [hH : IsNilpotent G] :
    Group.nilpotencyClass (G ⧸ center G) = Group.nilpotencyClass G - 1 := by
  generalize hn : Group.nilpotencyClass G = n
  rcases n with (rfl | n)
  · simp [nilpotencyClass_zero_iff_subsingleton] at *
    exact Quotient.instSubsingletonQuotient (leftRel (center G))
  · suffices Group.nilpotencyClass (G ⧸ center G) = n by 

Proof state:
G : Type u_1
inst✝¹ : Group G
H : Subgroup G
inst✝ : Normal H
hH : Group.IsNilpotent G
n : ℕ
hn : nilpotencyClass G = Nat.succ n
this : nilpotencyClass (G ⧸ center G) = n
⊢ nilpotencyClass (G ⧸ center G) = Nat.succ n - 1

Next tactic:
simpa
/-- Quotienting the `center G` reduces the nilpotency class by 1 -/
theorem nilpotencyClass_quotient_center [hH : IsNilpotent G] :
    Group.nilpotencyClass (G ⧸ center G) = Group.nilpotencyClass G - 1 := by
  generalize hn : Group.nilpotencyClass G = n
  rcases n with (rfl | n)
  · simp [nilpotencyClass_zero_iff_subsingleton] at *
    exact Quotient.instSubsingletonQuotient (leftRel (center G))
  · suffices Group.nilpotencyClass (G ⧸ center G) = n by simpa
    

Proof state:
case succ
G : Type u_1
inst✝¹ : Group G
H : Subgroup G
inst✝ : Normal H
hH : Group.IsNilpotent G
n : ℕ
hn : nilpotencyClass G = Nat.succ n
⊢ nilpotencyClass (G ⧸ center G) = n

Next tactic:
apply le_antisymm
/-- Quotienting the `center G` reduces the nilpotency class by 1 -/
theorem nilpotencyClass_quotient_center [hH : IsNilpotent G] :
    Group.nilpotencyClass (G ⧸ center G) = Group.nilpotencyClass G - 1 := by
  generalize hn : Group.nilpotencyClass G = n
  rcases n with (rfl | n)
  · simp [nilpotencyClass_zero_iff_subsingleton] at *
    exact Quotient.instSubsingletonQuotient (leftRel (center G))
  · suffices Group.nilpotencyClass (G ⧸ center G) = n by simpa
    apply le_antisymm
    · 

Proof state:
case succ.a
G : Type u_1
inst✝¹ : Group G
H : Subgroup G
inst✝ : Normal H
hH : Group.IsNilpotent G
n : ℕ
hn : nilpotencyClass G = Nat.succ n
⊢ nilpotencyClass (G ⧸ center G) ≤ n

Next tactic:
apply upperCentralSeries_eq_top_iff_nilpotencyClass_le.mp
/-- Quotienting the `center G` reduces the nilpotency class by 1 -/
theorem nilpotencyClass_quotient_center [hH : IsNilpotent G] :
    Group.nilpotencyClass (G ⧸ center G) = Group.nilpotencyClass G - 1 := by
  generalize hn : Group.nilpotencyClass G = n
  rcases n with (rfl | n)
  · simp [nilpotencyClass_zero_iff_subsingleton] at *
    exact Quotient.instSubsingletonQuotient (leftRel (center G))
  · suffices Group.nilpotencyClass (G ⧸ center G) = n by simpa
    apply le_antisymm
    · apply upperCentralSeries_eq_top_iff_nilpotencyClass_le.mp
      

Proof state:
case succ.a
G : Type u_1
inst✝¹ : Group G
H : Subgroup G
inst✝ : Normal H
hH : Group.IsNilpotent G
n : ℕ
hn : nilpotencyClass G = Nat.succ n
⊢ upperCentralSeries (G ⧸ center G) n = ⊤

Next tactic:
apply @comap_injective G _ _ _ (mk' (center G)) (surjective_quot_mk _)
/-- Quotienting the `center G` reduces the nilpotency class by 1 -/
theorem nilpotencyClass_quotient_center [hH : IsNilpotent G] :
    Group.nilpotencyClass (G ⧸ center G) = Group.nilpotencyClass G - 1 := by
  generalize hn : Group.nilpotencyClass G = n
  rcases n with (rfl | n)
  · simp [nilpotencyClass_zero_iff_subsingleton] at *
    exact Quotient.instSubsingletonQuotient (leftRel (center G))
  · suffices Group.nilpotencyClass (G ⧸ center G) = n by simpa
    apply le_antisymm
    · apply upperCentralSeries_eq_top_iff_nilpotencyClass_le.mp
      apply @comap_injective G _ _ _ (mk' (center G)) (surjective_quot_mk _)
      

Proof state:
case succ.a.a
G : Type u_1
inst✝¹ : Group G
H : Subgroup G
inst✝ : Normal H
hH : Group.IsNilpotent G
n : ℕ
hn : nilpotencyClass G = Nat.succ n
⊢ comap (mk' (center G)) (upperCentralSeries (G ⧸ center G) n) = comap (mk' (center G)) ⊤

Next tactic:
rw [comap_upperCentralSeries_quotient_center, comap_top, ← hn]
/-- Quotienting the `center G` reduces the nilpotency class by 1 -/
theorem nilpotencyClass_quotient_center [hH : IsNilpotent G] :
    Group.nilpotencyClass (G ⧸ center G) = Group.nilpotencyClass G - 1 := by
  generalize hn : Group.nilpotencyClass G = n
  rcases n with (rfl | n)
  · simp [nilpotencyClass_zero_iff_subsingleton] at *
    exact Quotient.instSubsingletonQuotient (leftRel (center G))
  · suffices Group.nilpotencyClass (G ⧸ center G) = n by simpa
    apply le_antisymm
    · apply upperCentralSeries_eq_top_iff_nilpotencyClass_le.mp
      apply @comap_injective G _ _ _ (mk' (center G)) (surjective_quot_mk _)
      rw [comap_upperCentralSeries_quotient_center, comap_top, ← hn]
      

Proof state:
case succ.a.a
G : Type u_1
inst✝¹ : Group G
H : Subgroup G
inst✝ : Normal H
hH : Group.IsNilpotent G
n : ℕ
hn : nilpotencyClass G = Nat.succ n
⊢ upperCentralSeries G (nilpotencyClass G) = ⊤

Next tactic:
exact upperCentralSeries_nilpotencyClass
/-- Quotienting the `center G` reduces the nilpotency class by 1 -/
theorem nilpotencyClass_quotient_center [hH : IsNilpotent G] :
    Group.nilpotencyClass (G ⧸ center G) = Group.nilpotencyClass G - 1 := by
  generalize hn : Group.nilpotencyClass G = n
  rcases n with (rfl | n)
  · simp [nilpotencyClass_zero_iff_subsingleton] at *
    exact Quotient.instSubsingletonQuotient (leftRel (center G))
  · suffices Group.nilpotencyClass (G ⧸ center G) = n by simpa
    apply le_antisymm
    · apply upperCentralSeries_eq_top_iff_nilpotencyClass_le.mp
      apply @comap_injective G _ _ _ (mk' (center G)) (surjective_quot_mk _)
      rw [comap_upperCentralSeries_quotient_center, comap_top, ← hn]
      exact upperCentralSeries_nilpotencyClass
    · 

Proof state:
case succ.a
G : Type u_1
inst✝¹ : Group G
H : Subgroup G
inst✝ : Normal H
hH : Group.IsNilpotent G
n : ℕ
hn : nilpotencyClass G = Nat.succ n
⊢ n ≤ nilpotencyClass (G ⧸ center G)

Next tactic:
apply le_of_add_le_add_right
/-- Quotienting the `center G` reduces the nilpotency class by 1 -/
theorem nilpotencyClass_quotient_center [hH : IsNilpotent G] :
    Group.nilpotencyClass (G ⧸ center G) = Group.nilpotencyClass G - 1 := by
  generalize hn : Group.nilpotencyClass G = n
  rcases n with (rfl | n)
  · simp [nilpotencyClass_zero_iff_subsingleton] at *
    exact Quotient.instSubsingletonQuotient (leftRel (center G))
  · suffices Group.nilpotencyClass (G ⧸ center G) = n by simpa
    apply le_antisymm
    · apply upperCentralSeries_eq_top_iff_nilpotencyClass_le.mp
      apply @comap_injective G _ _ _ (mk' (center G)) (surjective_quot_mk _)
      rw [comap_upperCentralSeries_quotient_center, comap_top, ← hn]
      exact upperCentralSeries_nilpotencyClass
    · apply le_of_add_le_add_right
      

Proof state:
case succ.a.bc
G : Type u_1
inst✝¹ : Group G
H : Subgroup G
inst✝ : Normal H
hH : Group.IsNilpotent G
n : ℕ
hn : nilpotencyClass G = Nat.succ n
⊢ n + ?succ.a.a ≤ nilpotencyClass (G ⧸ center G) + ?succ.a.a
case succ.a.a
G : Type u_1
inst✝¹ : Group G
H : Subgroup G
inst✝ : Normal H
hH : Group.IsNilpotent G
n : ℕ
hn : nilpotencyClass G = Nat.succ n
⊢ ℕ

Next tactic:
calc
        n + 1 = n.succ := rfl
        _ = Group.nilpotencyClass G := (symm hn)
        _ ≤ Group.nilpotencyClass (G ⧸ center G) + 1 :=
          nilpotencyClass_le_of_ker_le_center _ (le_of_eq (ker_mk' _)) _
/-- The nilpotency class of a non-trivial group is one more than its quotient by the center -/
theorem nilpotencyClass_eq_quotient_center_plus_one [hH : IsNilpotent G] [Nontrivial G] :
    Group.nilpotencyClass G = Group.nilpotencyClass (G ⧸ center G) + 1 := by
  

Proof state:
G : Type u_1
inst✝² : Group G
H : Subgroup G
inst✝¹ : Normal H
hH : Group.IsNilpotent G
inst✝ : Nontrivial G
⊢ nilpotencyClass G = nilpotencyClass (G ⧸ center G) + 1

Next tactic:
rw [nilpotencyClass_quotient_center]
/-- The nilpotency class of a non-trivial group is one more than its quotient by the center -/
theorem nilpotencyClass_eq_quotient_center_plus_one [hH : IsNilpotent G] [Nontrivial G] :
    Group.nilpotencyClass G = Group.nilpotencyClass (G ⧸ center G) + 1 := by
  rw [nilpotencyClass_quotient_center]
  

Proof state:
G : Type u_1
inst✝² : Group G
H : Subgroup G
inst✝¹ : Normal H
hH : Group.IsNilpotent G
inst✝ : Nontrivial G
⊢ nilpotencyClass G = nilpotencyClass G - 1 + 1

Next tactic:
rcases h : Group.nilpotencyClass G with ⟨⟩
/-- The nilpotency class of a non-trivial group is one more than its quotient by the center -/
theorem nilpotencyClass_eq_quotient_center_plus_one [hH : IsNilpotent G] [Nontrivial G] :
    Group.nilpotencyClass G = Group.nilpotencyClass (G ⧸ center G) + 1 := by
  rw [nilpotencyClass_quotient_center]
  rcases h : Group.nilpotencyClass G with ⟨⟩
  · 

Proof state:
case zero
G : Type u_1
inst✝² : Group G
H : Subgroup G
inst✝¹ : Normal H
hH : Group.IsNilpotent G
inst✝ : Nontrivial G
h : nilpotencyClass G = Nat.zero
⊢ Nat.zero = Nat.zero - 1 + 1

Next tactic:
exfalso
/-- The nilpotency class of a non-trivial group is one more than its quotient by the center -/
theorem nilpotencyClass_eq_quotient_center_plus_one [hH : IsNilpotent G] [Nontrivial G] :
    Group.nilpotencyClass G = Group.nilpotencyClass (G ⧸ center G) + 1 := by
  rw [nilpotencyClass_quotient_center]
  rcases h : Group.nilpotencyClass G with ⟨⟩
  · exfalso
    

Proof state:
case zero.h
G : Type u_1
inst✝² : Group G
H : Subgroup G
inst✝¹ : Normal H
hH : Group.IsNilpotent G
inst✝ : Nontrivial G
h : nilpotencyClass G = Nat.zero
⊢ False

Next tactic:
rw [nilpotencyClass_zero_iff_subsingleton] at h