l3lab/ntp-mathlib huggingface dataset:
/-- An inequality involving `2`. -/
theorem sub_one_div_inv_le_two (a2 : 2 ≤ a) : (1 - 1 / a)⁻¹ ≤ 2 := by
  -- Take inverses on both sides to obtain `2⁻¹ ≤ 1 - 1 / a`
  

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
inst✝ : LinearOrderedField α
a b c d : α
n : ℤ
a2 : 2 ≤ a
⊢ (1 - 1 / a)⁻¹ ≤ 2

Next tactic:
refine' (inv_le_inv_of_le (inv_pos.2 <| zero_lt_two' α) _).trans_eq (inv_inv (2 : α))
/-- An inequality involving `2`. -/
theorem sub_one_div_inv_le_two (a2 : 2 ≤ a) : (1 - 1 / a)⁻¹ ≤ 2 := by
  -- Take inverses on both sides to obtain `2⁻¹ ≤ 1 - 1 / a`
  refine' (inv_le_inv_of_le (inv_pos.2 <| zero_lt_two' α) _).trans_eq (inv_inv (2 : α))
  -- move `1 / a` to the left and `2⁻¹` to the right.
  

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
inst✝ : LinearOrderedField α
a b c d : α
n : ℤ
a2 : 2 ≤ a
⊢ 2⁻¹ ≤ 1 - 1 / a

Next tactic:
rw [le_sub_iff_add_le, add_comm, ← le_sub_iff_add_le]
/-- An inequality involving `2`. -/
theorem sub_one_div_inv_le_two (a2 : 2 ≤ a) : (1 - 1 / a)⁻¹ ≤ 2 := by
  -- Take inverses on both sides to obtain `2⁻¹ ≤ 1 - 1 / a`
  refine' (inv_le_inv_of_le (inv_pos.2 <| zero_lt_two' α) _).trans_eq (inv_inv (2 : α))
  -- move `1 / a` to the left and `2⁻¹` to the right.
  rw [le_sub_iff_add_le, add_comm, ← le_sub_iff_add_le]
  -- take inverses on both sides and use the assumption `2 ≤ a`.
  

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
inst✝ : LinearOrderedField α
a b c d : α
n : ℤ
a2 : 2 ≤ a
⊢ 1 / a ≤ 1 - 2⁻¹

Next tactic:
convert (one_div a).le.trans (inv_le_inv_of_le zero_lt_two a2) using 1
/-- An inequality involving `2`. -/
theorem sub_one_div_inv_le_two (a2 : 2 ≤ a) : (1 - 1 / a)⁻¹ ≤ 2 := by
  -- Take inverses on both sides to obtain `2⁻¹ ≤ 1 - 1 / a`
  refine' (inv_le_inv_of_le (inv_pos.2 <| zero_lt_two' α) _).trans_eq (inv_inv (2 : α))
  -- move `1 / a` to the left and `2⁻¹` to the right.
  rw [le_sub_iff_add_le, add_comm, ← le_sub_iff_add_le]
  -- take inverses on both sides and use the assumption `2 ≤ a`.
  convert (one_div a).le.trans (inv_le_inv_of_le zero_lt_two a2) using 1
  -- show `1 - 1 / 2 = 1 / 2`.
  

Proof state:
case h.e'_4
ι : Type u_1
α : Type u_2
β : Type u_3
inst✝ : LinearOrderedField α
a b c d : α
n : ℤ
a2 : 2 ≤ a
⊢ 1 - 2⁻¹ = 2⁻¹

Next tactic:
rw [sub_eq_iff_eq_add, ← two_mul, mul_inv_cancel two_ne_zero]
theorem IsLUB.mul_left {s : Set α} (ha : 0 ≤ a) (hs : IsLUB s b) :
    IsLUB ((fun b => a * b) '' s) (a * b) := by
  

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
inst✝ : LinearOrderedField α
a b c d : α
n : ℤ
s : Set α
ha : 0 ≤ a
hs : IsLUB s b
⊢ IsLUB ((fun b => a * b) '' s) (a * b)

Next tactic:
rcases lt_or_eq_of_le ha with (ha | rfl)
theorem IsLUB.mul_left {s : Set α} (ha : 0 ≤ a) (hs : IsLUB s b) :
    IsLUB ((fun b => a * b) '' s) (a * b) := by
  rcases lt_or_eq_of_le ha with (ha | rfl)
  · 

