l3lab/ntp-mathlib huggingface dataset:
/-- 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
    rw [nilpotencyClass_zero_iff_subsingleton] at h; 

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 : Subsingleton G
⊢ False

Next tactic:
skip
/-- 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
    rw [nilpotencyClass_zero_iff_subsingleton] at h; skip
    

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 : Subsingleton G
⊢ False

Next tactic:
apply false_of_nontrivial_of_subsingleton G
/-- 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
    rw [nilpotencyClass_zero_iff_subsingleton] at h; skip
    apply false_of_nontrivial_of_subsingleton G
  · 

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

Next tactic:
simp
/-- If the quotient by `center G` is nilpotent, then so is G. -/
theorem of_quotient_center_nilpotent (h : IsNilpotent (G ⧸ center G)) : IsNilpotent G := by
  

Proof state:
G : Type u_1
inst✝¹ : Group G
H : Subgroup G
inst✝ : Normal H
h : Group.IsNilpotent (G ⧸ center G)
⊢ Group.IsNilpotent G

Next tactic:
obtain ⟨n, hn⟩ := h.nilpotent
/-- If the quotient by `center G` is nilpotent, then so is G. -/
theorem of_quotient_center_nilpotent (h : IsNilpotent (G ⧸ center G)) : IsNilpotent G := by
  obtain ⟨n, hn⟩ := h.nilpotent
  

Proof state:
case intro
G : Type u_1
inst✝¹ : Group G
H : Subgroup G
inst✝ : Normal H
h : Group.IsNilpotent (G ⧸ center G)
n : ℕ
hn : upperCentralSeries (G ⧸ center G) n = ⊤
⊢ Group.IsNilpotent G

Next tactic:
use n.succ
/-- If the quotient by `center G` is nilpotent, then so is G. -/
theorem of_quotient_center_nilpotent (h : IsNilpotent (G ⧸ center G)) : IsNilpotent G := by
  obtain ⟨n, hn⟩ := h.nilpotent
  use n.succ
  

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

Next tactic:
simp [← comap_upperCentralSeries_quotient_center, hn]
/-- A custom induction principle for nilpotent groups. The base case is a trivial group
(`subsingleton G`), and in the induction step, one can assume the hypothesis for
the group quotiented by its center. -/
@[elab_as_elim]
theorem nilpotent_center_quotient_ind {P : ∀ (G) [Group G] [IsNilpotent G], Prop}
    (G : Type*) [Group G] [IsNilpotent G]
    (hbase : ∀ (G) [Group G] [Subsingleton G], P G)
    (hstep : ∀ (G) [Group G] [IsNilpotent G], ∀ _ih : P (G ⧸ center G), P G) : P G := by
  

Proof state:
G✝ : Type u_1
inst✝³ : Group G✝
H : Subgroup G✝
inst✝² : Normal H
P : (G : Type u_2) → [inst : Group G] → [inst : Group.IsNilpotent G] → Prop
G : Type u_2
inst✝¹ : Group G
inst✝ : Group.IsNilpotent G
hbase : ∀ (G : Type u_2) [inst : Group G] [inst_1 : Subsingleton G], P G
hstep : ∀ (G : Type u_2) [inst : Group G] [inst_1 : Group.IsNilpotent G], P (G ⧸ center G) → P G
⊢ P G

Next tactic:
obtain ⟨n, h⟩ : ∃ n, Group.nilpotencyClass G = n := ⟨_, rfl⟩
/-- A custom induction principle for nilpotent groups. The base case is a trivial group
(`subsingleton G`), and in the induction step, one can assume the hypothesis for
the group quotiented by its center. -/
@[elab_as_elim]
theorem nilpotent_center_quotient_ind {P : ∀ (G) [Group G] [IsNilpotent G], Prop}
    (G : Type*) [Group G] [IsNilpotent G]
    (hbase : ∀ (G) [Group G] [Subsingleton G], P G)
    (hstep : ∀ (G) [Group G] [IsNilpotent G], ∀ _ih : P (G ⧸ center G), P G) : P G := by
  obtain ⟨n, h⟩ : ∃ n, Group.nilpotencyClass G = n := ⟨_, rfl⟩
  

