l3lab/ntp-mathlib huggingface dataset:
theorem equiv_snd_eq_iff_rightCosetEquivalence {g₁ g₂ : G} :
    (hHT.equiv g₁).snd = (hHT.equiv g₂).snd ↔ RightCosetEquivalence H g₁ g₂ := by
  rw [RightCosetEquivalence, rightCoset_eq_iff]
  constructor
  · 

Proof state:
case mp
G : Type u_1
inst✝ : Group G
H K : Subgroup G
S T : Set G
hST : IsComplement S T
hHT : IsComplement (↑H) T
hSK : IsComplement S ↑K
g₁ g₂ : G
⊢ ((equiv hHT) g₁).2 = ((equiv hHT) g₂).2 → g₂ * g₁⁻¹ ∈ H

Next tactic:
intro h
theorem equiv_snd_eq_iff_rightCosetEquivalence {g₁ g₂ : G} :
    (hHT.equiv g₁).snd = (hHT.equiv g₂).snd ↔ RightCosetEquivalence H g₁ g₂ := by
  rw [RightCosetEquivalence, rightCoset_eq_iff]
  constructor
  · intro h
    

Proof state:
case mp
G : Type u_1
inst✝ : Group G
H K : Subgroup G
S T : Set G
hST : IsComplement S T
hHT : IsComplement (↑H) T
hSK : IsComplement S ↑K
g₁ g₂ : G
h : ((equiv hHT) g₁).2 = ((equiv hHT) g₂).2
⊢ g₂ * g₁⁻¹ ∈ H

Next tactic:
rw [← hHT.equiv_fst_mul_equiv_snd g₂, ← hHT.equiv_fst_mul_equiv_snd g₁, ← h,
      mul_inv_rev, mul_assoc, mul_inv_cancel_left, ← coe_inv, ← coe_mul]
theorem equiv_snd_eq_iff_rightCosetEquivalence {g₁ g₂ : G} :
    (hHT.equiv g₁).snd = (hHT.equiv g₂).snd ↔ RightCosetEquivalence H g₁ g₂ := by
  rw [RightCosetEquivalence, rightCoset_eq_iff]
  constructor
  · intro h
    rw [← hHT.equiv_fst_mul_equiv_snd g₂, ← hHT.equiv_fst_mul_equiv_snd g₁, ← h,
      mul_inv_rev, mul_assoc, mul_inv_cancel_left, ← coe_inv, ← coe_mul]
    

Proof state:
case mp
G : Type u_1
inst✝ : Group G
H K : Subgroup G
S T : Set G
hST : IsComplement S T
hHT : IsComplement (↑H) T
hSK : IsComplement S ↑K
g₁ g₂ : G
h : ((equiv hHT) g₁).2 = ((equiv hHT) g₂).2
⊢ ↑(((equiv hHT) g₂).1 * ((equiv hHT) g₁).1⁻¹) ∈ H

Next tactic:
exact Subtype.property _
theorem equiv_snd_eq_iff_rightCosetEquivalence {g₁ g₂ : G} :
    (hHT.equiv g₁).snd = (hHT.equiv g₂).snd ↔ RightCosetEquivalence H g₁ g₂ := by
  rw [RightCosetEquivalence, rightCoset_eq_iff]
  constructor
  · intro h
    rw [← hHT.equiv_fst_mul_equiv_snd g₂, ← hHT.equiv_fst_mul_equiv_snd g₁, ← h,
      mul_inv_rev, mul_assoc, mul_inv_cancel_left, ← coe_inv, ← coe_mul]
    exact Subtype.property _
  · 

Proof state:
case mpr
G : Type u_1
inst✝ : Group G
H K : Subgroup G
S T : Set G
hST : IsComplement S T
hHT : IsComplement (↑H) T
hSK : IsComplement S ↑K
g₁ g₂ : G
⊢ g₂ * g₁⁻¹ ∈ H → ((equiv hHT) g₁).2 = ((equiv hHT) g₂).2

Next tactic:
intro h
theorem equiv_snd_eq_iff_rightCosetEquivalence {g₁ g₂ : G} :
    (hHT.equiv g₁).snd = (hHT.equiv g₂).snd ↔ RightCosetEquivalence H g₁ g₂ := by
  rw [RightCosetEquivalence, rightCoset_eq_iff]
  constructor
  · intro h
    rw [← hHT.equiv_fst_mul_equiv_snd g₂, ← hHT.equiv_fst_mul_equiv_snd g₁, ← h,
      mul_inv_rev, mul_assoc, mul_inv_cancel_left, ← coe_inv, ← coe_mul]
    exact Subtype.property _
  · intro h
    

Proof state:
case mpr
G : Type u_1
inst✝ : Group G
H K : Subgroup G
S T : Set G
hST : IsComplement S T
hHT : IsComplement (↑H) T
hSK : IsComplement S ↑K
g₁ g₂ : G
h : g₂ * g₁⁻¹ ∈ H
⊢ ((equiv hHT) g₁).2 = ((equiv hHT) g₂).2