Proof state:
case inl
ι : Type u_1
α : Type u_2
β : Type u_3
inst✝ : LinearOrderedField α
a b c d : α
n : ℤ
s : Set α
ha✝ : 0 ≤ a
hs : IsLUB s b
ha : 0 < a
⊢ IsLUB ((fun b => a * b) '' s) (a * b)

Next tactic:
exact (OrderIso.mulLeft₀ _ ha).isLUB_image'.2 hs
theorem IsLUB.mul_left {s : Set α} (ha : 0 ≤ a) (hs : IsLUB s b) :
    IsLUB ((fun b => a * b) '' s) (a * b) := by
  rcases lt_or_eq_of_le ha with (ha | rfl)
  · exact (OrderIso.mulLeft₀ _ ha).isLUB_image'.2 hs
  · 

Proof state:
case inr
ι : Type u_1
α : Type u_2
β : Type u_3
inst✝ : LinearOrderedField α
b c d : α
n : ℤ
s : Set α
hs : IsLUB s b
ha : 0 ≤ 0
⊢ IsLUB ((fun b => 0 * b) '' s) (0 * b)

Next tactic:
simp_rw [zero_mul]
theorem IsLUB.mul_left {s : Set α} (ha : 0 ≤ a) (hs : IsLUB s b) :
    IsLUB ((fun b => a * b) '' s) (a * b) := by
  rcases lt_or_eq_of_le ha with (ha | rfl)
  · exact (OrderIso.mulLeft₀ _ ha).isLUB_image'.2 hs
  · simp_rw [zero_mul]
    

Proof state:
case inr
ι : Type u_1
α : Type u_2
β : Type u_3
inst✝ : LinearOrderedField α
b c d : α
n : ℤ
s : Set α
hs : IsLUB s b
ha : 0 ≤ 0
⊢ IsLUB ((fun a => 0) '' s) 0

Next tactic:
rw [hs.nonempty.image_const]
theorem IsLUB.mul_left {s : Set α} (ha : 0 ≤ a) (hs : IsLUB s b) :
    IsLUB ((fun b => a * b) '' s) (a * b) := by
  rcases lt_or_eq_of_le ha with (ha | rfl)
  · exact (OrderIso.mulLeft₀ _ ha).isLUB_image'.2 hs
  · simp_rw [zero_mul]
    rw [hs.nonempty.image_const]
    

Proof state:
case inr
ι : Type u_1
α : Type u_2
β : Type u_3
inst✝ : LinearOrderedField α
b c d : α
n : ℤ
s : Set α
hs : IsLUB s b
ha : 0 ≤ 0
⊢ IsLUB {0} 0

Next tactic:
exact isLUB_singleton
theorem IsLUB.mul_right {s : Set α} (ha : 0 ≤ a) (hs : IsLUB s b) :
    IsLUB ((fun b => b * a) '' s) (b * a) := by 

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
inst✝ : LinearOrderedField α
a b c d : α
n : ℤ
s : Set α
ha : 0 ≤ a
hs : IsLUB s b
⊢ IsLUB ((fun b => b * a) '' s) (b * a)

Next tactic:
simpa [mul_comm] using hs.mul_left ha
theorem mul_sub_mul_div_mul_neg_iff (hc : c ≠ 0) (hd : d ≠ 0) :
    (a * d - b * c) / (c * d) < 0 ↔ a / c < b / d := by
  

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
inst✝ : LinearOrderedField α
a b c d : α
n : ℤ
hc : c ≠ 0
hd : d ≠ 0
⊢ (a * d - b * c) / (c * d) < 0 ↔ a / c < b / d

Next tactic:
rw [mul_comm b c, ← div_sub_div _ _ hc hd, sub_lt_zero]
theorem mul_sub_mul_div_mul_nonpos_iff (hc : c ≠ 0) (hd : d ≠ 0) :
    (a * d - b * c) / (c * d) ≤ 0 ↔ a / c ≤ b / d := by
  

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
inst✝ : LinearOrderedField α
a b c d : α
n : ℤ
hc : c ≠ 0
hd : d ≠ 0
⊢ (a * d - b * c) / (c * d) ≤ 0 ↔ a / c ≤ b / d