Proof state:
case intro
G✝ : Type u_1
inst✝³ : Group G✝
H : Subgroup G✝
inst✝² : Normal H
P : (G : Type u_2) → [inst : Group G] → [inst : Group.IsNilpotent G] → Prop
G : Type u_2
inst✝¹ : Group G
inst✝ : Group.IsNilpotent G
hbase : ∀ (G : Type u_2) [inst : Group G] [inst_1 : Subsingleton G], P G
hstep : ∀ (G : Type u_2) [inst : Group G] [inst_1 : Group.IsNilpotent G], P (G ⧸ center G) → P G
n : ℕ
h : nilpotencyClass G = n
⊢ P G

Next tactic:
induction' n with n ih generalizing G
/-- A custom induction principle for nilpotent groups. The base case is a trivial group
(`subsingleton G`), and in the induction step, one can assume the hypothesis for
the group quotiented by its center. -/
@[elab_as_elim]
theorem nilpotent_center_quotient_ind {P : ∀ (G) [Group G] [IsNilpotent G], Prop}
    (G : Type*) [Group G] [IsNilpotent G]
    (hbase : ∀ (G) [Group G] [Subsingleton G], P G)
    (hstep : ∀ (G) [Group G] [IsNilpotent G], ∀ _ih : P (G ⧸ center G), P G) : P G := by
  obtain ⟨n, h⟩ : ∃ n, Group.nilpotencyClass G = n := ⟨_, rfl⟩
  induction' n with n ih generalizing G
  · 

Proof state:
case intro.zero
G✝ : Type u_1
inst✝³ : Group G✝
H : Subgroup G✝
inst✝² : Normal H
P : (G : Type u_2) → [inst : Group G] → [inst : Group.IsNilpotent G] → Prop
hbase : ∀ (G : Type u_2) [inst : Group G] [inst_1 : Subsingleton G], P G
hstep : ∀ (G : Type u_2) [inst : Group G] [inst_1 : Group.IsNilpotent G], P (G ⧸ center G) → P G
G : Type u_2
inst✝¹ : Group G
inst✝ : Group.IsNilpotent G
h : nilpotencyClass G = Nat.zero
⊢ P G

Next tactic:
haveI := nilpotencyClass_zero_iff_subsingleton.mp h
/-- A custom induction principle for nilpotent groups. The base case is a trivial group
(`subsingleton G`), and in the induction step, one can assume the hypothesis for
the group quotiented by its center. -/
@[elab_as_elim]
theorem nilpotent_center_quotient_ind {P : ∀ (G) [Group G] [IsNilpotent G], Prop}
    (G : Type*) [Group G] [IsNilpotent G]
    (hbase : ∀ (G) [Group G] [Subsingleton G], P G)
    (hstep : ∀ (G) [Group G] [IsNilpotent G], ∀ _ih : P (G ⧸ center G), P G) : P G := by
  obtain ⟨n, h⟩ : ∃ n, Group.nilpotencyClass G = n := ⟨_, rfl⟩
  induction' n with n ih generalizing G
  · haveI := nilpotencyClass_zero_iff_subsingleton.mp h
    

Proof state:
case intro.zero
G✝ : Type u_1
inst✝³ : Group G✝
H : Subgroup G✝
inst✝² : Normal H
P : (G : Type u_2) → [inst : Group G] → [inst : Group.IsNilpotent G] → Prop
hbase : ∀ (G : Type u_2) [inst : Group G] [inst_1 : Subsingleton G], P G
hstep : ∀ (G : Type u_2) [inst : Group G] [inst_1 : Group.IsNilpotent G], P (G ⧸ center G) → P G
G : Type u_2
inst✝¹ : Group G
inst✝ : Group.IsNilpotent G
h : nilpotencyClass G = Nat.zero
this : Subsingleton G
⊢ P G