Next tactic:
apply (mem_rightTransversals_iff_existsUnique_mul_inv_mem.1 hHT g₁).unique
theorem equiv_snd_eq_iff_rightCosetEquivalence {g₁ g₂ : G} :
    (hHT.equiv g₁).snd = (hHT.equiv g₂).snd ↔ RightCosetEquivalence H g₁ g₂ := by
  rw [RightCosetEquivalence, rightCoset_eq_iff]
  constructor
  · intro h
    rw [← hHT.equiv_fst_mul_equiv_snd g₂, ← hHT.equiv_fst_mul_equiv_snd g₁, ← h,
      mul_inv_rev, mul_assoc, mul_inv_cancel_left, ← coe_inv, ← coe_mul]
    exact Subtype.property _
  · intro h
    apply (mem_rightTransversals_iff_existsUnique_mul_inv_mem.1 hHT g₁).unique
    · -- This used to be `simp [...]` before leanprover/lean4#2644
      

Proof state:
case mpr.py₁
G : Type u_1
inst✝ : Group G
H K : Subgroup G
S T : Set G
hST : IsComplement S T
hHT : IsComplement (↑H) T
hSK : IsComplement S ↑K
g₁ g₂ : G
h : g₂ * g₁⁻¹ ∈ H
⊢ g₁ * (↑((equiv hHT) g₁).2)⁻¹ ∈ ↑H

Next tactic:
rw [equiv_snd_eq_inv_mul]
theorem equiv_snd_eq_iff_rightCosetEquivalence {g₁ g₂ : G} :
    (hHT.equiv g₁).snd = (hHT.equiv g₂).snd ↔ RightCosetEquivalence H g₁ g₂ := by
  rw [RightCosetEquivalence, rightCoset_eq_iff]
  constructor
  · intro h
    rw [← hHT.equiv_fst_mul_equiv_snd g₂, ← hHT.equiv_fst_mul_equiv_snd g₁, ← h,
      mul_inv_rev, mul_assoc, mul_inv_cancel_left, ← coe_inv, ← coe_mul]
    exact Subtype.property _
  · intro h
    apply (mem_rightTransversals_iff_existsUnique_mul_inv_mem.1 hHT g₁).unique
    · -- This used to be `simp [...]` before leanprover/lean4#2644
      rw [equiv_snd_eq_inv_mul]; 

Proof state:
case mpr.py₁
G : Type u_1
inst✝ : Group G
H K : Subgroup G
S T : Set G
hST : IsComplement S T
hHT : IsComplement (↑H) T
hSK : IsComplement S ↑K
g₁ g₂ : G
h : g₂ * g₁⁻¹ ∈ H
⊢ g₁ * ((↑((equiv hHT) g₁).1)⁻¹ * g₁)⁻¹ ∈ ↑H

Next tactic:
simp
theorem equiv_snd_eq_iff_rightCosetEquivalence {g₁ g₂ : G} :
    (hHT.equiv g₁).snd = (hHT.equiv g₂).snd ↔ RightCosetEquivalence H g₁ g₂ := by
  rw [RightCosetEquivalence, rightCoset_eq_iff]
  constructor
  · intro h
    rw [← hHT.equiv_fst_mul_equiv_snd g₂, ← hHT.equiv_fst_mul_equiv_snd g₁, ← h,
      mul_inv_rev, mul_assoc, mul_inv_cancel_left, ← coe_inv, ← coe_mul]
    exact Subtype.property _
  · intro h
    apply (mem_rightTransversals_iff_existsUnique_mul_inv_mem.1 hHT g₁).unique
    · -- This used to be `simp [...]` before leanprover/lean4#2644
      rw [equiv_snd_eq_inv_mul]; simp
    · 

Proof state:
case mpr.py₂
G : Type u_1
inst✝ : Group G
H K : Subgroup G
S T : Set G
hST : IsComplement S T
hHT : IsComplement (↑H) T
hSK : IsComplement S ↑K
g₁ g₂ : G
h : g₂ * g₁⁻¹ ∈ H
⊢ g₁ * (↑((equiv hHT) g₂).2)⁻¹ ∈ ↑H

