l3lab/ntp-mathlib huggingface dataset:
@[to_additive (attr := simp)]
theorem mulSingle_mem_pi [DecidableEq η] {I : Set η} {H : ∀ i, Subgroup (f i)} (i : η) (x : f i) :
    Pi.mulSingle i x ∈ pi I H ↔ i ∈ I → x ∈ H i := by
  constructor
  · intro h hi
    simpa using h i hi
  · intro h j hj
    by_cases heq : j = i
    · subst heq
      simpa using h hj
    · 

Proof state:
case neg
G : Type u_1
G' : Type u_2
G'' : Type u_3
inst✝⁷ : Group G
inst✝⁶ : Group G'
inst✝⁵ : Group G''
A : Type u_4
inst✝⁴ : AddGroup A
H✝ K : Subgroup G
k : Set G
N : Type u_5
inst✝³ : Group N
P : Type u_6
inst✝² : Group P
η : Type u_7
f : η → Type u_8
inst✝¹ : (i : η) → Group (f i)
inst✝ : DecidableEq η
I : Set η
H : (i : η) → Subgroup (f i)
i : η
x : f i
h : i ∈ I → x ∈ H i
j : η
hj : j ∈ I
heq : ¬j = i
⊢ Pi.mulSingle i x j ∈ (fun i => ((fun i => (H i).toSubmonoid) i).carrier) j

Next tactic:
simp [heq, one_mem]
@[to_additive]
theorem pi_eq_bot_iff (H : ∀ i, Subgroup (f i)) : pi Set.univ H = ⊥ ↔ ∀ i, H i = ⊥ := by
  

Proof state:
G : Type u_1
G' : Type u_2
G'' : Type u_3
inst✝⁶ : Group G
inst✝⁵ : Group G'
inst✝⁴ : Group G''
A : Type u_4
inst✝³ : AddGroup A
H✝ K : Subgroup G
k : Set G
N : Type u_5
inst✝² : Group N
P : Type u_6
inst✝¹ : Group P
η : Type u_7
f : η → Type u_8
inst✝ : (i : η) → Group (f i)
H : (i : η) → Subgroup (f i)
⊢ pi univ H = ⊥ ↔ ∀ (i : η), H i = ⊥

Next tactic:
classical
    simp only [eq_bot_iff_forall]
    constructor
    · intro h i x hx
      have : MonoidHom.single f i x = 1 :=
        h (MonoidHom.single f i x) ((mulSingle_mem_pi i x).mpr fun _ => hx)
      simpa using congr_fun this i
    · exact fun h x hx => funext fun i => h _ _ (hx i trivial)
@[to_additive]
theorem pi_eq_bot_iff (H : ∀ i, Subgroup (f i)) : pi Set.univ H = ⊥ ↔ ∀ i, H i = ⊥ := by
  classical
    

Proof state:
G : Type u_1
G' : Type u_2
G'' : Type u_3
inst✝⁶ : Group G
inst✝⁵ : Group G'
inst✝⁴ : Group G''
A : Type u_4
inst✝³ : AddGroup A
H✝ K : Subgroup G
k : Set G
N : Type u_5
inst✝² : Group N
P : Type u_6
inst✝¹ : Group P
η : Type u_7
f : η → Type u_8
inst✝ : (i : η) → Group (f i)
H : (i : η) → Subgroup (f i)
⊢ pi univ H = ⊥ ↔ ∀ (i : η), H i = ⊥

Next tactic:
simp only [eq_bot_iff_forall]
@[to_additive]
theorem pi_eq_bot_iff (H : ∀ i, Subgroup (f i)) : pi Set.univ H = ⊥ ↔ ∀ i, H i = ⊥ := by
  classical
    simp only [eq_bot_iff_forall]
    

Proof state:
G : Type u_1
G' : Type u_2
G'' : Type u_3
inst✝⁶ : Group G
inst✝⁵ : Group G'
inst✝⁴ : Group G''
A : Type u_4
inst✝³ : AddGroup A
H✝ K : Subgroup G
k : Set G
N : Type u_5
inst✝² : Group N
P : Type u_6
inst✝¹ : Group P
η : Type u_7
f : η → Type u_8
inst✝ : (i : η) → Group (f i)
H : (i : η) → Subgroup (f i)
⊢ (∀ x ∈ pi univ H, x = 1) ↔ ∀ (i : η), ∀ x ∈ H i, x = 1

Next tactic:
constructor
@[to_additive]
theorem pi_eq_bot_iff (H : ∀ i, Subgroup (f i)) : pi Set.univ H = ⊥ ↔ ∀ i, H i = ⊥ := by
  classical
    simp only [eq_bot_iff_forall]
    constructor
    · 

