l3lab/ntp-mathlib huggingface dataset:
theorem rel_bot_eq_right_group_rel (H : Subgroup G) :
    (setoid ↑H ↑(⊥ : Subgroup G)).Rel = (QuotientGroup.rightRel H).Rel := by
  

Proof state:
G : Type u_1
inst✝¹ : Group G
α : Type u_2
inst✝ : Mul α
J : Subgroup G
g : G
H : Subgroup G
⊢ Setoid.Rel (setoid ↑H ↑⊥) = Setoid.Rel (QuotientGroup.rightRel H)

Next tactic:
ext a b
theorem rel_bot_eq_right_group_rel (H : Subgroup G) :
    (setoid ↑H ↑(⊥ : Subgroup G)).Rel = (QuotientGroup.rightRel H).Rel := by
  ext a b
  

Proof state:
case h.h.a
G : Type u_1
inst✝¹ : Group G
α : Type u_2
inst✝ : Mul α
J : Subgroup G
g : G
H : Subgroup G
a b : G
⊢ Setoid.Rel (setoid ↑H ↑⊥) a b ↔ Setoid.Rel (QuotientGroup.rightRel H) a b

Next tactic:
rw [rel_iff, Setoid.Rel, QuotientGroup.rightRel_apply]
theorem rel_bot_eq_right_group_rel (H : Subgroup G) :
    (setoid ↑H ↑(⊥ : Subgroup G)).Rel = (QuotientGroup.rightRel H).Rel := by
  ext a b
  rw [rel_iff, Setoid.Rel, QuotientGroup.rightRel_apply]
  

Proof state:
case h.h.a
G : Type u_1
inst✝¹ : Group G
α : Type u_2
inst✝ : Mul α
J : Subgroup G
g : G
H : Subgroup G
a b : G
⊢ (∃ a_1 ∈ H, ∃ b_1 ∈ ⊥, b = a_1 * a * b_1) ↔ b * a⁻¹ ∈ H

Next tactic:
constructor
theorem rel_bot_eq_right_group_rel (H : Subgroup G) :
    (setoid ↑H ↑(⊥ : Subgroup G)).Rel = (QuotientGroup.rightRel H).Rel := by
  ext a b
  rw [rel_iff, Setoid.Rel, QuotientGroup.rightRel_apply]
  constructor
  · 

Proof state:
case h.h.a.mp
G : Type u_1
inst✝¹ : Group G
α : Type u_2
inst✝ : Mul α
J : Subgroup G
g : G
H : Subgroup G
a b : G
⊢ (∃ a_1 ∈ H, ∃ b_1 ∈ ⊥, b = a_1 * a * b_1) → b * a⁻¹ ∈ H

Next tactic:
rintro ⟨b, hb, a, rfl : a = 1, rfl⟩
theorem rel_bot_eq_right_group_rel (H : Subgroup G) :
    (setoid ↑H ↑(⊥ : Subgroup G)).Rel = (QuotientGroup.rightRel H).Rel := by
  ext a b
  rw [rel_iff, Setoid.Rel, QuotientGroup.rightRel_apply]
  constructor
  · rintro ⟨b, hb, a, rfl : a = 1, rfl⟩
    

Proof state:
case h.h.a.mp.intro.intro.intro.intro
G : Type u_1
inst✝¹ : Group G
α : Type u_2
inst✝ : Mul α
J : Subgroup G
g : G
H : Subgroup G
a b : G
hb : b ∈ H
⊢ b * a * 1 * a⁻¹ ∈ H

Next tactic:
change b * a * 1 * a⁻¹ ∈ H
theorem rel_bot_eq_right_group_rel (H : Subgroup G) :
    (setoid ↑H ↑(⊥ : Subgroup G)).Rel = (QuotientGroup.rightRel H).Rel := by
  ext a b
  rw [rel_iff, Setoid.Rel, QuotientGroup.rightRel_apply]
  constructor
  · rintro ⟨b, hb, a, rfl : a = 1, rfl⟩
    change b * a * 1 * a⁻¹ ∈ H
    

Proof state:
case h.h.a.mp.intro.intro.intro.intro
G : Type u_1
inst✝¹ : Group G
α : Type u_2
inst✝ : Mul α
J : Subgroup G
g : G
H : Subgroup G
a b : G
hb : b ∈ H
⊢ b * a * 1 * a⁻¹ ∈ H

Next tactic:
rwa [mul_one, mul_inv_cancel_right]
theorem rel_bot_eq_right_group_rel (H : Subgroup G) :
    (setoid ↑H ↑(⊥ : Subgroup G)).Rel = (QuotientGroup.rightRel H).Rel := by
  ext a b
  rw [rel_iff, Setoid.Rel, QuotientGroup.rightRel_apply]
  constructor
  · rintro ⟨b, hb, a, rfl : a = 1, rfl⟩
    change b * a * 1 * a⁻¹ ∈ H
    rwa [mul_one, mul_inv_cancel_right]
  · 