Next tactic:
rw [SetLike.mem_coe, ← mul_mem_cancel_left h]
theorem equiv_snd_eq_iff_rightCosetEquivalence {g₁ g₂ : G} :
    (hHT.equiv g₁).snd = (hHT.equiv g₂).snd ↔ RightCosetEquivalence H g₁ g₂ := by
  rw [RightCosetEquivalence, rightCoset_eq_iff]
  constructor
  · intro h
    rw [← hHT.equiv_fst_mul_equiv_snd g₂, ← hHT.equiv_fst_mul_equiv_snd g₁, ← h,
      mul_inv_rev, mul_assoc, mul_inv_cancel_left, ← coe_inv, ← coe_mul]
    exact Subtype.property _
  · intro h
    apply (mem_rightTransversals_iff_existsUnique_mul_inv_mem.1 hHT g₁).unique
    · -- This used to be `simp [...]` before leanprover/lean4#2644
      rw [equiv_snd_eq_inv_mul]; simp
    · rw [SetLike.mem_coe, ← mul_mem_cancel_left h]
      -- This used to be `simp [...]` before leanprover/lean4#2644
      

Proof state:
case mpr.py₂
G : Type u_1
inst✝ : Group G
H K : Subgroup G
S T : Set G
hST : IsComplement S T
hHT : IsComplement (↑H) T
hSK : IsComplement S ↑K
g₁ g₂ : G
h : g₂ * g₁⁻¹ ∈ H
⊢ g₂ * g₁⁻¹ * (g₁ * (↑((equiv hHT) g₂).2)⁻¹) ∈ H

Next tactic:
rw [equiv_snd_eq_inv_mul, mul_assoc]
theorem equiv_snd_eq_iff_rightCosetEquivalence {g₁ g₂ : G} :
    (hHT.equiv g₁).snd = (hHT.equiv g₂).snd ↔ RightCosetEquivalence H g₁ g₂ := by
  rw [RightCosetEquivalence, rightCoset_eq_iff]
  constructor
  · intro h
    rw [← hHT.equiv_fst_mul_equiv_snd g₂, ← hHT.equiv_fst_mul_equiv_snd g₁, ← h,
      mul_inv_rev, mul_assoc, mul_inv_cancel_left, ← coe_inv, ← coe_mul]
    exact Subtype.property _
  · intro h
    apply (mem_rightTransversals_iff_existsUnique_mul_inv_mem.1 hHT g₁).unique
    · -- This used to be `simp [...]` before leanprover/lean4#2644
      rw [equiv_snd_eq_inv_mul]; simp
    · rw [SetLike.mem_coe, ← mul_mem_cancel_left h]
      -- This used to be `simp [...]` before leanprover/lean4#2644
      rw [equiv_snd_eq_inv_mul, mul_assoc]; 

Proof state:
case mpr.py₂
G : Type u_1
inst✝ : Group G
H K : Subgroup G
S T : Set G
hST : IsComplement S T
hHT : IsComplement (↑H) T
hSK : IsComplement S ↑K
g₁ g₂ : G
h : g₂ * g₁⁻¹ ∈ H
⊢ g₂ * (g₁⁻¹ * (g₁ * ((↑((equiv hHT) g₂).1)⁻¹ * g₂)⁻¹)) ∈ H

Next tactic:
simp
theorem leftCosetEquivalence_equiv_fst (g : G) :
    LeftCosetEquivalence K g ((hSK.equiv g).fst : G) := by
  -- This used to be `simp [...]` before leanprover/lean4#2644
  

Proof state:
G : Type u_1
inst✝ : Group G
H K : Subgroup G
S T : Set G
hST : IsComplement S T
hHT : IsComplement (↑H) T
hSK : IsComplement S ↑K
g : G
⊢ LeftCosetEquivalence (↑K) g ↑((equiv hSK) g).1

Next tactic:
rw [equiv_fst_eq_mul_inv]
theorem leftCosetEquivalence_equiv_fst (g : G) :
    LeftCosetEquivalence K g ((hSK.equiv g).fst : G) := by
  -- This used to be `simp [...]` before leanprover/lean4#2644
  rw [equiv_fst_eq_mul_inv]; 

Proof state:
G : Type u_1
inst✝ : Group G
H K : Subgroup G
S T : Set G
hST : IsComplement S T
hHT : IsComplement (↑H) T
hSK : IsComplement S ↑K
g : G
⊢ LeftCosetEquivalence (↑K) g (g * (↑((equiv hSK) g).2)⁻¹)

Next tactic:
simp [LeftCosetEquivalence, leftCoset_eq_iff]
theorem rightCosetEquivalence_equiv_snd (g : G) :
    RightCosetEquivalence H g ((hHT.equiv g).snd : G) := by
  -- This used to be `simp [...]` before leanprover/lean4#2644
  

Proof state:
G : Type u_1
inst✝ : Group G
H K : Subgroup G
S T : Set G
hST : IsComplement S T
hHT : IsComplement (↑H) T
hSK : IsComplement S ↑K
g : G
⊢ RightCosetEquivalence (↑H) g ↑((equiv hHT) g).2

Next tactic:
rw [RightCosetEquivalence, rightCoset_eq_iff, equiv_snd_eq_inv_mul]
theorem rightCosetEquivalence_equiv_snd (g : G) :
    RightCosetEquivalence H g ((hHT.equiv g).snd : G) := by
  -- This used to be `simp [...]` before leanprover/lean4#2644
  rw [RightCosetEquivalence, rightCoset_eq_iff, equiv_snd_eq_inv_mul]; 

