l3lab/ntp-mathlib huggingface dataset:
@[to_additive (attr := simp)]
theorem coe_inclusion {H K : S} {h : H ≤ K} (a : H) : (inclusion h a : G) = a := by
  cases a
  

Proof state:
case mk
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
M : Type u_5
S : Type u_6
inst✝³ : DivInvMonoid M
inst✝² : SetLike S M
hSM : SubgroupClass S M
H✝ K✝ : S
inst✝¹ : SetLike S G
inst✝ : SubgroupClass S G
H K : S
h : H ≤ K
val✝ : G
property✝ : val✝ ∈ H
⊢ ↑((inclusion h) { val := val✝, property := property✝ }) = ↑{ val := val✝, property := property✝ }

Next tactic:
simp only [inclusion, MonoidHom.mk'_apply]
@[to_additive (attr := simp)]
theorem subtype_comp_inclusion {H K : S} (hH : H ≤ K) :
    (SubgroupClass.subtype K).comp (inclusion hH) = SubgroupClass.subtype 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
M : Type u_5
S : Type u_6
inst✝³ : DivInvMonoid M
inst✝² : SetLike S M
hSM : SubgroupClass S M
H✝ K✝ : S
inst✝¹ : SetLike S G
inst✝ : SubgroupClass S G
H K : S
hH : H ≤ K
⊢ MonoidHom.comp (↑K) (inclusion hH) = ↑H

Next tactic:
ext
@[to_additive (attr := simp)]
theorem subtype_comp_inclusion {H K : S} (hH : H ≤ K) :
    (SubgroupClass.subtype K).comp (inclusion hH) = SubgroupClass.subtype H := by
  ext
  

Proof state:
case h
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
M : Type u_5
S : Type u_6
inst✝³ : DivInvMonoid M
inst✝² : SetLike S M
hSM : SubgroupClass S M
H✝ K✝ : S
inst✝¹ : SetLike S G
inst✝ : SubgroupClass S G
H K : S
hH : H ≤ K
x✝ : ↥H
⊢ (MonoidHom.comp (↑K) (inclusion hH)) x✝ = ↑H x✝

Next tactic:
simp only [MonoidHom.comp_apply, coeSubtype, coe_inclusion]
@[to_additive]
instance : SetLike (Subgroup G) G where
  coe s := s.carrier
  coe_injective' p q 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
p q : Subgroup G
h : (fun s => s.carrier) p = (fun s => s.carrier) q
⊢ p = q

Next tactic:
obtain ⟨⟨⟨hp,_⟩,_⟩,_⟩ := p
@[to_additive]
instance : SetLike (Subgroup G) G where
  coe s := s.carrier
  coe_injective' p q h := by
    obtain ⟨⟨⟨hp,_⟩,_⟩,_⟩ := p
    

Proof state:
case mk.mk.mk
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
q : Subgroup G
hp : Set G
mul_mem'✝ : ∀ {a b : G}, a ∈ hp → b ∈ hp → a * b ∈ hp
one_mem'✝ : 1 ∈ { carrier := hp, mul_mem' := mul_mem'✝ }.carrier
inv_mem'✝ :
  ∀ {x : G},
    x ∈ { toSubsemigroup := { carrier := hp, mul_mem' := mul_mem'✝ }, one_mem' := one_mem'✝ }.toSubsemigroup.carrier →
      x⁻¹ ∈ { toSubsemigroup := { carrier := hp, mul_mem' := mul_mem'✝ }, one_mem' := one_mem'✝ }.toSubsemigroup.carrier
h :
  (fun s => s.carrier)
      { toSubmonoid := { toSubsemigroup := { carrier := hp, mul_mem' := mul_mem'✝ }, one_mem' := one_mem'✝ },
        inv_mem' := inv_mem'✝ } =
    (fun s => s.carrier) q
⊢ { toSubmonoid := { toSubsemigroup := { carrier := hp, mul_mem' := mul_mem'✝ }, one_mem' := one_mem'✝ },
      inv_mem' := inv_mem'✝ } =
    q

Next tactic:
obtain ⟨⟨⟨hq,_⟩,_⟩,_⟩ := q
@[to_additive]
instance : SetLike (Subgroup G) G where
  coe s := s.carrier
  coe_injective' p q h := by
    obtain ⟨⟨⟨hp,_⟩,_⟩,_⟩ := p
    obtain ⟨⟨⟨hq,_⟩,_⟩,_⟩ := q
    

Proof state:
case mk.mk.mk.mk.mk.mk
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
hp : Set G
mul_mem'✝¹ : ∀ {a b : G}, a ∈ hp → b ∈ hp → a * b ∈ hp
one_mem'✝¹ : 1 ∈ { carrier := hp, mul_mem' := mul_mem'✝¹ }.carrier
inv_mem'✝¹ :
  ∀ {x : G},
    x ∈ { toSubsemigroup := { carrier := hp, mul_mem' := mul_mem'✝¹ }, one_mem' := one_mem'✝¹ }.toSubsemigroup.carrier →
      x⁻¹ ∈
        { toSubsemigroup := { carrier := hp, mul_mem' := mul_mem'✝¹ }, one_mem' := one_mem'✝¹ }.toSubsemigroup.carrier
hq : Set G
mul_mem'✝ : ∀ {a b : G}, a ∈ hq → b ∈ hq → a * b ∈ hq
one_mem'✝ : 1 ∈ { carrier := hq, mul_mem' := mul_mem'✝ }.carrier
inv_mem'✝ :
  ∀ {x : G},
    x ∈ { toSubsemigroup := { carrier := hq, mul_mem' := mul_mem'✝ }, one_mem' := one_mem'✝ }.toSubsemigroup.carrier →
      x⁻¹ ∈ { toSubsemigroup := { carrier := hq, mul_mem' := mul_mem'✝ }, one_mem' := one_mem'✝ }.toSubsemigroup.carrier
h :
  (fun s => s.carrier)
      { toSubmonoid := { toSubsemigroup := { carrier := hp, mul_mem' := mul_mem'✝¹ }, one_mem' := one_mem'✝¹ },
        inv_mem' := inv_mem'✝¹ } =
    (fun s => s.carrier)
      { toSubmonoid := { toSubsemigroup := { carrier := hq, mul_mem' := mul_mem'✝ }, one_mem' := one_mem'✝ },
        inv_mem' := inv_mem'✝ }
⊢ { toSubmonoid := { toSubsemigroup := { carrier := hp, mul_mem' := mul_mem'✝¹ }, one_mem' := one_mem'✝¹ },
      inv_mem' := inv_mem'✝¹ } =
    { toSubmonoid := { toSubsemigroup := { carrier := hq, mul_mem' := mul_mem'✝ }, one_mem' := one_mem'✝ },
      inv_mem' := inv_mem'✝ }

Next tactic:
congr
@[to_additive]
theorem toSubmonoid_injective : Function.Injective (toSubmonoid : Subgroup G → Submonoid G) :=
  -- fun p q h => SetLike.ext'_iff.2 (show _ from SetLike.ext'_iff.1 h)
  fun p q 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
