l3lab/ntp-mathlib huggingface dataset:
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]
  by_cases hij : i = j
  · 

Proof state:
case pos
ι : 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
hij : i = j
⊢ ({ 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:
subst i
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]
  by_cases hij : i = j
  · subst i
    

Proof state:
case pos
ι : 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 ι
j : ι
m₂ : M j
w : Word M
m₁ : M j
⊢ ({ fst := j, snd := m₁ } ∈ List.tail w.toList ∨
      (j ≠ j ∧ ∃ (h : w.toList ≠ []), List.head w.toList h = { fst := j, snd := m₁ }) ∨
        m₁ ≠ 1 ∧
          ∃ (h : j = j),
            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) ↔
    ¬j = j ∧ { fst := j, snd := m₁ } ∈ w.toList ∨
      m₁ ≠ 1 ∧
        ∃ (hij : j = j),
          { fst := j, snd := m₁ } ∈ List.tail w.toList ∨
            (∃ m', { fst := j, snd := m' } ∈ List.head? w.toList ∧ m₁ = (_ : j = j) ▸ (m₂ * m')) ∨
              fstIdx w ≠ some j ∧ m₁ = (_ : j = j) ▸ m₂

Next tactic:
simp only [not_true, ne_eq, false_and, exists_prop, true_and, false_or]
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]
  by_cases hij : i = j
  · subst i
    simp only [not_true, ne_eq, false_and, exists_prop, true_and, false_or]
    

Proof state:
case pos
ι : 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 ι
j : ι
m₂ : M j
w : Word M
m₁ : M j
⊢ ({ fst := j, snd := m₁ } ∈ List.tail w.toList ∨
      ¬m₁ = 1 ∧
        m₁ =
          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) ↔
    ¬m₁ = 1 ∧
      ({ fst := j, snd := m₁ } ∈ List.tail w.toList ∨
        (∃ m', { fst := j, snd := m' } ∈ List.head? w.toList ∧ m₁ = m₂ * m') ∨ ¬fstIdx w = some j ∧ m₁ = m₂)

Next tactic:
by_cases hw : ⟨j, m₁⟩ ∈ w.toList.tail
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]
  by_cases hij : i = j
  · subst i
    simp only [not_true, ne_eq, false_and, exists_prop, true_and, false_or]
    by_cases hw : ⟨j, m₁⟩ ∈ w.toList.tail
    · 

Proof state:
case pos
ι : 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 ι
j : ι
m₂ : M j
w : Word M
m₁ : M j
hw : { fst := j, snd := m₁ } ∈ List.tail w.toList
⊢ ({ fst := j, snd := m₁ } ∈ List.tail w.toList ∨
      ¬m₁ = 1 ∧
        m₁ =
          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) ↔
    ¬m₁ = 1 ∧
      ({ fst := j, snd := m₁ } ∈ List.tail w.toList ∨
        (∃ m', { fst := j, snd := m' } ∈ List.head? w.toList ∧ m₁ = m₂ * m') ∨ ¬fstIdx w = some j ∧ m₁ = m₂)

Next tactic:
simp [hw, show m₁ ≠ 1 from w.ne_one _ (List.mem_of_mem_tail hw)]
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]
  by_cases hij : i = j
  · subst i
    simp only [not_true, ne_eq, false_and, exists_prop, true_and, false_or]
    by_cases hw : ⟨j, m₁⟩ ∈ w.toList.tail
    · simp [hw, show m₁ ≠ 1 from w.ne_one _ (List.mem_of_mem_tail hw)]
    · 

Proof state:
case neg
ι : 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 ι
j : ι
m₂ : M j
w : Word M
m₁ : M j
hw : { fst := j, snd := m₁ } ∉ List.tail w.toList
⊢ ({ fst := j, snd := m₁ } ∈ List.tail w.toList ∨
      ¬m₁ = 1 ∧
        m₁ =
          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) ↔
    ¬m₁ = 1 ∧
      ({ fst := j, snd := m₁ } ∈ List.tail w.toList ∨
        (∃ m', { fst := j, snd := m' } ∈ List.head? w.toList ∧ m₁ = m₂ * m') ∨ ¬fstIdx w = some j ∧ m₁ = m₂)

Next tactic:
simp only [hw, false_or, Option.mem_def, ne_eq, and_congr_right_iff]
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]
  by_cases hij : i = j
  · subst i
    simp only [not_true, ne_eq, false_and, exists_prop, true_and, false_or]
    by_cases hw : ⟨j, m₁⟩ ∈ w.toList.tail
    · simp [hw, show m₁ ≠ 1 from w.ne_one _ (List.mem_of_mem_tail hw)]
    · simp only [hw, false_or, Option.mem_def, ne_eq, and_congr_right_iff]
      

Proof state:
case neg
ι : 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 ι
j : ι
m₂ : M j
w : Word M
m₁ : M j
hw : { fst := j, snd := m₁ } ∉ List.tail w.toList
⊢ ¬m₁ = 1 →
    ((m₁ =
        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) ↔
      (∃ m', List.head? w.toList = some { fst := j, snd := m' } ∧ m₁ = m₂ * m') ∨ ¬fstIdx w = some j ∧ m₁ = m₂)

Next tactic:
intro hm1
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]
  by_cases hij : i = j
  · subst i
    simp only [not_true, ne_eq, false_and, exists_prop, true_and, false_or]
    by_cases hw : ⟨j, m₁⟩ ∈ w.toList.tail
    · simp [hw, show m₁ ≠ 1 from w.ne_one _ (List.mem_of_mem_tail hw)]
    · simp only [hw, false_or, Option.mem_def, ne_eq, and_congr_right_iff]
      intro hm1
      

Proof state:
case neg
ι : 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 ι
j : ι
m₂ : M j
w : Word M
m₁ : M j
hw : { fst := j, snd := m₁ } ∉ List.tail w.toList
hm1 : ¬m₁ = 1
⊢ (m₁ =
      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) ↔
    (∃ m', List.head? w.toList = some { fst := j, snd := m' } ∧ m₁ = m₂ * m') ∨ ¬fstIdx w = some j ∧ m₁ = m₂

Next tactic:
split_ifs with h
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]
  by_cases hij : i = j
  · subst i
    simp only [not_true, ne_eq, false_and, exists_prop, true_and, false_or]
    by_cases hw : ⟨j, m₁⟩ ∈ w.toList.tail
    · simp [hw, show m₁ ≠ 1 from w.ne_one _ (List.mem_of_mem_tail hw)]
    · simp only [hw, false_or, Option.mem_def, ne_eq, and_congr_right_iff]
      intro hm1
      split_ifs with h
      · 

