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
  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 <;> intro l₁
  · refine' ⟨Γ'.bit1::l₁, [], some Γ'.cons, rfl, TransGen.head rfl (TransGen.single _)⟩
    simp [trPosNum, show PosNum.one.succ = PosNum.one.bit0 from rfl]
  · obtain ⟨l₁', l₂', s', e, h⟩ := IH (some Γ'.bit0) (Γ'.bit1 :: l₁)
    refine' ⟨l₁', l₂', s', e, TransGen.head _ h⟩
    simp
    rfl
  · obtain ⟨a, l, e, h⟩ : ∃ a l, (trPosNum m = a::l) ∧ natEnd a = false := by
      cases m <;> 

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

Next tactic:
refine' ⟨_, _, rfl, rfl⟩
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 <;> intro l₁
  · refine' ⟨Γ'.bit1::l₁, [], some Γ'.cons, rfl, TransGen.head rfl (TransGen.single _)⟩
    simp [trPosNum, show PosNum.one.succ = PosNum.one.bit0 from rfl]
  · obtain ⟨l₁', l₂', s', e, h⟩ := IH (some Γ'.bit0) (Γ'.bit1 :: l₁)
    refine' ⟨l₁', l₂', s', e, TransGen.head _ h⟩
    simp
    rfl
  · obtain ⟨a, l, e, h⟩ : ∃ a l, (trPosNum m = a::l) ∧ natEnd a = false := by
      cases m <;> refine' ⟨_, _, rfl, rfl⟩
    

Proof state:
case cons.succ.pos.bit0.intro.intro.intro
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 Γ'
a : Γ'
l : List Γ'
e : trPosNum m = a :: l
h : natEnd a = false
⊢ ∃ 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:
refine' ⟨Γ'.bit0 :: l₁, _, some a, rfl, TransGen.single _⟩
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 <;> intro l₁
  · refine' ⟨Γ'.bit1::l₁, [], some Γ'.cons, rfl, TransGen.head rfl (TransGen.single _)⟩
    simp [trPosNum, show PosNum.one.succ = PosNum.one.bit0 from rfl]
  · obtain ⟨l₁', l₂', s', e, h⟩ := IH (some Γ'.bit0) (Γ'.bit1 :: l₁)
    refine' ⟨l₁', l₂', s', e, TransGen.head _ h⟩
    simp
    rfl
  · obtain ⟨a, l, e, h⟩ : ∃ a l, (trPosNum m = a::l) ∧ natEnd a = false := by
      cases m <;> refine' ⟨_, _, rfl, rfl⟩
    refine' ⟨Γ'.bit0 :: l₁, _, some a, rfl, TransGen.single _⟩
    

Proof state:
case cons.succ.pos.bit0.intro.intro.intro
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 Γ'
a : Γ'
l : List Γ'
e : trPosNum m = a :: l
h : natEnd a = false
⊢ { l := some (unrev q₂), var := some a, stk := elim (trPosNum m ++ Γ'.cons :: trList v) (Γ'.bit0 :: l₁) c d } ∈
    TM2.step tr
      { l := some (Λ'.pred q₁ q₂), var := s,
        stk := elim (trPosNum (PosNum.succ (PosNum.bit0 m)) ++ Γ'.cons :: trList v) l₁ c d }

Next tactic:
simp [trPosNum, PosNum.succ, e, h, show some Γ'.bit1 ≠ some Γ'.bit0 by decide,
      Option.iget, -natEnd]
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 <;> intro l₁
  · refine' ⟨Γ'.bit1::l₁, [], some Γ'.cons, rfl, TransGen.head rfl (TransGen.single _)⟩
    simp [trPosNum, show PosNum.one.succ = PosNum.one.bit0 from rfl]
  · obtain ⟨l₁', l₂', s', e, h⟩ := IH (some Γ'.bit0) (Γ'.bit1 :: l₁)
    refine' ⟨l₁', l₂', s', e, TransGen.head _ h⟩
    simp
    rfl
  · obtain ⟨a, l, e, h⟩ : ∃ a l, (trPosNum m = a::l) ∧ natEnd a = false := by
      cases m <;> refine' ⟨_, _, rfl, rfl⟩
    refine' ⟨Γ'.bit0 :: l₁, _, some a, rfl, TransGen.single _⟩
    simp [trPosNum, PosNum.succ, e, h, show some Γ'.bit1 ≠ some Γ'.bit0 by 

Proof state:
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 Γ'
a : Γ'
l : List Γ'
e : trPosNum m = a :: l
h : natEnd a = false
⊢ some Γ'.bit1 ≠ some Γ'.bit0

Next tactic:
decide
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 <;> intro l₁
  · refine' ⟨Γ'.bit1::l₁, [], some Γ'.cons, rfl, TransGen.head rfl (TransGen.single _)⟩
    simp [trPosNum, show PosNum.one.succ = PosNum.one.bit0 from rfl]
  · obtain ⟨l₁', l₂', s', e, h⟩ := IH (some Γ'.bit0) (Γ'.bit1 :: l₁)
    refine' ⟨l₁', l₂', s', e, TransGen.head _ h⟩
    simp
    rfl
  · obtain ⟨a, l, e, h⟩ : ∃ a l, (trPosNum m = a::l) ∧ natEnd a = false := by
      cases m <;> refine' ⟨_, _, rfl, rfl⟩
    refine' ⟨Γ'.bit0 :: l₁, _, some a, rfl, TransGen.single _⟩
    simp [trPosNum, PosNum.succ, e, h, show some Γ'.bit1 ≠ some Γ'.bit0 by decide,
      Option.iget, -natEnd]
    

Proof state:
case cons.succ.pos.bit0.intro.intro.intro
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 Γ'
a : Γ'
l : List Γ'
e : trPosNum m = a :: l
h : natEnd a = false
⊢ (bif natEnd Γ'.bit1 then { l := some q₁, var := some Γ'.bit1, stk := elim (a :: (l ++ Γ'.cons :: trList v)) l₁ c d }
    else { l := some (unrev q₂), var := some a, stk := elim (a :: (l ++ Γ'.cons :: trList v)) (Γ'.bit0 :: l₁) c d }) =
    { l := some (unrev q₂), var := some a, stk := elim (a :: (l ++ Γ'.cons :: trList v)) (Γ'.bit0 :: l₁) c d }

Next tactic:
rfl
theorem trNormal_respects (c k v s) :
    ∃ b₂,
      TrCfg (stepNormal c k v) b₂ ∧
        Reaches₁ (TM2.step tr)
          ⟨some (trNormal c (trCont k)), s, K'.elim (trList v) [] [] (trContStack k)⟩ b₂ := by
  

Proof state:
c : Code
k : Cont
v : List ℕ
s : Option Γ'
⊢ ∃ b₂,
    TrCfg (stepNormal c k v) b₂ ∧
      Reaches₁ (TM2.step tr)
        { l := some (trNormal c (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) } b₂

Next tactic:
induction c generalizing k v s
theorem trNormal_respects (c k v s) :
    ∃ b₂,
      TrCfg (stepNormal c k v) b₂ ∧
        Reaches₁ (TM2.step tr)
          ⟨some (trNormal c (trCont k)), s, K'.elim (trList v) [] [] (trContStack k)⟩ b₂ := by
  induction c generalizing k v s
  

Proof state:
k : Cont
v : List ℕ
s : Option Γ'
⊢ ∃ b₂,
    TrCfg (stepNormal Code.zero' k v) b₂ ∧
      Reaches₁ (TM2.step tr)
        { l := some (trNormal Code.zero' (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) } b₂

Next tactic:
case zero' => refine' ⟨_, ⟨s, rfl⟩, TransGen.single _⟩; simp
theorem trNormal_respects (c k v s) :
    ∃ b₂,
      TrCfg (stepNormal c k v) b₂ ∧
        Reaches₁ (TM2.step tr)
          ⟨some (trNormal c (trCont k)), s, K'.elim (trList v) [] [] (trContStack k)⟩ b₂ := by
  induction c generalizing k v s
  case zero' => 

Proof state:
k : Cont
v : List ℕ
s : Option Γ'
⊢ ∃ b₂,
    TrCfg (stepNormal Code.zero' k v) b₂ ∧
      Reaches₁ (TM2.step tr)
        { l := some (trNormal Code.zero' (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) } b₂

Next tactic:
refine' ⟨_, ⟨s, rfl⟩, TransGen.single _⟩
theorem trNormal_respects (c k v s) :
    ∃ b₂,
      TrCfg (stepNormal c k v) b₂ ∧
        Reaches₁ (TM2.step tr)
          ⟨some (trNormal c (trCont k)), s, K'.elim (trList v) [] [] (trContStack k)⟩ b₂ := by
  induction c generalizing k v s
  case zero' => refine' ⟨_, ⟨s, rfl⟩, TransGen.single _⟩; 

Proof state:
k : Cont
v : List ℕ
s : Option Γ'
⊢ { l := some (Λ'.ret (trCont k)), var := s, stk := elim (trList (0 :: v)) [] [] (trContStack k) } ∈
    TM2.step tr { l := some (trNormal Code.zero' (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) }

Next tactic:
simp
theorem trNormal_respects (c k v s) :
    ∃ b₂,
      TrCfg (stepNormal c k v) b₂ ∧
        Reaches₁ (TM2.step tr)
          ⟨some (trNormal c (trCont k)), s, K'.elim (trList v) [] [] (trContStack k)⟩ b₂ := by
  induction c generalizing k v s
  case zero' => refine' ⟨_, ⟨s, rfl⟩, TransGen.single _⟩; simp
  

Proof state:
k : Cont
v : List ℕ
s : Option Γ'
⊢ ∃ b₂,
    TrCfg (stepNormal Code.succ k v) b₂ ∧
      Reaches₁ (TM2.step tr)
        { l := some (trNormal Code.succ (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) } b₂

Next tactic:
case succ => refine' ⟨_, ⟨none, rfl⟩, head_main_ok.trans succ_ok⟩
theorem trNormal_respects (c k v s) :
    ∃ b₂,
      TrCfg (stepNormal c k v) b₂ ∧
        Reaches₁ (TM2.step tr)
          ⟨some (trNormal c (trCont k)), s, K'.elim (trList v) [] [] (trContStack k)⟩ b₂ := by
  induction c generalizing k v s
  case zero' => refine' ⟨_, ⟨s, rfl⟩, TransGen.single _⟩; simp
  case succ => 

Proof state:
k : Cont
v : List ℕ
s : Option Γ'
⊢ ∃ b₂,
    TrCfg (stepNormal Code.succ k v) b₂ ∧
      Reaches₁ (TM2.step tr)
        { l := some (trNormal Code.succ (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) } b₂

Next tactic:
refine' ⟨_, ⟨none, rfl⟩, head_main_ok.trans succ_ok⟩
theorem trNormal_respects (c k v s) :
    ∃ b₂,
      TrCfg (stepNormal c k v) b₂ ∧
        Reaches₁ (TM2.step tr)
          ⟨some (trNormal c (trCont k)), s, K'.elim (trList v) [] [] (trContStack k)⟩ b₂ := by
  induction c generalizing k v s
  case zero' => refine' ⟨_, ⟨s, rfl⟩, TransGen.single _⟩; simp
  case succ => refine' ⟨_, ⟨none, rfl⟩, head_main_ok.trans succ_ok⟩
  

Proof state:
k : Cont
v : List ℕ
s : Option Γ'
⊢ ∃ b₂,
    TrCfg (stepNormal Code.tail k v) b₂ ∧
      Reaches₁ (TM2.step tr)
        { l := some (trNormal Code.tail (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) } b₂

Next tactic:
case tail =>
    let o : Option Γ' := List.casesOn v none fun _ _ => some Γ'.cons
    refine' ⟨_, ⟨o, rfl⟩, _⟩; convert clear_ok _ using 2; simp; rfl; swap
    refine' splitAtPred_eq _ _ (trNat v.headI) _ _ (trNat_natEnd _) _
    cases v <;> simp
theorem trNormal_respects (c k v s) :
    ∃ b₂,
      TrCfg (stepNormal c k v) b₂ ∧
        Reaches₁ (TM2.step tr)
          ⟨some (trNormal c (trCont k)), s, K'.elim (trList v) [] [] (trContStack k)⟩ b₂ := by
  induction c generalizing k v s
  case zero' => refine' ⟨_, ⟨s, rfl⟩, TransGen.single _⟩; simp
  case succ => refine' ⟨_, ⟨none, rfl⟩, head_main_ok.trans succ_ok⟩
  case tail =>
    

Proof state:
k : Cont
v : List ℕ
s : Option Γ'
⊢ ∃ b₂,
    TrCfg (stepNormal Code.tail k v) b₂ ∧
      Reaches₁ (TM2.step tr)
        { l := some (trNormal Code.tail (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) } b₂

Next tactic:
let o : Option Γ' := List.casesOn v none fun _ _ => some Γ'.cons
theorem trNormal_respects (c k v s) :
    ∃ b₂,
      TrCfg (stepNormal c k v) b₂ ∧
        Reaches₁ (TM2.step tr)
          ⟨some (trNormal c (trCont k)), s, K'.elim (trList v) [] [] (trContStack k)⟩ b₂ := by
  induction c generalizing k v s
  case zero' => refine' ⟨_, ⟨s, rfl⟩, TransGen.single _⟩; simp
  case succ => refine' ⟨_, ⟨none, rfl⟩, head_main_ok.trans succ_ok⟩
  case tail =>
    let o : Option Γ' := List.casesOn v none fun _ _ => some Γ'.cons
    

Proof state:
k : Cont
v : List ℕ
s : Option Γ'
o : Option Γ' := List.casesOn v none fun x x => some Γ'.cons
⊢ ∃ b₂,
    TrCfg (stepNormal Code.tail k v) b₂ ∧
      Reaches₁ (TM2.step tr)
        { l := some (trNormal Code.tail (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) } b₂

Next tactic:
refine' ⟨_, ⟨o, rfl⟩, _⟩
theorem trNormal_respects (c k v s) :
    ∃ b₂,
      TrCfg (stepNormal c k v) b₂ ∧
        Reaches₁ (TM2.step tr)
          ⟨some (trNormal c (trCont k)), s, K'.elim (trList v) [] [] (trContStack k)⟩ b₂ := by
  induction c generalizing k v s
  case zero' => refine' ⟨_, ⟨s, rfl⟩, TransGen.single _⟩; simp
  case succ => refine' ⟨_, ⟨none, rfl⟩, head_main_ok.trans succ_ok⟩
  case tail =>
    let o : Option Γ' := List.casesOn v none fun _ _ => some Γ'.cons
    refine' ⟨_, ⟨o, rfl⟩, _⟩; 

Proof state:
k : Cont
v : List ℕ
s : Option Γ'
o : Option Γ' := List.casesOn v none fun x x => some Γ'.cons
⊢ Reaches₁ (TM2.step tr)
    { l := some (trNormal Code.tail (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) }
    { l := some (Λ'.ret (trCont k)), var := o, stk := elim (trList (List.tail v)) [] [] (trContStack k) }

Next tactic:
convert clear_ok _ using 2
theorem trNormal_respects (c k v s) :
    ∃ b₂,
      TrCfg (stepNormal c k v) b₂ ∧
        Reaches₁ (TM2.step tr)
          ⟨some (trNormal c (trCont k)), s, K'.elim (trList v) [] [] (trContStack k)⟩ b₂ := by
  induction c generalizing k v s
  case zero' => refine' ⟨_, ⟨s, rfl⟩, TransGen.single _⟩; simp
  case succ => refine' ⟨_, ⟨none, rfl⟩, head_main_ok.trans succ_ok⟩
  case tail =>
    let o : Option Γ' := List.casesOn v none fun _ _ => some Γ'.cons
    refine' ⟨_, ⟨o, rfl⟩, _⟩; convert clear_ok _ using 2; 

Proof state:
case h.e'_4.h.e'_7
k : Cont
v : List ℕ
s : Option Γ'
o : Option Γ' := List.casesOn v none fun x x => some Γ'.cons
⊢ elim (trList (List.tail v)) [] [] (trContStack k) = update (elim (trList v) [] [] (trContStack k)) main ?convert_7
case convert_5
k : Cont
v : List ℕ
s : Option Γ'
o : Option Γ' := List.casesOn v none fun x x => some Γ'.cons
⊢ List Γ'
case convert_7
k : Cont
v : List ℕ
s : Option Γ'
o : Option Γ' := List.casesOn v none fun x x => some Γ'.cons
⊢ List Γ'
case convert_9
k : Cont
v : List ℕ
s : Option Γ'
o : Option Γ' := List.casesOn v none fun x x => some Γ'.cons
⊢ splitAtPred natEnd (elim (trList v) [] [] (trContStack k) main) = (?convert_5, o, ?convert_7)

Next tactic:
simp
theorem trNormal_respects (c k v s) :
    ∃ b₂,
      TrCfg (stepNormal c k v) b₂ ∧
        Reaches₁ (TM2.step tr)
          ⟨some (trNormal c (trCont k)), s, K'.elim (trList v) [] [] (trContStack k)⟩ b₂ := by
  induction c generalizing k v s
  case zero' => refine' ⟨_, ⟨s, rfl⟩, TransGen.single _⟩; simp
  case succ => refine' ⟨_, ⟨none, rfl⟩, head_main_ok.trans succ_ok⟩
  case tail =>
    let o : Option Γ' := List.casesOn v none fun _ _ => some Γ'.cons
    refine' ⟨_, ⟨o, rfl⟩, _⟩; convert clear_ok _ using 2; simp; 

Proof state:
case h.e'_4.h.e'_7
k : Cont
v : List ℕ
s : Option Γ'
o : Option Γ' := List.casesOn v none fun x x => some Γ'.cons
⊢ elim (trList (List.tail v)) [] [] (trContStack k) = elim ?convert_7 [] [] (trContStack k)
case convert_5
k : Cont
v : List ℕ
s : Option Γ'
o : Option Γ' := List.casesOn v none fun x x => some Γ'.cons
⊢ List Γ'
case convert_7
k : Cont
v : List ℕ
s : Option Γ'
o : Option Γ' := List.casesOn v none fun x x => some Γ'.cons
⊢ List Γ'
case convert_9
k : Cont
v : List ℕ
s : Option Γ'
o : Option Γ' := List.casesOn v none fun x x => some Γ'.cons
⊢ splitAtPred natEnd (elim (trList v) [] [] (trContStack k) main) = (?convert_5, o, ?convert_7)

Next tactic:
rfl
theorem trNormal_respects (c k v s) :
    ∃ b₂,
      TrCfg (stepNormal c k v) b₂ ∧
        Reaches₁ (TM2.step tr)
          ⟨some (trNormal c (trCont k)), s, K'.elim (trList v) [] [] (trContStack k)⟩ b₂ := by
  induction c generalizing k v s
  case zero' => refine' ⟨_, ⟨s, rfl⟩, TransGen.single _⟩; simp
  case succ => refine' ⟨_, ⟨none, rfl⟩, head_main_ok.trans succ_ok⟩
  case tail =>
    let o : Option Γ' := List.casesOn v none fun _ _ => some Γ'.cons
    refine' ⟨_, ⟨o, rfl⟩, _⟩; convert clear_ok _ using 2; simp; rfl; 

Proof state:
case convert_5
k : Cont
v : List ℕ
s : Option Γ'
o : Option Γ' := List.casesOn v none fun x x => some Γ'.cons
⊢ List Γ'
case convert_9
k : Cont
v : List ℕ
s : Option Γ'
o : Option Γ' := List.casesOn v none fun x x => some Γ'.cons
⊢ splitAtPred natEnd (elim (trList v) [] [] (trContStack k) main) = (?convert_5, o, trList (List.tail v))

Next tactic:
swap