Proof state:
G : Type u_1
inst✝ : Group G
H K : Subgroup G
S T : Set G
hST : IsComplement S T
hHT : IsComplement (↑H) T
hSK : IsComplement S ↑K
g : G
⊢ (↑((equiv hHT) g).1)⁻¹ * g * g⁻¹ ∈ H

Next tactic:
simp
theorem equiv_fst_eq_self_of_mem_of_one_mem {g : G} (h1 : 1 ∈ T) (hg : g ∈ S) :
    (hST.equiv g).fst = ⟨g, hg⟩ := by
  

Proof state:
G : Type u_1
inst✝ : Group G
H K : Subgroup G
S T : Set G
hST : IsComplement S T
hHT : IsComplement (↑H) T
hSK : IsComplement S ↑K
g : G
h1 : 1 ∈ T
hg : g ∈ S
⊢ ((equiv hST) g).1 = { val := g, property := hg }

Next tactic:
have : hST.equiv.symm (⟨g, hg⟩, ⟨1, h1⟩) = g := by
    rw [equiv, Equiv.ofBijective]; simp
theorem equiv_fst_eq_self_of_mem_of_one_mem {g : G} (h1 : 1 ∈ T) (hg : g ∈ S) :
    (hST.equiv g).fst = ⟨g, hg⟩ := by
  have : hST.equiv.symm (⟨g, hg⟩, ⟨1, h1⟩) = g := by
    

Proof state:
G : Type u_1
inst✝ : Group G
H K : Subgroup G
S T : Set G
hST : IsComplement S T
hHT : IsComplement (↑H) T
hSK : IsComplement S ↑K
g : G
h1 : 1 ∈ T
hg : g ∈ S
⊢ (equiv hST).symm ({ val := g, property := hg }, { val := 1, property := h1 }) = g

Next tactic:
rw [equiv, Equiv.ofBijective]
theorem equiv_fst_eq_self_of_mem_of_one_mem {g : G} (h1 : 1 ∈ T) (hg : g ∈ S) :
    (hST.equiv g).fst = ⟨g, hg⟩ := by
  have : hST.equiv.symm (⟨g, hg⟩, ⟨1, h1⟩) = g := by
    rw [equiv, Equiv.ofBijective]; 

Proof state:
G : Type u_1
inst✝ : Group G
H K : Subgroup G
S T : Set G
hST : IsComplement S T
hHT : IsComplement (↑H) T
hSK : IsComplement S ↑K
g : G
h1 : 1 ∈ T
hg : g ∈ S
⊢ { toFun := fun x => ↑x.1 * ↑x.2, invFun := Function.surjInv (_ : Function.Surjective fun x => ↑x.1 * ↑x.2),
            left_inv :=
              (_ :
                Function.LeftInverse (Function.surjInv (_ : Function.Surjective fun x => ↑x.1 * ↑x.2)) fun x =>
                  ↑x.1 * ↑x.2),
            right_inv :=
              (_ :
                Function.RightInverse (Function.surjInv (_ : Function.Surjective fun x => ↑x.1 * ↑x.2)) fun x =>
                  ↑x.1 * ↑x.2) }.symm.symm
      ({ val := g, property := hg }, { val := 1, property := h1 }) =
    g

Next tactic:
simp
theorem equiv_fst_eq_self_of_mem_of_one_mem {g : G} (h1 : 1 ∈ T) (hg : g ∈ S) :
    (hST.equiv g).fst = ⟨g, hg⟩ := by
  have : hST.equiv.symm (⟨g, hg⟩, ⟨1, h1⟩) = g := by
    rw [equiv, Equiv.ofBijective]; simp
  

Proof state:
G : Type u_1
inst✝ : Group G
H K : Subgroup G
S T : Set G
hST : IsComplement S T
hHT : IsComplement (↑H) T
hSK : IsComplement S ↑K
g : G
h1 : 1 ∈ T
hg : g ∈ S
this : (equiv hST).symm ({ val := g, property := hg }, { val := 1, property := h1 }) = g
⊢ ((equiv hST) g).1 = { val := g, property := hg }

Next tactic:
conv_lhs => rw [← this, Equiv.apply_symm_apply]
theorem equiv_fst_eq_self_of_mem_of_one_mem {g : G} (h1 : 1 ∈ T) (hg : g ∈ S) :
    (hST.equiv g).fst = ⟨g, hg⟩ := by
  have : hST.equiv.symm (⟨g, hg⟩, ⟨1, h1⟩) = g := by
    rw [equiv, Equiv.ofBijective]; simp
  conv_lhs => 