Proof state:
case pos
ι : 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 ι
j : ι
m₂ : M j
w : Word M
m₁ : M j
hw : { fst := j, snd := m₁ } ∉ List.tail w.toList
hm1 : ¬m₁ = 1
h : ∃ (h : ¬w.toList = []), (List.head w.toList h).fst = j
⊢ m₁ = m₂ * (_ : (List.head w.toList (_ : w.toList ≠ [])).fst = j) ▸ (List.head w.toList (_ : ¬w.toList = [])).snd ↔
    (∃ m', List.head? w.toList = some { fst := j, snd := m' } ∧ m₁ = m₂ * m') ∨ ¬fstIdx w = some j ∧ m₁ = m₂

Next tactic:
rcases h with ⟨hnil, rfl⟩
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]
  by_cases hij : i = j
  · subst i
    simp only [not_true, ne_eq, false_and, exists_prop, true_and, false_or]
    by_cases hw : ⟨j, m₁⟩ ∈ w.toList.tail
    · simp [hw, show m₁ ≠ 1 from w.ne_one _ (List.mem_of_mem_tail hw)]
    · simp only [hw, false_or, Option.mem_def, ne_eq, and_congr_right_iff]
      intro hm1
      split_ifs with h
      · rcases h with ⟨hnil, rfl⟩
        

Proof state:
case pos.intro
ι : 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 ι
w : Word M
hnil : ¬w.toList = []
m₂ m₁ : M (List.head w.toList hnil).fst
hw : { fst := (List.head w.toList hnil).fst, snd := m₁ } ∉ List.tail w.toList
hm1 : ¬m₁ = 1
⊢ m₁ =
      m₂ *
        (_ : (List.head w.toList (_ : w.toList ≠ [])).fst = (List.head w.toList hnil).fst) ▸
          (List.head w.toList (_ : ¬w.toList = [])).snd ↔
    (∃ m', List.head? w.toList = some { fst := (List.head w.toList hnil).fst, snd := m' } ∧ m₁ = m₂ * m') ∨
      ¬fstIdx w = some (List.head w.toList hnil).fst ∧ m₁ = m₂

Next tactic:
simp only [List.head?_eq_head _ hnil, Option.some.injEq, ne_eq]
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]
  by_cases hij : i = j
  · subst i
    simp only [not_true, ne_eq, false_and, exists_prop, true_and, false_or]
    by_cases hw : ⟨j, m₁⟩ ∈ w.toList.tail
    · simp [hw, show m₁ ≠ 1 from w.ne_one _ (List.mem_of_mem_tail hw)]
    · simp only [hw, false_or, Option.mem_def, ne_eq, and_congr_right_iff]
      intro hm1
      split_ifs with h
      · rcases h with ⟨hnil, rfl⟩
        simp only [List.head?_eq_head _ hnil, Option.some.injEq, ne_eq]
        

