Theorem: FreeProduct.Word.rcons_inj
File: Mathlib/GroupTheory/FreeProduct.lean

tactic: rintro ⟨m, w, h⟩ ⟨m', w', h'⟩ he
state_before: ι : Type u_1
M : ι → Type u_2
inst✝² : (i : ι) → Monoid (M i)
N : Type ?u.406645
inst✝¹ : Monoid N
inst✝ : (i : ι) → DecidableEq (M i)
i : ι
⊢ Function.Injective rcons

tactic: by_cases hm : m = 1 <;> by_cases hm' : m' = 1
state_before: case mk.mk
ι : Type u_1
M : ι → Type u_2
inst✝² : (i : ι) → Monoid (M i)
N : Type ?u.406645
inst✝¹ : Monoid N
inst✝ : (i : ι) → DecidableEq (M i)
i : ι
m : M i
w : Word M
h : fstIdx w ≠ some i
m' : M i
w' : Word M
h' : fstIdx w' ≠ some i
he : rcons { head := m, tail := w, fstIdx_ne := h } = rcons { head := m', tail := w', fstIdx_ne := h' }
⊢ { head := m, tail := w, fstIdx_ne := h } = { head := m', tail := w', fstIdx_ne := h' }

tactic: simp only [rcons, dif_pos hm, dif_pos hm'] at he
state_before: case pos
ι : Type u_1
M : ι → Type u_2
inst✝² : (i : ι) → Monoid (M i)
N : Type ?u.406645
inst✝¹ : Monoid N
inst✝ : (i : ι) → DecidableEq (M i)
i : ι
m : M i
w : Word M
h : fstIdx w ≠ some i
m' : M i
w' : Word M
h' : fstIdx w' ≠ some i
he : rcons { head := m, tail := w, fstIdx_ne := h } = rcons { head := m', tail := w', fstIdx_ne := h' }
hm : m = 1
hm' : m' = 1
⊢ { head := m, tail := w, fstIdx_ne := h } = { head := m', tail := w', fstIdx_ne := h' }

tactic: aesop
state_before: case pos
ι : Type u_1
M : ι → Type u_2
inst✝² : (i : ι) → Monoid (M i)
N : Type ?u.406645
inst✝¹ : Monoid N
inst✝ : (i : ι) → DecidableEq (M i)
i : ι
m : M i
w : Word M
h : fstIdx w ≠ some i
m' : M i
w' : Word M
h' : fstIdx w' ≠ some i
hm : m = 1
hm' : m' = 1
he : w = w'
⊢ { head := m, tail := w, fstIdx_ne := h } = { head := m', tail := w', fstIdx_ne := h' }

tactic: exfalso
state_before: case neg
ι : Type u_1
M : ι → Type u_2
inst✝² : (i : ι) → Monoid (M i)
N : Type ?u.406645
inst✝¹ : Monoid N
inst✝ : (i : ι) → DecidableEq (M i)
i : ι
m : M i
w : Word M
h : fstIdx w ≠ some i
m' : M i
w' : Word M
h' : fstIdx w' ≠ some i
he : rcons { head := m, tail := w, fstIdx_ne := h } = rcons { head := m', tail := w', fstIdx_ne := h' }
hm : m = 1
hm' : ¬m' = 1
⊢ { head := m, tail := w, fstIdx_ne := h } = { head := m', tail := w', fstIdx_ne := h' }

tactic: simp only [rcons, dif_pos hm, dif_neg hm'] at he
state_before: case neg.h
ι : Type u_1
M : ι → Type u_2
inst✝² : (i : ι) → Monoid (M i)
N : Type ?u.406645
inst✝¹ : Monoid N
inst✝ : (i : ι) → DecidableEq (M i)
i : ι
m : M i
w : Word M
h : fstIdx w ≠ some i
m' : M i
w' : Word M
h' : fstIdx w' ≠ some i
he : rcons { head := m, tail := w, fstIdx_ne := h } = rcons { head := m', tail := w', fstIdx_ne := h' }
hm : m = 1
hm' : ¬m' = 1
⊢ False

tactic: rw [he] at h
state_before: case neg.h
ι : Type u_1
M : ι → Type u_2
inst✝² : (i : ι) → Monoid (M i)
N : Type ?u.406645
inst✝¹ : Monoid N
inst✝ : (i : ι) → DecidableEq (M i)
i : ι
m : M i
w : Word M
h : fstIdx w ≠ some i
m' : M i
w' : Word M
h' : fstIdx w' ≠ some i
hm : m = 1
hm' : ¬m' = 1
he :
  w =
    { toList := { fst := i, snd := m' } :: w'.toList,
      ne_one :=
        (_ :
          ∀ (l : (i : ι) × M i),
            l ∈
                { fst := i, snd := { head := m', tail := w', fstIdx_ne := h' }.head } ::
                  { head := m', tail := w', fstIdx_ne := h' }.tail.toList →
              l.snd ≠ 1),
      chain_ne :=
        (_ :
          List.Chain' (fun l l' => l.fst ≠ l'.fst)
            ({ fst := i, snd := { head := m', tail := w', fstIdx_ne := h' }.head } ::
              { head := m', tail := w', fstIdx_ne := h' }.tail.toList)) }
⊢ False

tactic: exact h rfl
state_before: case neg.h
ι : Type u_1
M : ι → Type u_2
inst✝² : (i : ι) → Monoid (M i)
N : Type ?u.406645
inst✝¹ : Monoid N
inst✝ : (i : ι) → DecidableEq (M i)
i : ι
m : M i
w : Word M
m' : M i
w' : Word M
h' : fstIdx w' ≠ some i
hm : m = 1
hm' : ¬m' = 1
h :
  fstIdx
      { toList := { fst := i, snd := m' } :: w'.toList,
        ne_one :=
          (_ :
            ∀ (l : (i : ι) × M i),
              l ∈
                  { fst := i, snd := { head := m', tail := w', fstIdx_ne := h' }.head } ::
                    { head := m', tail := w', fstIdx_ne := h' }.tail.toList →
                l.snd ≠ 1),
        chain_ne :=
          (_ :
            List.Chain' (fun l l' => l.fst ≠ l'.fst)
              ({ fst := i, snd := { head := m', tail := w', fstIdx_ne := h' }.head } ::
                { head := m', tail := w', fstIdx_ne := h' }.tail.toList)) } ≠
    some i
he :
  w =
    { toList := { fst := i, snd := m' } :: w'.toList,
      ne_one :=
        (_ :
          ∀ (l : (i : ι) × M i),
            l ∈
                { fst := i, snd := { head := m', tail := w', fstIdx_ne := h' }.head } ::
                  { head := m', tail := w', fstIdx_ne := h' }.tail.toList →
              l.snd ≠ 1),
      chain_ne :=
        (_ :
          List.Chain' (fun l l' => l.fst ≠ l'.fst)
            ({ fst := i, snd := { head := m', tail := w', fstIdx_ne := h' }.head } ::
              { head := m', tail := w', fstIdx_ne := h' }.tail.toList)) }
⊢ False

tactic: exfalso
state_before: case pos
ι : Type u_1
M : ι → Type u_2
inst✝² : (i : ι) → Monoid (M i)
N : Type ?u.406645
inst✝¹ : Monoid N
inst✝ : (i : ι) → DecidableEq (M i)
i : ι
m : M i
w : Word M
h : fstIdx w ≠ some i
m' : M i
w' : Word M
h' : fstIdx w' ≠ some i
he : rcons { head := m, tail := w, fstIdx_ne := h } = rcons { head := m', tail := w', fstIdx_ne := h' }
hm : ¬m = 1
hm' : m' = 1
⊢ { head := m, tail := w, fstIdx_ne := h } = { head := m', tail := w', fstIdx_ne := h' }

tactic: simp only [rcons, dif_pos hm', dif_neg hm] at he
state_before: case pos.h
ι : Type u_1
M : ι → Type u_2
inst✝² : (i : ι) → Monoid (M i)
N : Type ?u.406645
inst✝¹ : Monoid N
inst✝ : (i : ι) → DecidableEq (M i)
i : ι
m : M i
w : Word M
h : fstIdx w ≠ some i
m' : M i
w' : Word M
h' : fstIdx w' ≠ some i
he : rcons { head := m, tail := w, fstIdx_ne := h } = rcons { head := m', tail := w', fstIdx_ne := h' }
hm : ¬m = 1
hm' : m' = 1
⊢ False

tactic: rw [← he] at h'
state_before: case pos.h
ι : Type u_1
M : ι → Type u_2
inst✝² : (i : ι) → Monoid (M i)
N : Type ?u.406645
inst✝¹ : Monoid N
inst✝ : (i : ι) → DecidableEq (M i)
i : ι
m : M i
w : Word M
h : fstIdx w ≠ some i
m' : M i
w' : Word M
h' : fstIdx w' ≠ some i
hm : ¬m = 1
hm' : m' = 1
he :
  { toList := { fst := i, snd := m } :: w.toList,
      ne_one :=
        (_ :
          ∀ (l : (i : ι) × M i),
            l ∈
                { fst := i, snd := { head := m, tail := w, fstIdx_ne := h }.head } ::
                  { head := m, tail := w, fstIdx_ne := h }.tail.toList →
              l.snd ≠ 1),
      chain_ne :=
        (_ :
          List.Chain' (fun l l' => l.fst ≠ l'.fst)
            ({ fst := i, snd := { head := m, tail := w, fstIdx_ne := h }.head } ::
              { head := m, tail := w, fstIdx_ne := h }.tail.toList)) } =
    w'
⊢ False

tactic: exact h' rfl
state_before: case pos.h
ι : Type u_1
M : ι → Type u_2
inst✝² : (i : ι) → Monoid (M i)
N : Type ?u.406645
inst✝¹ : Monoid N
inst✝ : (i : ι) → DecidableEq (M i)
i : ι
m : M i
w : Word M
h : fstIdx w ≠ some i
m' : M i
w' : Word M
hm : ¬m = 1
h' :
  fstIdx
      { toList := { fst := i, snd := m } :: w.toList,
        ne_one :=
          (_ :
            ∀ (l : (i : ι) × M i),
              l ∈
                  { fst := i, snd := { head := m, tail := w, fstIdx_ne := h }.head } ::
                    { head := m, tail := w, fstIdx_ne := h }.tail.toList →
                l.snd ≠ 1),
        chain_ne :=
          (_ :
            List.Chain' (fun l l' => l.fst ≠ l'.fst)
              ({ fst := i, snd := { head := m, tail := w, fstIdx_ne := h }.head } ::
                { head := m, tail := w, fstIdx_ne := h }.tail.toList)) } ≠
    some i
hm' : m' = 1
he :
  { toList := { fst := i, snd := m } :: w.toList,
      ne_one :=
        (_ :
          ∀ (l : (i : ι) × M i),
            l ∈
                { fst := i, snd := { head := m, tail := w, fstIdx_ne := h }.head } ::
                  { head := m, tail := w, fstIdx_ne := h }.tail.toList →
              l.snd ≠ 1),
      chain_ne :=
        (_ :
          List.Chain' (fun l l' => l.fst ≠ l'.fst)
            ({ fst := i, snd := { head := m, tail := w, fstIdx_ne := h }.head } ::
              { head := m, tail := w, fstIdx_ne := h }.tail.toList)) } =
    w'
⊢ False

tactic: have : m = m' ∧ w.toList = w'.toList := by
  simpa [rcons, dif_neg hm, dif_neg hm', true_and_iff, eq_self_iff_true, Subtype.mk_eq_mk,
    heq_iff_eq, ← Subtype.ext_iff_val] using he
state_before: case neg
ι : Type u_1
M : ι → Type u_2
inst✝² : (i : ι) → Monoid (M i)
N : Type ?u.406645
inst✝¹ : Monoid N
inst✝ : (i : ι) → DecidableEq (M i)
i : ι
m : M i
w : Word M
h : fstIdx w ≠ some i
m' : M i
w' : Word M
h' : fstIdx w' ≠ some i
he : rcons { head := m, tail := w, fstIdx_ne := h } = rcons { head := m', tail := w', fstIdx_ne := h' }
hm : ¬m = 1
hm' : ¬m' = 1
⊢ { head := m, tail := w, fstIdx_ne := h } = { head := m', tail := w', fstIdx_ne := h' }

tactic: rcases this with ⟨rfl, h⟩
state_before: case neg
ι : Type u_1
M : ι → Type u_2
inst✝² : (i : ι) → Monoid (M i)
N : Type ?u.406645
inst✝¹ : Monoid N
inst✝ : (i : ι) → DecidableEq (M i)
i : ι
m : M i
w : Word M
h : fstIdx w ≠ some i
m' : M i
w' : Word M
h' : fstIdx w' ≠ some i
he : rcons { head := m, tail := w, fstIdx_ne := h } = rcons { head := m', tail := w', fstIdx_ne := h' }
hm : ¬m = 1
hm' : ¬m' = 1
this : m = m' ∧ w.toList = w'.toList
⊢ { head := m, tail := w, fstIdx_ne := h } = { head := m', tail := w', fstIdx_ne := h' }

tactic: congr
state_before: case neg.intro
ι : Type u_1
M : ι → Type u_2
inst✝² : (i : ι) → Monoid (M i)
N : Type ?u.406645
inst✝¹ : Monoid N
inst✝ : (i : ι) → DecidableEq (M i)
i : ι
m : M i
w : Word M
h✝ : fstIdx w ≠ some i
w' : Word M
h' : fstIdx w' ≠ some i
hm : ¬m = 1
h : w.toList = w'.toList
he : rcons { head := m, tail := w, fstIdx_ne := h✝ } = rcons { head := m, tail := w', fstIdx_ne := h' }
hm' : ¬m = 1
⊢ { head := m, tail := w, fstIdx_ne := h✝ } = { head := m, tail := w', fstIdx_ne := h' }

tactic: exact Word.ext _ _ h
state_before: case neg.intro.e_tail
ι : Type u_1
M : ι → Type u_2
inst✝² : (i : ι) → Monoid (M i)
N : Type ?u.406645
inst✝¹ : Monoid N
inst✝ : (i : ι) → DecidableEq (M i)
i : ι
m : M i
w : Word M
h✝ : fstIdx w ≠ some i
w' : Word M
h' : fstIdx w' ≠ some i
hm : ¬m = 1
h : w.toList = w'.toList
he : rcons { head := m, tail := w, fstIdx_ne := h✝ } = rcons { head := m, tail := w', fstIdx_ne := h' }
hm' : ¬m = 1
⊢ w = w'

tactic: simpa [rcons, dif_neg hm, dif_neg hm', true_and_iff, eq_self_iff_true, Subtype.mk_eq_mk,
  heq_iff_eq, ← Subtype.ext_iff_val] using he
state_before: ι : Type u_1
M : ι → Type u_2
inst✝² : (i : ι) → Monoid (M i)
N : Type ?u.406645
inst✝¹ : Monoid N
inst✝ : (i : ι) → DecidableEq (M i)
i : ι
m : M i
w : Word M
h : fstIdx w ≠ some i
m' : M i
w' : Word M
h' : fstIdx w' ≠ some i
he : rcons { head := m, tail := w, fstIdx_ne := h } = rcons { head := m', tail := w', fstIdx_ne := h' }
hm : ¬m = 1
hm' : ¬m' = 1
⊢ m = m' ∧ w.toList = w'.toList