l3lab/ntp-mathlib huggingface dataset:
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; swap
    

Proof state:
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))
case convert_5 k : Cont v : List ℕ s : Option Γ' o : Option Γ' := List.casesOn v none fun x x => some Γ'.cons ⊢ List Γ'

Next tactic:
refine' splitAtPred_eq _ _ (trNat v.headI) _ _ (trNat_natEnd _) _
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; swap
    refine' splitAtPred_eq _ _ (trNat v.headI) _ _ (trNat_natEnd _) _
    

Proof state:
case convert_9
k : Cont
v : List ℕ
s : Option Γ'
o : Option Γ' := List.casesOn v none fun x x => some Γ'.cons
⊢ Option.elim' (elim (trList v) [] [] (trContStack k) main = trNat (List.headI v) ∧ trList (List.tail v) = [])
    (fun a =>
      natEnd a = true ∧ elim (trList v) [] [] (trContStack k) main = trNat (List.headI v) ++ a :: trList (List.tail v))
    o

Next tactic:
cases v
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; swap
    refine' splitAtPred_eq _ _ (trNat v.headI) _ _ (trNat_natEnd _) _
    cases v <;> 

Proof state:
case convert_9.nil
k : Cont
s : Option Γ'
o : Option Γ' := List.casesOn [] none fun x x => some Γ'.cons
⊢ Option.elim' (elim (trList []) [] [] (trContStack k) main = trNat (List.headI []) ∧ trList (List.tail []) = [])
    (fun a =>
      natEnd a = true ∧
        elim (trList []) [] [] (trContStack k) main = trNat (List.headI []) ++ a :: trList (List.tail []))
    o

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; rfl; swap
    refine' splitAtPred_eq _ _ (trNat v.headI) _ _ (trNat_natEnd _) _
    cases v <;> 

Proof state:
case convert_9.cons
k : Cont
s : Option Γ'
head✝ : ℕ
tail✝ : List ℕ
o : Option Γ' := List.casesOn (head✝ :: tail✝) none fun x x => some Γ'.cons
⊢ Option.elim'
    (elim (trList (head✝ :: tail✝)) [] [] (trContStack k) main = trNat (List.headI (head✝ :: tail✝)) ∧
      trList (List.tail (head✝ :: tail✝)) = [])
    (fun a =>
      natEnd a = true ∧
        elim (trList (head✝ :: tail✝)) [] [] (trContStack k) main =
          trNat (List.headI (head✝ :: tail✝)) ++ a :: trList (List.tail (head✝ :: tail✝)))
    o

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; rfl; swap
    refine' splitAtPred_eq _ _ (trNat v.headI) _ _ (trNat_natEnd _) _
    cases v <;> simp
  

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

Next tactic:
case
    cons f fs IHf _ =>
    obtain ⟨c, h₁, h₂⟩ := IHf (Cont.cons₁ fs v k) v none
    refine' ⟨c, h₁, TransGen.head rfl <| (move_ok (by decide) (splitAtPred_false _)).trans _⟩
    simp only [TM2.step, Option.mem_def, elim_stack, elim_update_stack, elim_update_main, ne_eq,
      Function.update_noteq, elim_main, elim_rev, elim_update_rev]
    refine' (copy_ok _ none [] (trList v).reverse _ _).trans _
    convert h₂ using 2
    simp [List.reverseAux_eq, trContStack]
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; swap
    refine' splitAtPred_eq _ _ (trNat v.headI) _ _ (trNat_natEnd _) _
    cases v <;> simp
  case
    cons f fs IHf _ =>
    

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

Next tactic:
obtain ⟨c, h₁, h₂⟩ := IHf (Cont.cons₁ fs v k) v none
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; swap
    refine' splitAtPred_eq _ _ (trNat v.headI) _ _ (trNat_natEnd _) _
    cases v <;> simp
  case
    cons f fs IHf _ =>
    obtain ⟨c, h₁, h₂⟩ := IHf (Cont.cons₁ fs v k) v none
    

