l3lab/ntp-mathlib huggingface dataset:
theorem head_stack_ok {q s L₁ L₂ L₃} :
    Reaches₁ (TM2.step tr)
      ⟨some (head stack q), s, K'.elim (trList L₁) [] [] (trList L₂ ++ Γ'.consₗ :: L₃)⟩
      ⟨some q, none, K'.elim (trList (L₂.headI :: L₁)) [] [] L₃⟩ := by
  cases' L₂ with a L₂
  · refine'
      TransGen.trans
        (move_ok (by decide)
          (splitAtPred_eq _ _ [] (some Γ'.consₗ) L₃ (by rintro _ ⟨⟩) ⟨rfl, rfl⟩))
        (TransGen.head rfl (TransGen.head rfl _))
    simp only [TM2.step, Option.mem_def, TM2.stepAux, ite_true, id_eq, trList, List.nil_append,
      elim_update_stack, elim_rev, List.reverseAux_nil, elim_update_rev, Function.update_same,
      List.headI_nil, trNat_default]
    convert unrev_ok using 2
    simp
  · refine'
      TransGen.trans
        (move_ok (by decide)
          (splitAtPred_eq _ _ (trNat a) (some Γ'.cons) (trList L₂ ++ Γ'.consₗ :: L₃)
            (trNat_natEnd _) ⟨rfl, by simp⟩))
        (TransGen.head rfl (TransGen.head rfl _))
    

Proof state:
case cons
q : Λ'
s : Option Γ'
L₁ : List ℕ
L₃ : List Γ'
a : ℕ
L₂ : List ℕ
⊢ TransGen (fun a b => b ∈ TM2.step tr a)
    (TM2.stepAux
      (tr
        ((fun x =>
            Λ'.read fun s => ite (s = some Γ'.consₗ) id (Λ'.clear (fun x => decide (x = Γ'.consₗ)) stack) (unrev q))
          (some Γ'.cons)))
      (some Γ'.cons)
      (update
        (update
          (update (elim (trList L₁) [] [] (trList (a :: L₂) ++ Γ'.consₗ :: L₃)) stack (trList L₂ ++ Γ'.consₗ :: L₃)) rev
          (List.reverseAux (trNat a) (elim (trList L₁) [] [] (trList (a :: L₂) ++ Γ'.consₗ :: L₃) rev)))
        rev
        ((fun s => Option.iget ((fun x => some Γ'.cons) s)) (some Γ'.cons) ::
          update
            (update (elim (trList L₁) [] [] (trList (a :: L₂) ++ Γ'.consₗ :: L₃)) stack (trList L₂ ++ Γ'.consₗ :: L₃))
            rev (List.reverseAux (trNat a) (elim (trList L₁) [] [] (trList (a :: L₂) ++ Γ'.consₗ :: L₃) rev)) rev)))
    { l := some q, var := none, stk := elim (trList (List.headI (a :: L₂) :: L₁)) [] [] L₃ }

Next tactic:
simp only [TM2.step, Option.mem_def, TM2.stepAux, ite_false, trList, List.append_assoc,
      List.cons_append, elim_update_stack, elim_rev, elim_update_rev, Function.update_same,
      List.headI_cons]
theorem head_stack_ok {q s L₁ L₂ L₃} :
    Reaches₁ (TM2.step tr)
      ⟨some (head stack q), s, K'.elim (trList L₁) [] [] (trList L₂ ++ Γ'.consₗ :: L₃)⟩
      ⟨some q, none, K'.elim (trList (L₂.headI :: L₁)) [] [] L₃⟩ := by
  cases' L₂ with a L₂
  · refine'
      TransGen.trans
        (move_ok (by decide)
          (splitAtPred_eq _ _ [] (some Γ'.consₗ) L₃ (by rintro _ ⟨⟩) ⟨rfl, rfl⟩))
        (TransGen.head rfl (TransGen.head rfl _))
    simp only [TM2.step, Option.mem_def, TM2.stepAux, ite_true, id_eq, trList, List.nil_append,
      elim_update_stack, elim_rev, List.reverseAux_nil, elim_update_rev, Function.update_same,
      List.headI_nil, trNat_default]
    convert unrev_ok using 2
    simp
  · refine'
      TransGen.trans
        (move_ok (by decide)
          (splitAtPred_eq _ _ (trNat a) (some Γ'.cons) (trList L₂ ++ Γ'.consₗ :: L₃)
            (trNat_natEnd _) ⟨rfl, by simp⟩))
        (TransGen.head rfl (TransGen.head rfl _))
    simp only [TM2.step, Option.mem_def, TM2.stepAux, ite_false, trList, List.append_assoc,
      List.cons_append, elim_update_stack, elim_rev, elim_update_rev, Function.update_same,
      List.headI_cons]
    

Proof state:
case cons
q : Λ'
s : Option Γ'
L₁ : List ℕ
L₃ : List Γ'
a : ℕ
L₂ : List ℕ
⊢ TransGen
    (fun a b =>
      (match a with
        | { l := none, var := var, stk := stk } => none
        | { l := some l, var := v, stk := S } => some (TM2.stepAux (tr l) v S)) =
        some b)
    { l := some (ite (some Γ'.cons = some Γ'.consₗ) id (Λ'.clear (fun x => decide (x = Γ'.consₗ)) stack) (unrev q)),
      var := some Γ'.cons,
      stk :=
        elim (trList L₁) (Option.iget (some Γ'.cons) :: List.reverseAux (trNat a) []) [] (trList L₂ ++ Γ'.consₗ :: L₃) }
    { l := some q, var := none, stk := elim (trNat a ++ Γ'.cons :: trList L₁) [] [] L₃ }

Next tactic:
refine'
      TransGen.trans
        (clear_ok
          (splitAtPred_eq _ _ (trList L₂) (some Γ'.consₗ) L₃
            (fun x h => Bool.decide_false (trList_ne_consₗ _ _ h)) ⟨rfl, by simp⟩))
        _
theorem head_stack_ok {q s L₁ L₂ L₃} :
    Reaches₁ (TM2.step tr)
      ⟨some (head stack q), s, K'.elim (trList L₁) [] [] (trList L₂ ++ Γ'.consₗ :: L₃)⟩
      ⟨some q, none, K'.elim (trList (L₂.headI :: L₁)) [] [] L₃⟩ := by
  cases' L₂ with a L₂
  · refine'
      TransGen.trans
        (move_ok (by decide)
          (splitAtPred_eq _ _ [] (some Γ'.consₗ) L₃ (by rintro _ ⟨⟩) ⟨rfl, rfl⟩))
        (TransGen.head rfl (TransGen.head rfl _))
    simp only [TM2.step, Option.mem_def, TM2.stepAux, ite_true, id_eq, trList, List.nil_append,
      elim_update_stack, elim_rev, List.reverseAux_nil, elim_update_rev, Function.update_same,
      List.headI_nil, trNat_default]
    convert unrev_ok using 2
    simp
  · refine'
      TransGen.trans
        (move_ok (by decide)
          (splitAtPred_eq _ _ (trNat a) (some Γ'.cons) (trList L₂ ++ Γ'.consₗ :: L₃)
            (trNat_natEnd _) ⟨rfl, by simp⟩))
        (TransGen.head rfl (TransGen.head rfl _))
    simp only [TM2.step, Option.mem_def, TM2.stepAux, ite_false, trList, List.append_assoc,
      List.cons_append, elim_update_stack, elim_rev, elim_update_rev, Function.update_same,
      List.headI_cons]
    refine'
      TransGen.trans
        (clear_ok
          (splitAtPred_eq _ _ (trList L₂) (some Γ'.consₗ) L₃
            (fun x h => Bool.decide_false (trList_ne_consₗ _ _ h)) ⟨rfl, by 

Proof state:
q : Λ'
s : Option Γ'
L₁ : List ℕ
L₃ : List Γ'
a : ℕ
L₂ : List ℕ
⊢ elim (trList L₁) (Option.iget (some Γ'.cons) :: List.reverseAux (trNat a) []) [] (trList L₂ ++ Γ'.consₗ :: L₃) stack =
    trList L₂ ++ Γ'.consₗ :: L₃

Next tactic:
simp
theorem head_stack_ok {q s L₁ L₂ L₃} :
    Reaches₁ (TM2.step tr)
      ⟨some (head stack q), s, K'.elim (trList L₁) [] [] (trList L₂ ++ Γ'.consₗ :: L₃)⟩
      ⟨some q, none, K'.elim (trList (L₂.headI :: L₁)) [] [] L₃⟩ := by
  cases' L₂ with a L₂
  · refine'
      TransGen.trans
        (move_ok (by decide)
          (splitAtPred_eq _ _ [] (some Γ'.consₗ) L₃ (by rintro _ ⟨⟩) ⟨rfl, rfl⟩))
        (TransGen.head rfl (TransGen.head rfl _))
    simp only [TM2.step, Option.mem_def, TM2.stepAux, ite_true, id_eq, trList, List.nil_append,
      elim_update_stack, elim_rev, List.reverseAux_nil, elim_update_rev, Function.update_same,
      List.headI_nil, trNat_default]
    convert unrev_ok using 2
    simp
  · refine'
      TransGen.trans
        (move_ok (by decide)
          (splitAtPred_eq _ _ (trNat a) (some Γ'.cons) (trList L₂ ++ Γ'.consₗ :: L₃)
            (trNat_natEnd _) ⟨rfl, by simp⟩))
        (TransGen.head rfl (TransGen.head rfl _))
    simp only [TM2.step, Option.mem_def, TM2.stepAux, ite_false, trList, List.append_assoc,
      List.cons_append, elim_update_stack, elim_rev, elim_update_rev, Function.update_same,
      List.headI_cons]
    refine'
      TransGen.trans
        (clear_ok
          (splitAtPred_eq _ _ (trList L₂) (some Γ'.consₗ) L₃
            (fun x h => Bool.decide_false (trList_ne_consₗ _ _ h)) ⟨rfl, by simp⟩))
        _
    

Proof state:
case cons
q : Λ'
s : Option Γ'
L₁ : List ℕ
L₃ : List Γ'
a : ℕ
L₂ : List ℕ
⊢ TransGen
    (fun a b =>
      (match a with
        | { l := none, var := var, stk := stk } => none
        | { l := some l, var := v, stk := S } => some (TM2.stepAux (tr l) v S)) =
        some b)
    { l := some (unrev q), var := some Γ'.consₗ,
      stk :=
        update
          (elim (trList L₁) (Option.iget (some Γ'.cons) :: List.reverseAux (trNat a) []) []
            (trList L₂ ++ Γ'.consₗ :: L₃))
          stack L₃ }
    { l := some q, var := none, stk := elim (trNat a ++ Γ'.cons :: trList L₁) [] [] L₃ }

Next tactic:
convert unrev_ok using 2
theorem head_stack_ok {q s L₁ L₂ L₃} :
    Reaches₁ (TM2.step tr)
      ⟨some (head stack q), s, K'.elim (trList L₁) [] [] (trList L₂ ++ Γ'.consₗ :: L₃)⟩
      ⟨some q, none, K'.elim (trList (L₂.headI :: L₁)) [] [] L₃⟩ := by
  cases' L₂ with a L₂
  · refine'
      TransGen.trans
        (move_ok (by decide)
          (splitAtPred_eq _ _ [] (some Γ'.consₗ) L₃ (by rintro _ ⟨⟩) ⟨rfl, rfl⟩))
        (TransGen.head rfl (TransGen.head rfl _))
    simp only [TM2.step, Option.mem_def, TM2.stepAux, ite_true, id_eq, trList, List.nil_append,
      elim_update_stack, elim_rev, List.reverseAux_nil, elim_update_rev, Function.update_same,
      List.headI_nil, trNat_default]
    convert unrev_ok using 2
    simp
  · refine'
      TransGen.trans
        (move_ok (by decide)
          (splitAtPred_eq _ _ (trNat a) (some Γ'.cons) (trList L₂ ++ Γ'.consₗ :: L₃)
            (trNat_natEnd _) ⟨rfl, by simp⟩))
        (TransGen.head rfl (TransGen.head rfl _))
    simp only [TM2.step, Option.mem_def, TM2.stepAux, ite_false, trList, List.append_assoc,
      List.cons_append, elim_update_stack, elim_rev, elim_update_rev, Function.update_same,
      List.headI_cons]
    refine'
      TransGen.trans
        (clear_ok
          (splitAtPred_eq _ _ (trList L₂) (some Γ'.consₗ) L₃
            (fun x h => Bool.decide_false (trList_ne_consₗ _ _ h)) ⟨rfl, by simp⟩))
        _
    convert unrev_ok using 2
    

Proof state:
case h.e'_2.h.e'_7
q : Λ'
s : Option Γ'
L₁ : List ℕ
L₃ : List Γ'
a : ℕ
L₂ : List ℕ
⊢ elim (trNat a ++ Γ'.cons :: trList L₁) [] [] L₃ =
    update
      (update
        (update
          (elim (trList L₁) (Option.iget (some Γ'.cons) :: List.reverseAux (trNat a) []) []
            (trList L₂ ++ Γ'.consₗ :: L₃))
          stack L₃)
        rev [])
      main
      (List.reverseAux
        (update
          (elim (trList L₁) (Option.iget (some Γ'.cons) :: List.reverseAux (trNat a) []) []
            (trList L₂ ++ Γ'.consₗ :: L₃))
          stack L₃ rev)
        (update
          (elim (trList L₁) (Option.iget (some Γ'.cons) :: List.reverseAux (trNat a) []) []
            (trList L₂ ++ Γ'.consₗ :: L₃))
          stack L₃ main))

Next tactic:
simp [List.reverseAux_eq]
theorem succ_ok {q s n} {c d : List Γ'} :
    Reaches₁ (TM2.step tr) ⟨some (Λ'.succ q), s, K'.elim (trList [n]) [] c d⟩
      ⟨some q, none, K'.elim (trList [n.succ]) [] c d⟩ := by
  

Proof state:
q : Λ'
s : Option Γ'
n : ℕ
c d : List Γ'
⊢ Reaches₁ (TM2.step tr) { l := some (Λ'.succ q), var := s, stk := elim (trList [n]) [] c d }
    { l := some q, var := none, stk := elim (trList [Nat.succ n]) [] c d }

Next tactic:
simp only [TM2.step, trList, trNat._eq_1, Nat.cast_succ, Num.add_one]
theorem succ_ok {q s n} {c d : List Γ'} :
    Reaches₁ (TM2.step tr) ⟨some (Λ'.succ q), s, K'.elim (trList [n]) [] c d⟩
      ⟨some q, none, K'.elim (trList [n.succ]) [] c d⟩ := by
  simp only [TM2.step, trList, trNat._eq_1, Nat.cast_succ, Num.add_one]
  

Proof state:
q : Λ'
s : Option Γ'
n : ℕ
c d : List Γ'
⊢ Reaches₁ (TM2.step tr) { l := some (Λ'.succ q), var := s, stk := elim (trNum ↑n ++ [Γ'.cons]) [] c d }
    { l := some q, var := none, stk := elim (trNum (Num.succ ↑n) ++ [Γ'.cons]) [] c d }

Next tactic:
cases' (n : Num) with a
theorem succ_ok {q s n} {c d : List Γ'} :
    Reaches₁ (TM2.step tr) ⟨some (Λ'.succ q), s, K'.elim (trList [n]) [] c d⟩
      ⟨some q, none, K'.elim (trList [n.succ]) [] c d⟩ := by
  simp only [TM2.step, trList, trNat._eq_1, Nat.cast_succ, Num.add_one]
  cases' (n : Num) with a
  · 

Proof state:
case zero
q : Λ'
s : Option Γ'
n : ℕ
c d : List Γ'
⊢ Reaches₁ (TM2.step tr) { l := some (Λ'.succ q), var := s, stk := elim (trNum Num.zero ++ [Γ'.cons]) [] c d }
    { l := some q, var := none, stk := elim (trNum (Num.succ Num.zero) ++ [Γ'.cons]) [] c d }

Next tactic:
refine' TransGen.head rfl _
theorem succ_ok {q s n} {c d : List Γ'} :
    Reaches₁ (TM2.step tr) ⟨some (Λ'.succ q), s, K'.elim (trList [n]) [] c d⟩
      ⟨some q, none, K'.elim (trList [n.succ]) [] c d⟩ := by
  simp only [TM2.step, trList, trNat._eq_1, Nat.cast_succ, Num.add_one]
  cases' (n : Num) with a
  · refine' TransGen.head rfl _
    

Proof state:
case zero
q : Λ'
s : Option Γ'
n : ℕ
c d : List Γ'
⊢ TransGen (fun a b => b ∈ TM2.step tr a) (TM2.stepAux (tr (Λ'.succ q)) s (elim (trNum Num.zero ++ [Γ'.cons]) [] c d))
    { l := some q, var := none, stk := elim (trNum (Num.succ Num.zero) ++ [Γ'.cons]) [] c d }

Next tactic:
simp only [Option.mem_def, TM2.stepAux, elim_main, decide_False, elim_update_main, ne_eq,
      Function.update_noteq, elim_rev, elim_update_rev, decide_True, Function.update_same,
      cond_true, cond_false]
theorem succ_ok {q s n} {c d : List Γ'} :
    Reaches₁ (TM2.step tr) ⟨some (Λ'.succ q), s, K'.elim (trList [n]) [] c d⟩
      ⟨some q, none, K'.elim (trList [n.succ]) [] c d⟩ := by
  simp only [TM2.step, trList, trNat._eq_1, Nat.cast_succ, Num.add_one]
  cases' (n : Num) with a
  · refine' TransGen.head rfl _
    simp only [Option.mem_def, TM2.stepAux, elim_main, decide_False, elim_update_main, ne_eq,
      Function.update_noteq, elim_rev, elim_update_rev, decide_True, Function.update_same,
      cond_true, cond_false]
    

Proof state:
case zero
q : Λ'
s : Option Γ'
n : ℕ
c d : List Γ'
⊢ TransGen (fun a b => TM2.step tr a = some b)
    (bif decide (List.head? (trNum Num.zero ++ [Γ'.cons]) = some Γ'.bit1) then
      { l := some (Λ'.succ q), var := List.head? (trNum Num.zero ++ [Γ'.cons]),
        stk := elim (List.tail (trNum Num.zero ++ [Γ'.cons])) [Γ'.bit0] c d }
    else
      bif decide (List.head? (trNum Num.zero ++ [Γ'.cons]) = some Γ'.cons) then
        { l := some (unrev q), var := List.head? (trNum Num.zero ++ [Γ'.cons]),
          stk := elim (Γ'.bit1 :: Γ'.cons :: List.tail (trNum Num.zero ++ [Γ'.cons])) [] c d }
      else
        { l := some (unrev q), var := List.head? (trNum Num.zero ++ [Γ'.cons]),
          stk := elim (Γ'.bit1 :: List.tail (trNum Num.zero ++ [Γ'.cons])) [] c d })
    { l := some q, var := none, stk := elim (trNum (Num.succ Num.zero) ++ [Γ'.cons]) [] c d }

Next tactic:
convert unrev_ok using 1
theorem succ_ok {q s n} {c d : List Γ'} :
    Reaches₁ (TM2.step tr) ⟨some (Λ'.succ q), s, K'.elim (trList [n]) [] c d⟩
      ⟨some q, none, K'.elim (trList [n.succ]) [] c d⟩ := by
  simp only [TM2.step, trList, trNat._eq_1, Nat.cast_succ, Num.add_one]
  cases' (n : Num) with a
  · refine' TransGen.head rfl _
    simp only [Option.mem_def, TM2.stepAux, elim_main, decide_False, elim_update_main, ne_eq,
      Function.update_noteq, elim_rev, elim_update_rev, decide_True, Function.update_same,
      cond_true, cond_false]
    convert unrev_ok using 1
    

Proof state:
case h.e'_2
q : Λ'
s : Option Γ'
n : ℕ
c d : List Γ'
⊢ { l := some q, var := none, stk := elim (trNum (Num.succ Num.zero) ++ [Γ'.cons]) [] c d } =
    { l := some q, var := none,
      stk :=
        update (update (elim (Γ'.bit1 :: Γ'.cons :: List.tail (trNum Num.zero ++ [Γ'.cons])) [] c d) rev []) main
          (List.reverseAux (elim (Γ'.bit1 :: Γ'.cons :: List.tail (trNum Num.zero ++ [Γ'.cons])) [] c d rev)
            (elim (Γ'.bit1 :: Γ'.cons :: List.tail (trNum Num.zero ++ [Γ'.cons])) [] c d main)) }

Next tactic:
simp only [elim_update_rev, elim_rev, elim_main, List.reverseAux_nil, elim_update_main]
theorem succ_ok {q s n} {c d : List Γ'} :
    Reaches₁ (TM2.step tr) ⟨some (Λ'.succ q), s, K'.elim (trList [n]) [] c d⟩
      ⟨some q, none, K'.elim (trList [n.succ]) [] c d⟩ := by
  simp only [TM2.step, trList, trNat._eq_1, Nat.cast_succ, Num.add_one]
  cases' (n : Num) with a
  · refine' TransGen.head rfl _
    simp only [Option.mem_def, TM2.stepAux, elim_main, decide_False, elim_update_main, ne_eq,
      Function.update_noteq, elim_rev, elim_update_rev, decide_True, Function.update_same,
      cond_true, cond_false]
    convert unrev_ok using 1
    simp only [elim_update_rev, elim_rev, elim_main, List.reverseAux_nil, elim_update_main]
    

Proof state:
case h.e'_2
q : Λ'
s : Option Γ'
n : ℕ
c d : List Γ'
⊢ { l := some q, var := none, stk := elim (trNum (Num.succ Num.zero) ++ [Γ'.cons]) [] c d } =
    { l := some q, var := none, stk := elim (Γ'.bit1 :: Γ'.cons :: List.tail (trNum Num.zero ++ [Γ'.cons])) [] c d }

Next tactic:
rfl
theorem succ_ok {q s n} {c d : List Γ'} :
    Reaches₁ (TM2.step tr) ⟨some (Λ'.succ q), s, K'.elim (trList [n]) [] c d⟩
      ⟨some q, none, K'.elim (trList [n.succ]) [] c d⟩ := by
  simp only [TM2.step, trList, trNat._eq_1, Nat.cast_succ, Num.add_one]
  cases' (n : Num) with a
  · refine' TransGen.head rfl _
    simp only [Option.mem_def, TM2.stepAux, elim_main, decide_False, elim_update_main, ne_eq,
      Function.update_noteq, elim_rev, elim_update_rev, decide_True, Function.update_same,
      cond_true, cond_false]
    convert unrev_ok using 1
    simp only [elim_update_rev, elim_rev, elim_main, List.reverseAux_nil, elim_update_main]
    rfl
  

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

Next tactic:
simp only [trNum, Num.succ, Num.succ']
theorem succ_ok {q s n} {c d : List Γ'} :
    Reaches₁ (TM2.step tr) ⟨some (Λ'.succ q), s, K'.elim (trList [n]) [] c d⟩
      ⟨some q, none, K'.elim (trList [n.succ]) [] c d⟩ := by
  simp only [TM2.step, trList, trNat._eq_1, Nat.cast_succ, Num.add_one]
  cases' (n : Num) with a
  · refine' TransGen.head rfl _
    simp only [Option.mem_def, TM2.stepAux, elim_main, decide_False, elim_update_main, ne_eq,
      Function.update_noteq, elim_rev, elim_update_rev, decide_True, Function.update_same,
      cond_true, cond_false]
    convert unrev_ok using 1
    simp only [elim_update_rev, elim_rev, elim_main, List.reverseAux_nil, elim_update_main]
    rfl
  simp only [trNum, Num.succ, Num.succ']
  

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

Next tactic:
suffices ∀ l₁, ∃ l₁' l₂' s',
      List.reverseAux l₁ (trPosNum a.succ) = List.reverseAux l₁' l₂' ∧
        Reaches₁ (TM2.step tr) ⟨some q.succ, s, K'.elim (trPosNum a ++ [Γ'.cons]) l₁ c d⟩
          ⟨some (unrev q), s', K'.elim (l₂' ++ [Γ'.cons]) l₁' c d⟩ by
    obtain ⟨l₁', l₂', s', e, h⟩ := this []
    simp? [List.reverseAux] at e says simp only [List.reverseAux] at e
    refine' h.trans _
    convert unrev_ok using 2
    simp [e, List.reverseAux_eq]
theorem succ_ok {q s n} {c d : List Γ'} :
    Reaches₁ (TM2.step tr) ⟨some (Λ'.succ q), s, K'.elim (trList [n]) [] c d⟩
      ⟨some q, none, K'.elim (trList [n.succ]) [] c d⟩ := by
  simp only [TM2.step, trList, trNat._eq_1, Nat.cast_succ, Num.add_one]
  cases' (n : Num) with a
  · refine' TransGen.head rfl _
    simp only [Option.mem_def, TM2.stepAux, elim_main, decide_False, elim_update_main, ne_eq,
      Function.update_noteq, elim_rev, elim_update_rev, decide_True, Function.update_same,
      cond_true, cond_false]
    convert unrev_ok using 1
    simp only [elim_update_rev, elim_rev, elim_main, List.reverseAux_nil, elim_update_main]
    rfl
  simp only [trNum, Num.succ, Num.succ']
  suffices ∀ l₁, ∃ l₁' l₂' s',
      List.reverseAux l₁ (trPosNum a.succ) = List.reverseAux l₁' l₂' ∧
        Reaches₁ (TM2.step tr) ⟨some q.succ, s, K'.elim (trPosNum a ++ [Γ'.cons]) l₁ c d⟩
          ⟨some (unrev q), s', K'.elim (l₂' ++ [Γ'.cons]) l₁' c d⟩ by
    

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

Next tactic:
obtain ⟨l₁', l₂', s', e, h⟩ := this []
theorem succ_ok {q s n} {c d : List Γ'} :
    Reaches₁ (TM2.step tr) ⟨some (Λ'.succ q), s, K'.elim (trList [n]) [] c d⟩
      ⟨some q, none, K'.elim (trList [n.succ]) [] c d⟩ := by
  simp only [TM2.step, trList, trNat._eq_1, Nat.cast_succ, Num.add_one]
  cases' (n : Num) with a
  · refine' TransGen.head rfl _
    simp only [Option.mem_def, TM2.stepAux, elim_main, decide_False, elim_update_main, ne_eq,
      Function.update_noteq, elim_rev, elim_update_rev, decide_True, Function.update_same,
      cond_true, cond_false]
    convert unrev_ok using 1
    simp only [elim_update_rev, elim_rev, elim_main, List.reverseAux_nil, elim_update_main]
    rfl
  simp only [trNum, Num.succ, Num.succ']
  suffices ∀ l₁, ∃ l₁' l₂' s',
      List.reverseAux l₁ (trPosNum a.succ) = List.reverseAux l₁' l₂' ∧
        Reaches₁ (TM2.step tr) ⟨some q.succ, s, K'.elim (trPosNum a ++ [Γ'.cons]) l₁ c d⟩
          ⟨some (unrev q), s', K'.elim (l₂' ++ [Γ'.cons]) l₁' c d⟩ by
    obtain ⟨l₁', l₂', s', e, h⟩ := this []
    

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

Next tactic:
simp? [List.reverseAux] at e says simp only [List.reverseAux] at e
theorem succ_ok {q s n} {c d : List Γ'} :
    Reaches₁ (TM2.step tr) ⟨some (Λ'.succ q), s, K'.elim (trList [n]) [] c d⟩
      ⟨some q, none, K'.elim (trList [n.succ]) [] c d⟩ := by
  simp only [TM2.step, trList, trNat._eq_1, Nat.cast_succ, Num.add_one]
  cases' (n : Num) with a
  · refine' TransGen.head rfl _
    simp only [Option.mem_def, TM2.stepAux, elim_main, decide_False, elim_update_main, ne_eq,
      Function.update_noteq, elim_rev, elim_update_rev, decide_True, Function.update_same,
      cond_true, cond_false]
    convert unrev_ok using 1
    simp only [elim_update_rev, elim_rev, elim_main, List.reverseAux_nil, elim_update_main]
    rfl
  simp only [trNum, Num.succ, Num.succ']
  suffices ∀ l₁, ∃ l₁' l₂' s',
      List.reverseAux l₁ (trPosNum a.succ) = List.reverseAux l₁' l₂' ∧
        Reaches₁ (TM2.step tr) ⟨some q.succ, s, K'.elim (trPosNum a ++ [Γ'.cons]) l₁ c d⟩
          ⟨some (unrev q), s', K'.elim (l₂' ++ [Γ'.cons]) l₁' c d⟩ by
    obtain ⟨l₁', l₂', s', e, h⟩ := this []
    simp? [List.reverseAux] at e says 

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

Next tactic:
simp only [List.reverseAux] at e