l3lab/ntp-mathlib huggingface dataset:
theorem tr_ret_respects (k v s) : ∃ b₂,
    TrCfg (stepRet k v) b₂ ∧
      Reaches₁ (TM2.step tr)
        ⟨some (Λ'.ret (trCont k)), s, K'.elim (trList v) [] [] (trContStack k)⟩ b₂ := by
  induction k generalizing v s
  case halt => exact ⟨_, rfl, TransGen.single rfl⟩
  case
    cons₁ fs as k _ =>
    obtain ⟨s', h₁, h₂⟩ := trNormal_respects fs (Cont.cons₂ v k) as none
    refine' ⟨s', h₁, TransGen.head rfl _⟩; simp
    refine' (move₂_ok (by decide) _ (splitAtPred_false _)).trans _; · rfl
    simp only [TM2.step, Option.mem_def, Option.elim, id_eq, elim_update_main, elim_main, elim_aux,
      List.append_nil, elim_update_aux]
    refine' (move₂_ok (by decide) _ _).trans _; pick_goal 4; · rfl
    pick_goal 4;
    · exact
        splitAtPred_eq _ _ _ (some Γ'.consₗ) _
          (fun x h => Bool.decide_false (trList_ne_consₗ _ _ h)) ⟨rfl, rfl⟩
    refine' (move₂_ok (by decide) _ (splitAtPred_false _)).trans _; · rfl
    simp only [TM2.step, Option.mem_def, Option.elim, elim_update_stack, elim_main,
      List.append_nil, elim_update_main,  id_eq, elim_update_aux, ne_eq, Function.update_noteq,
      elim_aux, elim_stack]
    exact h₂
  case cons₂ ns k IH =>
    obtain ⟨c, h₁, h₂⟩ := IH (ns.headI :: v) none
    exact ⟨c, h₁, TransGen.head rfl <| head_stack_ok.trans h₂⟩
  case comp f k _ =>
    obtain ⟨s', h₁, h₂⟩ := trNormal_respects f k v s
    exact ⟨_, h₁, TransGen.head rfl h₂⟩
  case fix f k IH =>
    rw [stepRet]
    have :
      if v.headI = 0 then natEnd (trList v).head?.iget = true ∧ (trList v).tail = trList v.tail
      else
        natEnd (trList v).head?.iget = false ∧
          (trList v).tail = (trNat v.headI).tail ++ Γ'.cons :: trList v.tail := by
      cases' v with n
      · exact ⟨rfl, rfl⟩
      cases' n with n
      · simp
      rw [trList, List.headI, trNat, Nat.cast_succ, Num.add_one, Num.succ, List.tail]
      cases (n : Num).succ' <;> exact ⟨rfl, rfl⟩
    

Proof state:
f : Code
k : Cont
IH :
  ∀ (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepRet k v) b₂ ∧
        Reaches₁ (TM2.step tr) { l := some (Λ'.ret (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) }
          b₂
v : List ℕ
s : Option Γ'
this :
  if List.headI v = 0 then
    natEnd (Option.iget (List.head? (trList v))) = true ∧ List.tail (trList v) = trList (List.tail v)
  else
    natEnd (Option.iget (List.head? (trList v))) = false ∧
      List.tail (trList v) = List.tail (trNat (List.headI v)) ++ Γ'.cons :: trList (List.tail v)
⊢ ∃ b₂,
    TrCfg (if List.headI v = 0 then stepRet k (List.tail v) else stepNormal f (Cont.fix f k) (List.tail v)) b₂ ∧
      Reaches₁ (TM2.step tr)
        { l := some (Λ'.ret (trCont (Cont.fix f k))), var := s,
          stk := elim (trList v) [] [] (trContStack (Cont.fix f k)) }
        b₂

Next tactic:
by_cases h : v.headI = 0
theorem tr_ret_respects (k v s) : ∃ b₂,
    TrCfg (stepRet k v) b₂ ∧
      Reaches₁ (TM2.step tr)
        ⟨some (Λ'.ret (trCont k)), s, K'.elim (trList v) [] [] (trContStack k)⟩ b₂ := by
  induction k generalizing v s
  case halt => exact ⟨_, rfl, TransGen.single rfl⟩
  case
    cons₁ fs as k _ =>
    obtain ⟨s', h₁, h₂⟩ := trNormal_respects fs (Cont.cons₂ v k) as none
    refine' ⟨s', h₁, TransGen.head rfl _⟩; simp
    refine' (move₂_ok (by decide) _ (splitAtPred_false _)).trans _; · rfl
    simp only [TM2.step, Option.mem_def, Option.elim, id_eq, elim_update_main, elim_main, elim_aux,
      List.append_nil, elim_update_aux]
    refine' (move₂_ok (by decide) _ _).trans _; pick_goal 4; · rfl
    pick_goal 4;
    · exact
        splitAtPred_eq _ _ _ (some Γ'.consₗ) _
          (fun x h => Bool.decide_false (trList_ne_consₗ _ _ h)) ⟨rfl, rfl⟩
    refine' (move₂_ok (by decide) _ (splitAtPred_false _)).trans _; · rfl
    simp only [TM2.step, Option.mem_def, Option.elim, elim_update_stack, elim_main,
      List.append_nil, elim_update_main,  id_eq, elim_update_aux, ne_eq, Function.update_noteq,
      elim_aux, elim_stack]
    exact h₂
  case cons₂ ns k IH =>
    obtain ⟨c, h₁, h₂⟩ := IH (ns.headI :: v) none
    exact ⟨c, h₁, TransGen.head rfl <| head_stack_ok.trans h₂⟩
  case comp f k _ =>
    obtain ⟨s', h₁, h₂⟩ := trNormal_respects f k v s
    exact ⟨_, h₁, TransGen.head rfl h₂⟩
  case fix f k IH =>
    rw [stepRet]
    have :
      if v.headI = 0 then natEnd (trList v).head?.iget = true ∧ (trList v).tail = trList v.tail
      else
        natEnd (trList v).head?.iget = false ∧
          (trList v).tail = (trNat v.headI).tail ++ Γ'.cons :: trList v.tail := by
      cases' v with n
      · exact ⟨rfl, rfl⟩
      cases' n with n
      · simp
      rw [trList, List.headI, trNat, Nat.cast_succ, Num.add_one, Num.succ, List.tail]
      cases (n : Num).succ' <;> exact ⟨rfl, rfl⟩
    by_cases h : v.headI = 0 <;> 

Proof state:
case pos
f : Code
k : Cont
IH :
  ∀ (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepRet k v) b₂ ∧
        Reaches₁ (TM2.step tr) { l := some (Λ'.ret (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) }
          b₂
v : List ℕ
s : Option Γ'
this :
  if List.headI v = 0 then
    natEnd (Option.iget (List.head? (trList v))) = true ∧ List.tail (trList v) = trList (List.tail v)
  else
    natEnd (Option.iget (List.head? (trList v))) = false ∧
      List.tail (trList v) = List.tail (trNat (List.headI v)) ++ Γ'.cons :: trList (List.tail v)
h : List.headI v = 0
⊢ ∃ b₂,
    TrCfg (if List.headI v = 0 then stepRet k (List.tail v) else stepNormal f (Cont.fix f k) (List.tail v)) b₂ ∧
      Reaches₁ (TM2.step tr)
        { l := some (Λ'.ret (trCont (Cont.fix f k))), var := s,
          stk := elim (trList v) [] [] (trContStack (Cont.fix f k)) }
        b₂

Next tactic:
simp only [h, ite_true, ite_false] at this ⊢
theorem tr_ret_respects (k v s) : ∃ b₂,
    TrCfg (stepRet k v) b₂ ∧
      Reaches₁ (TM2.step tr)
        ⟨some (Λ'.ret (trCont k)), s, K'.elim (trList v) [] [] (trContStack k)⟩ b₂ := by
  induction k generalizing v s
  case halt => exact ⟨_, rfl, TransGen.single rfl⟩
  case
    cons₁ fs as k _ =>
    obtain ⟨s', h₁, h₂⟩ := trNormal_respects fs (Cont.cons₂ v k) as none
    refine' ⟨s', h₁, TransGen.head rfl _⟩; simp
    refine' (move₂_ok (by decide) _ (splitAtPred_false _)).trans _; · rfl
    simp only [TM2.step, Option.mem_def, Option.elim, id_eq, elim_update_main, elim_main, elim_aux,
      List.append_nil, elim_update_aux]
    refine' (move₂_ok (by decide) _ _).trans _; pick_goal 4; · rfl
    pick_goal 4;
    · exact
        splitAtPred_eq _ _ _ (some Γ'.consₗ) _
          (fun x h => Bool.decide_false (trList_ne_consₗ _ _ h)) ⟨rfl, rfl⟩
    refine' (move₂_ok (by decide) _ (splitAtPred_false _)).trans _; · rfl
    simp only [TM2.step, Option.mem_def, Option.elim, elim_update_stack, elim_main,
      List.append_nil, elim_update_main,  id_eq, elim_update_aux, ne_eq, Function.update_noteq,
      elim_aux, elim_stack]
    exact h₂
  case cons₂ ns k IH =>
    obtain ⟨c, h₁, h₂⟩ := IH (ns.headI :: v) none
    exact ⟨c, h₁, TransGen.head rfl <| head_stack_ok.trans h₂⟩
  case comp f k _ =>
    obtain ⟨s', h₁, h₂⟩ := trNormal_respects f k v s
    exact ⟨_, h₁, TransGen.head rfl h₂⟩
  case fix f k IH =>
    rw [stepRet]
    have :
      if v.headI = 0 then natEnd (trList v).head?.iget = true ∧ (trList v).tail = trList v.tail
      else
        natEnd (trList v).head?.iget = false ∧
          (trList v).tail = (trNat v.headI).tail ++ Γ'.cons :: trList v.tail := by
      cases' v with n
      · exact ⟨rfl, rfl⟩
      cases' n with n
      · simp
      rw [trList, List.headI, trNat, Nat.cast_succ, Num.add_one, Num.succ, List.tail]
      cases (n : Num).succ' <;> exact ⟨rfl, rfl⟩
    by_cases h : v.headI = 0 <;> 

Proof state:
case neg
f : Code
k : Cont
IH :
  ∀ (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepRet k v) b₂ ∧
        Reaches₁ (TM2.step tr) { l := some (Λ'.ret (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) }
          b₂
v : List ℕ
s : Option Γ'
this :
  if List.headI v = 0 then
    natEnd (Option.iget (List.head? (trList v))) = true ∧ List.tail (trList v) = trList (List.tail v)
  else
    natEnd (Option.iget (List.head? (trList v))) = false ∧
      List.tail (trList v) = List.tail (trNat (List.headI v)) ++ Γ'.cons :: trList (List.tail v)
h : ¬List.headI v = 0
⊢ ∃ b₂,
    TrCfg (if List.headI v = 0 then stepRet k (List.tail v) else stepNormal f (Cont.fix f k) (List.tail v)) b₂ ∧
      Reaches₁ (TM2.step tr)
        { l := some (Λ'.ret (trCont (Cont.fix f k))), var := s,
          stk := elim (trList v) [] [] (trContStack (Cont.fix f k)) }
        b₂

Next tactic:
simp only [h, ite_true, ite_false] at this ⊢
theorem tr_ret_respects (k v s) : ∃ b₂,
    TrCfg (stepRet k v) b₂ ∧
      Reaches₁ (TM2.step tr)
        ⟨some (Λ'.ret (trCont k)), s, K'.elim (trList v) [] [] (trContStack k)⟩ b₂ := by
  induction k generalizing v s
  case halt => exact ⟨_, rfl, TransGen.single rfl⟩
  case
    cons₁ fs as k _ =>
    obtain ⟨s', h₁, h₂⟩ := trNormal_respects fs (Cont.cons₂ v k) as none
    refine' ⟨s', h₁, TransGen.head rfl _⟩; simp
    refine' (move₂_ok (by decide) _ (splitAtPred_false _)).trans _; · rfl
    simp only [TM2.step, Option.mem_def, Option.elim, id_eq, elim_update_main, elim_main, elim_aux,
      List.append_nil, elim_update_aux]
    refine' (move₂_ok (by decide) _ _).trans _; pick_goal 4; · rfl
    pick_goal 4;
    · exact
        splitAtPred_eq _ _ _ (some Γ'.consₗ) _
          (fun x h => Bool.decide_false (trList_ne_consₗ _ _ h)) ⟨rfl, rfl⟩
    refine' (move₂_ok (by decide) _ (splitAtPred_false _)).trans _; · rfl
    simp only [TM2.step, Option.mem_def, Option.elim, elim_update_stack, elim_main,
      List.append_nil, elim_update_main,  id_eq, elim_update_aux, ne_eq, Function.update_noteq,
      elim_aux, elim_stack]
    exact h₂
  case cons₂ ns k IH =>
    obtain ⟨c, h₁, h₂⟩ := IH (ns.headI :: v) none
    exact ⟨c, h₁, TransGen.head rfl <| head_stack_ok.trans h₂⟩
  case comp f k _ =>
    obtain ⟨s', h₁, h₂⟩ := trNormal_respects f k v s
    exact ⟨_, h₁, TransGen.head rfl h₂⟩
  case fix f k IH =>
    rw [stepRet]
    have :
      if v.headI = 0 then natEnd (trList v).head?.iget = true ∧ (trList v).tail = trList v.tail
      else
        natEnd (trList v).head?.iget = false ∧
          (trList v).tail = (trNat v.headI).tail ++ Γ'.cons :: trList v.tail := by
      cases' v with n
      · exact ⟨rfl, rfl⟩
      cases' n with n
      · simp
      rw [trList, List.headI, trNat, Nat.cast_succ, Num.add_one, Num.succ, List.tail]
      cases (n : Num).succ' <;> exact ⟨rfl, rfl⟩
    by_cases h : v.headI = 0 <;> simp only [h, ite_true, ite_false] at this ⊢
    · 

Proof state:
case pos
f : Code
k : Cont
IH :
  ∀ (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepRet k v) b₂ ∧
        Reaches₁ (TM2.step tr) { l := some (Λ'.ret (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) }
          b₂
v : List ℕ
s : Option Γ'
h : List.headI v = 0
this : natEnd (Option.iget (List.head? (trList v))) = true ∧ List.tail (trList v) = trList (List.tail v)
⊢ ∃ b₂,
    TrCfg (stepRet k (List.tail v)) b₂ ∧
      Reaches₁ (TM2.step tr)
        { l := some (Λ'.ret (trCont (Cont.fix f k))), var := s,
          stk := elim (trList v) [] [] (trContStack (Cont.fix f k)) }
        b₂

Next tactic:
obtain ⟨c, h₁, h₂⟩ := IH v.tail (trList v).head?
theorem tr_ret_respects (k v s) : ∃ b₂,
    TrCfg (stepRet k v) b₂ ∧
      Reaches₁ (TM2.step tr)
        ⟨some (Λ'.ret (trCont k)), s, K'.elim (trList v) [] [] (trContStack k)⟩ b₂ := by
  induction k generalizing v s
  case halt => exact ⟨_, rfl, TransGen.single rfl⟩
  case
    cons₁ fs as k _ =>
    obtain ⟨s', h₁, h₂⟩ := trNormal_respects fs (Cont.cons₂ v k) as none
    refine' ⟨s', h₁, TransGen.head rfl _⟩; simp
    refine' (move₂_ok (by decide) _ (splitAtPred_false _)).trans _; · rfl
    simp only [TM2.step, Option.mem_def, Option.elim, id_eq, elim_update_main, elim_main, elim_aux,
      List.append_nil, elim_update_aux]
    refine' (move₂_ok (by decide) _ _).trans _; pick_goal 4; · rfl
    pick_goal 4;
    · exact
        splitAtPred_eq _ _ _ (some Γ'.consₗ) _
          (fun x h => Bool.decide_false (trList_ne_consₗ _ _ h)) ⟨rfl, rfl⟩
    refine' (move₂_ok (by decide) _ (splitAtPred_false _)).trans _; · rfl
    simp only [TM2.step, Option.mem_def, Option.elim, elim_update_stack, elim_main,
      List.append_nil, elim_update_main,  id_eq, elim_update_aux, ne_eq, Function.update_noteq,
      elim_aux, elim_stack]
    exact h₂
  case cons₂ ns k IH =>
    obtain ⟨c, h₁, h₂⟩ := IH (ns.headI :: v) none
    exact ⟨c, h₁, TransGen.head rfl <| head_stack_ok.trans h₂⟩
  case comp f k _ =>
    obtain ⟨s', h₁, h₂⟩ := trNormal_respects f k v s
    exact ⟨_, h₁, TransGen.head rfl h₂⟩
  case fix f k IH =>
    rw [stepRet]
    have :
      if v.headI = 0 then natEnd (trList v).head?.iget = true ∧ (trList v).tail = trList v.tail
      else
        natEnd (trList v).head?.iget = false ∧
          (trList v).tail = (trNat v.headI).tail ++ Γ'.cons :: trList v.tail := by
      cases' v with n
      · exact ⟨rfl, rfl⟩
      cases' n with n
      · simp
      rw [trList, List.headI, trNat, Nat.cast_succ, Num.add_one, Num.succ, List.tail]
      cases (n : Num).succ' <;> exact ⟨rfl, rfl⟩
    by_cases h : v.headI = 0 <;> simp only [h, ite_true, ite_false] at this ⊢
    · obtain ⟨c, h₁, h₂⟩ := IH v.tail (trList v).head?
      

Proof state:
case pos.intro.intro
f : Code
k : Cont
IH :
  ∀ (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepRet k v) b₂ ∧
        Reaches₁ (TM2.step tr) { l := some (Λ'.ret (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) }
          b₂
v : List ℕ
s : Option Γ'
h : List.headI v = 0
this : natEnd (Option.iget (List.head? (trList v))) = true ∧ List.tail (trList v) = trList (List.tail v)
c : Cfg'
h₁ : TrCfg (stepRet k (List.tail v)) c
h₂ :
  Reaches₁ (TM2.step tr)
    { l := some (Λ'.ret (trCont k)), var := List.head? (trList v),
      stk := elim (trList (List.tail v)) [] [] (trContStack k) }
    c
⊢ ∃ b₂,
    TrCfg (stepRet k (List.tail v)) b₂ ∧
      Reaches₁ (TM2.step tr)
        { l := some (Λ'.ret (trCont (Cont.fix f k))), var := s,
          stk := elim (trList v) [] [] (trContStack (Cont.fix f k)) }
        b₂

Next tactic:
refine' ⟨c, h₁, TransGen.head rfl _⟩
theorem tr_ret_respects (k v s) : ∃ b₂,
    TrCfg (stepRet k v) b₂ ∧
      Reaches₁ (TM2.step tr)
        ⟨some (Λ'.ret (trCont k)), s, K'.elim (trList v) [] [] (trContStack k)⟩ b₂ := by
  induction k generalizing v s
  case halt => exact ⟨_, rfl, TransGen.single rfl⟩
  case
    cons₁ fs as k _ =>
    obtain ⟨s', h₁, h₂⟩ := trNormal_respects fs (Cont.cons₂ v k) as none
    refine' ⟨s', h₁, TransGen.head rfl _⟩; simp
    refine' (move₂_ok (by decide) _ (splitAtPred_false _)).trans _; · rfl
    simp only [TM2.step, Option.mem_def, Option.elim, id_eq, elim_update_main, elim_main, elim_aux,
      List.append_nil, elim_update_aux]
    refine' (move₂_ok (by decide) _ _).trans _; pick_goal 4; · rfl
    pick_goal 4;
    · exact
        splitAtPred_eq _ _ _ (some Γ'.consₗ) _
          (fun x h => Bool.decide_false (trList_ne_consₗ _ _ h)) ⟨rfl, rfl⟩
    refine' (move₂_ok (by decide) _ (splitAtPred_false _)).trans _; · rfl
    simp only [TM2.step, Option.mem_def, Option.elim, elim_update_stack, elim_main,
      List.append_nil, elim_update_main,  id_eq, elim_update_aux, ne_eq, Function.update_noteq,
      elim_aux, elim_stack]
    exact h₂
  case cons₂ ns k IH =>
    obtain ⟨c, h₁, h₂⟩ := IH (ns.headI :: v) none
    exact ⟨c, h₁, TransGen.head rfl <| head_stack_ok.trans h₂⟩
  case comp f k _ =>
    obtain ⟨s', h₁, h₂⟩ := trNormal_respects f k v s
    exact ⟨_, h₁, TransGen.head rfl h₂⟩
  case fix f k IH =>
    rw [stepRet]
    have :
      if v.headI = 0 then natEnd (trList v).head?.iget = true ∧ (trList v).tail = trList v.tail
      else
        natEnd (trList v).head?.iget = false ∧
          (trList v).tail = (trNat v.headI).tail ++ Γ'.cons :: trList v.tail := by
      cases' v with n
      · exact ⟨rfl, rfl⟩
      cases' n with n
      · simp
      rw [trList, List.headI, trNat, Nat.cast_succ, Num.add_one, Num.succ, List.tail]
      cases (n : Num).succ' <;> exact ⟨rfl, rfl⟩
    by_cases h : v.headI = 0 <;> simp only [h, ite_true, ite_false] at this ⊢
    · obtain ⟨c, h₁, h₂⟩ := IH v.tail (trList v).head?
      refine' ⟨c, h₁, TransGen.head rfl _⟩
      

Proof state:
case pos.intro.intro
f : Code
k : Cont
IH :
  ∀ (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepRet k v) b₂ ∧
        Reaches₁ (TM2.step tr) { l := some (Λ'.ret (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) }
          b₂
v : List ℕ
s : Option Γ'
h : List.headI v = 0
this : natEnd (Option.iget (List.head? (trList v))) = true ∧ List.tail (trList v) = trList (List.tail v)
c : Cfg'
h₁ : TrCfg (stepRet k (List.tail v)) c
h₂ :
  Reaches₁ (TM2.step tr)
    { l := some (Λ'.ret (trCont k)), var := List.head? (trList v),
      stk := elim (trList (List.tail v)) [] [] (trContStack k) }
    c
⊢ TransGen (fun a b => b ∈ TM2.step tr a)
    (TM2.stepAux (tr (Λ'.ret (trCont (Cont.fix f k)))) s (elim (trList v) [] [] (trContStack (Cont.fix f k)))) c

Next tactic:
simp only [Option.mem_def, TM2.stepAux, trContStack, contStack, elim_main, this, cond_true,
        elim_update_main]
theorem tr_ret_respects (k v s) : ∃ b₂,
    TrCfg (stepRet k v) b₂ ∧
      Reaches₁ (TM2.step tr)
        ⟨some (Λ'.ret (trCont k)), s, K'.elim (trList v) [] [] (trContStack k)⟩ b₂ := by
  induction k generalizing v s
  case halt => exact ⟨_, rfl, TransGen.single rfl⟩
  case
    cons₁ fs as k _ =>
    obtain ⟨s', h₁, h₂⟩ := trNormal_respects fs (Cont.cons₂ v k) as none
    refine' ⟨s', h₁, TransGen.head rfl _⟩; simp
    refine' (move₂_ok (by decide) _ (splitAtPred_false _)).trans _; · rfl
    simp only [TM2.step, Option.mem_def, Option.elim, id_eq, elim_update_main, elim_main, elim_aux,
      List.append_nil, elim_update_aux]
    refine' (move₂_ok (by decide) _ _).trans _; pick_goal 4; · rfl
    pick_goal 4;
    · exact
        splitAtPred_eq _ _ _ (some Γ'.consₗ) _
          (fun x h => Bool.decide_false (trList_ne_consₗ _ _ h)) ⟨rfl, rfl⟩
    refine' (move₂_ok (by decide) _ (splitAtPred_false _)).trans _; · rfl
    simp only [TM2.step, Option.mem_def, Option.elim, elim_update_stack, elim_main,
      List.append_nil, elim_update_main,  id_eq, elim_update_aux, ne_eq, Function.update_noteq,
      elim_aux, elim_stack]
    exact h₂
  case cons₂ ns k IH =>
    obtain ⟨c, h₁, h₂⟩ := IH (ns.headI :: v) none
    exact ⟨c, h₁, TransGen.head rfl <| head_stack_ok.trans h₂⟩
  case comp f k _ =>
    obtain ⟨s', h₁, h₂⟩ := trNormal_respects f k v s
    exact ⟨_, h₁, TransGen.head rfl h₂⟩
  case fix f k IH =>
    rw [stepRet]
    have :
      if v.headI = 0 then natEnd (trList v).head?.iget = true ∧ (trList v).tail = trList v.tail
      else
        natEnd (trList v).head?.iget = false ∧
          (trList v).tail = (trNat v.headI).tail ++ Γ'.cons :: trList v.tail := by
      cases' v with n
      · exact ⟨rfl, rfl⟩
      cases' n with n
      · simp
      rw [trList, List.headI, trNat, Nat.cast_succ, Num.add_one, Num.succ, List.tail]
      cases (n : Num).succ' <;> exact ⟨rfl, rfl⟩
    by_cases h : v.headI = 0 <;> simp only [h, ite_true, ite_false] at this ⊢
    · obtain ⟨c, h₁, h₂⟩ := IH v.tail (trList v).head?
      refine' ⟨c, h₁, TransGen.head rfl _⟩
      simp only [Option.mem_def, TM2.stepAux, trContStack, contStack, elim_main, this, cond_true,
        elim_update_main]
      

Proof state:
case pos.intro.intro
f : Code
k : Cont
IH :
  ∀ (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepRet k v) b₂ ∧
        Reaches₁ (TM2.step tr) { l := some (Λ'.ret (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) }
          b₂
v : List ℕ
s : Option Γ'
h : List.headI v = 0
this : natEnd (Option.iget (List.head? (trList v))) = true ∧ List.tail (trList v) = trList (List.tail v)
c : Cfg'
h₁ : TrCfg (stepRet k (List.tail v)) c
h₂ :
  Reaches₁ (TM2.step tr)
    { l := some (Λ'.ret (trCont k)), var := List.head? (trList v),
      stk := elim (trList (List.tail v)) [] [] (trContStack k) }
    c
⊢ TransGen (fun a b => TM2.step tr a = some b)
    { l := some (Λ'.ret (trCont k)), var := List.head? (trList v),
      stk := elim (trList (List.tail v)) [] [] (trLList (contStack k)) }
    c

Next tactic:
exact h₂
theorem tr_ret_respects (k v s) : ∃ b₂,
    TrCfg (stepRet k v) b₂ ∧
      Reaches₁ (TM2.step tr)
        ⟨some (Λ'.ret (trCont k)), s, K'.elim (trList v) [] [] (trContStack k)⟩ b₂ := by
  induction k generalizing v s
  case halt => exact ⟨_, rfl, TransGen.single rfl⟩
  case
    cons₁ fs as k _ =>
    obtain ⟨s', h₁, h₂⟩ := trNormal_respects fs (Cont.cons₂ v k) as none
    refine' ⟨s', h₁, TransGen.head rfl _⟩; simp
    refine' (move₂_ok (by decide) _ (splitAtPred_false _)).trans _; · rfl
    simp only [TM2.step, Option.mem_def, Option.elim, id_eq, elim_update_main, elim_main, elim_aux,
      List.append_nil, elim_update_aux]
    refine' (move₂_ok (by decide) _ _).trans _; pick_goal 4; · rfl
    pick_goal 4;
    · exact
        splitAtPred_eq _ _ _ (some Γ'.consₗ) _
          (fun x h => Bool.decide_false (trList_ne_consₗ _ _ h)) ⟨rfl, rfl⟩
    refine' (move₂_ok (by decide) _ (splitAtPred_false _)).trans _; · rfl
    simp only [TM2.step, Option.mem_def, Option.elim, elim_update_stack, elim_main,
      List.append_nil, elim_update_main,  id_eq, elim_update_aux, ne_eq, Function.update_noteq,
      elim_aux, elim_stack]
    exact h₂
  case cons₂ ns k IH =>
    obtain ⟨c, h₁, h₂⟩ := IH (ns.headI :: v) none
    exact ⟨c, h₁, TransGen.head rfl <| head_stack_ok.trans h₂⟩
  case comp f k _ =>
    obtain ⟨s', h₁, h₂⟩ := trNormal_respects f k v s
    exact ⟨_, h₁, TransGen.head rfl h₂⟩
  case fix f k IH =>
    rw [stepRet]
    have :
      if v.headI = 0 then natEnd (trList v).head?.iget = true ∧ (trList v).tail = trList v.tail
      else
        natEnd (trList v).head?.iget = false ∧
          (trList v).tail = (trNat v.headI).tail ++ Γ'.cons :: trList v.tail := by
      cases' v with n
      · exact ⟨rfl, rfl⟩
      cases' n with n
      · simp
      rw [trList, List.headI, trNat, Nat.cast_succ, Num.add_one, Num.succ, List.tail]
      cases (n : Num).succ' <;> exact ⟨rfl, rfl⟩
    by_cases h : v.headI = 0 <;> simp only [h, ite_true, ite_false] at this ⊢
    · obtain ⟨c, h₁, h₂⟩ := IH v.tail (trList v).head?
      refine' ⟨c, h₁, TransGen.head rfl _⟩
      simp only [Option.mem_def, TM2.stepAux, trContStack, contStack, elim_main, this, cond_true,
        elim_update_main]
      exact h₂
    · 

Proof state:
case neg
f : Code
k : Cont
IH :
  ∀ (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepRet k v) b₂ ∧
        Reaches₁ (TM2.step tr) { l := some (Λ'.ret (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) }
          b₂
v : List ℕ
s : Option Γ'
h : ¬List.headI v = 0
this :
  natEnd (Option.iget (List.head? (trList v))) = false ∧
    List.tail (trList v) = List.tail (trNat (List.headI v)) ++ Γ'.cons :: trList (List.tail v)
⊢ ∃ b₂,
    TrCfg (stepNormal f (Cont.fix f k) (List.tail v)) b₂ ∧
      Reaches₁ (TM2.step tr)
        { l := some (Λ'.ret (trCont (Cont.fix f k))), var := s,
          stk := elim (trList v) [] [] (trContStack (Cont.fix f k)) }
        b₂

Next tactic:
obtain ⟨s', h₁, h₂⟩ := trNormal_respects f (Cont.fix f k) v.tail (some Γ'.cons)
theorem tr_eval (c v) : eval (TM2.step tr) (init c v) = halt <$> Code.eval c v := by
  

Proof state:
c : Code
v : List ℕ
⊢ eval (TM2.step tr) (init c v) = halt <$> Code.eval c v

Next tactic:
obtain ⟨i, h₁, h₂⟩ := tr_init c v
theorem tr_eval (c v) : eval (TM2.step tr) (init c v) = halt <$> Code.eval c v := by
  obtain ⟨i, h₁, h₂⟩ := tr_init c v
  

Proof state:
case intro.intro
c : Code
v : List ℕ
i : Cfg'
h₁ : TrCfg (stepNormal c Cont.halt v) i
h₂ : Reaches₁ (TM2.step tr) (init c v) i
⊢ eval (TM2.step tr) (init c v) = halt <$> Code.eval c v

Next tactic:
refine' Part.ext fun x => _
theorem tr_eval (c v) : eval (TM2.step tr) (init c v) = halt <$> Code.eval c v := by
  obtain ⟨i, h₁, h₂⟩ := tr_init c v
  refine' Part.ext fun x => _
  

Proof state:
case intro.intro
c : Code
v : List ℕ
i : Cfg'
h₁ : TrCfg (stepNormal c Cont.halt v) i
h₂ : Reaches₁ (TM2.step tr) (init c v) i
x : TM2.Cfg (fun x => Γ') Λ' (Option Γ')
⊢ x ∈ eval (TM2.step tr) (init c v) ↔ x ∈ halt <$> Code.eval c v

Next tactic:
rw [reaches_eval h₂.to_reflTransGen]