Theorem: Turing.ToPartrec.cont_eval_fix
File: Mathlib/Computability/TMToPartrec.lean

tactic: refine' Part.ext fun x => _
state_before: 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)

tactic: simp only [Part.bind_eq_bind, Part.mem_bind_iff]
state_before: 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)

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

tactic: refine' fun c he => evalInduction he fun y h IH => _
state_before: case mp
f : Code
k : Cont
v : List ℕ
fok : Code.Ok f
x : Cfg
⊢ ∀ (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₁,
              v₁ ∈ Code.eval f v ∧
                ∃ 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₂)

tactic: rintro v (⟨v'⟩ | ⟨k', v'⟩) rfl hr <;> rw [Cfg.then] at h IH <;> simp only [] at h IH
state_before: case mp
f : Code
k : Cont
v : List ℕ
fok : Code.Ok f
x c : Cfg
he : x ∈ eval step c
y : Cfg
h : x ∈ eval step y
IH :
  ∀ (a' : Cfg),
    step y = some a' →
      ∀ (v : List ℕ) (c' : Cfg),
        a' = Cfg.then c' (Cont.fix f k) →
          Reaches step (stepNormal f Cont.halt v) c' →
            ∃ v₁,
              v₁ ∈ Code.eval f v ∧
                ∃ 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₂)
⊢ ∀ (v : List ℕ) (c' : Cfg),
    y = Cfg.then c' (Cont.fix f k) →
      Reaches step (stepNormal f Cont.halt v) c' →
        ∃ v₁,
          v₁ ∈ Code.eval f v ∧
            ∃ 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₂)

tactic: intro h
state_before: 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₁,
              v₁ ∈ Code.eval f v ∧
                ∃ 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, a ∈ Code.eval (Code.fix f) v ∧ x ∈ eval step (Cfg.ret k a)

tactic: obtain ⟨v₁, hv₁, v₂, hv₂, h₃⟩ :=
  this _ h _ _ (stepNormal_then _ Cont.halt _ _) ReflTransGen.refl
state_before: 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₁,
              v₁ ∈ Code.eval f v ∧
                ∃ 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, a ∈ Code.eval (Code.fix f) v ∧ x ∈ eval step (Cfg.ret k a)

tactic: refine' ⟨v₂, PFun.mem_fix_iff.2 _, h₃⟩
state_before: 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₁,
              v₁ ∈ Code.eval f v ∧
                ∃ 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, a ∈ Code.eval (Code.fix f) v ∧ x ∈ eval step (Cfg.ret k a)

tactic: simp only [Part.eq_some_iff.2 hv₁, Part.map_some]
state_before: 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₁,
              v₁ ∈ Code.eval f v ∧
                ∃ 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'

tactic: split_ifs at hv₂ ⊢
state_before: 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₁,
              v₁ ∈ Code.eval f v ∧
                ∃ 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'

tactic: rw [Part.mem_some_iff.1 hv₂]
state_before: case intro.intro.intro.intro.inl
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₁,
              v₁ ∈ Code.eval f v ∧
                ∃ 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'

tactic: exact Or.inl (Part.mem_some _)
state_before: case intro.intro.intro.intro.inl
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₁,
              v₁ ∈ Code.eval f v ∧
                ∃ 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'

tactic: exact Or.inr ⟨_, Part.mem_some _, hv₂⟩
state_before: case intro.intro.intro.intro.inr
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₁,
              v₁ ∈ Code.eval f v ∧
                ∃ 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₂ ∈ Code.eval (Code.fix f) (List.tail v₁)
⊢ Sum.inl v₂ ∈ Part.some (Sum.inr (List.tail v₁)) ∨
    ∃ a',
      Sum.inr a' ∈ Part.some (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'

tactic: have := mem_eval.2 ⟨hr, rfl⟩
state_before: case mp.halt
f : Code
k : Cont
v✝ : List ℕ
fok : Code.Ok f
x c : Cfg
he : x ∈ eval step c
v v' : List ℕ
h : x ∈ eval step (stepRet (Cont.fix f k) v')
IH :
  ∀ (a' : Cfg),
    step (stepRet (Cont.fix f k) v') = some a' →
      ∀ (v : List ℕ) (c' : Cfg),
        a' = Cfg.then c' (Cont.fix f k) →
          Reaches step (stepNormal f Cont.halt v) c' →
            ∃ v₁,
              v₁ ∈ Code.eval f v ∧
                ∃ 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₂)
hr : Reaches step (stepNormal f Cont.halt v) (Cfg.halt v')
⊢ ∃ v₁,
    v₁ ∈ Code.eval f v ∧
      ∃ 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₂)

tactic: rw [fok, Part.bind_eq_bind, Part.mem_bind_iff] at this
state_before: case mp.halt
f : Code
k : Cont
v✝ : List ℕ
fok : Code.Ok f
x c : Cfg
he : x ∈ eval step c
v v' : List ℕ
h : x ∈ eval step (stepRet (Cont.fix f k) v')
IH :
  ∀ (a' : Cfg),
    step (stepRet (Cont.fix f k) v') = some a' →
      ∀ (v : List ℕ) (c' : Cfg),
        a' = Cfg.then c' (Cont.fix f k) →
          Reaches step (stepNormal f Cont.halt v) c' →
            ∃ v₁,
              v₁ ∈ Code.eval f v ∧
                ∃ 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₂)
hr : Reaches step (stepNormal f Cont.halt v) (Cfg.halt v')
this : Cfg.halt v' ∈ eval step (stepNormal f Cont.halt v)
⊢ ∃ v₁,
    v₁ ∈ Code.eval f v ∧
      ∃ 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₂)

tactic: obtain ⟨v'', h₁, h₂⟩ := this
state_before: case mp.halt
f : Code
k : Cont
v✝ : List ℕ
fok : Code.Ok f
x c : Cfg
he : x ∈ eval step c
v v' : List ℕ
h : x ∈ eval step (stepRet (Cont.fix f k) v')
IH :
  ∀ (a' : Cfg),
    step (stepRet (Cont.fix f k) v') = some a' →
      ∀ (v : List ℕ) (c' : Cfg),
        a' = Cfg.then c' (Cont.fix f k) →
          Reaches step (stepNormal f Cont.halt v) c' →
            ∃ v₁,
              v₁ ∈ Code.eval f v ∧
                ∃ 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₂)
hr : Reaches step (stepNormal f Cont.halt v) (Cfg.halt v')
this : ∃ a, a ∈ Code.eval f v ∧ Cfg.halt v' ∈ eval step (Cfg.ret Cont.halt a)
⊢ ∃ v₁,
    v₁ ∈ Code.eval f v ∧
      ∃ 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₂)

tactic: rw [reaches_eval] at h₂
state_before: case mp.halt.intro.intro
f : Code
k : Cont
v✝ : List ℕ
fok : Code.Ok f
x c : Cfg
he : x ∈ eval step c
v v' : List ℕ
h : x ∈ eval step (stepRet (Cont.fix f k) v')
IH :
  ∀ (a' : Cfg),
    step (stepRet (Cont.fix f k) v') = some a' →
      ∀ (v : List ℕ) (c' : Cfg),
        a' = Cfg.then c' (Cont.fix f k) →
          Reaches step (stepNormal f Cont.halt v) c' →
            ∃ v₁,
              v₁ ∈ Code.eval f v ∧
                ∃ 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₂)
hr : Reaches step (stepNormal f Cont.halt v) (Cfg.halt v')
v'' : List ℕ
h₁ : v'' ∈ Code.eval f v
h₂ : Cfg.halt v' ∈ eval step (Cfg.ret Cont.halt v'')
⊢ ∃ v₁,
    v₁ ∈ Code.eval f v ∧
      ∃ 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₂)

tactic: swap
state_before: case mp.halt.intro.intro
f : Code
k : Cont
v✝ : List ℕ
fok : Code.Ok f
x c : Cfg
he : x ∈ eval step c
v v' : List ℕ
h : x ∈ eval step (stepRet (Cont.fix f k) v')
IH :
  ∀ (a' : Cfg),
    step (stepRet (Cont.fix f k) v') = some a' →
      ∀ (v : List ℕ) (c' : Cfg),
        a' = Cfg.then c' (Cont.fix f k) →
          Reaches step (stepNormal f Cont.halt v) c' →
            ∃ v₁,
              v₁ ∈ Code.eval f v ∧
                ∃ 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₂)
hr : Reaches step (stepNormal f Cont.halt v) (Cfg.halt v')
v'' : List ℕ
h₁ : v'' ∈ Code.eval f v
h₂✝ : Cfg.halt v' ∈ eval step (Cfg.ret Cont.halt v'')
h₂ : Cfg.halt v' ∈ eval step ?m.191025
⊢ ∃ v₁,
    v₁ ∈ Code.eval f v ∧
      ∃ 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₂)

case mp.halt.intro.intro
f : Code
k : Cont
v✝ : List ℕ
fok : Code.Ok f
x c : Cfg
he : x ∈ eval step c
v v' : List ℕ
h : x ∈ eval step (stepRet (Cont.fix f k) v')
IH :
  ∀ (a' : Cfg),
    step (stepRet (Cont.fix f k) v') = some a' →
      ∀ (v : List ℕ) (c' : Cfg),
        a' = Cfg.then c' (Cont.fix f k) →
          Reaches step (stepNormal f Cont.halt v) c' →
            ∃ v₁,
              v₁ ∈ Code.eval f v ∧
                ∃ 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₂)
hr : Reaches step (stepNormal f Cont.halt v) (Cfg.halt v')
v'' : List ℕ
h₁ : v'' ∈ Code.eval f v
h₂ : Cfg.halt v' ∈ eval step (Cfg.ret Cont.halt v'')
⊢ Reaches step (Cfg.ret Cont.halt v'') ?m.191025

f : Code
k : Cont
v✝ : List ℕ
fok : Code.Ok f
x c : Cfg
he : x ∈ eval step c
v v' : List ℕ
h : x ∈ eval step (stepRet (Cont.fix f k) v')
IH :
  ∀ (a' : Cfg),
    step (stepRet (Cont.fix f k) v') = some a' →
      ∀ (v : List ℕ) (c' : Cfg),
        a' = Cfg.then c' (Cont.fix f k) →
          Reaches step (stepNormal f Cont.halt v) c' →
            ∃ v₁,
              v₁ ∈ Code.eval f v ∧
                ∃ 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₂)
hr : Reaches step (stepNormal f Cont.halt v) (Cfg.halt v')
v'' : List ℕ
h₁ : v'' ∈ Code.eval f v
h₂ : Cfg.halt v' ∈ eval step (Cfg.ret Cont.halt v'')
⊢ Cfg

tactic: exact ReflTransGen.single rfl
state_before: case mp.halt.intro.intro
f : Code
k : Cont
v✝ : List ℕ
fok : Code.Ok f
x c : Cfg
he : x ∈ eval step c
v v' : List ℕ
h : x ∈ eval step (stepRet (Cont.fix f k) v')
IH :
  ∀ (a' : Cfg),
    step (stepRet (Cont.fix f k) v') = some a' →
      ∀ (v : List ℕ) (c' : Cfg),
        a' = Cfg.then c' (Cont.fix f k) →
          Reaches step (stepNormal f Cont.halt v) c' →
            ∃ v₁,
              v₁ ∈ Code.eval f v ∧
                ∃ 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₂)
hr : Reaches step (stepNormal f Cont.halt v) (Cfg.halt v')
v'' : List ℕ
h₁ : v'' ∈ Code.eval f v
h₂ : Cfg.halt v' ∈ eval step (Cfg.ret Cont.halt v'')
⊢ Reaches step (Cfg.ret Cont.halt v'') ?m.191025

case mp.halt.intro.intro
f : Code
k : Cont
v✝ : List ℕ
fok : Code.Ok f
x c : Cfg
he : x ∈ eval step c
v v' : List ℕ
h : x ∈ eval step (stepRet (Cont.fix f k) v')
IH :
  ∀ (a' : Cfg),
    step (stepRet (Cont.fix f k) v') = some a' →
      ∀ (v : List ℕ) (c' : Cfg),
        a' = Cfg.then c' (Cont.fix f k) →
          Reaches step (stepNormal f Cont.halt v) c' →
            ∃ v₁,
              v₁ ∈ Code.eval f v ∧
                ∃ 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₂)
hr : Reaches step (stepNormal f Cont.halt v) (Cfg.halt v')
v'' : List ℕ
h₁ : v'' ∈ Code.eval f v
h₂✝ : Cfg.halt v' ∈ eval step (Cfg.ret Cont.halt v'')
h₂ : Cfg.halt v' ∈ eval step ?m.191025
⊢ ∃ v₁,
    v₁ ∈ Code.eval f v ∧
      ∃ 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₂)

f : Code
k : Cont
v✝ : List ℕ
fok : Code.Ok f
x c : Cfg
he : x ∈ eval step c
v v' : List ℕ
h : x ∈ eval step (stepRet (Cont.fix f k) v')
IH :
  ∀ (a' : Cfg),
    step (stepRet (Cont.fix f k) v') = some a' →
      ∀ (v : List ℕ) (c' : Cfg),
        a' = Cfg.then c' (Cont.fix f k) →
          Reaches step (stepNormal f Cont.halt v) c' →
            ∃ v₁,
              v₁ ∈ Code.eval f v ∧
                ∃ 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₂)
hr : Reaches step (stepNormal f Cont.halt v) (Cfg.halt v')
v'' : List ℕ
h₁ : v'' ∈ Code.eval f v
h₂ : Cfg.halt v' ∈ eval step (Cfg.ret Cont.halt v'')
⊢ Cfg

tactic: cases Part.mem_unique h₂ (mem_eval.2 ⟨ReflTransGen.refl, rfl⟩)
state_before: case mp.halt.intro.intro
f : Code
k : Cont
v✝ : List ℕ
fok : Code.Ok f
x c : Cfg
he : x ∈ eval step c
v v' : List ℕ
h : x ∈ eval step (stepRet (Cont.fix f k) v')
IH :
  ∀ (a' : Cfg),
    step (stepRet (Cont.fix f k) v') = some a' →
      ∀ (v : List ℕ) (c' : Cfg),
        a' = Cfg.then c' (Cont.fix f k) →
          Reaches step (stepNormal f Cont.halt v) c' →
            ∃ v₁,
              v₁ ∈ Code.eval f v ∧
                ∃ 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₂)
hr : Reaches step (stepNormal f Cont.halt v) (Cfg.halt v')
v'' : List ℕ
h₁ : v'' ∈ Code.eval f v
h₂✝ : Cfg.halt v' ∈ eval step (Cfg.ret Cont.halt v'')
h₂ : Cfg.halt v' ∈ eval step (stepRet Cont.halt v'')
⊢ ∃ v₁,
    v₁ ∈ Code.eval f v ∧
      ∃ 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₂)

tactic: refine' ⟨v', h₁, _⟩
state_before: case mp.halt.intro.intro.refl
f : Code
k : Cont
v✝ : List ℕ
fok : Code.Ok f
x c : Cfg
he : x ∈ eval step c
v v' : List ℕ
h : x ∈ eval step (stepRet (Cont.fix f k) v')
IH :
  ∀ (a' : Cfg),
    step (stepRet (Cont.fix f k) v') = some a' →
      ∀ (v : List ℕ) (c' : Cfg),
        a' = Cfg.then c' (Cont.fix f k) →
          Reaches step (stepNormal f Cont.halt v) c' →
            ∃ v₁,
              v₁ ∈ Code.eval f v ∧
                ∃ 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₂)
hr : Reaches step (stepNormal f Cont.halt v) (Cfg.halt v')
h₁ : v' ∈ Code.eval f v
h₂✝ : Cfg.halt v' ∈ eval step (Cfg.ret Cont.halt v')
h₂ : Cfg.halt v' ∈ eval step (stepRet Cont.halt v')
⊢ ∃ v₁,
    v₁ ∈ Code.eval f v ∧
      ∃ 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₂)

tactic: rw [stepRet] at h
state_before: case mp.halt.intro.intro.refl
f : Code
k : Cont
v✝ : List ℕ
fok : Code.Ok f
x c : Cfg
he : x ∈ eval step c
v v' : List ℕ
h : x ∈ eval step (stepRet (Cont.fix f k) v')
IH :
  ∀ (a' : Cfg),
    step (stepRet (Cont.fix f k) v') = some a' →
      ∀ (v : List ℕ) (c' : Cfg),
        a' = Cfg.then c' (Cont.fix f k) →
          Reaches step (stepNormal f Cont.halt v) c' →
            ∃ v₁,
              v₁ ∈ Code.eval f v ∧
                ∃ 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₂)
hr : Reaches step (stepNormal f Cont.halt v) (Cfg.halt v')
h₁ : v' ∈ Code.eval f v
h₂✝ : Cfg.halt v' ∈ eval step (Cfg.ret Cont.halt v')
h₂ : Cfg.halt v' ∈ eval step (stepRet Cont.halt v')
⊢ ∃ 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₂)

tactic: revert h
state_before: case mp.halt.intro.intro.refl
f : Code
k : Cont
v✝ : List ℕ
fok : Code.Ok f
x c : Cfg
he : x ∈ eval step c
v v' : List ℕ
h : x ∈ eval step (if List.headI v' = 0 then stepRet k (List.tail v') else stepNormal f (Cont.fix f k) (List.tail v'))
IH :
  ∀ (a' : Cfg),
    step (stepRet (Cont.fix f k) v') = some a' →
      ∀ (v : List ℕ) (c' : Cfg),
        a' = Cfg.then c' (Cont.fix f k) →
          Reaches step (stepNormal f Cont.halt v) c' →
            ∃ v₁,
              v₁ ∈ Code.eval f v ∧
                ∃ 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₂)
hr : Reaches step (stepNormal f Cont.halt v) (Cfg.halt v')
h₁ : v' ∈ Code.eval f v
h₂✝ : Cfg.halt v' ∈ eval step (Cfg.ret Cont.halt v')
h₂ : Cfg.halt v' ∈ eval step (stepRet Cont.halt v')
⊢ ∃ 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₂)

tactic: by_cases he : v'.headI = 0 <;> simp only [exists_prop, if_pos, if_false, he] <;> intro h
state_before: case mp.halt.intro.intro.refl
f : Code
k : Cont
v✝ : List ℕ
fok : Code.Ok f
x c : Cfg
he : x ∈ eval step c
v v' : List ℕ
IH :
  ∀ (a' : Cfg),
    step (stepRet (Cont.fix f k) v') = some a' →
      ∀ (v : List ℕ) (c' : Cfg),
        a' = Cfg.then c' (Cont.fix f k) →
          Reaches step (stepNormal f Cont.halt v) c' →
            ∃ v₁,
              v₁ ∈ Code.eval f v ∧
                ∃ 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₂)
hr : Reaches step (stepNormal f Cont.halt v) (Cfg.halt v')
h₁ : v' ∈ Code.eval f v
h₂✝ : Cfg.halt v' ∈ eval step (Cfg.ret Cont.halt v')
h₂ : Cfg.halt v' ∈ eval step (stepRet Cont.halt v')
⊢ x ∈ eval step (if List.headI v' = 0 then stepRet k (List.tail v') else stepNormal f (Cont.fix f k) (List.tail v')) →
    ∃ 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₂)

tactic: refine' ⟨_, Part.mem_some _, _⟩
state_before: case pos
f : Code
k : Cont
v✝ : List ℕ
fok : Code.Ok f
x c : Cfg
he✝ : x ∈ eval step c
v v' : List ℕ
IH :
  ∀ (a' : Cfg),
    step (stepRet (Cont.fix f k) v') = some a' →
      ∀ (v : List ℕ) (c' : Cfg),
        a' = Cfg.then c' (Cont.fix f k) →
          Reaches step (stepNormal f Cont.halt v) c' →
            ∃ v₁,
              v₁ ∈ Code.eval f v ∧
                ∃ 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₂)
hr : Reaches step (stepNormal f Cont.halt v) (Cfg.halt v')
h₁ : v' ∈ Code.eval f v
h₂✝ : Cfg.halt v' ∈ eval step (Cfg.ret Cont.halt v')
h₂ : Cfg.halt v' ∈ eval step (stepRet Cont.halt v')
he : List.headI v' = 0
h : x ∈ eval step (stepRet k (List.tail v'))
⊢ ∃ v₂, v₂ ∈ pure (List.tail v') ∧ x ∈ eval step (Cfg.ret k v₂)

tactic: rw [reaches_eval]
state_before: case pos
f : Code
k : Cont
v✝ : List ℕ
fok : Code.Ok f
x c : Cfg
he✝ : x ∈ eval step c
v v' : List ℕ
IH :
  ∀ (a' : Cfg),
    step (stepRet (Cont.fix f k) v') = some a' →
      ∀ (v : List ℕ) (c' : Cfg),
        a' = Cfg.then c' (Cont.fix f k) →
          Reaches step (stepNormal f Cont.halt v) c' →
            ∃ v₁,
              v₁ ∈ Code.eval f v ∧
                ∃ 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₂)
hr : Reaches step (stepNormal f Cont.halt v) (Cfg.halt v')
h₁ : v' ∈ Code.eval f v
h₂✝ : Cfg.halt v' ∈ eval step (Cfg.ret Cont.halt v')
h₂ : Cfg.halt v' ∈ eval step (stepRet Cont.halt v')
he : List.headI v' = 0
h : x ∈ eval step (stepRet k (List.tail v'))
⊢ x ∈ eval step (Cfg.ret k (List.tail v'))

tactic: exact h
state_before: case pos
f : Code
k : Cont
v✝ : List ℕ
fok : Code.Ok f
x c : Cfg
he✝ : x ∈ eval step c
v v' : List ℕ
IH :
  ∀ (a' : Cfg),
    step (stepRet (Cont.fix f k) v') = some a' →
      ∀ (v : List ℕ) (c' : Cfg),
        a' = Cfg.then c' (Cont.fix f k) →
          Reaches step (stepNormal f Cont.halt v) c' →
            ∃ v₁,
              v₁ ∈ Code.eval f v ∧
                ∃ 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₂)
hr : Reaches step (stepNormal f Cont.halt v) (Cfg.halt v')
h₁ : v' ∈ Code.eval f v
h₂✝ : Cfg.halt v' ∈ eval step (Cfg.ret Cont.halt v')
h₂ : Cfg.halt v' ∈ eval step (stepRet Cont.halt v')
he : List.headI v' = 0
h : x ∈ eval step (stepRet k (List.tail v'))
⊢ x ∈ eval step ?m.192020

case pos
f : Code
k : Cont
v✝ : List ℕ
fok : Code.Ok f
x c : Cfg
he✝ : x ∈ eval step c
v v' : List ℕ
IH :
  ∀ (a' : Cfg),
    step (stepRet (Cont.fix f k) v') = some a' →
      ∀ (v : List ℕ) (c' : Cfg),
        a' = Cfg.then c' (Cont.fix f k) →
          Reaches step (stepNormal f Cont.halt v) c' →
            ∃ v₁,
              v₁ ∈ Code.eval f v ∧
                ∃ 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₂)
hr : Reaches step (stepNormal f Cont.halt v) (Cfg.halt v')
h₁ : v' ∈ Code.eval f v
h₂✝ : Cfg.halt v' ∈ eval step (Cfg.ret Cont.halt v')
h₂ : Cfg.halt v' ∈ eval step (stepRet Cont.halt v')
he : List.headI v' = 0
h : x ∈ eval step (stepRet k (List.tail v'))
⊢ Reaches step (Cfg.ret k (List.tail v')) ?m.192020

f : Code
k : Cont
v✝ : List ℕ
fok : Code.Ok f
x c : Cfg
he✝ : x ∈ eval step c
v v' : List ℕ
IH :
  ∀ (a' : Cfg),
    step (stepRet (Cont.fix f k) v') = some a' →
      ∀ (v : List ℕ) (c' : Cfg),
        a' = Cfg.then c' (Cont.fix f k) →
          Reaches step (stepNormal f Cont.halt v) c' →
            ∃ v₁,
              v₁ ∈ Code.eval f v ∧
                ∃ 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₂)
hr : Reaches step (stepNormal f Cont.halt v) (Cfg.halt v')
h₁ : v' ∈ Code.eval f v
h₂✝ : Cfg.halt v' ∈ eval step (Cfg.ret Cont.halt v')
h₂ : Cfg.halt v' ∈ eval step (stepRet Cont.halt v')
he : List.headI v' = 0
h : x ∈ eval step (stepRet k (List.tail v'))
⊢ Cfg

tactic: exact ReflTransGen.single rfl
state_before: case pos
f : Code
k : Cont
v✝ : List ℕ
fok : Code.Ok f
x c : Cfg
he✝ : x ∈ eval step c
v v' : List ℕ
IH :
  ∀ (a' : Cfg),
    step (stepRet (Cont.fix f k) v') = some a' →
      ∀ (v : List ℕ) (c' : Cfg),
        a' = Cfg.then c' (Cont.fix f k) →
          Reaches step (stepNormal f Cont.halt v) c' →
            ∃ v₁,
              v₁ ∈ Code.eval f v ∧
                ∃ 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₂)
hr : Reaches step (stepNormal f Cont.halt v) (Cfg.halt v')
h₁ : v' ∈ Code.eval f v
h₂✝ : Cfg.halt v' ∈ eval step (Cfg.ret Cont.halt v')
h₂ : Cfg.halt v' ∈ eval step (stepRet Cont.halt v')
he : List.headI v' = 0
h : x ∈ eval step (stepRet k (List.tail v'))
⊢ Reaches step (Cfg.ret k (List.tail v')) (stepRet k (List.tail v'))

tactic: obtain ⟨k₀, v₀, e₀⟩ := stepNormal.is_ret f Cont.halt v'.tail
state_before: case neg
f : Code
k : Cont
v✝ : List ℕ
fok : Code.Ok f
x c : Cfg
he✝ : x ∈ eval step c
v v' : List ℕ
IH :
  ∀ (a' : Cfg),
    step (stepRet (Cont.fix f k) v') = some a' →
      ∀ (v : List ℕ) (c' : Cfg),
        a' = Cfg.then c' (Cont.fix f k) →
          Reaches step (stepNormal f Cont.halt v) c' →
            ∃ v₁,
              v₁ ∈ Code.eval f v ∧
                ∃ 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₂)
hr : Reaches step (stepNormal f Cont.halt v) (Cfg.halt v')
h₁ : v' ∈ Code.eval f v
h₂✝ : Cfg.halt v' ∈ eval step (Cfg.ret Cont.halt v')
h₂ : Cfg.halt v' ∈ eval step (stepRet Cont.halt v')
he : ¬List.headI v' = 0
h : x ∈ eval step (stepNormal f (Cont.fix f k) (List.tail v'))
⊢ ∃ v₂, v₂ ∈ Code.eval (Code.fix f) (List.tail v') ∧ x ∈ eval step (Cfg.ret k v₂)

tactic: have e₁ := stepNormal_then f Cont.halt (Cont.fix f k) v'.tail
state_before: case neg.intro.intro
f : Code
k : Cont
v✝ : List ℕ
fok : Code.Ok f
x c : Cfg
he✝ : x ∈ eval step c
v v' : List ℕ
IH :
  ∀ (a' : Cfg),
    step (stepRet (Cont.fix f k) v') = some a' →
      ∀ (v : List ℕ) (c' : Cfg),
        a' = Cfg.then c' (Cont.fix f k) →
          Reaches step (stepNormal f Cont.halt v) c' →
            ∃ v₁,
              v₁ ∈ Code.eval f v ∧
                ∃ 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₂)
hr : Reaches step (stepNormal f Cont.halt v) (Cfg.halt v')
h₁ : v' ∈ Code.eval f v
h₂✝ : Cfg.halt v' ∈ eval step (Cfg.ret Cont.halt v')
h₂ : Cfg.halt v' ∈ eval step (stepRet Cont.halt v')
he : ¬List.headI v' = 0
h : x ∈ eval step (stepNormal f (Cont.fix f k) (List.tail v'))
k₀ : Cont
v₀ : List ℕ
e₀ : stepNormal f Cont.halt (List.tail v') = Cfg.ret k₀ v₀
⊢ ∃ v₂, v₂ ∈ Code.eval (Code.fix f) (List.tail v') ∧ x ∈ eval step (Cfg.ret k v₂)

tactic: rw [e₀, Cont.then, Cfg.then] at e₁
state_before: case neg.intro.intro
f : Code
k : Cont
v✝ : List ℕ
fok : Code.Ok f
x c : Cfg
he✝ : x ∈ eval step c
v v' : List ℕ
IH :
  ∀ (a' : Cfg),
    step (stepRet (Cont.fix f k) v') = some a' →
      ∀ (v : List ℕ) (c' : Cfg),
        a' = Cfg.then c' (Cont.fix f k) →
          Reaches step (stepNormal f Cont.halt v) c' →
            ∃ v₁,
              v₁ ∈ Code.eval f v ∧
                ∃ 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₂)
hr : Reaches step (stepNormal f Cont.halt v) (Cfg.halt v')
h₁ : v' ∈ Code.eval f v
h₂✝ : Cfg.halt v' ∈ eval step (Cfg.ret Cont.halt v')
h₂ : Cfg.halt v' ∈ eval step (stepRet Cont.halt v')
he : ¬List.headI v' = 0
h : x ∈ eval step (stepNormal f (Cont.fix f k) (List.tail v'))
k₀ : Cont
v₀ : List ℕ
e₀ : stepNormal f Cont.halt (List.tail v') = Cfg.ret k₀ v₀
e₁ :
  stepNormal f (Cont.then Cont.halt (Cont.fix f k)) (List.tail v') =
    Cfg.then (stepNormal f Cont.halt (List.tail v')) (Cont.fix f k)
⊢ ∃ v₂, v₂ ∈ Code.eval (Code.fix f) (List.tail v') ∧ x ∈ eval step (Cfg.ret k v₂)

tactic: simp only [] at e₁
state_before: case neg.intro.intro
f : Code
k : Cont
v✝ : List ℕ
fok : Code.Ok f
x c : Cfg
he✝ : x ∈ eval step c
v v' : List ℕ
IH :
  ∀ (a' : Cfg),
    step (stepRet (Cont.fix f k) v') = some a' →
      ∀ (v : List ℕ) (c' : Cfg),
        a' = Cfg.then c' (Cont.fix f k) →
          Reaches step (stepNormal f Cont.halt v) c' →
            ∃ v₁,
              v₁ ∈ Code.eval f v ∧
                ∃ 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₂)
hr : Reaches step (stepNormal f Cont.halt v) (Cfg.halt v')
h₁ : v' ∈ Code.eval f v
h₂✝ : Cfg.halt v' ∈ eval step (Cfg.ret Cont.halt v')
h₂ : Cfg.halt v' ∈ eval step (stepRet Cont.halt v')
he : ¬List.headI v' = 0
h : x ∈ eval step (stepNormal f (Cont.fix f k) (List.tail v'))
k₀ : Cont
v₀ : List ℕ
e₀ : stepNormal f Cont.halt (List.tail v') = Cfg.ret k₀ v₀
e₁ :
  stepNormal f ((fun k' => k') (Cont.fix f k)) (List.tail v') =
    (match (motive := Cfg → Cont → Cfg) Cfg.ret k₀ v₀ with
      | Cfg.halt v => fun k' => stepRet k' v
      | Cfg.ret k v => fun k' => Cfg.ret (Cont.then k k') v)
      (Cont.fix f k)
⊢ ∃ v₂, v₂ ∈ Code.eval (Code.fix f) (List.tail v') ∧ x ∈ eval step (Cfg.ret k v₂)

tactic: obtain ⟨v₁, hv₁, v₂, hv₂, h₃⟩ :=
  IH (stepRet (k₀.then (Cont.fix f k)) v₀) (by rw [stepRet, if_neg he, e₁]; rfl)
    v'.tail _ stepRet_then (by apply ReflTransGen.single; rw [e₀]; rfl)
state_before: case neg.intro.intro
f : Code
k : Cont
v✝ : List ℕ
fok : Code.Ok f
x c : Cfg
he✝ : x ∈ eval step c
v v' : List ℕ
IH :
  ∀ (a' : Cfg),
    step (stepRet (Cont.fix f k) v') = some a' →
      ∀ (v : List ℕ) (c' : Cfg),
        a' = Cfg.then c' (Cont.fix f k) →
          Reaches step (stepNormal f Cont.halt v) c' →
            ∃ v₁,
              v₁ ∈ Code.eval f v ∧
                ∃ 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₂)
hr : Reaches step (stepNormal f Cont.halt v) (Cfg.halt v')
h₁ : v' ∈ Code.eval f v
h₂✝ : Cfg.halt v' ∈ eval step (Cfg.ret Cont.halt v')
h₂ : Cfg.halt v' ∈ eval step (stepRet Cont.halt v')
he : ¬List.headI v' = 0
h : x ∈ eval step (stepNormal f (Cont.fix f k) (List.tail v'))
k₀ : Cont
v₀ : List ℕ
e₀ : stepNormal f Cont.halt (List.tail v') = Cfg.ret k₀ v₀
e₁ : stepNormal f (Cont.fix f k) (List.tail v') = Cfg.ret (Cont.then k₀ (Cont.fix f k)) v₀
⊢ ∃ v₂, v₂ ∈ Code.eval (Code.fix f) (List.tail v') ∧ x ∈ eval step (Cfg.ret k v₂)

tactic: rw [stepRet, if_neg he, e₁]
state_before: f : Code
k : Cont
v✝ : List ℕ
fok : Code.Ok f
x c : Cfg
he✝ : x ∈ eval step c
v v' : List ℕ
IH :
  ∀ (a' : Cfg),
    step (stepRet (Cont.fix f k) v') = some a' →
      ∀ (v : List ℕ) (c' : Cfg),
        a' = Cfg.then c' (Cont.fix f k) →
          Reaches step (stepNormal f Cont.halt v) c' →
            ∃ v₁,
              v₁ ∈ Code.eval f v ∧
                ∃ 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₂)
hr : Reaches step (stepNormal f Cont.halt v) (Cfg.halt v')
h₁ : v' ∈ Code.eval f v
h₂✝ : Cfg.halt v' ∈ eval step (Cfg.ret Cont.halt v')
h₂ : Cfg.halt v' ∈ eval step (stepRet Cont.halt v')
he : ¬List.headI v' = 0
h : x ∈ eval step (stepNormal f (Cont.fix f k) (List.tail v'))
k₀ : Cont
v₀ : List ℕ
e₀ : stepNormal f Cont.halt (List.tail v') = Cfg.ret k₀ v₀
e₁ : stepNormal f (Cont.fix f k) (List.tail v') = Cfg.ret (Cont.then k₀ (Cont.fix f k)) v₀
⊢ step (stepRet (Cont.fix f k) v') = some (stepRet (Cont.then k₀ (Cont.fix f k)) v₀)

tactic: rfl
state_before: f : Code
k : Cont
v✝ : List ℕ
fok : Code.Ok f
x c : Cfg
he✝ : x ∈ eval step c
v v' : List ℕ
IH :
  ∀ (a' : Cfg),
    step (stepRet (Cont.fix f k) v') = some a' →
      ∀ (v : List ℕ) (c' : Cfg),
        a' = Cfg.then c' (Cont.fix f k) →
          Reaches step (stepNormal f Cont.halt v) c' →
            ∃ v₁,
              v₁ ∈ Code.eval f v ∧
                ∃ 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₂)
hr : Reaches step (stepNormal f Cont.halt v) (Cfg.halt v')
h₁ : v' ∈ Code.eval f v
h₂✝ : Cfg.halt v' ∈ eval step (Cfg.ret Cont.halt v')
h₂ : Cfg.halt v' ∈ eval step (stepRet Cont.halt v')
he : ¬List.headI v' = 0
h : x ∈ eval step (stepNormal f (Cont.fix f k) (List.tail v'))
k₀ : Cont
v₀ : List ℕ
e₀ : stepNormal f Cont.halt (List.tail v') = Cfg.ret k₀ v₀
e₁ : stepNormal f (Cont.fix f k) (List.tail v') = Cfg.ret (Cont.then k₀ (Cont.fix f k)) v₀
⊢ step (Cfg.ret (Cont.then k₀ (Cont.fix f k)) v₀) = some (stepRet (Cont.then k₀ (Cont.fix f k)) v₀)

tactic: apply ReflTransGen.single
state_before: f : Code
k : Cont
v✝ : List ℕ
fok : Code.Ok f
x c : Cfg
he✝ : x ∈ eval step c
v v' : List ℕ
IH :
  ∀ (a' : Cfg),
    step (stepRet (Cont.fix f k) v') = some a' →
      ∀ (v : List ℕ) (c' : Cfg),
        a' = Cfg.then c' (Cont.fix f k) →
          Reaches step (stepNormal f Cont.halt v) c' →
            ∃ v₁,
              v₁ ∈ Code.eval f v ∧
                ∃ 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₂)
hr : Reaches step (stepNormal f Cont.halt v) (Cfg.halt v')
h₁ : v' ∈ Code.eval f v
h₂✝ : Cfg.halt v' ∈ eval step (Cfg.ret Cont.halt v')
h₂ : Cfg.halt v' ∈ eval step (stepRet Cont.halt v')
he : ¬List.headI v' = 0
h : x ∈ eval step (stepNormal f (Cont.fix f k) (List.tail v'))
k₀ : Cont
v₀ : List ℕ
e₀ : stepNormal f Cont.halt (List.tail v') = Cfg.ret k₀ v₀
e₁ : stepNormal f (Cont.fix f k) (List.tail v') = Cfg.ret (Cont.then k₀ (Cont.fix f k)) v₀
⊢ Reaches step (stepNormal f Cont.halt (List.tail v')) (stepRet k₀ v₀)

tactic: rw [e₀]
state_before: case hab
f : Code
k : Cont
v✝ : List ℕ
fok : Code.Ok f
x c : Cfg
he✝ : x ∈ eval step c
v v' : List ℕ
IH :
  ∀ (a' : Cfg),
    step (stepRet (Cont.fix f k) v') = some a' →
      ∀ (v : List ℕ) (c' : Cfg),
        a' = Cfg.then c' (Cont.fix f k) →
          Reaches step (stepNormal f Cont.halt v) c' →
            ∃ v₁,
              v₁ ∈ Code.eval f v ∧
                ∃ 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₂)
hr : Reaches step (stepNormal f Cont.halt v) (Cfg.halt v')
h₁ : v' ∈ Code.eval f v
h₂✝ : Cfg.halt v' ∈ eval step (Cfg.ret Cont.halt v')
h₂ : Cfg.halt v' ∈ eval step (stepRet Cont.halt v')
he : ¬List.headI v' = 0
h : x ∈ eval step (stepNormal f (Cont.fix f k) (List.tail v'))
k₀ : Cont
v₀ : List ℕ
e₀ : stepNormal f Cont.halt (List.tail v') = Cfg.ret k₀ v₀
e₁ : stepNormal f (Cont.fix f k) (List.tail v') = Cfg.ret (Cont.then k₀ (Cont.fix f k)) v₀
⊢ stepRet k₀ v₀ ∈ step (stepNormal f Cont.halt (List.tail v'))

tactic: rfl
state_before: case hab
f : Code
k : Cont
v✝ : List ℕ
fok : Code.Ok f
x c : Cfg
he✝ : x ∈ eval step c
v v' : List ℕ
IH :
  ∀ (a' : Cfg),
    step (stepRet (Cont.fix f k) v') = some a' →
      ∀ (v : List ℕ) (c' : Cfg),
        a' = Cfg.then c' (Cont.fix f k) →
          Reaches step (stepNormal f Cont.halt v) c' →
            ∃ v₁,
              v₁ ∈ Code.eval f v ∧
                ∃ 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₂)
hr : Reaches step (stepNormal f Cont.halt v) (Cfg.halt v')
h₁ : v' ∈ Code.eval f v
h₂✝ : Cfg.halt v' ∈ eval step (Cfg.ret Cont.halt v')
h₂ : Cfg.halt v' ∈ eval step (stepRet Cont.halt v')
he : ¬List.headI v' = 0
h : x ∈ eval step (stepNormal f (Cont.fix f k) (List.tail v'))
k₀ : Cont
v₀ : List ℕ
e₀ : stepNormal f Cont.halt (List.tail v') = Cfg.ret k₀ v₀
e₁ : stepNormal f (Cont.fix f k) (List.tail v') = Cfg.ret (Cont.then k₀ (Cont.fix f k)) v₀
⊢ stepRet k₀ v₀ ∈ step (Cfg.ret k₀ v₀)

tactic: refine' ⟨_, PFun.mem_fix_iff.2 _, h₃⟩
state_before: case neg.intro.intro.intro.intro.intro.intro
f : Code
k : Cont
v✝ : List ℕ
fok : Code.Ok f
x c : Cfg
he✝ : x ∈ eval step c
v v' : List ℕ
IH :
  ∀ (a' : Cfg),
    step (stepRet (Cont.fix f k) v') = some a' →
      ∀ (v : List ℕ) (c' : Cfg),
        a' = Cfg.then c' (Cont.fix f k) →
          Reaches step (stepNormal f Cont.halt v) c' →
            ∃ v₁,
              v₁ ∈ Code.eval f v ∧
                ∃ 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₂)
hr : Reaches step (stepNormal f Cont.halt v) (Cfg.halt v')
h₁ : v' ∈ Code.eval f v
h₂✝ : Cfg.halt v' ∈ eval step (Cfg.ret Cont.halt v')
h₂ : Cfg.halt v' ∈ eval step (stepRet Cont.halt v')
he : ¬List.headI v' = 0
h : x ∈ eval step (stepNormal f (Cont.fix f k) (List.tail v'))
k₀ : Cont
v₀ : List ℕ
e₀ : stepNormal f Cont.halt (List.tail v') = Cfg.ret k₀ v₀
e₁ : stepNormal f (Cont.fix f k) (List.tail v') = Cfg.ret (Cont.then k₀ (Cont.fix f k)) v₀
v₁ : List ℕ
hv₁ : v₁ ∈ Code.eval f (List.tail 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₂)
⊢ ∃ v₂, v₂ ∈ Code.eval (Code.fix f) (List.tail v') ∧ x ∈ eval step (Cfg.ret k v₂)

tactic: simp only [Part.eq_some_iff.2 hv₁, Part.map_some, Part.mem_some_iff]
state_before: case neg.intro.intro.intro.intro.intro.intro
f : Code
k : Cont
v✝ : List ℕ
fok : Code.Ok f
x c : Cfg
he✝ : x ∈ eval step c
v v' : List ℕ
IH :
  ∀ (a' : Cfg),
    step (stepRet (Cont.fix f k) v') = some a' →
      ∀ (v : List ℕ) (c' : Cfg),
        a' = Cfg.then c' (Cont.fix f k) →
          Reaches step (stepNormal f Cont.halt v) c' →
            ∃ v₁,
              v₁ ∈ Code.eval f v ∧
                ∃ 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₂)
hr : Reaches step (stepNormal f Cont.halt v) (Cfg.halt v')
h₁ : v' ∈ Code.eval f v
h₂✝ : Cfg.halt v' ∈ eval step (Cfg.ret Cont.halt v')
h₂ : Cfg.halt v' ∈ eval step (stepRet Cont.halt v')
he : ¬List.headI v' = 0
h : x ∈ eval step (stepNormal f (Cont.fix f k) (List.tail v'))
k₀ : Cont
v₀ : List ℕ
e₀ : stepNormal f Cont.halt (List.tail v') = Cfg.ret k₀ v₀
e₁ : stepNormal f (Cont.fix f k) (List.tail v') = Cfg.ret (Cont.then k₀ (Cont.fix f k)) v₀
v₁ : List ℕ
hv₁ : v₁ ∈ Code.eval f (List.tail 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 (List.tail 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 (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'

tactic: split_ifs at hv₂ ⊢ <;> [exact Or.inl (congr_arg Sum.inl (Part.mem_some_iff.1 hv₂));
  exact Or.inr ⟨_, rfl, hv₂⟩]
state_before: case neg.intro.intro.intro.intro.intro.intro
f : Code
k : Cont
v✝ : List ℕ
fok : Code.Ok f
x c : Cfg
he✝ : x ∈ eval step c
v v' : List ℕ
IH :
  ∀ (a' : Cfg),
    step (stepRet (Cont.fix f k) v') = some a' →
      ∀ (v : List ℕ) (c' : Cfg),
        a' = Cfg.then c' (Cont.fix f k) →
          Reaches step (stepNormal f Cont.halt v) c' →
            ∃ v₁,
              v₁ ∈ Code.eval f v ∧
                ∃ 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₂)
hr : Reaches step (stepNormal f Cont.halt v) (Cfg.halt v')
h₁ : v' ∈ Code.eval f v
h₂✝ : Cfg.halt v' ∈ eval step (Cfg.ret Cont.halt v')
h₂ : Cfg.halt v' ∈ eval step (stepRet Cont.halt v')
he : ¬List.headI v' = 0
h : x ∈ eval step (stepNormal f (Cont.fix f k) (List.tail v'))
k₀ : Cont
v₀ : List ℕ
e₀ : stepNormal f Cont.halt (List.tail v') = Cfg.ret k₀ v₀
e₁ : stepNormal f (Cont.fix f k) (List.tail v') = Cfg.ret (Cont.then k₀ (Cont.fix f k)) v₀
v₁ : List ℕ
hv₁ : v₁ ∈ Code.eval f (List.tail 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₂ = if List.headI v₁ = 0 then Sum.inl (List.tail v₁) else Sum.inr (List.tail v₁)) ∨
    ∃ a',
      (Sum.inr a' = 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'

tactic: exact IH _ rfl _ _ stepRet_then (ReflTransGen.tail hr rfl)
state_before: case mp.ret
f : Code
k : Cont
v✝ : List ℕ
fok : Code.Ok f
x c : Cfg
he : x ∈ eval step c
v : List ℕ
k' : Cont
v' : List ℕ
h : x ∈ eval step (Cfg.ret (Cont.then k' (Cont.fix f k)) v')
IH :
  ∀ (a' : Cfg),
    step (Cfg.ret (Cont.then k' (Cont.fix f k)) v') = some a' →
      ∀ (v : List ℕ) (c' : Cfg),
        a' = Cfg.then c' (Cont.fix f k) →
          Reaches step (stepNormal f Cont.halt v) c' →
            ∃ v₁,
              v₁ ∈ Code.eval f v ∧
                ∃ 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₂)
hr : Reaches step (stepNormal f Cont.halt v) (Cfg.ret k' v')
⊢ ∃ v₁,
    v₁ ∈ Code.eval f v ∧
      ∃ 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₂)

tactic: rintro ⟨v', he, hr⟩
state_before: case mpr
f : Code
k : Cont
v : List ℕ
fok : Code.Ok f
x : Cfg
⊢ (∃ a, a ∈ Code.eval (Code.fix f) v ∧ x ∈ eval step (Cfg.ret k a)) → x ∈ eval step (stepNormal f (Cont.fix f k) v)

tactic: rw [reaches_eval] at hr
state_before: case mpr.intro.intro
f : Code
k : Cont
v : List ℕ
fok : Code.Ok f
x : Cfg
v' : List ℕ
he : v' ∈ Code.eval (Code.fix f) v
hr : x ∈ eval step (Cfg.ret k v')
⊢ x ∈ eval step (stepNormal f (Cont.fix f k) v)

tactic: swap
state_before: case mpr.intro.intro
f : Code
k : Cont
v : List ℕ
fok : Code.Ok f
x : Cfg
v' : List ℕ
he : v' ∈ Code.eval (Code.fix f) v
hr✝ : x ∈ eval step (Cfg.ret k v')
hr : x ∈ eval step ?m.193807
⊢ x ∈ eval step (stepNormal f (Cont.fix f k) v)

case mpr.intro.intro
f : Code
k : Cont
v : List ℕ
fok : Code.Ok f
x : Cfg
v' : List ℕ
he : v' ∈ Code.eval (Code.fix f) v
hr : x ∈ eval step (Cfg.ret k v')
⊢ Reaches step (Cfg.ret k v') ?m.193807

f : Code
k : Cont
v : List ℕ
fok : Code.Ok f
x : Cfg
v' : List ℕ
he : v' ∈ Code.eval (Code.fix f) v
hr : x ∈ eval step (Cfg.ret k v')
⊢ Cfg

tactic: exact ReflTransGen.single rfl
state_before: case mpr.intro.intro
f : Code
k : Cont
v : List ℕ
fok : Code.Ok f
x : Cfg
v' : List ℕ
he : v' ∈ Code.eval (Code.fix f) v
hr : x ∈ eval step (Cfg.ret k v')
⊢ Reaches step (Cfg.ret k v') ?m.193807

case mpr.intro.intro
f : Code
k : Cont
v : List ℕ
fok : Code.Ok f
x : Cfg
v' : List ℕ
he : v' ∈ Code.eval (Code.fix f) v
hr✝ : x ∈ eval step (Cfg.ret k v')
hr : x ∈ eval step ?m.193807
⊢ x ∈ eval step (stepNormal f (Cont.fix f k) v)

f : Code
k : Cont
v : List ℕ
fok : Code.Ok f
x : Cfg
v' : List ℕ
he : v' ∈ Code.eval (Code.fix f) v
hr : x ∈ eval step (Cfg.ret k v')
⊢ Cfg

tactic: refine' PFun.fixInduction he fun v (he : v' ∈ f.fix.eval v) IH => _
state_before: case mpr.intro.intro
f : Code
k : Cont
v : List ℕ
fok : Code.Ok f
x : Cfg
v' : List ℕ
he : v' ∈ Code.eval (Code.fix f) v
hr✝ : x ∈ eval step (Cfg.ret k v')
hr : x ∈ eval step (stepRet k v')
⊢ x ∈ eval step (stepNormal f (Cont.fix f k) v)

tactic: rw [fok, Part.bind_eq_bind, Part.mem_bind_iff]
state_before: case mpr.intro.intro
f : Code
k : Cont
v✝ : List ℕ
fok : Code.Ok f
x : Cfg
v' : List ℕ
he✝ : v' ∈ Code.eval (Code.fix f) v✝
hr✝ : x ∈ eval step (Cfg.ret k v')
hr : x ∈ eval step (stepRet k v')
v : List ℕ
he : v' ∈ Code.eval (Code.fix f) v
IH :
  ∀ (a'' : List ℕ),
    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) →
      x ∈ eval step (stepNormal f (Cont.fix f k) a'')
⊢ x ∈ eval step (stepNormal f (Cont.fix f k) v)

tactic: obtain he | ⟨v'', he₁', _⟩ := PFun.mem_fix_iff.1 he
state_before: case mpr.intro.intro
f : Code
k : Cont
v✝ : List ℕ
fok : Code.Ok f
x : Cfg
v' : List ℕ
he✝ : v' ∈ Code.eval (Code.fix f) v✝
hr✝ : x ∈ eval step (Cfg.ret k v')
hr : x ∈ eval step (stepRet k v')
v : List ℕ
he : v' ∈ Code.eval (Code.fix f) v
IH :
  ∀ (a'' : List ℕ),
    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) →
      x ∈ eval step (stepNormal f (Cont.fix f k) a'')
⊢ ∃ a, a ∈ Code.eval f v ∧ x ∈ eval step (Cfg.ret (Cont.fix f k) a)

tactic: obtain ⟨v', he₁, he₂⟩ := (Part.mem_map_iff _).1 he
state_before: case mpr.intro.intro.inl
f : Code
k : Cont
v✝ : List ℕ
fok : Code.Ok f
x : Cfg
v' : List ℕ
he✝¹ : v' ∈ Code.eval (Code.fix f) v✝
hr✝ : x ∈ eval step (Cfg.ret k v')
hr : x ∈ eval step (stepRet k v')
v : List ℕ
he✝ : v' ∈ Code.eval (Code.fix f) v
IH :
  ∀ (a'' : List ℕ),
    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) →
      x ∈ eval step (stepNormal f (Cont.fix f k) a'')
he :
  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, a ∈ Code.eval f v ∧ x ∈ eval step (Cfg.ret (Cont.fix f k) a)

tactic: split_ifs at he₂ with h
state_before: case mpr.intro.intro.inl.intro.intro
f : Code
k : Cont
v✝ : List ℕ
fok : Code.Ok f
x : Cfg
v'✝ : List ℕ
he✝¹ : v'✝ ∈ Code.eval (Code.fix f) v✝
hr✝ : x ∈ eval step (Cfg.ret k v'✝)
hr : x ∈ eval step (stepRet k v'✝)
v : List ℕ
he✝ : v'✝ ∈ Code.eval (Code.fix f) v
IH :
  ∀ (a'' : List ℕ),
    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) →
      x ∈ eval step (stepNormal f (Cont.fix f k) a'')
he :
  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)
v' : List ℕ
he₁ : v' ∈ Code.eval f v
he₂ : (if List.headI v' = 0 then Sum.inl (List.tail v') else Sum.inr (List.tail v')) = Sum.inl v'✝
⊢ ∃ a, a ∈ Code.eval f v ∧ x ∈ eval step (Cfg.ret (Cont.fix f k) a)

tactic: cases he₂
state_before: case mpr.intro.intro.inl.intro.intro.inl
f : Code
k : Cont
v✝ : List ℕ
fok : Code.Ok f
x : Cfg
v'✝ : List ℕ
he✝¹ : v'✝ ∈ Code.eval (Code.fix f) v✝
hr✝ : x ∈ eval step (Cfg.ret k v'✝)
hr : x ∈ eval step (stepRet k v'✝)
v : List ℕ
he✝ : v'✝ ∈ Code.eval (Code.fix f) v
IH :
  ∀ (a'' : List ℕ),
    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) →
      x ∈ eval step (stepNormal f (Cont.fix f k) a'')
he :
  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)
v' : List ℕ
he₁ : v' ∈ Code.eval f v
h : List.headI v' = 0
he₂ : Sum.inl (List.tail v') = Sum.inl v'✝
⊢ ∃ a, a ∈ Code.eval f v ∧ x ∈ eval step (Cfg.ret (Cont.fix f k) a)

tactic: refine' ⟨_, he₁, _⟩
state_before: case mpr.intro.intro.inl.intro.intro.inl.refl
f : Code
k : Cont
v✝ : List ℕ
fok : Code.Ok f
x : Cfg
v : List ℕ
IH :
  ∀ (a'' : List ℕ),
    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) →
      x ∈ eval step (stepNormal f (Cont.fix f k) a'')
v' : List ℕ
he₁ : v' ∈ Code.eval f v
h : List.headI v' = 0
he✝¹ : List.tail v' ∈ Code.eval (Code.fix f) v✝
hr✝ : x ∈ eval step (Cfg.ret k (List.tail v'))
hr : x ∈ eval step (stepRet k (List.tail v'))
he✝ : List.tail v' ∈ Code.eval (Code.fix f) v
he :
  Sum.inl (List.tail 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, a ∈ Code.eval f v ∧ x ∈ eval step (Cfg.ret (Cont.fix f k) a)

tactic: rw [reaches_eval]
state_before: case mpr.intro.intro.inl.intro.intro.inl.refl
f : Code
k : Cont
v✝ : List ℕ
fok : Code.Ok f
x : Cfg
v : List ℕ
IH :
  ∀ (a'' : List ℕ),
    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) →
      x ∈ eval step (stepNormal f (Cont.fix f k) a'')
v' : List ℕ
he₁ : v' ∈ Code.eval f v
h : List.headI v' = 0
he✝¹ : List.tail v' ∈ Code.eval (Code.fix f) v✝
hr✝ : x ∈ eval step (Cfg.ret k (List.tail v'))
hr : x ∈ eval step (stepRet k (List.tail v'))
he✝ : List.tail v' ∈ Code.eval (Code.fix f) v
he :
  Sum.inl (List.tail 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)
⊢ x ∈ eval step (Cfg.ret (Cont.fix f k) v')

tactic: swap
state_before: case mpr.intro.intro.inl.intro.intro.inl.refl
f : Code
k : Cont
v✝ : List ℕ
fok : Code.Ok f
x : Cfg
v : List ℕ
IH :
  ∀ (a'' : List ℕ),
    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) →
      x ∈ eval step (stepNormal f (Cont.fix f k) a'')
v' : List ℕ
he₁ : v' ∈ Code.eval f v
h : List.headI v' = 0
he✝¹ : List.tail v' ∈ Code.eval (Code.fix f) v✝
hr✝ : x ∈ eval step (Cfg.ret k (List.tail v'))
hr : x ∈ eval step (stepRet k (List.tail v'))
he✝ : List.tail v' ∈ Code.eval (Code.fix f) v
he :
  Sum.inl (List.tail 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)
⊢ x ∈ eval step ?m.194630

case mpr.intro.intro.inl.intro.intro.inl.refl
f : Code
k : Cont
v✝ : List ℕ
fok : Code.Ok f
x : Cfg
v : List ℕ
IH :
  ∀ (a'' : List ℕ),
    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) →
      x ∈ eval step (stepNormal f (Cont.fix f k) a'')
v' : List ℕ
he₁ : v' ∈ Code.eval f v
h : List.headI v' = 0
he✝¹ : List.tail v' ∈ Code.eval (Code.fix f) v✝
hr✝ : x ∈ eval step (Cfg.ret k (List.tail v'))
hr : x ∈ eval step (stepRet k (List.tail v'))
he✝ : List.tail v' ∈ Code.eval (Code.fix f) v
he :
  Sum.inl (List.tail 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)
⊢ Reaches step (Cfg.ret (Cont.fix f k) v') ?m.194630

f : Code
k : Cont
v✝ : List ℕ
fok : Code.Ok f
x : Cfg
v : List ℕ
IH :
  ∀ (a'' : List ℕ),
    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) →
      x ∈ eval step (stepNormal f (Cont.fix f k) a'')
v' : List ℕ
he₁ : v' ∈ Code.eval f v
h : List.headI v' = 0
he✝¹ : List.tail v' ∈ Code.eval (Code.fix f) v✝
hr✝ : x ∈ eval step (Cfg.ret k (List.tail v'))
hr : x ∈ eval step (stepRet k (List.tail v'))
he✝ : List.tail v' ∈ Code.eval (Code.fix f) v
he :
  Sum.inl (List.tail 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)
⊢ Cfg

tactic: exact ReflTransGen.single rfl
state_before: case mpr.intro.intro.inl.intro.intro.inl.refl
f : Code
k : Cont
v✝ : List ℕ
fok : Code.Ok f
x : Cfg
v : List ℕ
IH :
  ∀ (a'' : List ℕ),
    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) →
      x ∈ eval step (stepNormal f (Cont.fix f k) a'')
v' : List ℕ
he₁ : v' ∈ Code.eval f v
h : List.headI v' = 0
he✝¹ : List.tail v' ∈ Code.eval (Code.fix f) v✝
hr✝ : x ∈ eval step (Cfg.ret k (List.tail v'))
hr : x ∈ eval step (stepRet k (List.tail v'))
he✝ : List.tail v' ∈ Code.eval (Code.fix f) v
he :
  Sum.inl (List.tail 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)
⊢ Reaches step (Cfg.ret (Cont.fix f k) v') ?m.194630

case mpr.intro.intro.inl.intro.intro.inl.refl
f : Code
k : Cont
v✝ : List ℕ
fok : Code.Ok f
x : Cfg
v : List ℕ
IH :
  ∀ (a'' : List ℕ),
    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) →
      x ∈ eval step (stepNormal f (Cont.fix f k) a'')
v' : List ℕ
he₁ : v' ∈ Code.eval f v
h : List.headI v' = 0
he✝¹ : List.tail v' ∈ Code.eval (Code.fix f) v✝
hr✝ : x ∈ eval step (Cfg.ret k (List.tail v'))
hr : x ∈ eval step (stepRet k (List.tail v'))
he✝ : List.tail v' ∈ Code.eval (Code.fix f) v
he :
  Sum.inl (List.tail 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)
⊢ x ∈ eval step ?m.194630

f : Code
k : Cont
v✝ : List ℕ
fok : Code.Ok f
x : Cfg
v : List ℕ
IH :
  ∀ (a'' : List ℕ),
    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) →
      x ∈ eval step (stepNormal f (Cont.fix f k) a'')
v' : List ℕ
he₁ : v' ∈ Code.eval f v
h : List.headI v' = 0
he✝¹ : List.tail v' ∈ Code.eval (Code.fix f) v✝
hr✝ : x ∈ eval step (Cfg.ret k (List.tail v'))
hr : x ∈ eval step (stepRet k (List.tail v'))
he✝ : List.tail v' ∈ Code.eval (Code.fix f) v
he :
  Sum.inl (List.tail 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)
⊢ Cfg

tactic: rwa [stepRet, if_pos h]
state_before: case mpr.intro.intro.inl.intro.intro.inl.refl
f : Code
k : Cont
v✝ : List ℕ
fok : Code.Ok f
x : Cfg
v : List ℕ
IH :
  ∀ (a'' : List ℕ),
    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) →
      x ∈ eval step (stepNormal f (Cont.fix f k) a'')
v' : List ℕ
he₁ : v' ∈ Code.eval f v
h : List.headI v' = 0
he✝¹ : List.tail v' ∈ Code.eval (Code.fix f) v✝
hr✝ : x ∈ eval step (Cfg.ret k (List.tail v'))
hr : x ∈ eval step (stepRet k (List.tail v'))
he✝ : List.tail v' ∈ Code.eval (Code.fix f) v
he :
  Sum.inl (List.tail 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)
⊢ x ∈ eval step (stepRet (Cont.fix f k) v')

tactic: obtain ⟨v₁, he₁, he₂⟩ := (Part.mem_map_iff _).1 he₁'
state_before: case mpr.intro.intro.inr.intro.intro
f : Code
k : Cont
v✝ : List ℕ
fok : Code.Ok f
x : Cfg
v' : List ℕ
he✝ : v' ∈ Code.eval (Code.fix f) v✝
hr✝ : x ∈ eval step (Cfg.ret k v')
hr : x ∈ eval step (stepRet k v')
v : List ℕ
he : v' ∈ Code.eval (Code.fix f) v
IH :
  ∀ (a'' : List ℕ),
    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) →
      x ∈ eval step (stepNormal f (Cont.fix f k) a'')
v'' : List ℕ
he₁' :
  Sum.inr 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)
right✝ :
  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))
      v''
⊢ ∃ a, a ∈ Code.eval f v ∧ x ∈ eval step (Cfg.ret (Cont.fix f k) a)

tactic: split_ifs at he₂ with h
state_before: case mpr.intro.intro.inr.intro.intro.intro.intro
f : Code
k : Cont
v✝ : List ℕ
fok : Code.Ok f
x : Cfg
v' : List ℕ
he✝ : v' ∈ Code.eval (Code.fix f) v✝
hr✝ : x ∈ eval step (Cfg.ret k v')
hr : x ∈ eval step (stepRet k v')
v : List ℕ
he : v' ∈ Code.eval (Code.fix f) v
IH :
  ∀ (a'' : List ℕ),
    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) →
      x ∈ eval step (stepNormal f (Cont.fix f k) a'')
v'' : List ℕ
he₁' :
  Sum.inr 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)
right✝ :
  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))
      v''
v₁ : List ℕ
he₁ : v₁ ∈ Code.eval f v
he₂ : (if List.headI v₁ = 0 then Sum.inl (List.tail v₁) else Sum.inr (List.tail v₁)) = Sum.inr v''
⊢ ∃ a, a ∈ Code.eval f v ∧ x ∈ eval step (Cfg.ret (Cont.fix f k) a)

tactic: cases he₂
state_before: case mpr.intro.intro.inr.intro.intro.intro.intro.inr
f : Code
k : Cont
v✝ : List ℕ
fok : Code.Ok f
x : Cfg
v' : List ℕ
he✝ : v' ∈ Code.eval (Code.fix f) v✝
hr✝ : x ∈ eval step (Cfg.ret k v')
hr : x ∈ eval step (stepRet k v')
v : List ℕ
he : v' ∈ Code.eval (Code.fix f) v
IH :
  ∀ (a'' : List ℕ),
    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) →
      x ∈ eval step (stepNormal f (Cont.fix f k) a'')
v'' : List ℕ
he₁' :
  Sum.inr 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)
right✝ :
  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))
      v''
v₁ : List ℕ
he₁ : v₁ ∈ Code.eval f v
h : ¬List.headI v₁ = 0
he₂ : Sum.inr (List.tail v₁) = Sum.inr v''
⊢ ∃ a, a ∈ Code.eval f v ∧ x ∈ eval step (Cfg.ret (Cont.fix f k) a)

tactic: clear he₁'
state_before: case mpr.intro.intro.inr.intro.intro.intro.intro.inr.refl
f : Code
k : Cont
v✝ : List ℕ
fok : Code.Ok f
x : Cfg
v' : List ℕ
he✝ : v' ∈ Code.eval (Code.fix f) v✝
hr✝ : x ∈ eval step (Cfg.ret k v')
hr : x ∈ eval step (stepRet k v')
v : List ℕ
he : v' ∈ Code.eval (Code.fix f) v
IH :
  ∀ (a'' : List ℕ),
    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) →
      x ∈ eval step (stepNormal f (Cont.fix f k) a'')
v₁ : List ℕ
he₁ : v₁ ∈ Code.eval f v
h : ¬List.headI v₁ = 0
he₁' :
  Sum.inr (List.tail 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)
right✝ :
  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))
      (List.tail v₁)
⊢ ∃ a, a ∈ Code.eval f v ∧ x ∈ eval step (Cfg.ret (Cont.fix f k) a)

tactic: refine' ⟨_, he₁, _⟩
state_before: case mpr.intro.intro.inr.intro.intro.intro.intro.inr.refl
f : Code
k : Cont
v✝ : List ℕ
fok : Code.Ok f
x : Cfg
v' : List ℕ
he✝ : v' ∈ Code.eval (Code.fix f) v✝
hr✝ : x ∈ eval step (Cfg.ret k v')
hr : x ∈ eval step (stepRet k v')
v : List ℕ
he : v' ∈ Code.eval (Code.fix f) v
IH :
  ∀ (a'' : List ℕ),
    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) →
      x ∈ eval step (stepNormal f (Cont.fix f k) a'')
v₁ : List ℕ
he₁ : v₁ ∈ Code.eval f v
h : ¬List.headI v₁ = 0
right✝ :
  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))
      (List.tail v₁)
⊢ ∃ a, a ∈ Code.eval f v ∧ x ∈ eval step (Cfg.ret (Cont.fix f k) a)

tactic: rw [reaches_eval]
state_before: case mpr.intro.intro.inr.intro.intro.intro.intro.inr.refl
f : Code
k : Cont
v✝ : List ℕ
fok : Code.Ok f
x : Cfg
v' : List ℕ
he✝ : v' ∈ Code.eval (Code.fix f) v✝
hr✝ : x ∈ eval step (Cfg.ret k v')
hr : x ∈ eval step (stepRet k v')
v : List ℕ
he : v' ∈ Code.eval (Code.fix f) v
IH :
  ∀ (a'' : List ℕ),
    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) →
      x ∈ eval step (stepNormal f (Cont.fix f k) a'')
v₁ : List ℕ
he₁ : v₁ ∈ Code.eval f v
h : ¬List.headI v₁ = 0
right✝ :
  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))
      (List.tail v₁)
⊢ x ∈ eval step (Cfg.ret (Cont.fix f k) v₁)

tactic: swap
state_before: case mpr.intro.intro.inr.intro.intro.intro.intro.inr.refl
f : Code
k : Cont
v✝ : List ℕ
fok : Code.Ok f
x : Cfg
v' : List ℕ
he✝ : v' ∈ Code.eval (Code.fix f) v✝
hr✝ : x ∈ eval step (Cfg.ret k v')
hr : x ∈ eval step (stepRet k v')
v : List ℕ
he : v' ∈ Code.eval (Code.fix f) v
IH :
  ∀ (a'' : List ℕ),
    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) →
      x ∈ eval step (stepNormal f (Cont.fix f k) a'')
v₁ : List ℕ
he₁ : v₁ ∈ Code.eval f v
h : ¬List.headI v₁ = 0
right✝ :
  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))
      (List.tail v₁)
⊢ x ∈ eval step ?m.195183

case mpr.intro.intro.inr.intro.intro.intro.intro.inr.refl
f : Code
k : Cont
v✝ : List ℕ
fok : Code.Ok f
x : Cfg
v' : List ℕ
he✝ : v' ∈ Code.eval (Code.fix f) v✝
hr✝ : x ∈ eval step (Cfg.ret k v')
hr : x ∈ eval step (stepRet k v')
v : List ℕ
he : v' ∈ Code.eval (Code.fix f) v
IH :
  ∀ (a'' : List ℕ),
    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) →
      x ∈ eval step (stepNormal f (Cont.fix f k) a'')
v₁ : List ℕ
he₁ : v₁ ∈ Code.eval f v
h : ¬List.headI v₁ = 0
right✝ :
  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))
      (List.tail v₁)
⊢ Reaches step (Cfg.ret (Cont.fix f k) v₁) ?m.195183

f : Code
k : Cont
v✝ : List ℕ
fok : Code.Ok f
x : Cfg
v' : List ℕ
he✝ : v' ∈ Code.eval (Code.fix f) v✝
hr✝ : x ∈ eval step (Cfg.ret k v')
hr : x ∈ eval step (stepRet k v')
v : List ℕ
he : v' ∈ Code.eval (Code.fix f) v
IH :
  ∀ (a'' : List ℕ),
    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) →
      x ∈ eval step (stepNormal f (Cont.fix f k) a'')
v₁ : List ℕ
he₁ : v₁ ∈ Code.eval f v
h : ¬List.headI v₁ = 0
right✝ :
  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))
      (List.tail v₁)
⊢ Cfg

tactic: exact ReflTransGen.single rfl
state_before: case mpr.intro.intro.inr.intro.intro.intro.intro.inr.refl
f : Code
k : Cont
v✝ : List ℕ
fok : Code.Ok f
x : Cfg
v' : List ℕ
he✝ : v' ∈ Code.eval (Code.fix f) v✝
hr✝ : x ∈ eval step (Cfg.ret k v')
hr : x ∈ eval step (stepRet k v')
v : List ℕ
he : v' ∈ Code.eval (Code.fix f) v
IH :
  ∀ (a'' : List ℕ),
    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) →
      x ∈ eval step (stepNormal f (Cont.fix f k) a'')
v₁ : List ℕ
he₁ : v₁ ∈ Code.eval f v
h : ¬List.headI v₁ = 0
right✝ :
  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))
      (List.tail v₁)
⊢ Reaches step (Cfg.ret (Cont.fix f k) v₁) ?m.195183

case mpr.intro.intro.inr.intro.intro.intro.intro.inr.refl
f : Code
k : Cont
v✝ : List ℕ
fok : Code.Ok f
x : Cfg
v' : List ℕ
he✝ : v' ∈ Code.eval (Code.fix f) v✝
hr✝ : x ∈ eval step (Cfg.ret k v')
hr : x ∈ eval step (stepRet k v')
v : List ℕ
he : v' ∈ Code.eval (Code.fix f) v
IH :
  ∀ (a'' : List ℕ),
    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) →
      x ∈ eval step (stepNormal f (Cont.fix f k) a'')
v₁ : List ℕ
he₁ : v₁ ∈ Code.eval f v
h : ¬List.headI v₁ = 0
right✝ :
  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))
      (List.tail v₁)
⊢ x ∈ eval step ?m.195183

f : Code
k : Cont
v✝ : List ℕ
fok : Code.Ok f
x : Cfg
v' : List ℕ
he✝ : v' ∈ Code.eval (Code.fix f) v✝
hr✝ : x ∈ eval step (Cfg.ret k v')
hr : x ∈ eval step (stepRet k v')
v : List ℕ
he : v' ∈ Code.eval (Code.fix f) v
IH :
  ∀ (a'' : List ℕ),
    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) →
      x ∈ eval step (stepNormal f (Cont.fix f k) a'')
v₁ : List ℕ
he₁ : v₁ ∈ Code.eval f v
h : ¬List.headI v₁ = 0
right✝ :
  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))
      (List.tail v₁)
⊢ Cfg

tactic: rw [stepRet, if_neg h]
state_before: case mpr.intro.intro.inr.intro.intro.intro.intro.inr.refl
f : Code
k : Cont
v✝ : List ℕ
fok : Code.Ok f
x : Cfg
v' : List ℕ
he✝ : v' ∈ Code.eval (Code.fix f) v✝
hr✝ : x ∈ eval step (Cfg.ret k v')
hr : x ∈ eval step (stepRet k v')
v : List ℕ
he : v' ∈ Code.eval (Code.fix f) v
IH :
  ∀ (a'' : List ℕ),
    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) →
      x ∈ eval step (stepNormal f (Cont.fix f k) a'')
v₁ : List ℕ
he₁ : v₁ ∈ Code.eval f v
h : ¬List.headI v₁ = 0
right✝ :
  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))
      (List.tail v₁)
⊢ x ∈ eval step (stepRet (Cont.fix f k) v₁)

tactic: exact IH v₁.tail ((Part.mem_map_iff _).2 ⟨_, he₁, if_neg h⟩)
state_before: case mpr.intro.intro.inr.intro.intro.intro.intro.inr.refl
f : Code
k : Cont
v✝ : List ℕ
fok : Code.Ok f
x : Cfg
v' : List ℕ
he✝ : v' ∈ Code.eval (Code.fix f) v✝
hr✝ : x ∈ eval step (Cfg.ret k v')
hr : x ∈ eval step (stepRet k v')
v : List ℕ
he : v' ∈ Code.eval (Code.fix f) v
IH :
  ∀ (a'' : List ℕ),
    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) →
      x ∈ eval step (stepNormal f (Cont.fix f k) a'')
v₁ : List ℕ
he₁ : v₁ ∈ Code.eval f v
h : ¬List.headI v₁ = 0
right✝ :
  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))
      (List.tail v₁)
⊢ x ∈ eval step (stepNormal f (Cont.fix f k) (List.tail v₁))