Next tactic:
exact hbase _
/-- A custom induction principle for nilpotent groups. The base case is a trivial group
(`subsingleton G`), and in the induction step, one can assume the hypothesis for
the group quotiented by its center. -/
@[elab_as_elim]
theorem nilpotent_center_quotient_ind {P : ∀ (G) [Group G] [IsNilpotent G], Prop}
    (G : Type*) [Group G] [IsNilpotent G]
    (hbase : ∀ (G) [Group G] [Subsingleton G], P G)
    (hstep : ∀ (G) [Group G] [IsNilpotent G], ∀ _ih : P (G ⧸ center G), P G) : P G := by
  obtain ⟨n, h⟩ : ∃ n, Group.nilpotencyClass G = n := ⟨_, rfl⟩
  induction' n with n ih generalizing G
  · haveI := nilpotencyClass_zero_iff_subsingleton.mp h
    exact hbase _
  · 

Proof state:
case intro.succ
G✝ : Type u_1
inst✝³ : Group G✝
H : Subgroup G✝
inst✝² : Normal H
P : (G : Type u_2) → [inst : Group G] → [inst : Group.IsNilpotent G] → Prop
hbase : ∀ (G : Type u_2) [inst : Group G] [inst_1 : Subsingleton G], P G
hstep : ∀ (G : Type u_2) [inst : Group G] [inst_1 : Group.IsNilpotent G], P (G ⧸ center G) → P G
n : ℕ
ih : ∀ (G : Type u_2) [inst : Group G] [inst_1 : Group.IsNilpotent G], nilpotencyClass G = n → P G
G : Type u_2
inst✝¹ : Group G
inst✝ : Group.IsNilpotent G
h : nilpotencyClass G = Nat.succ n
⊢ P G

Next tactic:
have hn : Group.nilpotencyClass (G ⧸ center G) = n := by
      simp [nilpotencyClass_quotient_center, h]
/-- A custom induction principle for nilpotent groups. The base case is a trivial group
(`subsingleton G`), and in the induction step, one can assume the hypothesis for
the group quotiented by its center. -/
@[elab_as_elim]
theorem nilpotent_center_quotient_ind {P : ∀ (G) [Group G] [IsNilpotent G], Prop}
    (G : Type*) [Group G] [IsNilpotent G]
    (hbase : ∀ (G) [Group G] [Subsingleton G], P G)
    (hstep : ∀ (G) [Group G] [IsNilpotent G], ∀ _ih : P (G ⧸ center G), P G) : P G := by
  obtain ⟨n, h⟩ : ∃ n, Group.nilpotencyClass G = n := ⟨_, rfl⟩
  induction' n with n ih generalizing G
  · haveI := nilpotencyClass_zero_iff_subsingleton.mp h
    exact hbase _
  · have hn : Group.nilpotencyClass (G ⧸ center G) = n := by
      

Proof state:
G✝ : Type u_1
inst✝³ : Group G✝
H : Subgroup G✝
inst✝² : Normal H
P : (G : Type u_2) → [inst : Group G] → [inst : Group.IsNilpotent G] → Prop
hbase : ∀ (G : Type u_2) [inst : Group G] [inst_1 : Subsingleton G], P G
hstep : ∀ (G : Type u_2) [inst : Group G] [inst_1 : Group.IsNilpotent G], P (G ⧸ center G) → P G
n : ℕ
ih : ∀ (G : Type u_2) [inst : Group G] [inst_1 : Group.IsNilpotent G], nilpotencyClass G = n → P G
G : Type u_2
inst✝¹ : Group G
inst✝ : Group.IsNilpotent G
h : nilpotencyClass G = Nat.succ n
⊢ nilpotencyClass (G ⧸ center G) = n

Next tactic:
simp [nilpotencyClass_quotient_center, h]
/-- A custom induction principle for nilpotent groups. The base case is a trivial group
(`subsingleton G`), and in the induction step, one can assume the hypothesis for
the group quotiented by its center. -/
@[elab_as_elim]
theorem nilpotent_center_quotient_ind {P : ∀ (G) [Group G] [IsNilpotent G], Prop}
    (G : Type*) [Group G] [IsNilpotent G]
    (hbase : ∀ (G) [Group G] [Subsingleton G], P G)
    (hstep : ∀ (G) [Group G] [IsNilpotent G], ∀ _ih : P (G ⧸ center G), P G) : P G := by
  obtain ⟨n, h⟩ : ∃ n, Group.nilpotencyClass G = n := ⟨_, rfl⟩
  induction' n with n ih generalizing G
  · haveI := nilpotencyClass_zero_iff_subsingleton.mp h
    exact hbase _
  · have hn : Group.nilpotencyClass (G ⧸ center G) = n := by
      simp [nilpotencyClass_quotient_center, h]
    