Next tactic:
rw [mul_comm b c, ← div_sub_div _ _ hc hd, sub_nonpos]
theorem le_of_forall_sub_le (h : ∀ ε > 0, b - ε ≤ a) : b ≤ a := by
  

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
inst✝ : LinearOrderedField α
a b c d : α
n : ℤ
h : ∀ ε > 0, b - ε ≤ a
⊢ b ≤ a

Next tactic:
contrapose! h
theorem le_of_forall_sub_le (h : ∀ ε > 0, b - ε ≤ a) : b ≤ a := by
  contrapose! h
  

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
inst✝ : LinearOrderedField α
a b c d : α
n : ℤ
h : a < b
⊢ ∃ ε > 0, a < b - ε

Next tactic:
simpa only [@and_comm ((0 : α) < _), lt_sub_iff_add_lt, gt_iff_lt] using
    exists_add_lt_and_pos_of_lt h
theorem mul_self_inj_of_nonneg (a0 : 0 ≤ a) (b0 : 0 ≤ b) : a * a = b * b ↔ a = b :=
  mul_self_eq_mul_self_iff.trans <|
    or_iff_left_of_imp fun h => by
      

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
inst✝ : LinearOrderedField α
a b c d : α
n : ℤ
a0 : 0 ≤ a
b0 : 0 ≤ b
h : a = -b
⊢ a = b

Next tactic:
subst a
theorem mul_self_inj_of_nonneg (a0 : 0 ≤ a) (b0 : 0 ≤ b) : a * a = b * b ↔ a = b :=
  mul_self_eq_mul_self_iff.trans <|
    or_iff_left_of_imp fun h => by
      subst a
      

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
inst✝ : LinearOrderedField α
b c d : α
n : ℤ
b0 : 0 ≤ b
a0 : 0 ≤ -b
⊢ -b = b

Next tactic:
have : b = 0 := le_antisymm (neg_nonneg.1 a0) b0
theorem mul_self_inj_of_nonneg (a0 : 0 ≤ a) (b0 : 0 ≤ b) : a * a = b * b ↔ a = b :=
  mul_self_eq_mul_self_iff.trans <|
    or_iff_left_of_imp fun h => by
      subst a
      have : b = 0 := le_antisymm (neg_nonneg.1 a0) b0
      

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
inst✝ : LinearOrderedField α
b c d : α
n : ℤ
b0 : 0 ≤ b
a0 : 0 ≤ -b
this : b = 0
⊢ -b = b

Next tactic:
rw [this, neg_zero]
theorem abs_one_div (a : α) : |1 / a| = 1 / |a| := by 

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
inst✝ : LinearOrderedField α
a✝ b c d : α
n : ℤ
a : α
⊢ |1 / a| = 1 / |a|

Next tactic:
rw [abs_div, abs_one]
theorem commutator_eq_closure : commutator G = Subgroup.closure (commutatorSet G) := by
  

Proof state:
G : Type u
inst✝ : Group G
⊢ commutator G = Subgroup.closure (commutatorSet G)

Next tactic:
simp [commutator, Subgroup.commutator_def, commutatorSet]
theorem commutator_eq_normalClosure : commutator G = Subgroup.normalClosure (commutatorSet G) := by
  

Proof state:
G : Type u
inst✝ : Group G
⊢ commutator G = Subgroup.normalClosure (commutatorSet G)