Proof state:
case pos.intro
ι : 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 ι
w : Word M
hnil : ¬w.toList = []
m₂ m₁ : M (List.head w.toList hnil).fst
hw : { fst := (List.head w.toList hnil).fst, snd := m₁ } ∉ List.tail w.toList
hm1 : ¬m₁ = 1
⊢ m₁ = m₂ * (List.head w.toList (_ : ¬w.toList = [])).snd ↔
    (∃ m', List.head w.toList hnil = { fst := (List.head w.toList hnil).fst, snd := m' } ∧ m₁ = m₂ * m') ∨
      ¬fstIdx w = some (List.head w.toList hnil).fst ∧ m₁ = m₂

Next tactic:
constructor
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]
  by_cases hij : i = j
  · subst i
    simp only [not_true, ne_eq, false_and, exists_prop, true_and, false_or]
    by_cases hw : ⟨j, m₁⟩ ∈ w.toList.tail
    · simp [hw, show m₁ ≠ 1 from w.ne_one _ (List.mem_of_mem_tail hw)]
    · simp only [hw, false_or, Option.mem_def, ne_eq, and_congr_right_iff]
      intro hm1
      split_ifs with h
      · rcases h with ⟨hnil, rfl⟩
        simp only [List.head?_eq_head _ hnil, Option.some.injEq, ne_eq]
        constructor
        · 

Proof state:
case pos.intro.mp
ι : 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 ι
w : Word M
hnil : ¬w.toList = []
m₂ m₁ : M (List.head w.toList hnil).fst
hw : { fst := (List.head w.toList hnil).fst, snd := m₁ } ∉ List.tail w.toList
hm1 : ¬m₁ = 1
⊢ m₁ = m₂ * (List.head w.toList (_ : ¬w.toList = [])).snd →
    (∃ m', List.head w.toList hnil = { fst := (List.head w.toList hnil).fst, snd := m' } ∧ m₁ = m₂ * m') ∨
      ¬fstIdx w = some (List.head w.toList hnil).fst ∧ m₁ = m₂

Next tactic:
rintro rfl
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]
  by_cases hij : i = j
  · subst i
    simp only [not_true, ne_eq, false_and, exists_prop, true_and, false_or]
    by_cases hw : ⟨j, m₁⟩ ∈ w.toList.tail
    · simp [hw, show m₁ ≠ 1 from w.ne_one _ (List.mem_of_mem_tail hw)]
    · simp only [hw, false_or, Option.mem_def, ne_eq, and_congr_right_iff]
      intro hm1
      split_ifs with h
      · rcases h with ⟨hnil, rfl⟩
        simp only [List.head?_eq_head _ hnil, Option.some.injEq, ne_eq]
        constructor
        · rintro rfl
          

Proof state:
case pos.intro.mp
ι : 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 ι
w : Word M
hnil : ¬w.toList = []
m₂ : M (List.head w.toList hnil).fst
hw :
  { fst := (List.head w.toList hnil).fst, snd := m₂ * (List.head w.toList (_ : ¬w.toList = [])).snd } ∉
    List.tail w.toList