Proof state:
case intro.succ
G✝ : Type u_1
inst✝³ : Group G✝
H : Subgroup G✝
inst✝² : Normal H
P : (G : Type u_2) → [inst : Group G] → [inst : Group.IsNilpotent G] → Prop
hbase : ∀ (G : Type u_2) [inst : Group G] [inst_1 : Subsingleton G], P G
hstep : ∀ (G : Type u_2) [inst : Group G] [inst_1 : Group.IsNilpotent G], P (G ⧸ center G) → P G
n : ℕ
ih : ∀ (G : Type u_2) [inst : Group G] [inst_1 : Group.IsNilpotent G], nilpotencyClass G = n → P G
G : Type u_2
inst✝¹ : Group G
inst✝ : Group.IsNilpotent G
h : nilpotencyClass G = Nat.succ n
hn : nilpotencyClass (G ⧸ center G) = n
⊢ P G

Next tactic:
exact hstep _ (ih _ hn)
theorem derived_le_lower_central (n : ℕ) : derivedSeries G n ≤ lowerCentralSeries G n := by
  

Proof state:
G : Type u_1
inst✝¹ : Group G
H : Subgroup G
inst✝ : Normal H
n : ℕ
⊢ derivedSeries G n ≤ lowerCentralSeries G n

Next tactic:
induction' n with i ih
theorem derived_le_lower_central (n : ℕ) : derivedSeries G n ≤ lowerCentralSeries G n := by
  induction' n with i ih
  · 

Proof state:
case zero
G : Type u_1
inst✝¹ : Group G
H : Subgroup G
inst✝ : Normal H
⊢ derivedSeries G Nat.zero ≤ lowerCentralSeries G Nat.zero

Next tactic:
simp
theorem derived_le_lower_central (n : ℕ) : derivedSeries G n ≤ lowerCentralSeries G n := by
  induction' n with i ih
  · simp
  · 

Proof state:
case succ
G : Type u_1
inst✝¹ : Group G
H : Subgroup G
inst✝ : Normal H
i : ℕ
ih : derivedSeries G i ≤ lowerCentralSeries G i
⊢ derivedSeries G (Nat.succ i) ≤ lowerCentralSeries G (Nat.succ i)

Next tactic:
apply commutator_mono ih
theorem derived_le_lower_central (n : ℕ) : derivedSeries G n ≤ lowerCentralSeries G n := by
  induction' n with i ih
  · simp
  · apply commutator_mono ih
    

Proof state:
case succ
G : Type u_1
inst✝¹ : Group G
H : Subgroup G
inst✝ : Normal H
i : ℕ
ih : derivedSeries G i ≤ lowerCentralSeries G i
⊢ derivedSeries G i ≤ ⊤

Next tactic:
simp
/-- Abelian groups are nilpotent -/
instance (priority := 100) CommGroup.isNilpotent {G : Type*} [CommGroup G] : IsNilpotent G := by
  

Proof state:
G✝ : Type u_1
inst✝² : Group G✝
H : Subgroup G✝
inst✝¹ : Normal H
G : Type u_2
inst✝ : CommGroup G
⊢ Group.IsNilpotent G

Next tactic:
use 1
/-- Abelian groups are nilpotent -/
instance (priority := 100) CommGroup.isNilpotent {G : Type*} [CommGroup G] : IsNilpotent G := by
  use 1
  

Proof state:
case h
G✝ : Type u_1
inst✝² : Group G✝
H : Subgroup G✝
inst✝¹ : Normal H
G : Type u_2
inst✝ : CommGroup G
⊢ upperCentralSeries G 1 = ⊤

Next tactic:
rw [upperCentralSeries_one]
/-- Abelian groups are nilpotent -/
instance (priority := 100) CommGroup.isNilpotent {G : Type*} [CommGroup G] : IsNilpotent G := by
  use 1
  rw [upperCentralSeries_one]
  