Proof state:
case mp
G : Type u_1
G' : Type u_2
G'' : Type u_3
inst✝⁶ : Group G
inst✝⁵ : Group G'
inst✝⁴ : Group G''
A : Type u_4
inst✝³ : AddGroup A
H✝ K : Subgroup G
k : Set G
N : Type u_5
inst✝² : Group N
P : Type u_6
inst✝¹ : Group P
η : Type u_7
f : η → Type u_8
inst✝ : (i : η) → Group (f i)
H : (i : η) → Subgroup (f i)
⊢ (∀ x ∈ pi univ H, x = 1) → ∀ (i : η), ∀ x ∈ H i, x = 1

Next tactic:
intro h i x hx
@[to_additive]
theorem pi_eq_bot_iff (H : ∀ i, Subgroup (f i)) : pi Set.univ H = ⊥ ↔ ∀ i, H i = ⊥ := by
  classical
    simp only [eq_bot_iff_forall]
    constructor
    · intro h i x hx
      

Proof state:
case mp
G : Type u_1
G' : Type u_2
G'' : Type u_3
inst✝⁶ : Group G
inst✝⁵ : Group G'
inst✝⁴ : Group G''
A : Type u_4
inst✝³ : AddGroup A
H✝ K : Subgroup G
k : Set G
N : Type u_5
inst✝² : Group N
P : Type u_6
inst✝¹ : Group P
η : Type u_7
f : η → Type u_8
inst✝ : (i : η) → Group (f i)
H : (i : η) → Subgroup (f i)
h : ∀ x ∈ pi univ H, x = 1
i : η
x : f i
hx : x ∈ H i
⊢ x = 1

Next tactic:
have : MonoidHom.single f i x = 1 :=
        h (MonoidHom.single f i x) ((mulSingle_mem_pi i x).mpr fun _ => hx)
@[to_additive]
theorem pi_eq_bot_iff (H : ∀ i, Subgroup (f i)) : pi Set.univ H = ⊥ ↔ ∀ i, H i = ⊥ := by
  classical
    simp only [eq_bot_iff_forall]
    constructor
    · intro h i x hx
      have : MonoidHom.single f i x = 1 :=
        h (MonoidHom.single f i x) ((mulSingle_mem_pi i x).mpr fun _ => hx)
      

Proof state:
case mp
G : Type u_1
G' : Type u_2
G'' : Type u_3
inst✝⁶ : Group G
inst✝⁵ : Group G'
inst✝⁴ : Group G''
A : Type u_4
inst✝³ : AddGroup A
H✝ K : Subgroup G
k : Set G
N : Type u_5
inst✝² : Group N
P : Type u_6
inst✝¹ : Group P
η : Type u_7
f : η → Type u_8
inst✝ : (i : η) → Group (f i)
H : (i : η) → Subgroup (f i)
h : ∀ x ∈ pi univ H, x = 1
i : η
x : f i
hx : x ∈ H i
this : (MonoidHom.single f i) x = 1
⊢ x = 1

Next tactic:
simpa using congr_fun this i
@[to_additive]
theorem pi_eq_bot_iff (H : ∀ i, Subgroup (f i)) : pi Set.univ H = ⊥ ↔ ∀ i, H i = ⊥ := by
  classical
    simp only [eq_bot_iff_forall]
    constructor
    · intro h i x hx
      have : MonoidHom.single f i x = 1 :=
        h (MonoidHom.single f i x) ((mulSingle_mem_pi i x).mpr fun _ => hx)
      simpa using congr_fun this i
    · 

Proof state:
case mpr
G : Type u_1
G' : Type u_2
G'' : Type u_3
inst✝⁶ : Group G
inst✝⁵ : Group G'
inst✝⁴ : Group G''
A : Type u_4
inst✝³ : AddGroup A
H✝ K : Subgroup G
k : Set G
N : Type u_5
inst✝² : Group N
P : Type u_6
inst✝¹ : Group P
η : Type u_7
f : η → Type u_8
inst✝ : (i : η) → Group (f i)
H : (i : η) → Subgroup (f i)
⊢ (∀ (i : η), ∀ x ∈ H i, x = 1) → ∀ x ∈ pi univ H, x = 1

Next tactic:
exact fun h x hx => funext fun i => h _ _ (hx i trivial)
@[to_additive]
instance (priority := 100) normal_of_comm {G : Type*} [CommGroup G] (H : Subgroup G) : H.Normal :=
  ⟨by 