hm1 : ¬m₂ * (List.head w.toList (_ : ¬w.toList = [])).snd = 1
⊢ (∃ m',
      List.head w.toList hnil = { fst := (List.head w.toList hnil).fst, snd := m' } ∧
        m₂ * (List.head w.toList (_ : ¬w.toList = [])).snd = m₂ * m') ∨
    ¬fstIdx w = some (List.head w.toList hnil).fst ∧ m₂ * (List.head w.toList (_ : ¬w.toList = [])).snd = m₂

Next tactic:
exact Or.inl ⟨_, rfl, rfl⟩
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]
  by_cases hij : i = j
  · subst i
    simp only [not_true, ne_eq, false_and, exists_prop, true_and, false_or]
    by_cases hw : ⟨j, m₁⟩ ∈ w.toList.tail
    · simp [hw, show m₁ ≠ 1 from w.ne_one _ (List.mem_of_mem_tail hw)]
    · simp only [hw, false_or, Option.mem_def, ne_eq, and_congr_right_iff]
      intro hm1
      split_ifs with h
      · rcases h with ⟨hnil, rfl⟩
        simp only [List.head?_eq_head _ hnil, Option.some.injEq, ne_eq]
        constructor
        · rintro rfl
          exact Or.inl ⟨_, rfl, rfl⟩
        · 

Proof state:
case pos.intro.mpr
ι : 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 ι
w : Word M
hnil : ¬w.toList = []
m₂ m₁ : M (List.head w.toList hnil).fst
hw : { fst := (List.head w.toList hnil).fst, snd := m₁ } ∉ List.tail w.toList
hm1 : ¬m₁ = 1
⊢ (∃ m', List.head w.toList hnil = { fst := (List.head w.toList hnil).fst, snd := m' } ∧ m₁ = m₂ * m') ∨
      ¬fstIdx w = some (List.head w.toList hnil).fst ∧ m₁ = m₂ →
    m₁ = m₂ * (List.head w.toList (_ : ¬w.toList = [])).snd

Next tactic:
rintro (⟨_, h, rfl⟩ | hm')
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]
  by_cases hij : i = j
  · subst i
    simp only [not_true, ne_eq, false_and, exists_prop, true_and, false_or]
    by_cases hw : ⟨j, m₁⟩ ∈ w.toList.tail
    · simp [hw, show m₁ ≠ 1 from w.ne_one _ (List.mem_of_mem_tail hw)]
    · simp only [hw, false_or, Option.mem_def, ne_eq, and_congr_right_iff]
      intro hm1
      split_ifs with h
      · rcases h with ⟨hnil, rfl⟩
        simp only [List.head?_eq_head _ hnil, Option.some.injEq, ne_eq]
        constructor
        · rintro rfl
          exact Or.inl ⟨_, rfl, rfl⟩
        · rintro (⟨_, h, rfl⟩ | hm')
          · 

Proof state:
case pos.intro.mpr.inl.intro.intro
ι : 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 ι
w : Word M
hnil : ¬w.toList = []
m₂ w✝ : M (List.head w.toList hnil).fst
h : List.head w.toList hnil = { fst := (List.head w.toList hnil).fst, snd := w✝ }
hw : { fst := (List.head w.toList hnil).fst, snd := m₂ * w✝ } ∉ List.tail w.toList
hm1 : ¬m₂ * w✝ = 1
⊢ m₂ * w✝ = m₂ * (List.head w.toList (_ : ¬w.toList = [])).snd

Next tactic:
simp [Sigma.ext_iff] at h
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]
  by_cases hij : i = j
  · subst i
    simp only [not_true, ne_eq, false_and, exists_prop, true_and, false_or]
    by_cases hw : ⟨j, m₁⟩ ∈ w.toList.tail
    · simp [hw, show m₁ ≠ 1 from w.ne_one _ (List.mem_of_mem_tail hw)]
    · simp only [hw, false_or, Option.mem_def, ne_eq, and_congr_right_iff]
      intro hm1
      split_ifs with h
      · rcases h with ⟨hnil, rfl⟩
        simp only [List.head?_eq_head _ hnil, Option.some.injEq, ne_eq]
        constructor
        · rintro rfl
          exact Or.inl ⟨_, rfl, rfl⟩
        · rintro (⟨_, h, rfl⟩ | hm')
          · simp [Sigma.ext_iff] at h
            

Proof state:
case pos.intro.mpr.inl.intro.intro
ι : 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 ι
w : Word M
hnil : ¬w.toList = []
m₂ w✝ : M (List.head w.toList hnil).fst
hw : { fst := (List.head w.toList hnil).fst, snd := m₂ * w✝ } ∉ List.tail w.toList
hm1 : ¬m₂ * w✝ = 1
h : (List.head w.toList hnil).snd = w✝
⊢ m₂ * w✝ = m₂ * (List.head w.toList (_ : ¬w.toList = [])).snd

Next tactic:
subst h
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]
  by_cases hij : i = j
  · subst i
    simp only [not_true, ne_eq, false_and, exists_prop, true_and, false_or]
    by_cases hw : ⟨j, m₁⟩ ∈ w.toList.tail
    · simp [hw, show m₁ ≠ 1 from w.ne_one _ (List.mem_of_mem_tail hw)]
    · simp only [hw, false_or, Option.mem_def, ne_eq, and_congr_right_iff]
      intro hm1
      split_ifs with h
      · rcases h with ⟨hnil, rfl⟩
        simp only [List.head?_eq_head _ hnil, Option.some.injEq, ne_eq]
        constructor
        · rintro rfl
          exact Or.inl ⟨_, rfl, rfl⟩
        · rintro (⟨_, h, rfl⟩ | hm')
          · simp [Sigma.ext_iff] at h
            subst h
            

Proof state:
case pos.intro.mpr.inl.intro.intro
ι : 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 ι
w : Word M
hnil : ¬w.toList = []
m₂ : M (List.head w.toList hnil).fst
hw : { fst := (List.head w.toList hnil).fst, snd := m₂ * (List.head w.toList hnil).snd } ∉ List.tail w.toList
hm1 : ¬m₂ * (List.head w.toList hnil).snd = 1
⊢ m₂ * (List.head w.toList hnil).snd = m₂ * (List.head w.toList (_ : ¬w.toList = [])).snd

Next tactic:
rfl