p q : Subgroup G
h : p.toSubmonoid = q.toSubmonoid
⊢ p = q

Next tactic:
have := SetLike.ext'_iff.1 h
@[to_additive]
theorem toSubmonoid_injective : Function.Injective (toSubmonoid : Subgroup G → Submonoid G) :=
  -- fun p q h => SetLike.ext'_iff.2 (show _ from SetLike.ext'_iff.1 h)
  fun p q h => by
    have := SetLike.ext'_iff.1 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
p q : Subgroup G
h : p.toSubmonoid = q.toSubmonoid
this : ↑p.toSubmonoid = ↑q.toSubmonoid
⊢ p = q

Next tactic:
rw [coe_toSubmonoid, coe_toSubmonoid] at this
@[to_additive]
theorem toSubmonoid_injective : Function.Injective (toSubmonoid : Subgroup G → Submonoid G) :=
  -- fun p q h => SetLike.ext'_iff.2 (show _ from SetLike.ext'_iff.1 h)
  fun p q h => by
    have := SetLike.ext'_iff.1 h
    rw [coe_toSubmonoid, coe_toSubmonoid] at this
    

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
p q : Subgroup G
h : p.toSubmonoid = q.toSubmonoid
this : ↑p = ↑q
⊢ p = q

Next tactic:
exact SetLike.ext'_iff.2 this
/-- Subgroups of a group `G` are isomorphic to additive subgroups of `Additive G`. -/
@[simps!]
def Subgroup.toAddSubgroup : Subgroup G ≃o AddSubgroup (Additive G) where
  toFun S := { Submonoid.toAddSubmonoid S.toSubmonoid with neg_mem' := S.inv_mem' }
  invFun S := { AddSubmonoid.toSubmonoid S.toAddSubmonoid with inv_mem' := S.neg_mem' }
  left_inv x := 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
