l3lab/ntp-mathlib huggingface dataset:
/-- Multiplying `t^u` by a `NormalWord`, `w` and putting the result in normal form. -/
noncomputable def unitsSMul (u : ℤˣ) (w : NormalWord d) : NormalWord d :=
  letI := Classical.dec
  if h : Cancels u w
  then unitsSMulWithCancel φ u w h
  else let g' := unitsSMulGroup φ d u w.head
    cons g'.1 u ((g'.2 * w.head⁻¹ : G) • w)
      (by simp)
      (by
        simp only [group_smul_toList, Option.mem_def, Option.map_eq_some', Prod.exists,
          exists_and_right, exists_eq_right, group_smul_head, inv_mul_cancel_right,
          forall_exists_index, unitsSMulGroup]
        simp only [Cancels, Option.map_eq_some', Prod.exists, exists_and_right, exists_eq_right,
          not_and, not_exists] at h
        intro u' x hx hmem
        have : w.head ∈ toSubgroup A B u := by
          have := (d.compl u).rightCosetEquivalence_equiv_snd w.head
          rw [RightCosetEquivalence, rightCoset_eq_iff, mul_mem_cancel_left hmem] at this
          simp_all
        

Proof state:
G : Type u_1
inst✝³ : Group G
A B : Subgroup G
φ : ↥A ≃* ↥B
H : Type u_2
inst✝² : Group H
M : Type u_3
inst✝¹ : Monoid M
d : TransversalPair G A B
inst✝ : DecidableEq G
u : ℤˣ
w : NormalWord d
this✝ : (p : Prop) → Decidable p := Classical.dec
g' : ↥(toSubgroup A B (-u)) × ↑(TransversalPair.set d u) := unitsSMulGroup φ d u w.head
h : w.head ∈ toSubgroup A B u → ∀ (x : G), ¬List.head? w.toList = some (-u, x)
u' : ℤˣ
x : G
hx : List.head? w.toList = some (u', x)
hmem :
  ↑((IsComplement.equiv (_ : IsComplement (↑(toSubgroup A B u)) (TransversalPair.set d u))) w.head).2 ∈ toSubgroup A B u
this : w.head ∈ toSubgroup A B u
⊢ u = u'

Next tactic:
have := h this x
/-- Multiplying `t^u` by a `NormalWord`, `w` and putting the result in normal form. -/
noncomputable def unitsSMul (u : ℤˣ) (w : NormalWord d) : NormalWord d :=
  letI := Classical.dec
  if h : Cancels u w
  then unitsSMulWithCancel φ u w h
  else let g' := unitsSMulGroup φ d u w.head
    cons g'.1 u ((g'.2 * w.head⁻¹ : G) • w)
      (by simp)
      (by
        simp only [group_smul_toList, Option.mem_def, Option.map_eq_some', Prod.exists,
          exists_and_right, exists_eq_right, group_smul_head, inv_mul_cancel_right,
          forall_exists_index, unitsSMulGroup]
        simp only [Cancels, Option.map_eq_some', Prod.exists, exists_and_right, exists_eq_right,
          not_and, not_exists] at h
        intro u' x hx hmem
        have : w.head ∈ toSubgroup A B u := by
          have := (d.compl u).rightCosetEquivalence_equiv_snd w.head
          rw [RightCosetEquivalence, rightCoset_eq_iff, mul_mem_cancel_left hmem] at this
          simp_all
        have := h this x
        

Proof state:
G : Type u_1
inst✝³ : Group G
A B : Subgroup G
φ : ↥A ≃* ↥B
H : Type u_2
inst✝² : Group H
M : Type u_3
inst✝¹ : Monoid M
d : TransversalPair G A B
inst✝ : DecidableEq G
u : ℤˣ
w : NormalWord d
this✝¹ : (p : Prop) → Decidable p := Classical.dec
g' : ↥(toSubgroup A B (-u)) × ↑(TransversalPair.set d u) := unitsSMulGroup φ d u w.head
h : w.head ∈ toSubgroup A B u → ∀ (x : G), ¬List.head? w.toList = some (-u, x)
u' : ℤˣ
x : G
hx : List.head? w.toList = some (u', x)
hmem :
  ↑((IsComplement.equiv (_ : IsComplement (↑(toSubgroup A B u)) (TransversalPair.set d u))) w.head).2 ∈ toSubgroup A B u
this✝ : w.head ∈ toSubgroup A B u
this : ¬List.head? w.toList = some (-u, x)
⊢ u = u'

Next tactic:
simp_all [Int.units_ne_iff_eq_neg]
/-- A condition for not cancelling whose hypothese are the same as those of the `cons` function. -/
theorem not_cancels_of_cons_hyp (u : ℤˣ) (w : NormalWord d)
    (h2 : ∀ u' ∈ Option.map Prod.fst w.toList.head?,
      w.head ∈ toSubgroup A B u → u = u') :
    ¬ Cancels u w := by
  

Proof state:
G : Type u_1
inst✝³ : Group G
A B : Subgroup G
φ : ↥A ≃* ↥B
H : Type u_2
inst✝² : Group H
M : Type u_3
inst✝¹ : Monoid M
d : TransversalPair G A B
inst✝ : DecidableEq G
u : ℤˣ
w : NormalWord d
h2 : ∀ u' ∈ Option.map Prod.fst (List.head? w.toList), w.head ∈ toSubgroup A B u → u = u'
⊢ ¬Cancels u w

Next tactic:
simp only [Cancels, Option.map_eq_some', Prod.exists,
    exists_and_right, exists_eq_right, not_and, not_exists]
/-- A condition for not cancelling whose hypothese are the same as those of the `cons` function. -/
theorem not_cancels_of_cons_hyp (u : ℤˣ) (w : NormalWord d)
    (h2 : ∀ u' ∈ Option.map Prod.fst w.toList.head?,
      w.head ∈ toSubgroup A B u → u = u') :
    ¬ Cancels u w := by
  simp only [Cancels, Option.map_eq_some', Prod.exists,
    exists_and_right, exists_eq_right, not_and, not_exists]
  

Proof state:
G : Type u_1
inst✝³ : Group G
A B : Subgroup G
φ : ↥A ≃* ↥B
H : Type u_2
inst✝² : Group H
M : Type u_3
inst✝¹ : Monoid M
d : TransversalPair G A B
inst✝ : DecidableEq G
u : ℤˣ
w : NormalWord d
h2 : ∀ u' ∈ Option.map Prod.fst (List.head? w.toList), w.head ∈ toSubgroup A B u → u = u'
⊢ w.head ∈ toSubgroup A B u → ∀ (x : G), ¬List.head? w.toList = some (-u, x)

Next tactic:
intro hw x hx
/-- A condition for not cancelling whose hypothese are the same as those of the `cons` function. -/
theorem not_cancels_of_cons_hyp (u : ℤˣ) (w : NormalWord d)
    (h2 : ∀ u' ∈ Option.map Prod.fst w.toList.head?,
      w.head ∈ toSubgroup A B u → u = u') :
    ¬ Cancels u w := by
  simp only [Cancels, Option.map_eq_some', Prod.exists,
    exists_and_right, exists_eq_right, not_and, not_exists]
  intro hw x hx
  

Proof state:
G : Type u_1
inst✝³ : Group G
A B : Subgroup G
φ : ↥A ≃* ↥B
H : Type u_2
inst✝² : Group H
M : Type u_3
inst✝¹ : Monoid M
d : TransversalPair G A B
inst✝ : DecidableEq G
u : ℤˣ
w : NormalWord d
h2 : ∀ u' ∈ Option.map Prod.fst (List.head? w.toList), w.head ∈ toSubgroup A B u → u = u'
hw : w.head ∈ toSubgroup A B u
x : G
hx : List.head? w.toList = some (-u, x)
⊢ False

Next tactic:
rw [hx] at h2
/-- A condition for not cancelling whose hypothese are the same as those of the `cons` function. -/
theorem not_cancels_of_cons_hyp (u : ℤˣ) (w : NormalWord d)
    (h2 : ∀ u' ∈ Option.map Prod.fst w.toList.head?,
      w.head ∈ toSubgroup A B u → u = u') :
    ¬ Cancels u w := by
  simp only [Cancels, Option.map_eq_some', Prod.exists,
    exists_and_right, exists_eq_right, not_and, not_exists]
  intro hw x hx
  rw [hx] at h2
  

Proof state:
G : Type u_1
inst✝³ : Group G
A B : Subgroup G
φ : ↥A ≃* ↥B
H : Type u_2
inst✝² : Group H
M : Type u_3
inst✝¹ : Monoid M
d : TransversalPair G A B
inst✝ : DecidableEq G
u : ℤˣ
w : NormalWord d
hw : w.head ∈ toSubgroup A B u
x : G
h2 : ∀ u' ∈ Option.map Prod.fst (some (-u, x)), w.head ∈ toSubgroup A B u → u = u'
hx : List.head? w.toList = some (-u, x)
⊢ False

Next tactic:
simpa using h2 (-u) rfl hw
theorem unitsSMul_cancels_iff (u : ℤˣ) (w : NormalWord d) :
    Cancels (-u) (unitsSMul φ u w) ↔ ¬ Cancels u w := by
  

Proof state:
G : Type u_1
inst✝³ : Group G
A B : Subgroup G
φ : ↥A ≃* ↥B
H : Type u_2
inst✝² : Group H
M : Type u_3
inst✝¹ : Monoid M
d : TransversalPair G A B
inst✝ : DecidableEq G
u : ℤˣ
w : NormalWord d
⊢ Cancels (-u) (unitsSMul φ u w) ↔ ¬Cancels u w

Next tactic:
by_cases h : Cancels u w
theorem unitsSMul_cancels_iff (u : ℤˣ) (w : NormalWord d) :
    Cancels (-u) (unitsSMul φ u w) ↔ ¬ Cancels u w := by
  by_cases h : Cancels u w
  · 

Proof state:
case pos
G : Type u_1
inst✝³ : Group G
A B : Subgroup G
φ : ↥A ≃* ↥B
H : Type u_2
inst✝² : Group H
M : Type u_3
inst✝¹ : Monoid M
d : TransversalPair G A B
inst✝ : DecidableEq G
u : ℤˣ
w : NormalWord d
h : Cancels u w
⊢ Cancels (-u) (unitsSMul φ u w) ↔ ¬Cancels u w

Next tactic:
simp only [unitsSMul, h, dite_true, not_true_eq_false, iff_false]
theorem unitsSMul_cancels_iff (u : ℤˣ) (w : NormalWord d) :
    Cancels (-u) (unitsSMul φ u w) ↔ ¬ Cancels u w := by
  by_cases h : Cancels u w
  · simp only [unitsSMul, h, dite_true, not_true_eq_false, iff_false]
    

Proof state:
case pos
G : Type u_1
inst✝³ : Group G
A B : Subgroup G
φ : ↥A ≃* ↥B
H : Type u_2
inst✝² : Group H
M : Type u_3
inst✝¹ : Monoid M
d : TransversalPair G A B
inst✝ : DecidableEq G
u : ℤˣ
w : NormalWord d
h : Cancels u w
⊢ ¬Cancels (-u) (unitsSMulWithCancel φ u w (_ : Cancels u w))

Next tactic:
induction w using consRecOn with
    | ofGroup => simp [Cancels, unitsSMulWithCancel]
    | cons g u' w h1 h2 _ =>
      intro hc
      apply not_cancels_of_cons_hyp _ _ h2
      simp only [Cancels, cons_head, cons_toList, List.head?_cons,
        Option.map_some', Option.some.injEq] at h
      cases h.2
      simpa [Cancels, unitsSMulWithCancel,
        Subgroup.mul_mem_cancel_left] using hc
theorem unitsSMul_cancels_iff (u : ℤˣ) (w : NormalWord d) :
    Cancels (-u) (unitsSMul φ u w) ↔ ¬ Cancels u w := by
  by_cases h : Cancels u w
  · simp only [unitsSMul, h, dite_true, not_true_eq_false, iff_false]
    induction w using consRecOn with
    

Proof state:
case pos.ofGroup
G : Type u_1
inst✝³ : Group G
A B : Subgroup G
φ : ↥A ≃* ↥B
H : Type u_2
inst✝² : Group H
M : Type u_3
inst✝¹ : Monoid M
d : TransversalPair G A B
inst✝ : DecidableEq G
u : ℤˣ
g✝ : G
h : Cancels u (ofGroup g✝)
⊢ ¬Cancels (-u) (unitsSMulWithCancel φ u (ofGroup g✝) (_ : Cancels u (ofGroup g✝)))

Next tactic:
| ofGroup => simp [Cancels, unitsSMulWithCancel]
theorem unitsSMul_cancels_iff (u : ℤˣ) (w : NormalWord d) :
    Cancels (-u) (unitsSMul φ u w) ↔ ¬ Cancels u w := by
  by_cases h : Cancels u w
  · simp only [unitsSMul, h, dite_true, not_true_eq_false, iff_false]
    induction w using consRecOn with
    | ofGroup => 

Proof state:
case pos.ofGroup
G : Type u_1
inst✝³ : Group G
A B : Subgroup G
φ : ↥A ≃* ↥B
H : Type u_2
inst✝² : Group H
M : Type u_3
inst✝¹ : Monoid M
d : TransversalPair G A B
inst✝ : DecidableEq G
u : ℤˣ
g✝ : G
h : Cancels u (ofGroup g✝)
⊢ ¬Cancels (-u) (unitsSMulWithCancel φ u (ofGroup g✝) (_ : Cancels u (ofGroup g✝)))

Next tactic:
simp [Cancels, unitsSMulWithCancel]
theorem unitsSMul_cancels_iff (u : ℤˣ) (w : NormalWord d) :
    Cancels (-u) (unitsSMul φ u w) ↔ ¬ Cancels u w := by
  by_cases h : Cancels u w
  · simp only [unitsSMul, h, dite_true, not_true_eq_false, iff_false]
    induction w using consRecOn with
    | ofGroup => simp [Cancels, unitsSMulWithCancel]
    

Proof state:
case pos.cons
G : Type u_1
inst✝³ : Group G
A B : Subgroup G
φ : ↥A ≃* ↥B
H : Type u_2
inst✝² : Group H
M : Type u_3
inst✝¹ : Monoid M
d : TransversalPair G A B
inst✝ : DecidableEq G
u : ℤˣ
g : G
u' : ℤˣ
w : NormalWord d
h1 : w.head ∈ TransversalPair.set d u'
h2 : ∀ u'_1 ∈ Option.map Prod.fst (List.head? w.toList), w.head ∈ toSubgroup A B u' → u' = u'_1
a✝ : ∀ (h : Cancels u w), ¬Cancels (-u) (unitsSMulWithCancel φ u w (_ : Cancels u w))
h : Cancels u (cons g u' w h1 h2)
⊢ ¬Cancels (-u) (unitsSMulWithCancel φ u (cons g u' w h1 h2) (_ : Cancels u (cons g u' w h1 h2)))

Next tactic:
| cons g u' w h1 h2 _ =>
      intro hc
      apply not_cancels_of_cons_hyp _ _ h2
      simp only [Cancels, cons_head, cons_toList, List.head?_cons,
        Option.map_some', Option.some.injEq] at h
      cases h.2
      simpa [Cancels, unitsSMulWithCancel,
        Subgroup.mul_mem_cancel_left] using hc
theorem unitsSMul_cancels_iff (u : ℤˣ) (w : NormalWord d) :
    Cancels (-u) (unitsSMul φ u w) ↔ ¬ Cancels u w := by
  by_cases h : Cancels u w
  · simp only [unitsSMul, h, dite_true, not_true_eq_false, iff_false]
    induction w using consRecOn with
    | ofGroup => simp [Cancels, unitsSMulWithCancel]
    | cons g u' w h1 h2 _ =>
      

Proof state:
case pos.cons
G : Type u_1
inst✝³ : Group G
A B : Subgroup G
φ : ↥A ≃* ↥B
H : Type u_2
inst✝² : Group H
M : Type u_3
inst✝¹ : Monoid M
d : TransversalPair G A B
inst✝ : DecidableEq G
u : ℤˣ
g : G
u' : ℤˣ
w : NormalWord d
h1 : w.head ∈ TransversalPair.set d u'
h2 : ∀ u'_1 ∈ Option.map Prod.fst (List.head? w.toList), w.head ∈ toSubgroup A B u' → u' = u'_1
a✝ : ∀ (h : Cancels u w), ¬Cancels (-u) (unitsSMulWithCancel φ u w (_ : Cancels u w))
h : Cancels u (cons g u' w h1 h2)
⊢ ¬Cancels (-u) (unitsSMulWithCancel φ u (cons g u' w h1 h2) (_ : Cancels u (cons g u' w h1 h2)))

Next tactic:
intro hc
theorem unitsSMul_cancels_iff (u : ℤˣ) (w : NormalWord d) :
    Cancels (-u) (unitsSMul φ u w) ↔ ¬ Cancels u w := by
  by_cases h : Cancels u w
  · simp only [unitsSMul, h, dite_true, not_true_eq_false, iff_false]
    induction w using consRecOn with
    | ofGroup => simp [Cancels, unitsSMulWithCancel]
    | cons g u' w h1 h2 _ =>
      intro hc
      

Proof state:
case pos.cons
G : Type u_1
inst✝³ : Group G
A B : Subgroup G
φ : ↥A ≃* ↥B
H : Type u_2
inst✝² : Group H
M : Type u_3
inst✝¹ : Monoid M
d : TransversalPair G A B
inst✝ : DecidableEq G
u : ℤˣ
g : G
u' : ℤˣ
w : NormalWord d
h1 : w.head ∈ TransversalPair.set d u'
h2 : ∀ u'_1 ∈ Option.map Prod.fst (List.head? w.toList), w.head ∈ toSubgroup A B u' → u' = u'_1
a✝ : ∀ (h : Cancels u w), ¬Cancels (-u) (unitsSMulWithCancel φ u w (_ : Cancels u w))
h : Cancels u (cons g u' w h1 h2)
hc : Cancels (-u) (unitsSMulWithCancel φ u (cons g u' w h1 h2) (_ : Cancels u (cons g u' w h1 h2)))
⊢ False

Next tactic:
apply not_cancels_of_cons_hyp _ _ h2
theorem unitsSMul_cancels_iff (u : ℤˣ) (w : NormalWord d) :
    Cancels (-u) (unitsSMul φ u w) ↔ ¬ Cancels u w := by
  by_cases h : Cancels u w
  · simp only [unitsSMul, h, dite_true, not_true_eq_false, iff_false]
    induction w using consRecOn with
    | ofGroup => simp [Cancels, unitsSMulWithCancel]
    | cons g u' w h1 h2 _ =>
      intro hc
      apply not_cancels_of_cons_hyp _ _ h2
      

Proof state:
case pos.cons
G : Type u_1
inst✝³ : Group G
A B : Subgroup G
φ : ↥A ≃* ↥B
H : Type u_2
inst✝² : Group H
M : Type u_3
inst✝¹ : Monoid M
d : TransversalPair G A B
inst✝ : DecidableEq G
u : ℤˣ
g : G
u' : ℤˣ
w : NormalWord d
h1 : w.head ∈ TransversalPair.set d u'
h2 : ∀ u'_1 ∈ Option.map Prod.fst (List.head? w.toList), w.head ∈ toSubgroup A B u' → u' = u'_1
a✝ : ∀ (h : Cancels u w), ¬Cancels (-u) (unitsSMulWithCancel φ u w (_ : Cancels u w))
h : Cancels u (cons g u' w h1 h2)
hc : Cancels (-u) (unitsSMulWithCancel φ u (cons g u' w h1 h2) (_ : Cancels u (cons g u' w h1 h2)))
⊢ Cancels u' w

Next tactic:
simp only [Cancels, cons_head, cons_toList, List.head?_cons,
        Option.map_some', Option.some.injEq] at h
theorem unitsSMul_cancels_iff (u : ℤˣ) (w : NormalWord d) :
    Cancels (-u) (unitsSMul φ u w) ↔ ¬ Cancels u w := by
  by_cases h : Cancels u w
  · simp only [unitsSMul, h, dite_true, not_true_eq_false, iff_false]
    induction w using consRecOn with
    | ofGroup => simp [Cancels, unitsSMulWithCancel]
    | cons g u' w h1 h2 _ =>
      intro hc
      apply not_cancels_of_cons_hyp _ _ h2
      simp only [Cancels, cons_head, cons_toList, List.head?_cons,
        Option.map_some', Option.some.injEq] at h
      

Proof state:
case pos.cons
G : Type u_1
inst✝³ : Group G
A B : Subgroup G
φ : ↥A ≃* ↥B
H : Type u_2
inst✝² : Group H
M : Type u_3
inst✝¹ : Monoid M
d : TransversalPair G A B
inst✝ : DecidableEq G
u : ℤˣ
g : G
u' : ℤˣ
w : NormalWord d
h1 : w.head ∈ TransversalPair.set d u'
h2 : ∀ u'_1 ∈ Option.map Prod.fst (List.head? w.toList), w.head ∈ toSubgroup A B u' → u' = u'_1
a✝ : ∀ (h : Cancels u w), ¬Cancels (-u) (unitsSMulWithCancel φ u w (_ : Cancels u w))
h✝ : Cancels u (cons g u' w h1 h2)
hc : Cancels (-u) (unitsSMulWithCancel φ u (cons g u' w h1 h2) (_ : Cancels u (cons g u' w h1 h2)))
h : g ∈ toSubgroup A B u ∧ u' = -u
⊢ Cancels u' w

Next tactic:
cases h.2
theorem unitsSMul_cancels_iff (u : ℤˣ) (w : NormalWord d) :
    Cancels (-u) (unitsSMul φ u w) ↔ ¬ Cancels u w := by
  by_cases h : Cancels u w
  · simp only [unitsSMul, h, dite_true, not_true_eq_false, iff_false]
    induction w using consRecOn with
    | ofGroup => simp [Cancels, unitsSMulWithCancel]
    | cons g u' w h1 h2 _ =>
      intro hc
      apply not_cancels_of_cons_hyp _ _ h2
      simp only [Cancels, cons_head, cons_toList, List.head?_cons,
        Option.map_some', Option.some.injEq] at h
      cases h.2
      

Proof state:
case pos.cons.refl
G : Type u_1
inst✝³ : Group G
A B : Subgroup G
φ : ↥A ≃* ↥B
H : Type u_2
inst✝² : Group H
M : Type u_3
inst✝¹ : Monoid M
d : TransversalPair G A B
inst✝ : DecidableEq G
u : ℤˣ
g : G
w : NormalWord d
a✝ : ∀ (h : Cancels u w), ¬Cancels (-u) (unitsSMulWithCancel φ u w (_ : Cancels u w))
h1 : w.head ∈ TransversalPair.set d (-u)
h2 : ∀ u' ∈ Option.map Prod.fst (List.head? w.toList), w.head ∈ toSubgroup A B (-u) → -u = u'
h✝ : Cancels u (cons g (-u) w h1 h2)
hc : Cancels (-u) (unitsSMulWithCancel φ u (cons g (-u) w h1 h2) (_ : Cancels u (cons g (-u) w h1 h2)))
h : g ∈ toSubgroup A B u ∧ -u = -u
⊢ Cancels (-u) w

Next tactic:
simpa [Cancels, unitsSMulWithCancel,
        Subgroup.mul_mem_cancel_left] using hc
theorem unitsSMul_cancels_iff (u : ℤˣ) (w : NormalWord d) :
    Cancels (-u) (unitsSMul φ u w) ↔ ¬ Cancels u w := by
  by_cases h : Cancels u w
  · simp only [unitsSMul, h, dite_true, not_true_eq_false, iff_false]
    induction w using consRecOn with
    | ofGroup => simp [Cancels, unitsSMulWithCancel]
    | cons g u' w h1 h2 _ =>
      intro hc
      apply not_cancels_of_cons_hyp _ _ h2
      simp only [Cancels, cons_head, cons_toList, List.head?_cons,
        Option.map_some', Option.some.injEq] at h
      cases h.2
      simpa [Cancels, unitsSMulWithCancel,
        Subgroup.mul_mem_cancel_left] using hc
  · 

Proof state:
case neg
G : Type u_1
inst✝³ : Group G
A B : Subgroup G
φ : ↥A ≃* ↥B
H : Type u_2
inst✝² : Group H
M : Type u_3
inst✝¹ : Monoid M
d : TransversalPair G A B
inst✝ : DecidableEq G
u : ℤˣ
w : NormalWord d
h : ¬Cancels u w
⊢ Cancels (-u) (unitsSMul φ u w) ↔ ¬Cancels u w

Next tactic:
simp only [unitsSMul, dif_neg h]
theorem unitsSMul_cancels_iff (u : ℤˣ) (w : NormalWord d) :
    Cancels (-u) (unitsSMul φ u w) ↔ ¬ Cancels u w := by
  by_cases h : Cancels u w
  · simp only [unitsSMul, h, dite_true, not_true_eq_false, iff_false]
    induction w using consRecOn with
    | ofGroup => simp [Cancels, unitsSMulWithCancel]
    | cons g u' w h1 h2 _ =>
      intro hc
      apply not_cancels_of_cons_hyp _ _ h2
      simp only [Cancels, cons_head, cons_toList, List.head?_cons,
        Option.map_some', Option.some.injEq] at h
      cases h.2
      simpa [Cancels, unitsSMulWithCancel,
        Subgroup.mul_mem_cancel_left] using hc
  · simp only [unitsSMul, dif_neg h]
    

Proof state:
case neg
G : Type u_1
inst✝³ : Group G
A B : Subgroup G
φ : ↥A ≃* ↥B
H : Type u_2
inst✝² : Group H
M : Type u_3
inst✝¹ : Monoid M
d : TransversalPair G A B
inst✝ : DecidableEq G
u : ℤˣ
w : NormalWord d
h : ¬Cancels u w
⊢ Cancels (-u)
      (cons (↑(unitsSMulGroup φ d u w.head).1) u ((↑(unitsSMulGroup φ d u w.head).2 * w.head⁻¹) • w)
        (_ : ↑(unitsSMulGroup φ d u w.head).2 * w.head⁻¹ * w.head ∈ TransversalPair.set d u)
        (_ :
          ∀ u' ∈ Option.map Prod.fst (List.head? ((↑(unitsSMulGroup φ d u w.head).2 * w.head⁻¹) • w).toList),
            ((↑(unitsSMulGroup φ d u w.head).2 * w.head⁻¹) • w).head ∈ toSubgroup A B u → u = u')) ↔
    ¬Cancels u w

Next tactic:
simpa [Cancels] using h
theorem unitsSMul_neg (u : ℤˣ) (w : NormalWord d) :
    unitsSMul φ (-u) (unitsSMul φ u w) = w := by
  

Proof state:
G : Type u_1
inst✝³ : Group G
A B : Subgroup G
φ : ↥A ≃* ↥B
H : Type u_2
inst✝² : Group H
M : Type u_3
inst✝¹ : Monoid M
d : TransversalPair G A B
inst✝ : DecidableEq G
u : ℤˣ
w : NormalWord d
⊢ unitsSMul φ (-u) (unitsSMul φ u w) = w

Next tactic:
rw [unitsSMul]
theorem unitsSMul_neg (u : ℤˣ) (w : NormalWord d) :
    unitsSMul φ (-u) (unitsSMul φ u w) = w := by
  rw [unitsSMul]
  

Proof state:
G : Type u_1
inst✝³ : Group G
A B : Subgroup G
φ : ↥A ≃* ↥B
H : Type u_2
inst✝² : Group H
M : Type u_3
inst✝¹ : Monoid M
d : TransversalPair G A B
inst✝ : DecidableEq G
u : ℤˣ
w : NormalWord d
⊢ (if h : Cancels (-u) (unitsSMul φ u w) then unitsSMulWithCancel φ (-u) (unitsSMul φ u w) h
    else
      let g' := unitsSMulGroup φ d (-u) (unitsSMul φ u w).toReducedWord.head;
      cons (↑g'.1) (-u) ((↑g'.2 * (unitsSMul φ u w).toReducedWord.head⁻¹) • unitsSMul φ u w)
        (_ :
          ↑(unitsSMulGroup φ d (-u) (unitsSMul φ u w).toReducedWord.head).2 * (unitsSMul φ u w).toReducedWord.head⁻¹ *
              (unitsSMul φ u w).toReducedWord.head ∈
            TransversalPair.set d (-u))
        (_ :
          ∀
            u' ∈
              Option.map Prod.fst
                (List.head?
                  ((↑(unitsSMulGroup φ d (-u) (unitsSMul φ u w).toReducedWord.head).2 *
                        (unitsSMul φ u w).toReducedWord.head⁻¹) •
                      unitsSMul φ u w).toList),
            ((↑(unitsSMulGroup φ d (-u) (unitsSMul φ u w).toReducedWord.head).2 *
                      (unitsSMul φ u w).toReducedWord.head⁻¹) •
                    unitsSMul φ u w).head ∈
                toSubgroup A B (-u) →
              -u = u')) =
    w

Next tactic:
split_ifs with hcan
theorem unitsSMul_neg (u : ℤˣ) (w : NormalWord d) :
    unitsSMul φ (-u) (unitsSMul φ u w) = w := by
  rw [unitsSMul]
  split_ifs with hcan
  · 

Proof state:
case pos
G : Type u_1
inst✝³ : Group G
A B : Subgroup G
φ : ↥A ≃* ↥B
H : Type u_2
inst✝² : Group H
M : Type u_3
inst✝¹ : Monoid M
d : TransversalPair G A B
inst✝ : DecidableEq G
u : ℤˣ
w : NormalWord d
hcan : Cancels (-u) (unitsSMul φ u w)
⊢ unitsSMulWithCancel φ (-u) (unitsSMul φ u w) hcan = w

Next tactic:
have hncan : ¬ Cancels u w := (unitsSMul_cancels_iff _ _ _).1 hcan
theorem unitsSMul_neg (u : ℤˣ) (w : NormalWord d) :
    unitsSMul φ (-u) (unitsSMul φ u w) = w := by
  rw [unitsSMul]
  split_ifs with hcan
  · have hncan : ¬ Cancels u w := (unitsSMul_cancels_iff _ _ _).1 hcan
    

Proof state:
case pos
G : Type u_1
inst✝³ : Group G
A B : Subgroup G
φ : ↥A ≃* ↥B
H : Type u_2
inst✝² : Group H
M : Type u_3
inst✝¹ : Monoid M
d : TransversalPair G A B
inst✝ : DecidableEq G
u : ℤˣ
w : NormalWord d
hcan : Cancels (-u) (unitsSMul φ u w)
hncan : ¬Cancels u w
⊢ unitsSMulWithCancel φ (-u) (unitsSMul φ u w) hcan = w

Next tactic:
unfold unitsSMul
theorem unitsSMul_neg (u : ℤˣ) (w : NormalWord d) :
    unitsSMul φ (-u) (unitsSMul φ u w) = w := by
  rw [unitsSMul]
  split_ifs with hcan
  · have hncan : ¬ Cancels u w := (unitsSMul_cancels_iff _ _ _).1 hcan
    unfold unitsSMul
    

Proof state:
case pos
G : Type u_1
inst✝³ : Group G
A B : Subgroup G
φ : ↥A ≃* ↥B
H : Type u_2
inst✝² : Group H
M : Type u_3
inst✝¹ : Monoid M
d : TransversalPair G A B
inst✝ : DecidableEq G
u : ℤˣ
w : NormalWord d
hcan : Cancels (-u) (unitsSMul φ u w)
hncan : ¬Cancels u w
⊢ unitsSMulWithCancel φ (-u)
      (if h : Cancels u w then unitsSMulWithCancel φ u w h
      else
        let g' := unitsSMulGroup φ d u w.head;
        cons (↑g'.1) u ((↑g'.2 * w.head⁻¹) • w)
          (_ : ↑(unitsSMulGroup φ d u w.head).2 * w.head⁻¹ * w.head ∈ TransversalPair.set d u)
          (_ :
            ∀ u' ∈ Option.map Prod.fst (List.head? ((↑(unitsSMulGroup φ d u w.head).2 * w.head⁻¹) • w).toList),
              ((↑(unitsSMulGroup φ d u w.head).2 * w.head⁻¹) • w).head ∈ toSubgroup A B u → u = u'))
      hcan =
    w

Next tactic:
simp only [dif_neg hncan]
theorem unitsSMul_neg (u : ℤˣ) (w : NormalWord d) :
    unitsSMul φ (-u) (unitsSMul φ u w) = w := by
  rw [unitsSMul]
  split_ifs with hcan
  · have hncan : ¬ Cancels u w := (unitsSMul_cancels_iff _ _ _).1 hcan
    unfold unitsSMul
    simp only [dif_neg hncan]
    

Proof state:
case pos
G : Type u_1
inst✝³ : Group G
A B : Subgroup G
φ : ↥A ≃* ↥B
H : Type u_2
inst✝² : Group H
M : Type u_3
inst✝¹ : Monoid M
d : TransversalPair G A B
inst✝ : DecidableEq G
u : ℤˣ
w : NormalWord d
hcan : Cancels (-u) (unitsSMul φ u w)
hncan : ¬Cancels u w
⊢ unitsSMulWithCancel φ (-u)
      (cons (↑(unitsSMulGroup φ d u w.head).1) u ((↑(unitsSMulGroup φ d u w.head).2 * w.head⁻¹) • w)
        (_ : ↑(unitsSMulGroup φ d u w.head).2 * w.head⁻¹ * w.head ∈ TransversalPair.set d u)
        (_ :
          ∀ u' ∈ Option.map Prod.fst (List.head? ((↑(unitsSMulGroup φ d u w.head).2 * w.head⁻¹) • w).toList),
            ((↑(unitsSMulGroup φ d u w.head).2 * w.head⁻¹) • w).head ∈ toSubgroup A B u → u = u'))
      (_ :
        Cancels (-u)
          (cons (↑(unitsSMulGroup φ d u w.head).1) u ((↑(unitsSMulGroup φ d u w.head).2 * w.head⁻¹) • w)
            (_ : ↑(unitsSMulGroup φ d u w.head).2 * w.head⁻¹ * w.head ∈ TransversalPair.set d u)
            (_ :
              ∀ u' ∈ Option.map Prod.fst (List.head? ((↑(unitsSMulGroup φ d u w.head).2 * w.head⁻¹) • w).toList),
                ((↑(unitsSMulGroup φ d u w.head).2 * w.head⁻¹) • w).head ∈ toSubgroup A B u → u = u'))) =
    w

Next tactic:
simp [unitsSMulWithCancel, unitsSMulGroup, (d.compl u).equiv_snd_eq_inv_mul]