l3lab/ntp-mathlib huggingface dataset:
@[to_additive add_center_normal]
theorem center_normal : IsNormalSubgroup (center G) :=
  { one_mem := by simp [center]
    mul_mem := fun ha hb g => by
      rw [← mul_assoc, mem_center.2 ha g, mul_assoc, mem_center.2 hb g, ← mul_assoc]
    inv_mem := fun {a} ha g =>
      calc
        g * a⁻¹ = a⁻¹ * (g * a) * a⁻¹ := by 

Proof state:
G : Type u_1
H : Type u_2
A : Type u_3
a✝ a₁ a₂ b c : G
inst✝ : Group G
a : G
ha : a ∈ center G
g : G
⊢ g * a⁻¹ = a⁻¹ * (g * a) * a⁻¹

Next tactic:
simp [ha g]
@[to_additive add_center_normal]
theorem center_normal : IsNormalSubgroup (center G) :=
  { one_mem := by simp [center]
    mul_mem := fun ha hb g => by
      rw [← mul_assoc, mem_center.2 ha g, mul_assoc, mem_center.2 hb g, ← mul_assoc]
    inv_mem := fun {a} ha g =>
      calc
        g * a⁻¹ = a⁻¹ * (g * a) * a⁻¹ := by simp [ha g]
        _ = a⁻¹ * g := by 

Proof state:
G : Type u_1
H : Type u_2
A : Type u_3
a✝ a₁ a₂ b c : G
inst✝ : Group G
a : G
ha : a ∈ center G
g : G
⊢ a⁻¹ * (g * a) * a⁻¹ = a⁻¹ * g

Next tactic:
rw [← mul_assoc, mul_assoc]
@[to_additive add_center_normal]
theorem center_normal : IsNormalSubgroup (center G) :=
  { one_mem := by simp [center]
    mul_mem := fun ha hb g => by
      rw [← mul_assoc, mem_center.2 ha g, mul_assoc, mem_center.2 hb g, ← mul_assoc]
    inv_mem := fun {a} ha g =>
      calc
        g * a⁻¹ = a⁻¹ * (g * a) * a⁻¹ := by simp [ha g]
        _ = a⁻¹ * g := by rw [← mul_assoc, mul_assoc]; 

Proof state:
G : Type u_1
H : Type u_2
A : Type u_3
a✝ a₁ a₂ b c : G
inst✝ : Group G
a : G
ha : a ∈ center G
g : G
⊢ a⁻¹ * g * (a * a⁻¹) = a⁻¹ * g

Next tactic:
simp
@[to_additive add_center_normal]
theorem center_normal : IsNormalSubgroup (center G) :=
  { one_mem := by simp [center]
    mul_mem := fun ha hb g => by
      rw [← mul_assoc, mem_center.2 ha g, mul_assoc, mem_center.2 hb g, ← mul_assoc]
    inv_mem := fun {a} ha g =>
      calc
        g * a⁻¹ = a⁻¹ * (g * a) * a⁻¹ := by simp [ha g]
        _ = a⁻¹ * g := by rw [← mul_assoc, mul_assoc]; simp
    normal := fun n ha g h =>
      calc
        h * (g * n * g⁻¹) = h * n := by 

Proof state:
G : Type u_1
H : Type u_2
A : Type u_3
a a₁ a₂ b c : G
inst✝ : Group G
n : G
ha : n ∈ center G
g h : G
⊢ h * (g * n * g⁻¹) = h * n

Next tactic:
simp [ha g, mul_assoc]
@[to_additive add_center_normal]
theorem center_normal : IsNormalSubgroup (center G) :=
  { one_mem := by simp [center]
    mul_mem := fun ha hb g => by
      rw [← mul_assoc, mem_center.2 ha g, mul_assoc, mem_center.2 hb g, ← mul_assoc]
    inv_mem := fun {a} ha g =>
      calc
        g * a⁻¹ = a⁻¹ * (g * a) * a⁻¹ := by simp [ha g]
        _ = a⁻¹ * g := by rw [← mul_assoc, mul_assoc]; simp
    normal := fun n ha g h =>
      calc
        h * (g * n * g⁻¹) = h * n := by simp [ha g, mul_assoc]
        _ = g * g⁻¹ * n * h := by 

Proof state:
G : Type u_1
H : Type u_2
A : Type u_3
a a₁ a₂ b c : G
inst✝ : Group G
n : G
ha : n ∈ center G
g h : G
⊢ h * n = g * g⁻¹ * n * h

Next tactic:
rw [ha h]
@[to_additive add_center_normal]
theorem center_normal : IsNormalSubgroup (center G) :=
  { one_mem := by simp [center]
    mul_mem := fun ha hb g => by
      rw [← mul_assoc, mem_center.2 ha g, mul_assoc, mem_center.2 hb g, ← mul_assoc]
    inv_mem := fun {a} ha g =>
      calc
        g * a⁻¹ = a⁻¹ * (g * a) * a⁻¹ := by simp [ha g]
        _ = a⁻¹ * g := by rw [← mul_assoc, mul_assoc]; simp
    normal := fun n ha g h =>
      calc
        h * (g * n * g⁻¹) = h * n := by simp [ha g, mul_assoc]
        _ = g * g⁻¹ * n * h := by rw [ha h]; 

Proof state:
G : Type u_1
H : Type u_2
A : Type u_3
a a₁ a₂ b c : G
inst✝ : Group G
n : G
ha : n ∈ center G
g h : G
⊢ n * h = g * g⁻¹ * n * h

Next tactic:
simp
@[to_additive add_center_normal]
theorem center_normal : IsNormalSubgroup (center G) :=
  { one_mem := by simp [center]
    mul_mem := fun ha hb g => by
      rw [← mul_assoc, mem_center.2 ha g, mul_assoc, mem_center.2 hb g, ← mul_assoc]
    inv_mem := fun {a} ha g =>
      calc
        g * a⁻¹ = a⁻¹ * (g * a) * a⁻¹ := by simp [ha g]
        _ = a⁻¹ * g := by rw [← mul_assoc, mul_assoc]; simp
    normal := fun n ha g h =>
      calc
        h * (g * n * g⁻¹) = h * n := by simp [ha g, mul_assoc]
        _ = g * g⁻¹ * n * h := by rw [ha h]; simp
        _ = g * n * g⁻¹ * h := by 

Proof state:
G : Type u_1
H : Type u_2
A : Type u_3
a a₁ a₂ b c : G
inst✝ : Group G
n : G
ha : n ∈ center G
g h : G
⊢ g * g⁻¹ * n * h = g * n * g⁻¹ * h

Next tactic:
rw [mul_assoc g, ha g⁻¹, ← mul_assoc]
@[to_additive]
theorem normalizer_isSubgroup (s : Set G) : IsSubgroup (normalizer s) :=
  { one_mem := by 

Proof state:
G : Type u_1
H : Type u_2
A : Type u_3
a a₁ a₂ b c : G
inst✝ : Group G
s : Set G
⊢ 1 ∈ normalizer s

Next tactic:
simp [normalizer]
@[to_additive]
theorem normalizer_isSubgroup (s : Set G) : IsSubgroup (normalizer s) :=
  { one_mem := by simp [normalizer]
    mul_mem := fun {a b}
      (ha : ∀ n, n ∈ s ↔ a * n * a⁻¹ ∈ s) (hb : ∀ n, n ∈ s ↔ b * n * b⁻¹ ∈ s) n =>
      by 

Proof state:
G : Type u_1
H : Type u_2
A : Type u_3
a✝ a₁ a₂ b✝ c : G
inst✝ : Group G
s : Set G
a b : G
ha : ∀ (n : G), n ∈ s ↔ a * n * a⁻¹ ∈ s
hb : ∀ (n : G), n ∈ s ↔ b * n * b⁻¹ ∈ s
n : G
⊢ n ∈ s ↔ a * b * n * (a * b)⁻¹ ∈ s

Next tactic:
rw [mul_inv_rev, ← mul_assoc, mul_assoc a, mul_assoc a, ← ha, ← hb]
@[to_additive]
theorem normalizer_isSubgroup (s : Set G) : IsSubgroup (normalizer s) :=
  { one_mem := by simp [normalizer]
    mul_mem := fun {a b}
      (ha : ∀ n, n ∈ s ↔ a * n * a⁻¹ ∈ s) (hb : ∀ n, n ∈ s ↔ b * n * b⁻¹ ∈ s) n =>
      by rw [mul_inv_rev, ← mul_assoc, mul_assoc a, mul_assoc a, ← ha, ← hb]
    inv_mem := fun {a} (ha : ∀ n, n ∈ s ↔ a * n * a⁻¹ ∈ s) n => by
      

Proof state:
G : Type u_1
H : Type u_2
A : Type u_3
a✝ a₁ a₂ b c : G
inst✝ : Group G
s : Set G
a : G
ha : ∀ (n : G), n ∈ s ↔ a * n * a⁻¹ ∈ s
n : G
⊢ n ∈ s ↔ a⁻¹ * n * a⁻¹⁻¹ ∈ s

Next tactic:
rw [ha (a⁻¹ * n * a⁻¹⁻¹)]
@[to_additive]
theorem normalizer_isSubgroup (s : Set G) : IsSubgroup (normalizer s) :=
  { one_mem := by simp [normalizer]
    mul_mem := fun {a b}
      (ha : ∀ n, n ∈ s ↔ a * n * a⁻¹ ∈ s) (hb : ∀ n, n ∈ s ↔ b * n * b⁻¹ ∈ s) n =>
      by rw [mul_inv_rev, ← mul_assoc, mul_assoc a, mul_assoc a, ← ha, ← hb]
    inv_mem := fun {a} (ha : ∀ n, n ∈ s ↔ a * n * a⁻¹ ∈ s) n => by
      rw [ha (a⁻¹ * n * a⁻¹⁻¹)]; 

Proof state:
G : Type u_1
H : Type u_2
A : Type u_3
a✝ a₁ a₂ b c : G
inst✝ : Group G
s : Set G
a : G
ha : ∀ (n : G), n ∈ s ↔ a * n * a⁻¹ ∈ s
n : G
⊢ n ∈ s ↔ a * (a⁻¹ * n * a⁻¹⁻¹) * a⁻¹ ∈ s

Next tactic:
simp [mul_assoc]
@[to_additive subset_add_normalizer]
theorem subset_normalizer {s : Set G} (hs : IsSubgroup s) : s ⊆ normalizer s := fun g hg n => by
  

Proof state:
G : Type u_1
H : Type u_2
A : Type u_3
a a₁ a₂ b c : G
inst✝ : Group G
s : Set G
hs : IsSubgroup s
g : G
hg : g ∈ s
n : G
⊢ n ∈ s ↔ g * n * g⁻¹ ∈ s

Next tactic:
rw [IsSubgroup.mul_mem_cancel_right hs ((IsSubgroup.inv_mem_iff hs).2 hg),
    IsSubgroup.mul_mem_cancel_left hs hg]
@[to_additive]
theorem one_ker_inv {f : G → H} (hf : IsGroupHom f) {a b : G} (h : f (a * b⁻¹) = 1) :
    f a = f b := by
  

Proof state:
G : Type u_1
H : Type u_2
A : Type u_3
a✝ a₁ a₂ b✝ c : G
inst✝¹ : Group G
inst✝ : Group H
f : G → H
hf : IsGroupHom f
a b : G
h : f (a * b⁻¹) = 1
⊢ f a = f b

Next tactic:
rw [hf.map_mul, hf.map_inv] at h
@[to_additive]
theorem one_ker_inv {f : G → H} (hf : IsGroupHom f) {a b : G} (h : f (a * b⁻¹) = 1) :
    f a = f b := by
  rw [hf.map_mul, hf.map_inv] at h
  

Proof state:
G : Type u_1
H : Type u_2
A : Type u_3
a✝ a₁ a₂ b✝ c : G
inst✝¹ : Group G
inst✝ : Group H
f : G → H
hf : IsGroupHom f
a b : G
h : f a * (f b)⁻¹ = 1
⊢ f a = f b

Next tactic:
rw [← inv_inv (f b), eq_inv_of_mul_eq_one_left h]
@[to_additive]
theorem one_ker_inv' {f : G → H} (hf : IsGroupHom f) {a b : G} (h : f (a⁻¹ * b) = 1) :
    f a = f b := by
  

Proof state:
G : Type u_1
H : Type u_2
A : Type u_3
a✝ a₁ a₂ b✝ c : G
inst✝¹ : Group G
inst✝ : Group H
f : G → H
hf : IsGroupHom f
a b : G
h : f (a⁻¹ * b) = 1
⊢ f a = f b

Next tactic:
rw [hf.map_mul, hf.map_inv] at h
@[to_additive]
theorem one_ker_inv' {f : G → H} (hf : IsGroupHom f) {a b : G} (h : f (a⁻¹ * b) = 1) :
    f a = f b := by
  rw [hf.map_mul, hf.map_inv] at h
  

Proof state:
G : Type u_1
H : Type u_2
A : Type u_3
a✝ a₁ a₂ b✝ c : G
inst✝¹ : Group G
inst✝ : Group H
f : G → H
hf : IsGroupHom f
a b : G
h : (f a)⁻¹ * f b = 1
⊢ f a = f b

Next tactic:
apply inv_injective
@[to_additive]
theorem one_ker_inv' {f : G → H} (hf : IsGroupHom f) {a b : G} (h : f (a⁻¹ * b) = 1) :
    f a = f b := by
  rw [hf.map_mul, hf.map_inv] at h
  apply inv_injective
  

Proof state:
case a
G : Type u_1
H : Type u_2
A : Type u_3
a✝ a₁ a₂ b✝ c : G
inst✝¹ : Group G
inst✝ : Group H
f : G → H
hf : IsGroupHom f
a b : G
h : (f a)⁻¹ * f b = 1
⊢ (f a)⁻¹ = (f b)⁻¹

Next tactic:
rw [eq_inv_of_mul_eq_one_left h]
@[to_additive]
theorem inv_ker_one {f : G → H} (hf : IsGroupHom f) {a b : G} (h : f a = f b) :
    f (a * b⁻¹) = 1 := by
  

Proof state:
G : Type u_1
H : Type u_2
A : Type u_3
a✝ a₁ a₂ b✝ c : G
inst✝¹ : Group G
inst✝ : Group H
f : G → H
hf : IsGroupHom f
a b : G
h : f a = f b
⊢ f (a * b⁻¹) = 1

Next tactic:
have : f a * (f b)⁻¹ = 1 := by rw [h, mul_right_inv]
@[to_additive]
theorem inv_ker_one {f : G → H} (hf : IsGroupHom f) {a b : G} (h : f a = f b) :
    f (a * b⁻¹) = 1 := by
  have : f a * (f b)⁻¹ = 1 := by 

Proof state:
G : Type u_1
H : Type u_2
A : Type u_3
a✝ a₁ a₂ b✝ c : G
inst✝¹ : Group G
inst✝ : Group H
f : G → H
hf : IsGroupHom f
a b : G
h : f a = f b
⊢ f a * (f b)⁻¹ = 1

Next tactic:
rw [h, mul_right_inv]
@[to_additive]
theorem inv_ker_one {f : G → H} (hf : IsGroupHom f) {a b : G} (h : f a = f b) :
    f (a * b⁻¹) = 1 := by
  have : f a * (f b)⁻¹ = 1 := by rw [h, mul_right_inv]
  

Proof state:
G : Type u_1
H : Type u_2
A : Type u_3
a✝ a₁ a₂ b✝ c : G
inst✝¹ : Group G
inst✝ : Group H
f : G → H
hf : IsGroupHom f
a b : G
h : f a = f b
this : f a * (f b)⁻¹ = 1
⊢ f (a * b⁻¹) = 1

Next tactic:
rwa [← hf.map_inv, ← hf.map_mul] at this
@[to_additive]
theorem inv_ker_one' {f : G → H} (hf : IsGroupHom f) {a b : G} (h : f a = f b) :
    f (a⁻¹ * b) = 1 := by
  

Proof state:
G : Type u_1
H : Type u_2
A : Type u_3
a✝ a₁ a₂ b✝ c : G
inst✝¹ : Group G
inst✝ : Group H
f : G → H
hf : IsGroupHom f
a b : G
h : f a = f b
⊢ f (a⁻¹ * b) = 1

Next tactic:
have : (f a)⁻¹ * f b = 1 := by rw [h, mul_left_inv]
@[to_additive]
theorem inv_ker_one' {f : G → H} (hf : IsGroupHom f) {a b : G} (h : f a = f b) :
    f (a⁻¹ * b) = 1 := by
  have : (f a)⁻¹ * f b = 1 := by 

Proof state:
G : Type u_1
H : Type u_2
A : Type u_3
a✝ a₁ a₂ b✝ c : G
inst✝¹ : Group G
inst✝ : Group H
f : G → H
hf : IsGroupHom f
a b : G
h : f a = f b
⊢ (f a)⁻¹ * f b = 1

Next tactic:
rw [h, mul_left_inv]
@[to_additive]
theorem inv_ker_one' {f : G → H} (hf : IsGroupHom f) {a b : G} (h : f a = f b) :
    f (a⁻¹ * b) = 1 := by
  have : (f a)⁻¹ * f b = 1 := by rw [h, mul_left_inv]
  

Proof state:
G : Type u_1
H : Type u_2
A : Type u_3
a✝ a₁ a₂ b✝ c : G
inst✝¹ : Group G
inst✝ : Group H
f : G → H
hf : IsGroupHom f
a b : G
h : f a = f b
this : (f a)⁻¹ * f b = 1
⊢ f (a⁻¹ * b) = 1

Next tactic:
rwa [← hf.map_inv, ← hf.map_mul] at this
@[to_additive]
theorem inv_iff_ker {f : G → H} (hf : IsGroupHom f) (a b : G) : f a = f b ↔ a * b⁻¹ ∈ ker f := by
  

Proof state:
G : Type u_1
H : Type u_2
A : Type u_3
a✝ a₁ a₂ b✝ c : G
inst✝¹ : Group G
inst✝ : Group H
f : G → H
hf : IsGroupHom f
a b : G
⊢ f a = f b ↔ a * b⁻¹ ∈ ker f

Next tactic:
rw [mem_ker]
@[to_additive]
theorem inv_iff_ker {f : G → H} (hf : IsGroupHom f) (a b : G) : f a = f b ↔ a * b⁻¹ ∈ ker f := by
  rw [mem_ker]; 

Proof state:
G : Type u_1
H : Type u_2
A : Type u_3
a✝ a₁ a₂ b✝ c : G
inst✝¹ : Group G
inst✝ : Group H
f : G → H
hf : IsGroupHom f
a b : G
⊢ f a = f b ↔ f (a * b⁻¹) = 1

Next tactic:
exact one_iff_ker_inv hf _ _
@[to_additive]
theorem inv_iff_ker' {f : G → H} (hf : IsGroupHom f) (a b : G) : f a = f b ↔ a⁻¹ * b ∈ ker f := by
  

Proof state:
G : Type u_1
H : Type u_2
A : Type u_3
a✝ a₁ a₂ b✝ c : G
inst✝¹ : Group G
inst✝ : Group H
f : G → H
hf : IsGroupHom f
a b : G
⊢ f a = f b ↔ a⁻¹ * b ∈ ker f

Next tactic:
rw [mem_ker]
@[to_additive]
theorem inv_iff_ker' {f : G → H} (hf : IsGroupHom f) (a b : G) : f a = f b ↔ a⁻¹ * b ∈ ker f := by
  rw [mem_ker]; 

Proof state:
G : Type u_1
H : Type u_2
A : Type u_3
a✝ a₁ a₂ b✝ c : G
inst✝¹ : Group G
inst✝ : Group H
f : G → H
hf : IsGroupHom f
a b : G
⊢ f a = f b ↔ f (a⁻¹ * b) = 1

Next tactic:
exact one_iff_ker_inv' hf _ _
@[to_additive]
theorem image_subgroup {f : G → H} (hf : IsGroupHom f) {s : Set G} (hs : IsSubgroup s) :
    IsSubgroup (f '' s) :=
  { mul_mem := fun {a₁ a₂} ⟨b₁, hb₁, eq₁⟩ ⟨b₂, hb₂, eq₂⟩ =>
      ⟨b₁ * b₂, hs.mul_mem hb₁ hb₂, by 

Proof state:
G : Type u_1
H : Type u_2
A : Type u_3
a a₁✝ a₂✝ b c : G
inst✝¹ : Group G
inst✝ : Group H
f : G → H
hf : IsGroupHom f
s : Set G
hs : IsSubgroup s
a₁ a₂ : H
x✝¹ : a₁ ∈ f '' s
x✝ : a₂ ∈ f '' s
b₁ : G
hb₁ : b₁ ∈ s
eq₁ : f b₁ = a₁
b₂ : G
hb₂ : b₂ ∈ s
eq₂ : f b₂ = a₂
⊢ f (b₁ * b₂) = a₁ * a₂

Next tactic:
simp [eq₁, eq₂, hf.map_mul]
@[to_additive]
theorem image_subgroup {f : G → H} (hf : IsGroupHom f) {s : Set G} (hs : IsSubgroup s) :
    IsSubgroup (f '' s) :=
  { mul_mem := fun {a₁ a₂} ⟨b₁, hb₁, eq₁⟩ ⟨b₂, hb₂, eq₂⟩ =>
      ⟨b₁ * b₂, hs.mul_mem hb₁ hb₂, by simp [eq₁, eq₂, hf.map_mul]⟩
    one_mem := ⟨1, hs.toIsSubmonoid.one_mem, hf.map_one⟩
    inv_mem := fun {a} ⟨b, hb, Eq⟩ =>
      ⟨b⁻¹, hs.inv_mem hb, by
        

Proof state:
G : Type u_1
H : Type u_2
A : Type u_3
a✝ a₁ a₂ b✝ c : G
inst✝¹ : Group G
inst✝ : Group H
f : G → H
hf : IsGroupHom f
s : Set G
hs : IsSubgroup s
a : H
x✝ : a ∈ f '' s
b : G
hb : b ∈ s
Eq : f b = a
⊢ f b⁻¹ = a⁻¹

Next tactic:
rw [hf.map_inv]
@[to_additive]
theorem image_subgroup {f : G → H} (hf : IsGroupHom f) {s : Set G} (hs : IsSubgroup s) :
    IsSubgroup (f '' s) :=
  { mul_mem := fun {a₁ a₂} ⟨b₁, hb₁, eq₁⟩ ⟨b₂, hb₂, eq₂⟩ =>
      ⟨b₁ * b₂, hs.mul_mem hb₁ hb₂, by simp [eq₁, eq₂, hf.map_mul]⟩
    one_mem := ⟨1, hs.toIsSubmonoid.one_mem, hf.map_one⟩
    inv_mem := fun {a} ⟨b, hb, Eq⟩ =>
      ⟨b⁻¹, hs.inv_mem hb, by
        rw [hf.map_inv]
        

Proof state:
G : Type u_1
H : Type u_2
A : Type u_3
a✝ a₁ a₂ b✝ c : G
inst✝¹ : Group G
inst✝ : Group H
f : G → H
hf : IsGroupHom f
s : Set G
hs : IsSubgroup s
a : H
x✝ : a ∈ f '' s
b : G
hb : b ∈ s
Eq : f b = a
⊢ (f b)⁻¹ = a⁻¹

Next tactic:
simp [*]
@[to_additive]
theorem preimage {f : G → H} (hf : IsGroupHom f) {s : Set H} (hs : IsSubgroup s) :
    IsSubgroup (f ⁻¹' s) := by
  

Proof state:
G : Type u_1
H : Type u_2
A : Type u_3
a a₁ a₂ b c : G
inst✝¹ : Group G
inst✝ : Group H
f : G → H
hf : IsGroupHom f
s : Set H
hs : IsSubgroup s
⊢ IsSubgroup (f ⁻¹' s)

Next tactic:
refine' { .. }
@[to_additive]
theorem preimage {f : G → H} (hf : IsGroupHom f) {s : Set H} (hs : IsSubgroup s) :
    IsSubgroup (f ⁻¹' s) := by
  refine' { .. } <;>
    

Proof state:
case refine'_1
G : Type u_1
H : Type u_2
A : Type u_3
a a₁ a₂ b c : G
inst✝¹ : Group G
inst✝ : Group H
f : G → H
hf : IsGroupHom f
s : Set H
hs : IsSubgroup s
⊢ 1 ∈ f ⁻¹' s

Next tactic:
simp (config := { contextual := true }) [hs.one_mem, hs.mul_mem, hs.inv_mem, hf.map_mul,
      hf.map_one, hf.map_inv, InvMemClass.inv_mem]
@[to_additive]
theorem preimage {f : G → H} (hf : IsGroupHom f) {s : Set H} (hs : IsSubgroup s) :
    IsSubgroup (f ⁻¹' s) := by
  refine' { .. } <;>
    

Proof state:
case refine'_2
G : Type u_1
H : Type u_2
A : Type u_3
a a₁ a₂ b c : G
inst✝¹ : Group G
inst✝ : Group H
f : G → H
hf : IsGroupHom f
s : Set H
hs : IsSubgroup s
⊢ ∀ {a b : G}, a ∈ f ⁻¹' s → b ∈ f ⁻¹' s → a * b ∈ f ⁻¹' s

Next tactic:
simp (config := { contextual := true }) [hs.one_mem, hs.mul_mem, hs.inv_mem, hf.map_mul,
      hf.map_one, hf.map_inv, InvMemClass.inv_mem]
@[to_additive]
theorem preimage {f : G → H} (hf : IsGroupHom f) {s : Set H} (hs : IsSubgroup s) :
    IsSubgroup (f ⁻¹' s) := by
  refine' { .. } <;>
    

Proof state:
case refine'_3
G : Type u_1
H : Type u_2
A : Type u_3
a a₁ a₂ b c : G
inst✝¹ : Group G
inst✝ : Group H
f : G → H
hf : IsGroupHom f
s : Set H
hs : IsSubgroup s
⊢ ∀ {a : G}, a ∈ f ⁻¹' s → a⁻¹ ∈ f ⁻¹' s

Next tactic:
simp (config := { contextual := true }) [hs.one_mem, hs.mul_mem, hs.inv_mem, hf.map_mul,
      hf.map_one, hf.map_inv, InvMemClass.inv_mem]
@[to_additive]
theorem preimage_normal {f : G → H} (hf : IsGroupHom f) {s : Set H} (hs : IsNormalSubgroup s) :
    IsNormalSubgroup (f ⁻¹' s) :=
  { one_mem := by 

Proof state:
G : Type u_1
H : Type u_2
A : Type u_3
a a₁ a₂ b c : G
inst✝¹ : Group G
inst✝ : Group H
f : G → H
hf : IsGroupHom f
s : Set H
hs : IsNormalSubgroup s
⊢ 1 ∈ f ⁻¹' s

Next tactic:
simp [hf.map_one, hs.toIsSubgroup.one_mem]
@[to_additive]
theorem preimage_normal {f : G → H} (hf : IsGroupHom f) {s : Set H} (hs : IsNormalSubgroup s) :
    IsNormalSubgroup (f ⁻¹' s) :=
  { one_mem := by simp [hf.map_one, hs.toIsSubgroup.one_mem]
    mul_mem := by 

Proof state:
G : Type u_1
H : Type u_2
A : Type u_3
a a₁ a₂ b c : G
inst✝¹ : Group G
inst✝ : Group H
f : G → H
hf : IsGroupHom f
s : Set H
hs : IsNormalSubgroup s
⊢ ∀ {a b : G}, a ∈ f ⁻¹' s → b ∈ f ⁻¹' s → a * b ∈ f ⁻¹' s

Next tactic:
simp (config := { contextual := true }) [hf.map_mul, hs.toIsSubgroup.mul_mem]
@[to_additive]
theorem preimage_normal {f : G → H} (hf : IsGroupHom f) {s : Set H} (hs : IsNormalSubgroup s) :
    IsNormalSubgroup (f ⁻¹' s) :=
  { one_mem := by simp [hf.map_one, hs.toIsSubgroup.one_mem]
    mul_mem := by simp (config := { contextual := true }) [hf.map_mul, hs.toIsSubgroup.mul_mem]
    inv_mem := by 

Proof state:
G : Type u_1
H : Type u_2
A : Type u_3
a a₁ a₂ b c : G
inst✝¹ : Group G
inst✝ : Group H
f : G → H
hf : IsGroupHom f
s : Set H
hs : IsNormalSubgroup s
⊢ ∀ {a : G}, a ∈ f ⁻¹' s → a⁻¹ ∈ f ⁻¹' s

Next tactic:
simp (config := { contextual := true }) [hf.map_inv, hs.toIsSubgroup.inv_mem]
@[to_additive]
theorem preimage_normal {f : G → H} (hf : IsGroupHom f) {s : Set H} (hs : IsNormalSubgroup s) :
    IsNormalSubgroup (f ⁻¹' s) :=
  { one_mem := by simp [hf.map_one, hs.toIsSubgroup.one_mem]
    mul_mem := by simp (config := { contextual := true }) [hf.map_mul, hs.toIsSubgroup.mul_mem]
    inv_mem := by simp (config := { contextual := true }) [hf.map_inv, hs.toIsSubgroup.inv_mem]
    normal := by 

Proof state:
G : Type u_1
H : Type u_2
A : Type u_3
a a₁ a₂ b c : G
inst✝¹ : Group G
inst✝ : Group H
f : G → H
hf : IsGroupHom f
s : Set H
hs : IsNormalSubgroup s
⊢ ∀ n ∈ f ⁻¹' s, ∀ (g : G), g * n * g⁻¹ ∈ f ⁻¹' s

Next tactic:
simp (config := { contextual := true }) [hs.normal, hf.map_mul, hf.map_inv]
@[to_additive]
theorem injective_of_trivial_ker {f : G → H} (hf : IsGroupHom f) (h : ker f = trivial G) :
    Function.Injective f := by
  

Proof state:
G : Type u_1
H : Type u_2
A : Type u_3
a a₁ a₂ b c : G
inst✝¹ : Group G
inst✝ : Group H
f : G → H
hf : IsGroupHom f
h : ker f = IsSubgroup.trivial G
⊢ Injective f

Next tactic:
intro a₁ a₂ hfa
@[to_additive]
theorem injective_of_trivial_ker {f : G → H} (hf : IsGroupHom f) (h : ker f = trivial G) :
    Function.Injective f := by
  intro a₁ a₂ hfa
  

Proof state:
G : Type u_1
H : Type u_2
A : Type u_3
a a₁✝ a₂✝ b c : G
inst✝¹ : Group G
inst✝ : Group H
f : G → H
hf : IsGroupHom f
h : ker f = IsSubgroup.trivial G
a₁ a₂ : G
hfa : f a₁ = f a₂
⊢ a₁ = a₂

Next tactic:
simp [ext_iff, ker, IsSubgroup.trivial] at h
@[to_additive]
theorem injective_of_trivial_ker {f : G → H} (hf : IsGroupHom f) (h : ker f = trivial G) :
    Function.Injective f := by
  intro a₁ a₂ hfa
  simp [ext_iff, ker, IsSubgroup.trivial] at h
  

Proof state:
G : Type u_1
H : Type u_2
A : Type u_3
a a₁✝ a₂✝ b c : G
inst✝¹ : Group G
inst✝ : Group H
f : G → H
hf : IsGroupHom f
a₁ a₂ : G
hfa : f a₁ = f a₂
h : ∀ (x : G), f x = 1 ↔ x = 1
⊢ a₁ = a₂

Next tactic:
have ha : a₁ * a₂⁻¹ = 1 := by rw [← h]; exact hf.inv_ker_one hfa
@[to_additive]
theorem injective_of_trivial_ker {f : G → H} (hf : IsGroupHom f) (h : ker f = trivial G) :
    Function.Injective f := by
  intro a₁ a₂ hfa
  simp [ext_iff, ker, IsSubgroup.trivial] at h
  have ha : a₁ * a₂⁻¹ = 1 := by 

Proof state:
G : Type u_1
H : Type u_2
A : Type u_3
a a₁✝ a₂✝ b c : G
inst✝¹ : Group G
inst✝ : Group H
f : G → H
hf : IsGroupHom f
a₁ a₂ : G
hfa : f a₁ = f a₂
h : ∀ (x : G), f x = 1 ↔ x = 1
⊢ a₁ * a₂⁻¹ = 1

Next tactic:
rw [← h]
@[to_additive]
theorem injective_of_trivial_ker {f : G → H} (hf : IsGroupHom f) (h : ker f = trivial G) :
    Function.Injective f := by
  intro a₁ a₂ hfa
  simp [ext_iff, ker, IsSubgroup.trivial] at h
  have ha : a₁ * a₂⁻¹ = 1 := by rw [← h]; 

Proof state:
G : Type u_1
H : Type u_2
A : Type u_3
a a₁✝ a₂✝ b c : G
inst✝¹ : Group G
inst✝ : Group H
f : G → H
hf : IsGroupHom f
a₁ a₂ : G
hfa : f a₁ = f a₂
h : ∀ (x : G), f x = 1 ↔ x = 1
⊢ f (a₁ * a₂⁻¹) = 1

Next tactic:
exact hf.inv_ker_one hfa
@[to_additive]
theorem injective_of_trivial_ker {f : G → H} (hf : IsGroupHom f) (h : ker f = trivial G) :
    Function.Injective f := by
  intro a₁ a₂ hfa
  simp [ext_iff, ker, IsSubgroup.trivial] at h
  have ha : a₁ * a₂⁻¹ = 1 := by rw [← h]; exact hf.inv_ker_one hfa
  

Proof state:
G : Type u_1
H : Type u_2
A : Type u_3
a a₁✝ a₂✝ b c : G
inst✝¹ : Group G
inst✝ : Group H
f : G → H
hf : IsGroupHom f
a₁ a₂ : G
hfa : f a₁ = f a₂
h : ∀ (x : G), f x = 1 ↔ x = 1
ha : a₁ * a₂⁻¹ = 1
⊢ a₁ = a₂

Next tactic:
rw [eq_inv_of_mul_eq_one_left ha, inv_inv a₂]
@[to_additive]
theorem trivial_ker_of_injective {f : G → H} (hf : IsGroupHom f) (h : Function.Injective f) :
    ker f = trivial G :=
  Set.ext fun x =>
    Iff.intro
      (fun hx => by
        

Proof state:
G : Type u_1
H : Type u_2
A : Type u_3
a a₁ a₂ b c : G
inst✝¹ : Group G
inst✝ : Group H
f : G → H
hf : IsGroupHom f
h : Injective f
x : G
hx : x ∈ ker f
⊢ x ∈ IsSubgroup.trivial G

Next tactic:
suffices f x = f 1 by simpa using h this
@[to_additive]
theorem trivial_ker_of_injective {f : G → H} (hf : IsGroupHom f) (h : Function.Injective f) :
    ker f = trivial G :=
  Set.ext fun x =>
    Iff.intro
      (fun hx => by
        suffices f x = f 1 by 

Proof state:
G : Type u_1
H : Type u_2
A : Type u_3
a a₁ a₂ b c : G
inst✝¹ : Group G
inst✝ : Group H
f : G → H
hf : IsGroupHom f
h : Injective f
x : G
hx : x ∈ ker f
this : f x = f 1
⊢ x ∈ IsSubgroup.trivial G

Next tactic:
simpa using h this
@[to_additive]
theorem trivial_ker_of_injective {f : G → H} (hf : IsGroupHom f) (h : Function.Injective f) :
    ker f = trivial G :=
  Set.ext fun x =>
    Iff.intro
      (fun hx => by
        suffices f x = f 1 by simpa using h this
        

Proof state:
G : Type u_1
H : Type u_2
A : Type u_3
a a₁ a₂ b c : G
inst✝¹ : Group G
inst✝ : Group H
f : G → H
hf : IsGroupHom f
h : Injective f
x : G
hx : x ∈ ker f
⊢ f x = f 1

Next tactic:
simp [hf.map_one]
@[to_additive]
theorem trivial_ker_of_injective {f : G → H} (hf : IsGroupHom f) (h : Function.Injective f) :
    ker f = trivial G :=
  Set.ext fun x =>
    Iff.intro
      (fun hx => by
        suffices f x = f 1 by simpa using h this
        simp [hf.map_one]; 

Proof state:
G : Type u_1
H : Type u_2
A : Type u_3
a a₁ a₂ b c : G
inst✝¹ : Group G
inst✝ : Group H
f : G → H
hf : IsGroupHom f
h : Injective f
x : G
hx : x ∈ ker f
⊢ f x = 1

Next tactic:
rwa [mem_ker] at hx
@[to_additive]
theorem trivial_ker_of_injective {f : G → H} (hf : IsGroupHom f) (h : Function.Injective f) :
    ker f = trivial G :=
  Set.ext fun x =>
    Iff.intro
      (fun hx => by
        suffices f x = f 1 by simpa using h this
        simp [hf.map_one]; rwa [mem_ker] at hx)
      (by 

Proof state:
G : Type u_1
H : Type u_2
A : Type u_3
a a₁ a₂ b c : G
inst✝¹ : Group G
inst✝ : Group H
f : G → H
hf : IsGroupHom f
h : Injective f
x : G
⊢ x ∈ IsSubgroup.trivial G → x ∈ ker f

Next tactic:
simp (config := { contextual := true }) [mem_ker, hf.map_one]
@[to_additive]
theorem trivial_ker_iff_eq_one {f : G → H} (hf : IsGroupHom f) :
    ker f = trivial G ↔ ∀ x, f x = 1 → x = 1 := by
  

Proof state:
G : Type u_1
H : Type u_2
A : Type u_3
a a₁ a₂ b c : G
inst✝¹ : Group G
inst✝ : Group H
f : G → H
hf : IsGroupHom f
⊢ ker f = IsSubgroup.trivial G ↔ ∀ (x : G), f x = 1 → x = 1

Next tactic:
rw [Set.ext_iff]
@[to_additive]
theorem trivial_ker_iff_eq_one {f : G → H} (hf : IsGroupHom f) :
    ker f = trivial G ↔ ∀ x, f x = 1 → x = 1 := by
  rw [Set.ext_iff]; 

Proof state:
G : Type u_1
H : Type u_2
A : Type u_3
a a₁ a₂ b c : G
inst✝¹ : Group G
inst✝ : Group H
f : G → H
hf : IsGroupHom f
⊢ (∀ (x : G), x ∈ ker f ↔ x ∈ IsSubgroup.trivial G) ↔ ∀ (x : G), f x = 1 → x = 1

Next tactic:
simp [ker]