l3lab/ntp-mathlib huggingface dataset:
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 => apply IHf
  

Proof state:
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 comp f _g _IHf IHg => apply IHg
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 => apply IHf
  

Proof state:
f _g : Code
_IHf : ∀ (k : Cont) (v : List ℕ), ∃ k' v', stepNormal f k v = Cfg.ret k' v'
IHg : ∀ (k : Cont) (v : List ℕ), ∃ k' v', stepNormal _g k v = Cfg.ret k' v'
k : Cont
v : List ℕ
⊢ ∃ k' v', stepNormal (Code.comp f _g) k v = Cfg.ret k' v'

Next tactic:
case comp f _g _IHf IHg => apply IHg
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 => apply IHf
  case comp f _g _IHf IHg => 

Proof state:
f _g : Code
_IHf : ∀ (k : Cont) (v : List ℕ), ∃ k' v', stepNormal f k v = Cfg.ret k' v'
IHg : ∀ (k : Cont) (v : List ℕ), ∃ k' v', stepNormal _g k v = Cfg.ret k' v'
k : Cont
v : List ℕ
⊢ ∃ k' v', stepNormal (Code.comp f _g) k v = Cfg.ret k' v'

Next tactic:
apply IHg
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 => apply IHf
  case comp f _g _IHf IHg => apply IHg
  

Proof state:
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 case f g IHf IHg =>
    rw [stepNormal]
    simp only []
    cases v.headI <;> simp only [] <;> [apply IHf; apply IHg]
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 => apply IHf
  case comp f _g _IHf IHg => apply IHg
  

Proof state:
f g : Code
IHf : ∀ (k : Cont) (v : List ℕ), ∃ k' v', stepNormal f k v = Cfg.ret k' v'
IHg : ∀ (k : Cont) (v : List ℕ), ∃ k' v', stepNormal g k v = Cfg.ret k' v'
k : Cont
v : List ℕ
⊢ ∃ k' v', stepNormal (Code.case f g) k v = Cfg.ret k' v'

Next tactic:
case case f g IHf IHg =>
    rw [stepNormal]
    simp only []
    cases v.headI <;> simp only [] <;> [apply IHf; apply IHg]
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 => apply IHf
  case comp f _g _IHf IHg => apply IHg
  case case f g IHf IHg =>
    

Proof state:
f g : Code
IHf : ∀ (k : Cont) (v : List ℕ), ∃ k' v', stepNormal f k v = Cfg.ret k' v'
IHg : ∀ (k : Cont) (v : List ℕ), ∃ k' v', stepNormal g k v = Cfg.ret k' v'
k : Cont
v : List ℕ
⊢ ∃ k' v', stepNormal (Code.case f g) k v = Cfg.ret k' v'

Next tactic:
rw [stepNormal]
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 => apply IHf
  case comp f _g _IHf IHg => apply IHg
  case case f g IHf IHg =>
    rw [stepNormal]
    

Proof state:
f g : Code
IHf : ∀ (k : Cont) (v : List ℕ), ∃ k' v', stepNormal f k v = Cfg.ret k' v'
IHg : ∀ (k : Cont) (v : List ℕ), ∃ k' v', stepNormal g k v = Cfg.ret k' v'
k : Cont
v : List ℕ
⊢ ∃ k' v',
    (fun k v => Nat.rec (stepNormal f k (List.tail v)) (fun y x => stepNormal g k (y :: List.tail v)) (List.headI v)) k
        v =
      Cfg.ret k' v'

Next tactic:
simp only []
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 => apply IHf
  case comp f _g _IHf IHg => apply IHg
  case case f g IHf IHg =>
    rw [stepNormal]
    simp only []
    

Proof state:
f g : Code
IHf : ∀ (k : Cont) (v : List ℕ), ∃ k' v', stepNormal f k v = Cfg.ret k' v'
IHg : ∀ (k : Cont) (v : List ℕ), ∃ k' v', stepNormal g k v = Cfg.ret k' v'
k : Cont
v : List ℕ
⊢ ∃ k' v',
    Nat.rec (stepNormal f k (List.tail v)) (fun y x => stepNormal g k (y :: List.tail v)) (List.headI v) = Cfg.ret k' v'