Proof state:
case h
G✝ : Type u_1
inst✝² : Group G✝
H : Subgroup G✝
inst✝¹ : Normal H
G : Type u_2
inst✝ : CommGroup G
⊢ center G = ⊤

Next tactic:
apply CommGroup.center_eq_top
/-- Abelian groups have nilpotency class at most one -/
theorem CommGroup.nilpotencyClass_le_one {G : Type*} [CommGroup G] :
    Group.nilpotencyClass G ≤ 1 := by
  

Proof state:
G✝ : Type u_1
inst✝² : Group G✝
H : Subgroup G✝
inst✝¹ : Normal H
G : Type u_2
inst✝ : CommGroup G
⊢ nilpotencyClass G ≤ 1

Next tactic:
apply upperCentralSeries_eq_top_iff_nilpotencyClass_le.mp
/-- Abelian groups have nilpotency class at most one -/
theorem CommGroup.nilpotencyClass_le_one {G : Type*} [CommGroup G] :
    Group.nilpotencyClass G ≤ 1 := by
  apply upperCentralSeries_eq_top_iff_nilpotencyClass_le.mp
  

Proof state:
G✝ : Type u_1
inst✝² : Group G✝
H : Subgroup G✝
inst✝¹ : Normal H
G : Type u_2
inst✝ : CommGroup G
⊢ upperCentralSeries G 1 = ⊤

Next tactic:
rw [upperCentralSeries_one]
/-- Abelian groups have nilpotency class at most one -/
theorem CommGroup.nilpotencyClass_le_one {G : Type*} [CommGroup G] :
    Group.nilpotencyClass G ≤ 1 := by
  apply upperCentralSeries_eq_top_iff_nilpotencyClass_le.mp
  rw [upperCentralSeries_one]
  

Proof state:
G✝ : Type u_1
inst✝² : Group G✝
H : Subgroup G✝
inst✝¹ : Normal H
G : Type u_2
inst✝ : CommGroup G
⊢ center G = ⊤

Next tactic:
apply CommGroup.center_eq_top
/-- Groups with nilpotency class at most one are abelian -/
def commGroupOfNilpotencyClass [IsNilpotent G] (h : Group.nilpotencyClass G ≤ 1) : CommGroup G :=
  Group.commGroupOfCenterEqTop <| by
    

Proof state:
G : Type u_1
inst✝² : Group G
H : Subgroup G
inst✝¹ : Normal H
inst✝ : Group.IsNilpotent G
h : nilpotencyClass G ≤ 1
⊢ center G = ⊤

Next tactic:
rw [← upperCentralSeries_one]
/-- Groups with nilpotency class at most one are abelian -/
def commGroupOfNilpotencyClass [IsNilpotent G] (h : Group.nilpotencyClass G ≤ 1) : CommGroup G :=
  Group.commGroupOfCenterEqTop <| by
    rw [← upperCentralSeries_one]
    

Proof state:
G : Type u_1
inst✝² : Group G
H : Subgroup G
inst✝¹ : Normal H
inst✝ : Group.IsNilpotent G
h : nilpotencyClass G ≤ 1
⊢ upperCentralSeries G 1 = ⊤

Next tactic:
exact upperCentralSeries_eq_top_iff_nilpotencyClass_le.mpr h
theorem lowerCentralSeries_prod (n : ℕ) :
    lowerCentralSeries (G₁ × G₂) n = (lowerCentralSeries G₁ n).prod (lowerCentralSeries G₂ n) := by
  

Proof state:
G : Type u_1
inst✝³ : Group G
H : Subgroup G
inst✝² : Normal H
G₁ : Type u_2
G₂ : Type u_3
inst✝¹ : Group G₁
inst✝ : Group G₂
n : ℕ
⊢ lowerCentralSeries (G₁ × G₂) n = prod (lowerCentralSeries G₁ n) (lowerCentralSeries G₂ n)

