l3lab/ntp-mathlib huggingface dataset:
theorem pred_ok (q₁ q₂ s v) (c d : List Γ') : ∃ s',
    Reaches₁ (TM2.step tr) ⟨some (Λ'.pred q₁ q₂), s, K'.elim (trList v) [] c d⟩
      (v.headI.rec ⟨some q₁, s', K'.elim (trList v.tail) [] c d⟩ fun n _ =>
        ⟨some q₂, s', K'.elim (trList (n::v.tail)) [] c d⟩) := by
  rcases v with (_ | ⟨_ | n, v⟩)
  · refine' ⟨none, TransGen.single _⟩
    simp
    rfl
  · refine' ⟨some Γ'.cons, TransGen.single _⟩
    simp
  refine' ⟨none, _⟩
  simp only [TM2.step, trList, trNat._eq_1, trNum, Nat.cast_succ, Num.add_one, Num.succ,
    List.tail_cons, List.headI_cons]
  cases' (n : Num) with a
  · simp [trPosNum, trNum, show Num.zero.succ' = PosNum.one from rfl]
    refine' TransGen.head rfl _
    simp only [Option.mem_def, TM2.stepAux, elim_main, List.head?_cons, Option.some.injEq,
      decide_False, List.tail_cons, elim_update_main, ne_eq, Function.update_noteq, elim_rev,
      elim_update_rev, natEnd, Function.update_same,  cond_true, cond_false]
    convert unrev_ok using 2
    simp
  

Proof state:
case cons.succ.pos
q₁ q₂ : Λ'
s : Option Γ'
c d : List Γ'
v : List ℕ
n : ℕ
a : PosNum
⊢ Reaches₁ (TM2.step tr)
    { l := some (Λ'.pred q₁ q₂), var := s,
      stk := elim (trPosNum (Num.succ' (Num.pos a)) ++ Γ'.cons :: trList v) [] c d }
    { l := some q₂, var := none,
      stk :=
        elim
          ((match Num.pos a with
            | Num.zero => []
            | Num.pos n => trPosNum n) ++
            Γ'.cons :: trList v)
          [] c d }

Next tactic:
simp only [Num.succ']
theorem pred_ok (q₁ q₂ s v) (c d : List Γ') : ∃ s',
    Reaches₁ (TM2.step tr) ⟨some (Λ'.pred q₁ q₂), s, K'.elim (trList v) [] c d⟩
      (v.headI.rec ⟨some q₁, s', K'.elim (trList v.tail) [] c d⟩ fun n _ =>
        ⟨some q₂, s', K'.elim (trList (n::v.tail)) [] c d⟩) := by
  rcases v with (_ | ⟨_ | n, v⟩)
  · refine' ⟨none, TransGen.single _⟩
    simp
    rfl
  · refine' ⟨some Γ'.cons, TransGen.single _⟩
    simp
  refine' ⟨none, _⟩
  simp only [TM2.step, trList, trNat._eq_1, trNum, Nat.cast_succ, Num.add_one, Num.succ,
    List.tail_cons, List.headI_cons]
  cases' (n : Num) with a
  · simp [trPosNum, trNum, show Num.zero.succ' = PosNum.one from rfl]
    refine' TransGen.head rfl _
    simp only [Option.mem_def, TM2.stepAux, elim_main, List.head?_cons, Option.some.injEq,
      decide_False, List.tail_cons, elim_update_main, ne_eq, Function.update_noteq, elim_rev,
      elim_update_rev, natEnd, Function.update_same,  cond_true, cond_false]
    convert unrev_ok using 2
    simp
  simp only [Num.succ']
  

Proof state:
case cons.succ.pos
q₁ q₂ : Λ'
s : Option Γ'
c d : List Γ'
v : List ℕ
n : ℕ
a : PosNum
⊢ Reaches₁ (TM2.step tr)
    { l := some (Λ'.pred q₁ q₂), var := s, stk := elim (trPosNum (PosNum.succ a) ++ Γ'.cons :: trList v) [] c d }
    { l := some q₂, var := none, stk := elim (trPosNum a ++ Γ'.cons :: trList v) [] c d }

Next tactic:
suffices ∀ l₁, ∃ l₁' l₂' s',
    List.reverseAux l₁ (trPosNum a) = List.reverseAux l₁' l₂' ∧
      Reaches₁ (TM2.step tr)
        ⟨some (q₁.pred q₂), s, K'.elim (trPosNum a.succ ++ Γ'.cons :: trList v) l₁ c d⟩
        ⟨some (unrev q₂), s', K'.elim (l₂' ++ Γ'.cons :: trList v) l₁' c d⟩ by
    obtain ⟨l₁', l₂', s', e, h⟩ := this []
    simp only [List.reverseAux] at e
    refine' h.trans _
    convert unrev_ok using 2
    simp [e, List.reverseAux_eq]
theorem pred_ok (q₁ q₂ s v) (c d : List Γ') : ∃ s',
    Reaches₁ (TM2.step tr) ⟨some (Λ'.pred q₁ q₂), s, K'.elim (trList v) [] c d⟩
      (v.headI.rec ⟨some q₁, s', K'.elim (trList v.tail) [] c d⟩ fun n _ =>
        ⟨some q₂, s', K'.elim (trList (n::v.tail)) [] c d⟩) := by
  rcases v with (_ | ⟨_ | n, v⟩)
  · refine' ⟨none, TransGen.single _⟩
    simp
    rfl
  · refine' ⟨some Γ'.cons, TransGen.single _⟩
    simp
  refine' ⟨none, _⟩
  simp only [TM2.step, trList, trNat._eq_1, trNum, Nat.cast_succ, Num.add_one, Num.succ,
    List.tail_cons, List.headI_cons]
  cases' (n : Num) with a
  · simp [trPosNum, trNum, show Num.zero.succ' = PosNum.one from rfl]
    refine' TransGen.head rfl _
    simp only [Option.mem_def, TM2.stepAux, elim_main, List.head?_cons, Option.some.injEq,
      decide_False, List.tail_cons, elim_update_main, ne_eq, Function.update_noteq, elim_rev,
      elim_update_rev, natEnd, Function.update_same,  cond_true, cond_false]
    convert unrev_ok using 2
    simp
  simp only [Num.succ']
  suffices ∀ l₁, ∃ l₁' l₂' s',
    List.reverseAux l₁ (trPosNum a) = List.reverseAux l₁' l₂' ∧
      Reaches₁ (TM2.step tr)
        ⟨some (q₁.pred q₂), s, K'.elim (trPosNum a.succ ++ Γ'.cons :: trList v) l₁ c d⟩
        ⟨some (unrev q₂), s', K'.elim (l₂' ++ Γ'.cons :: trList v) l₁' c d⟩ by
    

Proof state:
q₁ q₂ : Λ'
s : Option Γ'
c d : List Γ'
v : List ℕ
n : ℕ
a : PosNum
this :
  ∀ (l₁ : List Γ'),
    ∃ l₁' l₂' s',
      List.reverseAux l₁ (trPosNum a) = List.reverseAux l₁' l₂' ∧
        Reaches₁ (TM2.step tr)
          { l := some (Λ'.pred q₁ q₂), var := s, stk := elim (trPosNum (PosNum.succ a) ++ Γ'.cons :: trList v) l₁ c d }
          { l := some (unrev q₂), var := s', stk := elim (l₂' ++ Γ'.cons :: trList v) l₁' c d }
⊢ Reaches₁ (TM2.step tr)
    { l := some (Λ'.pred q₁ q₂), var := s, stk := elim (trPosNum (PosNum.succ a) ++ Γ'.cons :: trList v) [] c d }
    { l := some q₂, var := none, stk := elim (trPosNum a ++ Γ'.cons :: trList v) [] c d }

Next tactic:
obtain ⟨l₁', l₂', s', e, h⟩ := this []
theorem pred_ok (q₁ q₂ s v) (c d : List Γ') : ∃ s',
    Reaches₁ (TM2.step tr) ⟨some (Λ'.pred q₁ q₂), s, K'.elim (trList v) [] c d⟩
      (v.headI.rec ⟨some q₁, s', K'.elim (trList v.tail) [] c d⟩ fun n _ =>
        ⟨some q₂, s', K'.elim (trList (n::v.tail)) [] c d⟩) := by
  rcases v with (_ | ⟨_ | n, v⟩)
  · refine' ⟨none, TransGen.single _⟩
    simp
    rfl
  · refine' ⟨some Γ'.cons, TransGen.single _⟩
    simp
  refine' ⟨none, _⟩
  simp only [TM2.step, trList, trNat._eq_1, trNum, Nat.cast_succ, Num.add_one, Num.succ,
    List.tail_cons, List.headI_cons]
  cases' (n : Num) with a
  · simp [trPosNum, trNum, show Num.zero.succ' = PosNum.one from rfl]
    refine' TransGen.head rfl _
    simp only [Option.mem_def, TM2.stepAux, elim_main, List.head?_cons, Option.some.injEq,
      decide_False, List.tail_cons, elim_update_main, ne_eq, Function.update_noteq, elim_rev,
      elim_update_rev, natEnd, Function.update_same,  cond_true, cond_false]
    convert unrev_ok using 2
    simp
  simp only [Num.succ']
  suffices ∀ l₁, ∃ l₁' l₂' s',
    List.reverseAux l₁ (trPosNum a) = List.reverseAux l₁' l₂' ∧
      Reaches₁ (TM2.step tr)
        ⟨some (q₁.pred q₂), s, K'.elim (trPosNum a.succ ++ Γ'.cons :: trList v) l₁ c d⟩
        ⟨some (unrev q₂), s', K'.elim (l₂' ++ Γ'.cons :: trList v) l₁' c d⟩ by
    obtain ⟨l₁', l₂', s', e, h⟩ := this []
    

Proof state:
case intro.intro.intro.intro
q₁ q₂ : Λ'
s : Option Γ'
c d : List Γ'
v : List ℕ
n : ℕ
a : PosNum
this :
  ∀ (l₁ : List Γ'),
    ∃ l₁' l₂' s',
      List.reverseAux l₁ (trPosNum a) = List.reverseAux l₁' l₂' ∧
        Reaches₁ (TM2.step tr)
          { l := some (Λ'.pred q₁ q₂), var := s, stk := elim (trPosNum (PosNum.succ a) ++ Γ'.cons :: trList v) l₁ c d }
          { l := some (unrev q₂), var := s', stk := elim (l₂' ++ Γ'.cons :: trList v) l₁' c d }
l₁' l₂' : List Γ'
s' : Option Γ'
e : List.reverseAux [] (trPosNum a) = List.reverseAux l₁' l₂'
h :
  Reaches₁ (TM2.step tr)
    { l := some (Λ'.pred q₁ q₂), var := s, stk := elim (trPosNum (PosNum.succ a) ++ Γ'.cons :: trList v) [] c d }
    { l := some (unrev q₂), var := s', stk := elim (l₂' ++ Γ'.cons :: trList v) l₁' c d }
⊢ Reaches₁ (TM2.step tr)
    { l := some (Λ'.pred q₁ q₂), var := s, stk := elim (trPosNum (PosNum.succ a) ++ Γ'.cons :: trList v) [] c d }
    { l := some q₂, var := none, stk := elim (trPosNum a ++ Γ'.cons :: trList v) [] c d }

Next tactic:
simp only [List.reverseAux] at e
theorem pred_ok (q₁ q₂ s v) (c d : List Γ') : ∃ s',
    Reaches₁ (TM2.step tr) ⟨some (Λ'.pred q₁ q₂), s, K'.elim (trList v) [] c d⟩
      (v.headI.rec ⟨some q₁, s', K'.elim (trList v.tail) [] c d⟩ fun n _ =>
        ⟨some q₂, s', K'.elim (trList (n::v.tail)) [] c d⟩) := by
  rcases v with (_ | ⟨_ | n, v⟩)
  · refine' ⟨none, TransGen.single _⟩
    simp
    rfl
  · refine' ⟨some Γ'.cons, TransGen.single _⟩
    simp
  refine' ⟨none, _⟩
  simp only [TM2.step, trList, trNat._eq_1, trNum, Nat.cast_succ, Num.add_one, Num.succ,
    List.tail_cons, List.headI_cons]
  cases' (n : Num) with a
  · simp [trPosNum, trNum, show Num.zero.succ' = PosNum.one from rfl]
    refine' TransGen.head rfl _
    simp only [Option.mem_def, TM2.stepAux, elim_main, List.head?_cons, Option.some.injEq,
      decide_False, List.tail_cons, elim_update_main, ne_eq, Function.update_noteq, elim_rev,
      elim_update_rev, natEnd, Function.update_same,  cond_true, cond_false]
    convert unrev_ok using 2
    simp
  simp only [Num.succ']
  suffices ∀ l₁, ∃ l₁' l₂' s',
    List.reverseAux l₁ (trPosNum a) = List.reverseAux l₁' l₂' ∧
      Reaches₁ (TM2.step tr)
        ⟨some (q₁.pred q₂), s, K'.elim (trPosNum a.succ ++ Γ'.cons :: trList v) l₁ c d⟩
        ⟨some (unrev q₂), s', K'.elim (l₂' ++ Γ'.cons :: trList v) l₁' c d⟩ by
    obtain ⟨l₁', l₂', s', e, h⟩ := this []
    simp only [List.reverseAux] at e
    

Proof state:
case intro.intro.intro.intro
q₁ q₂ : Λ'
s : Option Γ'
c d : List Γ'
v : List ℕ
n : ℕ
a : PosNum
this :
  ∀ (l₁ : List Γ'),
    ∃ l₁' l₂' s',
      List.reverseAux l₁ (trPosNum a) = List.reverseAux l₁' l₂' ∧
        Reaches₁ (TM2.step tr)
          { l := some (Λ'.pred q₁ q₂), var := s, stk := elim (trPosNum (PosNum.succ a) ++ Γ'.cons :: trList v) l₁ c d }
          { l := some (unrev q₂), var := s', stk := elim (l₂' ++ Γ'.cons :: trList v) l₁' c d }
l₁' l₂' : List Γ'
s' : Option Γ'
e : trPosNum a = List.reverseAux l₁' l₂'
h :
  Reaches₁ (TM2.step tr)
    { l := some (Λ'.pred q₁ q₂), var := s, stk := elim (trPosNum (PosNum.succ a) ++ Γ'.cons :: trList v) [] c d }
    { l := some (unrev q₂), var := s', stk := elim (l₂' ++ Γ'.cons :: trList v) l₁' c d }
⊢ Reaches₁ (TM2.step tr)
    { l := some (Λ'.pred q₁ q₂), var := s, stk := elim (trPosNum (PosNum.succ a) ++ Γ'.cons :: trList v) [] c d }
    { l := some q₂, var := none, stk := elim (trPosNum a ++ Γ'.cons :: trList v) [] c d }

Next tactic:
refine' h.trans _
theorem pred_ok (q₁ q₂ s v) (c d : List Γ') : ∃ s',
    Reaches₁ (TM2.step tr) ⟨some (Λ'.pred q₁ q₂), s, K'.elim (trList v) [] c d⟩
      (v.headI.rec ⟨some q₁, s', K'.elim (trList v.tail) [] c d⟩ fun n _ =>
        ⟨some q₂, s', K'.elim (trList (n::v.tail)) [] c d⟩) := by
  rcases v with (_ | ⟨_ | n, v⟩)
  · refine' ⟨none, TransGen.single _⟩
    simp
    rfl
  · refine' ⟨some Γ'.cons, TransGen.single _⟩
    simp
  refine' ⟨none, _⟩
  simp only [TM2.step, trList, trNat._eq_1, trNum, Nat.cast_succ, Num.add_one, Num.succ,
    List.tail_cons, List.headI_cons]
  cases' (n : Num) with a
  · simp [trPosNum, trNum, show Num.zero.succ' = PosNum.one from rfl]
    refine' TransGen.head rfl _
    simp only [Option.mem_def, TM2.stepAux, elim_main, List.head?_cons, Option.some.injEq,
      decide_False, List.tail_cons, elim_update_main, ne_eq, Function.update_noteq, elim_rev,
      elim_update_rev, natEnd, Function.update_same,  cond_true, cond_false]
    convert unrev_ok using 2
    simp
  simp only [Num.succ']
  suffices ∀ l₁, ∃ l₁' l₂' s',
    List.reverseAux l₁ (trPosNum a) = List.reverseAux l₁' l₂' ∧
      Reaches₁ (TM2.step tr)
        ⟨some (q₁.pred q₂), s, K'.elim (trPosNum a.succ ++ Γ'.cons :: trList v) l₁ c d⟩
        ⟨some (unrev q₂), s', K'.elim (l₂' ++ Γ'.cons :: trList v) l₁' c d⟩ by
    obtain ⟨l₁', l₂', s', e, h⟩ := this []
    simp only [List.reverseAux] at e
    refine' h.trans _
    

Proof state:
case intro.intro.intro.intro
q₁ q₂ : Λ'
s : Option Γ'
c d : List Γ'
v : List ℕ
n : ℕ
a : PosNum
this :
  ∀ (l₁ : List Γ'),
    ∃ l₁' l₂' s',
      List.reverseAux l₁ (trPosNum a) = List.reverseAux l₁' l₂' ∧
        Reaches₁ (TM2.step tr)
          { l := some (Λ'.pred q₁ q₂), var := s, stk := elim (trPosNum (PosNum.succ a) ++ Γ'.cons :: trList v) l₁ c d }
          { l := some (unrev q₂), var := s', stk := elim (l₂' ++ Γ'.cons :: trList v) l₁' c d }
l₁' l₂' : List Γ'
s' : Option Γ'
e : trPosNum a = List.reverseAux l₁' l₂'
h :
  Reaches₁ (TM2.step tr)
    { l := some (Λ'.pred q₁ q₂), var := s, stk := elim (trPosNum (PosNum.succ a) ++ Γ'.cons :: trList v) [] c d }
    { l := some (unrev q₂), var := s', stk := elim (l₂' ++ Γ'.cons :: trList v) l₁' c d }
⊢ TransGen (fun a b => b ∈ TM2.step tr a)
    { l := some (unrev q₂), var := s', stk := elim (l₂' ++ Γ'.cons :: trList v) l₁' c d }
    { l := some q₂, var := none, stk := elim (trPosNum a ++ Γ'.cons :: trList v) [] c d }

Next tactic:
convert unrev_ok using 2
theorem pred_ok (q₁ q₂ s v) (c d : List Γ') : ∃ s',
    Reaches₁ (TM2.step tr) ⟨some (Λ'.pred q₁ q₂), s, K'.elim (trList v) [] c d⟩
      (v.headI.rec ⟨some q₁, s', K'.elim (trList v.tail) [] c d⟩ fun n _ =>
        ⟨some q₂, s', K'.elim (trList (n::v.tail)) [] c d⟩) := by
  rcases v with (_ | ⟨_ | n, v⟩)
  · refine' ⟨none, TransGen.single _⟩
    simp
    rfl
  · refine' ⟨some Γ'.cons, TransGen.single _⟩
    simp
  refine' ⟨none, _⟩
  simp only [TM2.step, trList, trNat._eq_1, trNum, Nat.cast_succ, Num.add_one, Num.succ,
    List.tail_cons, List.headI_cons]
  cases' (n : Num) with a
  · simp [trPosNum, trNum, show Num.zero.succ' = PosNum.one from rfl]
    refine' TransGen.head rfl _
    simp only [Option.mem_def, TM2.stepAux, elim_main, List.head?_cons, Option.some.injEq,
      decide_False, List.tail_cons, elim_update_main, ne_eq, Function.update_noteq, elim_rev,
      elim_update_rev, natEnd, Function.update_same,  cond_true, cond_false]
    convert unrev_ok using 2
    simp
  simp only [Num.succ']
  suffices ∀ l₁, ∃ l₁' l₂' s',
    List.reverseAux l₁ (trPosNum a) = List.reverseAux l₁' l₂' ∧
      Reaches₁ (TM2.step tr)
        ⟨some (q₁.pred q₂), s, K'.elim (trPosNum a.succ ++ Γ'.cons :: trList v) l₁ c d⟩
        ⟨some (unrev q₂), s', K'.elim (l₂' ++ Γ'.cons :: trList v) l₁' c d⟩ by
    obtain ⟨l₁', l₂', s', e, h⟩ := this []
    simp only [List.reverseAux] at e
    refine' h.trans _
    convert unrev_ok using 2
    

Proof state:
case h.e'_2.h.e'_7
q₁ q₂ : Λ'
s : Option Γ'
c d : List Γ'
v : List ℕ
n : ℕ
a : PosNum
this :
  ∀ (l₁ : List Γ'),
    ∃ l₁' l₂' s',
      List.reverseAux l₁ (trPosNum a) = List.reverseAux l₁' l₂' ∧
        Reaches₁ (TM2.step tr)
          { l := some (Λ'.pred q₁ q₂), var := s, stk := elim (trPosNum (PosNum.succ a) ++ Γ'.cons :: trList v) l₁ c d }
          { l := some (unrev q₂), var := s', stk := elim (l₂' ++ Γ'.cons :: trList v) l₁' c d }
l₁' l₂' : List Γ'
s' : Option Γ'
e : trPosNum a = List.reverseAux l₁' l₂'
h :
  Reaches₁ (TM2.step tr)
    { l := some (Λ'.pred q₁ q₂), var := s, stk := elim (trPosNum (PosNum.succ a) ++ Γ'.cons :: trList v) [] c d }
    { l := some (unrev q₂), var := s', stk := elim (l₂' ++ Γ'.cons :: trList v) l₁' c d }
⊢ elim (trPosNum a ++ Γ'.cons :: trList v) [] c d =
    update (update (elim (l₂' ++ Γ'.cons :: trList v) l₁' c d) rev []) main
      (List.reverseAux (elim (l₂' ++ Γ'.cons :: trList v) l₁' c d rev) (elim (l₂' ++ Γ'.cons :: trList v) l₁' c d main))

Next tactic:
simp [e, List.reverseAux_eq]
theorem pred_ok (q₁ q₂ s v) (c d : List Γ') : ∃ s',
    Reaches₁ (TM2.step tr) ⟨some (Λ'.pred q₁ q₂), s, K'.elim (trList v) [] c d⟩
      (v.headI.rec ⟨some q₁, s', K'.elim (trList v.tail) [] c d⟩ fun n _ =>
        ⟨some q₂, s', K'.elim (trList (n::v.tail)) [] c d⟩) := by
  rcases v with (_ | ⟨_ | n, v⟩)
  · refine' ⟨none, TransGen.single _⟩
    simp
    rfl
  · refine' ⟨some Γ'.cons, TransGen.single _⟩
    simp
  refine' ⟨none, _⟩
  simp only [TM2.step, trList, trNat._eq_1, trNum, Nat.cast_succ, Num.add_one, Num.succ,
    List.tail_cons, List.headI_cons]
  cases' (n : Num) with a
  · simp [trPosNum, trNum, show Num.zero.succ' = PosNum.one from rfl]
    refine' TransGen.head rfl _
    simp only [Option.mem_def, TM2.stepAux, elim_main, List.head?_cons, Option.some.injEq,
      decide_False, List.tail_cons, elim_update_main, ne_eq, Function.update_noteq, elim_rev,
      elim_update_rev, natEnd, Function.update_same,  cond_true, cond_false]
    convert unrev_ok using 2
    simp
  simp only [Num.succ']
  suffices ∀ l₁, ∃ l₁' l₂' s',
    List.reverseAux l₁ (trPosNum a) = List.reverseAux l₁' l₂' ∧
      Reaches₁ (TM2.step tr)
        ⟨some (q₁.pred q₂), s, K'.elim (trPosNum a.succ ++ Γ'.cons :: trList v) l₁ c d⟩
        ⟨some (unrev q₂), s', K'.elim (l₂' ++ Γ'.cons :: trList v) l₁' c d⟩ by
    obtain ⟨l₁', l₂', s', e, h⟩ := this []
    simp only [List.reverseAux] at e
    refine' h.trans _
    convert unrev_ok using 2
    simp [e, List.reverseAux_eq]
  

Proof state:
case cons.succ.pos
q₁ q₂ : Λ'
s : Option Γ'
c d : List Γ'
v : List ℕ
n : ℕ
a : PosNum
⊢ ∀ (l₁ : List Γ'),
    ∃ l₁' l₂' s',
      List.reverseAux l₁ (trPosNum a) = List.reverseAux l₁' l₂' ∧
        Reaches₁ (TM2.step tr)
          { l := some (Λ'.pred q₁ q₂), var := s, stk := elim (trPosNum (PosNum.succ a) ++ Γ'.cons :: trList v) l₁ c d }
          { l := some (unrev q₂), var := s', stk := elim (l₂' ++ Γ'.cons :: trList v) l₁' c d }

Next tactic:
induction' a with m IH m IH generalizing s
theorem pred_ok (q₁ q₂ s v) (c d : List Γ') : ∃ s',
    Reaches₁ (TM2.step tr) ⟨some (Λ'.pred q₁ q₂), s, K'.elim (trList v) [] c d⟩
      (v.headI.rec ⟨some q₁, s', K'.elim (trList v.tail) [] c d⟩ fun n _ =>
        ⟨some q₂, s', K'.elim (trList (n::v.tail)) [] c d⟩) := by
  rcases v with (_ | ⟨_ | n, v⟩)
  · refine' ⟨none, TransGen.single _⟩
    simp
    rfl
  · refine' ⟨some Γ'.cons, TransGen.single _⟩
    simp
  refine' ⟨none, _⟩
  simp only [TM2.step, trList, trNat._eq_1, trNum, Nat.cast_succ, Num.add_one, Num.succ,
    List.tail_cons, List.headI_cons]
  cases' (n : Num) with a
  · simp [trPosNum, trNum, show Num.zero.succ' = PosNum.one from rfl]
    refine' TransGen.head rfl _
    simp only [Option.mem_def, TM2.stepAux, elim_main, List.head?_cons, Option.some.injEq,
      decide_False, List.tail_cons, elim_update_main, ne_eq, Function.update_noteq, elim_rev,
      elim_update_rev, natEnd, Function.update_same,  cond_true, cond_false]
    convert unrev_ok using 2
    simp
  simp only [Num.succ']
  suffices ∀ l₁, ∃ l₁' l₂' s',
    List.reverseAux l₁ (trPosNum a) = List.reverseAux l₁' l₂' ∧
      Reaches₁ (TM2.step tr)
        ⟨some (q₁.pred q₂), s, K'.elim (trPosNum a.succ ++ Γ'.cons :: trList v) l₁ c d⟩
        ⟨some (unrev q₂), s', K'.elim (l₂' ++ Γ'.cons :: trList v) l₁' c d⟩ by
    obtain ⟨l₁', l₂', s', e, h⟩ := this []
    simp only [List.reverseAux] at e
    refine' h.trans _
    convert unrev_ok using 2
    simp [e, List.reverseAux_eq]
  induction' a with m IH m IH generalizing s <;> 

Proof state:
case cons.succ.pos.one
q₁ q₂ : Λ'
c d : List Γ'
v : List ℕ
n : ℕ
s : Option Γ'
⊢ ∀ (l₁ : List Γ'),
    ∃ l₁' l₂' s',
      List.reverseAux l₁ (trPosNum PosNum.one) = List.reverseAux l₁' l₂' ∧
        Reaches₁ (TM2.step tr)
          { l := some (Λ'.pred q₁ q₂), var := s,
            stk := elim (trPosNum (PosNum.succ PosNum.one) ++ Γ'.cons :: trList v) l₁ c d }
          { l := some (unrev q₂), var := s', stk := elim (l₂' ++ Γ'.cons :: trList v) l₁' c d }

Next tactic:
intro l₁
theorem pred_ok (q₁ q₂ s v) (c d : List Γ') : ∃ s',
    Reaches₁ (TM2.step tr) ⟨some (Λ'.pred q₁ q₂), s, K'.elim (trList v) [] c d⟩
      (v.headI.rec ⟨some q₁, s', K'.elim (trList v.tail) [] c d⟩ fun n _ =>
        ⟨some q₂, s', K'.elim (trList (n::v.tail)) [] c d⟩) := by
  rcases v with (_ | ⟨_ | n, v⟩)
  · refine' ⟨none, TransGen.single _⟩
    simp
    rfl
  · refine' ⟨some Γ'.cons, TransGen.single _⟩
    simp
  refine' ⟨none, _⟩
  simp only [TM2.step, trList, trNat._eq_1, trNum, Nat.cast_succ, Num.add_one, Num.succ,
    List.tail_cons, List.headI_cons]
  cases' (n : Num) with a
  · simp [trPosNum, trNum, show Num.zero.succ' = PosNum.one from rfl]
    refine' TransGen.head rfl _
    simp only [Option.mem_def, TM2.stepAux, elim_main, List.head?_cons, Option.some.injEq,
      decide_False, List.tail_cons, elim_update_main, ne_eq, Function.update_noteq, elim_rev,
      elim_update_rev, natEnd, Function.update_same,  cond_true, cond_false]
    convert unrev_ok using 2
    simp
  simp only [Num.succ']
  suffices ∀ l₁, ∃ l₁' l₂' s',
    List.reverseAux l₁ (trPosNum a) = List.reverseAux l₁' l₂' ∧
      Reaches₁ (TM2.step tr)
        ⟨some (q₁.pred q₂), s, K'.elim (trPosNum a.succ ++ Γ'.cons :: trList v) l₁ c d⟩
        ⟨some (unrev q₂), s', K'.elim (l₂' ++ Γ'.cons :: trList v) l₁' c d⟩ by
    obtain ⟨l₁', l₂', s', e, h⟩ := this []
    simp only [List.reverseAux] at e
    refine' h.trans _
    convert unrev_ok using 2
    simp [e, List.reverseAux_eq]
  induction' a with m IH m IH generalizing s <;> 

Proof state:
case cons.succ.pos.bit1
q₁ q₂ : Λ'
c d : List Γ'
v : List ℕ
n : ℕ
m : PosNum
IH :
  ∀ (s : Option Γ') (l₁ : List Γ'),
    ∃ l₁' l₂' s',
      List.reverseAux l₁ (trPosNum m) = List.reverseAux l₁' l₂' ∧
        Reaches₁ (TM2.step tr)
          { l := some (Λ'.pred q₁ q₂), var := s, stk := elim (trPosNum (PosNum.succ m) ++ Γ'.cons :: trList v) l₁ c d }
          { l := some (unrev q₂), var := s', stk := elim (l₂' ++ Γ'.cons :: trList v) l₁' c d }
s : Option Γ'
⊢ ∀ (l₁ : List Γ'),
    ∃ l₁' l₂' s',
      List.reverseAux l₁ (trPosNum (PosNum.bit1 m)) = List.reverseAux l₁' l₂' ∧
        Reaches₁ (TM2.step tr)
          { l := some (Λ'.pred q₁ q₂), var := s,
            stk := elim (trPosNum (PosNum.succ (PosNum.bit1 m)) ++ Γ'.cons :: trList v) l₁ c d }
          { l := some (unrev q₂), var := s', stk := elim (l₂' ++ Γ'.cons :: trList v) l₁' c d }

Next tactic:
intro l₁
theorem pred_ok (q₁ q₂ s v) (c d : List Γ') : ∃ s',
    Reaches₁ (TM2.step tr) ⟨some (Λ'.pred q₁ q₂), s, K'.elim (trList v) [] c d⟩
      (v.headI.rec ⟨some q₁, s', K'.elim (trList v.tail) [] c d⟩ fun n _ =>
        ⟨some q₂, s', K'.elim (trList (n::v.tail)) [] c d⟩) := by
  rcases v with (_ | ⟨_ | n, v⟩)
  · refine' ⟨none, TransGen.single _⟩
    simp
    rfl
  · refine' ⟨some Γ'.cons, TransGen.single _⟩
    simp
  refine' ⟨none, _⟩
  simp only [TM2.step, trList, trNat._eq_1, trNum, Nat.cast_succ, Num.add_one, Num.succ,
    List.tail_cons, List.headI_cons]
  cases' (n : Num) with a
  · simp [trPosNum, trNum, show Num.zero.succ' = PosNum.one from rfl]
    refine' TransGen.head rfl _
    simp only [Option.mem_def, TM2.stepAux, elim_main, List.head?_cons, Option.some.injEq,
      decide_False, List.tail_cons, elim_update_main, ne_eq, Function.update_noteq, elim_rev,
      elim_update_rev, natEnd, Function.update_same,  cond_true, cond_false]
    convert unrev_ok using 2
    simp
  simp only [Num.succ']
  suffices ∀ l₁, ∃ l₁' l₂' s',
    List.reverseAux l₁ (trPosNum a) = List.reverseAux l₁' l₂' ∧
      Reaches₁ (TM2.step tr)
        ⟨some (q₁.pred q₂), s, K'.elim (trPosNum a.succ ++ Γ'.cons :: trList v) l₁ c d⟩
        ⟨some (unrev q₂), s', K'.elim (l₂' ++ Γ'.cons :: trList v) l₁' c d⟩ by
    obtain ⟨l₁', l₂', s', e, h⟩ := this []
    simp only [List.reverseAux] at e
    refine' h.trans _
    convert unrev_ok using 2
    simp [e, List.reverseAux_eq]
  induction' a with m IH m IH generalizing s <;> 

Proof state:
case cons.succ.pos.bit0
q₁ q₂ : Λ'
c d : List Γ'
v : List ℕ
n : ℕ
m : PosNum
IH :
  ∀ (s : Option Γ') (l₁ : List Γ'),
    ∃ l₁' l₂' s',
      List.reverseAux l₁ (trPosNum m) = List.reverseAux l₁' l₂' ∧
        Reaches₁ (TM2.step tr)
          { l := some (Λ'.pred q₁ q₂), var := s, stk := elim (trPosNum (PosNum.succ m) ++ Γ'.cons :: trList v) l₁ c d }
          { l := some (unrev q₂), var := s', stk := elim (l₂' ++ Γ'.cons :: trList v) l₁' c d }
s : Option Γ'
⊢ ∀ (l₁ : List Γ'),
    ∃ l₁' l₂' s',
      List.reverseAux l₁ (trPosNum (PosNum.bit0 m)) = List.reverseAux l₁' l₂' ∧
        Reaches₁ (TM2.step tr)
          { l := some (Λ'.pred q₁ q₂), var := s,
            stk := elim (trPosNum (PosNum.succ (PosNum.bit0 m)) ++ Γ'.cons :: trList v) l₁ c d }
          { l := some (unrev q₂), var := s', stk := elim (l₂' ++ Γ'.cons :: trList v) l₁' c d }

Next tactic:
intro l₁