/-- A recursor to induct on a `NormalWord`, by proving the propert is preserved under `cons` -/
@[elab_as_elim]
def consRecOn {motive : NormalWord d → Sort*} (w : NormalWord d)
    (ofGroup : ∀g, motive (ofGroup g))
    (cons : ∀ (g : G) (u : ℤˣ) (w : NormalWord d) (h1 : w.head ∈ d.set u)
      (h2 : ∀ u' ∈ Option.map Prod.fst w.toList.head?,
        w.head ∈ toSubgroup A B u → u = u'),
      motive w → motive (cons g u w h1 h2)) : motive w := by
  rcases w with ⟨⟨g, l, chain⟩, mem_set⟩
  induction l generalizing g with
  | nil => exact ofGroup _
  | cons a l ih =>
    exact cons g a.1
      { head := a.2
        toList := l
        mem_set := fun _ _ h => mem_set _ _ (List.mem_cons_of_mem _ h),
        chain := (List.chain'_cons'.1 chain).2 }
      (mem_set a.1 a.2 (List.mem_cons_self _ _))
      (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
motive : NormalWord d → Sort u_4
ofGroup : (g : G) → motive (HNNExtension.NormalWord.ofGroup g)
cons :
  (g : G) →
    (u : ℤˣ) →
      (w : NormalWord d) →
        (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') →
            motive w → motive (HNNExtension.NormalWord.cons g u w h1 h2)
a : ℤˣ × G
l : List (ℤˣ × G)
ih :
  (g : G) →
    (chain : List.Chain' (fun a b => a.2 ∈ toSubgroup A B a.1 → a.1 = b.1) l) →
      (mem_set :
          ∀ (u : ℤˣ) (g_1 : G),
            (u, g_1) ∈ { head := g, toList := l, chain := chain }.toList → g_1 ∈ TransversalPair.set d u) →
        motive { toReducedWord := { head := g, toList := l, chain := chain }, mem_set := mem_set }
g : G
chain : List.Chain' (fun a b => a.2 ∈ toSubgroup A B a.1 → a.1 = b.1) (a :: l)
mem_set :
  ∀ (u : ℤˣ) (g_1 : G),
    (u, g_1) ∈ { head := g, toList := a :: l, chain := chain }.toList → g_1 ∈ TransversalPair.set d u
⊢ ∀
    u' ∈
      Option.map Prod.fst
        (List.head?
          {
                toReducedWord :=
                  { head := a.2, toList := l,
                    chain := (_ : List.Chain' (fun a b => a.2 ∈ toSubgroup A B a.1 → a.1 = b.1) l) },
                mem_set :=
                  (_ :
                    ∀ (x : ℤˣ) (x_1 : G),
                      (x, x_1) ∈
                          { head := a.2, toList := l,
                              chain := (_ : List.Chain' (fun a b => a.2 ∈ toSubgroup A B a.1 → a.1 = b.1) l) }.toList →
                        x_1 ∈ TransversalPair.set d x) }.toReducedWord.toList),
    {
              toReducedWord :=
                { head := a.2, toList := l,
                  chain := (_ : List.Chain' (fun a b => a.2 ∈ toSubgroup A B a.1 → a.1 = b.1) l) },
              mem_set :=
                (_ :
                  ∀ (x : ℤˣ) (x_1 : G),
                    (x, x_1) ∈
                        { head := a.2, toList := l,
                            chain := (_ : List.Chain' (fun a b => a.2 ∈ toSubgroup A B a.1 → a.1 = b.1) l) }.toList →
                      x_1 ∈ TransversalPair.set d x) }.toReducedWord.head ∈
        toSubgroup A B a.1 →
      a.1 = u'

Next tactic:
simpa using (List.chain'_cons'.1 chain).1