Proof state:
G✝ : Type u_1
G' : Type u_2
G'' : Type u_3
inst✝⁴ : Group G✝
inst✝³ : Group G'
inst✝² : Group G''
A : Type u_4
inst✝¹ : AddGroup A
H✝ K : Subgroup G✝
G : Type u_5
inst✝ : CommGroup G
H : Subgroup G
⊢ ∀ n ∈ H, ∀ (g : G), g * n * g⁻¹ ∈ H

Next tactic:
simp [mul_comm, mul_left_comm]
@[to_additive]
theorem mem_comm {a b : G} (h : a * b ∈ H) : b * a ∈ H := by
  

Proof state:
G : Type u_1
G' : Type u_2
G'' : Type u_3
inst✝³ : Group G
inst✝² : Group G'
inst✝¹ : Group G''
A : Type u_4
inst✝ : AddGroup A
H K : Subgroup G
nH : Normal H
a b : G
h : a * b ∈ H
⊢ b * a ∈ H

Next tactic:
have : a⁻¹ * (a * b) * a⁻¹⁻¹ ∈ H := nH.conj_mem (a * b) h a⁻¹
@[to_additive]
theorem mem_comm {a b : G} (h : a * b ∈ H) : b * a ∈ H := by
  have : a⁻¹ * (a * b) * a⁻¹⁻¹ ∈ H := nH.conj_mem (a * b) h a⁻¹
  -- Porting note: Previous code was:
  -- simpa
  

Proof state:
G : Type u_1
G' : Type u_2
G'' : Type u_3
inst✝³ : Group G
inst✝² : Group G'
inst✝¹ : Group G''
A : Type u_4
inst✝ : AddGroup A
H K : Subgroup G
nH : Normal H
a b : G
h : a * b ∈ H
this : a⁻¹ * (a * b) * a⁻¹⁻¹ ∈ H
⊢ b * a ∈ H

Next tactic:
simp_all only [inv_mul_cancel_left, inv_inv]
@[to_additive]
theorem characteristic_iff_map_eq : H.Characteristic ↔ ∀ ϕ : G ≃* G, H.map ϕ.toMonoidHom = H := by
  

Proof state:
G : Type u_1
G' : Type u_2
G'' : Type u_3
inst✝³ : Group G
inst✝² : Group G'
inst✝¹ : Group G''
A : Type u_4
inst✝ : AddGroup A
H K : Subgroup G
⊢ Characteristic H ↔ ∀ (ϕ : G ≃* G), map (MulEquiv.toMonoidHom ϕ) H = H

Next tactic:
simp_rw [map_equiv_eq_comap_symm]
@[to_additive]
theorem characteristic_iff_map_eq : H.Characteristic ↔ ∀ ϕ : G ≃* G, H.map ϕ.toMonoidHom = H := by
  simp_rw [map_equiv_eq_comap_symm]
  

Proof state:
G : Type u_1
G' : Type u_2
G'' : Type u_3
inst✝³ : Group G
inst✝² : Group G'
inst✝¹ : Group G''
A : Type u_4
inst✝ : AddGroup A
H K : Subgroup G
⊢ Characteristic H ↔ ∀ (ϕ : G ≃* G), comap (MulEquiv.toMonoidHom (MulEquiv.symm ϕ)) H = H

Next tactic:
exact characteristic_iff_comap_eq.trans ⟨fun h ϕ => h ϕ.symm, fun h ϕ => h ϕ.symm⟩
@[to_additive]
theorem characteristic_iff_map_le : H.Characteristic ↔ ∀ ϕ : G ≃* G, H.map ϕ.toMonoidHom ≤ H := by
  

Proof state:
G : Type u_1
G' : Type u_2
G'' : Type u_3
inst✝³ : Group G
inst✝² : Group G'
inst✝¹ : Group G''
A : Type u_4
inst✝ : AddGroup A
H K : Subgroup G
⊢ Characteristic H ↔ ∀ (ϕ : G ≃* G), map (MulEquiv.toMonoidHom ϕ) H ≤ H

Next tactic:
simp_rw [map_equiv_eq_comap_symm]
@[to_additive]
theorem characteristic_iff_map_le : H.Characteristic ↔ ∀ ϕ : G ≃* G, H.map ϕ.toMonoidHom ≤ H := by
  simp_rw [map_equiv_eq_comap_symm]
  

Proof state:
G : Type u_1
G' : Type u_2
G'' : Type u_3
inst✝³ : Group G
inst✝² : Group G'
inst✝¹ : Group G''
A : Type u_4
inst✝ : AddGroup A
H K : Subgroup G
⊢ Characteristic H ↔ ∀ (ϕ : G ≃* G), comap (MulEquiv.toMonoidHom (MulEquiv.symm ϕ)) H ≤ H

