-- Mathlib/Computability/TMToPartrec.lean
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₂

Proof state:
case cons.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))).copy, var := none,
      stk :=
        update
          (update
            (update (elim (trList v) [] [] (trContStack k)) stack
              ((fun s => ((fun x => some Γ'.consₗ) s).iget) s :: elim (trList v) [] [] (trContStack k) stack))
            main [])
          rev
          ((update (elim (trList v) [] [] (trContStack k)) stack
                ((fun s => ((fun x => some Γ'.consₗ) s).iget) s :: elim (trList v) [] [] (trContStack k) stack)
                main).reverseAux
            (update (elim (trList v) [] [] (trContStack k)) stack
              ((fun s => ((fun x => some Γ'.consₗ) s).iget) s :: elim (trList v) [] [] (trContStack k) stack) rev)) }
    c

Tactic:
simp only [TM2.step, Option.mem_def, elim_stack, elim_update_stack, elim_update_main, ne_eq,
  Function.update_of_ne, elim_main, elim_rev, elim_update_rev]

Result:
case cons.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 (trNormal f (Cont'.cons₁ fs (trCont k))).copy, var := none,
      stk := elim [] ((trList v).reverseAux []) [] ((some Γ'.consₗ).iget :: trContStack k) }
    c

Proof state:
case tail
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₂

Tactic:
let o : Option Γ' := List.casesOn v none fun _ _ => some Γ'.cons

Result:
case tail
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₂

Proof state:
case case.intro
f g : 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₂
IHg :
  ∀ (k : Cont) (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepNormal g k v) b₂ ∧
        Reaches₁ (TM2.step tr)
          { l := some (trNormal g (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) } b₂
k : Cont
v : List ℕ
s s' : Option Γ'
⊢ Reaches₁ (TM2.step tr)
      { l := some (Λ'.pred ?m.139559 ?m.139560), var := s, stk := elim (trList v) [] ?m.139561 ?m.139562 }
      (Nat.rec { l := some ?m.139559, var := s', stk := elim (trList v.tail) [] ?m.139561 ?m.139562 }
        (fun n x => { l := some ?m.139560, var := s', stk := elim (trList (n :: v.tail)) [] ?m.139561 ?m.139562 })
        v.headI) →
    ∃ b₂,
      TrCfg (Nat.rec (stepNormal f k v.tail) (fun y x => stepNormal g k (y :: v.tail)) v.headI) b₂ ∧
        Reaches₁ (TM2.step tr)
          { l := some (trNormal (f.case g) (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) } b₂

Tactic:
rcases v.headI with - | n <;> intro h

Result:
case case.intro.zero
f g : 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₂
IHg :
  ∀ (k : Cont) (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepNormal g k v) b₂ ∧
        Reaches₁ (TM2.step tr)
          { l := some (trNormal g (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) } b₂
k : Cont
v : List ℕ
s s' : Option Γ'
h :
  Reaches₁ (TM2.step tr)
    { l := some (Λ'.pred ?m.139559 ?m.139560), var := s, stk := elim (trList v) [] ?m.139561 ?m.139562 }
    (Nat.rec { l := some ?m.139559, var := s', stk := elim (trList v.tail) [] ?m.139561 ?m.139562 }
      (fun n x => { l := some ?m.139560, var := s', stk := elim (trList (n :: v.tail)) [] ?m.139561 ?m.139562 }) 0)
⊢ ∃ b₂,
    TrCfg (Nat.rec (stepNormal f k v.tail) (fun y x => stepNormal g k (y :: v.tail)) 0) b₂ ∧
      Reaches₁ (TM2.step tr)
        { l := some (trNormal (f.case g) (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) } b₂

case case.intro.succ
f g : 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₂
IHg :
  ∀ (k : Cont) (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepNormal g k v) b₂ ∧
        Reaches₁ (TM2.step tr)
          { l := some (trNormal g (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) } b₂
k : Cont
v : List ℕ
s s' : Option Γ'
n : ℕ
h :
  Reaches₁ (TM2.step tr)
    { l := some (Λ'.pred ?m.139559 ?m.139560), var := s, stk := elim (trList v) [] ?m.139561 ?m.139562 }
    (Nat.rec { l := some ?m.139559, var := s', stk := elim (trList v.tail) [] ?m.139561 ?m.139562 }
      (fun n x => { l := some ?m.139560, var := s', stk := elim (trList (n :: v.tail)) [] ?m.139561 ?m.139562 })
      (n + 1))
⊢ ∃ b₂,
    TrCfg (Nat.rec (stepNormal f k v.tail) (fun y x => stepNormal g k (y :: v.tail)) (n + 1)) b₂ ∧
      Reaches₁ (TM2.step tr)
        { l := some (trNormal (f.case g) (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) } b₂