Proof state:
case h.h.a.mpr
G : Type u_1
inst✝¹ : Group G
α : Type u_2
inst✝ : Mul α
J : Subgroup G
g : G
H : Subgroup G
a b : G
⊢ b * a⁻¹ ∈ H → ∃ a_2 ∈ H, ∃ b_1 ∈ ⊥, b = a_2 * a * b_1

Next tactic:
rintro (h : b * a⁻¹ ∈ H)
theorem rel_bot_eq_right_group_rel (H : Subgroup G) :
    (setoid ↑H ↑(⊥ : Subgroup G)).Rel = (QuotientGroup.rightRel H).Rel := by
  ext a b
  rw [rel_iff, Setoid.Rel, QuotientGroup.rightRel_apply]
  constructor
  · rintro ⟨b, hb, a, rfl : a = 1, rfl⟩
    change b * a * 1 * a⁻¹ ∈ H
    rwa [mul_one, mul_inv_cancel_right]
  · rintro (h : b * a⁻¹ ∈ H)
    

Proof state:
case h.h.a.mpr
G : Type u_1
inst✝¹ : Group G
α : Type u_2
inst✝ : Mul α
J : Subgroup G
g : G
H : Subgroup G
a b : G
h : b * a⁻¹ ∈ H
⊢ ∃ a_1 ∈ H, ∃ b_1 ∈ ⊥, b = a_1 * a * b_1

Next tactic:
exact ⟨b * a⁻¹, h, 1, rfl, by rw [mul_one, inv_mul_cancel_right]⟩
theorem rel_bot_eq_right_group_rel (H : Subgroup G) :
    (setoid ↑H ↑(⊥ : Subgroup G)).Rel = (QuotientGroup.rightRel H).Rel := by
  ext a b
  rw [rel_iff, Setoid.Rel, QuotientGroup.rightRel_apply]
  constructor
  · rintro ⟨b, hb, a, rfl : a = 1, rfl⟩
    change b * a * 1 * a⁻¹ ∈ H
    rwa [mul_one, mul_inv_cancel_right]
  · rintro (h : b * a⁻¹ ∈ H)
    exact ⟨b * a⁻¹, h, 1, rfl, by 

Proof state:
G : Type u_1
inst✝¹ : Group G
α : Type u_2
inst✝ : Mul α
J : Subgroup G
g : G
H : Subgroup G
a b : G
h : b * a⁻¹ ∈ H
⊢ b = b * a⁻¹ * a * 1

Next tactic:
rw [mul_one, inv_mul_cancel_right]
theorem eq (H K : Subgroup G) (a b : G) :
    mk H K a = mk H K b ↔ ∃ h ∈ H, ∃ k ∈ K, b = h * a * k := by
  

Proof state:
G : Type u_1
inst✝¹ : Group G
α : Type u_2
inst✝ : Mul α
J : Subgroup G
g : G
H K : Subgroup G
a b : G
⊢ mk H K a = mk H K b ↔ ∃ h ∈ H, ∃ k ∈ K, b = h * a * k

Next tactic:
rw [Quotient.eq'']
theorem eq (H K : Subgroup G) (a b : G) :
    mk H K a = mk H K b ↔ ∃ h ∈ H, ∃ k ∈ K, b = h * a * k := by
  rw [Quotient.eq'']
  

Proof state:
G : Type u_1
inst✝¹ : Group G
α : Type u_2
inst✝ : Mul α
J : Subgroup G
g : G
H K : Subgroup G
a b : G
⊢ Setoid.r a b ↔ ∃ h ∈ H, ∃ k ∈ K, b = h * a * k

Next tactic:
apply rel_iff
theorem mk_out'_eq_mul (H K : Subgroup G) (g : G) :
    ∃ h k : G, h ∈ H ∧ k ∈ K ∧ (mk H K g : Quotient ↑H ↑K).out' = h * g * k := by
  

Proof state:
G : Type u_1
inst✝¹ : Group G
α : Type u_2
inst✝ : Mul α
J : Subgroup G
g✝ : G
H K : Subgroup G
g : G
⊢ ∃ h k, h ∈ H ∧ k ∈ K ∧ Quotient.out' (mk H K g) = h * g * k

Next tactic:
have := eq H K (mk H K g : Quotient ↑H ↑K).out' g
theorem mk_out'_eq_mul (H K : Subgroup G) (g : G) :
    ∃ h k : G, h ∈ H ∧ k ∈ K ∧ (mk H K g : Quotient ↑H ↑K).out' = h * g * k := by
  have := eq H K (mk H K g : Quotient ↑H ↑K).out' g
  