x : Subgroup G
⊢ (fun S =>
        let src := AddSubmonoid.toSubmonoid S.toAddSubmonoid;
        { toSubmonoid := { toSubsemigroup := src.toSubsemigroup, one_mem' := (_ : 1 ∈ src.carrier) },
          inv_mem' := (_ : ∀ {x : G}, x ∈ S.carrier → -x ∈ S.carrier) })
      ((fun S =>
          let src := Submonoid.toAddSubmonoid S.toSubmonoid;
          { toAddSubmonoid := { toAddSubsemigroup := src.toAddSubsemigroup, zero_mem' := (_ : 0 ∈ src.carrier) },
            neg_mem' := (_ : ∀ {x : Additive G}, x ∈ S.carrier → x⁻¹ ∈ S.carrier) })
        x) =
    x

Next tactic:
cases x
/-- Subgroups of a group `G` are isomorphic to additive subgroups of `Additive G`. -/
@[simps!]
def Subgroup.toAddSubgroup : Subgroup G ≃o AddSubgroup (Additive G) where
  toFun S := { Submonoid.toAddSubmonoid S.toSubmonoid with neg_mem' := S.inv_mem' }
  invFun S := { AddSubmonoid.toSubmonoid S.toAddSubmonoid with inv_mem' := S.neg_mem' }
  left_inv x := by cases x; 

Proof state:
case mk
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
toSubmonoid✝ : Submonoid G
inv_mem'✝ : ∀ {x : G}, x ∈ toSubmonoid✝.carrier → x⁻¹ ∈ toSubmonoid✝.carrier
⊢ (fun S =>
        let src := AddSubmonoid.toSubmonoid S.toAddSubmonoid;
        { toSubmonoid := { toSubsemigroup := src.toSubsemigroup, one_mem' := (_ : 1 ∈ src.carrier) },
          inv_mem' := (_ : ∀ {x : G}, x ∈ S.carrier → -x ∈ S.carrier) })
      ((fun S =>
          let src := Submonoid.toAddSubmonoid S.toSubmonoid;
          { toAddSubmonoid := { toAddSubsemigroup := src.toAddSubsemigroup, zero_mem' := (_ : 0 ∈ src.carrier) },
            neg_mem' := (_ : ∀ {x : Additive G}, x ∈ S.carrier → x⁻¹ ∈ S.carrier) })
        { toSubmonoid := toSubmonoid✝, inv_mem' := inv_mem'✝ }) =
    { toSubmonoid := toSubmonoid✝, inv_mem' := inv_mem'✝ }

Next tactic:
rfl
/-- Subgroups of a group `G` are isomorphic to additive subgroups of `Additive G`. -/
@[simps!]
def Subgroup.toAddSubgroup : Subgroup G ≃o AddSubgroup (Additive G) where
  toFun S := { Submonoid.toAddSubmonoid S.toSubmonoid with neg_mem' := S.inv_mem' }
  invFun S := { AddSubmonoid.toSubmonoid S.toAddSubmonoid with inv_mem' := S.neg_mem' }
  left_inv x := by cases x; rfl
  right_inv x := 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
x : AddSubgroup (Additive G)
⊢ (fun S =>
        let src := Submonoid.toAddSubmonoid S.toSubmonoid;
        { toAddSubmonoid := { toAddSubsemigroup := src.toAddSubsemigroup, zero_mem' := (_ : 0 ∈ src.carrier) },
          neg_mem' := (_ : ∀ {x : Additive G}, x ∈ S.carrier → x⁻¹ ∈ S.carrier) })
      ((fun S =>
          let src := AddSubmonoid.toSubmonoid S.toAddSubmonoid;
          { toSubmonoid := { toSubsemigroup := src.toSubsemigroup, one_mem' := (_ : 1 ∈ src.carrier) },
            inv_mem' := (_ : ∀ {x : G}, x ∈ S.carrier → -x ∈ S.carrier) })
        x) =
    x

Next tactic:
cases x
/-- Subgroups of a group `G` are isomorphic to additive subgroups of `Additive G`. -/
@[simps!]
def Subgroup.toAddSubgroup : Subgroup G ≃o AddSubgroup (Additive G) where
  toFun S := { Submonoid.toAddSubmonoid S.toSubmonoid with neg_mem' := S.inv_mem' }
  invFun S := { AddSubmonoid.toSubmonoid S.toAddSubmonoid with inv_mem' := S.neg_mem' }
  left_inv x := by cases x; rfl
  right_inv x := by cases x; 

Proof state:
case mk
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
toAddSubmonoid✝ : AddSubmonoid (Additive G)
neg_mem'✝ : ∀ {x : Additive G}, x ∈ toAddSubmonoid✝.carrier → -x ∈ toAddSubmonoid✝.carrier
⊢ (fun S =>
        let src := Submonoid.toAddSubmonoid S.toSubmonoid;
        { toAddSubmonoid := { toAddSubsemigroup := src.toAddSubsemigroup, zero_mem' := (_ : 0 ∈ src.carrier) },
          neg_mem' := (_ : ∀ {x : Additive G}, x ∈ S.carrier → x⁻¹ ∈ S.carrier) })
      ((fun S =>
          let src := AddSubmonoid.toSubmonoid S.toAddSubmonoid;
          { toSubmonoid := { toSubsemigroup := src.toSubsemigroup, one_mem' := (_ : 1 ∈ src.carrier) },
            inv_mem' := (_ : ∀ {x : G}, x ∈ S.carrier → -x ∈ S.carrier) })
        { toAddSubmonoid := toAddSubmonoid✝, neg_mem' := neg_mem'✝ }) =
    { toAddSubmonoid := toAddSubmonoid✝, neg_mem' := neg_mem'✝ }

Next tactic:
rfl
/-- Additive subgroups of an additive group `A` are isomorphic to subgroups of `Multiplicative A`.
-/
@[simps!]
def AddSubgroup.toSubgroup : AddSubgroup A ≃o Subgroup (Multiplicative A) where
  toFun S := { AddSubmonoid.toSubmonoid S.toAddSubmonoid with inv_mem' := S.neg_mem' }
  invFun S := { Submonoid.toAddSubmonoid S.toSubmonoid with neg_mem' := S.inv_mem' }
  left_inv x := 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
x : AddSubgroup A
⊢ (fun S =>
        let src := Submonoid.toAddSubmonoid S.toSubmonoid;
        { toAddSubmonoid := { toAddSubsemigroup := src.toAddSubsemigroup, zero_mem' := (_ : 0 ∈ src.carrier) },
          neg_mem' := (_ : ∀ {x : A}, x ∈ S.carrier → x⁻¹ ∈ S.carrier) })
      ((fun S =>
          let src := AddSubmonoid.toSubmonoid S.toAddSubmonoid;
          { toSubmonoid := { toSubsemigroup := src.toSubsemigroup, one_mem' := (_ : 1 ∈ src.carrier) },
            inv_mem' := (_ : ∀ {x : Multiplicative A}, x ∈ S.carrier → -x ∈ S.carrier) })
        x) =
    x

Next tactic:
cases x
/-- Additive subgroups of an additive group `A` are isomorphic to subgroups of `Multiplicative A`.
-/
@[simps!]
def AddSubgroup.toSubgroup : AddSubgroup A ≃o Subgroup (Multiplicative A) where
  toFun S := { AddSubmonoid.toSubmonoid S.toAddSubmonoid with inv_mem' := S.neg_mem' }
  invFun S := { Submonoid.toAddSubmonoid S.toSubmonoid with neg_mem' := S.inv_mem' }
  left_inv x := by cases x; 

Proof state:
case mk
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
toAddSubmonoid✝ : AddSubmonoid A
neg_mem'✝ : ∀ {x : A}, x ∈ toAddSubmonoid✝.carrier → -x ∈ toAddSubmonoid✝.carrier
⊢ (fun S =>
        let src := Submonoid.toAddSubmonoid S.toSubmonoid;
        { toAddSubmonoid := { toAddSubsemigroup := src.toAddSubsemigroup, zero_mem' := (_ : 0 ∈ src.carrier) },
          neg_mem' := (_ : ∀ {x : A}, x ∈ S.carrier → x⁻¹ ∈ S.carrier) })
      ((fun S =>
          let src := AddSubmonoid.toSubmonoid S.toAddSubmonoid;
          { toSubmonoid := { toSubsemigroup := src.toSubsemigroup, one_mem' := (_ : 1 ∈ src.carrier) },
            inv_mem' := (_ : ∀ {x : Multiplicative A}, x ∈ S.carrier → -x ∈ S.carrier) })
        { toAddSubmonoid := toAddSubmonoid✝, neg_mem' := neg_mem'✝ }) =
    { toAddSubmonoid := toAddSubmonoid✝, neg_mem' := neg_mem'✝ }

Next tactic:
rfl
/-- Additive subgroups of an additive group `A` are isomorphic to subgroups of `Multiplicative A`.
-/
@[simps!]
def AddSubgroup.toSubgroup : AddSubgroup A ≃o Subgroup (Multiplicative A) where
  toFun S := { AddSubmonoid.toSubmonoid S.toAddSubmonoid with inv_mem' := S.neg_mem' }
  invFun S := { Submonoid.toAddSubmonoid S.toSubmonoid with neg_mem' := S.inv_mem' }
  left_inv x := by cases x; rfl
  right_inv x := 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
x : Subgroup (Multiplicative A)
⊢ (fun S =>
        let src := AddSubmonoid.toSubmonoid S.toAddSubmonoid;
        { toSubmonoid := { toSubsemigroup := src.toSubsemigroup, one_mem' := (_ : 1 ∈ src.carrier) },
          inv_mem' := (_ : ∀ {x : Multiplicative A}, x ∈ S.carrier → -x ∈ S.carrier) })
      ((fun S =>
          let src := Submonoid.toAddSubmonoid S.toSubmonoid;
          { toAddSubmonoid := { toAddSubsemigroup := src.toAddSubsemigroup, zero_mem' := (_ : 0 ∈ src.carrier) },
            neg_mem' := (_ : ∀ {x : A}, x ∈ S.carrier → x⁻¹ ∈ S.carrier) })
        x) =
    x

Next tactic:
cases x
/-- Additive subgroups of an additive group `A` are isomorphic to subgroups of `Multiplicative A`.
-/
@[simps!]
def AddSubgroup.toSubgroup : AddSubgroup A ≃o Subgroup (Multiplicative A) where
  toFun S := { AddSubmonoid.toSubmonoid S.toAddSubmonoid with inv_mem' := S.neg_mem' }
  invFun S := { Submonoid.toAddSubmonoid S.toSubmonoid with neg_mem' := S.inv_mem' }
  left_inv x := by cases x; rfl
  right_inv x := by cases x; 

Proof state:
case mk
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
toSubmonoid✝ : Submonoid (Multiplicative A)
inv_mem'✝ : ∀ {x : Multiplicative A}, x ∈ toSubmonoid✝.carrier → x⁻¹ ∈ toSubmonoid✝.carrier
⊢ (fun S =>
        let src := AddSubmonoid.toSubmonoid S.toAddSubmonoid;
        { toSubmonoid := { toSubsemigroup := src.toSubsemigroup, one_mem' := (_ : 1 ∈ src.carrier) },
          inv_mem' := (_ : ∀ {x : Multiplicative A}, x ∈ S.carrier → -x ∈ S.carrier) })
      ((fun S =>
          let src := Submonoid.toAddSubmonoid S.toSubmonoid;
          { toAddSubmonoid := { toAddSubsemigroup := src.toAddSubsemigroup, zero_mem' := (_ : 0 ∈ src.carrier) },
            neg_mem' := (_ : ∀ {x : A}, x ∈ S.carrier → x⁻¹ ∈ S.carrier) })
        { toSubmonoid := toSubmonoid✝, inv_mem' := inv_mem'✝ }) =
    { toSubmonoid := toSubmonoid✝, inv_mem' := inv_mem'✝ }

Next tactic:
rfl
/-- Copy of a subgroup with a new `carrier` equal to the old one. Useful to fix definitional
equalities.-/
@[to_additive
      "Copy of an additive subgroup with a new `carrier` equal to the old one.
      Useful to fix definitional equalities"]
protected def copy (K : Subgroup G) (s : Set G) (hs : s = K) : Subgroup G where
  carrier := s
  one_mem' := hs.symm ▸ K.one_mem'
  mul_mem' := hs.symm ▸ K.mul_mem'
  inv_mem' hx := 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✝ K : Subgroup G
s : Set G
hs : s = ↑K
x✝ : G
hx :
  x✝ ∈
    { toSubsemigroup := { carrier := s, mul_mem' := (_ : ∀ {a b : G}, a ∈ s → b ∈ s → a * b ∈ s) },
          one_mem' :=
            (_ :
              1 ∈
                { carrier := s,
                    mul_mem' := (_ : ∀ {a b : G}, a ∈ s → b ∈ s → a * b ∈ s) }.carrier) }.toSubsemigroup.carrier
⊢ x✝⁻¹ ∈
    { toSubsemigroup := { carrier := s, mul_mem' := (_ : ∀ {a b : G}, a ∈ s → b ∈ s → a * b ∈ s) },
          one_mem' :=
            (_ :
              1 ∈
                { carrier := s,
                    mul_mem' := (_ : ∀ {a b : G}, a ∈ s → b ∈ s → a * b ∈ s) }.carrier) }.toSubsemigroup.carrier

Next tactic:
simpa [hs] using hx
/-- Construct a subgroup from a nonempty set that is closed under division. -/
@[to_additive "Construct a subgroup from a nonempty set that is closed under subtraction"]
def ofDiv (s : Set G) (hsn : s.Nonempty) (hs : ∀ᵉ (x ∈ s) (y ∈ s), x * y⁻¹ ∈ s) :
    Subgroup G :=
  have one_mem : (1 : G) ∈ s := 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
s : Set G
hsn : Set.Nonempty s
hs : ∀ x ∈ s, ∀ y ∈ s, x * y⁻¹ ∈ s
⊢ 1 ∈ s

Next tactic:
let ⟨x, hx⟩ := hsn
/-- Construct a subgroup from a nonempty set that is closed under division. -/
@[to_additive "Construct a subgroup from a nonempty set that is closed under subtraction"]
def ofDiv (s : Set G) (hsn : s.Nonempty) (hs : ∀ᵉ (x ∈ s) (y ∈ s), x * y⁻¹ ∈ s) :
    Subgroup G :=
  have one_mem : (1 : G) ∈ s := by
    let ⟨x, hx⟩ := hsn
    

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
s : Set G
hsn : Set.Nonempty s
hs : ∀ x ∈ s, ∀ y ∈ s, x * y⁻¹ ∈ s
x : G
hx : x ∈ s
⊢ 1 ∈ s

Next tactic:
simpa using hs x hx x hx
/-- Construct a subgroup from a nonempty set that is closed under division. -/
@[to_additive "Construct a subgroup from a nonempty set that is closed under subtraction"]
def ofDiv (s : Set G) (hsn : s.Nonempty) (hs : ∀ᵉ (x ∈ s) (y ∈ s), x * y⁻¹ ∈ s) :
    Subgroup G :=
  have one_mem : (1 : G) ∈ s := by
    let ⟨x, hx⟩ := hsn
    simpa using hs x hx x hx
  have inv_mem : ∀ x, x ∈ s → x⁻¹ ∈ s := fun x hx => 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
s : Set G
hsn : Set.Nonempty s
hs : ∀ x ∈ s, ∀ y ∈ s, x * y⁻¹ ∈ s
one_mem : 1 ∈ s
x : G
hx : x ∈ s
⊢ x⁻¹ ∈ s

Next tactic:
simpa using hs 1 one_mem x hx
/-- Construct a subgroup from a nonempty set that is closed under division. -/
@[to_additive "Construct a subgroup from a nonempty set that is closed under subtraction"]
def ofDiv (s : Set G) (hsn : s.Nonempty) (hs : ∀ᵉ (x ∈ s) (y ∈ s), x * y⁻¹ ∈ s) :
    Subgroup G :=
  have one_mem : (1 : G) ∈ s := by
    let ⟨x, hx⟩ := hsn
    simpa using hs x hx x hx
  have inv_mem : ∀ x, x ∈ s → x⁻¹ ∈ s := fun x hx => by simpa using hs 1 one_mem x hx
  { carrier := s
    one_mem' := one_mem
    inv_mem' := inv_mem _
    mul_mem' := fun hx hy => 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
s : Set G
hsn : Set.Nonempty s
hs : ∀ x ∈ s, ∀ y ∈ s, x * y⁻¹ ∈ s
one_mem : 1 ∈ s
inv_mem : ∀ x ∈ s, x⁻¹ ∈ s
a✝ b✝ : G
hx : a✝ ∈ s
hy : b✝ ∈ s
⊢ a✝ * b✝ ∈ s

Next tactic:
simpa using hs _ hx _ (inv_mem _ hy)
@[to_additive (attr := simp)]
theorem mk_eq_one_iff {g : G} {h} : (⟨g, h⟩ : H) = 1 ↔ g = 1 :=
  show (⟨g, h⟩ : H) = (⟨1, H.one_mem⟩ : H) ↔ g = 1 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 : G
h : g ∈ H
⊢ { val := g, property := h } = { val := 1, property := (_ : 1 ∈ H) } ↔ g = 1

Next tactic:
simp
@[to_additive (attr := simp)]
theorem coe_inclusion {H K : Subgroup G} {h : H ≤ K} (a : H) : (inclusion h a : G) = a := 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✝ H K : Subgroup G
h : H ≤ K
a : ↥H
⊢ ↑((inclusion h) a) = ↑a

Next tactic:
cases a
@[to_additive (attr := simp)]
theorem coe_inclusion {H K : Subgroup G} {h : H ≤ K} (a : H) : (inclusion h a : G) = a := by
  cases a
  

Proof state:
case mk
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✝ H K : Subgroup G
h : H ≤ K
val✝ : G
property✝ : val✝ ∈ H
⊢ ↑((inclusion h) { val := val✝, property := property✝ }) = ↑{ val := val✝, property := property✝ }

Next tactic:
simp only [inclusion, coe_mk, MonoidHom.mk'_apply]
/-- The trivial subgroup `{1}` of a group `G`. -/
@[to_additive "The trivial `AddSubgroup` `{0}` of an `AddGroup` `G`."]
instance : Bot (Subgroup G) :=
  ⟨{ (⊥ : Submonoid G) with inv_mem' := 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
src✝ : Submonoid G := ⊥
⊢ ∀ {x : G},
    x ∈ { toSubsemigroup := src✝.toSubsemigroup, one_mem' := (_ : 1 ∈ src✝.carrier) }.toSubsemigroup.carrier →
      x⁻¹ ∈ { toSubsemigroup := src✝.toSubsemigroup, one_mem' := (_ : 1 ∈ src✝.carrier) }.toSubsemigroup.carrier

Next tactic:
simp
@[to_additive]
theorem eq_bot_of_subsingleton [Subsingleton H] : 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
inst✝ : Subsingleton ↥H
⊢ H = ⊥

Next tactic:
rw [Subgroup.eq_bot_iff_forall]
@[to_additive]
theorem eq_bot_of_subsingleton [Subsingleton H] : H = ⊥ := by
  rw [Subgroup.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
inst✝ : Subsingleton ↥H
⊢ ∀ x ∈ H, x = 1

Next tactic:
intro y hy
@[to_additive]
theorem eq_bot_of_subsingleton [Subsingleton H] : H = ⊥ := by
  rw [Subgroup.eq_bot_iff_forall]
  intro y hy
  

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
inst✝ : Subsingleton ↥H
y : G
hy : y ∈ H
⊢ y = 1

Next tactic:
rw [← Subgroup.coe_mk H y hy, Subsingleton.elim (⟨y, hy⟩ : H) 1, Subgroup.coe_one]
@[to_additive (attr := simp, norm_cast)]
theorem coe_eq_univ {H : Subgroup G} : (H : Set G) = Set.univ ↔ H = ⊤ :=
  (SetLike.ext'_iff.trans (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 H : Subgroup G
⊢ ↑H = ↑⊤ ↔ ↑H = Set.univ

Next tactic:
rfl
@[to_additive]
theorem coe_eq_singleton {H : Subgroup G} : (∃ g : G, (H : Set G) = {g}) ↔ H = ⊥ :=
  ⟨fun ⟨g, hg⟩ =>
    haveI : Subsingleton (H : Set 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 H : Subgroup G
x✝ : ∃ g, ↑H = {g}
g : G
hg : ↑H = {g}
⊢ Subsingleton ↑↑H

Next tactic:
rw [hg]