l3lab/ntp-mathlib huggingface dataset:
/-- An induction principle for elements of `⨆ i, S i`.
If `C` holds for `1` and all elements of `S i` for all `i`, and is preserved under multiplication,
then it holds for all elements of the supremum of `S`. -/
@[to_additive (attr := elab_as_elim) " An induction principle for elements of `⨆ i, S i`.
If `C` holds for `0` and all elements of `S i` for all `i`, and is preserved under addition,
then it holds for all elements of the supremum of `S`. "]
theorem iSup_induction {ι : Sort*} (S : ι → Subgroup G) {C : G → Prop} {x : G} (hx : x ∈ ⨆ i, S i)
    (hp : ∀ (i), ∀ x ∈ S i, C x) (h1 : C 1) (hmul : ∀ x y, C x → C y → C (x * y)) : C x := by
  rw [iSup_eq_closure] at hx
  refine' closure_induction'' hx (fun x hx => _) (fun x hx => _) h1 hmul
  · obtain ⟨i, hi⟩ := Set.mem_iUnion.mp hx
    

Proof state:
case refine'_1.intro
α : Type u_1
G : Type u_2
A : Type u_3
S✝ : Type u_4
inst✝¹ : Group G
inst✝ : AddGroup A
s : Set G
ι : Sort u_5
S : ι → Subgroup G
C : G → Prop
x✝ : G
hx✝ : x✝ ∈ closure (⋃ i, ↑(S i))
hp : ∀ (i : ι), ∀ x ∈ S i, C x
h1 : C 1
hmul : ∀ (x y : G), C x → C y → C (x * y)
x : G
hx : x ∈ ⋃ i, ↑(S i)
i : ι
hi : x ∈ ↑(S i)
⊢ C x

Next tactic:
exact hp _ _ hi
/-- An induction principle for elements of `⨆ i, S i`.
If `C` holds for `1` and all elements of `S i` for all `i`, and is preserved under multiplication,
then it holds for all elements of the supremum of `S`. -/
@[to_additive (attr := elab_as_elim) " An induction principle for elements of `⨆ i, S i`.
If `C` holds for `0` and all elements of `S i` for all `i`, and is preserved under addition,
then it holds for all elements of the supremum of `S`. "]
theorem iSup_induction {ι : Sort*} (S : ι → Subgroup G) {C : G → Prop} {x : G} (hx : x ∈ ⨆ i, S i)
    (hp : ∀ (i), ∀ x ∈ S i, C x) (h1 : C 1) (hmul : ∀ x y, C x → C y → C (x * y)) : C x := by
  rw [iSup_eq_closure] at hx
  refine' closure_induction'' hx (fun x hx => _) (fun x hx => _) h1 hmul
  · obtain ⟨i, hi⟩ := Set.mem_iUnion.mp hx
    exact hp _ _ hi
  · 

Proof state:
case refine'_2
α : Type u_1
G : Type u_2
A : Type u_3
S✝ : Type u_4
inst✝¹ : Group G
inst✝ : AddGroup A
s : Set G
ι : Sort u_5
S : ι → Subgroup G
C : G → Prop
x✝ : G
hx✝ : x✝ ∈ closure (⋃ i, ↑(S i))
hp : ∀ (i : ι), ∀ x ∈ S i, C x
h1 : C 1
hmul : ∀ (x y : G), C x → C y → C (x * y)
x : G
hx : x ∈ ⋃ i, ↑(S i)
⊢ C x⁻¹

Next tactic:
obtain ⟨i, hi⟩ := Set.mem_iUnion.mp hx
/-- An induction principle for elements of `⨆ i, S i`.
If `C` holds for `1` and all elements of `S i` for all `i`, and is preserved under multiplication,
then it holds for all elements of the supremum of `S`. -/
@[to_additive (attr := elab_as_elim) " An induction principle for elements of `⨆ i, S i`.
If `C` holds for `0` and all elements of `S i` for all `i`, and is preserved under addition,
then it holds for all elements of the supremum of `S`. "]
theorem iSup_induction {ι : Sort*} (S : ι → Subgroup G) {C : G → Prop} {x : G} (hx : x ∈ ⨆ i, S i)
    (hp : ∀ (i), ∀ x ∈ S i, C x) (h1 : C 1) (hmul : ∀ x y, C x → C y → C (x * y)) : C x := by
  rw [iSup_eq_closure] at hx
  refine' closure_induction'' hx (fun x hx => _) (fun x hx => _) h1 hmul
  · obtain ⟨i, hi⟩ := Set.mem_iUnion.mp hx
    exact hp _ _ hi
  · obtain ⟨i, hi⟩ := Set.mem_iUnion.mp hx
    

Proof state:
case refine'_2.intro
α : Type u_1
G : Type u_2
A : Type u_3
S✝ : Type u_4
inst✝¹ : Group G
inst✝ : AddGroup A
s : Set G
ι : Sort u_5
S : ι → Subgroup G
C : G → Prop
x✝ : G
hx✝ : x✝ ∈ closure (⋃ i, ↑(S i))
hp : ∀ (i : ι), ∀ x ∈ S i, C x
h1 : C 1
hmul : ∀ (x y : G), C x → C y → C (x * y)
x : G
hx : x ∈ ⋃ i, ↑(S i)
i : ι
hi : x ∈ ↑(S i)
⊢ C x⁻¹

Next tactic:
exact hp _ _ (inv_mem hi)
/-- A dependent version of `Subgroup.iSup_induction`. -/
@[to_additive (attr := elab_as_elim) "A dependent version of `AddSubgroup.iSup_induction`. "]
theorem iSup_induction' {ι : Sort*} (S : ι → Subgroup G) {C : ∀ x, (x ∈ ⨆ i, S i) → Prop}
    (hp : ∀ (i), ∀ x (hx : x ∈ S i), C x (mem_iSup_of_mem i hx)) (h1 : C 1 (one_mem _))
    (hmul : ∀ x y hx hy, C x hx → C y hy → C (x * y) (mul_mem ‹_› ‹_›)) {x : G}
    (hx : x ∈ ⨆ i, S i) : C x hx := by
  

Proof state:
α : Type u_1
G : Type u_2
A : Type u_3
S✝ : Type u_4
inst✝¹ : Group G
inst✝ : AddGroup A
s : Set G
ι : Sort u_5
S : ι → Subgroup G
C : (x : G) → x ∈ ⨆ i, S i → Prop
hp : ∀ (i : ι) (x : G) (hx : x ∈ S i), C x (_ : x ∈ ⨆ i, S i)
h1 : C 1 (_ : 1 ∈ ⨆ i, S i)
hmul : ∀ (x y : G) (hx : x ∈ ⨆ i, S i) (hy : y ∈ ⨆ i, S i), C x hx → C y hy → C (x * y) (_ : x * y ∈ ⨆ i, S i)
x : G
hx : x ∈ ⨆ i, S i
⊢ C x hx

Next tactic:
suffices : ∃ h, C x h
/-- A dependent version of `Subgroup.iSup_induction`. -/
@[to_additive (attr := elab_as_elim) "A dependent version of `AddSubgroup.iSup_induction`. "]
theorem iSup_induction' {ι : Sort*} (S : ι → Subgroup G) {C : ∀ x, (x ∈ ⨆ i, S i) → Prop}
    (hp : ∀ (i), ∀ x (hx : x ∈ S i), C x (mem_iSup_of_mem i hx)) (h1 : C 1 (one_mem _))
    (hmul : ∀ x y hx hy, C x hx → C y hy → C (x * y) (mul_mem ‹_› ‹_›)) {x : G}
    (hx : x ∈ ⨆ i, S i) : C x hx := by
  suffices : ∃ h, C x h; 

Proof state:
α : Type u_1
G : Type u_2
A : Type u_3
S✝ : Type u_4
inst✝¹ : Group G
inst✝ : AddGroup A
s : Set G
ι : Sort u_5
S : ι → Subgroup G
C : (x : G) → x ∈ ⨆ i, S i → Prop
hp : ∀ (i : ι) (x : G) (hx : x ∈ S i), C x (_ : x ∈ ⨆ i, S i)
h1 : C 1 (_ : 1 ∈ ⨆ i, S i)
hmul : ∀ (x y : G) (hx : x ∈ ⨆ i, S i) (hy : y ∈ ⨆ i, S i), C x hx → C y hy → C (x * y) (_ : x * y ∈ ⨆ i, S i)
x : G
hx : x ∈ ⨆ i, S i
this : ∃ (h : x ∈ ⨆ i, S i), C x h
⊢ C x hx
case this
α : Type u_1
G : Type u_2
A : Type u_3
S✝ : Type u_4
inst✝¹ : Group G
inst✝ : AddGroup A
s : Set G
ι : Sort u_5
S : ι → Subgroup G
C : (x : G) → x ∈ ⨆ i, S i → Prop
hp : ∀ (i : ι) (x : G) (hx : x ∈ S i), C x (_ : x ∈ ⨆ i, S i)
h1 : C 1 (_ : 1 ∈ ⨆ i, S i)
hmul : ∀ (x y : G) (hx : x ∈ ⨆ i, S i) (hy : y ∈ ⨆ i, S i), C x hx → C y hy → C (x * y) (_ : x * y ∈ ⨆ i, S i)
x : G
hx : x ∈ ⨆ i, S i
⊢ ∃ (h : x ∈ ⨆ i, S i), C x h

Next tactic:
exact this.snd
/-- A dependent version of `Subgroup.iSup_induction`. -/
@[to_additive (attr := elab_as_elim) "A dependent version of `AddSubgroup.iSup_induction`. "]
theorem iSup_induction' {ι : Sort*} (S : ι → Subgroup G) {C : ∀ x, (x ∈ ⨆ i, S i) → Prop}
    (hp : ∀ (i), ∀ x (hx : x ∈ S i), C x (mem_iSup_of_mem i hx)) (h1 : C 1 (one_mem _))
    (hmul : ∀ x y hx hy, C x hx → C y hy → C (x * y) (mul_mem ‹_› ‹_›)) {x : G}
    (hx : x ∈ ⨆ i, S i) : C x hx := by
  suffices : ∃ h, C x h; exact this.snd
  

Proof state:
case this
α : Type u_1
G : Type u_2
A : Type u_3
S✝ : Type u_4
inst✝¹ : Group G
inst✝ : AddGroup A
s : Set G
ι : Sort u_5
S : ι → Subgroup G
C : (x : G) → x ∈ ⨆ i, S i → Prop
hp : ∀ (i : ι) (x : G) (hx : x ∈ S i), C x (_ : x ∈ ⨆ i, S i)
h1 : C 1 (_ : 1 ∈ ⨆ i, S i)
hmul : ∀ (x y : G) (hx : x ∈ ⨆ i, S i) (hy : y ∈ ⨆ i, S i), C x hx → C y hy → C (x * y) (_ : x * y ∈ ⨆ i, S i)
x : G
hx : x ∈ ⨆ i, S i
⊢ ∃ (h : x ∈ ⨆ i, S i), C x h

Next tactic:
refine' iSup_induction S (C := fun x => ∃ h, C x h) hx (fun i x hx => _) _ fun x y => _
/-- A dependent version of `Subgroup.iSup_induction`. -/
@[to_additive (attr := elab_as_elim) "A dependent version of `AddSubgroup.iSup_induction`. "]
theorem iSup_induction' {ι : Sort*} (S : ι → Subgroup G) {C : ∀ x, (x ∈ ⨆ i, S i) → Prop}
    (hp : ∀ (i), ∀ x (hx : x ∈ S i), C x (mem_iSup_of_mem i hx)) (h1 : C 1 (one_mem _))
    (hmul : ∀ x y hx hy, C x hx → C y hy → C (x * y) (mul_mem ‹_› ‹_›)) {x : G}
    (hx : x ∈ ⨆ i, S i) : C x hx := by
  suffices : ∃ h, C x h; exact this.snd
  refine' iSup_induction S (C := fun x => ∃ h, C x h) hx (fun i x hx => _) _ fun x y => _
  · 

Proof state:
case this.refine'_1
α : Type u_1
G : Type u_2
A : Type u_3
S✝ : Type u_4
inst✝¹ : Group G
inst✝ : AddGroup A
s : Set G
ι : Sort u_5
S : ι → Subgroup G
C : (x : G) → x ∈ ⨆ i, S i → Prop
hp : ∀ (i : ι) (x : G) (hx : x ∈ S i), C x (_ : x ∈ ⨆ i, S i)
h1 : C 1 (_ : 1 ∈ ⨆ i, S i)
hmul : ∀ (x y : G) (hx : x ∈ ⨆ i, S i) (hy : y ∈ ⨆ i, S i), C x hx → C y hy → C (x * y) (_ : x * y ∈ ⨆ i, S i)
x✝ : G
hx✝ : x✝ ∈ ⨆ i, S i
i : ι
x : G
hx : x ∈ S i
⊢ (fun x => ∃ (h : x ∈ ⨆ i, S i), C x h) x

Next tactic:
exact ⟨_, hp i _ hx⟩
/-- A dependent version of `Subgroup.iSup_induction`. -/
@[to_additive (attr := elab_as_elim) "A dependent version of `AddSubgroup.iSup_induction`. "]
theorem iSup_induction' {ι : Sort*} (S : ι → Subgroup G) {C : ∀ x, (x ∈ ⨆ i, S i) → Prop}
    (hp : ∀ (i), ∀ x (hx : x ∈ S i), C x (mem_iSup_of_mem i hx)) (h1 : C 1 (one_mem _))
    (hmul : ∀ x y hx hy, C x hx → C y hy → C (x * y) (mul_mem ‹_› ‹_›)) {x : G}
    (hx : x ∈ ⨆ i, S i) : C x hx := by
  suffices : ∃ h, C x h; exact this.snd
  refine' iSup_induction S (C := fun x => ∃ h, C x h) hx (fun i x hx => _) _ fun x y => _
  · exact ⟨_, hp i _ hx⟩
  · 

Proof state:
case this.refine'_2
α : Type u_1
G : Type u_2
A : Type u_3
S✝ : Type u_4
inst✝¹ : Group G
inst✝ : AddGroup A
s : Set G
ι : Sort u_5
S : ι → Subgroup G
C : (x : G) → x ∈ ⨆ i, S i → Prop
hp : ∀ (i : ι) (x : G) (hx : x ∈ S i), C x (_ : x ∈ ⨆ i, S i)
h1 : C 1 (_ : 1 ∈ ⨆ i, S i)
hmul : ∀ (x y : G) (hx : x ∈ ⨆ i, S i) (hy : y ∈ ⨆ i, S i), C x hx → C y hy → C (x * y) (_ : x * y ∈ ⨆ i, S i)
x : G
hx : x ∈ ⨆ i, S i
⊢ (fun x => ∃ (h : x ∈ ⨆ i, S i), C x h) 1

Next tactic:
exact ⟨_, h1⟩
/-- A dependent version of `Subgroup.iSup_induction`. -/
@[to_additive (attr := elab_as_elim) "A dependent version of `AddSubgroup.iSup_induction`. "]
theorem iSup_induction' {ι : Sort*} (S : ι → Subgroup G) {C : ∀ x, (x ∈ ⨆ i, S i) → Prop}
    (hp : ∀ (i), ∀ x (hx : x ∈ S i), C x (mem_iSup_of_mem i hx)) (h1 : C 1 (one_mem _))
    (hmul : ∀ x y hx hy, C x hx → C y hy → C (x * y) (mul_mem ‹_› ‹_›)) {x : G}
    (hx : x ∈ ⨆ i, S i) : C x hx := by
  suffices : ∃ h, C x h; exact this.snd
  refine' iSup_induction S (C := fun x => ∃ h, C x h) hx (fun i x hx => _) _ fun x y => _
  · exact ⟨_, hp i _ hx⟩
  · exact ⟨_, h1⟩
  · 

Proof state:
case this.refine'_3
α : Type u_1
G : Type u_2
A : Type u_3
S✝ : Type u_4
inst✝¹ : Group G
inst✝ : AddGroup A
s : Set G
ι : Sort u_5
S : ι → Subgroup G
C : (x : G) → x ∈ ⨆ i, S i → Prop
hp : ∀ (i : ι) (x : G) (hx : x ∈ S i), C x (_ : x ∈ ⨆ i, S i)
h1 : C 1 (_ : 1 ∈ ⨆ i, S i)
hmul : ∀ (x y : G) (hx : x ∈ ⨆ i, S i) (hy : y ∈ ⨆ i, S i), C x hx → C y hy → C (x * y) (_ : x * y ∈ ⨆ i, S i)
x✝ : G
hx : x✝ ∈ ⨆ i, S i
x y : G
⊢ (fun x => ∃ (h : x ∈ ⨆ i, S i), C x h) x →
    (fun x => ∃ (h : x ∈ ⨆ i, S i), C x h) y → (fun x => ∃ (h : x ∈ ⨆ i, S i), C x h) (x * y)

Next tactic:
rintro ⟨_, Cx⟩ ⟨_, Cy⟩
/-- A dependent version of `Subgroup.iSup_induction`. -/
@[to_additive (attr := elab_as_elim) "A dependent version of `AddSubgroup.iSup_induction`. "]
theorem iSup_induction' {ι : Sort*} (S : ι → Subgroup G) {C : ∀ x, (x ∈ ⨆ i, S i) → Prop}
    (hp : ∀ (i), ∀ x (hx : x ∈ S i), C x (mem_iSup_of_mem i hx)) (h1 : C 1 (one_mem _))
    (hmul : ∀ x y hx hy, C x hx → C y hy → C (x * y) (mul_mem ‹_› ‹_›)) {x : G}
    (hx : x ∈ ⨆ i, S i) : C x hx := by
  suffices : ∃ h, C x h; exact this.snd
  refine' iSup_induction S (C := fun x => ∃ h, C x h) hx (fun i x hx => _) _ fun x y => _
  · exact ⟨_, hp i _ hx⟩
  · exact ⟨_, h1⟩
  · rintro ⟨_, Cx⟩ ⟨_, Cy⟩
    

Proof state:
case this.refine'_3.intro.intro
α : Type u_1
G : Type u_2
A : Type u_3
S✝ : Type u_4
inst✝¹ : Group G
inst✝ : AddGroup A
s : Set G
ι : Sort u_5
S : ι → Subgroup G
C : (x : G) → x ∈ ⨆ i, S i → Prop
hp : ∀ (i : ι) (x : G) (hx : x ∈ S i), C x (_ : x ∈ ⨆ i, S i)
h1 : C 1 (_ : 1 ∈ ⨆ i, S i)
hmul : ∀ (x y : G) (hx : x ∈ ⨆ i, S i) (hy : y ∈ ⨆ i, S i), C x hx → C y hy → C (x * y) (_ : x * y ∈ ⨆ i, S i)
x✝ : G
hx : x✝ ∈ ⨆ i, S i
x y : G
w✝¹ : x ∈ ⨆ i, S i
Cx : C x w✝¹
w✝ : y ∈ ⨆ i, S i
Cy : C y w✝
⊢ ∃ (h : x * y ∈ ⨆ i, S i), C (x * y) h

Next tactic:
refine' ⟨_, hmul _ _ _ _ Cx Cy⟩
@[to_additive]
theorem sup_eq_closure_mul (H K : Subgroup G) : H ⊔ K = closure ((H : Set G) * (K : Set G)) :=
  le_antisymm
    (sup_le (fun h hh => subset_closure ⟨h, 1, hh, K.one_mem, mul_one h⟩) fun k hk =>
      subset_closure ⟨1, k, H.one_mem, hk, one_mul k⟩)
    ((closure_mul_le _ _).trans <| by 

Proof state:
α : Type u_1
G : Type u_2
A : Type u_3
S : Type u_4
inst✝¹ : Group G
inst✝ : AddGroup A
s : Set G
H K : Subgroup G
⊢ closure ↑H ⊔ closure ↑K ≤ H ⊔ K

Next tactic:
rw [closure_eq, closure_eq]
@[to_additive]
theorem set_mul_normal_comm (s : Set G) (N : Subgroup G) [hN : N.Normal] :
    s * (N : Set G) = (N : Set G) * s := by
  

Proof state:
α : Type u_1
G : Type u_2
A : Type u_3
S : Type u_4
inst✝¹ : Group G
inst✝ : AddGroup A
s✝ s : Set G
N : Subgroup G
hN : Normal N
⊢ s * ↑N = ↑N * s

Next tactic:
ext x
@[to_additive]
theorem set_mul_normal_comm (s : Set G) (N : Subgroup G) [hN : N.Normal] :
    s * (N : Set G) = (N : Set G) * s := by
  ext x
  

Proof state:
case h
α : Type u_1
G : Type u_2
A : Type u_3
S : Type u_4
inst✝¹ : Group G
inst✝ : AddGroup A
s✝ s : Set G
N : Subgroup G
hN : Normal N
x : G
⊢ x ∈ s * ↑N ↔ x ∈ ↑N * s

Next tactic:
refine (exists_congr fun y => ?_).trans exists_swap
@[to_additive]
theorem set_mul_normal_comm (s : Set G) (N : Subgroup G) [hN : N.Normal] :
    s * (N : Set G) = (N : Set G) * s := by
  ext x
  refine (exists_congr fun y => ?_).trans exists_swap
  

Proof state:
case h
α : Type u_1
G : Type u_2
A : Type u_3
S : Type u_4
inst✝¹ : Group G
inst✝ : AddGroup A
s✝ s : Set G
N : Subgroup G
hN : Normal N
x y : G
⊢ (∃ b, y ∈ s ∧ b ∈ ↑N ∧ (fun x x_1 => x * x_1) y b = x) ↔ ∃ y_1 ∈ ↑N, y ∈ s ∧ (fun x x_1 => x * x_1) y_1 y = x

Next tactic:
simp only [exists_and_left, @and_left_comm _ (y ∈ s), ← eq_inv_mul_iff_mul_eq (b := y),
    ← eq_mul_inv_iff_mul_eq (c := y), exists_eq_right, SetLike.mem_coe, hN.mem_comm_iff]
/-- The carrier of `H ⊔ N` is just `↑H * ↑N` (pointwise set product) when `N` is normal. -/
@[to_additive "The carrier of `H ⊔ N` is just `↑H + ↑N` (pointwise set addition)
when `N` is normal."]
theorem mul_normal (H N : Subgroup G) [hN : N.Normal] : (↑(H ⊔ N) : Set G) = H * N := by
  

Proof state:
α : Type u_1
G : Type u_2
A : Type u_3
S : Type u_4
inst✝¹ : Group G
inst✝ : AddGroup A
s : Set G
H N : Subgroup G
hN : Normal N
⊢ ↑(H ⊔ N) = ↑H * ↑N

Next tactic:
rw [sup_eq_closure_mul]
/-- The carrier of `H ⊔ N` is just `↑H * ↑N` (pointwise set product) when `N` is normal. -/
@[to_additive "The carrier of `H ⊔ N` is just `↑H + ↑N` (pointwise set addition)
when `N` is normal."]
theorem mul_normal (H N : Subgroup G) [hN : N.Normal] : (↑(H ⊔ N) : Set G) = H * N := by
  rw [sup_eq_closure_mul]
  

Proof state:
α : Type u_1
G : Type u_2
A : Type u_3
S : Type u_4
inst✝¹ : Group G
inst✝ : AddGroup A
s : Set G
H N : Subgroup G
hN : Normal N
⊢ ↑(closure (↑H * ↑N)) = ↑H * ↑N

Next tactic:
refine Set.Subset.antisymm (fun x hx => ?_) subset_closure
/-- The carrier of `H ⊔ N` is just `↑H * ↑N` (pointwise set product) when `N` is normal. -/
@[to_additive "The carrier of `H ⊔ N` is just `↑H + ↑N` (pointwise set addition)
when `N` is normal."]
theorem mul_normal (H N : Subgroup G) [hN : N.Normal] : (↑(H ⊔ N) : Set G) = H * N := by
  rw [sup_eq_closure_mul]
  refine Set.Subset.antisymm (fun x hx => ?_) subset_closure
  

Proof state:
α : Type u_1
G : Type u_2
A : Type u_3
S : Type u_4
inst✝¹ : Group G
inst✝ : AddGroup A
s : Set G
H N : Subgroup G
hN : Normal N
x : G
hx : x ∈ ↑(closure (↑H * ↑N))
⊢ x ∈ ↑H * ↑N

Next tactic:
refine closure_induction'' (p := fun x => x ∈ (H : Set G) * (N : Set G)) hx ?_ ?_ ?_ ?_
/-- The carrier of `H ⊔ N` is just `↑H * ↑N` (pointwise set product) when `N` is normal. -/
@[to_additive "The carrier of `H ⊔ N` is just `↑H + ↑N` (pointwise set addition)
when `N` is normal."]
theorem mul_normal (H N : Subgroup G) [hN : N.Normal] : (↑(H ⊔ N) : Set G) = H * N := by
  rw [sup_eq_closure_mul]
  refine Set.Subset.antisymm (fun x hx => ?_) subset_closure
  refine closure_induction'' (p := fun x => x ∈ (H : Set G) * (N : Set G)) hx ?_ ?_ ?_ ?_
  · 

Proof state:
case refine_1
α : Type u_1
G : Type u_2
A : Type u_3
S : Type u_4
inst✝¹ : Group G
inst✝ : AddGroup A
s : Set G
H N : Subgroup G
hN : Normal N
x : G
hx : x ∈ ↑(closure (↑H * ↑N))
⊢ ∀ x ∈ ↑H * ↑N, (fun x => x ∈ ↑H * ↑N) x

Next tactic:
rintro _ ⟨x, y, hx, hy, rfl⟩
/-- The carrier of `H ⊔ N` is just `↑H * ↑N` (pointwise set product) when `N` is normal. -/
@[to_additive "The carrier of `H ⊔ N` is just `↑H + ↑N` (pointwise set addition)
when `N` is normal."]
theorem mul_normal (H N : Subgroup G) [hN : N.Normal] : (↑(H ⊔ N) : Set G) = H * N := by
  rw [sup_eq_closure_mul]
  refine Set.Subset.antisymm (fun x hx => ?_) subset_closure
  refine closure_induction'' (p := fun x => x ∈ (H : Set G) * (N : Set G)) hx ?_ ?_ ?_ ?_
  · rintro _ ⟨x, y, hx, hy, rfl⟩
    

Proof state:
case refine_1.intro.intro.intro.intro
α : Type u_1
G : Type u_2
A : Type u_3
S : Type u_4
inst✝¹ : Group G
inst✝ : AddGroup A
s : Set G
H N : Subgroup G
hN : Normal N
x✝ : G
hx✝ : x✝ ∈ ↑(closure (↑H * ↑N))
x y : G
hx : x ∈ ↑H
hy : y ∈ ↑N
⊢ (fun x x_1 => x * x_1) x y ∈ ↑H * ↑N

Next tactic:
exact mul_mem_mul hx hy
/-- The carrier of `H ⊔ N` is just `↑H * ↑N` (pointwise set product) when `N` is normal. -/
@[to_additive "The carrier of `H ⊔ N` is just `↑H + ↑N` (pointwise set addition)
when `N` is normal."]
theorem mul_normal (H N : Subgroup G) [hN : N.Normal] : (↑(H ⊔ N) : Set G) = H * N := by
  rw [sup_eq_closure_mul]
  refine Set.Subset.antisymm (fun x hx => ?_) subset_closure
  refine closure_induction'' (p := fun x => x ∈ (H : Set G) * (N : Set G)) hx ?_ ?_ ?_ ?_
  · rintro _ ⟨x, y, hx, hy, rfl⟩
    exact mul_mem_mul hx hy
  · 

Proof state:
case refine_2
α : Type u_1
G : Type u_2
A : Type u_3
S : Type u_4
inst✝¹ : Group G
inst✝ : AddGroup A
s : Set G
H N : Subgroup G
hN : Normal N
x : G
hx : x ∈ ↑(closure (↑H * ↑N))
⊢ ∀ x ∈ ↑H * ↑N, (fun x => x ∈ ↑H * ↑N) x⁻¹

Next tactic:
rintro _ ⟨x, y, hx, hy, rfl⟩
/-- The carrier of `H ⊔ N` is just `↑H * ↑N` (pointwise set product) when `N` is normal. -/
@[to_additive "The carrier of `H ⊔ N` is just `↑H + ↑N` (pointwise set addition)
when `N` is normal."]
theorem mul_normal (H N : Subgroup G) [hN : N.Normal] : (↑(H ⊔ N) : Set G) = H * N := by
  rw [sup_eq_closure_mul]
  refine Set.Subset.antisymm (fun x hx => ?_) subset_closure
  refine closure_induction'' (p := fun x => x ∈ (H : Set G) * (N : Set G)) hx ?_ ?_ ?_ ?_
  · rintro _ ⟨x, y, hx, hy, rfl⟩
    exact mul_mem_mul hx hy
  · rintro _ ⟨x, y, hx, hy, rfl⟩
    

Proof state:
case refine_2.intro.intro.intro.intro
α : Type u_1
G : Type u_2
A : Type u_3
S : Type u_4
inst✝¹ : Group G
inst✝ : AddGroup A
s : Set G
H N : Subgroup G
hN : Normal N
x✝ : G
hx✝ : x✝ ∈ ↑(closure (↑H * ↑N))
x y : G
hx : x ∈ ↑H
hy : y ∈ ↑N
⊢ ((fun x x_1 => x * x_1) x y)⁻¹ ∈ ↑H * ↑N

Next tactic:
simpa only [mul_inv_rev, mul_assoc, inv_inv, inv_mul_cancel_left]
      using mul_mem_mul (inv_mem hx) (hN.conj_mem _ (inv_mem hy) x)
/-- The carrier of `H ⊔ N` is just `↑H * ↑N` (pointwise set product) when `N` is normal. -/
@[to_additive "The carrier of `H ⊔ N` is just `↑H + ↑N` (pointwise set addition)
when `N` is normal."]
theorem mul_normal (H N : Subgroup G) [hN : N.Normal] : (↑(H ⊔ N) : Set G) = H * N := by
  rw [sup_eq_closure_mul]
  refine Set.Subset.antisymm (fun x hx => ?_) subset_closure
  refine closure_induction'' (p := fun x => x ∈ (H : Set G) * (N : Set G)) hx ?_ ?_ ?_ ?_
  · rintro _ ⟨x, y, hx, hy, rfl⟩
    exact mul_mem_mul hx hy
  · rintro _ ⟨x, y, hx, hy, rfl⟩
    simpa only [mul_inv_rev, mul_assoc, inv_inv, inv_mul_cancel_left]
      using mul_mem_mul (inv_mem hx) (hN.conj_mem _ (inv_mem hy) x)
  · 

Proof state:
case refine_3
α : Type u_1
G : Type u_2
A : Type u_3
S : Type u_4
inst✝¹ : Group G
inst✝ : AddGroup A
s : Set G
H N : Subgroup G
hN : Normal N
x : G
hx : x ∈ ↑(closure (↑H * ↑N))
⊢ (fun x => x ∈ ↑H * ↑N) 1

Next tactic:
exact ⟨1, 1, one_mem _, one_mem _, mul_one 1⟩
/-- The carrier of `H ⊔ N` is just `↑H * ↑N` (pointwise set product) when `N` is normal. -/
@[to_additive "The carrier of `H ⊔ N` is just `↑H + ↑N` (pointwise set addition)
when `N` is normal."]
theorem mul_normal (H N : Subgroup G) [hN : N.Normal] : (↑(H ⊔ N) : Set G) = H * N := by
  rw [sup_eq_closure_mul]
  refine Set.Subset.antisymm (fun x hx => ?_) subset_closure
  refine closure_induction'' (p := fun x => x ∈ (H : Set G) * (N : Set G)) hx ?_ ?_ ?_ ?_
  · rintro _ ⟨x, y, hx, hy, rfl⟩
    exact mul_mem_mul hx hy
  · rintro _ ⟨x, y, hx, hy, rfl⟩
    simpa only [mul_inv_rev, mul_assoc, inv_inv, inv_mul_cancel_left]
      using mul_mem_mul (inv_mem hx) (hN.conj_mem _ (inv_mem hy) x)
  · exact ⟨1, 1, one_mem _, one_mem _, mul_one 1⟩
  · 

Proof state:
case refine_4
α : Type u_1
G : Type u_2
A : Type u_3
S : Type u_4
inst✝¹ : Group G
inst✝ : AddGroup A
s : Set G
H N : Subgroup G
hN : Normal N
x : G
hx : x ∈ ↑(closure (↑H * ↑N))
⊢ ∀ (x y : G), (fun x => x ∈ ↑H * ↑N) x → (fun x => x ∈ ↑H * ↑N) y → (fun x => x ∈ ↑H * ↑N) (x * y)

Next tactic:
rintro _ _ ⟨x, y, hx, hy, rfl⟩ ⟨x', y', hx', hy', rfl⟩
/-- The carrier of `H ⊔ N` is just `↑H * ↑N` (pointwise set product) when `N` is normal. -/
@[to_additive "The carrier of `H ⊔ N` is just `↑H + ↑N` (pointwise set addition)
when `N` is normal."]
theorem mul_normal (H N : Subgroup G) [hN : N.Normal] : (↑(H ⊔ N) : Set G) = H * N := by
  rw [sup_eq_closure_mul]
  refine Set.Subset.antisymm (fun x hx => ?_) subset_closure
  refine closure_induction'' (p := fun x => x ∈ (H : Set G) * (N : Set G)) hx ?_ ?_ ?_ ?_
  · rintro _ ⟨x, y, hx, hy, rfl⟩
    exact mul_mem_mul hx hy
  · rintro _ ⟨x, y, hx, hy, rfl⟩
    simpa only [mul_inv_rev, mul_assoc, inv_inv, inv_mul_cancel_left]
      using mul_mem_mul (inv_mem hx) (hN.conj_mem _ (inv_mem hy) x)
  · exact ⟨1, 1, one_mem _, one_mem _, mul_one 1⟩
  · rintro _ _ ⟨x, y, hx, hy, rfl⟩ ⟨x', y', hx', hy', rfl⟩
    

Proof state:
case refine_4.intro.intro.intro.intro.intro.intro.intro.intro
α : Type u_1
G : Type u_2
A : Type u_3
S : Type u_4
inst✝¹ : Group G
inst✝ : AddGroup A
s : Set G
H N : Subgroup G
hN : Normal N
x✝ : G
hx✝ : x✝ ∈ ↑(closure (↑H * ↑N))
x y : G
hx : x ∈ ↑H
hy : y ∈ ↑N
x' y' : G
hx' : x' ∈ ↑H
hy' : y' ∈ ↑N
⊢ (fun x x_1 => x * x_1) x y * (fun x x_1 => x * x_1) x' y' ∈ ↑H * ↑N

Next tactic:
refine ⟨x * x', x'⁻¹ * y * x' * y', mul_mem hx hx', mul_mem ?_ hy', ?_⟩
/-- The carrier of `H ⊔ N` is just `↑H * ↑N` (pointwise set product) when `N` is normal. -/
@[to_additive "The carrier of `H ⊔ N` is just `↑H + ↑N` (pointwise set addition)
when `N` is normal."]
theorem mul_normal (H N : Subgroup G) [hN : N.Normal] : (↑(H ⊔ N) : Set G) = H * N := by
  rw [sup_eq_closure_mul]
  refine Set.Subset.antisymm (fun x hx => ?_) subset_closure
  refine closure_induction'' (p := fun x => x ∈ (H : Set G) * (N : Set G)) hx ?_ ?_ ?_ ?_
  · rintro _ ⟨x, y, hx, hy, rfl⟩
    exact mul_mem_mul hx hy
  · rintro _ ⟨x, y, hx, hy, rfl⟩
    simpa only [mul_inv_rev, mul_assoc, inv_inv, inv_mul_cancel_left]
      using mul_mem_mul (inv_mem hx) (hN.conj_mem _ (inv_mem hy) x)
  · exact ⟨1, 1, one_mem _, one_mem _, mul_one 1⟩
  · rintro _ _ ⟨x, y, hx, hy, rfl⟩ ⟨x', y', hx', hy', rfl⟩
    refine ⟨x * x', x'⁻¹ * y * x' * y', mul_mem hx hx', mul_mem ?_ hy', ?_⟩
    · 

Proof state:
case refine_4.intro.intro.intro.intro.intro.intro.intro.intro.refine_1
α : Type u_1
G : Type u_2
A : Type u_3
S : Type u_4
inst✝¹ : Group G
inst✝ : AddGroup A
s : Set G
H N : Subgroup G
hN : Normal N
x✝ : G
hx✝ : x✝ ∈ ↑(closure (↑H * ↑N))
x y : G
hx : x ∈ ↑H
hy : y ∈ ↑N
x' y' : G
hx' : x' ∈ ↑H
hy' : y' ∈ ↑N
⊢ x'⁻¹ * y * x' ∈ N

Next tactic:
simpa using hN.conj_mem _ hy x'⁻¹