Proof state:
G : Type u_1
inst✝¹ : Group G
α : Type u_2
inst✝ : Mul α
J : Subgroup G
g✝ : G
H K : Subgroup G
g : G
this : mk H K (Quotient.out' (mk H K g)) = mk H K g ↔ ∃ h ∈ H, ∃ k ∈ K, g = h * Quotient.out' (mk H K g) * k
⊢ ∃ h k, h ∈ H ∧ k ∈ K ∧ Quotient.out' (mk H K g) = h * g * k

Next tactic:
rw [out_eq'] at this
theorem mk_out'_eq_mul (H K : Subgroup G) (g : G) :
    ∃ h k : G, h ∈ H ∧ k ∈ K ∧ (mk H K g : Quotient ↑H ↑K).out' = h * g * k := by
  have := eq H K (mk H K g : Quotient ↑H ↑K).out' g
  rw [out_eq'] at this
  

Proof state:
G : Type u_1
inst✝¹ : Group G
α : Type u_2
inst✝ : Mul α
J : Subgroup G
g✝ : G
H K : Subgroup G
g : G
this : mk H K g = mk H K g ↔ ∃ h ∈ H, ∃ k ∈ K, g = h * Quotient.out' (mk H K g) * k
⊢ ∃ h k, h ∈ H ∧ k ∈ K ∧ Quotient.out' (mk H K g) = h * g * k

Next tactic:
obtain ⟨h, h_h, k, hk, T⟩ := this.1 rfl
theorem mk_out'_eq_mul (H K : Subgroup G) (g : G) :
    ∃ h k : G, h ∈ H ∧ k ∈ K ∧ (mk H K g : Quotient ↑H ↑K).out' = h * g * k := by
  have := eq H K (mk H K g : Quotient ↑H ↑K).out' g
  rw [out_eq'] at this
  obtain ⟨h, h_h, k, hk, T⟩ := this.1 rfl
  

Proof state:
case intro.intro.intro.intro
G : Type u_1
inst✝¹ : Group G
α : Type u_2
inst✝ : Mul α
J : Subgroup G
g✝ : G
H K : Subgroup G
g : G
this : mk H K g = mk H K g ↔ ∃ h ∈ H, ∃ k ∈ K, g = h * Quotient.out' (mk H K g) * k
h : G
h_h : h ∈ H
k : G
hk : k ∈ K
T : g = h * Quotient.out' (mk H K g) * k
⊢ ∃ h k, h ∈ H ∧ k ∈ K ∧ Quotient.out' (mk H K g) = h * g * k

Next tactic:
refine' ⟨h⁻¹, k⁻¹, H.inv_mem h_h, K.inv_mem hk, eq_mul_inv_of_mul_eq (eq_inv_mul_of_mul_eq _)⟩
theorem mk_out'_eq_mul (H K : Subgroup G) (g : G) :
    ∃ h k : G, h ∈ H ∧ k ∈ K ∧ (mk H K g : Quotient ↑H ↑K).out' = h * g * k := by
  have := eq H K (mk H K g : Quotient ↑H ↑K).out' g
  rw [out_eq'] at this
  obtain ⟨h, h_h, k, hk, T⟩ := this.1 rfl
  refine' ⟨h⁻¹, k⁻¹, H.inv_mem h_h, K.inv_mem hk, eq_mul_inv_of_mul_eq (eq_inv_mul_of_mul_eq _)⟩
  

Proof state:
case intro.intro.intro.intro
G : Type u_1
inst✝¹ : Group G
α : Type u_2
inst✝ : Mul α
J : Subgroup G
g✝ : G
H K : Subgroup G
g : G
this : mk H K g = mk H K g ↔ ∃ h ∈ H, ∃ k ∈ K, g = h * Quotient.out' (mk H K g) * k
h : G
h_h : h ∈ H
k : G
hk : k ∈ K
T : g = h * Quotient.out' (mk H K g) * k
⊢ h * (Quotient.out' (mk H K g) * k) = g

Next tactic:
rw [← mul_assoc, ← T]
theorem mk_eq_of_doset_eq {H K : Subgroup G} {a b : G} (h : doset a H K = doset b H K) :
    mk H K a = mk H K b := by
  

Proof state:
G : Type u_1
inst✝¹ : Group G
α : Type u_2
inst✝ : Mul α
J : Subgroup G
g : G
H K : Subgroup G
a b : G
h : doset a ↑H ↑K = doset b ↑H ↑K
⊢ mk H K a = mk H K b

Next tactic:
rw [eq]
theorem mk_eq_of_doset_eq {H K : Subgroup G} {a b : G} (h : doset a H K = doset b H K) :
    mk H K a = mk H K b := by
  rw [eq]
  

Proof state:
G : Type u_1
inst✝¹ : Group G
α : Type u_2
inst✝ : Mul α
J : Subgroup G
g : G
H K : Subgroup G
a b : G
h : doset a ↑H ↑K = doset b ↑H ↑K
⊢ ∃ h ∈ H, ∃ k ∈ K, b = h * a * k

Next tactic:
exact mem_doset.mp (h.symm ▸ mem_doset_self H K b)
theorem disjoint_out' {H K : Subgroup G} {a b : Quotient H.1 K} :
    a ≠ b → Disjoint (doset a.out' H K) (doset b.out' (H : Set G) K) := by
  

Proof state:
G : Type u_1
inst✝¹ : Group G
α : Type u_2
inst✝ : Mul α
J : Subgroup G
g : G
H K : Subgroup G
a b : Quotient ↑H.toSubmonoid ↑K
⊢ a ≠ b → Disjoint (doset (Quotient.out' a) ↑H ↑K) (doset (Quotient.out' b) ↑H ↑K)

Next tactic:
contrapose!
theorem disjoint_out' {H K : Subgroup G} {a b : Quotient H.1 K} :
    a ≠ b → Disjoint (doset a.out' H K) (doset b.out' (H : Set G) K) := by
  contrapose!
  

Proof state:
G : Type u_1
inst✝¹ : Group G
α : Type u_2
inst✝ : Mul α
J : Subgroup G
g : G
H K : Subgroup G
a b : Quotient ↑H.toSubmonoid ↑K
⊢ ¬Disjoint (doset (Quotient.out' a) ↑H ↑K) (doset (Quotient.out' b) ↑H ↑K) → a = b

Next tactic:
intro h
theorem disjoint_out' {H K : Subgroup G} {a b : Quotient H.1 K} :
    a ≠ b → Disjoint (doset a.out' H K) (doset b.out' (H : Set G) K) := by
  contrapose!
  intro h
  

Proof state:
G : Type u_1
inst✝¹ : Group G
α : Type u_2
inst✝ : Mul α
J : Subgroup G
g : G
H K : Subgroup G
a b : Quotient ↑H.toSubmonoid ↑K
h : ¬Disjoint (doset (Quotient.out' a) ↑H ↑K) (doset (Quotient.out' b) ↑H ↑K)
⊢ a = b

Next tactic:
simpa [out_eq'] using mk_eq_of_doset_eq (eq_of_not_disjoint h)
theorem union_quotToDoset (H K : Subgroup G) : ⋃ q, quotToDoset H K q = Set.univ := by
  

Proof state:
G : Type u_1
inst✝¹ : Group G
α : Type u_2
inst✝ : Mul α
J : Subgroup G
g : G
H K : Subgroup G
⊢ ⋃ q, quotToDoset H K q = Set.univ

Next tactic:
ext x
theorem union_quotToDoset (H K : Subgroup G) : ⋃ q, quotToDoset H K q = Set.univ := by
  ext x
  

Proof state:
case h
G : Type u_1
inst✝¹ : Group G
α : Type u_2
inst✝ : Mul α
J : Subgroup G
g : G
H K : Subgroup G
x : G
⊢ x ∈ ⋃ q, quotToDoset H K q ↔ x ∈ Set.univ

Next tactic:
simp only [Set.mem_iUnion, quotToDoset, mem_doset, SetLike.mem_coe, exists_prop, Set.mem_univ,
    iff_true_iff]
theorem union_quotToDoset (H K : Subgroup G) : ⋃ q, quotToDoset H K q = Set.univ := by
  ext x
  simp only [Set.mem_iUnion, quotToDoset, mem_doset, SetLike.mem_coe, exists_prop, Set.mem_univ,
    iff_true_iff]
  

Proof state:
case h
G : Type u_1
inst✝¹ : Group G
α : Type u_2
inst✝ : Mul α
J : Subgroup G
g : G
H K : Subgroup G
x : G
⊢ ∃ i, ∃ x_1 ∈ H, ∃ y ∈ K, x = x_1 * Quotient.out' i * y

Next tactic:
use mk H K x
theorem union_quotToDoset (H K : Subgroup G) : ⋃ q, quotToDoset H K q = Set.univ := by
  ext x
  simp only [Set.mem_iUnion, quotToDoset, mem_doset, SetLike.mem_coe, exists_prop, Set.mem_univ,
    iff_true_iff]
  use mk H K x
  

Proof state:
case h
G : Type u_1
inst✝¹ : Group G
α : Type u_2
inst✝ : Mul α
J : Subgroup G
g : G
H K : Subgroup G
x : G
⊢ ∃ x_1 ∈ H, ∃ y ∈ K, x = x_1 * Quotient.out' (mk H K x) * y

Next tactic:
obtain ⟨h, k, h3, h4, h5⟩ := mk_out'_eq_mul H K x
theorem union_quotToDoset (H K : Subgroup G) : ⋃ q, quotToDoset H K q = Set.univ := by
  ext x
  simp only [Set.mem_iUnion, quotToDoset, mem_doset, SetLike.mem_coe, exists_prop, Set.mem_univ,
    iff_true_iff]
  use mk H K x
  obtain ⟨h, k, h3, h4, h5⟩ := mk_out'_eq_mul H K x
  

Proof state:
case h.intro.intro.intro.intro
G : Type u_1
inst✝¹ : Group G
α : Type u_2
inst✝ : Mul α
J : Subgroup G
g : G
H K : Subgroup G
x h k : G
h3 : h ∈ H
h4 : k ∈ K
h5 : Quotient.out' (mk H K x) = h * x * k
⊢ ∃ x_1 ∈ H, ∃ y ∈ K, x = x_1 * Quotient.out' (mk H K x) * y

Next tactic:
refine' ⟨h⁻¹, H.inv_mem h3, k⁻¹, K.inv_mem h4, _⟩
theorem union_quotToDoset (H K : Subgroup G) : ⋃ q, quotToDoset H K q = Set.univ := by
  ext x
  simp only [Set.mem_iUnion, quotToDoset, mem_doset, SetLike.mem_coe, exists_prop, Set.mem_univ,
    iff_true_iff]
  use mk H K x
  obtain ⟨h, k, h3, h4, h5⟩ := mk_out'_eq_mul H K x
  refine' ⟨h⁻¹, H.inv_mem h3, k⁻¹, K.inv_mem h4, _⟩
  

Proof state:
case h.intro.intro.intro.intro
G : Type u_1
inst✝¹ : Group G
α : Type u_2
inst✝ : Mul α
J : Subgroup G
g : G
H K : Subgroup G
x h k : G
h3 : h ∈ H
h4 : k ∈ K
h5 : Quotient.out' (mk H K x) = h * x * k
⊢ x = h⁻¹ * Quotient.out' (mk H K x) * k⁻¹

Next tactic:
simp only [h5, Subgroup.coe_mk, ← mul_assoc, one_mul, mul_left_inv, mul_inv_cancel_right]
theorem doset_union_rightCoset (H K : Subgroup G) (a : G) :
    ⋃ k : K, op (a * k) • ↑H = doset a H K := by
  

Proof state:
G : Type u_1
inst✝¹ : Group G
α : Type u_2
inst✝ : Mul α
J : Subgroup G
g : G
H K : Subgroup G
a : G
⊢ ⋃ k, op (a * ↑k) • ↑H = doset a ↑H ↑K

Next tactic:
ext x
theorem doset_union_rightCoset (H K : Subgroup G) (a : G) :
    ⋃ k : K, op (a * k) • ↑H = doset a H K := by
  ext x
  

Proof state:
case h
G : Type u_1
inst✝¹ : Group G
α : Type u_2
inst✝ : Mul α
J : Subgroup G
g : G
H K : Subgroup G
a x : G
⊢ x ∈ ⋃ k, op (a * ↑k) • ↑H ↔ x ∈ doset a ↑H ↑K

Next tactic:
simp only [mem_rightCoset_iff, exists_prop, mul_inv_rev, Set.mem_iUnion, mem_doset,
    Subgroup.mem_carrier, SetLike.mem_coe]
theorem doset_union_rightCoset (H K : Subgroup G) (a : G) :
    ⋃ k : K, op (a * k) • ↑H = doset a H K := by
  ext x
  simp only [mem_rightCoset_iff, exists_prop, mul_inv_rev, Set.mem_iUnion, mem_doset,
    Subgroup.mem_carrier, SetLike.mem_coe]
  

Proof state:
case h
G : Type u_1
inst✝¹ : Group G
α : Type u_2
inst✝ : Mul α
J : Subgroup G
g : G
H K : Subgroup G
a x : G
⊢ (∃ i, x * ((↑i)⁻¹ * a⁻¹) ∈ H) ↔ ∃ x_1 ∈ H, ∃ y ∈ K, x = x_1 * a * y

Next tactic:
constructor
theorem doset_union_rightCoset (H K : Subgroup G) (a : G) :
    ⋃ k : K, op (a * k) • ↑H = doset a H K := by
  ext x
  simp only [mem_rightCoset_iff, exists_prop, mul_inv_rev, Set.mem_iUnion, mem_doset,
    Subgroup.mem_carrier, SetLike.mem_coe]
  constructor
  · 

Proof state:
case h.mp
G : Type u_1
inst✝¹ : Group G
α : Type u_2
inst✝ : Mul α
J : Subgroup G
g : G
H K : Subgroup G
a x : G
⊢ (∃ i, x * ((↑i)⁻¹ * a⁻¹) ∈ H) → ∃ x_1 ∈ H, ∃ y ∈ K, x = x_1 * a * y

Next tactic:
rintro ⟨y, h_h⟩
theorem doset_union_rightCoset (H K : Subgroup G) (a : G) :
    ⋃ k : K, op (a * k) • ↑H = doset a H K := by
  ext x
  simp only [mem_rightCoset_iff, exists_prop, mul_inv_rev, Set.mem_iUnion, mem_doset,
    Subgroup.mem_carrier, SetLike.mem_coe]
  constructor
  · rintro ⟨y, h_h⟩
    

Proof state:
case h.mp.intro
G : Type u_1
inst✝¹ : Group G
α : Type u_2
inst✝ : Mul α
J : Subgroup G
g : G
H K : Subgroup G
a x : G
y : ↥K
h_h : x * ((↑y)⁻¹ * a⁻¹) ∈ H
⊢ ∃ x_1 ∈ H, ∃ y ∈ K, x = x_1 * a * y

Next tactic:
refine' ⟨x * (y⁻¹ * a⁻¹), h_h, y, y.2, _⟩
theorem doset_union_rightCoset (H K : Subgroup G) (a : G) :
    ⋃ k : K, op (a * k) • ↑H = doset a H K := by
  ext x
  simp only [mem_rightCoset_iff, exists_prop, mul_inv_rev, Set.mem_iUnion, mem_doset,
    Subgroup.mem_carrier, SetLike.mem_coe]
  constructor
  · rintro ⟨y, h_h⟩
    refine' ⟨x * (y⁻¹ * a⁻¹), h_h, y, y.2, _⟩
    

Proof state:
case h.mp.intro
G : Type u_1
inst✝¹ : Group G
α : Type u_2
inst✝ : Mul α
J : Subgroup G
g : G
H K : Subgroup G
a x : G
y : ↥K
h_h : x * ((↑y)⁻¹ * a⁻¹) ∈ H
⊢ x = x * (↑y⁻¹ * a⁻¹) * a * ↑y

Next tactic:
simp only [← mul_assoc, Subgroup.coe_mk, inv_mul_cancel_right, SubgroupClass.coe_inv]
theorem doset_union_rightCoset (H K : Subgroup G) (a : G) :
    ⋃ k : K, op (a * k) • ↑H = doset a H K := by
  ext x
  simp only [mem_rightCoset_iff, exists_prop, mul_inv_rev, Set.mem_iUnion, mem_doset,
    Subgroup.mem_carrier, SetLike.mem_coe]
  constructor
  · rintro ⟨y, h_h⟩
    refine' ⟨x * (y⁻¹ * a⁻¹), h_h, y, y.2, _⟩
    simp only [← mul_assoc, Subgroup.coe_mk, inv_mul_cancel_right, SubgroupClass.coe_inv]
  · 

Proof state:
case h.mpr
G : Type u_1
inst✝¹ : Group G
α : Type u_2
inst✝ : Mul α
J : Subgroup G
g : G
H K : Subgroup G
a x : G
⊢ (∃ x_1 ∈ H, ∃ y ∈ K, x = x_1 * a * y) → ∃ i, x * ((↑i)⁻¹ * a⁻¹) ∈ H

Next tactic:
rintro ⟨x, hx, y, hy, hxy⟩
theorem doset_union_rightCoset (H K : Subgroup G) (a : G) :
    ⋃ k : K, op (a * k) • ↑H = doset a H K := by
  ext x
  simp only [mem_rightCoset_iff, exists_prop, mul_inv_rev, Set.mem_iUnion, mem_doset,
    Subgroup.mem_carrier, SetLike.mem_coe]
  constructor
  · rintro ⟨y, h_h⟩
    refine' ⟨x * (y⁻¹ * a⁻¹), h_h, y, y.2, _⟩
    simp only [← mul_assoc, Subgroup.coe_mk, inv_mul_cancel_right, SubgroupClass.coe_inv]
  · rintro ⟨x, hx, y, hy, hxy⟩
    

Proof state:
case h.mpr.intro.intro.intro.intro
G : Type u_1
inst✝¹ : Group G
α : Type u_2
inst✝ : Mul α
J : Subgroup G
g : G
H K : Subgroup G
a x✝ x : G
hx : x ∈ H
y : G
hy : y ∈ K
hxy : x✝ = x * a * y
⊢ ∃ i, x✝ * ((↑i)⁻¹ * a⁻¹) ∈ H

Next tactic:
refine' ⟨⟨y, hy⟩, _⟩
theorem doset_union_rightCoset (H K : Subgroup G) (a : G) :
    ⋃ k : K, op (a * k) • ↑H = doset a H K := by
  ext x
  simp only [mem_rightCoset_iff, exists_prop, mul_inv_rev, Set.mem_iUnion, mem_doset,
    Subgroup.mem_carrier, SetLike.mem_coe]
  constructor
  · rintro ⟨y, h_h⟩
    refine' ⟨x * (y⁻¹ * a⁻¹), h_h, y, y.2, _⟩
    simp only [← mul_assoc, Subgroup.coe_mk, inv_mul_cancel_right, SubgroupClass.coe_inv]
  · rintro ⟨x, hx, y, hy, hxy⟩
    refine' ⟨⟨y, hy⟩, _⟩
    

Proof state:
case h.mpr.intro.intro.intro.intro
G : Type u_1
inst✝¹ : Group G
α : Type u_2
inst✝ : Mul α
J : Subgroup G
g : G
H K : Subgroup G
a x✝ x : G
hx : x ∈ H
y : G
hy : y ∈ K
hxy : x✝ = x * a * y
⊢ x✝ * ((↑{ val := y, property := hy })⁻¹ * a⁻¹) ∈ H

Next tactic:
simp only [hxy, ← mul_assoc, hx, mul_inv_cancel_right, Subgroup.coe_mk]
theorem doset_union_leftCoset (H K : Subgroup G) (a : G) :
    ⋃ h : H, (h * a : G) • ↑K = doset a H K := by
  

Proof state:
G : Type u_1
inst✝¹ : Group G
α : Type u_2
inst✝ : Mul α
J : Subgroup G
g : G
H K : Subgroup G
a : G
⊢ ⋃ h, (↑h * a) • ↑K = doset a ↑H ↑K

Next tactic:
ext x
theorem doset_union_leftCoset (H K : Subgroup G) (a : G) :
    ⋃ h : H, (h * a : G) • ↑K = doset a H K := by
  ext x
  

Proof state:
case h
G : Type u_1
inst✝¹ : Group G
α : Type u_2
inst✝ : Mul α
J : Subgroup G
g : G
H K : Subgroup G
a x : G
⊢ x ∈ ⋃ h, (↑h * a) • ↑K ↔ x ∈ doset a ↑H ↑K

Next tactic:
simp only [mem_leftCoset_iff, mul_inv_rev, Set.mem_iUnion, mem_doset]
theorem doset_union_leftCoset (H K : Subgroup G) (a : G) :
    ⋃ h : H, (h * a : G) • ↑K = doset a H K := by
  ext x
  simp only [mem_leftCoset_iff, mul_inv_rev, Set.mem_iUnion, mem_doset]
  

Proof state:
case h
G : Type u_1
inst✝¹ : Group G
α : Type u_2
inst✝ : Mul α
J : Subgroup G
g : G
H K : Subgroup G
a x : G
⊢ (∃ i, a⁻¹ * (↑i)⁻¹ * x ∈ ↑K) ↔ ∃ x_1 ∈ ↑H, ∃ y ∈ ↑K, x = x_1 * a * y

Next tactic:
constructor
theorem doset_union_leftCoset (H K : Subgroup G) (a : G) :
    ⋃ h : H, (h * a : G) • ↑K = doset a H K := by
  ext x
  simp only [mem_leftCoset_iff, mul_inv_rev, Set.mem_iUnion, mem_doset]
  constructor
  · 

Proof state:
case h.mp
G : Type u_1
inst✝¹ : Group G
α : Type u_2
inst✝ : Mul α
J : Subgroup G
g : G
H K : Subgroup G
a x : G
⊢ (∃ i, a⁻¹ * (↑i)⁻¹ * x ∈ ↑K) → ∃ x_1 ∈ ↑H, ∃ y ∈ ↑K, x = x_1 * a * y

Next tactic:
rintro ⟨y, h_h⟩
theorem doset_union_leftCoset (H K : Subgroup G) (a : G) :
    ⋃ h : H, (h * a : G) • ↑K = doset a H K := by
  ext x
  simp only [mem_leftCoset_iff, mul_inv_rev, Set.mem_iUnion, mem_doset]
  constructor
  · rintro ⟨y, h_h⟩
    

Proof state:
case h.mp.intro
G : Type u_1
inst✝¹ : Group G
α : Type u_2
inst✝ : Mul α
J : Subgroup G
g : G
H K : Subgroup G
a x : G
y : ↥H
h_h : a⁻¹ * (↑y)⁻¹ * x ∈ ↑K
⊢ ∃ x_1 ∈ ↑H, ∃ y ∈ ↑K, x = x_1 * a * y

Next tactic:
refine' ⟨y, y.2, a⁻¹ * y⁻¹ * x, h_h, _⟩
theorem doset_union_leftCoset (H K : Subgroup G) (a : G) :
    ⋃ h : H, (h * a : G) • ↑K = doset a H K := by
  ext x
  simp only [mem_leftCoset_iff, mul_inv_rev, Set.mem_iUnion, mem_doset]
  constructor
  · rintro ⟨y, h_h⟩
    refine' ⟨y, y.2, a⁻¹ * y⁻¹ * x, h_h, _⟩
    

Proof state:
case h.mp.intro
G : Type u_1
inst✝¹ : Group G
α : Type u_2
inst✝ : Mul α
J : Subgroup G
g : G
H K : Subgroup G
a x : G
y : ↥H
h_h : a⁻¹ * (↑y)⁻¹ * x ∈ ↑K
⊢ x = ↑y * a * (a⁻¹ * ↑y⁻¹ * x)

Next tactic:
simp only [← mul_assoc, one_mul, mul_right_inv, mul_inv_cancel_right, SubgroupClass.coe_inv]
theorem doset_union_leftCoset (H K : Subgroup G) (a : G) :
    ⋃ h : H, (h * a : G) • ↑K = doset a H K := by
  ext x
  simp only [mem_leftCoset_iff, mul_inv_rev, Set.mem_iUnion, mem_doset]
  constructor
  · rintro ⟨y, h_h⟩
    refine' ⟨y, y.2, a⁻¹ * y⁻¹ * x, h_h, _⟩
    simp only [← mul_assoc, one_mul, mul_right_inv, mul_inv_cancel_right, SubgroupClass.coe_inv]
  · 

Proof state:
case h.mpr
G : Type u_1
inst✝¹ : Group G
α : Type u_2
inst✝ : Mul α
J : Subgroup G
g : G
H K : Subgroup G
a x : G
⊢ (∃ x_1 ∈ ↑H, ∃ y ∈ ↑K, x = x_1 * a * y) → ∃ i, a⁻¹ * (↑i)⁻¹ * x ∈ ↑K

Next tactic:
rintro ⟨x, hx, y, hy, hxy⟩
theorem doset_union_leftCoset (H K : Subgroup G) (a : G) :
    ⋃ h : H, (h * a : G) • ↑K = doset a H K := by
  ext x
  simp only [mem_leftCoset_iff, mul_inv_rev, Set.mem_iUnion, mem_doset]
  constructor
  · rintro ⟨y, h_h⟩
    refine' ⟨y, y.2, a⁻¹ * y⁻¹ * x, h_h, _⟩
    simp only [← mul_assoc, one_mul, mul_right_inv, mul_inv_cancel_right, SubgroupClass.coe_inv]
  · rintro ⟨x, hx, y, hy, hxy⟩
    

Proof state:
case h.mpr.intro.intro.intro.intro
G : Type u_1
inst✝¹ : Group G
α : Type u_2
inst✝ : Mul α
J : Subgroup G
g : G
H K : Subgroup G
a x✝ x : G
hx : x ∈ ↑H
y : G
hy : y ∈ ↑K
hxy : x✝ = x * a * y
⊢ ∃ i, a⁻¹ * (↑i)⁻¹ * x✝ ∈ ↑K

Next tactic:
refine' ⟨⟨x, hx⟩, _⟩
theorem doset_union_leftCoset (H K : Subgroup G) (a : G) :
    ⋃ h : H, (h * a : G) • ↑K = doset a H K := by
  ext x
  simp only [mem_leftCoset_iff, mul_inv_rev, Set.mem_iUnion, mem_doset]
  constructor
  · rintro ⟨y, h_h⟩
    refine' ⟨y, y.2, a⁻¹ * y⁻¹ * x, h_h, _⟩
    simp only [← mul_assoc, one_mul, mul_right_inv, mul_inv_cancel_right, SubgroupClass.coe_inv]
  · rintro ⟨x, hx, y, hy, hxy⟩
    refine' ⟨⟨x, hx⟩, _⟩
    

Proof state:
case h.mpr.intro.intro.intro.intro
G : Type u_1
inst✝¹ : Group G
α : Type u_2
inst✝ : Mul α
J : Subgroup G
g : G
H K : Subgroup G
a x✝ x : G
hx : x ∈ ↑H
y : G
hy : y ∈ ↑K
hxy : x✝ = x * a * y
⊢ a⁻¹ * (↑{ val := x, property := hx })⁻¹ * x✝ ∈ ↑K

Next tactic:
simp only [hxy, ← mul_assoc, hy, one_mul, mul_left_inv, Subgroup.coe_mk, inv_mul_cancel_right]
theorem left_bot_eq_left_quot (H : Subgroup G) :
    Quotient (⊥ : Subgroup G).1 (H : Set G) = (G ⧸ H) := by
  

Proof state:
G : Type u_1
inst✝¹ : Group G
α : Type u_2
inst✝ : Mul α
J : Subgroup G
g : G
H : Subgroup G
⊢ Quotient ↑⊥.toSubmonoid ↑H = (G ⧸ H)

Next tactic:
unfold Quotient
theorem left_bot_eq_left_quot (H : Subgroup G) :
    Quotient (⊥ : Subgroup G).1 (H : Set G) = (G ⧸ H) := by
  unfold Quotient
  

Proof state:
G : Type u_1
inst✝¹ : Group G
α : Type u_2
inst✝ : Mul α
J : Subgroup G
g : G
H : Subgroup G
⊢ _root_.Quotient (setoid ↑⊥.toSubmonoid ↑H) = (G ⧸ H)

Next tactic:
congr
theorem left_bot_eq_left_quot (H : Subgroup G) :
    Quotient (⊥ : Subgroup G).1 (H : Set G) = (G ⧸ H) := by
  unfold Quotient
  congr
  

Proof state:
case e_s
G : Type u_1
inst✝¹ : Group G
α : Type u_2
inst✝ : Mul α
J : Subgroup G
g : G
H : Subgroup G
⊢ setoid ↑⊥.toSubmonoid ↑H = QuotientGroup.leftRel H

Next tactic:
ext
theorem left_bot_eq_left_quot (H : Subgroup G) :
    Quotient (⊥ : Subgroup G).1 (H : Set G) = (G ⧸ H) := by
  unfold Quotient
  congr
  ext
  

Proof state:
case e_s.H
G : Type u_1
inst✝¹ : Group G
α : Type u_2
inst✝ : Mul α
J : Subgroup G
g : G
H : Subgroup G
a✝ b✝ : G
⊢ Setoid.Rel (setoid ↑⊥.toSubmonoid ↑H) a✝ b✝ ↔ Setoid.Rel (QuotientGroup.leftRel H) a✝ b✝

Next tactic:
simp_rw [← bot_rel_eq_leftRel H]
theorem left_bot_eq_left_quot (H : Subgroup G) :
    Quotient (⊥ : Subgroup G).1 (H : Set G) = (G ⧸ H) := by
  unfold Quotient
  congr
  ext
  simp_rw [← bot_rel_eq_leftRel H]
  

Proof state:
case e_s.H
G : Type u_1
inst✝¹ : Group G
α : Type u_2
inst✝ : Mul α
J : Subgroup G
g : G
H : Subgroup G
a✝ b✝ : G
⊢ Setoid.Rel (setoid ↑⊥.toSubmonoid ↑H) a✝ b✝ ↔ Setoid.Rel (setoid ↑⊥ ↑H) a✝ b✝

Next tactic:
rfl