l3lab/ntp-mathlib huggingface dataset:
@[to_additive]
theorem IsComplement'.symm (h : IsComplement' H K) : IsComplement' K H := by
  let ϕ : H × K ≃ K × H :=
    Equiv.mk (fun x => ⟨x.2⁻¹, x.1⁻¹⟩) (fun x => ⟨x.2⁻¹, x.1⁻¹⟩)
      (fun x => Prod.ext (inv_inv _) (inv_inv _)) fun x => Prod.ext (inv_inv _) (inv_inv _)
  let ψ : G ≃ G := Equiv.mk (fun g : G => g⁻¹) (fun g : G => g⁻¹) inv_inv inv_inv
  suffices hf : (ψ ∘ fun x : H × K => x.1.1 * x.2.1) = (fun x : K × H => x.1.1 * x.2.1) ∘ ϕ by
    rw [isComplement'_def, IsComplement, ← Equiv.bijective_comp ϕ]
    apply (congr_arg Function.Bijective hf).mp -- porting note: This was a `rw` in mathlib3
    

Proof state:
G : Type u_1
inst✝ : Group G
H K : Subgroup G
S T : Set G
h : IsComplement' H K
ϕ : ↥H × ↥K ≃ ↥K × ↥H :=
  { toFun := fun x => (x.2⁻¹, x.1⁻¹), invFun := fun x => (x.2⁻¹, x.1⁻¹),
    left_inv := (_ : ∀ (x : ↥H × ↥K), (fun x => (x.2⁻¹, x.1⁻¹)) ((fun x => (x.2⁻¹, x.1⁻¹)) x) = x),
    right_inv := (_ : ∀ (x : ↥K × ↥H), (fun x => (x.2⁻¹, x.1⁻¹)) ((fun x => (x.2⁻¹, x.1⁻¹)) x) = x) }
ψ : G ≃ G :=
  { toFun := fun g => g⁻¹, invFun := fun g => g⁻¹, left_inv := (_ : ∀ (a : G), a⁻¹⁻¹ = a),
    right_inv := (_ : ∀ (a : G), a⁻¹⁻¹ = a) }
hf : (⇑ψ ∘ fun x => ↑x.1 * ↑x.2) = (fun x => ↑x.1 * ↑x.2) ∘ ⇑ϕ
⊢ Function.Bijective (⇑ψ ∘ fun x => ↑x.1 * ↑x.2)

Next tactic:
rwa [ψ.comp_bijective]
@[to_additive]
theorem IsComplement'.symm (h : IsComplement' H K) : IsComplement' K H := by
  let ϕ : H × K ≃ K × H :=
    Equiv.mk (fun x => ⟨x.2⁻¹, x.1⁻¹⟩) (fun x => ⟨x.2⁻¹, x.1⁻¹⟩)
      (fun x => Prod.ext (inv_inv _) (inv_inv _)) fun x => Prod.ext (inv_inv _) (inv_inv _)
  let ψ : G ≃ G := Equiv.mk (fun g : G => g⁻¹) (fun g : G => g⁻¹) inv_inv inv_inv
  suffices hf : (ψ ∘ fun x : H × K => x.1.1 * x.2.1) = (fun x : K × H => x.1.1 * x.2.1) ∘ ϕ by
    rw [isComplement'_def, IsComplement, ← Equiv.bijective_comp ϕ]
    apply (congr_arg Function.Bijective hf).mp -- porting note: This was a `rw` in mathlib3
    rwa [ψ.comp_bijective]
  

Proof state:
G : Type u_1
inst✝ : Group G
H K : Subgroup G
S T : Set G
h : IsComplement' H K
ϕ : ↥H × ↥K ≃ ↥K × ↥H :=
  { toFun := fun x => (x.2⁻¹, x.1⁻¹), invFun := fun x => (x.2⁻¹, x.1⁻¹),
    left_inv := (_ : ∀ (x : ↥H × ↥K), (fun x => (x.2⁻¹, x.1⁻¹)) ((fun x => (x.2⁻¹, x.1⁻¹)) x) = x),
    right_inv := (_ : ∀ (x : ↥K × ↥H), (fun x => (x.2⁻¹, x.1⁻¹)) ((fun x => (x.2⁻¹, x.1⁻¹)) x) = x) }
ψ : G ≃ G :=
  { toFun := fun g => g⁻¹, invFun := fun g => g⁻¹, left_inv := (_ : ∀ (a : G), a⁻¹⁻¹ = a),
    right_inv := (_ : ∀ (a : G), a⁻¹⁻¹ = a) }
⊢ (⇑ψ ∘ fun x => ↑x.1 * ↑x.2) = (fun x => ↑x.1 * ↑x.2) ∘ ⇑ϕ

Next tactic:
exact funext fun x => mul_inv_rev _ _
@[to_additive]
theorem isComplement_singleton_left {g : G} : IsComplement {g} S ↔ S = univ := by
  

Proof state:
G : Type u_1
inst✝ : Group G
H K : Subgroup G
S T : Set G
g : G
⊢ IsComplement {g} S ↔ S = univ

Next tactic:
refine'
    ⟨fun h => top_le_iff.mp fun x _ => _, fun h => (congr_arg _ h).mpr isComplement_singleton_univ⟩
@[to_additive]
theorem isComplement_singleton_left {g : G} : IsComplement {g} S ↔ S = univ := by
  refine'
    ⟨fun h => top_le_iff.mp fun x _ => _, fun h => (congr_arg _ h).mpr isComplement_singleton_univ⟩
  

Proof state:
G : Type u_1
inst✝ : Group G
H K : Subgroup G
S T : Set G
g : G
h : IsComplement {g} S
x : G
x✝ : x ∈ ⊤
⊢ x ∈ S

Next tactic:
obtain ⟨⟨⟨z, rfl : z = g⟩, y, _⟩, hy⟩ := h.2 (g * x)
@[to_additive]
theorem isComplement_singleton_left {g : G} : IsComplement {g} S ↔ S = univ := by
  refine'
    ⟨fun h => top_le_iff.mp fun x _ => _, fun h => (congr_arg _ h).mpr isComplement_singleton_univ⟩
  obtain ⟨⟨⟨z, rfl : z = g⟩, y, _⟩, hy⟩ := h.2 (g * x)
  

Proof state:
case intro.mk.mk.mk
G : Type u_1
inst✝ : Group G
H K : Subgroup G
S T : Set G
x : G
x✝ : x ∈ ⊤
z : G
h : IsComplement {z} S
y : G
property✝ : y ∈ S
hy : (fun x => ↑x.1 * ↑x.2) ({ val := z, property := (_ : z = z) }, { val := y, property := property✝ }) = z * x
⊢ x ∈ S

Next tactic:
rwa [← mul_left_cancel hy]
@[to_additive]
theorem isComplement_singleton_right {g : G} : IsComplement S {g} ↔ S = univ := by
  

Proof state:
G : Type u_1
inst✝ : Group G
H K : Subgroup G
S T : Set G
g : G
⊢ IsComplement S {g} ↔ S = univ

Next tactic:
refine'
    ⟨fun h => top_le_iff.mp fun x _ => _, fun h => h ▸ isComplement_univ_singleton⟩
@[to_additive]
theorem isComplement_singleton_right {g : G} : IsComplement S {g} ↔ S = univ := by
  refine'
    ⟨fun h => top_le_iff.mp fun x _ => _, fun h => h ▸ isComplement_univ_singleton⟩
  

Proof state:
G : Type u_1
inst✝ : Group G
H K : Subgroup G
S T : Set G
g : G
h : IsComplement S {g}
x : G
x✝ : x ∈ ⊤
⊢ x ∈ S

Next tactic:
obtain ⟨y, hy⟩ := h.2 (x * g)
@[to_additive]
theorem isComplement_singleton_right {g : G} : IsComplement S {g} ↔ S = univ := by
  refine'
    ⟨fun h => top_le_iff.mp fun x _ => _, fun h => h ▸ isComplement_univ_singleton⟩
  obtain ⟨y, hy⟩ := h.2 (x * g)
  

Proof state:
case intro
G : Type u_1
inst✝ : Group G
H K : Subgroup G
S T : Set G
g : G
h : IsComplement S {g}
x : G
x✝ : x ∈ ⊤
y : ↑S × ↑{g}
hy : (fun x => ↑x.1 * ↑x.2) y = x * g
⊢ x ∈ S

Next tactic:
conv_rhs at hy => rw [← show y.2.1 = g from y.2.2]
@[to_additive]
theorem isComplement_singleton_right {g : G} : IsComplement S {g} ↔ S = univ := by
  refine'
    ⟨fun h => top_le_iff.mp fun x _ => _, fun h => h ▸ isComplement_univ_singleton⟩
  obtain ⟨y, hy⟩ := h.2 (x * g)
  conv_rhs at hy => 

Proof state:
G : Type u_1
inst✝ : Group G
H K : Subgroup G
S T : Set G
g : G
h : IsComplement S {g}
x : G
x✝ : x ∈ ⊤
y : ↑S × ↑{g}
hy : (fun x => ↑x.1 * ↑x.2) y = x * g
| x * g

Next tactic:
rw [← show y.2.1 = g from y.2.2]
@[to_additive]
theorem isComplement_singleton_right {g : G} : IsComplement S {g} ↔ S = univ := by
  refine'
    ⟨fun h => top_le_iff.mp fun x _ => _, fun h => h ▸ isComplement_univ_singleton⟩
  obtain ⟨y, hy⟩ := h.2 (x * g)
  conv_rhs at hy => rw [← show y.2.1 = g from y.2.2]
  

Proof state:
case intro
G : Type u_1
inst✝ : Group G
H K : Subgroup G
S T : Set G
g : G
h : IsComplement S {g}
x : G
x✝ : x ∈ ⊤
y : ↑S × ↑{g}
hy : (fun x => ↑x.1 * ↑x.2) y = x * ↑y.2
⊢ x ∈ S

Next tactic:
rw [← mul_right_cancel hy]
@[to_additive]
theorem isComplement_singleton_right {g : G} : IsComplement S {g} ↔ S = univ := by
  refine'
    ⟨fun h => top_le_iff.mp fun x _ => _, fun h => h ▸ isComplement_univ_singleton⟩
  obtain ⟨y, hy⟩ := h.2 (x * g)
  conv_rhs at hy => rw [← show y.2.1 = g from y.2.2]
  rw [← mul_right_cancel hy]
  

Proof state:
case intro
G : Type u_1
inst✝ : Group G
H K : Subgroup G
S T : Set G
g : G
h : IsComplement S {g}
x : G
x✝ : x ∈ ⊤
y : ↑S × ↑{g}
hy : (fun x => ↑x.1 * ↑x.2) y = x * ↑y.2
⊢ ↑y.1 ∈ S

Next tactic:
exact y.1.2
@[to_additive]
theorem isComplement_univ_left : IsComplement univ S ↔ ∃ g : G, S = {g} := by
  

Proof state:
G : Type u_1
inst✝ : Group G
H K : Subgroup G
S T : Set G
⊢ IsComplement univ S ↔ ∃ g, S = {g}

Next tactic:
refine'
    ⟨fun h => Set.exists_eq_singleton_iff_nonempty_subsingleton.mpr ⟨_, fun a ha b hb => _⟩, _⟩
@[to_additive]
theorem isComplement_univ_left : IsComplement univ S ↔ ∃ g : G, S = {g} := by
  refine'
    ⟨fun h => Set.exists_eq_singleton_iff_nonempty_subsingleton.mpr ⟨_, fun a ha b hb => _⟩, _⟩
  · 

Proof state:
case refine'_1
G : Type u_1
inst✝ : Group G
H K : Subgroup G
S T : Set G
h : IsComplement univ S
⊢ Set.Nonempty S

Next tactic:
obtain ⟨a, _⟩ := h.2 1
@[to_additive]
theorem isComplement_univ_left : IsComplement univ S ↔ ∃ g : G, S = {g} := by
  refine'
    ⟨fun h => Set.exists_eq_singleton_iff_nonempty_subsingleton.mpr ⟨_, fun a ha b hb => _⟩, _⟩
  · obtain ⟨a, _⟩ := h.2 1
    

Proof state:
case refine'_1.intro
G : Type u_1
inst✝ : Group G
H K : Subgroup G
S T : Set G
h : IsComplement univ S
a : ↑univ × ↑S
h✝ : (fun x => ↑x.1 * ↑x.2) a = 1
⊢ Set.Nonempty S

Next tactic:
exact ⟨a.2.1, a.2.2⟩
@[to_additive]
theorem isComplement_univ_left : IsComplement univ S ↔ ∃ g : G, S = {g} := by
  refine'
    ⟨fun h => Set.exists_eq_singleton_iff_nonempty_subsingleton.mpr ⟨_, fun a ha b hb => _⟩, _⟩
  · obtain ⟨a, _⟩ := h.2 1
    exact ⟨a.2.1, a.2.2⟩
  · 

Proof state:
case refine'_2
G : Type u_1
inst✝ : Group G
H K : Subgroup G
S T : Set G
h : IsComplement univ S
a : G
ha : a ∈ S
b : G
hb : b ∈ S
⊢ a = b

Next tactic:
have : (⟨⟨_, mem_top a⁻¹⟩, ⟨a, ha⟩⟩ : (⊤ : Set G) × S) = ⟨⟨_, mem_top b⁻¹⟩, ⟨b, hb⟩⟩ :=
      h.1 ((inv_mul_self a).trans (inv_mul_self b).symm)
@[to_additive]
theorem isComplement_univ_left : IsComplement univ S ↔ ∃ g : G, S = {g} := by
  refine'
    ⟨fun h => Set.exists_eq_singleton_iff_nonempty_subsingleton.mpr ⟨_, fun a ha b hb => _⟩, _⟩
  · obtain ⟨a, _⟩ := h.2 1
    exact ⟨a.2.1, a.2.2⟩
  · have : (⟨⟨_, mem_top a⁻¹⟩, ⟨a, ha⟩⟩ : (⊤ : Set G) × S) = ⟨⟨_, mem_top b⁻¹⟩, ⟨b, hb⟩⟩ :=
      h.1 ((inv_mul_self a).trans (inv_mul_self b).symm)
    

Proof state:
case refine'_2
G : Type u_1
inst✝ : Group G
H K : Subgroup G
S T : Set G
h : IsComplement univ S
a : G
ha : a ∈ S
b : G
hb : b ∈ S
this :
  ({ val := a⁻¹, property := (_ : a⁻¹ ∈ ⊤) }, { val := a, property := ha }) =
    ({ val := b⁻¹, property := (_ : b⁻¹ ∈ ⊤) }, { val := b, property := hb })
⊢ a = b

Next tactic:
exact Subtype.ext_iff.mp (Prod.ext_iff.mp this).2
@[to_additive]
theorem isComplement_univ_left : IsComplement univ S ↔ ∃ g : G, S = {g} := by
  refine'
    ⟨fun h => Set.exists_eq_singleton_iff_nonempty_subsingleton.mpr ⟨_, fun a ha b hb => _⟩, _⟩
  · obtain ⟨a, _⟩ := h.2 1
    exact ⟨a.2.1, a.2.2⟩
  · have : (⟨⟨_, mem_top a⁻¹⟩, ⟨a, ha⟩⟩ : (⊤ : Set G) × S) = ⟨⟨_, mem_top b⁻¹⟩, ⟨b, hb⟩⟩ :=
      h.1 ((inv_mul_self a).trans (inv_mul_self b).symm)
    exact Subtype.ext_iff.mp (Prod.ext_iff.mp this).2
  · 

Proof state:
case refine'_3
G : Type u_1
inst✝ : Group G
H K : Subgroup G
S T : Set G
⊢ (∃ g, S = {g}) → IsComplement univ S

Next tactic:
rintro ⟨g, rfl⟩
@[to_additive]
theorem isComplement_univ_left : IsComplement univ S ↔ ∃ g : G, S = {g} := by
  refine'
    ⟨fun h => Set.exists_eq_singleton_iff_nonempty_subsingleton.mpr ⟨_, fun a ha b hb => _⟩, _⟩
  · obtain ⟨a, _⟩ := h.2 1
    exact ⟨a.2.1, a.2.2⟩
  · have : (⟨⟨_, mem_top a⁻¹⟩, ⟨a, ha⟩⟩ : (⊤ : Set G) × S) = ⟨⟨_, mem_top b⁻¹⟩, ⟨b, hb⟩⟩ :=
      h.1 ((inv_mul_self a).trans (inv_mul_self b).symm)
    exact Subtype.ext_iff.mp (Prod.ext_iff.mp this).2
  · rintro ⟨g, rfl⟩
    

Proof state:
case refine'_3.intro
G : Type u_1
inst✝ : Group G
H K : Subgroup G
T : Set G
g : G
⊢ IsComplement univ {g}

Next tactic:
exact isComplement_univ_singleton
@[to_additive]
theorem isComplement_univ_right : IsComplement S univ ↔ ∃ g : G, S = {g} := by
  

Proof state:
G : Type u_1
inst✝ : Group G
H K : Subgroup G
S T : Set G
⊢ IsComplement S univ ↔ ∃ g, S = {g}

Next tactic:
refine'
    ⟨fun h => Set.exists_eq_singleton_iff_nonempty_subsingleton.mpr ⟨_, fun a ha b hb => _⟩, _⟩
@[to_additive]
theorem isComplement_univ_right : IsComplement S univ ↔ ∃ g : G, S = {g} := by
  refine'
    ⟨fun h => Set.exists_eq_singleton_iff_nonempty_subsingleton.mpr ⟨_, fun a ha b hb => _⟩, _⟩
  · 

Proof state:
case refine'_1
G : Type u_1
inst✝ : Group G
H K : Subgroup G
S T : Set G
h : IsComplement S univ
⊢ Set.Nonempty S

Next tactic:
obtain ⟨a, _⟩ := h.2 1
@[to_additive]
theorem isComplement_univ_right : IsComplement S univ ↔ ∃ g : G, S = {g} := by
  refine'
    ⟨fun h => Set.exists_eq_singleton_iff_nonempty_subsingleton.mpr ⟨_, fun a ha b hb => _⟩, _⟩
  · obtain ⟨a, _⟩ := h.2 1
    

Proof state:
case refine'_1.intro
G : Type u_1
inst✝ : Group G
H K : Subgroup G
S T : Set G
h : IsComplement S univ
a : ↑S × ↑univ
h✝ : (fun x => ↑x.1 * ↑x.2) a = 1
⊢ Set.Nonempty S

Next tactic:
exact ⟨a.1.1, a.1.2⟩
@[to_additive]
theorem isComplement_univ_right : IsComplement S univ ↔ ∃ g : G, S = {g} := by
  refine'
    ⟨fun h => Set.exists_eq_singleton_iff_nonempty_subsingleton.mpr ⟨_, fun a ha b hb => _⟩, _⟩
  · obtain ⟨a, _⟩ := h.2 1
    exact ⟨a.1.1, a.1.2⟩
  · 

Proof state:
case refine'_2
G : Type u_1
inst✝ : Group G
H K : Subgroup G
S T : Set G
h : IsComplement S univ
a : G
ha : a ∈ S
b : G
hb : b ∈ S
⊢ a = b

Next tactic:
have : (⟨⟨a, ha⟩, ⟨_, mem_top a⁻¹⟩⟩ : S × (⊤ : Set G)) = ⟨⟨b, hb⟩, ⟨_, mem_top b⁻¹⟩⟩ :=
      h.1 ((mul_inv_self a).trans (mul_inv_self b).symm)
@[to_additive]
theorem isComplement_univ_right : IsComplement S univ ↔ ∃ g : G, S = {g} := by
  refine'
    ⟨fun h => Set.exists_eq_singleton_iff_nonempty_subsingleton.mpr ⟨_, fun a ha b hb => _⟩, _⟩
  · obtain ⟨a, _⟩ := h.2 1
    exact ⟨a.1.1, a.1.2⟩
  · have : (⟨⟨a, ha⟩, ⟨_, mem_top a⁻¹⟩⟩ : S × (⊤ : Set G)) = ⟨⟨b, hb⟩, ⟨_, mem_top b⁻¹⟩⟩ :=
      h.1 ((mul_inv_self a).trans (mul_inv_self b).symm)
    

Proof state:
case refine'_2
G : Type u_1
inst✝ : Group G
H K : Subgroup G
S T : Set G
h : IsComplement S univ
a : G
ha : a ∈ S
b : G
hb : b ∈ S
this :
  ({ val := a, property := ha }, { val := a⁻¹, property := (_ : a⁻¹ ∈ ⊤) }) =
    ({ val := b, property := hb }, { val := b⁻¹, property := (_ : b⁻¹ ∈ ⊤) })
⊢ a = b

Next tactic:
exact Subtype.ext_iff.mp (Prod.ext_iff.mp this).1
@[to_additive]
theorem isComplement_univ_right : IsComplement S univ ↔ ∃ g : G, S = {g} := by
  refine'
    ⟨fun h => Set.exists_eq_singleton_iff_nonempty_subsingleton.mpr ⟨_, fun a ha b hb => _⟩, _⟩
  · obtain ⟨a, _⟩ := h.2 1
    exact ⟨a.1.1, a.1.2⟩
  · have : (⟨⟨a, ha⟩, ⟨_, mem_top a⁻¹⟩⟩ : S × (⊤ : Set G)) = ⟨⟨b, hb⟩, ⟨_, mem_top b⁻¹⟩⟩ :=
      h.1 ((mul_inv_self a).trans (mul_inv_self b).symm)
    exact Subtype.ext_iff.mp (Prod.ext_iff.mp this).1
  · 

Proof state:
case refine'_3
G : Type u_1
inst✝ : Group G
H K : Subgroup G
S T : Set G
⊢ (∃ g, S = {g}) → IsComplement S univ

Next tactic:
rintro ⟨g, rfl⟩
@[to_additive]
theorem isComplement_univ_right : IsComplement S univ ↔ ∃ g : G, S = {g} := by
  refine'
    ⟨fun h => Set.exists_eq_singleton_iff_nonempty_subsingleton.mpr ⟨_, fun a ha b hb => _⟩, _⟩
  · obtain ⟨a, _⟩ := h.2 1
    exact ⟨a.1.1, a.1.2⟩
  · have : (⟨⟨a, ha⟩, ⟨_, mem_top a⁻¹⟩⟩ : S × (⊤ : Set G)) = ⟨⟨b, hb⟩, ⟨_, mem_top b⁻¹⟩⟩ :=
      h.1 ((mul_inv_self a).trans (mul_inv_self b).symm)
    exact Subtype.ext_iff.mp (Prod.ext_iff.mp this).1
  · rintro ⟨g, rfl⟩
    

Proof state:
case refine'_3.intro
G : Type u_1
inst✝ : Group G
H K : Subgroup G
T : Set G
g : G
⊢ IsComplement {g} univ

Next tactic:
exact isComplement_singleton_univ
@[to_additive]
lemma IsComplement.mul_eq (h : IsComplement S T) : S * T = univ :=
  eq_univ_of_forall fun x ↦ by 

Proof state:
G : Type u_1
inst✝ : Group G
H K : Subgroup G
S T : Set G
h : IsComplement S T
x : G
⊢ x ∈ S * T

Next tactic:
simpa [mem_mul] using (h.existsUnique x).exists
@[to_additive]
theorem mem_leftTransversals_iff_existsUnique_inv_mul_mem :
    S ∈ leftTransversals T ↔ ∀ g : G, ∃! s : S, (s : G)⁻¹ * g ∈ T := by
  

Proof state:
G : Type u_1
inst✝ : Group G
H K : Subgroup G
S T : Set G
⊢ S ∈ leftTransversals T ↔ ∀ (g : G), ∃! s, (↑s)⁻¹ * g ∈ T

Next tactic:
rw [leftTransversals, Set.mem_setOf_eq, isComplement_iff_existsUnique]
@[to_additive]
theorem mem_leftTransversals_iff_existsUnique_inv_mul_mem :
    S ∈ leftTransversals T ↔ ∀ g : G, ∃! s : S, (s : G)⁻¹ * g ∈ T := by
  rw [leftTransversals, Set.mem_setOf_eq, isComplement_iff_existsUnique]
  

Proof state:
G : Type u_1
inst✝ : Group G
H K : Subgroup G
S T : Set G
⊢ (∀ (g : G), ∃! x, ↑x.1 * ↑x.2 = g) ↔ ∀ (g : G), ∃! s, (↑s)⁻¹ * g ∈ T

Next tactic:
refine' ⟨fun h g => _, fun h g => _⟩
@[to_additive]
theorem mem_leftTransversals_iff_existsUnique_inv_mul_mem :
    S ∈ leftTransversals T ↔ ∀ g : G, ∃! s : S, (s : G)⁻¹ * g ∈ T := by
  rw [leftTransversals, Set.mem_setOf_eq, isComplement_iff_existsUnique]
  refine' ⟨fun h g => _, fun h g => _⟩
  · 

Proof state:
case refine'_1
G : Type u_1
inst✝ : Group G
H K : Subgroup G
S T : Set G
h : ∀ (g : G), ∃! x, ↑x.1 * ↑x.2 = g
g : G
⊢ ∃! s, (↑s)⁻¹ * g ∈ T

Next tactic:
obtain ⟨x, h1, h2⟩ := h g
@[to_additive]
theorem mem_leftTransversals_iff_existsUnique_inv_mul_mem :
    S ∈ leftTransversals T ↔ ∀ g : G, ∃! s : S, (s : G)⁻¹ * g ∈ T := by
  rw [leftTransversals, Set.mem_setOf_eq, isComplement_iff_existsUnique]
  refine' ⟨fun h g => _, fun h g => _⟩
  · obtain ⟨x, h1, h2⟩ := h g
    

Proof state:
case refine'_1.intro.intro
G : Type u_1
inst✝ : Group G
H K : Subgroup G
S T : Set G
h : ∀ (g : G), ∃! x, ↑x.1 * ↑x.2 = g
g : G
x : ↑S × ↑T
h1 : ↑x.1 * ↑x.2 = g
h2 : ∀ (y : ↑S × ↑T), (fun x => ↑x.1 * ↑x.2 = g) y → y = x
⊢ ∃! s, (↑s)⁻¹ * g ∈ T

Next tactic:
exact
      ⟨x.1, (congr_arg (· ∈ T) (eq_inv_mul_of_mul_eq h1)).mp x.2.2, fun y hy =>
        (Prod.ext_iff.mp (h2 ⟨y, (↑y)⁻¹ * g, hy⟩ (mul_inv_cancel_left ↑y g))).1⟩
@[to_additive]
theorem mem_leftTransversals_iff_existsUnique_inv_mul_mem :
    S ∈ leftTransversals T ↔ ∀ g : G, ∃! s : S, (s : G)⁻¹ * g ∈ T := by
  rw [leftTransversals, Set.mem_setOf_eq, isComplement_iff_existsUnique]
  refine' ⟨fun h g => _, fun h g => _⟩
  · obtain ⟨x, h1, h2⟩ := h g
    exact
      ⟨x.1, (congr_arg (· ∈ T) (eq_inv_mul_of_mul_eq h1)).mp x.2.2, fun y hy =>
        (Prod.ext_iff.mp (h2 ⟨y, (↑y)⁻¹ * g, hy⟩ (mul_inv_cancel_left ↑y g))).1⟩
  · 

Proof state:
case refine'_2
G : Type u_1
inst✝ : Group G
H K : Subgroup G
S T : Set G
h : ∀ (g : G), ∃! s, (↑s)⁻¹ * g ∈ T
g : G
⊢ ∃! x, ↑x.1 * ↑x.2 = g

Next tactic:
obtain ⟨x, h1, h2⟩ := h g
@[to_additive]
theorem mem_leftTransversals_iff_existsUnique_inv_mul_mem :
    S ∈ leftTransversals T ↔ ∀ g : G, ∃! s : S, (s : G)⁻¹ * g ∈ T := by
  rw [leftTransversals, Set.mem_setOf_eq, isComplement_iff_existsUnique]
  refine' ⟨fun h g => _, fun h g => _⟩
  · obtain ⟨x, h1, h2⟩ := h g
    exact
      ⟨x.1, (congr_arg (· ∈ T) (eq_inv_mul_of_mul_eq h1)).mp x.2.2, fun y hy =>
        (Prod.ext_iff.mp (h2 ⟨y, (↑y)⁻¹ * g, hy⟩ (mul_inv_cancel_left ↑y g))).1⟩
  · obtain ⟨x, h1, h2⟩ := h g
    

Proof state:
case refine'_2.intro.intro
G : Type u_1
inst✝ : Group G
H K : Subgroup G
S T : Set G
h : ∀ (g : G), ∃! s, (↑s)⁻¹ * g ∈ T
g : G
x : ↑S
h1 : (↑x)⁻¹ * g ∈ T
h2 : ∀ (y : ↑S), (fun s => (↑s)⁻¹ * g ∈ T) y → y = x
⊢ ∃! x, ↑x.1 * ↑x.2 = g

Next tactic:
refine' ⟨⟨x, (↑x)⁻¹ * g, h1⟩, mul_inv_cancel_left (↑x) g, fun y hy => _⟩
@[to_additive]
theorem mem_leftTransversals_iff_existsUnique_inv_mul_mem :
    S ∈ leftTransversals T ↔ ∀ g : G, ∃! s : S, (s : G)⁻¹ * g ∈ T := by
  rw [leftTransversals, Set.mem_setOf_eq, isComplement_iff_existsUnique]
  refine' ⟨fun h g => _, fun h g => _⟩
  · obtain ⟨x, h1, h2⟩ := h g
    exact
      ⟨x.1, (congr_arg (· ∈ T) (eq_inv_mul_of_mul_eq h1)).mp x.2.2, fun y hy =>
        (Prod.ext_iff.mp (h2 ⟨y, (↑y)⁻¹ * g, hy⟩ (mul_inv_cancel_left ↑y g))).1⟩
  · obtain ⟨x, h1, h2⟩ := h g
    refine' ⟨⟨x, (↑x)⁻¹ * g, h1⟩, mul_inv_cancel_left (↑x) g, fun y hy => _⟩
    

Proof state:
case refine'_2.intro.intro
G : Type u_1
inst✝ : Group G
H K : Subgroup G
S T : Set G
h : ∀ (g : G), ∃! s, (↑s)⁻¹ * g ∈ T
g : G
x : ↑S
h1 : (↑x)⁻¹ * g ∈ T
h2 : ∀ (y : ↑S), (fun s => (↑s)⁻¹ * g ∈ T) y → y = x
y : ↑S × ↑T
hy : (fun x => ↑x.1 * ↑x.2 = g) y
⊢ y = (x, { val := (↑x)⁻¹ * g, property := h1 })

Next tactic:
have hf := h2 y.1 ((congr_arg (· ∈ T) (eq_inv_mul_of_mul_eq hy)).mp y.2.2)
@[to_additive]
theorem mem_leftTransversals_iff_existsUnique_inv_mul_mem :
    S ∈ leftTransversals T ↔ ∀ g : G, ∃! s : S, (s : G)⁻¹ * g ∈ T := by
  rw [leftTransversals, Set.mem_setOf_eq, isComplement_iff_existsUnique]
  refine' ⟨fun h g => _, fun h g => _⟩
  · obtain ⟨x, h1, h2⟩ := h g
    exact
      ⟨x.1, (congr_arg (· ∈ T) (eq_inv_mul_of_mul_eq h1)).mp x.2.2, fun y hy =>
        (Prod.ext_iff.mp (h2 ⟨y, (↑y)⁻¹ * g, hy⟩ (mul_inv_cancel_left ↑y g))).1⟩
  · obtain ⟨x, h1, h2⟩ := h g
    refine' ⟨⟨x, (↑x)⁻¹ * g, h1⟩, mul_inv_cancel_left (↑x) g, fun y hy => _⟩
    have hf := h2 y.1 ((congr_arg (· ∈ T) (eq_inv_mul_of_mul_eq hy)).mp y.2.2)
    

Proof state:
case refine'_2.intro.intro
G : Type u_1
inst✝ : Group G
H K : Subgroup G
S T : Set G
h : ∀ (g : G), ∃! s, (↑s)⁻¹ * g ∈ T
g : G
x : ↑S
h1 : (↑x)⁻¹ * g ∈ T
h2 : ∀ (y : ↑S), (fun s => (↑s)⁻¹ * g ∈ T) y → y = x
y : ↑S × ↑T
hy : (fun x => ↑x.1 * ↑x.2 = g) y
hf : y.1 = x
⊢ y = (x, { val := (↑x)⁻¹ * g, property := h1 })

Next tactic:
exact Prod.ext hf (Subtype.ext (eq_inv_mul_of_mul_eq (hf ▸ hy)))
@[to_additive]
theorem mem_rightTransversals_iff_existsUnique_mul_inv_mem :
    S ∈ rightTransversals T ↔ ∀ g : G, ∃! s : S, g * (s : G)⁻¹ ∈ T := by
  

Proof state:
G : Type u_1
inst✝ : Group G
H K : Subgroup G
S T : Set G
⊢ S ∈ rightTransversals T ↔ ∀ (g : G), ∃! s, g * (↑s)⁻¹ ∈ T

Next tactic:
rw [rightTransversals, Set.mem_setOf_eq, isComplement_iff_existsUnique]
@[to_additive]
theorem mem_rightTransversals_iff_existsUnique_mul_inv_mem :
    S ∈ rightTransversals T ↔ ∀ g : G, ∃! s : S, g * (s : G)⁻¹ ∈ T := by
  rw [rightTransversals, Set.mem_setOf_eq, isComplement_iff_existsUnique]
  

Proof state:
G : Type u_1
inst✝ : Group G
H K : Subgroup G
S T : Set G
⊢ (∀ (g : G), ∃! x, ↑x.1 * ↑x.2 = g) ↔ ∀ (g : G), ∃! s, g * (↑s)⁻¹ ∈ T

Next tactic:
refine' ⟨fun h g => _, fun h g => _⟩
@[to_additive]
theorem mem_rightTransversals_iff_existsUnique_mul_inv_mem :
    S ∈ rightTransversals T ↔ ∀ g : G, ∃! s : S, g * (s : G)⁻¹ ∈ T := by
  rw [rightTransversals, Set.mem_setOf_eq, isComplement_iff_existsUnique]
  refine' ⟨fun h g => _, fun h g => _⟩
  · 

Proof state:
case refine'_1
G : Type u_1
inst✝ : Group G
H K : Subgroup G
S T : Set G
h : ∀ (g : G), ∃! x, ↑x.1 * ↑x.2 = g
g : G
⊢ ∃! s, g * (↑s)⁻¹ ∈ T

Next tactic:
obtain ⟨x, h1, h2⟩ := h g
@[to_additive]
theorem mem_rightTransversals_iff_existsUnique_mul_inv_mem :
    S ∈ rightTransversals T ↔ ∀ g : G, ∃! s : S, g * (s : G)⁻¹ ∈ T := by
  rw [rightTransversals, Set.mem_setOf_eq, isComplement_iff_existsUnique]
  refine' ⟨fun h g => _, fun h g => _⟩
  · obtain ⟨x, h1, h2⟩ := h g
    

Proof state:
case refine'_1.intro.intro
G : Type u_1
inst✝ : Group G
H K : Subgroup G
S T : Set G
h : ∀ (g : G), ∃! x, ↑x.1 * ↑x.2 = g
g : G
x : ↑T × ↑S
h1 : ↑x.1 * ↑x.2 = g
h2 : ∀ (y : ↑T × ↑S), (fun x => ↑x.1 * ↑x.2 = g) y → y = x
⊢ ∃! s, g * (↑s)⁻¹ ∈ T

Next tactic:
exact
      ⟨x.2, (congr_arg (· ∈ T) (eq_mul_inv_of_mul_eq h1)).mp x.1.2, fun y hy =>
        (Prod.ext_iff.mp (h2 ⟨⟨g * (↑y)⁻¹, hy⟩, y⟩ (inv_mul_cancel_right g y))).2⟩
@[to_additive]
theorem mem_rightTransversals_iff_existsUnique_mul_inv_mem :
    S ∈ rightTransversals T ↔ ∀ g : G, ∃! s : S, g * (s : G)⁻¹ ∈ T := by
  rw [rightTransversals, Set.mem_setOf_eq, isComplement_iff_existsUnique]
  refine' ⟨fun h g => _, fun h g => _⟩
  · obtain ⟨x, h1, h2⟩ := h g
    exact
      ⟨x.2, (congr_arg (· ∈ T) (eq_mul_inv_of_mul_eq h1)).mp x.1.2, fun y hy =>
        (Prod.ext_iff.mp (h2 ⟨⟨g * (↑y)⁻¹, hy⟩, y⟩ (inv_mul_cancel_right g y))).2⟩
  · 

Proof state:
case refine'_2
G : Type u_1
inst✝ : Group G
H K : Subgroup G
S T : Set G
h : ∀ (g : G), ∃! s, g * (↑s)⁻¹ ∈ T
g : G
⊢ ∃! x, ↑x.1 * ↑x.2 = g

Next tactic:
obtain ⟨x, h1, h2⟩ := h g
@[to_additive]
theorem mem_rightTransversals_iff_existsUnique_mul_inv_mem :
    S ∈ rightTransversals T ↔ ∀ g : G, ∃! s : S, g * (s : G)⁻¹ ∈ T := by
  rw [rightTransversals, Set.mem_setOf_eq, isComplement_iff_existsUnique]
  refine' ⟨fun h g => _, fun h g => _⟩
  · obtain ⟨x, h1, h2⟩ := h g
    exact
      ⟨x.2, (congr_arg (· ∈ T) (eq_mul_inv_of_mul_eq h1)).mp x.1.2, fun y hy =>
        (Prod.ext_iff.mp (h2 ⟨⟨g * (↑y)⁻¹, hy⟩, y⟩ (inv_mul_cancel_right g y))).2⟩
  · obtain ⟨x, h1, h2⟩ := h g
    

Proof state:
case refine'_2.intro.intro
G : Type u_1
inst✝ : Group G
H K : Subgroup G
S T : Set G
h : ∀ (g : G), ∃! s, g * (↑s)⁻¹ ∈ T
g : G
x : ↑S
h1 : g * (↑x)⁻¹ ∈ T
h2 : ∀ (y : ↑S), (fun s => g * (↑s)⁻¹ ∈ T) y → y = x
⊢ ∃! x, ↑x.1 * ↑x.2 = g

Next tactic:
refine' ⟨⟨⟨g * (↑x)⁻¹, h1⟩, x⟩, inv_mul_cancel_right g x, fun y hy => _⟩
@[to_additive]
theorem mem_rightTransversals_iff_existsUnique_mul_inv_mem :
    S ∈ rightTransversals T ↔ ∀ g : G, ∃! s : S, g * (s : G)⁻¹ ∈ T := by
  rw [rightTransversals, Set.mem_setOf_eq, isComplement_iff_existsUnique]
  refine' ⟨fun h g => _, fun h g => _⟩
  · obtain ⟨x, h1, h2⟩ := h g
    exact
      ⟨x.2, (congr_arg (· ∈ T) (eq_mul_inv_of_mul_eq h1)).mp x.1.2, fun y hy =>
        (Prod.ext_iff.mp (h2 ⟨⟨g * (↑y)⁻¹, hy⟩, y⟩ (inv_mul_cancel_right g y))).2⟩
  · obtain ⟨x, h1, h2⟩ := h g
    refine' ⟨⟨⟨g * (↑x)⁻¹, h1⟩, x⟩, inv_mul_cancel_right g x, fun y hy => _⟩
    

Proof state:
case refine'_2.intro.intro
G : Type u_1
inst✝ : Group G
H K : Subgroup G
S T : Set G
h : ∀ (g : G), ∃! s, g * (↑s)⁻¹ ∈ T
g : G
x : ↑S
h1 : g * (↑x)⁻¹ ∈ T
h2 : ∀ (y : ↑S), (fun s => g * (↑s)⁻¹ ∈ T) y → y = x
y : ↑T × ↑S
hy : (fun x => ↑x.1 * ↑x.2 = g) y
⊢ y = ({ val := g * (↑x)⁻¹, property := h1 }, x)

Next tactic:
have hf := h2 y.2 ((congr_arg (· ∈ T) (eq_mul_inv_of_mul_eq hy)).mp y.1.2)