Next tactic:
induction' n with n ih
theorem lowerCentralSeries_prod (n : ℕ) :
    lowerCentralSeries (G₁ × G₂) n = (lowerCentralSeries G₁ n).prod (lowerCentralSeries G₂ n) := by
  induction' n with n ih
  · 

Proof state:
case zero
G : Type u_1
inst✝³ : Group G
H : Subgroup G
inst✝² : Normal H
G₁ : Type u_2
G₂ : Type u_3
inst✝¹ : Group G₁
inst✝ : Group G₂
⊢ lowerCentralSeries (G₁ × G₂) Nat.zero = prod (lowerCentralSeries G₁ Nat.zero) (lowerCentralSeries G₂ Nat.zero)

Next tactic:
simp
theorem lowerCentralSeries_prod (n : ℕ) :
    lowerCentralSeries (G₁ × G₂) n = (lowerCentralSeries G₁ n).prod (lowerCentralSeries G₂ n) := by
  induction' n with n ih
  · simp
  · 

Proof state:
case succ
G : Type u_1
inst✝³ : Group G
H : Subgroup G
inst✝² : Normal H
G₁ : Type u_2
G₂ : Type u_3
inst✝¹ : Group G₁
inst✝ : Group G₂
n : ℕ
ih : lowerCentralSeries (G₁ × G₂) n = prod (lowerCentralSeries G₁ n) (lowerCentralSeries G₂ n)
⊢ lowerCentralSeries (G₁ × G₂) (Nat.succ n) =
    prod (lowerCentralSeries G₁ (Nat.succ n)) (lowerCentralSeries G₂ (Nat.succ n))

Next tactic:
calc
      lowerCentralSeries (G₁ × G₂) n.succ = ⁅lowerCentralSeries (G₁ × G₂) n, ⊤⁆ := rfl
      _ = ⁅(lowerCentralSeries G₁ n).prod (lowerCentralSeries G₂ n), ⊤⁆ := by rw [ih]
      _ = ⁅(lowerCentralSeries G₁ n).prod (lowerCentralSeries G₂ n), (⊤ : Subgroup G₁).prod ⊤⁆ :=
        by simp
      _ = ⁅lowerCentralSeries G₁ n, (⊤ : Subgroup G₁)⁆.prod ⁅lowerCentralSeries G₂ n, ⊤⁆ :=
        (commutator_prod_prod _ _ _ _)
      _ = (lowerCentralSeries G₁ n.succ).prod (lowerCentralSeries G₂ n.succ) := rfl
theorem lowerCentralSeries_prod (n : ℕ) :
    lowerCentralSeries (G₁ × G₂) n = (lowerCentralSeries G₁ n).prod (lowerCentralSeries G₂ n) := by
  induction' n with n ih
  · simp
  · calc
      lowerCentralSeries (G₁ × G₂) n.succ = ⁅lowerCentralSeries (G₁ × G₂) n, ⊤⁆ := rfl
      _ = ⁅(lowerCentralSeries G₁ n).prod (lowerCentralSeries G₂ n), ⊤⁆ := by 

Proof state:
G : Type u_1
inst✝³ : Group G
H : Subgroup G
inst✝² : Normal H
G₁ : Type u_2
G₂ : Type u_3
inst✝¹ : Group G₁
inst✝ : Group G₂
n : ℕ
ih : lowerCentralSeries (G₁ × G₂) n = prod (lowerCentralSeries G₁ n) (lowerCentralSeries G₂ n)
⊢ ⁅lowerCentralSeries (G₁ × G₂) n, ⊤⁆ = ⁅prod (lowerCentralSeries G₁ n) (lowerCentralSeries G₂ n), ⊤⁆

Next tactic:
rw [ih]
theorem lowerCentralSeries_prod (n : ℕ) :
    lowerCentralSeries (G₁ × G₂) n = (lowerCentralSeries G₁ n).prod (lowerCentralSeries G₂ n) := by
  induction' n with n ih
  · simp
  · calc
      lowerCentralSeries (G₁ × G₂) n.succ = ⁅lowerCentralSeries (G₁ × G₂) n, ⊤⁆ := rfl
      _ = ⁅(lowerCentralSeries G₁ n).prod (lowerCentralSeries G₂ n), ⊤⁆ := by rw [ih]
      _ = ⁅(lowerCentralSeries G₁ n).prod (lowerCentralSeries G₂ n), (⊤ : Subgroup G₁).prod ⊤⁆ :=
        by 

