File: Mathlib/GroupTheory/QuotientGroup.lean

full_name: QuotientGroup.con
code: /-- The congruence relation generated by a normal subgroup. -/
@[to_additive "The additive congruence relation generated by a normal additive subgroup."]
protected def con : Con G 
goal: Con G

full_name: QuotientAddGroup.con
code: /-- The congruence relation generated by a normal subgroup. -/
@[to_additive "The additive congruence relation generated by a normal additive subgroup."]
protected def con : Con G 
goal: AddCon G

full_name: QuotientGroup.Quotient.group
code: @[to_additive]
instance Quotient.group : Group (G ⧸ N) 
goal: Group (G ⧸ N)

full_name: QuotientAddGroup.Quotient.addGroup
code: @[to_additive]
instance Quotient.group : Group (G ⧸ N) 
goal: AddGroup (G ⧸ N)

full_name: QuotientAddGroup.mk'
code: /-- The group homomorphism from `G` to `G/N`. -/
@[to_additive "The additive group homomorphism from `G` to `G/N`."]
def mk' : G →* G ⧸ N 
goal: G →+ G ⧸ N

full_name: QuotientGroup.mk'
code: /-- The group homomorphism from `G` to `G/N`. -/
@[to_additive "The additive group homomorphism from `G` to `G/N`."]
def mk' : G →* G ⧸ N 
goal: G →* G ⧸ N