Proof state:
G : Type u_1
inst✝ : Group G
H K : Subgroup G
S T : Set G
hST : IsComplement S T
hHT : IsComplement (↑H) T
hSK : IsComplement S ↑K
g : G
h1 : 1 ∈ T
hg : g ∈ S
this : (equiv hST).symm ({ val := g, property := hg }, { val := 1, property := h1 }) = g
| ((equiv hST) g).1

Next tactic:
rw [← this, Equiv.apply_symm_apply]
theorem equiv_snd_eq_self_of_mem_of_one_mem {g : G} (h1 : 1 ∈ S) (hg : g ∈ T) :
    (hST.equiv g).snd = ⟨g, hg⟩ := by
  

Proof state:
G : Type u_1
inst✝ : Group G
H K : Subgroup G
S T : Set G
hST : IsComplement S T
hHT : IsComplement (↑H) T
hSK : IsComplement S ↑K
g : G
h1 : 1 ∈ S
hg : g ∈ T
⊢ ((equiv hST) g).2 = { val := g, property := hg }

Next tactic:
have : hST.equiv.symm (⟨1, h1⟩, ⟨g, hg⟩) = g := by
    rw [equiv, Equiv.ofBijective]; simp
theorem equiv_snd_eq_self_of_mem_of_one_mem {g : G} (h1 : 1 ∈ S) (hg : g ∈ T) :
    (hST.equiv g).snd = ⟨g, hg⟩ := by
  have : hST.equiv.symm (⟨1, h1⟩, ⟨g, hg⟩) = g := by
    

Proof state:
G : Type u_1
inst✝ : Group G
H K : Subgroup G
S T : Set G
hST : IsComplement S T
hHT : IsComplement (↑H) T
hSK : IsComplement S ↑K
g : G
h1 : 1 ∈ S
hg : g ∈ T
⊢ (equiv hST).symm ({ val := 1, property := h1 }, { val := g, property := hg }) = g

Next tactic:
rw [equiv, Equiv.ofBijective]
theorem equiv_snd_eq_self_of_mem_of_one_mem {g : G} (h1 : 1 ∈ S) (hg : g ∈ T) :
    (hST.equiv g).snd = ⟨g, hg⟩ := by
  have : hST.equiv.symm (⟨1, h1⟩, ⟨g, hg⟩) = g := by
    rw [equiv, Equiv.ofBijective]; 

Proof state:
G : Type u_1
inst✝ : Group G
H K : Subgroup G
S T : Set G
hST : IsComplement S T
hHT : IsComplement (↑H) T
hSK : IsComplement S ↑K
g : G
h1 : 1 ∈ S
hg : g ∈ T
⊢ { toFun := fun x => ↑x.1 * ↑x.2, invFun := Function.surjInv (_ : Function.Surjective fun x => ↑x.1 * ↑x.2),
            left_inv :=
              (_ :
                Function.LeftInverse (Function.surjInv (_ : Function.Surjective fun x => ↑x.1 * ↑x.2)) fun x =>
                  ↑x.1 * ↑x.2),
            right_inv :=
              (_ :
                Function.RightInverse (Function.surjInv (_ : Function.Surjective fun x => ↑x.1 * ↑x.2)) fun x =>
                  ↑x.1 * ↑x.2) }.symm.symm
      ({ val := 1, property := h1 }, { val := g, property := hg }) =
    g

Next tactic:
simp
theorem equiv_snd_eq_self_of_mem_of_one_mem {g : G} (h1 : 1 ∈ S) (hg : g ∈ T) :
    (hST.equiv g).snd = ⟨g, hg⟩ := by
  have : hST.equiv.symm (⟨1, h1⟩, ⟨g, hg⟩) = g := by
    rw [equiv, Equiv.ofBijective]; simp
  

Proof state:
G : Type u_1
inst✝ : Group G
H K : Subgroup G
S T : Set G
hST : IsComplement S T
hHT : IsComplement (↑H) T
hSK : IsComplement S ↑K
g : G
h1 : 1 ∈ S
hg : g ∈ T
this : (equiv hST).symm ({ val := 1, property := h1 }, { val := g, property := hg }) = g
⊢ ((equiv hST) g).2 = { val := g, property := hg }

Next tactic:
conv_lhs => rw [← this, Equiv.apply_symm_apply]
theorem equiv_snd_eq_self_of_mem_of_one_mem {g : G} (h1 : 1 ∈ S) (hg : g ∈ T) :
    (hST.equiv g).snd = ⟨g, hg⟩ := by
  have : hST.equiv.symm (⟨1, h1⟩, ⟨g, hg⟩) = g := by
    rw [equiv, Equiv.ofBijective]; simp
  conv_lhs => 

Proof state:
G : Type u_1
inst✝ : Group G
H K : Subgroup G
S T : Set G
hST : IsComplement S T
hHT : IsComplement (↑H) T
hSK : IsComplement S ↑K
g : G
h1 : 1 ∈ S
hg : g ∈ T
this : (equiv hST).symm ({ val := 1, property := h1 }, { val := g, property := hg }) = g
| ((equiv hST) g).2