Next tactic:
cases v.headI <;> simp only [] <;> [apply IHf; apply IHg]
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 => apply IHf
  case comp f _g _IHf IHg => apply IHg
  case case f g IHf IHg =>
    rw [stepNormal]
    simp only []
    

Proof state:
f g : Code
IHf : ∀ (k : Cont) (v : List ℕ), ∃ k' v', stepNormal f k v = Cfg.ret k' v'
IHg : ∀ (k : Cont) (v : List ℕ), ∃ k' v', stepNormal g k v = Cfg.ret k' v'
k : Cont
v : List ℕ
⊢ ∃ k' v',
    Nat.rec (stepNormal f k (List.tail v)) (fun y x => stepNormal g k (y :: List.tail v)) (List.headI v) = Cfg.ret k' v'

Next tactic:
cases v.headI
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 => apply IHf
  case comp f _g _IHf IHg => apply IHg
  case case f g IHf IHg =>
    rw [stepNormal]
    simp only []
    cases v.headI <;> 

Proof state:
case zero
f g : Code
IHf : ∀ (k : Cont) (v : List ℕ), ∃ k' v', stepNormal f k v = Cfg.ret k' v'
IHg : ∀ (k : Cont) (v : List ℕ), ∃ k' v', stepNormal g k v = Cfg.ret k' v'
k : Cont
v : List ℕ
⊢ ∃ k' v',
    Nat.rec (stepNormal f k (List.tail v)) (fun y x => stepNormal g k (y :: List.tail v)) Nat.zero = Cfg.ret k' v'

Next tactic:
simp only []
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 => apply IHf
  case comp f _g _IHf IHg => apply IHg
  case case f g IHf IHg =>
    rw [stepNormal]
    simp only []
    cases v.headI <;> 

Proof state:
case succ
f g : Code
IHf : ∀ (k : Cont) (v : List ℕ), ∃ k' v', stepNormal f k v = Cfg.ret k' v'
IHg : ∀ (k : Cont) (v : List ℕ), ∃ k' v', stepNormal g k v = Cfg.ret k' v'
k : Cont
v : List ℕ
n✝ : ℕ
⊢ ∃ k' v',
    Nat.rec (stepNormal f k (List.tail v)) (fun y x => stepNormal g k (y :: List.tail v)) (Nat.succ n✝) = Cfg.ret k' v'