full_name: QuotientAddGroup.coe_mk'
code: @[to_additive (attr := simp)]
theorem coe_mk' : (mk' N : G → G ⧸ N) = mk 
goal: ⇑(QuotientAddGroup.mk' N) = QuotientAddGroup.mk

full_name: QuotientGroup.coe_mk'
code: @[to_additive (attr := simp)]
theorem coe_mk' : (mk' N : G → G ⧸ N) = mk 
goal: ⇑(QuotientGroup.mk' N) = QuotientGroup.mk

full_name: QuotientGroup.mk'_apply
code: @[to_additive (attr := simp)]
theorem mk'_apply (x : G) : mk' N x = x 
goal: (QuotientGroup.mk' N) x = ↑x

full_name: QuotientAddGroup.mk'_apply
code: @[to_additive (attr := simp)]
theorem mk'_apply (x : G) : mk' N x = x 
goal: (QuotientAddGroup.mk' N) x = ↑x

full_name: QuotientGroup.mk'_surjective
code: @[to_additive]
theorem mk'_surjective : Surjective <| mk' N 
goal: Function.Surjective ⇑(QuotientGroup.mk' N)

full_name: QuotientAddGroup.mk'_surjective
code: @[to_additive]
theorem mk'_surjective : Surjective <| mk' N 
goal: Function.Surjective ⇑(QuotientAddGroup.mk' N)

full_name: QuotientGroup.mk'_eq_mk'
code: @[to_additive]
theorem mk'_eq_mk' {x y : G} : mk' N x = mk' N y ↔ ∃ z ∈ N, x * z = y 
goal: (QuotientGroup.mk' N) x = (QuotientGroup.mk' N) y ↔ ∃ z ∈ N, x * z = y

full_name: QuotientAddGroup.mk'_eq_mk'
code: @[to_additive]
theorem mk'_eq_mk' {x y : G} : mk' N x = mk' N y ↔ ∃ z ∈ N, x * z = y 
goal: (QuotientAddGroup.mk' N) x = (QuotientAddGroup.mk' N) y ↔ ∃ z ∈ N, x + z = y

full_name: QuotientGroup.sound
code: @[to_additive]
theorem sound (U : Set (G ⧸ N)) (g : N.op) :
    g • (mk' N) ⁻¹' U = (mk' N) ⁻¹' U 
goal: g • ⇑(QuotientGroup.mk' N) ⁻¹' U = ⇑(QuotientGroup.mk' N) ⁻¹' U

full_name: QuotientAddGroup.sound
code: @[to_additive]
theorem sound (U : Set (G ⧸ N)) (g : N.op) :
    g • (mk' N) ⁻¹' U = (mk' N) ⁻¹' U 
goal: g +ᵥ ⇑(QuotientAddGroup.mk' N) ⁻¹' U = ⇑(QuotientAddGroup.mk' N) ⁻¹' U

full_name: QuotientGroup.monoidHom_ext
code: /-- Two `MonoidHom`s from a quotient group are equal if their compositions with
`QuotientGroup.mk'` are equal.

See note [partially-applied ext lemmas]. -/
@[to_additive (attr := ext 1100) "Two `AddMonoidHom`s from an additive quotient group are equal if
 their compositions with `AddQuotientGroup.mk'` are equal.

 See note [partially-applied ext lemmas]. "]
theorem monoidHom_ext ⦃f g : G ⧸ N →* M⦄ (h : f.comp (mk' N) = g.comp (mk' N)) : f = g 
goal: f = g

full_name: QuotientAddGroup.addMonoidHom_ext
code: /-- Two `MonoidHom`s from a quotient group are equal if their compositions with
`QuotientGroup.mk'` are equal.

See note [partially-applied ext lemmas]. -/
@[to_additive (attr := ext 1100) "Two `AddMonoidHom`s from an additive quotient group are equal if
 their compositions with `AddQuotientGroup.mk'` are equal.

 See note [partially-applied ext lemmas]. "]
theorem monoidHom_ext ⦃f g : G ⧸ N →* M⦄ (h : f.comp (mk' N) = g.comp (mk' N)) : f = g 
goal: f = g

full_name: QuotientGroup.eq_one_iff
code: @[to_additive (attr := simp)]
theorem eq_one_iff {N : Subgroup G} [nN : N.Normal] (x : G) : (x : G ⧸ N) = 1 ↔ x ∈ N 
goal: ↑x = 1 ↔ x ∈ N

full_name: QuotientAddGroup.eq_zero_iff
code: @[to_additive (attr := simp)]
theorem eq_one_iff {N : Subgroup G} [nN : N.Normal] (x : G) : (x : G ⧸ N) = 1 ↔ x ∈ N 
goal: ↑x = 0 ↔ x ∈ N

full_name: QuotientAddGroup.ker_le_range_iff
code: @[to_additive]
theorem ker_le_range_iff {I : Type w} [Group I] (f : G →* H) [f.range.Normal] (g : H →* I) :
    g.ker ≤ f.range ↔ (mk' f.range).comp g.ker.subtype = 1 
goal: g.ker ≤ f.range ↔ (QuotientAddGroup.mk' f.range).comp g.ker.subtype = 0

full_name: QuotientGroup.ker_le_range_iff
code: @[to_additive]
theorem ker_le_range_iff {I : Type w} [Group I] (f : G →* H) [f.range.Normal] (g : H →* I) :
    g.ker ≤ f.range ↔ (mk' f.range).comp g.ker.subtype = 1 
goal: g.ker ≤ f.range ↔ (QuotientGroup.mk' f.range).comp g.ker.subtype = 1

full_name: QuotientAddGroup.ker_mk'
code: @[to_additive (attr := simp)]
theorem ker_mk' : MonoidHom.ker (QuotientGroup.mk' N : G →* G ⧸ N) = N 
goal: (QuotientAddGroup.mk' N).ker = N

full_name: QuotientGroup.ker_mk'
code: @[to_additive (attr := simp)]
theorem ker_mk' : MonoidHom.ker (QuotientGroup.mk' N : G →* G ⧸ N) = N 
goal: (QuotientGroup.mk' N).ker = N

full_name: QuotientAddGroup.eq_iff_sub_mem
code: @[to_additive]
theorem eq_iff_div_mem {N : Subgroup G} [nN : N.Normal] {x y : G} :
    (x : G ⧸ N) = y ↔ x / y ∈ N 
goal: ↑x = ↑y ↔ x - y ∈ N

full_name: QuotientGroup.eq_iff_div_mem
code: @[to_additive]
theorem eq_iff_div_mem {N : Subgroup G} [nN : N.Normal] {x y : G} :
    (x : G ⧸ N) = y ↔ x / y ∈ N 
goal: ↑x = ↑y ↔ x / y ∈ N

full_name: QuotientAddGroup.Quotient.addCommGroup
code: @[to_additive]
instance Quotient.commGroup {G : Type*} [CommGroup G] (N : Subgroup G) : CommGroup (G ⧸ N) 
goal: AddCommGroup (G ⧸ N)

full_name: QuotientGroup.Quotient.commGroup
code: @[to_additive]
instance Quotient.commGroup {G : Type*} [CommGroup G] (N : Subgroup G) : CommGroup (G ⧸ N) 
goal: CommGroup (G ⧸ N)

full_name: QuotientGroup._aux_Mathlib_GroupTheory_QuotientGroup___macroRules_QuotientGroup_termQ_1
code: local notation " Q " => G ⧸ N
goal: Lean.Macro

full_name: QuotientAddGroup.mk_zero
code: @[to_additive (attr := simp)]
theorem mk_one : ((1 : G) : Q) = 1 
goal: ↑0 = 0

full_name: QuotientGroup.mk_one
code: @[to_additive (attr := simp)]
theorem mk_one : ((1 : G) : Q) = 1 
goal: ↑1 = 1

full_name: QuotientAddGroup.mk_add
code: @[to_additive (attr := simp)]
theorem mk_mul (a b : G) : ((a * b : G) : Q) = a * b 
goal: ↑(a + b) = ↑a + ↑b

full_name: QuotientGroup.mk_mul
code: @[to_additive (attr := simp)]
theorem mk_mul (a b : G) : ((a * b : G) : Q) = a * b 
goal: ↑(a * b) = ↑a * ↑b

full_name: QuotientAddGroup.mk_neg
code: @[to_additive (attr := simp)]
theorem mk_inv (a : G) : ((a⁻¹ : G) : Q) = (a : Q)⁻¹ 
goal: ↑(-a) = -↑a

full_name: QuotientGroup.mk_inv
code: @[to_additive (attr := simp)]
theorem mk_inv (a : G) : ((a⁻¹ : G) : Q) = (a : Q)⁻¹ 
goal: ↑a⁻¹ = (↑a)⁻¹

full_name: QuotientGroup.mk_div
code: @[to_additive (attr := simp)]
theorem mk_div (a b : G) : ((a / b : G) : Q) = a / b 
goal: ↑(a / b) = ↑a / ↑b

full_name: QuotientAddGroup.mk_sub
code: @[to_additive (attr := simp)]
theorem mk_div (a b : G) : ((a / b : G) : Q) = a / b 
goal: ↑(a - b) = ↑a - ↑b

full_name: QuotientAddGroup.mk_nsmul
code: @[to_additive (attr := simp)]
theorem mk_pow (a : G) (n : ℕ) : ((a ^ n : G) : Q) = (a : Q) ^ n 
goal: ↑(n • a) = n • ↑a

full_name: QuotientGroup.mk_pow
code: @[to_additive (attr := simp)]
theorem mk_pow (a : G) (n : ℕ) : ((a ^ n : G) : Q) = (a : Q) ^ n 
goal: ↑(a ^ n) = ↑a ^ n

full_name: QuotientGroup.mk_zpow
code: @[to_additive (attr := simp)]
theorem mk_zpow (a : G) (n : ℤ) : ((a ^ n : G) : Q) = (a : Q) ^ n 
goal: ↑(a ^ n) = ↑a ^ n

full_name: QuotientAddGroup.mk_zsmul
code: @[to_additive (attr := simp)]
theorem mk_zpow (a : G) (n : ℤ) : ((a ^ n : G) : Q) = (a : Q) ^ n 
goal: ↑(n • a) = n • ↑a

full_name: QuotientGroup.mk_prod
code: @[to_additive (attr := simp)]
theorem mk_prod {G ι : Type*} [CommGroup G] (N : Subgroup G) (s : Finset ι) {f : ι → G} :
    ((Finset.prod s f : G) : G ⧸ N) = Finset.prod s (fun i => (f i : G ⧸ N)) 
goal: ↑(s.prod f) = ∏ i ∈ s, ↑(f i)

full_name: QuotientAddGroup.mk_sum
code: @[to_additive (attr := simp)]
theorem mk_prod {G ι : Type*} [CommGroup G] (N : Subgroup G) (s : Finset ι) {f : ι → G} :
    ((Finset.prod s f : G) : G ⧸ N) = Finset.prod s (fun i => (f i : G ⧸ N)) 
goal: ↑(s.sum f) = ∑ i ∈ s, ↑(f i)

full_name: QuotientGroup.map_mk'_self
code: @[to_additive (attr := simp)] lemma map_mk'_self : N.map (mk' N) = ⊥ 
goal: Subgroup.map (QuotientGroup.mk' N) N = ⊥

full_name: QuotientAddGroup.map_mk'_self
code: @[to_additive (attr := simp)] lemma map_mk'_self : N.map (mk' N) = ⊥ 
goal: AddSubgroup.map (QuotientAddGroup.mk' N) N = ⊥

full_name: QuotientGroup.lift
code: /-- A group homomorphism `φ : G →* M` with `N ⊆ ker(φ)` descends (i.e. `lift`s) to a
group homomorphism `G/N →* M`. -/
@[to_additive "An `AddGroup` homomorphism `φ : G →+ M` with `N ⊆ ker(φ)` descends (i.e. `lift`s)
 to a group homomorphism `G/N →* M`."]
def lift (φ : G →* M) (HN : N ≤ φ.ker) : Q →* M 
goal: G ⧸ N →* M

full_name: QuotientAddGroup.lift
code: /-- A group homomorphism `φ : G →* M` with `N ⊆ ker(φ)` descends (i.e. `lift`s) to a
group homomorphism `G/N →* M`. -/
@[to_additive "An `AddGroup` homomorphism `φ : G →+ M` with `N ⊆ ker(φ)` descends (i.e. `lift`s)
 to a group homomorphism `G/N →* M`."]
def lift (φ : G →* M) (HN : N ≤ φ.ker) : Q →* M 
goal: G ⧸ N →+ M

full_name: QuotientAddGroup.lift_mk
code: @[to_additive (attr := simp)]
theorem lift_mk {φ : G →* M} (HN : N ≤ φ.ker) (g : G) : lift N φ HN (g : Q) = φ g 
goal: (QuotientAddGroup.lift N φ HN) ↑g = φ g

full_name: QuotientGroup.lift_mk
code: @[to_additive (attr := simp)]
theorem lift_mk {φ : G →* M} (HN : N ≤ φ.ker) (g : G) : lift N φ HN (g : Q) = φ g 
goal: (QuotientGroup.lift N φ HN) ↑g = φ g

full_name: QuotientAddGroup.lift_mk'
code: @[to_additive (attr := simp)]
theorem lift_mk' {φ : G →* M} (HN : N ≤ φ.ker) (g : G) : lift N φ HN (mk g : Q) = φ g 
goal: (QuotientAddGroup.lift N φ HN) ↑g = φ g

full_name: QuotientGroup.lift_mk'
code: @[to_additive (attr := simp)]
theorem lift_mk' {φ : G →* M} (HN : N ≤ φ.ker) (g : G) : lift N φ HN (mk g : Q) = φ g 
goal: (QuotientGroup.lift N φ HN) ↑g = φ g

full_name: QuotientAddGroup.lift_quot_mk
code: @[to_additive (attr := simp)]
theorem lift_quot_mk {φ : G →* M} (HN : N ≤ φ.ker) (g : G) :
    lift N φ HN (Quot.mk _ g : Q) = φ g 
goal: (QuotientAddGroup.lift N φ HN) (Quot.mk Setoid.r g) = φ g

full_name: QuotientGroup.lift_quot_mk
code: @[to_additive (attr := simp)]
theorem lift_quot_mk {φ : G →* M} (HN : N ≤ φ.ker) (g : G) :
    lift N φ HN (Quot.mk _ g : Q) = φ g 
goal: (QuotientGroup.lift N φ HN) (Quot.mk Setoid.r g) = φ g

full_name: QuotientAddGroup.map
code: /-- A group homomorphism `f : G →* H` induces a map `G/N →* H/M` if `N ⊆ f⁻¹(M)`. -/
@[to_additive
      "An `AddGroup` homomorphism `f : G →+ H` induces a map `G/N →+ H/M` if `N ⊆ f⁻¹(M)`."]
def map (M : Subgroup H) [M.Normal] (f : G →* H) (h : N ≤ M.comap f) : G ⧸ N →* H ⧸ M 
goal: G ⧸ N →+ H ⧸ M

full_name: QuotientGroup.map
code: /-- A group homomorphism `f : G →* H` induces a map `G/N →* H/M` if `N ⊆ f⁻¹(M)`. -/
@[to_additive
      "An `AddGroup` homomorphism `f : G →+ H` induces a map `G/N →+ H/M` if `N ⊆ f⁻¹(M)`."]
def map (M : Subgroup H) [M.Normal] (f : G →* H) (h : N ≤ M.comap f) : G ⧸ N →* H ⧸ M 
goal: G ⧸ N →* H ⧸ M

full_name: QuotientGroup.map_mk
code: @[to_additive (attr := simp)]
theorem map_mk (M : Subgroup H) [M.Normal] (f : G →* H) (h : N ≤ M.comap f) (x : G) :
    map N M f h ↑x = ↑(f x) 
goal: (QuotientGroup.map N M f h) ↑x = ↑(f x)

full_name: QuotientAddGroup.map_mk
code: @[to_additive (attr := simp)]
theorem map_mk (M : Subgroup H) [M.Normal] (f : G →* H) (h : N ≤ M.comap f) (x : G) :
    map N M f h ↑x = ↑(f x) 
goal: (QuotientAddGroup.map N M f h) ↑x = ↑(f x)

full_name: QuotientGroup.map_mk'
code: @[to_additive]
theorem map_mk' (M : Subgroup H) [M.Normal] (f : G →* H) (h : N ≤ M.comap f) (x : G) :
    map N M f h (mk' _ x) = ↑(f x) 
goal: (QuotientGroup.map N M f h) ((QuotientGroup.mk' N) x) = ↑(f x)

full_name: QuotientAddGroup.map_mk'
code: @[to_additive]
theorem map_mk' (M : Subgroup H) [M.Normal] (f : G →* H) (h : N ≤ M.comap f) (x : G) :
    map N M f h (mk' _ x) = ↑(f x) 
goal: (QuotientAddGroup.map N M f h) ((QuotientAddGroup.mk' N) x) = ↑(f x)

full_name: QuotientGroup.map_id_apply
code: @[to_additive]
theorem map_id_apply (h : N ≤ Subgroup.comap (MonoidHom.id _) N := (Subgroup.comap_id N).le) (x) :
    map N N (MonoidHom.id _) h x = x 
goal: (QuotientGroup.map N N (MonoidHom.id G) h) x = x

full_name: QuotientAddGroup.map_id_apply
code: @[to_additive]
theorem map_id_apply (h : N ≤ Subgroup.comap (MonoidHom.id _) N := (Subgroup.comap_id N).le) (x) :
    map N N (MonoidHom.id _) h x = x 
goal: (QuotientAddGroup.map N N (AddMonoidHom.id G) h) x = x

full_name: QuotientAddGroup.map_id
code: @[to_additive (attr := simp)]
theorem map_id (h : N ≤ Subgroup.comap (MonoidHom.id _) N := (Subgroup.comap_id N).le) :
    map N N (MonoidHom.id _) h = MonoidHom.id _ 
goal: QuotientAddGroup.map N N (AddMonoidHom.id G) h = AddMonoidHom.id (G ⧸ N)

full_name: QuotientGroup.map_id
code: @[to_additive (attr := simp)]
theorem map_id (h : N ≤ Subgroup.comap (MonoidHom.id _) N := (Subgroup.comap_id N).le) :
    map N N (MonoidHom.id _) h = MonoidHom.id _ 
goal: QuotientGroup.map N N (MonoidHom.id G) h = MonoidHom.id (G ⧸ N)

full_name: QuotientAddGroup.map_map
code: @[to_additive (attr := simp)]
theorem map_map {I : Type*} [Group I] (M : Subgroup H) (O : Subgroup I) [M.Normal] [O.Normal]
    (f : G →* H) (g : H →* I) (hf : N ≤ Subgroup.comap f M) (hg : M ≤ Subgroup.comap g O)
    (hgf : N ≤ Subgroup.comap (g.comp f) O :=
      hf.trans ((Subgroup.comap_mono hg).trans_eq (Subgroup.comap_comap _ _ _)))
    (x : G ⧸ N) : map M O g hg (map N M f hf x) = map N O (g.comp f) hgf x 
goal: (QuotientAddGroup.map M O g hg) ((QuotientAddGroup.map N M f hf) x) = (QuotientAddGroup.map N O (g.comp f) hgf) x

full_name: QuotientGroup.map_map
code: @[to_additive (attr := simp)]
theorem map_map {I : Type*} [Group I] (M : Subgroup H) (O : Subgroup I) [M.Normal] [O.Normal]
    (f : G →* H) (g : H →* I) (hf : N ≤ Subgroup.comap f M) (hg : M ≤ Subgroup.comap g O)
    (hgf : N ≤ Subgroup.comap (g.comp f) O :=
      hf.trans ((Subgroup.comap_mono hg).trans_eq (Subgroup.comap_comap _ _ _)))
    (x : G ⧸ N) : map M O g hg (map N M f hf x) = map N O (g.comp f) hgf x 
goal: (QuotientGroup.map M O g hg) ((QuotientGroup.map N M f hf) x) = (QuotientGroup.map N O (g.comp f) hgf) x

full_name: QuotientGroup.map_comp_map
code: @[to_additive (attr := simp)]
theorem map_comp_map {I : Type*} [Group I] (M : Subgroup H) (O : Subgroup I) [M.Normal] [O.Normal]
    (f : G →* H) (g : H →* I) (hf : N ≤ Subgroup.comap f M) (hg : M ≤ Subgroup.comap g O)
    (hgf : N ≤ Subgroup.comap (g.comp f) O :=
      hf.trans ((Subgroup.comap_mono hg).trans_eq (Subgroup.comap_comap _ _ _))) :
    (map M O g hg).comp (map N M f hf) = map N O (g.comp f) hgf 
goal: (QuotientGroup.map M O g hg).comp (QuotientGroup.map N M f hf) = QuotientGroup.map N O (g.comp f) hgf

full_name: QuotientAddGroup.map_comp_map
code: @[to_additive (attr := simp)]
theorem map_comp_map {I : Type*} [Group I] (M : Subgroup H) (O : Subgroup I) [M.Normal] [O.Normal]
    (f : G →* H) (g : H →* I) (hf : N ≤ Subgroup.comap f M) (hg : M ≤ Subgroup.comap g O)
    (hgf : N ≤ Subgroup.comap (g.comp f) O :=
      hf.trans ((Subgroup.comap_mono hg).trans_eq (Subgroup.comap_comap _ _ _))) :
    (map M O g hg).comp (map N M f hf) = map N O (g.comp f) hgf 
goal: (QuotientAddGroup.map M O g hg).comp (QuotientAddGroup.map N M f hf) = QuotientAddGroup.map N O (g.comp f) hgf

full_name: QuotientGroup.image_coe
code: @[to_additive (attr := simp)] lemma image_coe : ((↑) : G → Q) '' N = 1 
goal: QuotientGroup.mk '' ↑N = 1

full_name: QuotientAddGroup.image_coe
code: @[to_additive (attr := simp)] lemma image_coe : ((↑) : G → Q) '' N = 1 
goal: QuotientAddGroup.mk '' ↑N = 0

full_name: QuotientGroup.preimage_image_coe
code: @[to_additive]
lemma preimage_image_coe (s : Set G) : ((↑) : G → Q) ⁻¹' ((↑) '' s) = N * s 
goal: QuotientGroup.mk ⁻¹' (QuotientGroup.mk '' s) = ↑N * s

full_name: QuotientAddGroup.preimage_image_coe
code: @[to_additive]
lemma preimage_image_coe (s : Set G) : ((↑) : G → Q) ⁻¹' ((↑) '' s) = N * s 
goal: QuotientAddGroup.mk ⁻¹' (QuotientAddGroup.mk '' s) = ↑N + s

full_name: QuotientGroup.image_coe_inj
code: @[to_additive]
lemma image_coe_inj {s t : Set G} : ((↑) : G → Q) '' s = ((↑) : G → Q) '' t ↔ ↑N * s = N * t 
goal: QuotientGroup.mk '' s = QuotientGroup.mk '' t ↔ ↑N * s = ↑N * t

full_name: QuotientAddGroup.image_coe_inj
code: @[to_additive]
lemma image_coe_inj {s t : Set G} : ((↑) : G → Q) '' s = ((↑) : G → Q) '' t ↔ ↑N * s = N * t 
goal: QuotientAddGroup.mk '' s = QuotientAddGroup.mk '' t ↔ ↑N + s = ↑N + t

full_name: QuotientAddGroup.congr
code: /-- `QuotientGroup.congr` lifts the isomorphism `e : G ≃ H` to `G ⧸ G' ≃ H ⧸ H'`,
given that `e` maps `G` to `H`. -/
@[to_additive "`QuotientAddGroup.congr` lifts the isomorphism `e : G ≃ H` to `G ⧸ G' ≃ H ⧸ H'`,
 given that `e` maps `G` to `H`."]
def congr (e : G ≃* H) (he : G'.map e = H') : G ⧸ G' ≃* H ⧸ H' 
goal: G ⧸ G' ≃+ H ⧸ H'

full_name: QuotientGroup.congr
code: /-- `QuotientGroup.congr` lifts the isomorphism `e : G ≃ H` to `G ⧸ G' ≃ H ⧸ H'`,
given that `e` maps `G` to `H`. -/
@[to_additive "`QuotientAddGroup.congr` lifts the isomorphism `e : G ≃ H` to `G ⧸ G' ≃ H ⧸ H'`,
 given that `e` maps `G` to `H`."]
def congr (e : G ≃* H) (he : G'.map e = H') : G ⧸ G' ≃* H ⧸ H' 
goal: G ⧸ G' ≃* H ⧸ H'

full_name: QuotientGroup.congr_mk
code: @[simp]
theorem congr_mk (e : G ≃* H) (he : G'.map ↑e = H') (x) : congr G' H' e he (mk x) = e x 
goal: (QuotientGroup.congr G' H' e he) ↑x = ↑(e x)

full_name: QuotientGroup.congr_mk'
code: theorem congr_mk' (e : G ≃* H) (he : G'.map ↑e = H') (x) :
    congr G' H' e he (mk' G' x) = mk' H' (e x) 
goal: (QuotientGroup.congr G' H' e he) ((QuotientGroup.mk' G') x) = (QuotientGroup.mk' H') (e x)

full_name: QuotientGroup.congr_apply
code: @[simp]
theorem congr_apply (e : G ≃* H) (he : G'.map ↑e = H') (x : G) :
    congr G' H' e he x = mk' H' (e x) 
goal: (QuotientGroup.congr G' H' e he) ↑x = (QuotientGroup.mk' H') (e x)

full_name: QuotientGroup.congr_refl
code: @[simp]
theorem congr_refl (he : G'.map (MulEquiv.refl G : G →* G) = G' := Subgroup.map_id G') :
    congr G' G' (MulEquiv.refl G) he = MulEquiv.refl (G ⧸ G') 
goal: QuotientGroup.congr G' G' (MulEquiv.refl G) he = MulEquiv.refl (G ⧸ G')

full_name: QuotientGroup.congr_symm
code: @[simp]
theorem congr_symm (e : G ≃* H) (he : G'.map ↑e = H') :
    (congr G' H' e he).symm = congr H' G' e.symm ((Subgroup.map_symm_eq_iff_map_eq _).mpr he) 
goal: (QuotientGroup.congr G' H' e he).symm = QuotientGroup.congr H' G' e.symm ⋯

full_name: QuotientGroup.kerLift
code: /-- The induced map from the quotient by the kernel to the codomain. -/
@[to_additive "The induced map from the quotient by the kernel to the codomain."]
def kerLift : G ⧸ ker φ →* H 
goal: G ⧸ φ.ker →* H

full_name: QuotientAddGroup.kerLift
code: /-- The induced map from the quotient by the kernel to the codomain. -/
@[to_additive "The induced map from the quotient by the kernel to the codomain."]
def kerLift : G ⧸ ker φ →* H 
goal: G ⧸ φ.ker →+ H

full_name: QuotientAddGroup.kerLift_mk
code: @[to_additive (attr := simp)]
theorem kerLift_mk (g : G) : (kerLift φ) g = φ g 
goal: (QuotientAddGroup.kerLift φ) ↑g = φ g

full_name: QuotientGroup.kerLift_mk
code: @[to_additive (attr := simp)]
theorem kerLift_mk (g : G) : (kerLift φ) g = φ g 
goal: (QuotientGroup.kerLift φ) ↑g = φ g

full_name: QuotientGroup.kerLift_mk'
code: @[to_additive (attr := simp)]
theorem kerLift_mk' (g : G) : (kerLift φ) (mk g) = φ g 
goal: (QuotientGroup.kerLift φ) ↑g = φ g

full_name: QuotientAddGroup.kerLift_mk'
code: @[to_additive (attr := simp)]
theorem kerLift_mk' (g : G) : (kerLift φ) (mk g) = φ g 
goal: (QuotientAddGroup.kerLift φ) ↑g = φ g

full_name: QuotientGroup.kerLift_injective
code: @[to_additive]
theorem kerLift_injective : Injective (kerLift φ) 
goal: Function.Injective ⇑(QuotientGroup.kerLift φ)

full_name: QuotientAddGroup.kerLift_injective
code: @[to_additive]
theorem kerLift_injective : Injective (kerLift φ) 
goal: Function.Injective ⇑(QuotientAddGroup.kerLift φ)

full_name: QuotientAddGroup.rangeKerLift
code: /-- The induced map from the quotient by the kernel to the range. -/
@[to_additive "The induced map from the quotient by the kernel to the range."]
def rangeKerLift : G ⧸ ker φ →* φ.range 
goal: G ⧸ φ.ker →+ ↥φ.range

full_name: QuotientGroup.rangeKerLift
code: /-- The induced map from the quotient by the kernel to the range. -/
@[to_additive "The induced map from the quotient by the kernel to the range."]
def rangeKerLift : G ⧸ ker φ →* φ.range 
goal: G ⧸ φ.ker →* ↥φ.range

full_name: QuotientAddGroup.rangeKerLift_injective
code: @[to_additive]
theorem rangeKerLift_injective : Injective (rangeKerLift φ) 
goal: Function.Injective ⇑(QuotientAddGroup.rangeKerLift φ)

full_name: QuotientGroup.rangeKerLift_injective
code: @[to_additive]
theorem rangeKerLift_injective : Injective (rangeKerLift φ) 
goal: Function.Injective ⇑(QuotientGroup.rangeKerLift φ)

full_name: QuotientAddGroup.rangeKerLift_surjective
code: @[to_additive]
theorem rangeKerLift_surjective : Surjective (rangeKerLift φ) 
goal: Function.Surjective ⇑(QuotientAddGroup.rangeKerLift φ)

full_name: QuotientGroup.rangeKerLift_surjective
code: @[to_additive]
theorem rangeKerLift_surjective : Surjective (rangeKerLift φ) 
goal: Function.Surjective ⇑(QuotientGroup.rangeKerLift φ)

full_name: QuotientAddGroup.quotientKerEquivRange
code: /-- **Noether's first isomorphism theorem** (a definition): the canonical isomorphism between
`G/(ker φ)` to `range φ`. -/
@[to_additive "The first isomorphism theorem (a definition): the canonical isomorphism between
`G/(ker φ)` to `range φ`."]
noncomputable def quotientKerEquivRange : G ⧸ ker φ ≃* range φ 
goal: G ⧸ φ.ker ≃+ ↥φ.range

full_name: QuotientGroup.quotientKerEquivRange
code: /-- **Noether's first isomorphism theorem** (a definition): the canonical isomorphism between
`G/(ker φ)` to `range φ`. -/
@[to_additive "The first isomorphism theorem (a definition): the canonical isomorphism between
`G/(ker φ)` to `range φ`."]
noncomputable def quotientKerEquivRange : G ⧸ ker φ ≃* range φ 
goal: G ⧸ φ.ker ≃* ↥φ.range

full_name: QuotientGroup.quotientKerEquivOfRightInverse_symm_apply
code: /-- The canonical isomorphism `G/(ker φ) ≃* H` induced by a homomorphism `φ : G →* H`
with a right inverse `ψ : H → G`. -/
@[to_additive (attr := simps) "The canonical isomorphism `G/(ker φ) ≃+ H` induced by a homomorphism
`φ : G →+ H` with a right inverse `ψ : H → G`."]
def quotientKerEquivOfRightInverse (ψ : H → G) (hφ : RightInverse ψ φ) : G ⧸ ker φ ≃* H 
goal: ∀ (a : H), (QuotientGroup.quotientKerEquivOfRightInverse φ ψ hφ).symm a = (QuotientGroup.mk ∘ ψ) a

full_name: QuotientGroup.quotientKerEquivOfRightInverse
code: /-- The canonical isomorphism `G/(ker φ) ≃* H` induced by a homomorphism `φ : G →* H`
with a right inverse `ψ : H → G`. -/
@[to_additive (attr := simps) "The canonical isomorphism `G/(ker φ) ≃+ H` induced by a homomorphism
`φ : G →+ H` with a right inverse `ψ : H → G`."]
def quotientKerEquivOfRightInverse (ψ : H → G) (hφ : RightInverse ψ φ) : G ⧸ ker φ ≃* H 
goal: G ⧸ φ.ker ≃* H

full_name: QuotientAddGroup.quotientKerEquivOfRightInverse
code: /-- The canonical isomorphism `G/(ker φ) ≃* H` induced by a homomorphism `φ : G →* H`
with a right inverse `ψ : H → G`. -/
@[to_additive (attr := simps) "The canonical isomorphism `G/(ker φ) ≃+ H` induced by a homomorphism
`φ : G →+ H` with a right inverse `ψ : H → G`."]
def quotientKerEquivOfRightInverse (ψ : H → G) (hφ : RightInverse ψ φ) : G ⧸ ker φ ≃* H 
goal: G ⧸ φ.ker ≃+ H

full_name: QuotientAddGroup.quotientKerEquivOfRightInverse_symm_apply
code: /-- The canonical isomorphism `G/(ker φ) ≃* H` induced by a homomorphism `φ : G →* H`
with a right inverse `ψ : H → G`. -/
@[to_additive (attr := simps) "The canonical isomorphism `G/(ker φ) ≃+ H` induced by a homomorphism
`φ : G →+ H` with a right inverse `ψ : H → G`."]
def quotientKerEquivOfRightInverse (ψ : H → G) (hφ : RightInverse ψ φ) : G ⧸ ker φ ≃* H 
goal: ∀ (a : H), (QuotientAddGroup.quotientKerEquivOfRightInverse φ ψ hφ).symm a = (QuotientAddGroup.mk ∘ ψ) a

full_name: QuotientGroup.quotientKerEquivOfRightInverse_apply
code: /-- The canonical isomorphism `G/(ker φ) ≃* H` induced by a homomorphism `φ : G →* H`
with a right inverse `ψ : H → G`. -/
@[to_additive (attr := simps) "The canonical isomorphism `G/(ker φ) ≃+ H` induced by a homomorphism
`φ : G →+ H` with a right inverse `ψ : H → G`."]
def quotientKerEquivOfRightInverse (ψ : H → G) (hφ : RightInverse ψ φ) : G ⧸ ker φ ≃* H 
goal: (QuotientGroup.quotientKerEquivOfRightInverse φ ψ hφ) a = (QuotientGroup.kerLift φ) a

full_name: QuotientAddGroup.quotientKerEquivOfRightInverse_apply
code: /-- The canonical isomorphism `G/(ker φ) ≃* H` induced by a homomorphism `φ : G →* H`
with a right inverse `ψ : H → G`. -/
@[to_additive (attr := simps) "The canonical isomorphism `G/(ker φ) ≃+ H` induced by a homomorphism
`φ : G →+ H` with a right inverse `ψ : H → G`."]
def quotientKerEquivOfRightInverse (ψ : H → G) (hφ : RightInverse ψ φ) : G ⧸ ker φ ≃* H 
goal: (QuotientAddGroup.quotientKerEquivOfRightInverse φ ψ hφ) a = (QuotientAddGroup.kerLift φ) a

full_name: QuotientAddGroup.quotientBot_apply
code: /-- The canonical isomorphism `G/⊥ ≃* G`. -/
@[to_additive (attr := simps!) "The canonical isomorphism `G/⊥ ≃+ G`."]
def quotientBot : G ⧸ (⊥ : Subgroup G) ≃* G 
goal: QuotientAddGroup.quotientBot a = (QuotientAddGroup.kerLift (AddMonoidHom.id G)) a

full_name: QuotientGroup.quotientBot_symm_apply
code: /-- The canonical isomorphism `G/⊥ ≃* G`. -/
@[to_additive (attr := simps!) "The canonical isomorphism `G/⊥ ≃+ G`."]
def quotientBot : G ⧸ (⊥ : Subgroup G) ≃* G 
goal: ∀ (a : G), QuotientGroup.quotientBot.symm a = ↑a

full_name: QuotientGroup.quotientBot_apply
code: /-- The canonical isomorphism `G/⊥ ≃* G`. -/
@[to_additive (attr := simps!) "The canonical isomorphism `G/⊥ ≃+ G`."]
def quotientBot : G ⧸ (⊥ : Subgroup G) ≃* G 
goal: QuotientGroup.quotientBot a = (QuotientGroup.kerLift (MonoidHom.id G)) a

full_name: QuotientGroup.quotientBot
code: /-- The canonical isomorphism `G/⊥ ≃* G`. -/
@[to_additive (attr := simps!) "The canonical isomorphism `G/⊥ ≃+ G`."]
def quotientBot : G ⧸ (⊥ : Subgroup G) ≃* G 
goal: G ⧸ ⊥ ≃* G

full_name: QuotientAddGroup.quotientBot_symm_apply
code: /-- The canonical isomorphism `G/⊥ ≃* G`. -/
@[to_additive (attr := simps!) "The canonical isomorphism `G/⊥ ≃+ G`."]
def quotientBot : G ⧸ (⊥ : Subgroup G) ≃* G 
goal: ∀ (a : G), QuotientAddGroup.quotientBot.symm a = ↑a

full_name: QuotientAddGroup.quotientBot
code: /-- The canonical isomorphism `G/⊥ ≃* G`. -/
@[to_additive (attr := simps!) "The canonical isomorphism `G/⊥ ≃+ G`."]
def quotientBot : G ⧸ (⊥ : Subgroup G) ≃* G 
goal: G ⧸ ⊥ ≃+ G

full_name: QuotientGroup.quotientKerEquivOfSurjective
code: /-- The canonical isomorphism `G/(ker φ) ≃* H` induced by a surjection `φ : G →* H`.

For a `computable` version, see `QuotientGroup.quotientKerEquivOfRightInverse`.
-/
@[to_additive "The canonical isomorphism `G/(ker φ) ≃+ H` induced by a surjection `φ : G →+ H`.
For a `computable` version, see `QuotientAddGroup.quotientKerEquivOfRightInverse`."]
noncomputable def quotientKerEquivOfSurjective (hφ : Surjective φ) : G ⧸ ker φ ≃* H 
goal: G ⧸ φ.ker ≃* H

full_name: QuotientAddGroup.quotientKerEquivOfSurjective
code: /-- The canonical isomorphism `G/(ker φ) ≃* H` induced by a surjection `φ : G →* H`.

For a `computable` version, see `QuotientGroup.quotientKerEquivOfRightInverse`.
-/
@[to_additive "The canonical isomorphism `G/(ker φ) ≃+ H` induced by a surjection `φ : G →+ H`.
For a `computable` version, see `QuotientAddGroup.quotientKerEquivOfRightInverse`."]
noncomputable def quotientKerEquivOfSurjective (hφ : Surjective φ) : G ⧸ ker φ ≃* H 
goal: G ⧸ φ.ker ≃+ H

full_name: QuotientGroup.quotientMulEquivOfEq
code: /-- If two normal subgroups `M` and `N` of `G` are the same, their quotient groups are
isomorphic. -/
@[to_additive "If two normal subgroups `M` and `N` of `G` are the same, their quotient groups are
isomorphic."]
def quotientMulEquivOfEq {M N : Subgroup G} [M.Normal] [N.Normal] (h : M = N) : G ⧸ M ≃* G ⧸ N 
goal: G ⧸ M ≃* G ⧸ N

full_name: QuotientAddGroup.quotientAddEquivOfEq
code: /-- If two normal subgroups `M` and `N` of `G` are the same, their quotient groups are
isomorphic. -/
@[to_additive "If two normal subgroups `M` and `N` of `G` are the same, their quotient groups are
isomorphic."]
def quotientMulEquivOfEq {M N : Subgroup G} [M.Normal] [N.Normal] (h : M = N) : G ⧸ M ≃* G ⧸ N 
goal: G ⧸ M ≃+ G ⧸ N

full_name: QuotientGroup.quotientMulEquivOfEq_mk
code: @[to_additive (attr := simp)]
theorem quotientMulEquivOfEq_mk {M N : Subgroup G} [M.Normal] [N.Normal] (h : M = N) (x : G) :
    QuotientGroup.quotientMulEquivOfEq h (QuotientGroup.mk x) = QuotientGroup.mk x 
goal: (QuotientGroup.quotientMulEquivOfEq h) ↑x = ↑x

full_name: QuotientAddGroup.quotientAddEquivOfEq_mk
code: @[to_additive (attr := simp)]
theorem quotientMulEquivOfEq_mk {M N : Subgroup G} [M.Normal] [N.Normal] (h : M = N) (x : G) :
    QuotientGroup.quotientMulEquivOfEq h (QuotientGroup.mk x) = QuotientGroup.mk x 
goal: (QuotientAddGroup.quotientAddEquivOfEq h) ↑x = ↑x

full_name: QuotientGroup.quotientMapSubgroupOfOfLe
code: /-- Let `A', A, B', B` be subgroups of `G`. If `A' ≤ B'` and `A ≤ B`,
then there is a map `A / (A' ⊓ A) →* B / (B' ⊓ B)` induced by the inclusions. -/
@[to_additive "Let `A', A, B', B` be subgroups of `G`. If `A' ≤ B'` and `A ≤ B`, then there is a map
`A / (A' ⊓ A) →+ B / (B' ⊓ B)` induced by the inclusions."]
def quotientMapSubgroupOfOfLe {A' A B' B : Subgroup G} [_hAN : (A'.subgroupOf A).Normal]
    [_hBN : (B'.subgroupOf B).Normal] (h' : A' ≤ B') (h : A ≤ B) :
    A ⧸ A'.subgroupOf A →* B ⧸ B'.subgroupOf B 
goal: ↥A ⧸ A'.subgroupOf A →* ↥B ⧸ B'.subgroupOf B

full_name: QuotientAddGroup.quotientMapAddSubgroupOfOfLe
code: /-- Let `A', A, B', B` be subgroups of `G`. If `A' ≤ B'` and `A ≤ B`,
then there is a map `A / (A' ⊓ A) →* B / (B' ⊓ B)` induced by the inclusions. -/
@[to_additive "Let `A', A, B', B` be subgroups of `G`. If `A' ≤ B'` and `A ≤ B`, then there is a map
`A / (A' ⊓ A) →+ B / (B' ⊓ B)` induced by the inclusions."]
def quotientMapSubgroupOfOfLe {A' A B' B : Subgroup G} [_hAN : (A'.subgroupOf A).Normal]
    [_hBN : (B'.subgroupOf B).Normal] (h' : A' ≤ B') (h : A ≤ B) :
    A ⧸ A'.subgroupOf A →* B ⧸ B'.subgroupOf B 
goal: ↥A ⧸ A'.addSubgroupOf A →+ ↥B ⧸ B'.addSubgroupOf B

full_name: QuotientGroup.quotientMapSubgroupOfOfLe_mk
code: @[to_additive (attr := simp)]
theorem quotientMapSubgroupOfOfLe_mk {A' A B' B : Subgroup G} [_hAN : (A'.subgroupOf A).Normal]
    [_hBN : (B'.subgroupOf B).Normal] (h' : A' ≤ B') (h : A ≤ B) (x : A) :
    quotientMapSubgroupOfOfLe h' h x = ↑(Subgroup.inclusion h x : B) 
goal: (QuotientGroup.quotientMapSubgroupOfOfLe h' h) ↑x = ↑((Subgroup.inclusion h) x)

full_name: QuotientAddGroup.quotientMapAddSubgroupOfOfLe_mk
code: @[to_additive (attr := simp)]
theorem quotientMapSubgroupOfOfLe_mk {A' A B' B : Subgroup G} [_hAN : (A'.subgroupOf A).Normal]
    [_hBN : (B'.subgroupOf B).Normal] (h' : A' ≤ B') (h : A ≤ B) (x : A) :
    quotientMapSubgroupOfOfLe h' h x = ↑(Subgroup.inclusion h x : B) 
goal: (QuotientAddGroup.quotientMapAddSubgroupOfOfLe h' h) ↑x = ↑((AddSubgroup.inclusion h) x)

full_name: QuotientAddGroup.equivQuotientAddSubgroupOfOfEq
code: /-- Let `A', A, B', B` be subgroups of `G`.
If `A' = B'` and `A = B`, then the quotients `A / (A' ⊓ A)` and `B / (B' ⊓ B)` are isomorphic.

Applying this equiv is nicer than rewriting along the equalities, since the type of
`(A'.subgroupOf A : Subgroup A)` depends on `A`.
-/
@[to_additive "Let `A', A, B', B` be subgroups of `G`. If `A' = B'` and `A = B`, then the quotients
`A / (A' ⊓ A)` and `B / (B' ⊓ B)` are isomorphic. Applying this equiv is nicer than rewriting along
the equalities, since the type of `(A'.addSubgroupOf A : AddSubgroup A)` depends on on `A`. "]
def equivQuotientSubgroupOfOfEq {A' A B' B : Subgroup G} [hAN : (A'.subgroupOf A).Normal]
    [hBN : (B'.subgroupOf B).Normal] (h' : A' = B') (h : A = B) :
    A ⧸ A'.subgroupOf A ≃* B ⧸ B'.subgroupOf B 
goal: ↥A ⧸ A'.addSubgroupOf A ≃+ ↥B ⧸ B'.addSubgroupOf B

full_name: QuotientGroup.equivQuotientSubgroupOfOfEq
code: /-- Let `A', A, B', B` be subgroups of `G`.
If `A' = B'` and `A = B`, then the quotients `A / (A' ⊓ A)` and `B / (B' ⊓ B)` are isomorphic.

Applying this equiv is nicer than rewriting along the equalities, since the type of
`(A'.subgroupOf A : Subgroup A)` depends on `A`.
-/
@[to_additive "Let `A', A, B', B` be subgroups of `G`. If `A' = B'` and `A = B`, then the quotients
`A / (A' ⊓ A)` and `B / (B' ⊓ B)` are isomorphic. Applying this equiv is nicer than rewriting along
the equalities, since the type of `(A'.addSubgroupOf A : AddSubgroup A)` depends on on `A`. "]
def equivQuotientSubgroupOfOfEq {A' A B' B : Subgroup G} [hAN : (A'.subgroupOf A).Normal]
    [hBN : (B'.subgroupOf B).Normal] (h' : A' = B') (h : A = B) :
    A ⧸ A'.subgroupOf A ≃* B ⧸ B'.subgroupOf B 
goal: ↥A ⧸ A'.subgroupOf A ≃* ↥B ⧸ B'.subgroupOf B

full_name: QuotientAddGroup.homQuotientZSMulOfHom
code: /-- The map of quotients by powers of an integer induced by a group homomorphism. -/
@[to_additive "The map of quotients by multiples of an integer induced by an additive group
homomorphism."]
def homQuotientZPowOfHom :
    A ⧸ (zpowGroupHom n : A →* A).range →* B ⧸ (zpowGroupHom n : B →* B).range 
goal: A ⧸ (zsmulAddGroupHom n).range →+ B ⧸ (zsmulAddGroupHom n).range

full_name: QuotientGroup.homQuotientZPowOfHom
code: /-- The map of quotients by powers of an integer induced by a group homomorphism. -/
@[to_additive "The map of quotients by multiples of an integer induced by an additive group
homomorphism."]
def homQuotientZPowOfHom :
    A ⧸ (zpowGroupHom n : A →* A).range →* B ⧸ (zpowGroupHom n : B →* B).range 
goal: A ⧸ (zpowGroupHom n).range →* B ⧸ (zpowGroupHom n).range

full_name: QuotientGroup.homQuotientZPowOfHom_id
code: @[to_additive (attr := simp)]
theorem homQuotientZPowOfHom_id : homQuotientZPowOfHom (MonoidHom.id A) n = MonoidHom.id _ 
goal: QuotientGroup.homQuotientZPowOfHom (MonoidHom.id A) n = MonoidHom.id (A ⧸ (zpowGroupHom n).range)

full_name: QuotientAddGroup.homQuotientZSMulOfHom_id
code: @[to_additive (attr := simp)]
theorem homQuotientZPowOfHom_id : homQuotientZPowOfHom (MonoidHom.id A) n = MonoidHom.id _ 
goal: QuotientAddGroup.homQuotientZSMulOfHom (AddMonoidHom.id A) n = AddMonoidHom.id (A ⧸ (zsmulAddGroupHom n).range)

full_name: QuotientGroup.homQuotientZPowOfHom_comp
code: @[to_additive (attr := simp)]
theorem homQuotientZPowOfHom_comp :
    homQuotientZPowOfHom (f.comp g) n =
      (homQuotientZPowOfHom f n).comp (homQuotientZPowOfHom g n) 
goal: QuotientGroup.homQuotientZPowOfHom (f.comp g) n =
  (QuotientGroup.homQuotientZPowOfHom f n).comp (QuotientGroup.homQuotientZPowOfHom g n)

full_name: QuotientAddGroup.homQuotientZSMulOfHom_comp
code: @[to_additive (attr := simp)]
theorem homQuotientZPowOfHom_comp :
    homQuotientZPowOfHom (f.comp g) n =
      (homQuotientZPowOfHom f n).comp (homQuotientZPowOfHom g n) 
goal: QuotientAddGroup.homQuotientZSMulOfHom (f.comp g) n =
  (QuotientAddGroup.homQuotientZSMulOfHom f n).comp (QuotientAddGroup.homQuotientZSMulOfHom g n)

full_name: QuotientAddGroup.homQuotientZSMulOfHom_comp_of_rightInverse
code: @[to_additive (attr := simp)]
theorem homQuotientZPowOfHom_comp_of_rightInverse (i : Function.RightInverse g f) :
    (homQuotientZPowOfHom f n).comp (homQuotientZPowOfHom g n) = MonoidHom.id _ 
goal: (QuotientAddGroup.homQuotientZSMulOfHom f n).comp (QuotientAddGroup.homQuotientZSMulOfHom g n) =
  AddMonoidHom.id (B ⧸ (zsmulAddGroupHom n).range)

full_name: QuotientGroup.homQuotientZPowOfHom_comp_of_rightInverse
code: @[to_additive (attr := simp)]
theorem homQuotientZPowOfHom_comp_of_rightInverse (i : Function.RightInverse g f) :
    (homQuotientZPowOfHom f n).comp (homQuotientZPowOfHom g n) = MonoidHom.id _ 
goal: (QuotientGroup.homQuotientZPowOfHom f n).comp (QuotientGroup.homQuotientZPowOfHom g n) =
  MonoidHom.id (B ⧸ (zpowGroupHom n).range)

full_name: QuotientGroup.equivQuotientZPowOfEquiv
code: /-- The equivalence of quotients by powers of an integer induced by a group isomorphism. -/
@[to_additive "The equivalence of quotients by multiples of an integer induced by an additive group
isomorphism."]
def equivQuotientZPowOfEquiv :
    A ⧸ (zpowGroupHom n : A →* A).range ≃* B ⧸ (zpowGroupHom n : B →* B).range 
goal: A ⧸ (zpowGroupHom n).range ≃* B ⧸ (zpowGroupHom n).range

full_name: QuotientAddGroup.equivQuotientZSMulOfEquiv
code: /-- The equivalence of quotients by powers of an integer induced by a group isomorphism. -/
@[to_additive "The equivalence of quotients by multiples of an integer induced by an additive group
isomorphism."]
def equivQuotientZPowOfEquiv :
    A ⧸ (zpowGroupHom n : A →* A).range ≃* B ⧸ (zpowGroupHom n : B →* B).range 
goal: A ⧸ (zsmulAddGroupHom n).range ≃+ B ⧸ (zsmulAddGroupHom n).range

full_name: QuotientGroup.equivQuotientZPowOfEquiv_refl
code: @[to_additive (attr := simp)]
theorem equivQuotientZPowOfEquiv_refl :
    MulEquiv.refl (A ⧸ (zpowGroupHom n : A →* A).range) =
      equivQuotientZPowOfEquiv (MulEquiv.refl A) n 
goal: MulEquiv.refl (A ⧸ (zpowGroupHom n).range) = QuotientGroup.equivQuotientZPowOfEquiv (MulEquiv.refl A) n

full_name: QuotientAddGroup.equivQuotientZSMulOfEquiv_refl
code: @[to_additive (attr := simp)]
theorem equivQuotientZPowOfEquiv_refl :
    MulEquiv.refl (A ⧸ (zpowGroupHom n : A →* A).range) =
      equivQuotientZPowOfEquiv (MulEquiv.refl A) n 
goal: AddEquiv.refl (A ⧸ (zsmulAddGroupHom n).range) = QuotientAddGroup.equivQuotientZSMulOfEquiv (AddEquiv.refl A) n

full_name: QuotientAddGroup.equivQuotientZSMulOfEquiv_symm
code: @[to_additive (attr := simp)]
theorem equivQuotientZPowOfEquiv_symm :
    (equivQuotientZPowOfEquiv e n).symm = equivQuotientZPowOfEquiv e.symm n 
goal: (QuotientAddGroup.equivQuotientZSMulOfEquiv e n).symm = QuotientAddGroup.equivQuotientZSMulOfEquiv e.symm n

full_name: QuotientGroup.equivQuotientZPowOfEquiv_symm
code: @[to_additive (attr := simp)]
theorem equivQuotientZPowOfEquiv_symm :
    (equivQuotientZPowOfEquiv e n).symm = equivQuotientZPowOfEquiv e.symm n 
goal: (QuotientGroup.equivQuotientZPowOfEquiv e n).symm = QuotientGroup.equivQuotientZPowOfEquiv e.symm n

full_name: QuotientGroup.equivQuotientZPowOfEquiv_trans
code: @[to_additive (attr := simp)]
theorem equivQuotientZPowOfEquiv_trans :
    (equivQuotientZPowOfEquiv e n).trans (equivQuotientZPowOfEquiv d n) =
      equivQuotientZPowOfEquiv (e.trans d) n 
goal: (QuotientGroup.equivQuotientZPowOfEquiv e n).trans (QuotientGroup.equivQuotientZPowOfEquiv d n) =
  QuotientGroup.equivQuotientZPowOfEquiv (e.trans d) n

full_name: QuotientAddGroup.equivQuotientZSMulOfEquiv_trans
code: @[to_additive (attr := simp)]
theorem equivQuotientZPowOfEquiv_trans :
    (equivQuotientZPowOfEquiv e n).trans (equivQuotientZPowOfEquiv d n) =
      equivQuotientZPowOfEquiv (e.trans d) n 
goal: (QuotientAddGroup.equivQuotientZSMulOfEquiv e n).trans (QuotientAddGroup.equivQuotientZSMulOfEquiv d n) =
  QuotientAddGroup.equivQuotientZSMulOfEquiv (e.trans d) n

full_name: QuotientGroup.quotientInfEquivProdNormalQuotient
code: /-- **Noether's second isomorphism theorem**: given two subgroups `H` and `N` of a group `G`, where
`N` is normal, defines an isomorphism between `H/(H ∩ N)` and `(HN)/N`. -/
@[to_additive "The second isomorphism theorem: given two subgroups `H` and `N` of a group `G`, where
`N` is normal, defines an isomorphism between `H/(H ∩ N)` and `(H + N)/N`"]
noncomputable def quotientInfEquivProdNormalQuotient (H N : Subgroup G) [N.Normal] :
    H ⧸ N.subgroupOf H ≃* _ ⧸ N.subgroupOf (H ⊔ N) 
goal: ↥H ⧸ N.subgroupOf H ≃* ↥(H ⊔ N) ⧸ N.subgroupOf (H ⊔ N)

full_name: QuotientAddGroup.quotientInfEquivSumNormalQuotient
code: /-- **Noether's second isomorphism theorem**: given two subgroups `H` and `N` of a group `G`, where
`N` is normal, defines an isomorphism between `H/(H ∩ N)` and `(HN)/N`. -/
@[to_additive "The second isomorphism theorem: given two subgroups `H` and `N` of a group `G`, where
`N` is normal, defines an isomorphism between `H/(H ∩ N)` and `(H + N)/N`"]
noncomputable def quotientInfEquivProdNormalQuotient (H N : Subgroup G) [N.Normal] :
    H ⧸ N.subgroupOf H ≃* _ ⧸ N.subgroupOf (H ⊔ N) 
goal: ↥H ⧸ N.addSubgroupOf H ≃+ ↥(H ⊔ N) ⧸ N.addSubgroupOf (H ⊔ N)

full_name: QuotientGroup.map_normal
code: @[to_additive]
instance map_normal : (M.map (QuotientGroup.mk' N)).Normal 
goal: (Subgroup.map (QuotientGroup.mk' N) M).Normal

full_name: QuotientAddGroup.map_normal
code: @[to_additive]
instance map_normal : (M.map (QuotientGroup.mk' N)).Normal 
goal: (AddSubgroup.map (QuotientAddGroup.mk' N) M).Normal

full_name: QuotientGroup.quotientQuotientEquivQuotientAux
code: /-- The map from the third isomorphism theorem for groups: `(G / N) / (M / N) → G / M`. -/
@[to_additive "The map from the third isomorphism theorem for additive groups:
`(A / N) / (M / N) → A / M`."]
def quotientQuotientEquivQuotientAux : (G ⧸ N) ⧸ M.map (mk' N) →* G ⧸ M 
goal: (G ⧸ N) ⧸ Subgroup.map (QuotientGroup.mk' N) M →* G ⧸ M

full_name: QuotientAddGroup.quotientQuotientEquivQuotientAux
code: /-- The map from the third isomorphism theorem for groups: `(G / N) / (M / N) → G / M`. -/
@[to_additive "The map from the third isomorphism theorem for additive groups:
`(A / N) / (M / N) → A / M`."]
def quotientQuotientEquivQuotientAux : (G ⧸ N) ⧸ M.map (mk' N) →* G ⧸ M 
goal: (G ⧸ N) ⧸ AddSubgroup.map (QuotientAddGroup.mk' N) M →+ G ⧸ M

full_name: QuotientAddGroup.quotientQuotientEquivQuotientAux_mk
code: @[to_additive (attr := simp)]
theorem quotientQuotientEquivQuotientAux_mk (x : G ⧸ N) :
    quotientQuotientEquivQuotientAux N M h x = QuotientGroup.map N M (MonoidHom.id G) h x 
goal: (QuotientAddGroup.quotientQuotientEquivQuotientAux N M h) ↑x = (QuotientAddGroup.map N M (AddMonoidHom.id G) h) x

full_name: QuotientGroup.quotientQuotientEquivQuotientAux_mk
code: @[to_additive (attr := simp)]
theorem quotientQuotientEquivQuotientAux_mk (x : G ⧸ N) :
    quotientQuotientEquivQuotientAux N M h x = QuotientGroup.map N M (MonoidHom.id G) h x 
goal: (QuotientGroup.quotientQuotientEquivQuotientAux N M h) ↑x = (QuotientGroup.map N M (MonoidHom.id G) h) x

full_name: QuotientAddGroup.quotientQuotientEquivQuotientAux_mk_mk
code: @[to_additive]
theorem quotientQuotientEquivQuotientAux_mk_mk (x : G) :
    quotientQuotientEquivQuotientAux N M h (x : G ⧸ N) = x 
goal: (QuotientAddGroup.quotientQuotientEquivQuotientAux N M h) ↑↑x = ↑x

full_name: QuotientGroup.quotientQuotientEquivQuotientAux_mk_mk
code: @[to_additive]
theorem quotientQuotientEquivQuotientAux_mk_mk (x : G) :
    quotientQuotientEquivQuotientAux N M h (x : G ⧸ N) = x 
goal: (QuotientGroup.quotientQuotientEquivQuotientAux N M h) ↑↑x = ↑x

full_name: QuotientGroup.quotientQuotientEquivQuotient
code: /-- **Noether's third isomorphism theorem** for groups: `(G / N) / (M / N) ≃* G / M`. -/
@[to_additive
      "**Noether's third isomorphism theorem** for additive groups: `(A / N) / (M / N) ≃+ A / M`."]
def quotientQuotientEquivQuotient : (G ⧸ N) ⧸ M.map (QuotientGroup.mk' N) ≃* G ⧸ M 
goal: (G ⧸ N) ⧸ Subgroup.map (QuotientGroup.mk' N) M ≃* G ⧸ M

full_name: QuotientAddGroup.quotientQuotientEquivQuotient
code: /-- **Noether's third isomorphism theorem** for groups: `(G / N) / (M / N) ≃* G / M`. -/
@[to_additive
      "**Noether's third isomorphism theorem** for additive groups: `(A / N) / (M / N) ≃+ A / M`."]
def quotientQuotientEquivQuotient : (G ⧸ N) ⧸ M.map (QuotientGroup.mk' N) ≃* G ⧸ M 
goal: (G ⧸ N) ⧸ AddSubgroup.map (QuotientAddGroup.mk' N) M ≃+ G ⧸ M

full_name: QuotientAddGroup.subsingleton_quotient_top
code: @[to_additive]
theorem subsingleton_quotient_top : Subsingleton (G ⧸ (⊤ : Subgroup G)) 
goal: Subsingleton (G ⧸ ⊤)

full_name: QuotientGroup.subsingleton_quotient_top
code: @[to_additive]
theorem subsingleton_quotient_top : Subsingleton (G ⧸ (⊤ : Subgroup G)) 
goal: Subsingleton (G ⧸ ⊤)

full_name: QuotientGroup.subgroup_eq_top_of_subsingleton
code: /-- If the quotient by a subgroup gives a singleton then the subgroup is the whole group. -/
@[to_additive "If the quotient by an additive subgroup gives a singleton then the additive subgroup
is the whole additive group."]
theorem subgroup_eq_top_of_subsingleton (H : Subgroup G) (h : Subsingleton (G ⧸ H)) : H = ⊤ 
goal: H = ⊤

full_name: QuotientAddGroup.addSubgroup_eq_top_of_subsingleton
code: /-- If the quotient by a subgroup gives a singleton then the subgroup is the whole group. -/
@[to_additive "If the quotient by an additive subgroup gives a singleton then the additive subgroup
is the whole additive group."]
theorem subgroup_eq_top_of_subsingleton (H : Subgroup G) (h : Subsingleton (G ⧸ H)) : H = ⊤ 
goal: H = ⊤

full_name: QuotientGroup.comap_comap_center
code: @[to_additive]
theorem comap_comap_center {H₁ : Subgroup G} [H₁.Normal] {H₂ : Subgroup (G ⧸ H₁)} [H₂.Normal] :
    ((Subgroup.center ((G ⧸ H₁) ⧸ H₂)).comap (mk' H₂)).comap (mk' H₁) =
      (Subgroup.center (G ⧸ H₂.comap (mk' H₁))).comap (mk' (H₂.comap (mk' H₁))) 
goal: Subgroup.comap (QuotientGroup.mk' H₁) (Subgroup.comap (QuotientGroup.mk' H₂) (Subgroup.center ((G ⧸ H₁) ⧸ H₂))) =
  Subgroup.comap (QuotientGroup.mk' (Subgroup.comap (QuotientGroup.mk' H₁) H₂))
    (Subgroup.center (G ⧸ Subgroup.comap (QuotientGroup.mk' H₁) H₂))

full_name: QuotientAddGroup.comap_comap_center
code: @[to_additive]
theorem comap_comap_center {H₁ : Subgroup G} [H₁.Normal] {H₂ : Subgroup (G ⧸ H₁)} [H₂.Normal] :
    ((Subgroup.center ((G ⧸ H₁) ⧸ H₂)).comap (mk' H₂)).comap (mk' H₁) =
      (Subgroup.center (G ⧸ H₂.comap (mk' H₁))).comap (mk' (H₂.comap (mk' H₁))) 
goal: AddSubgroup.comap (QuotientAddGroup.mk' H₁)
    (AddSubgroup.comap (QuotientAddGroup.mk' H₂) (AddSubgroup.center ((G ⧸ H₁) ⧸ H₂))) =
  AddSubgroup.comap (QuotientAddGroup.mk' (AddSubgroup.comap (QuotientAddGroup.mk' H₁) H₂))
    (AddSubgroup.center (G ⧸ AddSubgroup.comap (QuotientAddGroup.mk' H₁) H₂))

full_name: Group.fintypeOfKerLeRange
code: /-- If `F` and `H` are finite such that `ker(G →* H) ≤ im(F →* G)`, then `G` is finite. -/
@[to_additive "If `F` and `H` are finite such that `ker(G →+ H) ≤ im(F →+ G)`, then `G` is finite."]
noncomputable def fintypeOfKerLeRange (h : g.ker ≤ f.range) : Fintype G 
goal: Fintype G

full_name: AddGroup.fintypeOfKerLeRange
code: /-- If `F` and `H` are finite such that `ker(G →* H) ≤ im(F →* G)`, then `G` is finite. -/
@[to_additive "If `F` and `H` are finite such that `ker(G →+ H) ≤ im(F →+ G)`, then `G` is finite."]
noncomputable def fintypeOfKerLeRange (h : g.ker ≤ f.range) : Fintype G 
goal: Fintype G

full_name: Group.fintypeOfKerEqRange
code: /-- If `F` and `H` are finite such that `ker(G →* H) = im(F →* G)`, then `G` is finite. -/
@[to_additive "If `F` and `H` are finite such that `ker(G →+ H) = im(F →+ G)`, then `G` is finite."]
noncomputable def fintypeOfKerEqRange (h : g.ker = f.range) : Fintype G 
goal: Fintype G

full_name: AddGroup.fintypeOfKerEqRange
code: /-- If `F` and `H` are finite such that `ker(G →* H) = im(F →* G)`, then `G` is finite. -/
@[to_additive "If `F` and `H` are finite such that `ker(G →+ H) = im(F →+ G)`, then `G` is finite."]
noncomputable def fintypeOfKerEqRange (h : g.ker = f.range) : Fintype G 
goal: Fintype G

full_name: AddGroup.fintypeOfKerOfCodom
code: /-- If `ker(G →* H)` and `H` are finite, then `G` is finite. -/
@[to_additive "If `ker(G →+ H)` and `H` are finite, then `G` is finite."]
noncomputable def fintypeOfKerOfCodom [Fintype g.ker] : Fintype G 
goal: Fintype G

full_name: Group.fintypeOfKerOfCodom
code: /-- If `ker(G →* H)` and `H` are finite, then `G` is finite. -/
@[to_additive "If `ker(G →+ H)` and `H` are finite, then `G` is finite."]
noncomputable def fintypeOfKerOfCodom [Fintype g.ker] : Fintype G 
goal: Fintype G

full_name: AddGroup.fintypeOfDomOfCoker
code: /-- If `F` and `coker(F →* G)` are finite, then `G` is finite. -/
@[to_additive "If `F` and `coker(F →+ G)` are finite, then `G` is finite."]
noncomputable def fintypeOfDomOfCoker [Normal f.range] [Fintype <| G ⧸ f.range] : Fintype G 
goal: Fintype G

full_name: Group.fintypeOfDomOfCoker
code: /-- If `F` and `coker(F →* G)` are finite, then `G` is finite. -/
@[to_additive "If `F` and `coker(F →+ G)` are finite, then `G` is finite."]
noncomputable def fintypeOfDomOfCoker [Normal f.range] [Fintype <| G ⧸ f.range] : Fintype G 
goal: Fintype G