Next tactic:
rw [← this, Equiv.apply_symm_apply]
theorem equiv_snd_eq_one_of_mem_of_one_mem {g : G} (h1 : 1 ∈ T) (hg : g ∈ S) :
    (hST.equiv g).snd = ⟨1, h1⟩ := by
  

Proof state:
G : Type u_1
inst✝ : Group G
H K : Subgroup G
S T : Set G
hST : IsComplement S T
hHT : IsComplement (↑H) T
hSK : IsComplement S ↑K
g : G
h1 : 1 ∈ T
hg : g ∈ S
⊢ ((equiv hST) g).2 = { val := 1, property := h1 }

Next tactic:
ext
theorem equiv_snd_eq_one_of_mem_of_one_mem {g : G} (h1 : 1 ∈ T) (hg : g ∈ S) :
    (hST.equiv g).snd = ⟨1, h1⟩ := by
  ext
  

Proof state:
case a
G : Type u_1
inst✝ : Group G
H K : Subgroup G
S T : Set G
hST : IsComplement S T
hHT : IsComplement (↑H) T
hSK : IsComplement S ↑K
g : G
h1 : 1 ∈ T
hg : g ∈ S
⊢ ↑((equiv hST) g).2 = ↑{ val := 1, property := h1 }

Next tactic:
rw [equiv_snd_eq_inv_mul, equiv_fst_eq_self_of_mem_of_one_mem _ h1 hg, inv_mul_self]
theorem equiv_fst_eq_one_of_mem_of_one_mem {g : G} (h1 : 1 ∈ S) (hg : g ∈ T) :
    (hST.equiv g).fst = ⟨1, h1⟩ := by
  

Proof state:
G : Type u_1
inst✝ : Group G
H K : Subgroup G
S T : Set G
hST : IsComplement S T
hHT : IsComplement (↑H) T
hSK : IsComplement S ↑K
g : G
h1 : 1 ∈ S
hg : g ∈ T
⊢ ((equiv hST) g).1 = { val := 1, property := h1 }

Next tactic:
ext
theorem equiv_fst_eq_one_of_mem_of_one_mem {g : G} (h1 : 1 ∈ S) (hg : g ∈ T) :
    (hST.equiv g).fst = ⟨1, h1⟩ := by
  ext
  

Proof state:
case a
G : Type u_1
inst✝ : Group G
H K : Subgroup G
S T : Set G
hST : IsComplement S T
hHT : IsComplement (↑H) T
hSK : IsComplement S ↑K
g : G
h1 : 1 ∈ S
hg : g ∈ T
⊢ ↑((equiv hST) g).1 = ↑{ val := 1, property := h1 }

Next tactic:
rw [equiv_fst_eq_mul_inv, equiv_snd_eq_self_of_mem_of_one_mem _ h1 hg, mul_inv_self]
@[simp, nolint simpNF]
theorem equiv_mul_right (g : G) (k : K) :
    hSK.equiv (g * k) = ((hSK.equiv g).fst, (hSK.equiv g).snd * k) := by
  

Proof state:
G : Type u_1
inst✝ : Group G
H K : Subgroup G
S T : Set G
hST : IsComplement S T
hHT : IsComplement (↑H) T
hSK : IsComplement S ↑K
g : G
k : ↥K
⊢ (equiv hSK) (g * ↑k) = (((equiv hSK) g).1, ((equiv hSK) g).2 * k)

Next tactic:
have : (hSK.equiv (g * k)).fst = (hSK.equiv g).fst :=
    hSK.equiv_fst_eq_iff_leftCosetEquivalence.2
      (by simp [LeftCosetEquivalence, leftCoset_eq_iff])