Next tactic:
simp only []
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 => apply IHf
  case comp f _g _IHf IHg => apply IHg
  case case f g IHf IHg =>
    rw [stepNormal]
    simp only []
    cases v.headI <;> simp only [] <;> [

Proof state:
case zero
f g : Code
IHf : ∀ (k : Cont) (v : List ℕ), ∃ k' v', stepNormal f k v = Cfg.ret k' v'
IHg : ∀ (k : Cont) (v : List ℕ), ∃ k' v', stepNormal g k v = Cfg.ret k' v'
k : Cont
v : List ℕ
⊢ ∃ k' v', stepNormal f k (List.tail v) = Cfg.ret k' v'

Next tactic:
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 => apply IHf
  case comp f _g _IHf IHg => apply IHg
  case case f g IHf IHg =>
    rw [stepNormal]
    simp only []
    cases v.headI <;> simp only [] <;> [apply IHf; 

Proof state:
case succ
f g : Code
IHf : ∀ (k : Cont) (v : List ℕ), ∃ k' v', stepNormal f k v = Cfg.ret k' v'
IHg : ∀ (k : Cont) (v : List ℕ), ∃ k' v', stepNormal g k v = Cfg.ret k' v'
k : Cont
v : List ℕ
n✝ : ℕ
⊢ ∃ k' v', stepNormal g k (n✝ :: List.tail v) = Cfg.ret k' v'

Next tactic:
apply IHg
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 => apply IHf
  case comp f _g _IHf IHg => apply IHg
  case case f g IHf IHg =>
    rw [stepNormal]
    simp only []
    cases v.headI <;> simp only [] <;> [apply IHf; apply IHg]
  

Proof state:
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 fix f IHf => 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 => apply IHf
  case comp f _g _IHf IHg => apply IHg
  case case f g IHf IHg =>
    rw [stepNormal]
    simp only []
    cases v.headI <;> simp only [] <;> [apply IHf; apply IHg]
  

Proof state:
f : Code
IHf : ∀ (k : Cont) (v : List ℕ), ∃ k' v', stepNormal f k v = Cfg.ret k' v'
k : Cont
v : List ℕ
⊢ ∃ k' v', stepNormal (Code.fix f) k v = Cfg.ret k' v'

Next tactic:
case fix f IHf => 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 => apply IHf
  case comp f _g _IHf IHg => apply IHg
  case case f g IHf IHg =>
    rw [stepNormal]
    simp only []
    cases v.headI <;> simp only [] <;> [apply IHf; apply IHg]
  case fix f IHf => 

Proof state:
f : Code
IHf : ∀ (k : Cont) (v : List ℕ), ∃ k' v', stepNormal f k v = Cfg.ret k' v'
k : Cont
v : List ℕ
⊢ ∃ k' v', stepNormal (Code.fix f) k v = Cfg.ret k' v'

Next tactic:
apply IHf
theorem cont_eval_fix {f k v} (fok : Code.Ok f) :
    Turing.eval step (stepNormal f (Cont.fix f k) v) =
      f.fix.eval v >>= fun v => Turing.eval step (Cfg.ret k v) := by
  

Proof state:
f : Code
k : Cont
v : List ℕ
fok : Code.Ok f
⊢ eval step (stepNormal f (Cont.fix f k) v) = do
    let v ← Code.eval (Code.fix f) v
    eval step (Cfg.ret k v)

Next tactic:
refine' Part.ext fun x => _
theorem cont_eval_fix {f k v} (fok : Code.Ok f) :
    Turing.eval step (stepNormal f (Cont.fix f k) v) =
      f.fix.eval v >>= fun v => Turing.eval step (Cfg.ret k v) := by
  refine' Part.ext fun x => _
  

Proof state:
f : Code
k : Cont
v : List ℕ
fok : Code.Ok f
x : Cfg
⊢ x ∈ eval step (stepNormal f (Cont.fix f k) v) ↔
    x ∈ do
      let v ← Code.eval (Code.fix f) v
      eval step (Cfg.ret k v)

Next tactic:
simp only [Part.bind_eq_bind, Part.mem_bind_iff]
theorem cont_eval_fix {f k v} (fok : Code.Ok f) :
    Turing.eval step (stepNormal f (Cont.fix f k) v) =
      f.fix.eval v >>= fun v => Turing.eval step (Cfg.ret k v) := by
  refine' Part.ext fun x => _
  simp only [Part.bind_eq_bind, Part.mem_bind_iff]
  

Proof state:
f : Code
k : Cont
v : List ℕ
fok : Code.Ok f
x : Cfg
⊢ x ∈ eval step (stepNormal f (Cont.fix f k) v) ↔ ∃ a ∈ Code.eval (Code.fix f) v, x ∈ eval step (Cfg.ret k a)

Next tactic:
constructor
theorem cont_eval_fix {f k v} (fok : Code.Ok f) :
    Turing.eval step (stepNormal f (Cont.fix f k) v) =
      f.fix.eval v >>= fun v => Turing.eval step (Cfg.ret k v) := by
  refine' Part.ext fun x => _
  simp only [Part.bind_eq_bind, Part.mem_bind_iff]
  constructor
  · 

Proof state:
case mp
f : Code
k : Cont
v : List ℕ
fok : Code.Ok f
x : Cfg
⊢ x ∈ eval step (stepNormal f (Cont.fix f k) v) → ∃ a ∈ Code.eval (Code.fix f) v, x ∈ eval step (Cfg.ret k a)

Next tactic:
suffices ∀ c, x ∈ eval step c → ∀ v c', c = Cfg.then c' (Cont.fix f k) →
      Reaches step (stepNormal f Cont.halt v) c' →
        ∃ v₁ ∈ f.eval v, ∃ v₂ ∈ if List.headI v₁ = 0 then pure v₁.tail else f.fix.eval v₁.tail,
          x ∈ eval step (Cfg.ret k v₂) by
      intro h
      obtain ⟨v₁, hv₁, v₂, hv₂, h₃⟩ :=
        this _ h _ _ (stepNormal_then _ Cont.halt _ _) ReflTransGen.refl
      refine' ⟨v₂, PFun.mem_fix_iff.2 _, h₃⟩
      simp only [Part.eq_some_iff.2 hv₁, Part.map_some]
      split_ifs at hv₂ ⊢
      · rw [Part.mem_some_iff.1 hv₂]
        exact Or.inl (Part.mem_some _)
      · exact Or.inr ⟨_, Part.mem_some _, hv₂⟩
theorem cont_eval_fix {f k v} (fok : Code.Ok f) :
    Turing.eval step (stepNormal f (Cont.fix f k) v) =
      f.fix.eval v >>= fun v => Turing.eval step (Cfg.ret k v) := by
  refine' Part.ext fun x => _
  simp only [Part.bind_eq_bind, Part.mem_bind_iff]
  constructor
  · suffices ∀ c, x ∈ eval step c → ∀ v c', c = Cfg.then c' (Cont.fix f k) →
      Reaches step (stepNormal f Cont.halt v) c' →
        ∃ v₁ ∈ f.eval v, ∃ v₂ ∈ if List.headI v₁ = 0 then pure v₁.tail else f.fix.eval v₁.tail,
          x ∈ eval step (Cfg.ret k v₂) by
      

Proof state:
f : Code
k : Cont
v : List ℕ
fok : Code.Ok f
x : Cfg
this :
  ∀ (c : Cfg),
    x ∈ eval step c →
      ∀ (v : List ℕ) (c' : Cfg),
        c = Cfg.then c' (Cont.fix f k) →
          Reaches step (stepNormal f Cont.halt v) c' →
            ∃ v₁ ∈ Code.eval f v,
              ∃ v₂ ∈ if List.headI v₁ = 0 then pure (List.tail v₁) else Code.eval (Code.fix f) (List.tail v₁),
                x ∈ eval step (Cfg.ret k v₂)
⊢ x ∈ eval step (stepNormal f (Cont.fix f k) v) → ∃ a ∈ Code.eval (Code.fix f) v, x ∈ eval step (Cfg.ret k a)

Next tactic:
intro h
theorem cont_eval_fix {f k v} (fok : Code.Ok f) :
    Turing.eval step (stepNormal f (Cont.fix f k) v) =
      f.fix.eval v >>= fun v => Turing.eval step (Cfg.ret k v) := by
  refine' Part.ext fun x => _
  simp only [Part.bind_eq_bind, Part.mem_bind_iff]
  constructor
  · suffices ∀ c, x ∈ eval step c → ∀ v c', c = Cfg.then c' (Cont.fix f k) →
      Reaches step (stepNormal f Cont.halt v) c' →
        ∃ v₁ ∈ f.eval v, ∃ v₂ ∈ if List.headI v₁ = 0 then pure v₁.tail else f.fix.eval v₁.tail,
          x ∈ eval step (Cfg.ret k v₂) by
      intro h
      

Proof state:
f : Code
k : Cont
v : List ℕ
fok : Code.Ok f
x : Cfg
this :
  ∀ (c : Cfg),
    x ∈ eval step c →
      ∀ (v : List ℕ) (c' : Cfg),
        c = Cfg.then c' (Cont.fix f k) →
          Reaches step (stepNormal f Cont.halt v) c' →
            ∃ v₁ ∈ Code.eval f v,
              ∃ v₂ ∈ if List.headI v₁ = 0 then pure (List.tail v₁) else Code.eval (Code.fix f) (List.tail v₁),
                x ∈ eval step (Cfg.ret k v₂)
h : x ∈ eval step (stepNormal f (Cont.fix f k) v)
⊢ ∃ a ∈ Code.eval (Code.fix f) v, x ∈ eval step (Cfg.ret k a)

Next tactic:
obtain ⟨v₁, hv₁, v₂, hv₂, h₃⟩ :=
        this _ h _ _ (stepNormal_then _ Cont.halt _ _) ReflTransGen.refl
theorem cont_eval_fix {f k v} (fok : Code.Ok f) :
    Turing.eval step (stepNormal f (Cont.fix f k) v) =
      f.fix.eval v >>= fun v => Turing.eval step (Cfg.ret k v) := by
  refine' Part.ext fun x => _
  simp only [Part.bind_eq_bind, Part.mem_bind_iff]
  constructor
  · suffices ∀ c, x ∈ eval step c → ∀ v c', c = Cfg.then c' (Cont.fix f k) →
      Reaches step (stepNormal f Cont.halt v) c' →
        ∃ v₁ ∈ f.eval v, ∃ v₂ ∈ if List.headI v₁ = 0 then pure v₁.tail else f.fix.eval v₁.tail,
          x ∈ eval step (Cfg.ret k v₂) by
      intro h
      obtain ⟨v₁, hv₁, v₂, hv₂, h₃⟩ :=
        this _ h _ _ (stepNormal_then _ Cont.halt _ _) ReflTransGen.refl
      

Proof state:
case intro.intro.intro.intro
f : Code
k : Cont
v : List ℕ
fok : Code.Ok f
x : Cfg
this :
  ∀ (c : Cfg),
    x ∈ eval step c →
      ∀ (v : List ℕ) (c' : Cfg),
        c = Cfg.then c' (Cont.fix f k) →
          Reaches step (stepNormal f Cont.halt v) c' →
            ∃ v₁ ∈ Code.eval f v,
              ∃ v₂ ∈ if List.headI v₁ = 0 then pure (List.tail v₁) else Code.eval (Code.fix f) (List.tail v₁),
                x ∈ eval step (Cfg.ret k v₂)
h : x ∈ eval step (stepNormal f (Cont.fix f k) v)
v₁ : List ℕ
hv₁ : v₁ ∈ Code.eval f v
v₂ : List ℕ
hv₂ : v₂ ∈ if List.headI v₁ = 0 then pure (List.tail v₁) else Code.eval (Code.fix f) (List.tail v₁)
h₃ : x ∈ eval step (Cfg.ret k v₂)
⊢ ∃ a ∈ Code.eval (Code.fix f) v, x ∈ eval step (Cfg.ret k a)

Next tactic:
refine' ⟨v₂, PFun.mem_fix_iff.2 _, h₃⟩
theorem cont_eval_fix {f k v} (fok : Code.Ok f) :
    Turing.eval step (stepNormal f (Cont.fix f k) v) =
      f.fix.eval v >>= fun v => Turing.eval step (Cfg.ret k v) := by
  refine' Part.ext fun x => _
  simp only [Part.bind_eq_bind, Part.mem_bind_iff]
  constructor
  · suffices ∀ c, x ∈ eval step c → ∀ v c', c = Cfg.then c' (Cont.fix f k) →
      Reaches step (stepNormal f Cont.halt v) c' →
        ∃ v₁ ∈ f.eval v, ∃ v₂ ∈ if List.headI v₁ = 0 then pure v₁.tail else f.fix.eval v₁.tail,
          x ∈ eval step (Cfg.ret k v₂) by
      intro h
      obtain ⟨v₁, hv₁, v₂, hv₂, h₃⟩ :=
        this _ h _ _ (stepNormal_then _ Cont.halt _ _) ReflTransGen.refl
      refine' ⟨v₂, PFun.mem_fix_iff.2 _, h₃⟩
      

Proof state:
case intro.intro.intro.intro
f : Code
k : Cont
v : List ℕ
fok : Code.Ok f
x : Cfg
this :
  ∀ (c : Cfg),
    x ∈ eval step c →
      ∀ (v : List ℕ) (c' : Cfg),
        c = Cfg.then c' (Cont.fix f k) →
          Reaches step (stepNormal f Cont.halt v) c' →
            ∃ v₁ ∈ Code.eval f v,
              ∃ v₂ ∈ if List.headI v₁ = 0 then pure (List.tail v₁) else Code.eval (Code.fix f) (List.tail v₁),
                x ∈ eval step (Cfg.ret k v₂)
h : x ∈ eval step (stepNormal f (Cont.fix f k) v)
v₁ : List ℕ
hv₁ : v₁ ∈ Code.eval f v
v₂ : List ℕ
hv₂ : v₂ ∈ if List.headI v₁ = 0 then pure (List.tail v₁) else Code.eval (Code.fix f) (List.tail v₁)
h₃ : x ∈ eval step (Cfg.ret k v₂)
⊢ Sum.inl v₂ ∈
      Part.map (fun v => if List.headI v = 0 then Sum.inl (List.tail v) else Sum.inr (List.tail v)) (Code.eval f v) ∨
    ∃ a',
      Sum.inr a' ∈
          Part.map (fun v => if List.headI v = 0 then Sum.inl (List.tail v) else Sum.inr (List.tail v))
            (Code.eval f v) ∧
        v₂ ∈
          PFun.fix
            (fun v =>
              Part.map (fun v => if List.headI v = 0 then Sum.inl (List.tail v) else Sum.inr (List.tail v))
                (Code.eval f v))
            a'

Next tactic:
simp only [Part.eq_some_iff.2 hv₁, Part.map_some]
theorem cont_eval_fix {f k v} (fok : Code.Ok f) :
    Turing.eval step (stepNormal f (Cont.fix f k) v) =
      f.fix.eval v >>= fun v => Turing.eval step (Cfg.ret k v) := by
  refine' Part.ext fun x => _
  simp only [Part.bind_eq_bind, Part.mem_bind_iff]
  constructor
  · suffices ∀ c, x ∈ eval step c → ∀ v c', c = Cfg.then c' (Cont.fix f k) →
      Reaches step (stepNormal f Cont.halt v) c' →
        ∃ v₁ ∈ f.eval v, ∃ v₂ ∈ if List.headI v₁ = 0 then pure v₁.tail else f.fix.eval v₁.tail,
          x ∈ eval step (Cfg.ret k v₂) by
      intro h
      obtain ⟨v₁, hv₁, v₂, hv₂, h₃⟩ :=
        this _ h _ _ (stepNormal_then _ Cont.halt _ _) ReflTransGen.refl
      refine' ⟨v₂, PFun.mem_fix_iff.2 _, h₃⟩
      simp only [Part.eq_some_iff.2 hv₁, Part.map_some]
      

Proof state:
case intro.intro.intro.intro
f : Code
k : Cont
v : List ℕ
fok : Code.Ok f
x : Cfg
this :
  ∀ (c : Cfg),
    x ∈ eval step c →
      ∀ (v : List ℕ) (c' : Cfg),
        c = Cfg.then c' (Cont.fix f k) →
          Reaches step (stepNormal f Cont.halt v) c' →
            ∃ v₁ ∈ Code.eval f v,
              ∃ v₂ ∈ if List.headI v₁ = 0 then pure (List.tail v₁) else Code.eval (Code.fix f) (List.tail v₁),
                x ∈ eval step (Cfg.ret k v₂)
h : x ∈ eval step (stepNormal f (Cont.fix f k) v)
v₁ : List ℕ
hv₁ : v₁ ∈ Code.eval f v
v₂ : List ℕ
hv₂ : v₂ ∈ if List.headI v₁ = 0 then pure (List.tail v₁) else Code.eval (Code.fix f) (List.tail v₁)
h₃ : x ∈ eval step (Cfg.ret k v₂)
⊢ Sum.inl v₂ ∈ Part.some (if List.headI v₁ = 0 then Sum.inl (List.tail v₁) else Sum.inr (List.tail v₁)) ∨
    ∃ a',
      Sum.inr a' ∈ Part.some (if List.headI v₁ = 0 then Sum.inl (List.tail v₁) else Sum.inr (List.tail v₁)) ∧
        v₂ ∈
          PFun.fix
            (fun v =>
              Part.map (fun v => if List.headI v = 0 then Sum.inl (List.tail v) else Sum.inr (List.tail v))
                (Code.eval f v))
            a'

Next tactic:
split_ifs at hv₂ ⊢
theorem cont_eval_fix {f k v} (fok : Code.Ok f) :
    Turing.eval step (stepNormal f (Cont.fix f k) v) =
      f.fix.eval v >>= fun v => Turing.eval step (Cfg.ret k v) := by
  refine' Part.ext fun x => _
  simp only [Part.bind_eq_bind, Part.mem_bind_iff]
  constructor
  · suffices ∀ c, x ∈ eval step c → ∀ v c', c = Cfg.then c' (Cont.fix f k) →
      Reaches step (stepNormal f Cont.halt v) c' →
        ∃ v₁ ∈ f.eval v, ∃ v₂ ∈ if List.headI v₁ = 0 then pure v₁.tail else f.fix.eval v₁.tail,
          x ∈ eval step (Cfg.ret k v₂) by
      intro h
      obtain ⟨v₁, hv₁, v₂, hv₂, h₃⟩ :=
        this _ h _ _ (stepNormal_then _ Cont.halt _ _) ReflTransGen.refl
      refine' ⟨v₂, PFun.mem_fix_iff.2 _, h₃⟩
      simp only [Part.eq_some_iff.2 hv₁, Part.map_some]
      split_ifs at hv₂ ⊢
      · 

Proof state:
case pos
f : Code
k : Cont
v : List ℕ
fok : Code.Ok f
x : Cfg
this :
  ∀ (c : Cfg),
    x ∈ eval step c →
      ∀ (v : List ℕ) (c' : Cfg),
        c = Cfg.then c' (Cont.fix f k) →
          Reaches step (stepNormal f Cont.halt v) c' →
            ∃ v₁ ∈ Code.eval f v,
              ∃ v₂ ∈ if List.headI v₁ = 0 then pure (List.tail v₁) else Code.eval (Code.fix f) (List.tail v₁),
                x ∈ eval step (Cfg.ret k v₂)
h : x ∈ eval step (stepNormal f (Cont.fix f k) v)
v₁ : List ℕ
hv₁ : v₁ ∈ Code.eval f v
v₂ : List ℕ
h₃ : x ∈ eval step (Cfg.ret k v₂)
h✝ : List.headI v₁ = 0
hv₂ : v₂ ∈ pure (List.tail v₁)
⊢ Sum.inl v₂ ∈ Part.some (Sum.inl (List.tail v₁)) ∨
    ∃ a',
      Sum.inr a' ∈ Part.some (Sum.inl (List.tail v₁)) ∧
        v₂ ∈
          PFun.fix
            (fun v =>
              Part.map (fun v => if List.headI v = 0 then Sum.inl (List.tail v) else Sum.inr (List.tail v))
                (Code.eval f v))
            a'

Next tactic:
rw [Part.mem_some_iff.1 hv₂]
theorem cont_eval_fix {f k v} (fok : Code.Ok f) :
    Turing.eval step (stepNormal f (Cont.fix f k) v) =
      f.fix.eval v >>= fun v => Turing.eval step (Cfg.ret k v) := by
  refine' Part.ext fun x => _
  simp only [Part.bind_eq_bind, Part.mem_bind_iff]
  constructor
  · suffices ∀ c, x ∈ eval step c → ∀ v c', c = Cfg.then c' (Cont.fix f k) →
      Reaches step (stepNormal f Cont.halt v) c' →
        ∃ v₁ ∈ f.eval v, ∃ v₂ ∈ if List.headI v₁ = 0 then pure v₁.tail else f.fix.eval v₁.tail,
          x ∈ eval step (Cfg.ret k v₂) by
      intro h
      obtain ⟨v₁, hv₁, v₂, hv₂, h₃⟩ :=
        this _ h _ _ (stepNormal_then _ Cont.halt _ _) ReflTransGen.refl
      refine' ⟨v₂, PFun.mem_fix_iff.2 _, h₃⟩
      simp only [Part.eq_some_iff.2 hv₁, Part.map_some]
      split_ifs at hv₂ ⊢
      · rw [Part.mem_some_iff.1 hv₂]
        

Proof state:
case pos
f : Code
k : Cont
v : List ℕ
fok : Code.Ok f
x : Cfg
this :
  ∀ (c : Cfg),
    x ∈ eval step c →
      ∀ (v : List ℕ) (c' : Cfg),
        c = Cfg.then c' (Cont.fix f k) →
          Reaches step (stepNormal f Cont.halt v) c' →
            ∃ v₁ ∈ Code.eval f v,
              ∃ v₂ ∈ if List.headI v₁ = 0 then pure (List.tail v₁) else Code.eval (Code.fix f) (List.tail v₁),
                x ∈ eval step (Cfg.ret k v₂)
h : x ∈ eval step (stepNormal f (Cont.fix f k) v)
v₁ : List ℕ
hv₁ : v₁ ∈ Code.eval f v
v₂ : List ℕ
h₃ : x ∈ eval step (Cfg.ret k v₂)
h✝ : List.headI v₁ = 0
hv₂ : v₂ ∈ pure (List.tail v₁)
⊢ Sum.inl (List.tail v₁) ∈ Part.some (Sum.inl (List.tail v₁)) ∨
    ∃ a',
      Sum.inr a' ∈ Part.some (Sum.inl (List.tail v₁)) ∧
        List.tail v₁ ∈
          PFun.fix
            (fun v =>
              Part.map (fun v => if List.headI v = 0 then Sum.inl (List.tail v) else Sum.inr (List.tail v))
                (Code.eval f v))
            a'

Next tactic:
exact Or.inl (Part.mem_some _)