Proof state:
G : Type u_1
inst✝³ : Group G
H : Subgroup G
inst✝² : Normal H
G₁ : Type u_2
G₂ : Type u_3
inst✝¹ : Group G₁
inst✝ : Group G₂
n : ℕ
ih : lowerCentralSeries (G₁ × G₂) n = prod (lowerCentralSeries G₁ n) (lowerCentralSeries G₂ n)
⊢ ⁅prod (lowerCentralSeries G₁ n) (lowerCentralSeries G₂ n), ⊤⁆ =
    ⁅prod (lowerCentralSeries G₁ n) (lowerCentralSeries G₂ n), prod ⊤ ⊤⁆

Next tactic:
simp
/-- Products of nilpotent groups are nilpotent -/
instance isNilpotent_prod [IsNilpotent G₁] [IsNilpotent G₂] : IsNilpotent (G₁ × G₂) := by
  

Proof state:
G : Type u_1
inst✝⁵ : Group G
H : Subgroup G
inst✝⁴ : Normal H
G₁ : Type u_2
G₂ : Type u_3
inst✝³ : Group G₁
inst✝² : Group G₂
inst✝¹ : Group.IsNilpotent G₁
inst✝ : Group.IsNilpotent G₂
⊢ Group.IsNilpotent (G₁ × G₂)

Next tactic:
rw [nilpotent_iff_lowerCentralSeries]
/-- Products of nilpotent groups are nilpotent -/
instance isNilpotent_prod [IsNilpotent G₁] [IsNilpotent G₂] : IsNilpotent (G₁ × G₂) := by
  rw [nilpotent_iff_lowerCentralSeries]
  

Proof state:
G : Type u_1
inst✝⁵ : Group G
H : Subgroup G
inst✝⁴ : Normal H
G₁ : Type u_2
G₂ : Type u_3
inst✝³ : Group G₁
inst✝² : Group G₂
inst✝¹ : Group.IsNilpotent G₁
inst✝ : Group.IsNilpotent G₂
⊢ ∃ n, lowerCentralSeries (G₁ × G₂) n = ⊥

Next tactic:
refine' ⟨max (Group.nilpotencyClass G₁) (Group.nilpotencyClass G₂), _⟩
/-- Products of nilpotent groups are nilpotent -/
instance isNilpotent_prod [IsNilpotent G₁] [IsNilpotent G₂] : IsNilpotent (G₁ × G₂) := by
  rw [nilpotent_iff_lowerCentralSeries]
  refine' ⟨max (Group.nilpotencyClass G₁) (Group.nilpotencyClass G₂), _⟩
  

Proof state:
G : Type u_1
inst✝⁵ : Group G
H : Subgroup G
inst✝⁴ : Normal H
G₁ : Type u_2
G₂ : Type u_3
inst✝³ : Group G₁
inst✝² : Group G₂
inst✝¹ : Group.IsNilpotent G₁
inst✝ : Group.IsNilpotent G₂
⊢ lowerCentralSeries (G₁ × G₂) (max (nilpotencyClass G₁) (nilpotencyClass G₂)) = ⊥

Next tactic:
rw [lowerCentralSeries_prod,
    lowerCentralSeries_eq_bot_iff_nilpotencyClass_le.mpr (le_max_left _ _),
    lowerCentralSeries_eq_bot_iff_nilpotencyClass_le.mpr (le_max_right _ _), bot_prod_bot]
/-- The nilpotency class of a product is the max of the nilpotency classes of the factors -/
theorem nilpotencyClass_prod [IsNilpotent G₁] [IsNilpotent G₂] :
    Group.nilpotencyClass (G₁ × G₂) =
    max (Group.nilpotencyClass G₁) (Group.nilpotencyClass G₂) := by
  

