l3lab/ntp-mathlib huggingface dataset:
/-- Given `i : ι`, any reduced word can be decomposed into a pair `p` such that `w = rcons p`. -/
private def equivPairAux (i) (w : Word M) : { p : Pair M i // rcons p = w } :=
  consRecOn w ⟨⟨1, .empty, by simp [fstIdx, empty]⟩, by simp [rcons]⟩ <|
    fun j m w h1 h2 _ =>
      if ij : i = j then
        { val :=
          { head := ij ▸ m
            tail := w
            fstIdx_ne := ij ▸ h1 }
          property := by 

Proof state:
ι : Type u_1
M : ι → Type u_2
inst✝³ : (i : ι) → Monoid (M i)
N : Type u_3
inst✝² : Monoid N
inst✝¹ : (i : ι) → DecidableEq (M i)
inst✝ : DecidableEq ι
i : ι
w✝ : Word M
j : ι
m : M j
w : Word M
h1 : fstIdx w ≠ some j
h2 : m ≠ 1
x✝ : { p // rcons p = w }
ij : i = j
⊢ rcons { head := (_ : j = i) ▸ m, tail := w, fstIdx_ne := (_ : fstIdx w ≠ some i) } = cons m w h1 h2

Next tactic:
subst ij
/-- Given `i : ι`, any reduced word can be decomposed into a pair `p` such that `w = rcons p`. -/
private def equivPairAux (i) (w : Word M) : { p : Pair M i // rcons p = w } :=
  consRecOn w ⟨⟨1, .empty, by simp [fstIdx, empty]⟩, by simp [rcons]⟩ <|
    fun j m w h1 h2 _ =>
      if ij : i = j then
        { val :=
          { head := ij ▸ m
            tail := w
            fstIdx_ne := ij ▸ h1 }
          property := by subst ij; 

Proof state:
ι : Type u_1
M : ι → Type u_2
inst✝³ : (i : ι) → Monoid (M i)
N : Type u_3
inst✝² : Monoid N
inst✝¹ : (i : ι) → DecidableEq (M i)
inst✝ : DecidableEq ι
i : ι
w✝ w : Word M
x✝ : { p // rcons p = w }
m : M i
h1 : fstIdx w ≠ some i
h2 : m ≠ 1
⊢ rcons { head := (_ : i = i) ▸ m, tail := w, fstIdx_ne := (_ : fstIdx w ≠ some i) } = cons m w h1 h2

Next tactic:
simp [rcons, h2]
/-- Given `i : ι`, any reduced word can be decomposed into a pair `p` such that `w = rcons p`. -/
private def equivPairAux (i) (w : Word M) : { p : Pair M i // rcons p = w } :=
  consRecOn w ⟨⟨1, .empty, by simp [fstIdx, empty]⟩, by simp [rcons]⟩ <|
    fun j m w h1 h2 _ =>
      if ij : i = j then
        { val :=
          { head := ij ▸ m
            tail := w
            fstIdx_ne := ij ▸ h1 }
          property := by subst ij; simp [rcons, h2] }
      else ⟨⟨1, cons m w h1 h2, by 

Proof state:
ι : Type u_1
M : ι → Type u_2
inst✝³ : (i : ι) → Monoid (M i)
N : Type u_3
inst✝² : Monoid N
inst✝¹ : (i : ι) → DecidableEq (M i)
inst✝ : DecidableEq ι
i : ι
w✝ : Word M
j : ι
m : M j
w : Word M
h1 : fstIdx w ≠ some j
h2 : m ≠ 1
x✝ : { p // rcons p = w }
ij : ¬i = j
⊢ fstIdx (cons m w h1 h2) ≠ some i

Next tactic:
simp [cons, fstIdx, Ne.symm ij]
/-- Given `i : ι`, any reduced word can be decomposed into a pair `p` such that `w = rcons p`. -/
private def equivPairAux (i) (w : Word M) : { p : Pair M i // rcons p = w } :=
  consRecOn w ⟨⟨1, .empty, by simp [fstIdx, empty]⟩, by simp [rcons]⟩ <|
    fun j m w h1 h2 _ =>
      if ij : i = j then
        { val :=
          { head := ij ▸ m
            tail := w
            fstIdx_ne := ij ▸ h1 }
          property := by subst ij; simp [rcons, h2] }
      else ⟨⟨1, cons m w h1 h2, by simp [cons, fstIdx, Ne.symm ij]⟩,  by 

Proof state:
ι : Type u_1
M : ι → Type u_2
inst✝³ : (i : ι) → Monoid (M i)
N : Type u_3
inst✝² : Monoid N
inst✝¹ : (i : ι) → DecidableEq (M i)
inst✝ : DecidableEq ι
i : ι
w✝ : Word M
j : ι
m : M j
w : Word M
h1 : fstIdx w ≠ some j
h2 : m ≠ 1
x✝ : { p // rcons p = w }
ij : ¬i = j
⊢ rcons { head := 1, tail := cons m w h1 h2, fstIdx_ne := (_ : ¬some j = some i) } = cons m w h1 h2

Next tactic:
simp [rcons]
theorem mem_equivPair_tail_iff {i j : ι} {w : Word M} (m : M i) :
    (⟨i, m⟩ ∈ (equivPair j w).tail.toList) ↔ ⟨i, m⟩ ∈ w.toList.tail
      ∨ i ≠ j ∧ ∃ h : w.toList ≠ [], w.toList.head h = ⟨i, m⟩ := by
  

Proof state:
ι : Type u_1
M : ι → Type u_2
inst✝³ : (i : ι) → Monoid (M i)
N : Type u_3
inst✝² : Monoid N
inst✝¹ : (i : ι) → DecidableEq (M i)
inst✝ : DecidableEq ι
i j : ι
w : Word M
m : M i
⊢ { fst := i, snd := m } ∈ ((equivPair j) w).tail.toList ↔
    { fst := i, snd := m } ∈ List.tail w.toList ∨
      i ≠ j ∧ ∃ (h : w.toList ≠ []), List.head w.toList h = { fst := i, snd := m }

Next tactic:
simp only [equivPair, equivPairAux, ne_eq, Equiv.coe_fn_mk]
theorem mem_equivPair_tail_iff {i j : ι} {w : Word M} (m : M i) :
    (⟨i, m⟩ ∈ (equivPair j w).tail.toList) ↔ ⟨i, m⟩ ∈ w.toList.tail
      ∨ i ≠ j ∧ ∃ h : w.toList ≠ [], w.toList.head h = ⟨i, m⟩ := by
  simp only [equivPair, equivPairAux, ne_eq, Equiv.coe_fn_mk]
  

Proof state:
ι : Type u_1
M : ι → Type u_2
inst✝³ : (i : ι) → Monoid (M i)
N : Type u_3
inst✝² : Monoid N
inst✝¹ : (i : ι) → DecidableEq (M i)
inst✝ : DecidableEq ι
i j : ι
w : Word M
m : M i
⊢ { fst := i, snd := m } ∈
      (↑(consRecOn w
              { val := { head := 1, tail := empty, fstIdx_ne := (_ : ¬none = some j) },
                property :=
                  (_ :
                    (if h : { head := 1, tail := empty, fstIdx_ne := (_ : ¬none = some j) }.head = 1 then
                        { head := 1, tail := empty, fstIdx_ne := (_ : ¬none = some j) }.tail
                      else
                        cons { head := 1, tail := empty, fstIdx_ne := (_ : ¬none = some j) }.head
                          { head := 1, tail := empty, fstIdx_ne := (_ : ¬none = some j) }.tail
                          (_ : fstIdx { head := 1, tail := empty, fstIdx_ne := (_ : ¬none = some j) }.tail ≠ some j)
                          h) =
                      empty) }
              fun j_1 m w h1 h2 x =>
              if ij : j = j_1 then
                { val := { head := (_ : j_1 = j) ▸ m, tail := w, fstIdx_ne := (_ : fstIdx w ≠ some j) },
                  property :=
                    (_ :
                      rcons { head := (_ : j_1 = j) ▸ m, tail := w, fstIdx_ne := (_ : fstIdx w ≠ some j) } =
                        cons m w h1 h2) }
              else
                { val := { head := 1, tail := cons m w h1 h2, fstIdx_ne := (_ : ¬some j_1 = some j) },
                  property :=
                    (_ :
                      (if h : { head := 1, tail := cons m w h1 h2, fstIdx_ne := (_ : ¬some j_1 = some j) }.head = 1 then
                          { head := 1, tail := cons m w h1 h2, fstIdx_ne := (_ : ¬some j_1 = some j) }.tail
                        else
                          cons { head := 1, tail := cons m w h1 h2, fstIdx_ne := (_ : ¬some j_1 = some j) }.head
                            { head := 1, tail := cons m w h1 h2, fstIdx_ne := (_ : ¬some j_1 = some j) }.tail
                            (_ :
                              fstIdx { head := 1, tail := cons m w h1 h2, fstIdx_ne := (_ : ¬some j_1 = some j) }.tail ≠
                                some j)
                            h) =
                        cons m w h1 h2) })).tail.toList ↔
    { fst := i, snd := m } ∈ List.tail w.toList ∨
      ¬i = j ∧ ∃ (h : ¬w.toList = []), List.head w.toList h = { fst := i, snd := m }

Next tactic:
induction w using consRecOn with
  | h_empty => simp
  | h_cons k g tail h1 h2 ih =>
    simp only [consRecOn_cons]
    split_ifs with h
    · subst k
      by_cases hij : j = i <;> simp_all
    · by_cases hik : i = k
      · subst i; simp_all [eq_comm, and_comm, or_comm]
      · simp [hik, Ne.symm hik]
theorem mem_equivPair_tail_iff {i j : ι} {w : Word M} (m : M i) :
    (⟨i, m⟩ ∈ (equivPair j w).tail.toList) ↔ ⟨i, m⟩ ∈ w.toList.tail
      ∨ i ≠ j ∧ ∃ h : w.toList ≠ [], w.toList.head h = ⟨i, m⟩ := by
  simp only [equivPair, equivPairAux, ne_eq, Equiv.coe_fn_mk]
  induction w using consRecOn with
  

Proof state:
case h_empty
ι : Type u_1
M : ι → Type u_2
inst✝³ : (i : ι) → Monoid (M i)
N : Type u_3
inst✝² : Monoid N
inst✝¹ : (i : ι) → DecidableEq (M i)
inst✝ : DecidableEq ι
i j : ι
m : M i
⊢ { fst := i, snd := m } ∈
      (↑(consRecOn empty
              { val := { head := 1, tail := empty, fstIdx_ne := (_ : ¬none = some j) },
                property :=
                  (_ :
                    (if h : { head := 1, tail := empty, fstIdx_ne := (_ : ¬none = some j) }.head = 1 then
                        { head := 1, tail := empty, fstIdx_ne := (_ : ¬none = some j) }.tail
                      else
                        cons { head := 1, tail := empty, fstIdx_ne := (_ : ¬none = some j) }.head
                          { head := 1, tail := empty, fstIdx_ne := (_ : ¬none = some j) }.tail
                          (_ : fstIdx { head := 1, tail := empty, fstIdx_ne := (_ : ¬none = some j) }.tail ≠ some j)
                          h) =
                      empty) }
              fun j_1 m w h1 h2 x =>
              if ij : j = j_1 then
                { val := { head := (_ : j_1 = j) ▸ m, tail := w, fstIdx_ne := (_ : fstIdx w ≠ some j) },
                  property :=
                    (_ :
                      rcons { head := (_ : j_1 = j) ▸ m, tail := w, fstIdx_ne := (_ : fstIdx w ≠ some j) } =
                        cons m w h1 h2) }
              else
                { val := { head := 1, tail := cons m w h1 h2, fstIdx_ne := (_ : ¬some j_1 = some j) },
                  property :=
                    (_ :
                      (if h : { head := 1, tail := cons m w h1 h2, fstIdx_ne := (_ : ¬some j_1 = some j) }.head = 1 then
                          { head := 1, tail := cons m w h1 h2, fstIdx_ne := (_ : ¬some j_1 = some j) }.tail
                        else
                          cons { head := 1, tail := cons m w h1 h2, fstIdx_ne := (_ : ¬some j_1 = some j) }.head
                            { head := 1, tail := cons m w h1 h2, fstIdx_ne := (_ : ¬some j_1 = some j) }.tail
                            (_ :
                              fstIdx { head := 1, tail := cons m w h1 h2, fstIdx_ne := (_ : ¬some j_1 = some j) }.tail ≠
                                some j)
                            h) =
                        cons m w h1 h2) })).tail.toList ↔
    { fst := i, snd := m } ∈ List.tail empty.toList ∨
      ¬i = j ∧ ∃ (h : ¬empty.toList = []), List.head empty.toList h = { fst := i, snd := m }

Next tactic:
| h_empty => simp
theorem mem_equivPair_tail_iff {i j : ι} {w : Word M} (m : M i) :
    (⟨i, m⟩ ∈ (equivPair j w).tail.toList) ↔ ⟨i, m⟩ ∈ w.toList.tail
      ∨ i ≠ j ∧ ∃ h : w.toList ≠ [], w.toList.head h = ⟨i, m⟩ := by
  simp only [equivPair, equivPairAux, ne_eq, Equiv.coe_fn_mk]
  induction w using consRecOn with
  | h_empty => 

Proof state:
case h_empty
ι : Type u_1
M : ι → Type u_2
inst✝³ : (i : ι) → Monoid (M i)
N : Type u_3
inst✝² : Monoid N
inst✝¹ : (i : ι) → DecidableEq (M i)
inst✝ : DecidableEq ι
i j : ι
m : M i
⊢ { fst := i, snd := m } ∈
      (↑(consRecOn empty
              { val := { head := 1, tail := empty, fstIdx_ne := (_ : ¬none = some j) },
                property :=
                  (_ :
                    (if h : { head := 1, tail := empty, fstIdx_ne := (_ : ¬none = some j) }.head = 1 then
                        { head := 1, tail := empty, fstIdx_ne := (_ : ¬none = some j) }.tail
                      else
                        cons { head := 1, tail := empty, fstIdx_ne := (_ : ¬none = some j) }.head
                          { head := 1, tail := empty, fstIdx_ne := (_ : ¬none = some j) }.tail
                          (_ : fstIdx { head := 1, tail := empty, fstIdx_ne := (_ : ¬none = some j) }.tail ≠ some j)
                          h) =
                      empty) }
              fun j_1 m w h1 h2 x =>
              if ij : j = j_1 then
                { val := { head := (_ : j_1 = j) ▸ m, tail := w, fstIdx_ne := (_ : fstIdx w ≠ some j) },
                  property :=
                    (_ :
                      rcons { head := (_ : j_1 = j) ▸ m, tail := w, fstIdx_ne := (_ : fstIdx w ≠ some j) } =
                        cons m w h1 h2) }
              else
                { val := { head := 1, tail := cons m w h1 h2, fstIdx_ne := (_ : ¬some j_1 = some j) },
                  property :=
                    (_ :
                      (if h : { head := 1, tail := cons m w h1 h2, fstIdx_ne := (_ : ¬some j_1 = some j) }.head = 1 then
                          { head := 1, tail := cons m w h1 h2, fstIdx_ne := (_ : ¬some j_1 = some j) }.tail
                        else
                          cons { head := 1, tail := cons m w h1 h2, fstIdx_ne := (_ : ¬some j_1 = some j) }.head
                            { head := 1, tail := cons m w h1 h2, fstIdx_ne := (_ : ¬some j_1 = some j) }.tail
                            (_ :
                              fstIdx { head := 1, tail := cons m w h1 h2, fstIdx_ne := (_ : ¬some j_1 = some j) }.tail ≠
                                some j)
                            h) =
                        cons m w h1 h2) })).tail.toList ↔
    { fst := i, snd := m } ∈ List.tail empty.toList ∨
      ¬i = j ∧ ∃ (h : ¬empty.toList = []), List.head empty.toList h = { fst := i, snd := m }

Next tactic:
simp
theorem mem_of_mem_equivPair_tail {i j : ι} {w : Word M} (m : M i) :
    (⟨i, m⟩ ∈ (equivPair j w).tail.toList) → ⟨i, m⟩ ∈ w.toList := by
  

Proof state:
ι : Type u_1
M : ι → Type u_2
inst✝³ : (i : ι) → Monoid (M i)
N : Type u_3
inst✝² : Monoid N
inst✝¹ : (i : ι) → DecidableEq (M i)
inst✝ : DecidableEq ι
i j : ι
w : Word M
m : M i
⊢ { fst := i, snd := m } ∈ ((equivPair j) w).tail.toList → { fst := i, snd := m } ∈ w.toList

Next tactic:
rw [mem_equivPair_tail_iff]
theorem mem_of_mem_equivPair_tail {i j : ι} {w : Word M} (m : M i) :
    (⟨i, m⟩ ∈ (equivPair j w).tail.toList) → ⟨i, m⟩ ∈ w.toList := by
  rw [mem_equivPair_tail_iff]
  

Proof state:
ι : Type u_1
M : ι → Type u_2
inst✝³ : (i : ι) → Monoid (M i)
N : Type u_3
inst✝² : Monoid N
inst✝¹ : (i : ι) → DecidableEq (M i)
inst✝ : DecidableEq ι
i j : ι
w : Word M
m : M i
⊢ ({ fst := i, snd := m } ∈ List.tail w.toList ∨
      i ≠ j ∧ ∃ (h : w.toList ≠ []), List.head w.toList h = { fst := i, snd := m }) →
    { fst := i, snd := m } ∈ w.toList

Next tactic:
rintro (h | h)
theorem mem_of_mem_equivPair_tail {i j : ι} {w : Word M} (m : M i) :
    (⟨i, m⟩ ∈ (equivPair j w).tail.toList) → ⟨i, m⟩ ∈ w.toList := by
  rw [mem_equivPair_tail_iff]
  rintro (h | h)
  · 

Proof state:
case inl
ι : Type u_1
M : ι → Type u_2
inst✝³ : (i : ι) → Monoid (M i)
N : Type u_3
inst✝² : Monoid N
inst✝¹ : (i : ι) → DecidableEq (M i)
inst✝ : DecidableEq ι
i j : ι
w : Word M
m : M i
h : { fst := i, snd := m } ∈ List.tail w.toList
⊢ { fst := i, snd := m } ∈ w.toList

Next tactic:
exact List.mem_of_mem_tail h
theorem mem_of_mem_equivPair_tail {i j : ι} {w : Word M} (m : M i) :
    (⟨i, m⟩ ∈ (equivPair j w).tail.toList) → ⟨i, m⟩ ∈ w.toList := by
  rw [mem_equivPair_tail_iff]
  rintro (h | h)
  · exact List.mem_of_mem_tail h
  · 

Proof state:
case inr
ι : Type u_1
M : ι → Type u_2
inst✝³ : (i : ι) → Monoid (M i)
N : Type u_3
inst✝² : Monoid N
inst✝¹ : (i : ι) → DecidableEq (M i)
inst✝ : DecidableEq ι
i j : ι
w : Word M
m : M i
h : i ≠ j ∧ ∃ (h : w.toList ≠ []), List.head w.toList h = { fst := i, snd := m }
⊢ { fst := i, snd := m } ∈ w.toList

Next tactic:
revert h
theorem mem_of_mem_equivPair_tail {i j : ι} {w : Word M} (m : M i) :
    (⟨i, m⟩ ∈ (equivPair j w).tail.toList) → ⟨i, m⟩ ∈ w.toList := by
  rw [mem_equivPair_tail_iff]
  rintro (h | h)
  · exact List.mem_of_mem_tail h
  · revert h; 

Proof state:
case inr
ι : Type u_1
M : ι → Type u_2
inst✝³ : (i : ι) → Monoid (M i)
N : Type u_3
inst✝² : Monoid N
inst✝¹ : (i : ι) → DecidableEq (M i)
inst✝ : DecidableEq ι
i j : ι
w : Word M
m : M i
⊢ (i ≠ j ∧ ∃ (h : w.toList ≠ []), List.head w.toList h = { fst := i, snd := m }) → { fst := i, snd := m } ∈ w.toList

Next tactic:
cases w.toList
theorem mem_of_mem_equivPair_tail {i j : ι} {w : Word M} (m : M i) :
    (⟨i, m⟩ ∈ (equivPair j w).tail.toList) → ⟨i, m⟩ ∈ w.toList := by
  rw [mem_equivPair_tail_iff]
  rintro (h | h)
  · exact List.mem_of_mem_tail h
  · revert h; cases w.toList <;> 

Proof state:
case inr.nil
ι : Type u_1
M : ι → Type u_2
inst✝³ : (i : ι) → Monoid (M i)
N : Type u_3
inst✝² : Monoid N
inst✝¹ : (i : ι) → DecidableEq (M i)
inst✝ : DecidableEq ι
i j : ι
w : Word M
m : M i
⊢ (i ≠ j ∧ ∃ (h : [] ≠ []), List.head [] h = { fst := i, snd := m }) → { fst := i, snd := m } ∈ []

Next tactic:
simp (config := {contextual := true})
theorem mem_of_mem_equivPair_tail {i j : ι} {w : Word M} (m : M i) :
    (⟨i, m⟩ ∈ (equivPair j w).tail.toList) → ⟨i, m⟩ ∈ w.toList := by
  rw [mem_equivPair_tail_iff]
  rintro (h | h)
  · exact List.mem_of_mem_tail h
  · revert h; cases w.toList <;> 

Proof state:
case inr.cons
ι : Type u_1
M : ι → Type u_2
inst✝³ : (i : ι) → Monoid (M i)
N : Type u_3
inst✝² : Monoid N
inst✝¹ : (i : ι) → DecidableEq (M i)
inst✝ : DecidableEq ι
i j : ι
w : Word M
m : M i
head✝ : (i : ι) × M i
tail✝ : List ((i : ι) × M i)
⊢ (i ≠ j ∧ ∃ (h : head✝ :: tail✝ ≠ []), List.head (head✝ :: tail✝) h = { fst := i, snd := m }) →
    { fst := i, snd := m } ∈ head✝ :: tail✝

Next tactic:
simp (config := {contextual := true})
theorem equivPair_head {i : ι} {w : Word M} :
    (equivPair i w).head =
      if h : ∃ (h : w.toList ≠ []), (w.toList.head h).1 = i
      then h.snd ▸ (w.toList.head h.1).2
      else 1 := by
  

Proof state:
ι : Type u_1
M : ι → Type u_2
inst✝³ : (i : ι) → Monoid (M i)
N : Type u_3
inst✝² : Monoid N
inst✝¹ : (i : ι) → DecidableEq (M i)
inst✝ : DecidableEq ι
i : ι
w : Word M
⊢ ((equivPair i) w).head =
    if h : ∃ (h : w.toList ≠ []), (List.head w.toList h).fst = i then
      (_ : (List.head w.toList (_ : w.toList ≠ [])).fst = i) ▸ (List.head w.toList (_ : w.toList ≠ [])).snd
    else 1

Next tactic:
simp only [equivPair, equivPairAux]
instance summandAction (i) : MulAction (M i) (Word M) where
  smul m w := rcons { equivPair i w with head := m * (equivPair i w).head }
  one_smul w := by
    

Proof state:
ι : Type u_1
M : ι → Type u_2
inst✝³ : (i : ι) → Monoid (M i)
N : Type u_3
inst✝² : Monoid N
inst✝¹ : (i : ι) → DecidableEq (M i)
inst✝ : DecidableEq ι
i : ι
w : Word M
⊢ 1 • w = w

Next tactic:
apply (equivPair i).symm_apply_eq.mpr
instance summandAction (i) : MulAction (M i) (Word M) where
  smul m w := rcons { equivPair i w with head := m * (equivPair i w).head }
  one_smul w := by
    apply (equivPair i).symm_apply_eq.mpr
    

Proof state:
ι : Type u_1
M : ι → Type u_2
inst✝³ : (i : ι) → Monoid (M i)
N : Type u_3
inst✝² : Monoid N
inst✝¹ : (i : ι) → DecidableEq (M i)
inst✝ : DecidableEq ι
i : ι
w : Word M
⊢ (let src := (equivPair i) w;
    { head := 1 * ((equivPair i) w).head, tail := src.tail, fstIdx_ne := (_ : fstIdx src.tail ≠ some i) }) =
    (equivPair i) w

Next tactic:
simp [equivPair]
instance summandAction (i) : MulAction (M i) (Word M) where
  smul m w := rcons { equivPair i w with head := m * (equivPair i w).head }
  one_smul w := by
    apply (equivPair i).symm_apply_eq.mpr
    simp [equivPair]
  mul_smul m m' w := by
    

Proof state:
ι : Type u_1
M : ι → Type u_2
inst✝³ : (i : ι) → Monoid (M i)
N : Type u_3
inst✝² : Monoid N
inst✝¹ : (i : ι) → DecidableEq (M i)
inst✝ : DecidableEq ι
i : ι
m m' : M i
w : Word M
⊢ (m * m') • w = m • m' • w

Next tactic:
dsimp [instHSMul]
instance summandAction (i) : MulAction (M i) (Word M) where
  smul m w := rcons { equivPair i w with head := m * (equivPair i w).head }
  one_smul w := by
    apply (equivPair i).symm_apply_eq.mpr
    simp [equivPair]
  mul_smul m m' w := by
    dsimp [instHSMul]
    

Proof state:
ι : Type u_1
M : ι → Type u_2
inst✝³ : (i : ι) → Monoid (M i)
N : Type u_3
inst✝² : Monoid N
inst✝¹ : (i : ι) → DecidableEq (M i)
inst✝ : DecidableEq ι
i : ι
m m' : M i
w : Word M
⊢ rcons
      { head := m * m' * ((equivPair i) w).head, tail := ((equivPair i) w).tail,
        fstIdx_ne := (_ : fstIdx ((equivPair i) w).tail ≠ some i) } =
    rcons
      {
        head :=
          m *
            ((equivPair i)
                (rcons
                  { head := m' * ((equivPair i) w).head, tail := ((equivPair i) w).tail,
                    fstIdx_ne := (_ : fstIdx ((equivPair i) w).tail ≠ some i) })).head,
        tail :=
          ((equivPair i)
              (rcons
                { head := m' * ((equivPair i) w).head, tail := ((equivPair i) w).tail,
                  fstIdx_ne := (_ : fstIdx ((equivPair i) w).tail ≠ some i) })).tail,
        fstIdx_ne :=
          (_ :
            fstIdx
                ((equivPair i)
                    (rcons
                      { head := m' * ((equivPair i) w).head, tail := ((equivPair i) w).tail,
                        fstIdx_ne := (_ : fstIdx ((equivPair i) w).tail ≠ some i) })).tail ≠
              some i) }

Next tactic:
simp [mul_assoc, ← equivPair_symm, Equiv.apply_symm_apply]
theorem equivPair_smul_same {i} (m : M i) (w : Word M) :
    equivPair i (of m • w) = ⟨m * (equivPair i w).head, (equivPair i w).tail,
      (equivPair i w).fstIdx_ne⟩ := by
  

Proof state:
ι : Type u_1
M : ι → Type u_2
inst✝³ : (i : ι) → Monoid (M i)
N : Type u_3
inst✝² : Monoid N
inst✝¹ : (i : ι) → DecidableEq (M i)
inst✝ : DecidableEq ι
i : ι
m : M i
w : Word M
⊢ (equivPair i) (of m • w) =
    { head := m * ((equivPair i) w).head, tail := ((equivPair i) w).tail,
      fstIdx_ne := (_ : fstIdx ((equivPair i) w).tail ≠ some i) }

Next tactic:
rw [of_smul_def, ← equivPair_symm]
theorem equivPair_smul_same {i} (m : M i) (w : Word M) :
    equivPair i (of m • w) = ⟨m * (equivPair i w).head, (equivPair i w).tail,
      (equivPair i w).fstIdx_ne⟩ := by
  rw [of_smul_def, ← equivPair_symm]
  

Proof state:
ι : Type u_1
M : ι → Type u_2
inst✝³ : (i : ι) → Monoid (M i)
N : Type u_3
inst✝² : Monoid N
inst✝¹ : (i : ι) → DecidableEq (M i)
inst✝ : DecidableEq ι
i : ι
m : M i
w : Word M
⊢ (equivPair i)
      ((equivPair i).symm
        (let src := (equivPair i) w;
        { head := m * ((equivPair i) w).head, tail := src.tail, fstIdx_ne := (_ : fstIdx src.tail ≠ some i) })) =
    { head := m * ((equivPair i) w).head, tail := ((equivPair i) w).tail,
      fstIdx_ne := (_ : fstIdx ((equivPair i) w).tail ≠ some i) }

Next tactic:
simp
theorem mem_smul_iff {i j : ι} {m₁ : M i} {m₂ : M j} {w : Word M} :
    ⟨_, m₁⟩ ∈ (of m₂ • w).toList ↔
      (¬i = j ∧ ⟨i, m₁⟩ ∈ w.toList)
      ∨ (m₁ ≠ 1 ∧ ∃ (hij : i = j),(⟨i, m₁⟩ ∈ w.toList.tail) ∨
        (∃ m', ⟨j, m'⟩ ∈ w.toList.head? ∧ m₁ = hij ▸ (m₂ * m')) ∨
        (w.fstIdx ≠ some j ∧ m₁ = hij ▸ m₂)) := by
  

Proof state:
ι : Type u_1
M : ι → Type u_2
inst✝³ : (i : ι) → Monoid (M i)
N : Type u_3
inst✝² : Monoid N
inst✝¹ : (i : ι) → DecidableEq (M i)
inst✝ : DecidableEq ι
i j : ι
m₁ : M i
m₂ : M j
w : Word M
⊢ { fst := i, snd := m₁ } ∈ (of m₂ • w).toList ↔
    ¬i = j ∧ { fst := i, snd := m₁ } ∈ w.toList ∨
      m₁ ≠ 1 ∧
        ∃ (hij : i = j),
          { fst := i, snd := m₁ } ∈ List.tail w.toList ∨
            (∃ m', { fst := j, snd := m' } ∈ List.head? w.toList ∧ m₁ = (_ : j = i) ▸ (m₂ * m')) ∨
              fstIdx w ≠ some j ∧ m₁ = (_ : j = i) ▸ m₂

Next tactic:
rw [of_smul_def, mem_rcons_iff, mem_equivPair_tail_iff, equivPair_head, or_assoc]
theorem mem_smul_iff {i j : ι} {m₁ : M i} {m₂ : M j} {w : Word M} :
    ⟨_, m₁⟩ ∈ (of m₂ • w).toList ↔
      (¬i = j ∧ ⟨i, m₁⟩ ∈ w.toList)
      ∨ (m₁ ≠ 1 ∧ ∃ (hij : i = j),(⟨i, m₁⟩ ∈ w.toList.tail) ∨
        (∃ m', ⟨j, m'⟩ ∈ w.toList.head? ∧ m₁ = hij ▸ (m₂ * m')) ∨
        (w.fstIdx ≠ some j ∧ m₁ = hij ▸ m₂)) := by
  rw [of_smul_def, mem_rcons_iff, mem_equivPair_tail_iff, equivPair_head, or_assoc]
  

Proof state:
ι : Type u_1
M : ι → Type u_2
inst✝³ : (i : ι) → Monoid (M i)
N : Type u_3
inst✝² : Monoid N
inst✝¹ : (i : ι) → DecidableEq (M i)
inst✝ : DecidableEq ι
i j : ι
m₁ : M i
m₂ : M j
w : Word M
⊢ ({ fst := i, snd := m₁ } ∈ List.tail w.toList ∨
      (i ≠ j ∧ ∃ (h : w.toList ≠ []), List.head w.toList h = { fst := i, snd := m₁ }) ∨
        m₁ ≠ 1 ∧
          ∃ (h : j = i),
            m₁ =
              h ▸
                (let src := (equivPair j) w;
                  {
                    head :=
                      m₂ *
                        if h : ∃ (h : w.toList ≠ []), (List.head w.toList h).fst = j then
                          (_ : (List.head w.toList (_ : w.toList ≠ [])).fst = j) ▸
                            (List.head w.toList (_ : w.toList ≠ [])).snd
                        else 1,
                    tail := src.tail, fstIdx_ne := (_ : fstIdx src.tail ≠ some j) }).head) ↔
    ¬i = j ∧ { fst := i, snd := m₁ } ∈ w.toList ∨
      m₁ ≠ 1 ∧
        ∃ (hij : i = j),
          { fst := i, snd := m₁ } ∈ List.tail w.toList ∨
            (∃ m', { fst := j, snd := m' } ∈ List.head? w.toList ∧ m₁ = (_ : j = i) ▸ (m₂ * m')) ∨
              fstIdx w ≠ some j ∧ m₁ = (_ : j = i) ▸ m₂

Next tactic:
by_cases hij : i = j