Proof state:
case intro.intro
f fs : Code
IHf :
  ∀ (k : Cont) (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepNormal f k v) b₂ ∧
        Reaches₁ (TM2.step tr)
          { l := some (trNormal f (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) } b₂
a_ih✝ :
  ∀ (k : Cont) (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepNormal fs k v) b₂ ∧
        Reaches₁ (TM2.step tr)
          { l := some (trNormal fs (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) } b₂
k : Cont
v : List ℕ
s : Option Γ'
c : Cfg'
h₁ : TrCfg (stepNormal f (Cont.cons₁ fs v k) v) c
h₂ :
  Reaches₁ (TM2.step tr)
    { l := some (trNormal f (trCont (Cont.cons₁ fs v k))), var := none,
      stk := elim (trList v) [] [] (trContStack (Cont.cons₁ fs v k)) }
    c
⊢ ∃ b₂,
    TrCfg (stepNormal (Code.cons f fs) k v) b₂ ∧
      Reaches₁ (TM2.step tr)
        { l := some (trNormal (Code.cons f fs) (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) } b₂

Next tactic:
refine' ⟨c, h₁, TransGen.head rfl <| (move_ok (by decide) (splitAtPred_false _)).trans _⟩
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; swap
    refine' splitAtPred_eq _ _ (trNat v.headI) _ _ (trNat_natEnd _) _
    cases v <;> simp
  case
    cons f fs IHf _ =>
    obtain ⟨c, h₁, h₂⟩ := IHf (Cont.cons₁ fs v k) v none
    refine' ⟨c, h₁, TransGen.head rfl <| (move_ok (by 

Proof state:
f fs : Code
IHf :
  ∀ (k : Cont) (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepNormal f k v) b₂ ∧
        Reaches₁ (TM2.step tr)
          { l := some (trNormal f (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) } b₂
a_ih✝ :
  ∀ (k : Cont) (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepNormal fs k v) b₂ ∧
        Reaches₁ (TM2.step tr)
          { l := some (trNormal fs (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) } b₂
k : Cont
v : List ℕ
s : Option Γ'
c : Cfg'
h₁ : TrCfg (stepNormal f (Cont.cons₁ fs v k) v) c
h₂ :
  Reaches₁ (TM2.step tr)
    { l := some (trNormal f (trCont (Cont.cons₁ fs v k))), var := none,
      stk := elim (trList v) [] [] (trContStack (Cont.cons₁ fs v k)) }
    c
⊢ main ≠ rev

Next tactic:
decide
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; swap
    refine' splitAtPred_eq _ _ (trNat v.headI) _ _ (trNat_natEnd _) _
    cases v <;> simp
  case
    cons f fs IHf _ =>
    obtain ⟨c, h₁, h₂⟩ := IHf (Cont.cons₁ fs v k) v none
    refine' ⟨c, h₁, TransGen.head rfl <| (move_ok (by decide) (splitAtPred_false _)).trans _⟩
    

Proof state:
case intro.intro
f fs : Code
IHf :
  ∀ (k : Cont) (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepNormal f k v) b₂ ∧
        Reaches₁ (TM2.step tr)
          { l := some (trNormal f (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) } b₂
a_ih✝ :
  ∀ (k : Cont) (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepNormal fs k v) b₂ ∧
        Reaches₁ (TM2.step tr)
          { l := some (trNormal fs (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) } b₂
k : Cont
v : List ℕ
s : Option Γ'
c : Cfg'
h₁ : TrCfg (stepNormal f (Cont.cons₁ fs v k) v) c
h₂ :
  Reaches₁ (TM2.step tr)
    { l := some (trNormal f (trCont (Cont.cons₁ fs v k))), var := none,
      stk := elim (trList v) [] [] (trContStack (Cont.cons₁ fs v k)) }
    c
⊢ TransGen (fun a b => b ∈ TM2.step tr a)
    { l := some (Λ'.copy (trNormal f (Cont'.cons₁ fs (trCont k)))), var := none,
      stk :=
        update
          (update
            (update (elim (trList v) [] [] (trContStack k)) stack
              ((fun s => Option.iget ((fun x => some Γ'.consₗ) s)) s :: elim (trList v) [] [] (trContStack k) stack))
            main [])
          rev
          (List.reverseAux
            (update (elim (trList v) [] [] (trContStack k)) stack
              ((fun s => Option.iget ((fun x => some Γ'.consₗ) s)) s :: elim (trList v) [] [] (trContStack k) stack)
              main)
            (update (elim (trList v) [] [] (trContStack k)) stack
              ((fun s => Option.iget ((fun x => some Γ'.consₗ) s)) s :: elim (trList v) [] [] (trContStack k) stack)
              rev)) }
    c

Next tactic:
simp only [TM2.step, Option.mem_def, elim_stack, elim_update_stack, elim_update_main, ne_eq,
      Function.update_noteq, elim_main, elim_rev, elim_update_rev]
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; swap
    refine' splitAtPred_eq _ _ (trNat v.headI) _ _ (trNat_natEnd _) _
    cases v <;> simp
  case
    cons f fs IHf _ =>
    obtain ⟨c, h₁, h₂⟩ := IHf (Cont.cons₁ fs v k) v none
    refine' ⟨c, h₁, TransGen.head rfl <| (move_ok (by decide) (splitAtPred_false _)).trans _⟩
    simp only [TM2.step, Option.mem_def, elim_stack, elim_update_stack, elim_update_main, ne_eq,
      Function.update_noteq, elim_main, elim_rev, elim_update_rev]
    

Proof state:
case intro.intro
f fs : Code
IHf :
  ∀ (k : Cont) (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepNormal f k v) b₂ ∧
        Reaches₁ (TM2.step tr)
          { l := some (trNormal f (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) } b₂
a_ih✝ :
  ∀ (k : Cont) (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepNormal fs k v) b₂ ∧
        Reaches₁ (TM2.step tr)
          { l := some (trNormal fs (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) } b₂
k : Cont
v : List ℕ
s : Option Γ'
c : Cfg'
h₁ : TrCfg (stepNormal f (Cont.cons₁ fs v k) v) c
h₂ :
  Reaches₁ (TM2.step tr)
    { l := some (trNormal f (trCont (Cont.cons₁ fs v k))), var := none,
      stk := elim (trList v) [] [] (trContStack (Cont.cons₁ fs v k)) }
    c
⊢ 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 (Λ'.copy (trNormal f (Cont'.cons₁ fs (trCont k)))), var := none,
      stk := elim [] (List.reverseAux (trList v) []) [] (Option.iget (some Γ'.consₗ) :: trContStack k) }
    c

Next tactic:
refine' (copy_ok _ none [] (trList v).reverse _ _).trans _
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; swap
    refine' splitAtPred_eq _ _ (trNat v.headI) _ _ (trNat_natEnd _) _
    cases v <;> simp
  case
    cons f fs IHf _ =>
    obtain ⟨c, h₁, h₂⟩ := IHf (Cont.cons₁ fs v k) v none
    refine' ⟨c, h₁, TransGen.head rfl <| (move_ok (by decide) (splitAtPred_false _)).trans _⟩
    simp only [TM2.step, Option.mem_def, elim_stack, elim_update_stack, elim_update_main, ne_eq,
      Function.update_noteq, elim_main, elim_rev, elim_update_rev]
    refine' (copy_ok _ none [] (trList v).reverse _ _).trans _
    

Proof state:
case intro.intro
f fs : Code
IHf :
  ∀ (k : Cont) (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepNormal f k v) b₂ ∧
        Reaches₁ (TM2.step tr)
          { l := some (trNormal f (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) } b₂
a_ih✝ :
  ∀ (k : Cont) (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepNormal fs k v) b₂ ∧
        Reaches₁ (TM2.step tr)
          { l := some (trNormal fs (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) } b₂
k : Cont
v : List ℕ
s : Option Γ'
c : Cfg'
h₁ : TrCfg (stepNormal f (Cont.cons₁ fs v k) v) c
h₂ :
  Reaches₁ (TM2.step tr)
    { l := some (trNormal f (trCont (Cont.cons₁ fs v k))), var := none,
      stk := elim (trList v) [] [] (trContStack (Cont.cons₁ fs v k)) }
    c
⊢ TransGen (fun a b => b ∈ TM2.step tr a)
    { l := some (trNormal f (Cont'.cons₁ fs (trCont k))), var := none,
      stk :=
        elim (List.reverseAux (List.reverse (trList v)) []) [] []
          (List.reverseAux (List.reverse (trList v)) (Option.iget (some Γ'.consₗ) :: trContStack k)) }
    c

Next tactic:
convert h₂ 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; simp; rfl; swap
    refine' splitAtPred_eq _ _ (trNat v.headI) _ _ (trNat_natEnd _) _
    cases v <;> simp
  case
    cons f fs IHf _ =>
    obtain ⟨c, h₁, h₂⟩ := IHf (Cont.cons₁ fs v k) v none
    refine' ⟨c, h₁, TransGen.head rfl <| (move_ok (by decide) (splitAtPred_false _)).trans _⟩
    simp only [TM2.step, Option.mem_def, elim_stack, elim_update_stack, elim_update_main, ne_eq,
      Function.update_noteq, elim_main, elim_rev, elim_update_rev]
    refine' (copy_ok _ none [] (trList v).reverse _ _).trans _
    convert h₂ using 2
    

Proof state:
case h.e'_1.h.e'_7
f fs : Code
IHf :
  ∀ (k : Cont) (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepNormal f k v) b₂ ∧
        Reaches₁ (TM2.step tr)
          { l := some (trNormal f (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) } b₂
a_ih✝ :
  ∀ (k : Cont) (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepNormal fs k v) b₂ ∧
        Reaches₁ (TM2.step tr)
          { l := some (trNormal fs (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) } b₂
k : Cont
v : List ℕ
s : Option Γ'
c : Cfg'
h₁ : TrCfg (stepNormal f (Cont.cons₁ fs v k) v) c
h₂ :
  Reaches₁ (TM2.step tr)
    { l := some (trNormal f (trCont (Cont.cons₁ fs v k))), var := none,
      stk := elim (trList v) [] [] (trContStack (Cont.cons₁ fs v k)) }
    c
⊢ elim (List.reverseAux (List.reverse (trList v)) []) [] []
      (List.reverseAux (List.reverse (trList v)) (Option.iget (some Γ'.consₗ) :: trContStack k)) =
    elim (trList v) [] [] (trContStack (Cont.cons₁ fs v k))

Next tactic:
simp [List.reverseAux_eq, trContStack]
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; swap
    refine' splitAtPred_eq _ _ (trNat v.headI) _ _ (trNat_natEnd _) _
    cases v <;> simp
  case
    cons f fs IHf _ =>
    obtain ⟨c, h₁, h₂⟩ := IHf (Cont.cons₁ fs v k) v none
    refine' ⟨c, h₁, TransGen.head rfl <| (move_ok (by decide) (splitAtPred_false _)).trans _⟩
    simp only [TM2.step, Option.mem_def, elim_stack, elim_update_stack, elim_update_main, ne_eq,
      Function.update_noteq, elim_main, elim_rev, elim_update_rev]
    refine' (copy_ok _ none [] (trList v).reverse _ _).trans _
    convert h₂ using 2
    simp [List.reverseAux_eq, trContStack]
  

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

Next tactic:
case comp f _ _ IHg => exact IHg (Cont.comp f k) v s