Proof state:
G : Type u_1
inst✝⁵ : Group G
H : Subgroup G
inst✝⁴ : Normal H
G₁ : Type u_2
G₂ : Type u_3
inst✝³ : Group G₁
inst✝² : Group G₂
inst✝¹ : Group.IsNilpotent G₁
inst✝ : Group.IsNilpotent G₂
⊢ nilpotencyClass (G₁ × G₂) = max (nilpotencyClass G₁) (nilpotencyClass G₂)

Next tactic:
refine' eq_of_forall_ge_iff fun k => _
/-- The nilpotency class of a product is the max of the nilpotency classes of the factors -/
theorem nilpotencyClass_prod [IsNilpotent G₁] [IsNilpotent G₂] :
    Group.nilpotencyClass (G₁ × G₂) =
    max (Group.nilpotencyClass G₁) (Group.nilpotencyClass G₂) := by
  refine' eq_of_forall_ge_iff fun k => _
  

Proof state:
G : Type u_1
inst✝⁵ : Group G
H : Subgroup G
inst✝⁴ : Normal H
G₁ : Type u_2
G₂ : Type u_3
inst✝³ : Group G₁
inst✝² : Group G₂
inst✝¹ : Group.IsNilpotent G₁
inst✝ : Group.IsNilpotent G₂
k : ℕ
⊢ nilpotencyClass (G₁ × G₂) ≤ k ↔ max (nilpotencyClass G₁) (nilpotencyClass G₂) ≤ k

Next tactic:
simp only [max_le_iff, ← lowerCentralSeries_eq_bot_iff_nilpotencyClass_le,
    lowerCentralSeries_prod, prod_eq_bot_iff]
theorem lowerCentralSeries_pi_le (n : ℕ) :
    lowerCentralSeries (∀ i, Gs i) n ≤ Subgroup.pi Set.univ
      fun i => lowerCentralSeries (Gs i) n := by
  

Proof state:
G : Type u_1
inst✝² : Group G
H : Subgroup G
inst✝¹ : Normal H
η : Type u_2
Gs : η → Type u_3
inst✝ : (i : η) → Group (Gs i)
n : ℕ
⊢ lowerCentralSeries ((i : η) → Gs i) n ≤ pi Set.univ fun i => lowerCentralSeries (Gs i) n

Next tactic:
let pi := fun f : ∀ i, Subgroup (Gs i) => Subgroup.pi Set.univ f
theorem lowerCentralSeries_pi_le (n : ℕ) :
    lowerCentralSeries (∀ i, Gs i) n ≤ Subgroup.pi Set.univ
      fun i => lowerCentralSeries (Gs i) n := by
  let pi := fun f : ∀ i, Subgroup (Gs i) => Subgroup.pi Set.univ f
  

Proof state:
G : Type u_1
inst✝² : Group G
H : Subgroup G
inst✝¹ : Normal H
η : Type u_2
Gs : η → Type u_3
inst✝ : (i : η) → Group (Gs i)
n : ℕ
pi : ((i : η) → Subgroup (Gs i)) → Subgroup ((i : η) → Gs i) := fun f => Subgroup.pi Set.univ f
⊢ lowerCentralSeries ((i : η) → Gs i) n ≤ Subgroup.pi Set.univ fun i => lowerCentralSeries (Gs i) n

Next tactic:
induction' n with n ih
theorem lowerCentralSeries_pi_le (n : ℕ) :
    lowerCentralSeries (∀ i, Gs i) n ≤ Subgroup.pi Set.univ
      fun i => lowerCentralSeries (Gs i) n := by
  let pi := fun f : ∀ i, Subgroup (Gs i) => Subgroup.pi Set.univ f
  induction' n with n ih
  · 

Proof state:
case zero
G : Type u_1
inst✝² : Group G
H : Subgroup G
inst✝¹ : Normal H
η : Type u_2
Gs : η → Type u_3
inst✝ : (i : η) → Group (Gs i)
pi : ((i : η) → Subgroup (Gs i)) → Subgroup ((i : η) → Gs i) := fun f => Subgroup.pi Set.univ f
⊢ lowerCentralSeries ((i : η) → Gs i) Nat.zero ≤ Subgroup.pi Set.univ fun i => lowerCentralSeries (Gs i) Nat.zero

Next tactic:
simp [pi_top]