Next tactic:
exact characteristic_iff_comap_le.trans ⟨fun h ϕ => h ϕ.symm, fun h ϕ => h ϕ.symm⟩
@[to_additive]
theorem characteristic_iff_le_map : H.Characteristic ↔ ∀ ϕ : G ≃* G, H ≤ H.map ϕ.toMonoidHom := by
  

Proof state:
G : Type u_1
G' : Type u_2
G'' : Type u_3
inst✝³ : Group G
inst✝² : Group G'
inst✝¹ : Group G''
A : Type u_4
inst✝ : AddGroup A
H K : Subgroup G
⊢ Characteristic H ↔ ∀ (ϕ : G ≃* G), H ≤ map (MulEquiv.toMonoidHom ϕ) H

Next tactic:
simp_rw [map_equiv_eq_comap_symm]
@[to_additive]
theorem characteristic_iff_le_map : H.Characteristic ↔ ∀ ϕ : G ≃* G, H ≤ H.map ϕ.toMonoidHom := by
  simp_rw [map_equiv_eq_comap_symm]
  

Proof state:
G : Type u_1
G' : Type u_2
G'' : Type u_3
inst✝³ : Group G
inst✝² : Group G'
inst✝¹ : Group G''
A : Type u_4
inst✝ : AddGroup A
H K : Subgroup G
⊢ Characteristic H ↔ ∀ (ϕ : G ≃* G), H ≤ comap (MulEquiv.toMonoidHom (MulEquiv.symm ϕ)) H