Next tactic:
simp [commutator, Subgroup.commutator_def', commutatorSet]
instance [Finite (commutatorSet G)] : Group.FG (commutator G) := by
  

Proof state:
G : Type u
inst✝¹ : Group G
inst✝ : Finite ↑(commutatorSet G)
⊢ Group.FG ↥(commutator G)

Next tactic:
rw [commutator_eq_closure]
instance [Finite (commutatorSet G)] : Group.FG (commutator G) := by
  rw [commutator_eq_closure]
  

Proof state:
G : Type u
inst✝¹ : Group G
inst✝ : Finite ↑(commutatorSet G)
⊢ Group.FG ↥(Subgroup.closure (commutatorSet G))

Next tactic:
apply Group.closure_finite_fg
theorem rank_commutator_le_card [Finite (commutatorSet G)] :
    Group.rank (commutator G) ≤ Nat.card (commutatorSet G) := by
  

Proof state:
G : Type u
inst✝¹ : Group G
inst✝ : Finite ↑(commutatorSet G)
⊢ Group.rank ↥(commutator G) ≤ Nat.card ↑(commutatorSet G)

Next tactic:
rw [Subgroup.rank_congr (commutator_eq_closure G)]
theorem rank_commutator_le_card [Finite (commutatorSet G)] :
    Group.rank (commutator G) ≤ Nat.card (commutatorSet G) := by
  rw [Subgroup.rank_congr (commutator_eq_closure G)]
  

Proof state:
G : Type u
inst✝¹ : Group G
inst✝ : Finite ↑(commutatorSet G)
⊢ Group.rank ↥(Subgroup.closure (commutatorSet G)) ≤ Nat.card ↑(commutatorSet G)

Next tactic:
apply Subgroup.rank_closure_finite_le_nat_card
theorem commutator_centralizer_commutator_le_center :
    ⁅centralizer (commutator G : Set G), centralizer (commutator G)⁆ ≤ Subgroup.center G := by
  

Proof state:
G : Type u
inst✝ : Group G
⊢ ⁅centralizer ↑(commutator G), centralizer ↑(commutator G)⁆ ≤ Subgroup.center G

Next tactic:
rw [← Subgroup.centralizer_univ, ← Subgroup.coe_top, ←
    Subgroup.commutator_eq_bot_iff_le_centralizer]
theorem commutator_centralizer_commutator_le_center :
    ⁅centralizer (commutator G : Set G), centralizer (commutator G)⁆ ≤ Subgroup.center G := by
  rw [← Subgroup.centralizer_univ, ← Subgroup.coe_top, ←
    Subgroup.commutator_eq_bot_iff_le_centralizer]
  

Proof state:
G : Type u
inst✝ : Group G
⊢ ⁅⁅centralizer ↑(commutator G), centralizer ↑(commutator G)⁆, ⊤⁆ = ⊥

Next tactic:
suffices ⁅⁅⊤, centralizer (commutator G : Set G)⁆, centralizer (commutator G : Set G)⁆ = ⊥ by
    refine' Subgroup.commutator_commutator_eq_bot_of_rotate _ this
    rwa [Subgroup.commutator_comm (centralizer (commutator G : Set G))]
theorem commutator_centralizer_commutator_le_center :
    ⁅centralizer (commutator G : Set G), centralizer (commutator G)⁆ ≤ Subgroup.center G := by
  rw [← Subgroup.centralizer_univ, ← Subgroup.coe_top, ←
    Subgroup.commutator_eq_bot_iff_le_centralizer]
  suffices ⁅⁅⊤, centralizer (commutator G : Set G)⁆, centralizer (commutator G : Set G)⁆ = ⊥ by
    

Proof state:
G : Type u
inst✝ : Group G
this : ⁅⁅⊤, centralizer ↑(commutator G)⁆, centralizer ↑(commutator G)⁆ = ⊥
⊢ ⁅⁅centralizer ↑(commutator G), centralizer ↑(commutator G)⁆, ⊤⁆ = ⊥

Next tactic:
refine' Subgroup.commutator_commutator_eq_bot_of_rotate _ this
theorem commutator_centralizer_commutator_le_center :
    ⁅centralizer (commutator G : Set G), centralizer (commutator G)⁆ ≤ Subgroup.center G := by
  rw [← Subgroup.centralizer_univ, ← Subgroup.coe_top, ←
    Subgroup.commutator_eq_bot_iff_le_centralizer]
  suffices ⁅⁅⊤, centralizer (commutator G : Set G)⁆, centralizer (commutator G : Set G)⁆ = ⊥ by
    refine' Subgroup.commutator_commutator_eq_bot_of_rotate _ this
    

Proof state:
G : Type u
inst✝ : Group G
this : ⁅⁅⊤, centralizer ↑(commutator G)⁆, centralizer ↑(commutator G)⁆ = ⊥
⊢ ⁅⁅centralizer ↑(commutator G), ⊤⁆, centralizer ↑(commutator G)⁆ = ⊥

Next tactic:
rwa [Subgroup.commutator_comm (centralizer (commutator G : Set G))]
theorem commutator_centralizer_commutator_le_center :
    ⁅centralizer (commutator G : Set G), centralizer (commutator G)⁆ ≤ Subgroup.center G := by
  rw [← Subgroup.centralizer_univ, ← Subgroup.coe_top, ←
    Subgroup.commutator_eq_bot_iff_le_centralizer]
  suffices ⁅⁅⊤, centralizer (commutator G : Set G)⁆, centralizer (commutator G : Set G)⁆ = ⊥ by
    refine' Subgroup.commutator_commutator_eq_bot_of_rotate _ this
    rwa [Subgroup.commutator_comm (centralizer (commutator G : Set G))]
  

Proof state:
G : Type u
inst✝ : Group G
⊢ ⁅⁅⊤, centralizer ↑(commutator G)⁆, centralizer ↑(commutator G)⁆ = ⊥

Next tactic:
rw [Subgroup.commutator_comm, Subgroup.commutator_eq_bot_iff_le_centralizer]
theorem commutator_centralizer_commutator_le_center :
    ⁅centralizer (commutator G : Set G), centralizer (commutator G)⁆ ≤ Subgroup.center G := by
  rw [← Subgroup.centralizer_univ, ← Subgroup.coe_top, ←
    Subgroup.commutator_eq_bot_iff_le_centralizer]
  suffices ⁅⁅⊤, centralizer (commutator G : Set G)⁆, centralizer (commutator G : Set G)⁆ = ⊥ by
    refine' Subgroup.commutator_commutator_eq_bot_of_rotate _ this
    rwa [Subgroup.commutator_comm (centralizer (commutator G : Set G))]
  rw [Subgroup.commutator_comm, Subgroup.commutator_eq_bot_iff_le_centralizer]
  

Proof state:
G : Type u
inst✝ : Group G
⊢ centralizer ↑(commutator G) ≤ centralizer ↑⁅⊤, centralizer ↑(commutator G)⁆

Next tactic:
exact Set.centralizer_subset (Subgroup.commutator_mono le_top le_top)
instance commGroup : CommGroup (Abelianization G) :=
  { QuotientGroup.Quotient.group _ with
    mul_comm := fun x y =>
      Quotient.inductionOn₂' x y fun a b =>
        Quotient.sound' <|
          QuotientGroup.leftRel_apply.mpr <|
            Subgroup.subset_closure
              ⟨b⁻¹, Subgroup.mem_top b⁻¹, a⁻¹, Subgroup.mem_top a⁻¹, by 

Proof state:
G : Type u
inst✝ : Group G
src✝ : Group (G ⧸ commutator G) := QuotientGroup.Quotient.group (commutator G)
x y : Abelianization G
a b : G
⊢ ⁅b⁻¹, a⁻¹⁆ = ((fun x x_1 => x * x_1) a b)⁻¹ * (fun x x_1 => x * x_1) b a

Next tactic:
group
theorem commutator_subset_ker : commutator G ≤ f.ker := by
  

Proof state:
G : Type u
inst✝¹ : Group G
A : Type v
inst✝ : CommGroup A
f : G →* A
⊢ commutator G ≤ MonoidHom.ker f

Next tactic:
rw [commutator_eq_closure, Subgroup.closure_le]
theorem commutator_subset_ker : commutator G ≤ f.ker := by
  rw [commutator_eq_closure, Subgroup.closure_le]
  

Proof state:
G : Type u
inst✝¹ : Group G
A : Type v
inst✝ : CommGroup A
f : G →* A
⊢ commutatorSet G ⊆ ↑(MonoidHom.ker f)

Next tactic:
rintro x ⟨p, q, rfl⟩
theorem commutator_subset_ker : commutator G ≤ f.ker := by
  rw [commutator_eq_closure, Subgroup.closure_le]
  rintro x ⟨p, q, rfl⟩
  

Proof state:
case intro.intro
G : Type u
inst✝¹ : Group G
A : Type v
inst✝ : CommGroup A
f : G →* A
p q : G
⊢ ⁅p, q⁆ ∈ ↑(MonoidHom.ker f)

Next tactic:
simp [MonoidHom.mem_ker, mul_right_comm (f p) (f q), commutatorElement_def]
/-- Equivalent groups have equivalent abelianizations -/
def MulEquiv.abelianizationCongr : Abelianization G ≃* Abelianization H where
  toFun := Abelianization.map e.toMonoidHom
  invFun := Abelianization.map e.symm.toMonoidHom
  left_inv := by
    

Proof state:
G : Type u
inst✝² inst✝¹ : Group G
H : Type v
inst✝ : Group H
e : G ≃* H
⊢ Function.LeftInverse ⇑(Abelianization.map (toMonoidHom (symm e))) ⇑(Abelianization.map (toMonoidHom e))

Next tactic:
rintro ⟨a⟩
/-- Equivalent groups have equivalent abelianizations -/
def MulEquiv.abelianizationCongr : Abelianization G ≃* Abelianization H where
  toFun := Abelianization.map e.toMonoidHom
  invFun := Abelianization.map e.symm.toMonoidHom
  left_inv := by
    rintro ⟨a⟩
    

Proof state:
case mk
G : Type u
inst✝² inst✝¹ : Group G
H : Type v
inst✝ : Group H
e : G ≃* H
x✝ : Abelianization G
a : G
⊢ (Abelianization.map (toMonoidHom (symm e))) ((Abelianization.map (toMonoidHom e)) (Quot.mk Setoid.r a)) =
    Quot.mk Setoid.r a

Next tactic:
simp
/-- Equivalent groups have equivalent abelianizations -/
def MulEquiv.abelianizationCongr : Abelianization G ≃* Abelianization H where
  toFun := Abelianization.map e.toMonoidHom
  invFun := Abelianization.map e.symm.toMonoidHom
  left_inv := by
    rintro ⟨a⟩
    simp
  right_inv := by
    

Proof state:
G : Type u
inst✝² inst✝¹ : Group G
H : Type v
inst✝ : Group H
e : G ≃* H
⊢ Function.RightInverse ⇑(Abelianization.map (toMonoidHom (symm e))) ⇑(Abelianization.map (toMonoidHom e))

Next tactic:
rintro ⟨a⟩
/-- Equivalent groups have equivalent abelianizations -/
def MulEquiv.abelianizationCongr : Abelianization G ≃* Abelianization H where
  toFun := Abelianization.map e.toMonoidHom
  invFun := Abelianization.map e.symm.toMonoidHom
  left_inv := by
    rintro ⟨a⟩
    simp
  right_inv := by
    rintro ⟨a⟩
    

Proof state:
case mk
G : Type u
inst✝² inst✝¹ : Group G
H : Type v
inst✝ : Group H
e : G ≃* H
x✝ : Abelianization H
a : H
⊢ (Abelianization.map (toMonoidHom e)) ((Abelianization.map (toMonoidHom (symm e))) (Quot.mk Setoid.r a)) =
    Quot.mk Setoid.r a

Next tactic:
simp
/-- An Abelian group is equivalent to its own abelianization. -/
@[simps]
def Abelianization.equivOfComm {H : Type*} [CommGroup H] : H ≃* Abelianization H :=
  { Abelianization.of with
    toFun := Abelianization.of
    invFun := Abelianization.lift (MonoidHom.id H)
    left_inv := fun a => rfl
    right_inv := by
      

Proof state:
G : Type u
inst✝¹ : Group G
H : Type u_1
inst✝ : CommGroup H
src✝ : H →* Abelianization H := of
⊢ Function.RightInverse ⇑(lift (MonoidHom.id H)) ⇑of

Next tactic:
rintro ⟨a⟩
/-- An Abelian group is equivalent to its own abelianization. -/
@[simps]
def Abelianization.equivOfComm {H : Type*} [CommGroup H] : H ≃* Abelianization H :=
  { Abelianization.of with
    toFun := Abelianization.of
    invFun := Abelianization.lift (MonoidHom.id H)
    left_inv := fun a => rfl
    right_inv := by
      rintro ⟨a⟩
      

Proof state:
case mk
G : Type u
inst✝¹ : Group G
H : Type u_1
inst✝ : CommGroup H
src✝ : H →* Abelianization H := of
x✝ : Abelianization H
a : H
⊢ of ((lift (MonoidHom.id H)) (Quot.mk Setoid.r a)) = Quot.mk Setoid.r a

Next tactic:
rfl
theorem rank_closureCommutatorRepresentatives_le [Finite (commutatorSet G)] :
    Group.rank (closureCommutatorRepresentatives G) ≤ 2 * Nat.card (commutatorSet G) := by
  

Proof state:
G : Type u
inst✝¹ : Group G
inst✝ : Finite ↑(commutatorSet G)
⊢ Group.rank ↥(closureCommutatorRepresentatives G) ≤ 2 * Nat.card ↑(commutatorSet G)

Next tactic:
rw [two_mul]
theorem rank_closureCommutatorRepresentatives_le [Finite (commutatorSet G)] :
    Group.rank (closureCommutatorRepresentatives G) ≤ 2 * Nat.card (commutatorSet G) := by
  rw [two_mul]
  

Proof state:
G : Type u
inst✝¹ : Group G
inst✝ : Finite ↑(commutatorSet G)
⊢ Group.rank ↥(closureCommutatorRepresentatives G) ≤ Nat.card ↑(commutatorSet G) + Nat.card ↑(commutatorSet G)

Next tactic:
exact
    (Subgroup.rank_closure_finite_le_nat_card _).trans
      ((Set.card_union_le _ _).trans
        (add_le_add ((Finite.card_image_le _).trans (Finite.card_range_le _))
          ((Finite.card_image_le _).trans (Finite.card_range_le _))))
theorem image_commutatorSet_closureCommutatorRepresentatives :
    (closureCommutatorRepresentatives G).subtype ''
        commutatorSet (closureCommutatorRepresentatives G) =
      commutatorSet G := by
  

Proof state:
G : Type u
inst✝ : Group G
⊢ ⇑(Subgroup.subtype (closureCommutatorRepresentatives G)) '' commutatorSet ↥(closureCommutatorRepresentatives G) =
    commutatorSet G

Next tactic:
apply Set.Subset.antisymm
theorem image_commutatorSet_closureCommutatorRepresentatives :
    (closureCommutatorRepresentatives G).subtype ''
        commutatorSet (closureCommutatorRepresentatives G) =
      commutatorSet G := by
  apply Set.Subset.antisymm
  · 

Proof state:
case h₁
G : Type u
inst✝ : Group G
⊢ ⇑(Subgroup.subtype (closureCommutatorRepresentatives G)) '' commutatorSet ↥(closureCommutatorRepresentatives G) ⊆
    commutatorSet G

Next tactic:
rintro - ⟨-, ⟨g₁, g₂, rfl⟩, rfl⟩
theorem image_commutatorSet_closureCommutatorRepresentatives :
    (closureCommutatorRepresentatives G).subtype ''
        commutatorSet (closureCommutatorRepresentatives G) =
      commutatorSet G := by
  apply Set.Subset.antisymm
  · rintro - ⟨-, ⟨g₁, g₂, rfl⟩, rfl⟩
    

Proof state:
case h₁.intro.intro.intro.intro
G : Type u
inst✝ : Group G
g₁ g₂ : ↥(closureCommutatorRepresentatives G)
⊢ (Subgroup.subtype (closureCommutatorRepresentatives G)) ⁅g₁, g₂⁆ ∈ commutatorSet G

Next tactic:
exact ⟨g₁, g₂, rfl⟩
theorem image_commutatorSet_closureCommutatorRepresentatives :
    (closureCommutatorRepresentatives G).subtype ''
        commutatorSet (closureCommutatorRepresentatives G) =
      commutatorSet G := by
  apply Set.Subset.antisymm
  · rintro - ⟨-, ⟨g₁, g₂, rfl⟩, rfl⟩
    exact ⟨g₁, g₂, rfl⟩
  · 

Proof state:
case h₂
G : Type u
inst✝ : Group G
⊢ commutatorSet G ⊆
    ⇑(Subgroup.subtype (closureCommutatorRepresentatives G)) '' commutatorSet ↥(closureCommutatorRepresentatives G)

Next tactic:
exact fun g hg =>
      ⟨_,
        ⟨⟨_, subset_closure (Or.inl ⟨_, ⟨⟨g, hg⟩, rfl⟩, rfl⟩)⟩,
          ⟨_, subset_closure (Or.inr ⟨_, ⟨⟨g, hg⟩, rfl⟩, rfl⟩)⟩, rfl⟩,
        hg.choose_spec.choose_spec⟩
theorem card_commutatorSet_closureCommutatorRepresentatives :
    Nat.card (commutatorSet (closureCommutatorRepresentatives G)) = Nat.card (commutatorSet G) := by
  

Proof state:
G : Type u
inst✝ : Group G
⊢ Nat.card ↑(commutatorSet ↥(closureCommutatorRepresentatives G)) = Nat.card ↑(commutatorSet G)

Next tactic:
rw [← image_commutatorSet_closureCommutatorRepresentatives G]
theorem card_commutatorSet_closureCommutatorRepresentatives :
    Nat.card (commutatorSet (closureCommutatorRepresentatives G)) = Nat.card (commutatorSet G) := by
  rw [← image_commutatorSet_closureCommutatorRepresentatives G]
  

Proof state:
G : Type u
inst✝ : Group G
⊢ Nat.card ↑(commutatorSet ↥(closureCommutatorRepresentatives G)) =
    Nat.card
      ↑(⇑(Subgroup.subtype (closureCommutatorRepresentatives G)) '' commutatorSet ↥(closureCommutatorRepresentatives G))

Next tactic:
exact Nat.card_congr (Equiv.Set.image _ _ (subtype_injective _))
theorem card_commutator_closureCommutatorRepresentatives :
    Nat.card (commutator (closureCommutatorRepresentatives G)) = Nat.card (commutator G) := by
  

Proof state:
G : Type u
inst✝ : Group G
⊢ Nat.card ↥(_root_.commutator ↥(closureCommutatorRepresentatives G)) = Nat.card ↥(_root_.commutator G)

Next tactic:
rw [commutator_eq_closure G, ← image_commutatorSet_closureCommutatorRepresentatives, ←
    MonoidHom.map_closure, ← commutator_eq_closure]
theorem card_commutator_closureCommutatorRepresentatives :
    Nat.card (commutator (closureCommutatorRepresentatives G)) = Nat.card (commutator G) := by
  rw [commutator_eq_closure G, ← image_commutatorSet_closureCommutatorRepresentatives, ←
    MonoidHom.map_closure, ← commutator_eq_closure]
  

Proof state:
G : Type u
inst✝ : Group G
⊢ Nat.card ↥(_root_.commutator ↥(closureCommutatorRepresentatives G)) =
    Nat.card
      ↥(map (Subgroup.subtype (closureCommutatorRepresentatives G))
          (_root_.commutator ↥(closureCommutatorRepresentatives G)))

Next tactic:
exact Nat.card_congr (Equiv.Set.image _ _ (subtype_injective _))
instance [Finite (commutatorSet G)] :
    Finite (commutatorSet (closureCommutatorRepresentatives G)) := by
  

Proof state:
G : Type u
inst✝¹ : Group G
inst✝ : Finite ↑(commutatorSet G)
⊢ Finite ↑(commutatorSet ↥(closureCommutatorRepresentatives G))

Next tactic:
apply Nat.finite_of_card_ne_zero
instance [Finite (commutatorSet G)] :
    Finite (commutatorSet (closureCommutatorRepresentatives G)) := by
  apply Nat.finite_of_card_ne_zero
  

Proof state:
case h
G : Type u
inst✝¹ : Group G
inst✝ : Finite ↑(commutatorSet G)
⊢ Nat.card ↑(commutatorSet ↥(closureCommutatorRepresentatives G)) ≠ 0

Next tactic:
rw [card_commutatorSet_closureCommutatorRepresentatives]
instance [Finite (commutatorSet G)] :
    Finite (commutatorSet (closureCommutatorRepresentatives G)) := by
  apply Nat.finite_of_card_ne_zero
  rw [card_commutatorSet_closureCommutatorRepresentatives]
  

Proof state:
case h
G : Type u
inst✝¹ : Group G
inst✝ : Finite ↑(commutatorSet G)
⊢ Nat.card ↑(commutatorSet G) ≠ 0

Next tactic:
exact Finite.card_pos.ne'
instance : LieRing (CommutatorRing L) := show LieRing L by 

Proof state:
R : Type u
L : Type v
inst✝² : CommRing R
inst✝¹ : LieRing L
inst✝ : LieAlgebra R L
⊢ LieRing L

Next tactic:
infer_instance
instance : LieAlgebra R (CommutatorRing L) := show LieAlgebra R L by 

Proof state:
R : Type u
L : Type v
inst✝² : CommRing R
inst✝¹ : LieRing L
inst✝ : LieAlgebra R L
⊢ LieAlgebra R L

Next tactic:
infer_instance
instance CompHausToLocale.faithful : Faithful (compHausToTop ⋙ topToLocale.{u}) :=
  ⟨fun h => by
    

Proof state:
X✝ Y✝ : CompHaus
a₁✝ a₂✝ : X✝ ⟶ Y✝
h : (compHausToTop ⋙ topToLocale).map a₁✝ = (compHausToTop ⋙ topToLocale).map a₂✝
⊢ a₁✝ = a₂✝

Next tactic:
dsimp at h