l3lab/ntp-mathlib huggingface dataset:
/-- The `stepRet` function respects the `then k'` homomorphism. Note that this is an exact
equality, not a simulation; the original and embedded machines move in lock-step until the
embedded machine reaches the halt state. -/
theorem stepRet_then {k k' : Cont} {v} : stepRet (k.then k') v = (stepRet k v).then k' := by
  induction k generalizing v <;> simp only [Cont.then, stepRet, *] <;>
    try 

Proof state:
case fix
k' : Cont
a✝¹ : Code
a✝ : Cont
a_ih✝ : ∀ {v : List ℕ}, stepRet (Cont.then a✝ k') v = Cfg.then (stepRet a✝ v) k'
v : List ℕ
⊢ (if List.headI v = 0 then Cfg.then (stepRet a✝ (List.tail v)) k'
    else stepNormal a✝¹ (Cont.fix a✝¹ (Cont.then a✝ k')) (List.tail v)) =
    Cfg.then (if List.headI v = 0 then stepRet a✝ (List.tail v) else stepNormal a✝¹ (Cont.fix a✝¹ a✝) (List.tail v)) k'

Next tactic:
{ simp only [Cfg.then]; done }
/-- The `stepRet` function respects the `then k'` homomorphism. Note that this is an exact
equality, not a simulation; the original and embedded machines move in lock-step until the
embedded machine reaches the halt state. -/
theorem stepRet_then {k k' : Cont} {v} : stepRet (k.then k') v = (stepRet k v).then k' := by
  induction k generalizing v <;> simp only [Cont.then, stepRet, *] <;>
    try { 

Proof state:
case fix
k' : Cont
a✝¹ : Code
a✝ : Cont
a_ih✝ : ∀ {v : List ℕ}, stepRet (Cont.then a✝ k') v = Cfg.then (stepRet a✝ v) k'
v : List ℕ
⊢ (if List.headI v = 0 then Cfg.then (stepRet a✝ (List.tail v)) k'
    else stepNormal a✝¹ (Cont.fix a✝¹ (Cont.then a✝ k')) (List.tail v)) =
    Cfg.then (if List.headI v = 0 then stepRet a✝ (List.tail v) else stepNormal a✝¹ (Cont.fix a✝¹ a✝) (List.tail v)) k'

Next tactic:
simp only [Cfg.then]
/-- The `stepRet` function respects the `then k'` homomorphism. Note that this is an exact
equality, not a simulation; the original and embedded machines move in lock-step until the
embedded machine reaches the halt state. -/
theorem stepRet_then {k k' : Cont} {v} : stepRet (k.then k') v = (stepRet k v).then k' := by
  induction k generalizing v <;> simp only [Cont.then, stepRet, *] <;>
    try { simp only [Cfg.then]; 

Proof state:
case fix
k' : Cont
a✝¹ : Code
a✝ : Cont
a_ih✝ : ∀ {v : List ℕ}, stepRet (Cont.then a✝ k') v = Cfg.then (stepRet a✝ v) k'
v : List ℕ
⊢ (if List.headI v = 0 then
      (match (motive := Cfg → Cont → Cfg) stepRet a✝ (List.tail v) with
        | Cfg.halt v => fun k' => stepRet k' v
        | Cfg.ret k v => fun k' => Cfg.ret (Cont.then k k') v)
        k'
    else stepNormal a✝¹ (Cont.fix a✝¹ (Cont.then a✝ k')) (List.tail v)) =
    (match (motive := Cfg → Cont → Cfg)
        if List.headI v = 0 then stepRet a✝ (List.tail v) else stepNormal a✝¹ (Cont.fix a✝¹ a✝) (List.tail v) with
      | Cfg.halt v => fun k' => stepRet k' v
      | Cfg.ret k v => fun k' => Cfg.ret (Cont.then k k') v)
      k'

Next tactic:
done
/-- The `stepRet` function respects the `then k'` homomorphism. Note that this is an exact
equality, not a simulation; the original and embedded machines move in lock-step until the
embedded machine reaches the halt state. -/
theorem stepRet_then {k k' : Cont} {v} : stepRet (k.then k') v = (stepRet k v).then k' := by
  induction k generalizing v <;> simp only [Cont.then, stepRet, *] <;>
    try { simp only [Cfg.then]; done }
  

Proof state:
case cons₁
k' : Cont
a✝² : Code
a✝¹ : List ℕ
a✝ : Cont
a_ih✝ : ∀ {v : List ℕ}, stepRet (Cont.then a✝ k') v = Cfg.then (stepRet a✝ v) k'
v : List ℕ
⊢ stepNormal a✝² (Cont.cons₂ v (Cont.then a✝ k')) a✝¹ = Cfg.then (stepNormal a✝² (Cont.cons₂ v a✝) a✝¹) k'
case comp
k' : Cont
a✝¹ : Code
a✝ : Cont
a_ih✝ : ∀ {v : List ℕ}, stepRet (Cont.then a✝ k') v = Cfg.then (stepRet a✝ v) k'
v : List ℕ
⊢ stepNormal a✝¹ (Cont.then a✝ k') v = Cfg.then (stepNormal a✝¹ a✝ v) k'
case fix
k' : Cont
a✝¹ : Code
a✝ : Cont
a_ih✝ : ∀ {v : List ℕ}, stepRet (Cont.then a✝ k') v = Cfg.then (stepRet a✝ v) k'
v : List ℕ
⊢ (if List.headI v = 0 then Cfg.then (stepRet a✝ (List.tail v)) k'
    else stepNormal a✝¹ (Cont.fix a✝¹ (Cont.then a✝ k')) (List.tail v)) =
    Cfg.then (if List.headI v = 0 then stepRet a✝ (List.tail v) else stepNormal a✝¹ (Cont.fix a✝¹ a✝) (List.tail v)) k'

Next tactic:
case cons₁ =>
    rw [← stepNormal_then]
    rfl
/-- The `stepRet` function respects the `then k'` homomorphism. Note that this is an exact
equality, not a simulation; the original and embedded machines move in lock-step until the
embedded machine reaches the halt state. -/
theorem stepRet_then {k k' : Cont} {v} : stepRet (k.then k') v = (stepRet k v).then k' := by
  induction k generalizing v <;> simp only [Cont.then, stepRet, *] <;>
    try { simp only [Cfg.then]; done }
  

Proof state:
k' : Cont
a✝² : Code
a✝¹ : List ℕ
a✝ : Cont
a_ih✝ : ∀ {v : List ℕ}, stepRet (Cont.then a✝ k') v = Cfg.then (stepRet a✝ v) k'
v : List ℕ
⊢ stepNormal a✝² (Cont.cons₂ v (Cont.then a✝ k')) a✝¹ = Cfg.then (stepNormal a✝² (Cont.cons₂ v a✝) a✝¹) k'

Next tactic:
case cons₁ =>
    rw [← stepNormal_then]
    rfl
/-- The `stepRet` function respects the `then k'` homomorphism. Note that this is an exact
equality, not a simulation; the original and embedded machines move in lock-step until the
embedded machine reaches the halt state. -/
theorem stepRet_then {k k' : Cont} {v} : stepRet (k.then k') v = (stepRet k v).then k' := by
  induction k generalizing v <;> simp only [Cont.then, stepRet, *] <;>
    try { simp only [Cfg.then]; done }
  case cons₁ =>
    

Proof state:
k' : Cont
a✝² : Code
a✝¹ : List ℕ
a✝ : Cont
a_ih✝ : ∀ {v : List ℕ}, stepRet (Cont.then a✝ k') v = Cfg.then (stepRet a✝ v) k'
v : List ℕ
⊢ stepNormal a✝² (Cont.cons₂ v (Cont.then a✝ k')) a✝¹ = Cfg.then (stepNormal a✝² (Cont.cons₂ v a✝) a✝¹) k'

Next tactic:
rw [← stepNormal_then]
/-- The `stepRet` function respects the `then k'` homomorphism. Note that this is an exact
equality, not a simulation; the original and embedded machines move in lock-step until the
embedded machine reaches the halt state. -/
theorem stepRet_then {k k' : Cont} {v} : stepRet (k.then k') v = (stepRet k v).then k' := by
  induction k generalizing v <;> simp only [Cont.then, stepRet, *] <;>
    try { simp only [Cfg.then]; done }
  case cons₁ =>
    rw [← stepNormal_then]
    

Proof state:
k' : Cont
a✝² : Code
a✝¹ : List ℕ
a✝ : Cont
a_ih✝ : ∀ {v : List ℕ}, stepRet (Cont.then a✝ k') v = Cfg.then (stepRet a✝ v) k'
v : List ℕ
⊢ stepNormal a✝² (Cont.cons₂ v (Cont.then a✝ k')) a✝¹ = stepNormal a✝² (Cont.then (Cont.cons₂ v a✝) k') a✝¹

Next tactic:
rfl
/-- The `stepRet` function respects the `then k'` homomorphism. Note that this is an exact
equality, not a simulation; the original and embedded machines move in lock-step until the
embedded machine reaches the halt state. -/
theorem stepRet_then {k k' : Cont} {v} : stepRet (k.then k') v = (stepRet k v).then k' := by
  induction k generalizing v <;> simp only [Cont.then, stepRet, *] <;>
    try { simp only [Cfg.then]; done }
  case cons₁ =>
    rw [← stepNormal_then]
    rfl
  

Proof state:
case comp
k' : Cont
a✝¹ : Code
a✝ : Cont
a_ih✝ : ∀ {v : List ℕ}, stepRet (Cont.then a✝ k') v = Cfg.then (stepRet a✝ v) k'
v : List ℕ
⊢ stepNormal a✝¹ (Cont.then a✝ k') v = Cfg.then (stepNormal a✝¹ a✝ v) k'
case fix
k' : Cont
a✝¹ : Code
a✝ : Cont
a_ih✝ : ∀ {v : List ℕ}, stepRet (Cont.then a✝ k') v = Cfg.then (stepRet a✝ v) k'
v : List ℕ
⊢ (if List.headI v = 0 then Cfg.then (stepRet a✝ (List.tail v)) k'
    else stepNormal a✝¹ (Cont.fix a✝¹ (Cont.then a✝ k')) (List.tail v)) =
    Cfg.then (if List.headI v = 0 then stepRet a✝ (List.tail v) else stepNormal a✝¹ (Cont.fix a✝¹ a✝) (List.tail v)) k'

Next tactic:
case comp =>
    rw [← stepNormal_then]
/-- The `stepRet` function respects the `then k'` homomorphism. Note that this is an exact
equality, not a simulation; the original and embedded machines move in lock-step until the
embedded machine reaches the halt state. -/
theorem stepRet_then {k k' : Cont} {v} : stepRet (k.then k') v = (stepRet k v).then k' := by
  induction k generalizing v <;> simp only [Cont.then, stepRet, *] <;>
    try { simp only [Cfg.then]; done }
  case cons₁ =>
    rw [← stepNormal_then]
    rfl
  

Proof state:
k' : Cont
a✝¹ : Code
a✝ : Cont
a_ih✝ : ∀ {v : List ℕ}, stepRet (Cont.then a✝ k') v = Cfg.then (stepRet a✝ v) k'
v : List ℕ
⊢ stepNormal a✝¹ (Cont.then a✝ k') v = Cfg.then (stepNormal a✝¹ a✝ v) k'

Next tactic:
case comp =>
    rw [← stepNormal_then]
/-- The `stepRet` function respects the `then k'` homomorphism. Note that this is an exact
equality, not a simulation; the original and embedded machines move in lock-step until the
embedded machine reaches the halt state. -/
theorem stepRet_then {k k' : Cont} {v} : stepRet (k.then k') v = (stepRet k v).then k' := by
  induction k generalizing v <;> simp only [Cont.then, stepRet, *] <;>
    try { simp only [Cfg.then]; done }
  case cons₁ =>
    rw [← stepNormal_then]
    rfl
  case comp =>
    

Proof state:
k' : Cont
a✝¹ : Code
a✝ : Cont
a_ih✝ : ∀ {v : List ℕ}, stepRet (Cont.then a✝ k') v = Cfg.then (stepRet a✝ v) k'
v : List ℕ
⊢ stepNormal a✝¹ (Cont.then a✝ k') v = Cfg.then (stepNormal a✝¹ a✝ v) k'

Next tactic:
rw [← stepNormal_then]
/-- The `stepRet` function respects the `then k'` homomorphism. Note that this is an exact
equality, not a simulation; the original and embedded machines move in lock-step until the
embedded machine reaches the halt state. -/
theorem stepRet_then {k k' : Cont} {v} : stepRet (k.then k') v = (stepRet k v).then k' := by
  induction k generalizing v <;> simp only [Cont.then, stepRet, *] <;>
    try { simp only [Cfg.then]; done }
  case cons₁ =>
    rw [← stepNormal_then]
    rfl
  case comp =>
    rw [← stepNormal_then]
  

Proof state:
case fix
k' : Cont
a✝¹ : Code
a✝ : Cont
a_ih✝ : ∀ {v : List ℕ}, stepRet (Cont.then a✝ k') v = Cfg.then (stepRet a✝ v) k'
v : List ℕ
⊢ (if List.headI v = 0 then Cfg.then (stepRet a✝ (List.tail v)) k'
    else stepNormal a✝¹ (Cont.fix a✝¹ (Cont.then a✝ k')) (List.tail v)) =
    Cfg.then (if List.headI v = 0 then stepRet a✝ (List.tail v) else stepNormal a✝¹ (Cont.fix a✝¹ a✝) (List.tail v)) k'

Next tactic:
case fix _ k_ih =>
    split_ifs
    · rw [← k_ih]
    · rw [← stepNormal_then]
      rfl
/-- The `stepRet` function respects the `then k'` homomorphism. Note that this is an exact
equality, not a simulation; the original and embedded machines move in lock-step until the
embedded machine reaches the halt state. -/
theorem stepRet_then {k k' : Cont} {v} : stepRet (k.then k') v = (stepRet k v).then k' := by
  induction k generalizing v <;> simp only [Cont.then, stepRet, *] <;>
    try { simp only [Cfg.then]; done }
  case cons₁ =>
    rw [← stepNormal_then]
    rfl
  case comp =>
    rw [← stepNormal_then]
  

Proof state:
k' : Cont
a✝¹ : Code
a✝ : Cont
k_ih : ∀ {v : List ℕ}, stepRet (Cont.then a✝ k') v = Cfg.then (stepRet a✝ v) k'
v : List ℕ
⊢ (if List.headI v = 0 then Cfg.then (stepRet a✝ (List.tail v)) k'
    else stepNormal a✝¹ (Cont.fix a✝¹ (Cont.then a✝ k')) (List.tail v)) =
    Cfg.then (if List.headI v = 0 then stepRet a✝ (List.tail v) else stepNormal a✝¹ (Cont.fix a✝¹ a✝) (List.tail v)) k'

Next tactic:
case fix _ k_ih =>
    split_ifs
    · rw [← k_ih]
    · rw [← stepNormal_then]
      rfl
/-- The `stepRet` function respects the `then k'` homomorphism. Note that this is an exact
equality, not a simulation; the original and embedded machines move in lock-step until the
embedded machine reaches the halt state. -/
theorem stepRet_then {k k' : Cont} {v} : stepRet (k.then k') v = (stepRet k v).then k' := by
  induction k generalizing v <;> simp only [Cont.then, stepRet, *] <;>
    try { simp only [Cfg.then]; done }
  case cons₁ =>
    rw [← stepNormal_then]
    rfl
  case comp =>
    rw [← stepNormal_then]
  case fix _ k_ih =>
    

Proof state:
k' : Cont
a✝¹ : Code
a✝ : Cont
k_ih : ∀ {v : List ℕ}, stepRet (Cont.then a✝ k') v = Cfg.then (stepRet a✝ v) k'
v : List ℕ
⊢ (if List.headI v = 0 then Cfg.then (stepRet a✝ (List.tail v)) k'
    else stepNormal a✝¹ (Cont.fix a✝¹ (Cont.then a✝ k')) (List.tail v)) =
    Cfg.then (if List.headI v = 0 then stepRet a✝ (List.tail v) else stepNormal a✝¹ (Cont.fix a✝¹ a✝) (List.tail v)) k'

Next tactic:
split_ifs
/-- The `stepRet` function respects the `then k'` homomorphism. Note that this is an exact
equality, not a simulation; the original and embedded machines move in lock-step until the
embedded machine reaches the halt state. -/
theorem stepRet_then {k k' : Cont} {v} : stepRet (k.then k') v = (stepRet k v).then k' := by
  induction k generalizing v <;> simp only [Cont.then, stepRet, *] <;>
    try { simp only [Cfg.then]; done }
  case cons₁ =>
    rw [← stepNormal_then]
    rfl
  case comp =>
    rw [← stepNormal_then]
  case fix _ k_ih =>
    split_ifs
    · 

Proof state:
case pos
k' : Cont
a✝¹ : Code
a✝ : Cont
k_ih : ∀ {v : List ℕ}, stepRet (Cont.then a✝ k') v = Cfg.then (stepRet a✝ v) k'
v : List ℕ
h✝ : List.headI v = 0
⊢ Cfg.then (stepRet a✝ (List.tail v)) k' = Cfg.then (stepRet a✝ (List.tail v)) k'

Next tactic:
rw [← k_ih]
/-- The `stepRet` function respects the `then k'` homomorphism. Note that this is an exact
equality, not a simulation; the original and embedded machines move in lock-step until the
embedded machine reaches the halt state. -/
theorem stepRet_then {k k' : Cont} {v} : stepRet (k.then k') v = (stepRet k v).then k' := by
  induction k generalizing v <;> simp only [Cont.then, stepRet, *] <;>
    try { simp only [Cfg.then]; done }
  case cons₁ =>
    rw [← stepNormal_then]
    rfl
  case comp =>
    rw [← stepNormal_then]
  case fix _ k_ih =>
    split_ifs
    · rw [← k_ih]
    · 

Proof state:
case neg
k' : Cont
a✝¹ : Code
a✝ : Cont
k_ih : ∀ {v : List ℕ}, stepRet (Cont.then a✝ k') v = Cfg.then (stepRet a✝ v) k'
v : List ℕ
h✝ : ¬List.headI v = 0
⊢ stepNormal a✝¹ (Cont.fix a✝¹ (Cont.then a✝ k')) (List.tail v) =
    Cfg.then (stepNormal a✝¹ (Cont.fix a✝¹ a✝) (List.tail v)) k'

Next tactic:
rw [← stepNormal_then]
/-- The `stepRet` function respects the `then k'` homomorphism. Note that this is an exact
equality, not a simulation; the original and embedded machines move in lock-step until the
embedded machine reaches the halt state. -/
theorem stepRet_then {k k' : Cont} {v} : stepRet (k.then k') v = (stepRet k v).then k' := by
  induction k generalizing v <;> simp only [Cont.then, stepRet, *] <;>
    try { simp only [Cfg.then]; done }
  case cons₁ =>
    rw [← stepNormal_then]
    rfl
  case comp =>
    rw [← stepNormal_then]
  case fix _ k_ih =>
    split_ifs
    · rw [← k_ih]
    · rw [← stepNormal_then]
      

Proof state:
case neg
k' : Cont
a✝¹ : Code
a✝ : Cont
k_ih : ∀ {v : List ℕ}, stepRet (Cont.then a✝ k') v = Cfg.then (stepRet a✝ v) k'
v : List ℕ
h✝ : ¬List.headI v = 0
⊢ stepNormal a✝¹ (Cont.fix a✝¹ (Cont.then a✝ k')) (List.tail v) =
    stepNormal a✝¹ (Cont.then (Cont.fix a✝¹ a✝) k') (List.tail v)

Next tactic:
rfl
theorem Code.Ok.zero {c} (h : Code.Ok c) {v} :
    Turing.eval step (stepNormal c Cont.halt v) = Cfg.halt <$> Code.eval c v := by
  

Proof state:
c : Code
h : Ok c
v : List ℕ
⊢ Turing.eval step (stepNormal c Cont.halt v) = Cfg.halt <$> eval c v

Next tactic:
rw [h, ← bind_pure_comp]
theorem Code.Ok.zero {c} (h : Code.Ok c) {v} :
    Turing.eval step (stepNormal c Cont.halt v) = Cfg.halt <$> Code.eval c v := by
  rw [h, ← bind_pure_comp]; 

Proof state:
c : Code
h : Ok c
v : List ℕ
⊢ (do
      let v ← eval c v
      Turing.eval step (Cfg.ret Cont.halt v)) =
    do
    let a ← eval c v
    pure (Cfg.halt a)

Next tactic:
congr
theorem Code.Ok.zero {c} (h : Code.Ok c) {v} :
    Turing.eval step (stepNormal c Cont.halt v) = Cfg.halt <$> Code.eval c v := by
  rw [h, ← bind_pure_comp]; congr; 

Proof state:
case e_a
c : Code
h : Ok c
v : List ℕ
⊢ (fun v => Turing.eval step (Cfg.ret Cont.halt v)) = fun a => pure (Cfg.halt a)

Next tactic:
funext v
theorem Code.Ok.zero {c} (h : Code.Ok c) {v} :
    Turing.eval step (stepNormal c Cont.halt v) = Cfg.halt <$> Code.eval c v := by
  rw [h, ← bind_pure_comp]; congr; funext v
  

Proof state:
case e_a.h
c : Code
h : Ok c
v✝ v : List ℕ
⊢ Turing.eval step (Cfg.ret Cont.halt v) = pure (Cfg.halt v)

Next tactic:
exact Part.eq_some_iff.2 (mem_eval.2 ⟨ReflTransGen.single rfl, rfl⟩)
theorem stepNormal.is_ret (c k v) : ∃ k' v', stepNormal c k v = Cfg.ret k' v' := by
  

Proof state:
c : Code
k : Cont
v : List ℕ
⊢ ∃ k' v', stepNormal c k v = Cfg.ret k' v'

Next tactic:
induction c generalizing k v
theorem stepNormal.is_ret (c k v) : ∃ k' v', stepNormal c k v = Cfg.ret k' v' := by
  induction c generalizing k v
  

Proof state:
case zero'
k : Cont
v : List ℕ
⊢ ∃ k' v', stepNormal Code.zero' k v = Cfg.ret k' v'
case succ
k : Cont
v : List ℕ
⊢ ∃ k' v', stepNormal Code.succ k v = Cfg.ret k' v'
case tail
k : Cont
v : List ℕ
⊢ ∃ k' v', stepNormal Code.tail k v = Cfg.ret k' v'
case cons
a✝¹ a✝ : Code
a_ih✝¹ : ∀ (k : Cont) (v : List ℕ), ∃ k' v', stepNormal a✝¹ k v = Cfg.ret k' v'
a_ih✝ : ∀ (k : Cont) (v : List ℕ), ∃ k' v', stepNormal a✝ k v = Cfg.ret k' v'
k : Cont
v : List ℕ
⊢ ∃ k' v', stepNormal (Code.cons a✝¹ a✝) k v = Cfg.ret k' v'
case comp
a✝¹ a✝ : Code
a_ih✝¹ : ∀ (k : Cont) (v : List ℕ), ∃ k' v', stepNormal a✝¹ k v = Cfg.ret k' v'
a_ih✝ : ∀ (k : Cont) (v : List ℕ), ∃ k' v', stepNormal a✝ k v = Cfg.ret k' v'
k : Cont
v : List ℕ
⊢ ∃ k' v', stepNormal (Code.comp a✝¹ a✝) k v = Cfg.ret k' v'
case case
a✝¹ a✝ : Code
a_ih✝¹ : ∀ (k : Cont) (v : List ℕ), ∃ k' v', stepNormal a✝¹ k v = Cfg.ret k' v'
a_ih✝ : ∀ (k : Cont) (v : List ℕ), ∃ k' v', stepNormal a✝ k v = Cfg.ret k' v'
k : Cont
v : List ℕ
⊢ ∃ k' v', stepNormal (Code.case a✝¹ a✝) k v = Cfg.ret k' v'
case fix
a✝ : Code
a_ih✝ : ∀ (k : Cont) (v : List ℕ), ∃ k' v', stepNormal a✝ k v = Cfg.ret k' v'
k : Cont
v : List ℕ
⊢ ∃ k' v', stepNormal (Code.fix a✝) k v = Cfg.ret k' v'

Next tactic:
iterate 3 exact ⟨_, _, rfl⟩
theorem stepNormal.is_ret (c k v) : ∃ k' v', stepNormal c k v = Cfg.ret k' v' := by
  induction c generalizing k v
  iterate 3 

Proof state:
case zero'
k : Cont
v : List ℕ
⊢ ∃ k' v', stepNormal Code.zero' k v = Cfg.ret k' v'
case succ
k : Cont
v : List ℕ
⊢ ∃ k' v', stepNormal Code.succ k v = Cfg.ret k' v'
case tail
k : Cont
v : List ℕ
⊢ ∃ k' v', stepNormal Code.tail k v = Cfg.ret k' v'
case cons
a✝¹ a✝ : Code
a_ih✝¹ : ∀ (k : Cont) (v : List ℕ), ∃ k' v', stepNormal a✝¹ k v = Cfg.ret k' v'
a_ih✝ : ∀ (k : Cont) (v : List ℕ), ∃ k' v', stepNormal a✝ k v = Cfg.ret k' v'
k : Cont
v : List ℕ
⊢ ∃ k' v', stepNormal (Code.cons a✝¹ a✝) k v = Cfg.ret k' v'
case comp
a✝¹ a✝ : Code
a_ih✝¹ : ∀ (k : Cont) (v : List ℕ), ∃ k' v', stepNormal a✝¹ k v = Cfg.ret k' v'
a_ih✝ : ∀ (k : Cont) (v : List ℕ), ∃ k' v', stepNormal a✝ k v = Cfg.ret k' v'
k : Cont
v : List ℕ
⊢ ∃ k' v', stepNormal (Code.comp a✝¹ a✝) k v = Cfg.ret k' v'
case case
a✝¹ a✝ : Code
a_ih✝¹ : ∀ (k : Cont) (v : List ℕ), ∃ k' v', stepNormal a✝¹ k v = Cfg.ret k' v'
a_ih✝ : ∀ (k : Cont) (v : List ℕ), ∃ k' v', stepNormal a✝ k v = Cfg.ret k' v'
k : Cont
v : List ℕ
⊢ ∃ k' v', stepNormal (Code.case a✝¹ a✝) k v = Cfg.ret k' v'
case fix
a✝ : Code
a_ih✝ : ∀ (k : Cont) (v : List ℕ), ∃ k' v', stepNormal a✝ k v = Cfg.ret k' v'
k : Cont
v : List ℕ
⊢ ∃ k' v', stepNormal (Code.fix a✝) k v = Cfg.ret k' v'

Next tactic:
exact ⟨_, _, rfl⟩
theorem stepNormal.is_ret (c k v) : ∃ k' v', stepNormal c k v = Cfg.ret k' v' := by
  induction c generalizing k v
  iterate 3 

Proof state:
case succ
k : Cont
v : List ℕ
⊢ ∃ k' v', stepNormal Code.succ k v = Cfg.ret k' v'
case tail
k : Cont
v : List ℕ
⊢ ∃ k' v', stepNormal Code.tail k v = Cfg.ret k' v'
case cons
a✝¹ a✝ : Code
a_ih✝¹ : ∀ (k : Cont) (v : List ℕ), ∃ k' v', stepNormal a✝¹ k v = Cfg.ret k' v'
a_ih✝ : ∀ (k : Cont) (v : List ℕ), ∃ k' v', stepNormal a✝ k v = Cfg.ret k' v'
k : Cont
v : List ℕ
⊢ ∃ k' v', stepNormal (Code.cons a✝¹ a✝) k v = Cfg.ret k' v'
case comp
a✝¹ a✝ : Code
a_ih✝¹ : ∀ (k : Cont) (v : List ℕ), ∃ k' v', stepNormal a✝¹ k v = Cfg.ret k' v'
a_ih✝ : ∀ (k : Cont) (v : List ℕ), ∃ k' v', stepNormal a✝ k v = Cfg.ret k' v'
k : Cont
v : List ℕ
⊢ ∃ k' v', stepNormal (Code.comp a✝¹ a✝) k v = Cfg.ret k' v'
case case
a✝¹ a✝ : Code
a_ih✝¹ : ∀ (k : Cont) (v : List ℕ), ∃ k' v', stepNormal a✝¹ k v = Cfg.ret k' v'
a_ih✝ : ∀ (k : Cont) (v : List ℕ), ∃ k' v', stepNormal a✝ k v = Cfg.ret k' v'
k : Cont
v : List ℕ
⊢ ∃ k' v', stepNormal (Code.case a✝¹ a✝) k v = Cfg.ret k' v'
case fix
a✝ : Code
a_ih✝ : ∀ (k : Cont) (v : List ℕ), ∃ k' v', stepNormal a✝ k v = Cfg.ret k' v'
k : Cont
v : List ℕ
⊢ ∃ k' v', stepNormal (Code.fix a✝) k v = Cfg.ret k' v'

Next tactic:
exact ⟨_, _, rfl⟩
theorem stepNormal.is_ret (c k v) : ∃ k' v', stepNormal c k v = Cfg.ret k' v' := by
  induction c generalizing k v
  iterate 3 

Proof state:
case tail
k : Cont
v : List ℕ
⊢ ∃ k' v', stepNormal Code.tail k v = Cfg.ret k' v'
case cons
a✝¹ a✝ : Code
a_ih✝¹ : ∀ (k : Cont) (v : List ℕ), ∃ k' v', stepNormal a✝¹ k v = Cfg.ret k' v'
a_ih✝ : ∀ (k : Cont) (v : List ℕ), ∃ k' v', stepNormal a✝ k v = Cfg.ret k' v'
k : Cont
v : List ℕ
⊢ ∃ k' v', stepNormal (Code.cons a✝¹ a✝) k v = Cfg.ret k' v'
case comp
a✝¹ a✝ : Code
a_ih✝¹ : ∀ (k : Cont) (v : List ℕ), ∃ k' v', stepNormal a✝¹ k v = Cfg.ret k' v'
a_ih✝ : ∀ (k : Cont) (v : List ℕ), ∃ k' v', stepNormal a✝ k v = Cfg.ret k' v'
k : Cont
v : List ℕ
⊢ ∃ k' v', stepNormal (Code.comp a✝¹ a✝) k v = Cfg.ret k' v'
case case
a✝¹ a✝ : Code
a_ih✝¹ : ∀ (k : Cont) (v : List ℕ), ∃ k' v', stepNormal a✝¹ k v = Cfg.ret k' v'
a_ih✝ : ∀ (k : Cont) (v : List ℕ), ∃ k' v', stepNormal a✝ k v = Cfg.ret k' v'
k : Cont
v : List ℕ
⊢ ∃ k' v', stepNormal (Code.case a✝¹ a✝) k v = Cfg.ret k' v'
case fix
a✝ : Code
a_ih✝ : ∀ (k : Cont) (v : List ℕ), ∃ k' v', stepNormal a✝ k v = Cfg.ret k' v'
k : Cont
v : List ℕ
⊢ ∃ k' v', stepNormal (Code.fix a✝) k v = Cfg.ret k' v'

Next tactic:
exact ⟨_, _, rfl⟩
theorem stepNormal.is_ret (c k v) : ∃ k' v', stepNormal c k v = Cfg.ret k' v' := by
  induction c generalizing k v
  iterate 3 exact ⟨_, _, rfl⟩
  

Proof state:
case cons
a✝¹ a✝ : Code
a_ih✝¹ : ∀ (k : Cont) (v : List ℕ), ∃ k' v', stepNormal a✝¹ k v = Cfg.ret k' v'
a_ih✝ : ∀ (k : Cont) (v : List ℕ), ∃ k' v', stepNormal a✝ k v = Cfg.ret k' v'
k : Cont
v : List ℕ
⊢ ∃ k' v', stepNormal (Code.cons a✝¹ a✝) k v = Cfg.ret k' v'
case comp
a✝¹ a✝ : Code
a_ih✝¹ : ∀ (k : Cont) (v : List ℕ), ∃ k' v', stepNormal a✝¹ k v = Cfg.ret k' v'
a_ih✝ : ∀ (k : Cont) (v : List ℕ), ∃ k' v', stepNormal a✝ k v = Cfg.ret k' v'
k : Cont
v : List ℕ
⊢ ∃ k' v', stepNormal (Code.comp a✝¹ a✝) k v = Cfg.ret k' v'
case case
a✝¹ a✝ : Code
a_ih✝¹ : ∀ (k : Cont) (v : List ℕ), ∃ k' v', stepNormal a✝¹ k v = Cfg.ret k' v'
a_ih✝ : ∀ (k : Cont) (v : List ℕ), ∃ k' v', stepNormal a✝ k v = Cfg.ret k' v'
k : Cont
v : List ℕ
⊢ ∃ k' v', stepNormal (Code.case a✝¹ a✝) k v = Cfg.ret k' v'
case fix
a✝ : Code
a_ih✝ : ∀ (k : Cont) (v : List ℕ), ∃ k' v', stepNormal a✝ k v = Cfg.ret k' v'
k : Cont
v : List ℕ
⊢ ∃ k' v', stepNormal (Code.fix a✝) k v = Cfg.ret k' v'

Next tactic:
case cons _f fs IHf _IHfs => apply IHf
theorem stepNormal.is_ret (c k v) : ∃ k' v', stepNormal c k v = Cfg.ret k' v' := by
  induction c generalizing k v
  iterate 3 exact ⟨_, _, rfl⟩
  

Proof state:
_f fs : Code
IHf : ∀ (k : Cont) (v : List ℕ), ∃ k' v', stepNormal _f k v = Cfg.ret k' v'
_IHfs : ∀ (k : Cont) (v : List ℕ), ∃ k' v', stepNormal fs k v = Cfg.ret k' v'
k : Cont
v : List ℕ
⊢ ∃ k' v', stepNormal (Code.cons _f fs) k v = Cfg.ret k' v'

Next tactic:
case cons _f fs IHf _IHfs => apply IHf
theorem stepNormal.is_ret (c k v) : ∃ k' v', stepNormal c k v = Cfg.ret k' v' := by
  induction c generalizing k v
  iterate 3 exact ⟨_, _, rfl⟩
  case cons _f fs IHf _IHfs => 

Proof state:
_f fs : Code
IHf : ∀ (k : Cont) (v : List ℕ), ∃ k' v', stepNormal _f k v = Cfg.ret k' v'
_IHfs : ∀ (k : Cont) (v : List ℕ), ∃ k' v', stepNormal fs k v = Cfg.ret k' v'
k : Cont
v : List ℕ
⊢ ∃ k' v', stepNormal (Code.cons _f fs) k v = Cfg.ret k' v'

Next tactic:
apply IHf