Next tactic:
exact characteristic_iff_le_comap.trans ⟨fun h ϕ => h ϕ.symm, fun h ϕ => h ϕ.symm⟩
/-- For a group with zero, the center of the units is the same as the units of the center. -/
@[simps! apply_val_coe symm_apply_coe_val]
def centerUnitsEquivUnitsCenter (G₀ : Type*) [GroupWithZero G₀] :
    Subgroup.center (G₀ˣ) ≃* (Submonoid.center G₀)ˣ where
  toFun := MonoidHom.toHomUnits <|
    { toFun := fun u ↦ ⟨(u : G₀ˣ),
      (Submonoid.mem_center_iff.mpr (fun r ↦ by
          

Proof state:
G : Type u_1
G' : Type u_2
G'' : Type u_3
inst✝⁴ : Group G
inst✝³ : Group G'
inst✝² : Group G''
A : Type u_4
inst✝¹ : AddGroup A
H K : Subgroup G
G₀ : Type u_5
inst✝ : GroupWithZero G₀
u : ↥(center G₀ˣ)
r : G₀
⊢ r * ↑↑u = ↑↑u * r

Next tactic:
rcases eq_or_ne r 0 with (rfl | hr)
/-- For a group with zero, the center of the units is the same as the units of the center. -/
@[simps! apply_val_coe symm_apply_coe_val]
def centerUnitsEquivUnitsCenter (G₀ : Type*) [GroupWithZero G₀] :
    Subgroup.center (G₀ˣ) ≃* (Submonoid.center G₀)ˣ where
  toFun := MonoidHom.toHomUnits <|
    { toFun := fun u ↦ ⟨(u : G₀ˣ),
      (Submonoid.mem_center_iff.mpr (fun r ↦ by
          rcases eq_or_ne r 0 with (rfl | hr)
          · 

Proof state:
case inl
G : Type u_1
G' : Type u_2
G'' : Type u_3
inst✝⁴ : Group G
inst✝³ : Group G'
inst✝² : Group G''
A : Type u_4
inst✝¹ : AddGroup A
H K : Subgroup G
G₀ : Type u_5
inst✝ : GroupWithZero G₀
u : ↥(center G₀ˣ)
⊢ 0 * ↑↑u = ↑↑u * 0

Next tactic:
rw [mul_zero, zero_mul]
/-- For a group with zero, the center of the units is the same as the units of the center. -/
@[simps! apply_val_coe symm_apply_coe_val]
def centerUnitsEquivUnitsCenter (G₀ : Type*) [GroupWithZero G₀] :
    Subgroup.center (G₀ˣ) ≃* (Submonoid.center G₀)ˣ where
  toFun := MonoidHom.toHomUnits <|
    { toFun := fun u ↦ ⟨(u : G₀ˣ),
      (Submonoid.mem_center_iff.mpr (fun r ↦ by
          rcases eq_or_ne r 0 with (rfl | hr)
          · rw [mul_zero, zero_mul]
          

Proof state:
case inr
G : Type u_1
G' : Type u_2
G'' : Type u_3
inst✝⁴ : Group G
inst✝³ : Group G'
inst✝² : Group G''
A : Type u_4
inst✝¹ : AddGroup A
H K : Subgroup G
G₀ : Type u_5
inst✝ : GroupWithZero G₀
u : ↥(center G₀ˣ)
r : G₀
hr : r ≠ 0
⊢ r * ↑↑u = ↑↑u * r

Next tactic:
exact congrArg Units.val <| (u.2.comm <| Units.mk0 r hr).symm
/-- For a group with zero, the center of the units is the same as the units of the center. -/
@[simps! apply_val_coe symm_apply_coe_val]
def centerUnitsEquivUnitsCenter (G₀ : Type*) [GroupWithZero G₀] :
    Subgroup.center (G₀ˣ) ≃* (Submonoid.center G₀)ˣ where
  toFun := MonoidHom.toHomUnits <|
    { toFun := fun u ↦ ⟨(u : G₀ˣ),
      (Submonoid.mem_center_iff.mpr (fun r ↦ by
          rcases eq_or_ne r 0 with (rfl | hr)
          · rw [mul_zero, zero_mul]
          exact congrArg Units.val <| (u.2.comm <| Units.mk0 r hr).symm))⟩
      map_one' := rfl
      map_mul' := fun _ _ ↦ rfl }
  invFun u := unitsCenterToCenterUnits G₀ u
  left_inv _ := by 

Proof state:
G : Type u_1
G' : Type u_2
G'' : Type u_3
inst✝⁴ : Group G
inst✝³ : Group G'
inst✝² : Group G''
A : Type u_4
inst✝¹ : AddGroup A
H K : Subgroup G
G₀ : Type u_5
inst✝ : GroupWithZero G₀
x✝ : ↥(center G₀ˣ)
⊢ (fun u => (unitsCenterToCenterUnits G₀) u)
      ((MonoidHom.toHomUnits
          {
            toOneHom :=
              { toFun := fun u => { val := ↑↑u, property := (_ : ↑↑u ∈ Submonoid.center G₀) }, map_one' := ?m.311616 },
            map_mul' :=
              (_ :
                ∀ (x x_1 : ↥(center G₀ˣ)),
                  OneHom.toFun { toFun := fun u => ?m.311581 u, map_one' := ?m.311616 } (x * x_1) =
                    OneHom.toFun { toFun := fun u => ?m.311581 u, map_one' := ?m.311616 } x *
                      OneHom.toFun { toFun := fun u => ?m.311581 u, map_one' := ?m.311616 } x_1) })
        x✝) =
    x✝

Next tactic:
ext
/-- For a group with zero, the center of the units is the same as the units of the center. -/
@[simps! apply_val_coe symm_apply_coe_val]
def centerUnitsEquivUnitsCenter (G₀ : Type*) [GroupWithZero G₀] :
    Subgroup.center (G₀ˣ) ≃* (Submonoid.center G₀)ˣ where
  toFun := MonoidHom.toHomUnits <|
    { toFun := fun u ↦ ⟨(u : G₀ˣ),
      (Submonoid.mem_center_iff.mpr (fun r ↦ by
          rcases eq_or_ne r 0 with (rfl | hr)
          · rw [mul_zero, zero_mul]
          exact congrArg Units.val <| (u.2.comm <| Units.mk0 r hr).symm))⟩
      map_one' := rfl
      map_mul' := fun _ _ ↦ rfl }
  invFun u := unitsCenterToCenterUnits G₀ u
  left_inv _ := by ext; 

Proof state:
case a.a
G : Type u_1
G' : Type u_2
G'' : Type u_3
inst✝⁴ : Group G
inst✝³ : Group G'
inst✝² : Group G''
A : Type u_4
inst✝¹ : AddGroup A
H K : Subgroup G
G₀ : Type u_5
inst✝ : GroupWithZero G₀
x✝ : ↥(center G₀ˣ)
⊢ ↑↑((fun u => (unitsCenterToCenterUnits G₀) u)
          ((MonoidHom.toHomUnits
              {
                toOneHom :=
                  { toFun := fun u => { val := ↑↑u, property := (_ : ↑↑u ∈ Submonoid.center G₀) },
                    map_one' := ?m.311616 },
                map_mul' :=
                  (_ :
                    ∀ (x x_1 : ↥(center G₀ˣ)),
                      OneHom.toFun { toFun := fun u => ?m.311581 u, map_one' := ?m.311616 } (x * x_1) =
                        OneHom.toFun { toFun := fun u => ?m.311581 u, map_one' := ?m.311616 } x *
                          OneHom.toFun { toFun := fun u => ?m.311581 u, map_one' := ?m.311616 } x_1) })
            x✝)) =
    ↑↑x✝

Next tactic:
rfl
/-- For a group with zero, the center of the units is the same as the units of the center. -/
@[simps! apply_val_coe symm_apply_coe_val]
def centerUnitsEquivUnitsCenter (G₀ : Type*) [GroupWithZero G₀] :
    Subgroup.center (G₀ˣ) ≃* (Submonoid.center G₀)ˣ where
  toFun := MonoidHom.toHomUnits <|
    { toFun := fun u ↦ ⟨(u : G₀ˣ),
      (Submonoid.mem_center_iff.mpr (fun r ↦ by
          rcases eq_or_ne r 0 with (rfl | hr)
          · rw [mul_zero, zero_mul]
          exact congrArg Units.val <| (u.2.comm <| Units.mk0 r hr).symm))⟩
      map_one' := rfl
      map_mul' := fun _ _ ↦ rfl }
  invFun u := unitsCenterToCenterUnits G₀ u
  left_inv _ := by ext; rfl
  right_inv _ := by 

Proof state:
G : Type u_1
G' : Type u_2
G'' : Type u_3
inst✝⁴ : Group G
inst✝³ : Group G'
inst✝² : Group G''
A : Type u_4
inst✝¹ : AddGroup A
H K : Subgroup G
G₀ : Type u_5
inst✝ : GroupWithZero G₀
x✝ : (↥(Submonoid.center G₀))ˣ
⊢ (MonoidHom.toHomUnits
        {
          toOneHom :=
            { toFun := fun u => { val := ↑↑u, property := (_ : ↑↑u ∈ Submonoid.center G₀) }, map_one' := ?m.311616 },
          map_mul' :=
            (_ :
              ∀ (x x_1 : ↥(center G₀ˣ)),
                OneHom.toFun { toFun := fun u => ?m.311581 u, map_one' := ?m.311616 } (x * x_1) =
                  OneHom.toFun { toFun := fun u => ?m.311581 u, map_one' := ?m.311616 } x *
                    OneHom.toFun { toFun := fun u => ?m.311581 u, map_one' := ?m.311616 } x_1) })
      ((fun u => (unitsCenterToCenterUnits G₀) u) x✝) =
    x✝

Next tactic:
ext
/-- For a group with zero, the center of the units is the same as the units of the center. -/
@[simps! apply_val_coe symm_apply_coe_val]
def centerUnitsEquivUnitsCenter (G₀ : Type*) [GroupWithZero G₀] :
    Subgroup.center (G₀ˣ) ≃* (Submonoid.center G₀)ˣ where
  toFun := MonoidHom.toHomUnits <|
    { toFun := fun u ↦ ⟨(u : G₀ˣ),
      (Submonoid.mem_center_iff.mpr (fun r ↦ by
          rcases eq_or_ne r 0 with (rfl | hr)
          · rw [mul_zero, zero_mul]
          exact congrArg Units.val <| (u.2.comm <| Units.mk0 r hr).symm))⟩
      map_one' := rfl
      map_mul' := fun _ _ ↦ rfl }
  invFun u := unitsCenterToCenterUnits G₀ u
  left_inv _ := by ext; rfl
  right_inv _ := by ext; 

Proof state:
case a.a
G : Type u_1
G' : Type u_2
G'' : Type u_3
inst✝⁴ : Group G
inst✝³ : Group G'
inst✝² : Group G''
A : Type u_4
inst✝¹ : AddGroup A
H K : Subgroup G
G₀ : Type u_5
inst✝ : GroupWithZero G₀
x✝ : (↥(Submonoid.center G₀))ˣ
⊢ ↑↑((MonoidHom.toHomUnits
            {
              toOneHom :=
                { toFun := fun u => { val := ↑↑u, property := (_ : ↑↑u ∈ Submonoid.center G₀) },
                  map_one' := ?m.311616 },
              map_mul' :=
                (_ :
                  ∀ (x x_1 : ↥(center G₀ˣ)),
                    OneHom.toFun { toFun := fun u => ?m.311581 u, map_one' := ?m.311616 } (x * x_1) =
                      OneHom.toFun { toFun := fun u => ?m.311581 u, map_one' := ?m.311616 } x *
                        OneHom.toFun { toFun := fun u => ?m.311581 u, map_one' := ?m.311616 } x_1) })
          ((fun u => (unitsCenterToCenterUnits G₀) u) x✝)) =
    ↑↑x✝

Next tactic:
rfl
@[to_additive]
theorem mem_center_iff {z : G} : z ∈ center G ↔ ∀ g, g * z = z * g := by
  

Proof state:
G : Type u_1
G' : Type u_2
G'' : Type u_3
inst✝³ : Group G
inst✝² : Group G'
inst✝¹ : Group G''
A : Type u_4
inst✝ : AddGroup A
H K : Subgroup G
z : G
⊢ z ∈ center G ↔ ∀ (g : G), g * z = z * g

Next tactic:
rw [← Semigroup.mem_center_iff]
@[to_additive]
theorem mem_center_iff {z : G} : z ∈ center G ↔ ∀ g, g * z = z * g := by
  rw [← Semigroup.mem_center_iff]
  

Proof state:
G : Type u_1
G' : Type u_2
G'' : Type u_3
inst✝³ : Group G
inst✝² : Group G'
inst✝¹ : Group G''
A : Type u_4
inst✝ : AddGroup A
H K : Subgroup G
z : G
⊢ z ∈ center G ↔ z ∈ Set.center G

Next tactic:
exact Iff.rfl
@[to_additive]
instance centerCharacteristic : (center G).Characteristic := by
  

Proof state:
G : Type u_1
G' : Type u_2
G'' : Type u_3
inst✝³ : Group G
inst✝² : Group G'
inst✝¹ : Group G''
A : Type u_4
inst✝ : AddGroup A
H K : Subgroup G
⊢ Characteristic (center G)

Next tactic:
refine' characteristic_iff_comap_le.mpr fun ϕ g hg => _
@[to_additive]
instance centerCharacteristic : (center G).Characteristic := by
  refine' characteristic_iff_comap_le.mpr fun ϕ g hg => _
  

Proof state:
G : Type u_1
G' : Type u_2
G'' : Type u_3
inst✝³ : Group G
inst✝² : Group G'
inst✝¹ : Group G''
A : Type u_4
inst✝ : AddGroup A
H K : Subgroup G
ϕ : G ≃* G
g : G
hg : g ∈ comap (MulEquiv.toMonoidHom ϕ) (center G)
⊢ g ∈ center G

Next tactic:
rw [mem_center_iff]
@[to_additive]
instance centerCharacteristic : (center G).Characteristic := by
  refine' characteristic_iff_comap_le.mpr fun ϕ g hg => _
  rw [mem_center_iff]
  

Proof state:
G : Type u_1
G' : Type u_2
G'' : Type u_3
inst✝³ : Group G
inst✝² : Group G'
inst✝¹ : Group G''
A : Type u_4
inst✝ : AddGroup A
H K : Subgroup G
ϕ : G ≃* G
g : G
hg : g ∈ comap (MulEquiv.toMonoidHom ϕ) (center G)
⊢ ∀ (g_1 : G), g_1 * g = g * g_1

Next tactic:
intro h
@[to_additive]
instance centerCharacteristic : (center G).Characteristic := by
  refine' characteristic_iff_comap_le.mpr fun ϕ g hg => _
  rw [mem_center_iff]
  intro h
  

Proof state:
G : Type u_1
G' : Type u_2
G'' : Type u_3
inst✝³ : Group G
inst✝² : Group G'
inst✝¹ : Group G''
A : Type u_4
inst✝ : AddGroup A
H K : Subgroup G
ϕ : G ≃* G
g : G
hg : g ∈ comap (MulEquiv.toMonoidHom ϕ) (center G)
h : G
⊢ h * g = g * h

Next tactic:
rw [← ϕ.injective.eq_iff, ϕ.map_mul, ϕ.map_mul]
@[to_additive]
instance centerCharacteristic : (center G).Characteristic := by
  refine' characteristic_iff_comap_le.mpr fun ϕ g hg => _
  rw [mem_center_iff]
  intro h
  rw [← ϕ.injective.eq_iff, ϕ.map_mul, ϕ.map_mul]
  

Proof state:
G : Type u_1
G' : Type u_2
G'' : Type u_3
inst✝³ : Group G
inst✝² : Group G'
inst✝¹ : Group G''
A : Type u_4
inst✝ : AddGroup A
H K : Subgroup G
ϕ : G ≃* G
g : G
hg : g ∈ comap (MulEquiv.toMonoidHom ϕ) (center G)
h : G
⊢ ϕ h * ϕ g = ϕ g * ϕ h

Next tactic:
exact (hg.comm (ϕ h)).symm
theorem _root_.CommGroup.center_eq_top {G : Type*} [CommGroup G] : center G = ⊤ := by
  

Proof state:
G✝ : Type u_1
G' : Type u_2
G'' : Type u_3
inst✝⁴ : Group G✝
inst✝³ : Group G'
inst✝² : Group G''
A : Type u_4
inst✝¹ : AddGroup A
H K : Subgroup G✝
G : Type u_5
inst✝ : CommGroup G
⊢ center G = ⊤

Next tactic:
rw [eq_top_iff']
theorem _root_.CommGroup.center_eq_top {G : Type*} [CommGroup G] : center G = ⊤ := by
  rw [eq_top_iff']
  

Proof state:
G✝ : Type u_1
G' : Type u_2
G'' : Type u_3
inst✝⁴ : Group G✝
inst✝³ : Group G'
inst✝² : Group G''
A : Type u_4
inst✝¹ : AddGroup A
H K : Subgroup G✝
G : Type u_5
inst✝ : CommGroup G
⊢ ∀ (x : G), x ∈ center G

Next tactic:
intro x
theorem _root_.CommGroup.center_eq_top {G : Type*} [CommGroup G] : center G = ⊤ := by
  rw [eq_top_iff']
  intro x
  

Proof state:
G✝ : Type u_1
G' : Type u_2
G'' : Type u_3
inst✝⁴ : Group G✝
inst✝³ : Group G'
inst✝² : Group G''
A : Type u_4
inst✝¹ : AddGroup A
H K : Subgroup G✝
G : Type u_5
inst✝ : CommGroup G
x : G
⊢ x ∈ center G

Next tactic:
rw [Subgroup.mem_center_iff]
theorem _root_.CommGroup.center_eq_top {G : Type*} [CommGroup G] : center G = ⊤ := by
  rw [eq_top_iff']
  intro x
  rw [Subgroup.mem_center_iff]
  

Proof state:
G✝ : Type u_1
G' : Type u_2
G'' : Type u_3
inst✝⁴ : Group G✝
inst✝³ : Group G'
inst✝² : Group G''
A : Type u_4
inst✝¹ : AddGroup A
H K : Subgroup G✝
G : Type u_5
inst✝ : CommGroup G
x : G
⊢ ∀ (g : G), g * x = x * g

Next tactic:
intro y
theorem _root_.CommGroup.center_eq_top {G : Type*} [CommGroup G] : center G = ⊤ := by
  rw [eq_top_iff']
  intro x
  rw [Subgroup.mem_center_iff]
  intro y
  

Proof state:
G✝ : Type u_1
G' : Type u_2
G'' : Type u_3
inst✝⁴ : Group G✝
inst✝³ : Group G'
inst✝² : Group G''
A : Type u_4
inst✝¹ : AddGroup A
H K : Subgroup G✝
G : Type u_5
inst✝ : CommGroup G
x y : G
⊢ y * x = x * y

Next tactic:
exact mul_comm y x
/-- A group is commutative if the center is the whole group -/
def _root_.Group.commGroupOfCenterEqTop (h : center G = ⊤) : CommGroup G :=
  { (_ : Group G) with
    mul_comm := by
      

Proof state:
G : Type u_1
G' : Type u_2
G'' : Type u_3
inst✝³ : Group G
inst✝² : Group G'
inst✝¹ : Group G''
A : Type u_4
inst✝ : AddGroup A
H K : Subgroup G
h : center G = ⊤
src✝ : Group G := ?m.321619 h
⊢ ∀ (a b : G), a * b = b * a

Next tactic:
rw [eq_top_iff'] at h
/-- A group is commutative if the center is the whole group -/
def _root_.Group.commGroupOfCenterEqTop (h : center G = ⊤) : CommGroup G :=
  { (_ : Group G) with
    mul_comm := by
      rw [eq_top_iff'] at h
      

Proof state:
G : Type u_1
G' : Type u_2
G'' : Type u_3
inst✝³ : Group G
inst✝² : Group G'
inst✝¹ : Group G''
A : Type u_4
inst✝ : AddGroup A
H K : Subgroup G
h : ∀ (x : G), x ∈ center G
src✝ : Group G := inst✝³
⊢ ∀ (a b : G), a * b = b * a

Next tactic:
intro x y
/-- A group is commutative if the center is the whole group -/
def _root_.Group.commGroupOfCenterEqTop (h : center G = ⊤) : CommGroup G :=
  { (_ : Group G) with
    mul_comm := by
      rw [eq_top_iff'] at h
      intro x y
      

Proof state:
G : Type u_1
G' : Type u_2
G'' : Type u_3
inst✝³ : Group G
inst✝² : Group G'
inst✝¹ : Group G''
A : Type u_4
inst✝ : AddGroup A
H K : Subgroup G
h : ∀ (x : G), x ∈ center G
src✝ : Group G := inst✝³
x y : G
⊢ x * y = y * x

Next tactic:
apply Subgroup.mem_center_iff.mp _ x