@[simp, nolint simpNF]
theorem equiv_mul_right (g : G) (k : K) :
    hSK.equiv (g * k) = ((hSK.equiv g).fst, (hSK.equiv g).snd * k) := by
  have : (hSK.equiv (g * k)).fst = (hSK.equiv g).fst :=
    hSK.equiv_fst_eq_iff_leftCosetEquivalence.2
      (by 

Proof state:
G : Type u_1
inst✝ : Group G
H K : Subgroup G
S T : Set G
hST : IsComplement S T
hHT : IsComplement (↑H) T
hSK : IsComplement S ↑K
g : G
k : ↥K
⊢ LeftCosetEquivalence (↑K) (g * ↑k) g

Next tactic:
simp [LeftCosetEquivalence, leftCoset_eq_iff]
@[simp, nolint simpNF]
theorem equiv_mul_right (g : G) (k : K) :
    hSK.equiv (g * k) = ((hSK.equiv g).fst, (hSK.equiv g).snd * k) := by
  have : (hSK.equiv (g * k)).fst = (hSK.equiv g).fst :=
    hSK.equiv_fst_eq_iff_leftCosetEquivalence.2
      (by simp [LeftCosetEquivalence, leftCoset_eq_iff])
  

Proof state:
G : Type u_1
inst✝ : Group G
H K : Subgroup G
S T : Set G
hST : IsComplement S T
hHT : IsComplement (↑H) T
hSK : IsComplement S ↑K
g : G
k : ↥K
this : ((equiv hSK) (g * ↑k)).1 = ((equiv hSK) g).1
⊢ (equiv hSK) (g * ↑k) = (((equiv hSK) g).1, ((equiv hSK) g).2 * k)

Next tactic:
ext
@[simp, nolint simpNF]
theorem equiv_mul_right (g : G) (k : K) :
    hSK.equiv (g * k) = ((hSK.equiv g).fst, (hSK.equiv g).snd * k) := by
  have : (hSK.equiv (g * k)).fst = (hSK.equiv g).fst :=
    hSK.equiv_fst_eq_iff_leftCosetEquivalence.2
      (by simp [LeftCosetEquivalence, leftCoset_eq_iff])
  ext
  · 

Proof state:
case a.a
G : Type u_1
inst✝ : Group G
H K : Subgroup G
S T : Set G
hST : IsComplement S T
hHT : IsComplement (↑H) T
hSK : IsComplement S ↑K
g : G
k : ↥K
this : ((equiv hSK) (g * ↑k)).1 = ((equiv hSK) g).1
⊢ ↑((equiv hSK) (g * ↑k)).1 = ↑(((equiv hSK) g).1, ((equiv hSK) g).2 * k).1

Next tactic:
rw [this]
@[simp, nolint simpNF]
theorem equiv_mul_right (g : G) (k : K) :
    hSK.equiv (g * k) = ((hSK.equiv g).fst, (hSK.equiv g).snd * k) := by
  have : (hSK.equiv (g * k)).fst = (hSK.equiv g).fst :=
    hSK.equiv_fst_eq_iff_leftCosetEquivalence.2
      (by simp [LeftCosetEquivalence, leftCoset_eq_iff])
  ext
  · rw [this]
  · 

Proof state:
case a.a
G : Type u_1
inst✝ : Group G
H K : Subgroup G
S T : Set G
hST : IsComplement S T
hHT : IsComplement (↑H) T
hSK : IsComplement S ↑K
g : G
k : ↥K
this : ((equiv hSK) (g * ↑k)).1 = ((equiv hSK) g).1
⊢ ↑((equiv hSK) (g * ↑k)).2 = ↑(((equiv hSK) g).1, ((equiv hSK) g).2 * k).2

Next tactic:
rw [coe_mul, equiv_snd_eq_inv_mul, this, equiv_snd_eq_inv_mul, mul_assoc]
@[simp, nolint simpNF]
theorem equiv_mul_left (h : H) (g : G) :
    hHT.equiv (h * g) = (h * (hHT.equiv g).fst, (hHT.equiv g).snd) := by
  

Proof state:
G : Type u_1
inst✝ : Group G
H K : Subgroup G
S T : Set G
hST : IsComplement S T
hHT : IsComplement (↑H) T
hSK : IsComplement S ↑K
h : ↥H
g : G
⊢ (equiv hHT) (↑h * g) = (h * ((equiv hHT) g).1, ((equiv hHT) g).2)

Next tactic:
have : (hHT.equiv (h * g)).2 = (hHT.equiv g).2 := hHT.equiv_snd_eq_iff_rightCosetEquivalence.2 ?_
@[simp, nolint simpNF]
theorem equiv_mul_left (h : H) (g : G) :
    hHT.equiv (h * g) = (h * (hHT.equiv g).fst, (hHT.equiv g).snd) := by
  have : (hHT.equiv (h * g)).2 = (hHT.equiv g).2 := hHT.equiv_snd_eq_iff_rightCosetEquivalence.2 ?_
  

Proof state:
case refine_2
G : Type u_1
inst✝ : Group G
H K : Subgroup G
S T : Set G
hST : IsComplement S T
hHT : IsComplement (↑H) T
hSK : IsComplement S ↑K
h : ↥H
g : G
this : ((equiv hHT) (↑h * g)).2 = ((equiv hHT) g).2
⊢ (equiv hHT) (↑h * g) = (h * ((equiv hHT) g).1, ((equiv hHT) g).2)
case refine_1
G : Type u_1
inst✝ : Group G
H K : Subgroup G
S T : Set G
hST : IsComplement S T
hHT : IsComplement (↑H) T
hSK : IsComplement S ↑K
h : ↥H
g : G
⊢ RightCosetEquivalence (↑H) (↑h * g) g

Next tactic:
ext
@[simp, nolint simpNF]
theorem equiv_mul_left (h : H) (g : G) :
    hHT.equiv (h * g) = (h * (hHT.equiv g).fst, (hHT.equiv g).snd) := by
  have : (hHT.equiv (h * g)).2 = (hHT.equiv g).2 := hHT.equiv_snd_eq_iff_rightCosetEquivalence.2 ?_
  ext
  · 

Proof state:
case refine_2.a.a
G : Type u_1
inst✝ : Group G
H K : Subgroup G
S T : Set G
hST : IsComplement S T
hHT : IsComplement (↑H) T
hSK : IsComplement S ↑K
h : ↥H
g : G
this : ((equiv hHT) (↑h * g)).2 = ((equiv hHT) g).2
⊢ ↑((equiv hHT) (↑h * g)).1 = ↑(h * ((equiv hHT) g).1, ((equiv hHT) g).2).1

Next tactic:
rw [coe_mul, equiv_fst_eq_mul_inv, this, equiv_fst_eq_mul_inv, mul_assoc]
@[simp, nolint simpNF]
theorem equiv_mul_left (h : H) (g : G) :
    hHT.equiv (h * g) = (h * (hHT.equiv g).fst, (hHT.equiv g).snd) := by
  have : (hHT.equiv (h * g)).2 = (hHT.equiv g).2 := hHT.equiv_snd_eq_iff_rightCosetEquivalence.2 ?_
  ext
  · rw [coe_mul, equiv_fst_eq_mul_inv, this, equiv_fst_eq_mul_inv, mul_assoc]
  · 

Proof state:
case refine_2.a.a
G : Type u_1
inst✝ : Group G
H K : Subgroup G
S T : Set G
hST : IsComplement S T
hHT : IsComplement (↑H) T
hSK : IsComplement S ↑K
h : ↥H
g : G
this : ((equiv hHT) (↑h * g)).2 = ((equiv hHT) g).2
⊢ ↑((equiv hHT) (↑h * g)).2 = ↑(h * ((equiv hHT) g).1, ((equiv hHT) g).2).2

Next tactic:
rw [this]
@[simp, nolint simpNF]
theorem equiv_mul_left (h : H) (g : G) :
    hHT.equiv (h * g) = (h * (hHT.equiv g).fst, (hHT.equiv g).snd) := by
  have : (hHT.equiv (h * g)).2 = (hHT.equiv g).2 := hHT.equiv_snd_eq_iff_rightCosetEquivalence.2 ?_
  ext
  · rw [coe_mul, equiv_fst_eq_mul_inv, this, equiv_fst_eq_mul_inv, mul_assoc]
  · rw [this]
  · 

Proof state:
case refine_1
G : Type u_1
inst✝ : Group G
H K : Subgroup G
S T : Set G
hST : IsComplement S T
hHT : IsComplement (↑H) T
hSK : IsComplement S ↑K
h : ↥H
g : G
⊢ RightCosetEquivalence (↑H) (↑h * g) g

Next tactic:
simp [RightCosetEquivalence, ← smul_smul]
theorem equiv_one (hs1 : 1 ∈ S) (ht1 : 1 ∈ T) :
    hST.equiv 1 = (⟨1, hs1⟩, ⟨1, ht1⟩) := by
  

Proof state:
G : Type u_1
inst✝ : Group G
H K : Subgroup G
S T : Set G
hST : IsComplement S T
hHT : IsComplement (↑H) T
hSK : IsComplement S ↑K
hs1 : 1 ∈ S
ht1 : 1 ∈ T
⊢ (equiv hST) 1 = ({ val := 1, property := hs1 }, { val := 1, property := ht1 })

Next tactic:
rw [Equiv.apply_eq_iff_eq_symm_apply]
theorem equiv_one (hs1 : 1 ∈ S) (ht1 : 1 ∈ T) :
    hST.equiv 1 = (⟨1, hs1⟩, ⟨1, ht1⟩) := by
  rw [Equiv.apply_eq_iff_eq_symm_apply]; 

Proof state:
G : Type u_1
inst✝ : Group G
H K : Subgroup G
S T : Set G
hST : IsComplement S T
hHT : IsComplement (↑H) T
hSK : IsComplement S ↑K
hs1 : 1 ∈ S
ht1 : 1 ∈ T
⊢ 1 = (equiv hST).symm ({ val := 1, property := hs1 }, { val := 1, property := ht1 })

Next tactic:
simp [equiv]
theorem equiv_fst_eq_self_iff_mem {g : G} (h1 : 1 ∈ T) :
    ((hST.equiv g).fst : G) = g ↔ g ∈ S := by
  

Proof state:
G : Type u_1
inst✝ : Group G
H K : Subgroup G
S T : Set G
hST : IsComplement S T
hHT : IsComplement (↑H) T
hSK : IsComplement S ↑K
g : G
h1 : 1 ∈ T
⊢ ↑((equiv hST) g).1 = g ↔ g ∈ S

Next tactic:
constructor