Theorem: Turing.ToPartrec.Code.exists_code
File: Mathlib/Computability/TMToPartrec.lean

tactic: induction' hf with n f hf
state_before: n : ℕ
f : Vector ℕ n →. ℕ
hf : Nat.Partrec' f
⊢ ∃ c, ∀ (v : Vector ℕ n), eval c ↑v = pure <$> f v

tactic: induction hf
state_before: case prim
n✝ : ℕ
f✝ : Vector ℕ n✝ →. ℕ
n : ℕ
f : Vector ℕ n → ℕ
hf : Nat.Primrec' f
⊢ ∃ c, ∀ (v : Vector ℕ n), eval c ↑v = pure <$> ↑f v

case comp
n : ℕ
f : Vector ℕ n →. ℕ
m✝ n✝ : ℕ
f✝ : Vector ℕ n✝ →. ℕ
g✝ : Fin n✝ → Vector ℕ m✝ →. ℕ
a✝¹ : Nat.Partrec' f✝
a✝ : ∀ (i : Fin n✝), Nat.Partrec' (g✝ i)
a_ih✝¹ : ∃ c, ∀ (v : Vector ℕ n✝), eval c ↑v = pure <$> f✝ v
a_ih✝ : ∀ (i : Fin n✝), ∃ c, ∀ (v : Vector ℕ m✝), eval c ↑v = pure <$> g✝ i v
⊢ ∃ c, ∀ (v : Vector ℕ m✝), eval c ↑v = pure <$> (fun v => (Vector.mOfFn fun i => g✝ i v) >>= f✝) v

case rfind
n : ℕ
f : Vector ℕ n →. ℕ
n✝ : ℕ
f✝ : Vector ℕ (n✝ + 1) → ℕ
a✝ : Nat.Partrec' ↑f✝
a_ih✝ : ∃ c, ∀ (v : Vector ℕ (n✝ + 1)), eval c ↑v = pure <$> ↑f✝ v
⊢ ∃ c, ∀ (v : Vector ℕ n✝), eval c ↑v = pure <$> (fun v => Nat.rfind fun n => Part.some (decide (f✝ (n ::ᵥ v) = 0))) v

tactic: case prim.zero => exact ⟨zero', fun ⟨[], _⟩ => rfl⟩
state_before: case prim.zero
n✝ : ℕ
f✝ : Vector ℕ n✝ →. ℕ
n : ℕ
f : Vector ℕ n → ℕ
⊢ ∃ c, ∀ (v : Vector ℕ 0), eval c ↑v = pure <$> (↑fun x => 0) v

case prim.succ
n✝ : ℕ
f✝ : Vector ℕ n✝ →. ℕ
n : ℕ
f : Vector ℕ n → ℕ
⊢ ∃ c, ∀ (v : Vector ℕ 1), eval c ↑v = pure <$> (↑fun v => Nat.succ (Vector.head v)) v

case prim.get
n✝¹ : ℕ
f✝ : Vector ℕ n✝¹ →. ℕ
n : ℕ
f : Vector ℕ n → ℕ
n✝ : ℕ
i✝ : Fin n✝
⊢ ∃ c, ∀ (v : Vector ℕ n✝), eval c ↑v = pure <$> (↑fun v => Vector.get v i✝) v

case prim.comp
n✝¹ : ℕ
f✝¹ : Vector ℕ n✝¹ →. ℕ
n : ℕ
f : Vector ℕ n → ℕ
m✝ n✝ : ℕ
f✝ : Vector ℕ n✝ → ℕ
g✝ : Fin n✝ → Vector ℕ m✝ → ℕ
a✝¹ : Nat.Primrec' f✝
a✝ : ∀ (i : Fin n✝), Nat.Primrec' (g✝ i)
a_ih✝¹ : ∃ c, ∀ (v : Vector ℕ n✝), eval c ↑v = pure <$> ↑f✝ v
a_ih✝ : ∀ (i : Fin n✝), ∃ c, ∀ (v : Vector ℕ m✝), eval c ↑v = pure <$> ↑(g✝ i) v
⊢ ∃ c, ∀ (v : Vector ℕ m✝), eval c ↑v = pure <$> (↑fun a => f✝ (Vector.ofFn fun i => g✝ i a)) v

case prim.prec
n✝¹ : ℕ
f✝¹ : Vector ℕ n✝¹ →. ℕ
n : ℕ
f : Vector ℕ n → ℕ
n✝ : ℕ
f✝ : Vector ℕ n✝ → ℕ
g✝ : Vector ℕ (n✝ + 2) → ℕ
a✝¹ : Nat.Primrec' f✝
a✝ : Nat.Primrec' g✝
a_ih✝¹ : ∃ c, ∀ (v : Vector ℕ n✝), eval c ↑v = pure <$> ↑f✝ v
a_ih✝ : ∃ c, ∀ (v : Vector ℕ (n✝ + 2)), eval c ↑v = pure <$> ↑g✝ v
⊢ ∃ c,
    ∀ (v : Vector ℕ (n✝ + 1)),
      eval c ↑v =
        pure <$>
          (↑fun v => Nat.rec (f✝ (Vector.tail v)) (fun y IH => g✝ (y ::ᵥ IH ::ᵥ Vector.tail v)) (Vector.head v)) v

case comp
n : ℕ
f : Vector ℕ n →. ℕ
m✝ n✝ : ℕ
f✝ : Vector ℕ n✝ →. ℕ
g✝ : Fin n✝ → Vector ℕ m✝ →. ℕ
a✝¹ : Nat.Partrec' f✝
a✝ : ∀ (i : Fin n✝), Nat.Partrec' (g✝ i)
a_ih✝¹ : ∃ c, ∀ (v : Vector ℕ n✝), eval c ↑v = pure <$> f✝ v
a_ih✝ : ∀ (i : Fin n✝), ∃ c, ∀ (v : Vector ℕ m✝), eval c ↑v = pure <$> g✝ i v
⊢ ∃ c, ∀ (v : Vector ℕ m✝), eval c ↑v = pure <$> (fun v => (Vector.mOfFn fun i => g✝ i v) >>= f✝) v

case rfind
n : ℕ
f : Vector ℕ n →. ℕ
n✝ : ℕ
f✝ : Vector ℕ (n✝ + 1) → ℕ
a✝ : Nat.Partrec' ↑f✝
a_ih✝ : ∃ c, ∀ (v : Vector ℕ (n✝ + 1)), eval c ↑v = pure <$> ↑f✝ v
⊢ ∃ c, ∀ (v : Vector ℕ n✝), eval c ↑v = pure <$> (fun v => Nat.rfind fun n => Part.some (decide (f✝ (n ::ᵥ v) = 0))) v

tactic: case prim.succ => exact ⟨succ, fun ⟨[v], _⟩ => rfl⟩
state_before: case prim.succ
n✝ : ℕ
f✝ : Vector ℕ n✝ →. ℕ
n : ℕ
f : Vector ℕ n → ℕ
⊢ ∃ c, ∀ (v : Vector ℕ 1), eval c ↑v = pure <$> (↑fun v => Nat.succ (Vector.head v)) v

case prim.get
n✝¹ : ℕ
f✝ : Vector ℕ n✝¹ →. ℕ
n : ℕ
f : Vector ℕ n → ℕ
n✝ : ℕ
i✝ : Fin n✝
⊢ ∃ c, ∀ (v : Vector ℕ n✝), eval c ↑v = pure <$> (↑fun v => Vector.get v i✝) v

case prim.comp
n✝¹ : ℕ
f✝¹ : Vector ℕ n✝¹ →. ℕ
n : ℕ
f : Vector ℕ n → ℕ
m✝ n✝ : ℕ
f✝ : Vector ℕ n✝ → ℕ
g✝ : Fin n✝ → Vector ℕ m✝ → ℕ
a✝¹ : Nat.Primrec' f✝
a✝ : ∀ (i : Fin n✝), Nat.Primrec' (g✝ i)
a_ih✝¹ : ∃ c, ∀ (v : Vector ℕ n✝), eval c ↑v = pure <$> ↑f✝ v
a_ih✝ : ∀ (i : Fin n✝), ∃ c, ∀ (v : Vector ℕ m✝), eval c ↑v = pure <$> ↑(g✝ i) v
⊢ ∃ c, ∀ (v : Vector ℕ m✝), eval c ↑v = pure <$> (↑fun a => f✝ (Vector.ofFn fun i => g✝ i a)) v

case prim.prec
n✝¹ : ℕ
f✝¹ : Vector ℕ n✝¹ →. ℕ
n : ℕ
f : Vector ℕ n → ℕ
n✝ : ℕ
f✝ : Vector ℕ n✝ → ℕ
g✝ : Vector ℕ (n✝ + 2) → ℕ
a✝¹ : Nat.Primrec' f✝
a✝ : Nat.Primrec' g✝
a_ih✝¹ : ∃ c, ∀ (v : Vector ℕ n✝), eval c ↑v = pure <$> ↑f✝ v
a_ih✝ : ∃ c, ∀ (v : Vector ℕ (n✝ + 2)), eval c ↑v = pure <$> ↑g✝ v
⊢ ∃ c,
    ∀ (v : Vector ℕ (n✝ + 1)),
      eval c ↑v =
        pure <$>
          (↑fun v => Nat.rec (f✝ (Vector.tail v)) (fun y IH => g✝ (y ::ᵥ IH ::ᵥ Vector.tail v)) (Vector.head v)) v

case comp
n : ℕ
f : Vector ℕ n →. ℕ
m✝ n✝ : ℕ
f✝ : Vector ℕ n✝ →. ℕ
g✝ : Fin n✝ → Vector ℕ m✝ →. ℕ
a✝¹ : Nat.Partrec' f✝
a✝ : ∀ (i : Fin n✝), Nat.Partrec' (g✝ i)
a_ih✝¹ : ∃ c, ∀ (v : Vector ℕ n✝), eval c ↑v = pure <$> f✝ v
a_ih✝ : ∀ (i : Fin n✝), ∃ c, ∀ (v : Vector ℕ m✝), eval c ↑v = pure <$> g✝ i v
⊢ ∃ c, ∀ (v : Vector ℕ m✝), eval c ↑v = pure <$> (fun v => (Vector.mOfFn fun i => g✝ i v) >>= f✝) v

case rfind
n : ℕ
f : Vector ℕ n →. ℕ
n✝ : ℕ
f✝ : Vector ℕ (n✝ + 1) → ℕ
a✝ : Nat.Partrec' ↑f✝
a_ih✝ : ∃ c, ∀ (v : Vector ℕ (n✝ + 1)), eval c ↑v = pure <$> ↑f✝ v
⊢ ∃ c, ∀ (v : Vector ℕ n✝), eval c ↑v = pure <$> (fun v => Nat.rfind fun n => Part.some (decide (f✝ (n ::ᵥ v) = 0))) v

tactic: case prim.comp m n f g hf hg IHf IHg =>
  simpa [Part.bind_eq_bind] using exists_code.comp IHf IHg
state_before: case prim.comp
n✝¹ : ℕ
f✝¹ : Vector ℕ n✝¹ →. ℕ
n : ℕ
f : Vector ℕ n → ℕ
m✝ n✝ : ℕ
f✝ : Vector ℕ n✝ → ℕ
g✝ : Fin n✝ → Vector ℕ m✝ → ℕ
a✝¹ : Nat.Primrec' f✝
a✝ : ∀ (i : Fin n✝), Nat.Primrec' (g✝ i)
a_ih✝¹ : ∃ c, ∀ (v : Vector ℕ n✝), eval c ↑v = pure <$> ↑f✝ v
a_ih✝ : ∀ (i : Fin n✝), ∃ c, ∀ (v : Vector ℕ m✝), eval c ↑v = pure <$> ↑(g✝ i) v
⊢ ∃ c, ∀ (v : Vector ℕ m✝), eval c ↑v = pure <$> (↑fun a => f✝ (Vector.ofFn fun i => g✝ i a)) v

case prim.prec
n✝¹ : ℕ
f✝¹ : Vector ℕ n✝¹ →. ℕ
n : ℕ
f : Vector ℕ n → ℕ
n✝ : ℕ
f✝ : Vector ℕ n✝ → ℕ
g✝ : Vector ℕ (n✝ + 2) → ℕ
a✝¹ : Nat.Primrec' f✝
a✝ : Nat.Primrec' g✝
a_ih✝¹ : ∃ c, ∀ (v : Vector ℕ n✝), eval c ↑v = pure <$> ↑f✝ v
a_ih✝ : ∃ c, ∀ (v : Vector ℕ (n✝ + 2)), eval c ↑v = pure <$> ↑g✝ v
⊢ ∃ c,
    ∀ (v : Vector ℕ (n✝ + 1)),
      eval c ↑v =
        pure <$>
          (↑fun v => Nat.rec (f✝ (Vector.tail v)) (fun y IH => g✝ (y ::ᵥ IH ::ᵥ Vector.tail v)) (Vector.head v)) v

case comp
n : ℕ
f : Vector ℕ n →. ℕ
m✝ n✝ : ℕ
f✝ : Vector ℕ n✝ →. ℕ
g✝ : Fin n✝ → Vector ℕ m✝ →. ℕ
a✝¹ : Nat.Partrec' f✝
a✝ : ∀ (i : Fin n✝), Nat.Partrec' (g✝ i)
a_ih✝¹ : ∃ c, ∀ (v : Vector ℕ n✝), eval c ↑v = pure <$> f✝ v
a_ih✝ : ∀ (i : Fin n✝), ∃ c, ∀ (v : Vector ℕ m✝), eval c ↑v = pure <$> g✝ i v
⊢ ∃ c, ∀ (v : Vector ℕ m✝), eval c ↑v = pure <$> (fun v => (Vector.mOfFn fun i => g✝ i v) >>= f✝) v

case rfind
n : ℕ
f : Vector ℕ n →. ℕ
n✝ : ℕ
f✝ : Vector ℕ (n✝ + 1) → ℕ
a✝ : Nat.Partrec' ↑f✝
a_ih✝ : ∃ c, ∀ (v : Vector ℕ (n✝ + 1)), eval c ↑v = pure <$> ↑f✝ v
⊢ ∃ c, ∀ (v : Vector ℕ n✝), eval c ↑v = pure <$> (fun v => Nat.rfind fun n => Part.some (decide (f✝ (n ::ᵥ v) = 0))) v

tactic: case comp m n f g _ _ IHf IHg => exact exists_code.comp IHf IHg
state_before: case comp
n : ℕ
f : Vector ℕ n →. ℕ
m✝ n✝ : ℕ
f✝ : Vector ℕ n✝ →. ℕ
g✝ : Fin n✝ → Vector ℕ m✝ →. ℕ
a✝¹ : Nat.Partrec' f✝
a✝ : ∀ (i : Fin n✝), Nat.Partrec' (g✝ i)
a_ih✝¹ : ∃ c, ∀ (v : Vector ℕ n✝), eval c ↑v = pure <$> f✝ v
a_ih✝ : ∀ (i : Fin n✝), ∃ c, ∀ (v : Vector ℕ m✝), eval c ↑v = pure <$> g✝ i v
⊢ ∃ c, ∀ (v : Vector ℕ m✝), eval c ↑v = pure <$> (fun v => (Vector.mOfFn fun i => g✝ i v) >>= f✝) v

case rfind
n : ℕ
f : Vector ℕ n →. ℕ
n✝ : ℕ
f✝ : Vector ℕ (n✝ + 1) → ℕ
a✝ : Nat.Partrec' ↑f✝
a_ih✝ : ∃ c, ∀ (v : Vector ℕ (n✝ + 1)), eval c ↑v = pure <$> ↑f✝ v
⊢ ∃ c, ∀ (v : Vector ℕ n✝), eval c ↑v = pure <$> (fun v => Nat.rfind fun n => Part.some (decide (f✝ (n ::ᵥ v) = 0))) v

tactic: exact ⟨zero', fun ⟨[], _⟩ => rfl⟩
state_before: n✝ : ℕ
f✝ : Vector ℕ n✝ →. ℕ
n : ℕ
f : Vector ℕ n → ℕ
⊢ ∃ c, ∀ (v : Vector ℕ 0), eval c ↑v = pure <$> (↑fun x => 0) v

tactic: exact ⟨succ, fun ⟨[v], _⟩ => rfl⟩
state_before: n✝ : ℕ
f✝ : Vector ℕ n✝ →. ℕ
n : ℕ
f : Vector ℕ n → ℕ
⊢ ∃ c, ∀ (v : Vector ℕ 1), eval c ↑v = pure <$> (↑fun v => Nat.succ (Vector.head v)) v

tactic: refine' Fin.succRec (fun n => _) (fun n i IH => _) i
state_before: n✝¹ : ℕ
f✝ : Vector ℕ n✝¹ →. ℕ
n✝ : ℕ
f : Vector ℕ n✝ → ℕ
n : ℕ
i : Fin n
⊢ ∃ c, ∀ (v : Vector ℕ n), eval c ↑v = pure <$> (↑fun v => Vector.get v i) v

tactic: exact ⟨head, fun ⟨List.cons a as, _⟩ => by simp [Bind.bind]; rfl⟩
state_before: case refine'_1
n✝² : ℕ
f✝ : Vector ℕ n✝² →. ℕ
n✝¹ : ℕ
f : Vector ℕ n✝¹ → ℕ
n✝ : ℕ
i : Fin n✝
n : ℕ
⊢ ∃ c, ∀ (v : Vector ℕ (Nat.succ n)), eval c ↑v = pure <$> (↑fun v => Vector.get v 0) v

tactic: simp [Bind.bind]
state_before: n✝² : ℕ
f✝ : Vector ℕ n✝² →. ℕ
n✝¹ : ℕ
f : Vector ℕ n✝¹ → ℕ
n✝ : ℕ
i : Fin n✝
n : ℕ
x✝ : Vector ℕ (Nat.succ n)
a : ℕ
as : List ℕ
property✝ : List.length (a :: as) = Nat.succ n
⊢ eval head ↑{ val := a :: as, property := property✝ } =
    pure <$> (↑fun v => Vector.get v 0) { val := a :: as, property := property✝ }

tactic: rfl
state_before: n✝² : ℕ
f✝ : Vector ℕ n✝² →. ℕ
n✝¹ : ℕ
f : Vector ℕ n✝¹ → ℕ
n✝ : ℕ
i : Fin n✝
n : ℕ
x✝ : Vector ℕ (Nat.succ n)
a : ℕ
as : List ℕ
property✝ : List.length (a :: as) = Nat.succ n
⊢ Part.some [a] = pure <$> Part.some (Vector.head { val := a :: as, property := property✝ })

tactic: obtain ⟨c, h⟩ := IH
state_before: case refine'_2
n✝² : ℕ
f✝ : Vector ℕ n✝² →. ℕ
n✝¹ : ℕ
f : Vector ℕ n✝¹ → ℕ
n✝ : ℕ
i✝ : Fin n✝
n : ℕ
i : Fin n
IH : ∃ c, ∀ (v : Vector ℕ n), eval c ↑v = pure <$> (↑fun v => Vector.get v i) v
⊢ ∃ c, ∀ (v : Vector ℕ (Nat.succ n)), eval c ↑v = pure <$> (↑fun v => Vector.get v (Fin.succ i)) v

tactic: exact ⟨c.comp tail, fun v => by simpa [← Vector.get_tail, Bind.bind] using h v.tail⟩
state_before: case refine'_2.intro
n✝² : ℕ
f✝ : Vector ℕ n✝² →. ℕ
n✝¹ : ℕ
f : Vector ℕ n✝¹ → ℕ
n✝ : ℕ
i✝ : Fin n✝
n : ℕ
i : Fin n
c : Code
h : ∀ (v : Vector ℕ n), eval c ↑v = pure <$> (↑fun v => Vector.get v i) v
⊢ ∃ c, ∀ (v : Vector ℕ (Nat.succ n)), eval c ↑v = pure <$> (↑fun v => Vector.get v (Fin.succ i)) v

tactic: simpa [← Vector.get_tail, Bind.bind] using h v.tail
state_before: n✝² : ℕ
f✝ : Vector ℕ n✝² →. ℕ
n✝¹ : ℕ
f : Vector ℕ n✝¹ → ℕ
n✝ : ℕ
i✝ : Fin n✝
n : ℕ
i : Fin n
c : Code
h : ∀ (v : Vector ℕ n), eval c ↑v = pure <$> (↑fun v => Vector.get v i) v
v : Vector ℕ (Nat.succ n)
⊢ eval (comp c tail) ↑v = pure <$> (↑fun v => Vector.get v (Fin.succ i)) v

tactic: simpa [Part.bind_eq_bind] using exists_code.comp IHf IHg
state_before: n✝¹ : ℕ
f✝¹ : Vector ℕ n✝¹ →. ℕ
n✝ : ℕ
f✝ : Vector ℕ n✝ → ℕ
m n : ℕ
f : Vector ℕ n → ℕ
g : Fin n → Vector ℕ m → ℕ
hf : Nat.Primrec' f
hg : ∀ (i : Fin n), Nat.Primrec' (g i)
IHf : ∃ c, ∀ (v : Vector ℕ n), eval c ↑v = pure <$> ↑f v
IHg : ∀ (i : Fin n), ∃ c, ∀ (v : Vector ℕ m), eval c ↑v = pure <$> ↑(g i) v
⊢ ∃ c, ∀ (v : Vector ℕ m), eval c ↑v = pure <$> (↑fun a => f (Vector.ofFn fun i => g i a)) v

tactic: obtain ⟨cf, hf⟩ := IHf
state_before: n✝¹ : ℕ
f✝¹ : Vector ℕ n✝¹ →. ℕ
n✝ : ℕ
f✝ : Vector ℕ n✝ → ℕ
n : ℕ
f : Vector ℕ n → ℕ
g : Vector ℕ (n + 2) → ℕ
a✝¹ : Nat.Primrec' f
a✝ : Nat.Primrec' g
IHf : ∃ c, ∀ (v : Vector ℕ n), eval c ↑v = pure <$> ↑f v
IHg : ∃ c, ∀ (v : Vector ℕ (n + 2)), eval c ↑v = pure <$> ↑g v
⊢ ∃ c,
    ∀ (v : Vector ℕ (n + 1)),
      eval c ↑v =
        pure <$> (↑fun v => Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) (Vector.head v)) v

tactic: obtain ⟨cg, hg⟩ := IHg
state_before: case intro
n✝¹ : ℕ
f✝¹ : Vector ℕ n✝¹ →. ℕ
n✝ : ℕ
f✝ : Vector ℕ n✝ → ℕ
n : ℕ
f : Vector ℕ n → ℕ
g : Vector ℕ (n + 2) → ℕ
a✝¹ : Nat.Primrec' f
a✝ : Nat.Primrec' g
IHg : ∃ c, ∀ (v : Vector ℕ (n + 2)), eval c ↑v = pure <$> ↑g v
cf : Code
hf : ∀ (v : Vector ℕ n), eval cf ↑v = pure <$> ↑f v
⊢ ∃ c,
    ∀ (v : Vector ℕ (n + 1)),
      eval c ↑v =
        pure <$> (↑fun v => Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) (Vector.head v)) v

tactic: simp only [Part.map_eq_map, Part.map_some, PFun.coe_val] at hf hg
state_before: case intro.intro
n✝¹ : ℕ
f✝¹ : Vector ℕ n✝¹ →. ℕ
n✝ : ℕ
f✝ : Vector ℕ n✝ → ℕ
n : ℕ
f : Vector ℕ n → ℕ
g : Vector ℕ (n + 2) → ℕ
a✝¹ : Nat.Primrec' f
a✝ : Nat.Primrec' g
cf : Code
hf : ∀ (v : Vector ℕ n), eval cf ↑v = pure <$> ↑f v
cg : Code
hg : ∀ (v : Vector ℕ (n + 2)), eval cg ↑v = pure <$> ↑g v
⊢ ∃ c,
    ∀ (v : Vector ℕ (n + 1)),
      eval c ↑v =
        pure <$> (↑fun v => Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) (Vector.head v)) v

tactic: refine' ⟨prec cf cg, fun v => _⟩
state_before: case intro.intro
n✝¹ : ℕ
f✝¹ : Vector ℕ n✝¹ →. ℕ
n✝ : ℕ
f✝ : Vector ℕ n✝ → ℕ
n : ℕ
f : Vector ℕ n → ℕ
g : Vector ℕ (n + 2) → ℕ
a✝¹ : Nat.Primrec' f
a✝ : Nat.Primrec' g
cf cg : Code
hf : ∀ (v : Vector ℕ n), eval cf ↑v = Part.some (pure (f v))
hg : ∀ (v : Vector ℕ (n + 2)), eval cg ↑v = Part.some (pure (g v))
⊢ ∃ c,
    ∀ (v : Vector ℕ (n + 1)),
      eval c ↑v =
        pure <$> (↑fun v => Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) (Vector.head v)) v

tactic: rw [← v.cons_head_tail]
state_before: case intro.intro
n✝¹ : ℕ
f✝¹ : Vector ℕ n✝¹ →. ℕ
n✝ : ℕ
f✝ : Vector ℕ n✝ → ℕ
n : ℕ
f : Vector ℕ n → ℕ
g : Vector ℕ (n + 2) → ℕ
a✝¹ : Nat.Primrec' f
a✝ : Nat.Primrec' g
cf cg : Code
hf : ∀ (v : Vector ℕ n), eval cf ↑v = Part.some (pure (f v))
hg : ∀ (v : Vector ℕ (n + 2)), eval cg ↑v = Part.some (pure (g v))
v : Vector ℕ (n + 1)
⊢ eval (prec cf cg) ↑v =
    pure <$> (↑fun v => Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) (Vector.head v)) v

tactic: specialize hf v.tail
state_before: case intro.intro
n✝¹ : ℕ
f✝¹ : Vector ℕ n✝¹ →. ℕ
n✝ : ℕ
f✝ : Vector ℕ n✝ → ℕ
n : ℕ
f : Vector ℕ n → ℕ
g : Vector ℕ (n + 2) → ℕ
a✝¹ : Nat.Primrec' f
a✝ : Nat.Primrec' g
cf cg : Code
hf : ∀ (v : Vector ℕ n), eval cf ↑v = Part.some (pure (f v))
hg : ∀ (v : Vector ℕ (n + 2)), eval cg ↑v = Part.some (pure (g v))
v : Vector ℕ (n + 1)
⊢ eval (prec cf cg) ↑(Vector.head v ::ᵥ Vector.tail v) =
    pure <$>
      (↑fun v => Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) (Vector.head v))
        (Vector.head v ::ᵥ Vector.tail v)

tactic: replace hg := fun a b => hg (a ::ᵥ b ::ᵥ v.tail)
state_before: case intro.intro
n✝¹ : ℕ
f✝¹ : Vector ℕ n✝¹ →. ℕ
n✝ : ℕ
f✝ : Vector ℕ n✝ → ℕ
n : ℕ
f : Vector ℕ n → ℕ
g : Vector ℕ (n + 2) → ℕ
a✝¹ : Nat.Primrec' f
a✝ : Nat.Primrec' g
cf cg : Code
hg : ∀ (v : Vector ℕ (n + 2)), eval cg ↑v = Part.some (pure (g v))
v : Vector ℕ (n + 1)
hf : eval cf ↑(Vector.tail v) = Part.some (pure (f (Vector.tail v)))
⊢ eval (prec cf cg) ↑(Vector.head v ::ᵥ Vector.tail v) =
    pure <$>
      (↑fun v => Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) (Vector.head v))
        (Vector.head v ::ᵥ Vector.tail v)

tactic: simp only [Vector.cons_val, Vector.tail_val] at hf hg
state_before: case intro.intro
n✝¹ : ℕ
f✝¹ : Vector ℕ n✝¹ →. ℕ
n✝ : ℕ
f✝ : Vector ℕ n✝ → ℕ
n : ℕ
f : Vector ℕ n → ℕ
g : Vector ℕ (n + 2) → ℕ
a✝¹ : Nat.Primrec' f
a✝ : Nat.Primrec' g
cf cg : Code
v : Vector ℕ (n + 1)
hf : eval cf ↑(Vector.tail v) = Part.some (pure (f (Vector.tail v)))
hg : ∀ (a b : ℕ), eval cg ↑(a ::ᵥ b ::ᵥ Vector.tail v) = Part.some (pure (g (a ::ᵥ b ::ᵥ Vector.tail v)))
⊢ eval (prec cf cg) ↑(Vector.head v ::ᵥ Vector.tail v) =
    pure <$>
      (↑fun v => Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) (Vector.head v))
        (Vector.head v ::ᵥ Vector.tail v)

tactic: simp only [Part.map_eq_map, Part.map_some, Vector.cons_val, Vector.tail_cons, Vector.head_cons,
  PFun.coe_val, Vector.tail_val]
state_before: case intro.intro
n✝¹ : ℕ
f✝¹ : Vector ℕ n✝¹ →. ℕ
n✝ : ℕ
f✝ : Vector ℕ n✝ → ℕ
n : ℕ
f : Vector ℕ n → ℕ
g : Vector ℕ (n + 2) → ℕ
a✝¹ : Nat.Primrec' f
a✝ : Nat.Primrec' g
cf cg : Code
v : Vector ℕ (n + 1)
hf : eval cf (List.tail ↑v) = Part.some (pure (f (Vector.tail v)))
hg : ∀ (a b : ℕ), eval cg (a :: b :: List.tail ↑v) = Part.some (pure (g (a ::ᵥ b ::ᵥ Vector.tail v)))
⊢ eval (prec cf cg) ↑(Vector.head v ::ᵥ Vector.tail v) =
    pure <$>
      (↑fun v => Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) (Vector.head v))
        (Vector.head v ::ᵥ Vector.tail v)

tactic: simp only [← Part.pure_eq_some] at hf hg⊢
state_before: case intro.intro
n✝¹ : ℕ
f✝¹ : Vector ℕ n✝¹ →. ℕ
n✝ : ℕ
f✝ : Vector ℕ n✝ → ℕ
n : ℕ
f : Vector ℕ n → ℕ
g : Vector ℕ (n + 2) → ℕ
a✝¹ : Nat.Primrec' f
a✝ : Nat.Primrec' g
cf cg : Code
v : Vector ℕ (n + 1)
hf : eval cf (List.tail ↑v) = Part.some (pure (f (Vector.tail v)))
hg : ∀ (a b : ℕ), eval cg (a :: b :: List.tail ↑v) = Part.some (pure (g (a ::ᵥ b ::ᵥ Vector.tail v)))
⊢ eval (prec cf cg) (Vector.head v :: List.tail ↑v) =
    Part.some (pure (Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) (Vector.head v)))

tactic: induction' v.head with n _ <;>
  simp [prec, hf, Part.bind_assoc, ← Part.bind_some_eq_map, Part.bind_some,
    show ∀ x, pure x = [x] from fun _ => rfl, Bind.bind, Functor.map]
state_before: case intro.intro
n✝¹ : ℕ
f✝¹ : Vector ℕ n✝¹ →. ℕ
n✝ : ℕ
f✝ : Vector ℕ n✝ → ℕ
n : ℕ
f : Vector ℕ n → ℕ
g : Vector ℕ (n + 2) → ℕ
a✝¹ : Nat.Primrec' f
a✝ : Nat.Primrec' g
cf cg : Code
v : Vector ℕ (n + 1)
hf : eval cf (List.tail ↑v) = pure (pure (f (Vector.tail v)))
hg : ∀ (a b : ℕ), eval cg (a :: b :: List.tail ↑v) = pure (pure (g (a ::ᵥ b ::ᵥ Vector.tail v)))
⊢ eval (prec cf cg) (Vector.head v :: List.tail ↑v) =
    pure (pure (Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) (Vector.head v)))

tactic: suffices ∀ a b, a + b = n →
  (n.succ :: 0 ::
    g (n ::ᵥ Nat.rec (f v.tail) (fun y IH => g (y ::ᵥ IH ::ᵥ v.tail)) n ::ᵥ v.tail)
      :: v.val.tail : List ℕ) ∈
    PFun.fix
      (fun v : List ℕ => Part.bind (cg.eval (v.headI :: v.tail.tail))
        (fun x => Part.some (if v.tail.headI = 0
          then Sum.inl
            (v.headI.succ :: v.tail.headI.pred :: x.headI :: v.tail.tail.tail : List ℕ)
          else Sum.inr
            (v.headI.succ :: v.tail.headI.pred :: x.headI :: v.tail.tail.tail))))
      (a :: b :: Nat.rec (f v.tail) (fun y IH => g (y ::ᵥ IH ::ᵥ v.tail)) a :: v.val.tail) by
  erw [Part.eq_some_iff.2 (this 0 n (zero_add n))]
  simp only [List.headI, Part.bind_some, List.tail_cons]
state_before: case intro.intro.succ
n✝² : ℕ
f✝¹ : Vector ℕ n✝² →. ℕ
n✝¹ : ℕ
f✝ : Vector ℕ n✝¹ → ℕ
n✝ : ℕ
f : Vector ℕ n✝ → ℕ
g : Vector ℕ (n✝ + 2) → ℕ
a✝¹ : Nat.Primrec' f
a✝ : Nat.Primrec' g
cf cg : Code
v : Vector ℕ (n✝ + 1)
hf : eval cf (List.tail ↑v) = pure (pure (f (Vector.tail v)))
hg : ∀ (a b : ℕ), eval cg (a :: b :: List.tail ↑v) = pure (pure (g (a ::ᵥ b ::ᵥ Vector.tail v)))
n : ℕ
n_ih✝ :
  eval (prec cf cg) (n :: List.tail ↑v) =
    pure (pure (Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) n))
⊢ (Part.bind
      (PFun.fix
        (fun v =>
          Part.bind (eval cg (List.headI v :: List.tail (List.tail v))) fun x =>
            Part.some
              (if List.headI (List.tail v) = 0 then
                Sum.inl
                  (Nat.succ (List.headI v) ::
                    Nat.pred (List.headI (List.tail v)) :: List.headI x :: List.tail (List.tail (List.tail v)))
              else
                Sum.inr
                  (Nat.succ (List.headI v) ::
                    Nat.pred (List.headI (List.tail v)) :: List.headI x :: List.tail (List.tail (List.tail v)))))
        (0 :: n :: f (Vector.tail v) :: List.tail ↑v))
      fun x => Part.some [List.headI (List.tail (List.tail x))]) =
    Part.some [g (n ::ᵥ Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) n ::ᵥ Vector.tail v)]

tactic: intro a b e
state_before: case intro.intro.succ
n✝² : ℕ
f✝¹ : Vector ℕ n✝² →. ℕ
n✝¹ : ℕ
f✝ : Vector ℕ n✝¹ → ℕ
n✝ : ℕ
f : Vector ℕ n✝ → ℕ
g : Vector ℕ (n✝ + 2) → ℕ
a✝¹ : Nat.Primrec' f
a✝ : Nat.Primrec' g
cf cg : Code
v : Vector ℕ (n✝ + 1)
hf : eval cf (List.tail ↑v) = pure (pure (f (Vector.tail v)))
hg : ∀ (a b : ℕ), eval cg (a :: b :: List.tail ↑v) = pure (pure (g (a ::ᵥ b ::ᵥ Vector.tail v)))
n : ℕ
n_ih✝ :
  eval (prec cf cg) (n :: List.tail ↑v) =
    pure (pure (Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) n))
⊢ ∀ (a b : ℕ),
    a + b = n →
      Nat.succ n ::
          0 ::
            g (n ::ᵥ Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) n ::ᵥ Vector.tail v) ::
              List.tail ↑v ∈
        PFun.fix
          (fun v =>
            Part.bind (eval cg (List.headI v :: List.tail (List.tail v))) fun x =>
              Part.some
                (if List.headI (List.tail v) = 0 then
                  Sum.inl
                    (Nat.succ (List.headI v) ::
                      Nat.pred (List.headI (List.tail v)) :: List.headI x :: List.tail (List.tail (List.tail v)))
                else
                  Sum.inr
                    (Nat.succ (List.headI v) ::
                      Nat.pred (List.headI (List.tail v)) :: List.headI x :: List.tail (List.tail (List.tail v)))))
          (a :: b :: Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) a :: List.tail ↑v)

tactic: induction' b with b IH generalizing a
state_before: case intro.intro.succ
n✝² : ℕ
f✝¹ : Vector ℕ n✝² →. ℕ
n✝¹ : ℕ
f✝ : Vector ℕ n✝¹ → ℕ
n✝ : ℕ
f : Vector ℕ n✝ → ℕ
g : Vector ℕ (n✝ + 2) → ℕ
a✝¹ : Nat.Primrec' f
a✝ : Nat.Primrec' g
cf cg : Code
v : Vector ℕ (n✝ + 1)
hf : eval cf (List.tail ↑v) = pure (pure (f (Vector.tail v)))
hg : ∀ (a b : ℕ), eval cg (a :: b :: List.tail ↑v) = pure (pure (g (a ::ᵥ b ::ᵥ Vector.tail v)))
n : ℕ
n_ih✝ :
  eval (prec cf cg) (n :: List.tail ↑v) =
    pure (pure (Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) n))
a b : ℕ
e : a + b = n
⊢ Nat.succ n ::
      0 ::
        g (n ::ᵥ Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) n ::ᵥ Vector.tail v) ::
          List.tail ↑v ∈
    PFun.fix
      (fun v =>
        Part.bind (eval cg (List.headI v :: List.tail (List.tail v))) fun x =>
          Part.some
            (if List.headI (List.tail v) = 0 then
              Sum.inl
                (Nat.succ (List.headI v) ::
                  Nat.pred (List.headI (List.tail v)) :: List.headI x :: List.tail (List.tail (List.tail v)))
            else
              Sum.inr
                (Nat.succ (List.headI v) ::
                  Nat.pred (List.headI (List.tail v)) :: List.headI x :: List.tail (List.tail (List.tail v)))))
      (a :: b :: Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) a :: List.tail ↑v)

tactic: erw [Part.eq_some_iff.2 (this 0 n (zero_add n))]
state_before: n✝² : ℕ
f✝¹ : Vector ℕ n✝² →. ℕ
n✝¹ : ℕ
f✝ : Vector ℕ n✝¹ → ℕ
n✝ : ℕ
f : Vector ℕ n✝ → ℕ
g : Vector ℕ (n✝ + 2) → ℕ
a✝¹ : Nat.Primrec' f
a✝ : Nat.Primrec' g
cf cg : Code
v : Vector ℕ (n✝ + 1)
hf : eval cf (List.tail ↑v) = pure (pure (f (Vector.tail v)))
hg : ∀ (a b : ℕ), eval cg (a :: b :: List.tail ↑v) = pure (pure (g (a ::ᵥ b ::ᵥ Vector.tail v)))
n : ℕ
n_ih✝ :
  eval (prec cf cg) (n :: List.tail ↑v) =
    pure (pure (Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) n))
this :
  ∀ (a b : ℕ),
    a + b = n →
      Nat.succ n ::
          0 ::
            g (n ::ᵥ Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) n ::ᵥ Vector.tail v) ::
              List.tail ↑v ∈
        PFun.fix
          (fun v =>
            Part.bind (eval cg (List.headI v :: List.tail (List.tail v))) fun x =>
              Part.some
                (if List.headI (List.tail v) = 0 then
                  Sum.inl
                    (Nat.succ (List.headI v) ::
                      Nat.pred (List.headI (List.tail v)) :: List.headI x :: List.tail (List.tail (List.tail v)))
                else
                  Sum.inr
                    (Nat.succ (List.headI v) ::
                      Nat.pred (List.headI (List.tail v)) :: List.headI x :: List.tail (List.tail (List.tail v)))))
          (a :: b :: Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) a :: List.tail ↑v)
⊢ (Part.bind
      (PFun.fix
        (fun v =>
          Part.bind (eval cg (List.headI v :: List.tail (List.tail v))) fun x =>
            Part.some
              (if List.headI (List.tail v) = 0 then
                Sum.inl
                  (Nat.succ (List.headI v) ::
                    Nat.pred (List.headI (List.tail v)) :: List.headI x :: List.tail (List.tail (List.tail v)))
              else
                Sum.inr
                  (Nat.succ (List.headI v) ::
                    Nat.pred (List.headI (List.tail v)) :: List.headI x :: List.tail (List.tail (List.tail v)))))
        (0 :: n :: f (Vector.tail v) :: List.tail ↑v))
      fun x => Part.some [List.headI (List.tail (List.tail x))]) =
    Part.some [g (n ::ᵥ Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) n ::ᵥ Vector.tail v)]

tactic: simp only [List.headI, Part.bind_some, List.tail_cons]
state_before: n✝² : ℕ
f✝¹ : Vector ℕ n✝² →. ℕ
n✝¹ : ℕ
f✝ : Vector ℕ n✝¹ → ℕ
n✝ : ℕ
f : Vector ℕ n✝ → ℕ
g : Vector ℕ (n✝ + 2) → ℕ
a✝¹ : Nat.Primrec' f
a✝ : Nat.Primrec' g
cf cg : Code
v : Vector ℕ (n✝ + 1)
hf : eval cf (List.tail ↑v) = pure (pure (f (Vector.tail v)))
hg : ∀ (a b : ℕ), eval cg (a :: b :: List.tail ↑v) = pure (pure (g (a ::ᵥ b ::ᵥ Vector.tail v)))
n : ℕ
n_ih✝ :
  eval (prec cf cg) (n :: List.tail ↑v) =
    pure (pure (Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) n))
this :
  ∀ (a b : ℕ),
    a + b = n →
      Nat.succ n ::
          0 ::
            g (n ::ᵥ Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) n ::ᵥ Vector.tail v) ::
              List.tail ↑v ∈
        PFun.fix
          (fun v =>
            Part.bind (eval cg (List.headI v :: List.tail (List.tail v))) fun x =>
              Part.some
                (if List.headI (List.tail v) = 0 then
                  Sum.inl
                    (Nat.succ (List.headI v) ::
                      Nat.pred (List.headI (List.tail v)) :: List.headI x :: List.tail (List.tail (List.tail v)))
                else
                  Sum.inr
                    (Nat.succ (List.headI v) ::
                      Nat.pred (List.headI (List.tail v)) :: List.headI x :: List.tail (List.tail (List.tail v)))))
          (a :: b :: Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) a :: List.tail ↑v)
⊢ (Part.bind
      (Part.some
        (Nat.succ n ::
          0 ::
            g (n ::ᵥ Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) n ::ᵥ Vector.tail v) ::
              List.tail ↑v))
      fun x => Part.some [List.headI (List.tail (List.tail x))]) =
    Part.some [g (n ::ᵥ Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) n ::ᵥ Vector.tail v)]

tactic: refine' PFun.mem_fix_iff.2 (Or.inl <| Part.eq_some_iff.1 _)
state_before: case intro.intro.succ.zero
n✝² : ℕ
f✝¹ : Vector ℕ n✝² →. ℕ
n✝¹ : ℕ
f✝ : Vector ℕ n✝¹ → ℕ
n✝ : ℕ
f : Vector ℕ n✝ → ℕ
g : Vector ℕ (n✝ + 2) → ℕ
a✝² : Nat.Primrec' f
a✝¹ : Nat.Primrec' g
cf cg : Code
v : Vector ℕ (n✝ + 1)
hf : eval cf (List.tail ↑v) = pure (pure (f (Vector.tail v)))
hg : ∀ (a b : ℕ), eval cg (a :: b :: List.tail ↑v) = pure (pure (g (a ::ᵥ b ::ᵥ Vector.tail v)))
n : ℕ
n_ih✝ :
  eval (prec cf cg) (n :: List.tail ↑v) =
    pure (pure (Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) n))
a✝ b : ℕ
e✝ : a✝ + b = n
a : ℕ
e : a + Nat.zero = n
⊢ Nat.succ n ::
      0 ::
        g (n ::ᵥ Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) n ::ᵥ Vector.tail v) ::
          List.tail ↑v ∈
    PFun.fix
      (fun v =>
        Part.bind (eval cg (List.headI v :: List.tail (List.tail v))) fun x =>
          Part.some
            (if List.headI (List.tail v) = 0 then
              Sum.inl
                (Nat.succ (List.headI v) ::
                  Nat.pred (List.headI (List.tail v)) :: List.headI x :: List.tail (List.tail (List.tail v)))
            else
              Sum.inr
                (Nat.succ (List.headI v) ::
                  Nat.pred (List.headI (List.tail v)) :: List.headI x :: List.tail (List.tail (List.tail v)))))
      (a :: Nat.zero :: Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) a :: List.tail ↑v)

tactic: simp only [hg, ← e, Part.bind_some, List.tail_cons, pure]
state_before: case intro.intro.succ.zero
n✝² : ℕ
f✝¹ : Vector ℕ n✝² →. ℕ
n✝¹ : ℕ
f✝ : Vector ℕ n✝¹ → ℕ
n✝ : ℕ
f : Vector ℕ n✝ → ℕ
g : Vector ℕ (n✝ + 2) → ℕ
a✝² : Nat.Primrec' f
a✝¹ : Nat.Primrec' g
cf cg : Code
v : Vector ℕ (n✝ + 1)
hf : eval cf (List.tail ↑v) = pure (pure (f (Vector.tail v)))
hg : ∀ (a b : ℕ), eval cg (a :: b :: List.tail ↑v) = pure (pure (g (a ::ᵥ b ::ᵥ Vector.tail v)))
n : ℕ
n_ih✝ :
  eval (prec cf cg) (n :: List.tail ↑v) =
    pure (pure (Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) n))
a✝ b : ℕ
e✝ : a✝ + b = n
a : ℕ
e : a + Nat.zero = n
⊢ (Part.bind
      (eval cg
        (List.headI
            (a ::
              Nat.zero :: Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) a :: List.tail ↑v) ::
          List.tail
            (List.tail
              (a ::
                Nat.zero ::
                  Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) a :: List.tail ↑v))))
      fun x =>
      Part.some
        (if
            List.headI
                (List.tail
                  (a ::
                    Nat.zero ::
                      Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) a :: List.tail ↑v)) =
              0 then
          Sum.inl
            (Nat.succ
                (List.headI
                  (a ::
                    Nat.zero ::
                      Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) a :: List.tail ↑v)) ::
              Nat.pred
                  (List.headI
                    (List.tail
                      (a ::
                        Nat.zero ::
                          Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) a ::
                            List.tail ↑v))) ::
                List.headI x ::
                  List.tail
                    (List.tail
                      (List.tail
                        (a ::
                          Nat.zero ::
                            Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) a ::
                              List.tail ↑v))))
        else
          Sum.inr
            (Nat.succ
                (List.headI
                  (a ::
                    Nat.zero ::
                      Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) a :: List.tail ↑v)) ::
              Nat.pred
                  (List.headI
                    (List.tail
                      (a ::
                        Nat.zero ::
                          Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) a ::
                            List.tail ↑v))) ::
                List.headI x ::
                  List.tail
                    (List.tail
                      (List.tail
                        (a ::
                          Nat.zero ::
                            Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) a ::
                              List.tail ↑v)))))) =
    Part.some
      (Sum.inl
        (Nat.succ n ::
          0 ::
            g (n ::ᵥ Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) n ::ᵥ Vector.tail v) ::
              List.tail ↑v))

tactic: rfl
state_before: case intro.intro.succ.zero
n✝² : ℕ
f✝¹ : Vector ℕ n✝² →. ℕ
n✝¹ : ℕ
f✝ : Vector ℕ n✝¹ → ℕ
n✝ : ℕ
f : Vector ℕ n✝ → ℕ
g : Vector ℕ (n✝ + 2) → ℕ
a✝² : Nat.Primrec' f
a✝¹ : Nat.Primrec' g
cf cg : Code
v : Vector ℕ (n✝ + 1)
hf : eval cf (List.tail ↑v) = pure (pure (f (Vector.tail v)))
hg : ∀ (a b : ℕ), eval cg (a :: b :: List.tail ↑v) = pure (pure (g (a ::ᵥ b ::ᵥ Vector.tail v)))
n : ℕ
n_ih✝ :
  eval (prec cf cg) (n :: List.tail ↑v) =
    pure (pure (Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) n))
a✝ b : ℕ
e✝ : a✝ + b = n
a : ℕ
e : a + Nat.zero = n
⊢ Part.some
      (if
          List.headI
              (Nat.zero :: Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) a :: List.tail ↑v) =
            0 then
        Sum.inl
          (Nat.succ
              (List.headI
                (a ::
                  Nat.zero ::
                    Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) a :: List.tail ↑v)) ::
            Nat.pred
                (List.headI
                  (Nat.zero ::
                    Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) a :: List.tail ↑v)) ::
              List.headI
                  (List.ret
                    (g
                      (List.headI
                          (a ::
                            Nat.zero ::
                              Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) a ::
                                List.tail ↑v) ::ᵥ
                        Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) a ::ᵥ
                          Vector.tail v))) ::
                List.tail ↑v)
      else
        Sum.inr
          (Nat.succ
              (List.headI
                (a ::
                  Nat.zero ::
                    Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) a :: List.tail ↑v)) ::
            Nat.pred
                (List.headI
                  (Nat.zero ::
                    Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) a :: List.tail ↑v)) ::
              List.headI
                  (List.ret
                    (g
                      (List.headI
                          (a ::
                            Nat.zero ::
                              Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) a ::
                                List.tail ↑v) ::ᵥ
                        Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) a ::ᵥ
                          Vector.tail v))) ::
                List.tail ↑v)) =
    Part.some
      (Sum.inl
        (Nat.succ (a + Nat.zero) ::
          0 ::
            g
                ((a + Nat.zero) ::ᵥ
                  Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) (a + Nat.zero) ::ᵥ
                    Vector.tail v) ::
              List.tail ↑v))

tactic: refine' PFun.mem_fix_iff.2 (Or.inr ⟨_, _, IH (a + 1) (by rwa [add_right_comm])⟩)
state_before: case intro.intro.succ.succ
n✝² : ℕ
f✝¹ : Vector ℕ n✝² →. ℕ
n✝¹ : ℕ
f✝ : Vector ℕ n✝¹ → ℕ
n✝ : ℕ
f : Vector ℕ n✝ → ℕ
g : Vector ℕ (n✝ + 2) → ℕ
a✝² : Nat.Primrec' f
a✝¹ : Nat.Primrec' g
cf cg : Code
v : Vector ℕ (n✝ + 1)
hf : eval cf (List.tail ↑v) = pure (pure (f (Vector.tail v)))
hg : ∀ (a b : ℕ), eval cg (a :: b :: List.tail ↑v) = pure (pure (g (a ::ᵥ b ::ᵥ Vector.tail v)))
n : ℕ
n_ih✝ :
  eval (prec cf cg) (n :: List.tail ↑v) =
    pure (pure (Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) n))
a✝ b✝ : ℕ
e✝ : a✝ + b✝ = n
b : ℕ
IH :
  ∀ (a : ℕ),
    a + b = n →
      Nat.succ n ::
          0 ::
            g (n ::ᵥ Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) n ::ᵥ Vector.tail v) ::
              List.tail ↑v ∈
        PFun.fix
          (fun v =>
            Part.bind (eval cg (List.headI v :: List.tail (List.tail v))) fun x =>
              Part.some
                (if List.headI (List.tail v) = 0 then
                  Sum.inl
                    (Nat.succ (List.headI v) ::
                      Nat.pred (List.headI (List.tail v)) :: List.headI x :: List.tail (List.tail (List.tail v)))
                else
                  Sum.inr
                    (Nat.succ (List.headI v) ::
                      Nat.pred (List.headI (List.tail v)) :: List.headI x :: List.tail (List.tail (List.tail v)))))
          (a :: b :: Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) a :: List.tail ↑v)
a : ℕ
e : a + Nat.succ b = n
⊢ Nat.succ n ::
      0 ::
        g (n ::ᵥ Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) n ::ᵥ Vector.tail v) ::
          List.tail ↑v ∈
    PFun.fix
      (fun v =>
        Part.bind (eval cg (List.headI v :: List.tail (List.tail v))) fun x =>
          Part.some
            (if List.headI (List.tail v) = 0 then
              Sum.inl
                (Nat.succ (List.headI v) ::
                  Nat.pred (List.headI (List.tail v)) :: List.headI x :: List.tail (List.tail (List.tail v)))
            else
              Sum.inr
                (Nat.succ (List.headI v) ::
                  Nat.pred (List.headI (List.tail v)) :: List.headI x :: List.tail (List.tail (List.tail v)))))
      (a :: Nat.succ b :: Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) a :: List.tail ↑v)

tactic: simp only [hg, eval, Part.bind_some, Nat.rec_add_one, List.tail_nil, List.tail_cons, pure]
state_before: case intro.intro.succ.succ
n✝² : ℕ
f✝¹ : Vector ℕ n✝² →. ℕ
n✝¹ : ℕ
f✝ : Vector ℕ n✝¹ → ℕ
n✝ : ℕ
f : Vector ℕ n✝ → ℕ
g : Vector ℕ (n✝ + 2) → ℕ
a✝² : Nat.Primrec' f
a✝¹ : Nat.Primrec' g
cf cg : Code
v : Vector ℕ (n✝ + 1)
hf : eval cf (List.tail ↑v) = pure (pure (f (Vector.tail v)))
hg : ∀ (a b : ℕ), eval cg (a :: b :: List.tail ↑v) = pure (pure (g (a ::ᵥ b ::ᵥ Vector.tail v)))
n : ℕ
n_ih✝ :
  eval (prec cf cg) (n :: List.tail ↑v) =
    pure (pure (Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) n))
a✝ b✝ : ℕ
e✝ : a✝ + b✝ = n
b : ℕ
IH :
  ∀ (a : ℕ),
    a + b = n →
      Nat.succ n ::
          0 ::
            g (n ::ᵥ Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) n ::ᵥ Vector.tail v) ::
              List.tail ↑v ∈
        PFun.fix
          (fun v =>
            Part.bind (eval cg (List.headI v :: List.tail (List.tail v))) fun x =>
              Part.some
                (if List.headI (List.tail v) = 0 then
                  Sum.inl
                    (Nat.succ (List.headI v) ::
                      Nat.pred (List.headI (List.tail v)) :: List.headI x :: List.tail (List.tail (List.tail v)))
                else
                  Sum.inr
                    (Nat.succ (List.headI v) ::
                      Nat.pred (List.headI (List.tail v)) :: List.headI x :: List.tail (List.tail (List.tail v)))))
          (a :: b :: Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) a :: List.tail ↑v)
a : ℕ
e : a + Nat.succ b = n
⊢ Sum.inr
      ((a + 1) ::
        b :: Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) (a + 1) :: List.tail ↑v) ∈
    Part.bind
      (eval cg
        (List.headI
            (a ::
              Nat.succ b ::
                Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) a :: List.tail ↑v) ::
          List.tail
            (List.tail
              (a ::
                Nat.succ b ::
                  Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) a :: List.tail ↑v))))
      fun x =>
      Part.some
        (if
            List.headI
                (List.tail
                  (a ::
                    Nat.succ b ::
                      Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) a :: List.tail ↑v)) =
              0 then
          Sum.inl
            (Nat.succ
                (List.headI
                  (a ::
                    Nat.succ b ::
                      Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) a :: List.tail ↑v)) ::
              Nat.pred
                  (List.headI
                    (List.tail
                      (a ::
                        Nat.succ b ::
                          Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) a ::
                            List.tail ↑v))) ::
                List.headI x ::
                  List.tail
                    (List.tail
                      (List.tail
                        (a ::
                          Nat.succ b ::
                            Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) a ::
                              List.tail ↑v))))
        else
          Sum.inr
            (Nat.succ
                (List.headI
                  (a ::
                    Nat.succ b ::
                      Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) a :: List.tail ↑v)) ::
              Nat.pred
                  (List.headI
                    (List.tail
                      (a ::
                        Nat.succ b ::
                          Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) a ::
                            List.tail ↑v))) ::
                List.headI x ::
                  List.tail
                    (List.tail
                      (List.tail
                        (a ::
                          Nat.succ b ::
                            Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) a ::
                              List.tail ↑v)))))

tactic: exact Part.mem_some_iff.2 rfl
state_before: case intro.intro.succ.succ
n✝² : ℕ
f✝¹ : Vector ℕ n✝² →. ℕ
n✝¹ : ℕ
f✝ : Vector ℕ n✝¹ → ℕ
n✝ : ℕ
f : Vector ℕ n✝ → ℕ
g : Vector ℕ (n✝ + 2) → ℕ
a✝² : Nat.Primrec' f
a✝¹ : Nat.Primrec' g
cf cg : Code
v : Vector ℕ (n✝ + 1)
hf : eval cf (List.tail ↑v) = pure (pure (f (Vector.tail v)))
hg : ∀ (a b : ℕ), eval cg (a :: b :: List.tail ↑v) = pure (pure (g (a ::ᵥ b ::ᵥ Vector.tail v)))
n : ℕ
n_ih✝ :
  eval (prec cf cg) (n :: List.tail ↑v) =
    pure (pure (Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) n))
a✝ b✝ : ℕ
e✝ : a✝ + b✝ = n
b : ℕ
IH :
  ∀ (a : ℕ),
    a + b = n →
      Nat.succ n ::
          0 ::
            g (n ::ᵥ Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) n ::ᵥ Vector.tail v) ::
              List.tail ↑v ∈
        PFun.fix
          (fun v =>
            Part.bind (eval cg (List.headI v :: List.tail (List.tail v))) fun x =>
              Part.some
                (if List.headI (List.tail v) = 0 then
                  Sum.inl
                    (Nat.succ (List.headI v) ::
                      Nat.pred (List.headI (List.tail v)) :: List.headI x :: List.tail (List.tail (List.tail v)))
                else
                  Sum.inr
                    (Nat.succ (List.headI v) ::
                      Nat.pred (List.headI (List.tail v)) :: List.headI x :: List.tail (List.tail (List.tail v)))))
          (a :: b :: Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) a :: List.tail ↑v)
a : ℕ
e : a + Nat.succ b = n
⊢ Sum.inr
      ((a + 1) ::
        b ::
          g (a ::ᵥ Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) a ::ᵥ Vector.tail v) ::
            List.tail ↑v) ∈
    Part.some
      (if
          List.headI
              (Nat.succ b ::
                Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) a :: List.tail ↑v) =
            0 then
        Sum.inl
          (Nat.succ
              (List.headI
                (a ::
                  Nat.succ b ::
                    Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) a :: List.tail ↑v)) ::
            Nat.pred
                (List.headI
                  (Nat.succ b ::
                    Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) a :: List.tail ↑v)) ::
              List.headI
                  (List.ret
                    (g
                      (List.headI
                          (a ::
                            Nat.succ b ::
                              Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) a ::
                                List.tail ↑v) ::ᵥ
                        Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) a ::ᵥ
                          Vector.tail v))) ::
                List.tail ↑v)
      else
        Sum.inr
          (Nat.succ
              (List.headI
                (a ::
                  Nat.succ b ::
                    Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) a :: List.tail ↑v)) ::
            Nat.pred
                (List.headI
                  (Nat.succ b ::
                    Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) a :: List.tail ↑v)) ::
              List.headI
                  (List.ret
                    (g
                      (List.headI
                          (a ::
                            Nat.succ b ::
                              Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) a ::
                                List.tail ↑v) ::ᵥ
                        Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) a ::ᵥ
                          Vector.tail v))) ::
                List.tail ↑v))

tactic: rwa [add_right_comm]
state_before: n✝² : ℕ
f✝¹ : Vector ℕ n✝² →. ℕ
n✝¹ : ℕ
f✝ : Vector ℕ n✝¹ → ℕ
n✝ : ℕ
f : Vector ℕ n✝ → ℕ
g : Vector ℕ (n✝ + 2) → ℕ
a✝² : Nat.Primrec' f
a✝¹ : Nat.Primrec' g
cf cg : Code
v : Vector ℕ (n✝ + 1)
hf : eval cf (List.tail ↑v) = pure (pure (f (Vector.tail v)))
hg : ∀ (a b : ℕ), eval cg (a :: b :: List.tail ↑v) = pure (pure (g (a ::ᵥ b ::ᵥ Vector.tail v)))
n : ℕ
n_ih✝ :
  eval (prec cf cg) (n :: List.tail ↑v) =
    pure (pure (Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) n))
a✝ b✝ : ℕ
e✝ : a✝ + b✝ = n
b : ℕ
IH :
  ∀ (a : ℕ),
    a + b = n →
      Nat.succ n ::
          0 ::
            g (n ::ᵥ Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) n ::ᵥ Vector.tail v) ::
              List.tail ↑v ∈
        PFun.fix
          (fun v =>
            Part.bind (eval cg (List.headI v :: List.tail (List.tail v))) fun x =>
              Part.some
                (if List.headI (List.tail v) = 0 then
                  Sum.inl
                    (Nat.succ (List.headI v) ::
                      Nat.pred (List.headI (List.tail v)) :: List.headI x :: List.tail (List.tail (List.tail v)))
                else
                  Sum.inr
                    (Nat.succ (List.headI v) ::
                      Nat.pred (List.headI (List.tail v)) :: List.headI x :: List.tail (List.tail (List.tail v)))))
          (a :: b :: Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) a :: List.tail ↑v)
a : ℕ
e : a + Nat.succ b = n
⊢ a + 1 + b = n

tactic: exact exists_code.comp IHf IHg
state_before: n✝ : ℕ
f✝ : Vector ℕ n✝ →. ℕ
m n : ℕ
f : Vector ℕ n →. ℕ
g : Fin n → Vector ℕ m →. ℕ
a✝¹ : Nat.Partrec' f
a✝ : ∀ (i : Fin n), Nat.Partrec' (g i)
IHf : ∃ c, ∀ (v : Vector ℕ n), eval c ↑v = pure <$> f v
IHg : ∀ (i : Fin n), ∃ c, ∀ (v : Vector ℕ m), eval c ↑v = pure <$> g i v
⊢ ∃ c, ∀ (v : Vector ℕ m), eval c ↑v = pure <$> (fun v => (Vector.mOfFn fun i => g i v) >>= f) v

tactic: obtain ⟨cf, hf⟩ := IHf
state_before: n✝ : ℕ
f✝ : Vector ℕ n✝ →. ℕ
n : ℕ
f : Vector ℕ (n + 1) → ℕ
a✝ : Nat.Partrec' ↑f
IHf : ∃ c, ∀ (v : Vector ℕ (n + 1)), eval c ↑v = pure <$> ↑f v
⊢ ∃ c, ∀ (v : Vector ℕ n), eval c ↑v = pure <$> (fun v => Nat.rfind fun n_1 => Part.some (decide (f (n_1 ::ᵥ v) = 0))) v

tactic: refine' ⟨rfind cf, fun v => _⟩
state_before: case intro
n✝ : ℕ
f✝ : Vector ℕ n✝ →. ℕ
n : ℕ
f : Vector ℕ (n + 1) → ℕ
a✝ : Nat.Partrec' ↑f
cf : Code
hf : ∀ (v : Vector ℕ (n + 1)), eval cf ↑v = pure <$> ↑f v
⊢ ∃ c, ∀ (v : Vector ℕ n), eval c ↑v = pure <$> (fun v => Nat.rfind fun n_1 => Part.some (decide (f (n_1 ::ᵥ v) = 0))) v

tactic: replace hf := fun a => hf (a ::ᵥ v)
state_before: case intro
n✝ : ℕ
f✝ : Vector ℕ n✝ →. ℕ
n : ℕ
f : Vector ℕ (n + 1) → ℕ
a✝ : Nat.Partrec' ↑f
cf : Code
hf : ∀ (v : Vector ℕ (n + 1)), eval cf ↑v = pure <$> ↑f v
v : Vector ℕ n
⊢ eval (rfind cf) ↑v = pure <$> (fun v => Nat.rfind fun n_1 => Part.some (decide (f (n_1 ::ᵥ v) = 0))) v

tactic: simp only [Part.map_eq_map, Part.map_some, Vector.cons_val, PFun.coe_val,
  show ∀ x, pure x = [x] from fun _ => rfl] at hf⊢
state_before: case intro
n✝ : ℕ
f✝ : Vector ℕ n✝ →. ℕ
n : ℕ
f : Vector ℕ (n + 1) → ℕ
a✝ : Nat.Partrec' ↑f
cf : Code
v : Vector ℕ n
hf : ∀ (a : ℕ), eval cf ↑(a ::ᵥ v) = pure <$> ↑f (a ::ᵥ v)
⊢ eval (rfind cf) ↑v = pure <$> (fun v => Nat.rfind fun n_1 => Part.some (decide (f (n_1 ::ᵥ v) = 0))) v

tactic: refine' Part.ext fun x => _
state_before: case intro
n✝ : ℕ
f✝ : Vector ℕ n✝ →. ℕ
n : ℕ
f : Vector ℕ (n + 1) → ℕ
a✝ : Nat.Partrec' ↑f
cf : Code
v : Vector ℕ n
hf : ∀ (a : ℕ), eval cf (a :: ↑v) = Part.some [f (a ::ᵥ v)]
⊢ eval (rfind cf) ↑v = Part.map pure (Nat.rfind fun n_1 => Part.some (decide (f (n_1 ::ᵥ v) = 0)))

tactic: simp only [rfind, Part.bind_eq_bind, Part.pure_eq_some, Part.map_eq_map, Part.bind_some,
  exists_prop, cons_eval, comp_eval, fix_eval, tail_eval, succ_eval, zero'_eval,
  List.headI_nil, List.headI_cons, pred_eval, Part.map_some, Bool.false_eq_decide_iff,
  Part.mem_bind_iff, List.length, Part.mem_map_iff, Nat.mem_rfind, List.tail_nil,
  List.tail_cons, Bool.true_eq_decide_iff, Part.mem_some_iff, Part.map_bind]
state_before: case intro
n✝ : ℕ
f✝ : Vector ℕ n✝ →. ℕ
n : ℕ
f : Vector ℕ (n + 1) → ℕ
a✝ : Nat.Partrec' ↑f
cf : Code
v : Vector ℕ n
hf : ∀ (a : ℕ), eval cf (a :: ↑v) = Part.some [f (a ::ᵥ v)]
x : List ℕ
⊢ x ∈ eval (rfind cf) ↑v ↔ x ∈ Part.map pure (Nat.rfind fun n_1 => Part.some (decide (f (n_1 ::ᵥ v) = 0)))

tactic: constructor
state_before: case intro
n✝ : ℕ
f✝ : Vector ℕ n✝ →. ℕ
n : ℕ
f : Vector ℕ (n + 1) → ℕ
a✝ : Nat.Partrec' ↑f
cf : Code
v : Vector ℕ n
hf : ∀ (a : ℕ), eval cf (a :: ↑v) = Part.some [f (a ::ᵥ v)]
x : List ℕ
⊢ (∃ a,
      a ∈
          PFun.fix
            (fun v =>
              Part.bind (eval cf v) fun y =>
                Part.some
                  (if List.headI y = 0 then Sum.inl (Nat.succ (List.headI v) :: List.tail v)
                  else Sum.inr (Nat.succ (List.headI v) :: List.tail v)))
            (0 :: ↑v) ∧
        x = [Nat.pred (List.headI a)]) ↔
    ∃ a, (f (a ::ᵥ v) = 0 ∧ ∀ {m : ℕ}, m < a → ¬f (m ::ᵥ v) = 0) ∧ pure a = x

tactic: rintro ⟨v', h1, rfl⟩
state_before: case intro.mp
n✝ : ℕ
f✝ : Vector ℕ n✝ →. ℕ
n : ℕ
f : Vector ℕ (n + 1) → ℕ
a✝ : Nat.Partrec' ↑f
cf : Code
v : Vector ℕ n
hf : ∀ (a : ℕ), eval cf (a :: ↑v) = Part.some [f (a ::ᵥ v)]
x : List ℕ
⊢ (∃ a,
      a ∈
          PFun.fix
            (fun v =>
              Part.bind (eval cf v) fun y =>
                Part.some
                  (if List.headI y = 0 then Sum.inl (Nat.succ (List.headI v) :: List.tail v)
                  else Sum.inr (Nat.succ (List.headI v) :: List.tail v)))
            (0 :: ↑v) ∧
        x = [Nat.pred (List.headI a)]) →
    ∃ a, (f (a ::ᵥ v) = 0 ∧ ∀ {m : ℕ}, m < a → ¬f (m ::ᵥ v) = 0) ∧ pure a = x

tactic: suffices ∀ v₁ : List ℕ, v' ∈ PFun.fix
  (fun v => (cf.eval v).bind fun y => Part.some <|
    if y.headI = 0 then Sum.inl (v.headI.succ :: v.tail)
      else Sum.inr (v.headI.succ :: v.tail)) v₁ →
  ∀ n, (v₁ = n :: v.val) → (∀ m < n, ¬f (m ::ᵥ v) = 0) →
    ∃ a : ℕ,
      (f (a ::ᵥ v) = 0 ∧ ∀ {m : ℕ}, m < a → ¬f (m ::ᵥ v) = 0) ∧ [a] = [v'.headI.pred]
  by exact this _ h1 0 rfl (by rintro _ ⟨⟩)
state_before: case intro.mp.intro.intro
n✝ : ℕ
f✝ : Vector ℕ n✝ →. ℕ
n : ℕ
f : Vector ℕ (n + 1) → ℕ
a✝ : Nat.Partrec' ↑f
cf : Code
v : Vector ℕ n
hf : ∀ (a : ℕ), eval cf (a :: ↑v) = Part.some [f (a ::ᵥ v)]
v' : List ℕ
h1 :
  v' ∈
    PFun.fix
      (fun v =>
        Part.bind (eval cf v) fun y =>
          Part.some
            (if List.headI y = 0 then Sum.inl (Nat.succ (List.headI v) :: List.tail v)
            else Sum.inr (Nat.succ (List.headI v) :: List.tail v)))
      (0 :: ↑v)
⊢ ∃ a, (f (a ::ᵥ v) = 0 ∧ ∀ {m : ℕ}, m < a → ¬f (m ::ᵥ v) = 0) ∧ pure a = [Nat.pred (List.headI v')]

tactic: clear h1
state_before: case intro.mp.intro.intro
n✝ : ℕ
f✝ : Vector ℕ n✝ →. ℕ
n : ℕ
f : Vector ℕ (n + 1) → ℕ
a✝ : Nat.Partrec' ↑f
cf : Code
v : Vector ℕ n
hf : ∀ (a : ℕ), eval cf (a :: ↑v) = Part.some [f (a ::ᵥ v)]
v' : List ℕ
h1 :
  v' ∈
    PFun.fix
      (fun v =>
        Part.bind (eval cf v) fun y =>
          Part.some
            (if List.headI y = 0 then Sum.inl (Nat.succ (List.headI v) :: List.tail v)
            else Sum.inr (Nat.succ (List.headI v) :: List.tail v)))
      (0 :: ↑v)
⊢ ∀ (v₁ : List ℕ),
    v' ∈
        PFun.fix
          (fun v =>
            Part.bind (eval cf v) fun y =>
              Part.some
                (if List.headI y = 0 then Sum.inl (Nat.succ (List.headI v) :: List.tail v)
                else Sum.inr (Nat.succ (List.headI v) :: List.tail v)))
          v₁ →
      ∀ (n_1 : ℕ),
        v₁ = n_1 :: ↑v →
          (∀ (m : ℕ), m < n_1 → ¬f (m ::ᵥ v) = 0) →
            ∃ a, (f (a ::ᵥ v) = 0 ∧ ∀ {m : ℕ}, m < a → ¬f (m ::ᵥ v) = 0) ∧ [a] = [Nat.pred (List.headI v')]

tactic: intro v₀ h1
state_before: case intro.mp.intro.intro
n✝ : ℕ
f✝ : Vector ℕ n✝ →. ℕ
n : ℕ
f : Vector ℕ (n + 1) → ℕ
a✝ : Nat.Partrec' ↑f
cf : Code
v : Vector ℕ n
hf : ∀ (a : ℕ), eval cf (a :: ↑v) = Part.some [f (a ::ᵥ v)]
v' : List ℕ
⊢ ∀ (v₁ : List ℕ),
    v' ∈
        PFun.fix
          (fun v =>
            Part.bind (eval cf v) fun y =>
              Part.some
                (if List.headI y = 0 then Sum.inl (Nat.succ (List.headI v) :: List.tail v)
                else Sum.inr (Nat.succ (List.headI v) :: List.tail v)))
          v₁ →
      ∀ (n_1 : ℕ),
        v₁ = n_1 :: ↑v →
          (∀ (m : ℕ), m < n_1 → ¬f (m ::ᵥ v) = 0) →
            ∃ a, (f (a ::ᵥ v) = 0 ∧ ∀ {m : ℕ}, m < a → ¬f (m ::ᵥ v) = 0) ∧ [a] = [Nat.pred (List.headI v')]

tactic: refine' PFun.fixInduction h1 fun v₁ h2 IH => _
state_before: case intro.mp.intro.intro
n✝ : ℕ
f✝ : Vector ℕ n✝ →. ℕ
n : ℕ
f : Vector ℕ (n + 1) → ℕ
a✝ : Nat.Partrec' ↑f
cf : Code
v : Vector ℕ n
hf : ∀ (a : ℕ), eval cf (a :: ↑v) = Part.some [f (a ::ᵥ v)]
v' v₀ : List ℕ
h1 :
  v' ∈
    PFun.fix
      (fun v =>
        Part.bind (eval cf v) fun y =>
          Part.some
            (if List.headI y = 0 then Sum.inl (Nat.succ (List.headI v) :: List.tail v)
            else Sum.inr (Nat.succ (List.headI v) :: List.tail v)))
      v₀
⊢ ∀ (n_1 : ℕ),
    v₀ = n_1 :: ↑v →
      (∀ (m : ℕ), m < n_1 → ¬f (m ::ᵥ v) = 0) →
        ∃ a, (f (a ::ᵥ v) = 0 ∧ ∀ {m : ℕ}, m < a → ¬f (m ::ᵥ v) = 0) ∧ [a] = [Nat.pred (List.headI v')]

tactic: clear h1
state_before: case intro.mp.intro.intro
n✝ : ℕ
f✝ : Vector ℕ n✝ →. ℕ
n : ℕ
f : Vector ℕ (n + 1) → ℕ
a✝ : Nat.Partrec' ↑f
cf : Code
v : Vector ℕ n
hf : ∀ (a : ℕ), eval cf (a :: ↑v) = Part.some [f (a ::ᵥ v)]
v' v₀ : List ℕ
h1 :
  v' ∈
    PFun.fix
      (fun v =>
        Part.bind (eval cf v) fun y =>
          Part.some
            (if List.headI y = 0 then Sum.inl (Nat.succ (List.headI v) :: List.tail v)
            else Sum.inr (Nat.succ (List.headI v) :: List.tail v)))
      v₀
v₁ : List ℕ
h2 :
  v' ∈
    PFun.fix
      (fun v =>
        Part.bind (eval cf v) fun y =>
          Part.some
            (if List.headI y = 0 then Sum.inl (Nat.succ (List.headI v) :: List.tail v)
            else Sum.inr (Nat.succ (List.headI v) :: List.tail v)))
      v₁
IH :
  ∀ (a'' : List ℕ),
    (Sum.inr a'' ∈
        Part.bind (eval cf v₁) fun y =>
          Part.some
            (if List.headI y = 0 then Sum.inl (Nat.succ (List.headI v₁) :: List.tail v₁)
            else Sum.inr (Nat.succ (List.headI v₁) :: List.tail v₁))) →
      ∀ (n_1 : ℕ),
        a'' = n_1 :: ↑v →
          (∀ (m : ℕ), m < n_1 → ¬f (m ::ᵥ v) = 0) →
            ∃ a, (f (a ::ᵥ v) = 0 ∧ ∀ {m : ℕ}, m < a → ¬f (m ::ᵥ v) = 0) ∧ [a] = [Nat.pred (List.headI v')]
⊢ ∀ (n_1 : ℕ),
    v₁ = n_1 :: ↑v →
      (∀ (m : ℕ), m < n_1 → ¬f (m ::ᵥ v) = 0) →
        ∃ a, (f (a ::ᵥ v) = 0 ∧ ∀ {m : ℕ}, m < a → ¬f (m ::ᵥ v) = 0) ∧ [a] = [Nat.pred (List.headI v')]

tactic: rintro n rfl hm
state_before: case intro.mp.intro.intro
n✝ : ℕ
f✝ : Vector ℕ n✝ →. ℕ
n : ℕ
f : Vector ℕ (n + 1) → ℕ
a✝ : Nat.Partrec' ↑f
cf : Code
v : Vector ℕ n
hf : ∀ (a : ℕ), eval cf (a :: ↑v) = Part.some [f (a ::ᵥ v)]
v' v₀ v₁ : List ℕ
h2 :
  v' ∈
    PFun.fix
      (fun v =>
        Part.bind (eval cf v) fun y =>
          Part.some
            (if List.headI y = 0 then Sum.inl (Nat.succ (List.headI v) :: List.tail v)
            else Sum.inr (Nat.succ (List.headI v) :: List.tail v)))
      v₁
IH :
  ∀ (a'' : List ℕ),
    (Sum.inr a'' ∈
        Part.bind (eval cf v₁) fun y =>
          Part.some
            (if List.headI y = 0 then Sum.inl (Nat.succ (List.headI v₁) :: List.tail v₁)
            else Sum.inr (Nat.succ (List.headI v₁) :: List.tail v₁))) →
      ∀ (n_1 : ℕ),
        a'' = n_1 :: ↑v →
          (∀ (m : ℕ), m < n_1 → ¬f (m ::ᵥ v) = 0) →
            ∃ a, (f (a ::ᵥ v) = 0 ∧ ∀ {m : ℕ}, m < a → ¬f (m ::ᵥ v) = 0) ∧ [a] = [Nat.pred (List.headI v')]
⊢ ∀ (n_1 : ℕ),
    v₁ = n_1 :: ↑v →
      (∀ (m : ℕ), m < n_1 → ¬f (m ::ᵥ v) = 0) →
        ∃ a, (f (a ::ᵥ v) = 0 ∧ ∀ {m : ℕ}, m < a → ¬f (m ::ᵥ v) = 0) ∧ [a] = [Nat.pred (List.headI v')]

tactic: have := PFun.mem_fix_iff.1 h2
state_before: case intro.mp.intro.intro
n✝¹ : ℕ
f✝ : Vector ℕ n✝¹ →. ℕ
n✝ : ℕ
f : Vector ℕ (n✝ + 1) → ℕ
a✝ : Nat.Partrec' ↑f
cf : Code
v : Vector ℕ n✝
hf : ∀ (a : ℕ), eval cf (a :: ↑v) = Part.some [f (a ::ᵥ v)]
v' v₀ : List ℕ
n : ℕ
h2 :
  v' ∈
    PFun.fix
      (fun v =>
        Part.bind (eval cf v) fun y =>
          Part.some
            (if List.headI y = 0 then Sum.inl (Nat.succ (List.headI v) :: List.tail v)
            else Sum.inr (Nat.succ (List.headI v) :: List.tail v)))
      (n :: ↑v)
IH :
  ∀ (a'' : List ℕ),
    (Sum.inr a'' ∈
        Part.bind (eval cf (n :: ↑v)) fun y =>
          Part.some
            (if List.headI y = 0 then Sum.inl (Nat.succ (List.headI (n :: ↑v)) :: List.tail (n :: ↑v))
            else Sum.inr (Nat.succ (List.headI (n :: ↑v)) :: List.tail (n :: ↑v)))) →
      ∀ (n : ℕ),
        a'' = n :: ↑v →
          (∀ (m : ℕ), m < n → ¬f (m ::ᵥ v) = 0) →
            ∃ a, (f (a ::ᵥ v) = 0 ∧ ∀ {m : ℕ}, m < a → ¬f (m ::ᵥ v) = 0) ∧ [a] = [Nat.pred (List.headI v')]
hm : ∀ (m : ℕ), m < n → ¬f (m ::ᵥ v) = 0
⊢ ∃ a, (f (a ::ᵥ v) = 0 ∧ ∀ {m : ℕ}, m < a → ¬f (m ::ᵥ v) = 0) ∧ [a] = [Nat.pred (List.headI v')]

tactic: simp only [hf, Part.bind_some] at this
state_before: case intro.mp.intro.intro
n✝¹ : ℕ
f✝ : Vector ℕ n✝¹ →. ℕ
n✝ : ℕ
f : Vector ℕ (n✝ + 1) → ℕ
a✝ : Nat.Partrec' ↑f
cf : Code
v : Vector ℕ n✝
hf : ∀ (a : ℕ), eval cf (a :: ↑v) = Part.some [f (a ::ᵥ v)]
v' v₀ : List ℕ
n : ℕ
h2 :
  v' ∈
    PFun.fix
      (fun v =>
        Part.bind (eval cf v) fun y =>
          Part.some
            (if List.headI y = 0 then Sum.inl (Nat.succ (List.headI v) :: List.tail v)
            else Sum.inr (Nat.succ (List.headI v) :: List.tail v)))
      (n :: ↑v)
IH :
  ∀ (a'' : List ℕ),
    (Sum.inr a'' ∈
        Part.bind (eval cf (n :: ↑v)) fun y =>
          Part.some
            (if List.headI y = 0 then Sum.inl (Nat.succ (List.headI (n :: ↑v)) :: List.tail (n :: ↑v))
            else Sum.inr (Nat.succ (List.headI (n :: ↑v)) :: List.tail (n :: ↑v)))) →
      ∀ (n : ℕ),
        a'' = n :: ↑v →
          (∀ (m : ℕ), m < n → ¬f (m ::ᵥ v) = 0) →
            ∃ a, (f (a ::ᵥ v) = 0 ∧ ∀ {m : ℕ}, m < a → ¬f (m ::ᵥ v) = 0) ∧ [a] = [Nat.pred (List.headI v')]
hm : ∀ (m : ℕ), m < n → ¬f (m ::ᵥ v) = 0
this :
  (Sum.inl v' ∈
      Part.bind (eval cf (n :: ↑v)) fun y =>
        Part.some
          (if List.headI y = 0 then Sum.inl (Nat.succ (List.headI (n :: ↑v)) :: List.tail (n :: ↑v))
          else Sum.inr (Nat.succ (List.headI (n :: ↑v)) :: List.tail (n :: ↑v)))) ∨
    ∃ a',
      (Sum.inr a' ∈
          Part.bind (eval cf (n :: ↑v)) fun y =>
            Part.some
              (if List.headI y = 0 then Sum.inl (Nat.succ (List.headI (n :: ↑v)) :: List.tail (n :: ↑v))
              else Sum.inr (Nat.succ (List.headI (n :: ↑v)) :: List.tail (n :: ↑v)))) ∧
        v' ∈
          PFun.fix
            (fun v =>
              Part.bind (eval cf v) fun y =>
                Part.some
                  (if List.headI y = 0 then Sum.inl (Nat.succ (List.headI v) :: List.tail v)
                  else Sum.inr (Nat.succ (List.headI v) :: List.tail v)))
            a'
⊢ ∃ a, (f (a ::ᵥ v) = 0 ∧ ∀ {m : ℕ}, m < a → ¬f (m ::ᵥ v) = 0) ∧ [a] = [Nat.pred (List.headI v')]

tactic: split_ifs at this with h
state_before: case intro.mp.intro.intro
n✝¹ : ℕ
f✝ : Vector ℕ n✝¹ →. ℕ
n✝ : ℕ
f : Vector ℕ (n✝ + 1) → ℕ
a✝ : Nat.Partrec' ↑f
cf : Code
v : Vector ℕ n✝
hf : ∀ (a : ℕ), eval cf (a :: ↑v) = Part.some [f (a ::ᵥ v)]
v' v₀ : List ℕ
n : ℕ
h2 :
  v' ∈
    PFun.fix
      (fun v =>
        Part.bind (eval cf v) fun y =>
          Part.some
            (if List.headI y = 0 then Sum.inl (Nat.succ (List.headI v) :: List.tail v)
            else Sum.inr (Nat.succ (List.headI v) :: List.tail v)))
      (n :: ↑v)
IH :
  ∀ (a'' : List ℕ),
    (Sum.inr a'' ∈
        Part.bind (eval cf (n :: ↑v)) fun y =>
          Part.some
            (if List.headI y = 0 then Sum.inl (Nat.succ (List.headI (n :: ↑v)) :: List.tail (n :: ↑v))
            else Sum.inr (Nat.succ (List.headI (n :: ↑v)) :: List.tail (n :: ↑v)))) →
      ∀ (n : ℕ),
        a'' = n :: ↑v →
          (∀ (m : ℕ), m < n → ¬f (m ::ᵥ v) = 0) →
            ∃ a, (f (a ::ᵥ v) = 0 ∧ ∀ {m : ℕ}, m < a → ¬f (m ::ᵥ v) = 0) ∧ [a] = [Nat.pred (List.headI v')]
hm : ∀ (m : ℕ), m < n → ¬f (m ::ᵥ v) = 0
this :
  Sum.inl v' ∈
      Part.some
        (if List.headI [f (n ::ᵥ v)] = 0 then Sum.inl (Nat.succ (List.headI (n :: ↑v)) :: List.tail (n :: ↑v))
        else Sum.inr (Nat.succ (List.headI (n :: ↑v)) :: List.tail (n :: ↑v))) ∨
    ∃ a',
      Sum.inr a' ∈
          Part.some
            (if List.headI [f (n ::ᵥ v)] = 0 then Sum.inl (Nat.succ (List.headI (n :: ↑v)) :: List.tail (n :: ↑v))
            else Sum.inr (Nat.succ (List.headI (n :: ↑v)) :: List.tail (n :: ↑v))) ∧
        v' ∈
          PFun.fix
            (fun v =>
              Part.bind (eval cf v) fun y =>
                Part.some
                  (if List.headI y = 0 then Sum.inl (Nat.succ (List.headI v) :: List.tail v)
                  else Sum.inr (Nat.succ (List.headI v) :: List.tail v)))
            a'
⊢ ∃ a, (f (a ::ᵥ v) = 0 ∧ ∀ {m : ℕ}, m < a → ¬f (m ::ᵥ v) = 0) ∧ [a] = [Nat.pred (List.headI v')]

tactic: exact this _ h1 0 rfl (by rintro _ ⟨⟩)
state_before: n✝ : ℕ
f✝ : Vector ℕ n✝ →. ℕ
n : ℕ
f : Vector ℕ (n + 1) → ℕ
a✝ : Nat.Partrec' ↑f
cf : Code
v : Vector ℕ n
hf : ∀ (a : ℕ), eval cf (a :: ↑v) = Part.some [f (a ::ᵥ v)]
v' : List ℕ
h1 :
  v' ∈
    PFun.fix
      (fun v =>
        Part.bind (eval cf v) fun y =>
          Part.some
            (if List.headI y = 0 then Sum.inl (Nat.succ (List.headI v) :: List.tail v)
            else Sum.inr (Nat.succ (List.headI v) :: List.tail v)))
      (0 :: ↑v)
this :
  ∀ (v₁ : List ℕ),
    v' ∈
        PFun.fix
          (fun v =>
            Part.bind (eval cf v) fun y =>
              Part.some
                (if List.headI y = 0 then Sum.inl (Nat.succ (List.headI v) :: List.tail v)
                else Sum.inr (Nat.succ (List.headI v) :: List.tail v)))
          v₁ →
      ∀ (n_1 : ℕ),
        v₁ = n_1 :: ↑v →
          (∀ (m : ℕ), m < n_1 → ¬f (m ::ᵥ v) = 0) →
            ∃ a, (f (a ::ᵥ v) = 0 ∧ ∀ {m : ℕ}, m < a → ¬f (m ::ᵥ v) = 0) ∧ [a] = [Nat.pred (List.headI v')]
⊢ ∃ a, (f (a ::ᵥ v) = 0 ∧ ∀ {m : ℕ}, m < a → ¬f (m ::ᵥ v) = 0) ∧ pure a = [Nat.pred (List.headI v')]

tactic: rintro _ ⟨⟩
state_before: n✝ : ℕ
f✝ : Vector ℕ n✝ →. ℕ
n : ℕ
f : Vector ℕ (n + 1) → ℕ
a✝ : Nat.Partrec' ↑f
cf : Code
v : Vector ℕ n
hf : ∀ (a : ℕ), eval cf (a :: ↑v) = Part.some [f (a ::ᵥ v)]
v' : List ℕ
h1 :
  v' ∈
    PFun.fix
      (fun v =>
        Part.bind (eval cf v) fun y =>
          Part.some
            (if List.headI y = 0 then Sum.inl (Nat.succ (List.headI v) :: List.tail v)
            else Sum.inr (Nat.succ (List.headI v) :: List.tail v)))
      (0 :: ↑v)
this :
  ∀ (v₁ : List ℕ),
    v' ∈
        PFun.fix
          (fun v =>
            Part.bind (eval cf v) fun y =>
              Part.some
                (if List.headI y = 0 then Sum.inl (Nat.succ (List.headI v) :: List.tail v)
                else Sum.inr (Nat.succ (List.headI v) :: List.tail v)))
          v₁ →
      ∀ (n_1 : ℕ),
        v₁ = n_1 :: ↑v →
          (∀ (m : ℕ), m < n_1 → ¬f (m ::ᵥ v) = 0) →
            ∃ a, (f (a ::ᵥ v) = 0 ∧ ∀ {m : ℕ}, m < a → ¬f (m ::ᵥ v) = 0) ∧ [a] = [Nat.pred (List.headI v')]
⊢ ∀ (m : ℕ), m < 0 → ¬f (m ::ᵥ v) = 0

tactic: simp only [List.headI_nil, List.headI_cons, exists_false, or_false_iff, Part.mem_some_iff,
  List.tail_cons, false_and_iff, Sum.inl.injEq] at this
state_before: case intro.mp.intro.intro.inl
n✝¹ : ℕ
f✝ : Vector ℕ n✝¹ →. ℕ
n✝ : ℕ
f : Vector ℕ (n✝ + 1) → ℕ
a✝ : Nat.Partrec' ↑f
cf : Code
v : Vector ℕ n✝
hf : ∀ (a : ℕ), eval cf (a :: ↑v) = Part.some [f (a ::ᵥ v)]
v' v₀ : List ℕ
n : ℕ
h2 :
  v' ∈
    PFun.fix
      (fun v =>
        Part.bind (eval cf v) fun y =>
          Part.some
            (if List.headI y = 0 then Sum.inl (Nat.succ (List.headI v) :: List.tail v)
            else Sum.inr (Nat.succ (List.headI v) :: List.tail v)))
      (n :: ↑v)
IH :
  ∀ (a'' : List ℕ),
    (Sum.inr a'' ∈
        Part.bind (eval cf (n :: ↑v)) fun y =>
          Part.some
            (if List.headI y = 0 then Sum.inl (Nat.succ (List.headI (n :: ↑v)) :: List.tail (n :: ↑v))
            else Sum.inr (Nat.succ (List.headI (n :: ↑v)) :: List.tail (n :: ↑v)))) →
      ∀ (n : ℕ),
        a'' = n :: ↑v →
          (∀ (m : ℕ), m < n → ¬f (m ::ᵥ v) = 0) →
            ∃ a, (f (a ::ᵥ v) = 0 ∧ ∀ {m : ℕ}, m < a → ¬f (m ::ᵥ v) = 0) ∧ [a] = [Nat.pred (List.headI v')]
hm : ∀ (m : ℕ), m < n → ¬f (m ::ᵥ v) = 0
h : List.headI [f (n ::ᵥ v)] = 0
this :
  Sum.inl v' ∈ Part.some (Sum.inl (Nat.succ (List.headI (n :: ↑v)) :: List.tail (n :: ↑v))) ∨
    ∃ a',
      Sum.inr a' ∈ Part.some (Sum.inl (Nat.succ (List.headI (n :: ↑v)) :: List.tail (n :: ↑v))) ∧
        v' ∈
          PFun.fix
            (fun v =>
              Part.bind (eval cf v) fun y =>
                Part.some
                  (if List.headI y = 0 then Sum.inl (Nat.succ (List.headI v) :: List.tail v)
                  else Sum.inr (Nat.succ (List.headI v) :: List.tail v)))
            a'
⊢ ∃ a, (f (a ::ᵥ v) = 0 ∧ ∀ {m : ℕ}, m < a → ¬f (m ::ᵥ v) = 0) ∧ [a] = [Nat.pred (List.headI v')]

tactic: subst this
state_before: case intro.mp.intro.intro.inl
n✝¹ : ℕ
f✝ : Vector ℕ n✝¹ →. ℕ
n✝ : ℕ
f : Vector ℕ (n✝ + 1) → ℕ
a✝ : Nat.Partrec' ↑f
cf : Code
v : Vector ℕ n✝
hf : ∀ (a : ℕ), eval cf (a :: ↑v) = Part.some [f (a ::ᵥ v)]
v' v₀ : List ℕ
n : ℕ
h2 :
  v' ∈
    PFun.fix
      (fun v =>
        Part.bind (eval cf v) fun y =>
          Part.some
            (if List.headI y = 0 then Sum.inl (Nat.succ (List.headI v) :: List.tail v)
            else Sum.inr (Nat.succ (List.headI v) :: List.tail v)))
      (n :: ↑v)
IH :
  ∀ (a'' : List ℕ),
    (Sum.inr a'' ∈
        Part.bind (eval cf (n :: ↑v)) fun y =>
          Part.some
            (if List.headI y = 0 then Sum.inl (Nat.succ (List.headI (n :: ↑v)) :: List.tail (n :: ↑v))
            else Sum.inr (Nat.succ (List.headI (n :: ↑v)) :: List.tail (n :: ↑v)))) →
      ∀ (n : ℕ),
        a'' = n :: ↑v →
          (∀ (m : ℕ), m < n → ¬f (m ::ᵥ v) = 0) →
            ∃ a, (f (a ::ᵥ v) = 0 ∧ ∀ {m : ℕ}, m < a → ¬f (m ::ᵥ v) = 0) ∧ [a] = [Nat.pred (List.headI v')]
hm : ∀ (m : ℕ), m < n → ¬f (m ::ᵥ v) = 0
h : List.headI [f (n ::ᵥ v)] = 0
this : v' = Nat.succ n :: ↑v
⊢ ∃ a, (f (a ::ᵥ v) = 0 ∧ ∀ {m : ℕ}, m < a → ¬f (m ::ᵥ v) = 0) ∧ [a] = [Nat.pred (List.headI v')]

tactic: exact ⟨_, ⟨h, @(hm)⟩, rfl⟩
state_before: case intro.mp.intro.intro.inl
n✝¹ : ℕ
f✝ : Vector ℕ n✝¹ →. ℕ
n✝ : ℕ
f : Vector ℕ (n✝ + 1) → ℕ
a✝ : Nat.Partrec' ↑f
cf : Code
v : Vector ℕ n✝
hf : ∀ (a : ℕ), eval cf (a :: ↑v) = Part.some [f (a ::ᵥ v)]
v₀ : List ℕ
n : ℕ
hm : ∀ (m : ℕ), m < n → ¬f (m ::ᵥ v) = 0
h : List.headI [f (n ::ᵥ v)] = 0
h2 :
  Nat.succ n :: ↑v ∈
    PFun.fix
      (fun v =>
        Part.bind (eval cf v) fun y =>
          Part.some
            (if List.headI y = 0 then Sum.inl (Nat.succ (List.headI v) :: List.tail v)
            else Sum.inr (Nat.succ (List.headI v) :: List.tail v)))
      (n :: ↑v)
IH :
  ∀ (a'' : List ℕ),
    (Sum.inr a'' ∈
        Part.bind (eval cf (n :: ↑v)) fun y =>
          Part.some
            (if List.headI y = 0 then Sum.inl (Nat.succ (List.headI (n :: ↑v)) :: List.tail (n :: ↑v))
            else Sum.inr (Nat.succ (List.headI (n :: ↑v)) :: List.tail (n :: ↑v)))) →
      ∀ (n_1 : ℕ),
        a'' = n_1 :: ↑v →
          (∀ (m : ℕ), m < n_1 → ¬f (m ::ᵥ v) = 0) →
            ∃ a,
              (f (a ::ᵥ v) = 0 ∧ ∀ {m : ℕ}, m < a → ¬f (m ::ᵥ v) = 0) ∧ [a] = [Nat.pred (List.headI (Nat.succ n :: ↑v))]
⊢ ∃ a, (f (a ::ᵥ v) = 0 ∧ ∀ {m : ℕ}, m < a → ¬f (m ::ᵥ v) = 0) ∧ [a] = [Nat.pred (List.headI (Nat.succ n :: ↑v))]

tactic: refine' IH (n.succ::v.val) (by simp_all) _ rfl fun m h' => _
state_before: case intro.mp.intro.intro.inr
n✝¹ : ℕ
f✝ : Vector ℕ n✝¹ →. ℕ
n✝ : ℕ
f : Vector ℕ (n✝ + 1) → ℕ
a✝ : Nat.Partrec' ↑f
cf : Code
v : Vector ℕ n✝
hf : ∀ (a : ℕ), eval cf (a :: ↑v) = Part.some [f (a ::ᵥ v)]
v' v₀ : List ℕ
n : ℕ
h2 :
  v' ∈
    PFun.fix
      (fun v =>
        Part.bind (eval cf v) fun y =>
          Part.some
            (if List.headI y = 0 then Sum.inl (Nat.succ (List.headI v) :: List.tail v)
            else Sum.inr (Nat.succ (List.headI v) :: List.tail v)))
      (n :: ↑v)
IH :
  ∀ (a'' : List ℕ),
    (Sum.inr a'' ∈
        Part.bind (eval cf (n :: ↑v)) fun y =>
          Part.some
            (if List.headI y = 0 then Sum.inl (Nat.succ (List.headI (n :: ↑v)) :: List.tail (n :: ↑v))
            else Sum.inr (Nat.succ (List.headI (n :: ↑v)) :: List.tail (n :: ↑v)))) →
      ∀ (n : ℕ),
        a'' = n :: ↑v →
          (∀ (m : ℕ), m < n → ¬f (m ::ᵥ v) = 0) →
            ∃ a, (f (a ::ᵥ v) = 0 ∧ ∀ {m : ℕ}, m < a → ¬f (m ::ᵥ v) = 0) ∧ [a] = [Nat.pred (List.headI v')]
hm : ∀ (m : ℕ), m < n → ¬f (m ::ᵥ v) = 0
h : ¬List.headI [f (n ::ᵥ v)] = 0
this :
  Sum.inl v' ∈ Part.some (Sum.inr (Nat.succ (List.headI (n :: ↑v)) :: List.tail (n :: ↑v))) ∨
    ∃ a',
      Sum.inr a' ∈ Part.some (Sum.inr (Nat.succ (List.headI (n :: ↑v)) :: List.tail (n :: ↑v))) ∧
        v' ∈
          PFun.fix
            (fun v =>
              Part.bind (eval cf v) fun y =>
                Part.some
                  (if List.headI y = 0 then Sum.inl (Nat.succ (List.headI v) :: List.tail v)
                  else Sum.inr (Nat.succ (List.headI v) :: List.tail v)))
            a'
⊢ ∃ a, (f (a ::ᵥ v) = 0 ∧ ∀ {m : ℕ}, m < a → ¬f (m ::ᵥ v) = 0) ∧ [a] = [Nat.pred (List.headI v')]

tactic: obtain h | rfl := Nat.lt_succ_iff_lt_or_eq.1 h'
state_before: case intro.mp.intro.intro.inr
n✝¹ : ℕ
f✝ : Vector ℕ n✝¹ →. ℕ
n✝ : ℕ
f : Vector ℕ (n✝ + 1) → ℕ
a✝ : Nat.Partrec' ↑f
cf : Code
v : Vector ℕ n✝
hf : ∀ (a : ℕ), eval cf (a :: ↑v) = Part.some [f (a ::ᵥ v)]
v' v₀ : List ℕ
n : ℕ
h2 :
  v' ∈
    PFun.fix
      (fun v =>
        Part.bind (eval cf v) fun y =>
          Part.some
            (if List.headI y = 0 then Sum.inl (Nat.succ (List.headI v) :: List.tail v)
            else Sum.inr (Nat.succ (List.headI v) :: List.tail v)))
      (n :: ↑v)
IH :
  ∀ (a'' : List ℕ),
    (Sum.inr a'' ∈
        Part.bind (eval cf (n :: ↑v)) fun y =>
          Part.some
            (if List.headI y = 0 then Sum.inl (Nat.succ (List.headI (n :: ↑v)) :: List.tail (n :: ↑v))
            else Sum.inr (Nat.succ (List.headI (n :: ↑v)) :: List.tail (n :: ↑v)))) →
      ∀ (n : ℕ),
        a'' = n :: ↑v →
          (∀ (m : ℕ), m < n → ¬f (m ::ᵥ v) = 0) →
            ∃ a, (f (a ::ᵥ v) = 0 ∧ ∀ {m : ℕ}, m < a → ¬f (m ::ᵥ v) = 0) ∧ [a] = [Nat.pred (List.headI v')]
hm : ∀ (m : ℕ), m < n → ¬f (m ::ᵥ v) = 0
h : ¬List.headI [f (n ::ᵥ v)] = 0
this :
  Sum.inl v' ∈ Part.some (Sum.inr (Nat.succ (List.headI (n :: ↑v)) :: List.tail (n :: ↑v))) ∨
    ∃ a',
      Sum.inr a' ∈ Part.some (Sum.inr (Nat.succ (List.headI (n :: ↑v)) :: List.tail (n :: ↑v))) ∧
        v' ∈
          PFun.fix
            (fun v =>
              Part.bind (eval cf v) fun y =>
                Part.some
                  (if List.headI y = 0 then Sum.inl (Nat.succ (List.headI v) :: List.tail v)
                  else Sum.inr (Nat.succ (List.headI v) :: List.tail v)))
            a'
m : ℕ
h' : m < Nat.succ n
⊢ ¬f (m ::ᵥ v) = 0

tactic: exacts [hm _ h, h]
state_before: case intro.mp.intro.intro.inr.inl
n✝¹ : ℕ
f✝ : Vector ℕ n✝¹ →. ℕ
n✝ : ℕ
f : Vector ℕ (n✝ + 1) → ℕ
a✝ : Nat.Partrec' ↑f
cf : Code
v : Vector ℕ n✝
hf : ∀ (a : ℕ), eval cf (a :: ↑v) = Part.some [f (a ::ᵥ v)]
v' v₀ : List ℕ
n : ℕ
h2 :
  v' ∈
    PFun.fix
      (fun v =>
        Part.bind (eval cf v) fun y =>
          Part.some
            (if List.headI y = 0 then Sum.inl (Nat.succ (List.headI v) :: List.tail v)
            else Sum.inr (Nat.succ (List.headI v) :: List.tail v)))
      (n :: ↑v)
IH :
  ∀ (a'' : List ℕ),
    (Sum.inr a'' ∈
        Part.bind (eval cf (n :: ↑v)) fun y =>
          Part.some
            (if List.headI y = 0 then Sum.inl (Nat.succ (List.headI (n :: ↑v)) :: List.tail (n :: ↑v))
            else Sum.inr (Nat.succ (List.headI (n :: ↑v)) :: List.tail (n :: ↑v)))) →
      ∀ (n : ℕ),
        a'' = n :: ↑v →
          (∀ (m : ℕ), m < n → ¬f (m ::ᵥ v) = 0) →
            ∃ a, (f (a ::ᵥ v) = 0 ∧ ∀ {m : ℕ}, m < a → ¬f (m ::ᵥ v) = 0) ∧ [a] = [Nat.pred (List.headI v')]
hm : ∀ (m : ℕ), m < n → ¬f (m ::ᵥ v) = 0
h✝ : ¬List.headI [f (n ::ᵥ v)] = 0
this :
  Sum.inl v' ∈ Part.some (Sum.inr (Nat.succ (List.headI (n :: ↑v)) :: List.tail (n :: ↑v))) ∨
    ∃ a',
      Sum.inr a' ∈ Part.some (Sum.inr (Nat.succ (List.headI (n :: ↑v)) :: List.tail (n :: ↑v))) ∧
        v' ∈
          PFun.fix
            (fun v =>
              Part.bind (eval cf v) fun y =>
                Part.some
                  (if List.headI y = 0 then Sum.inl (Nat.succ (List.headI v) :: List.tail v)
                  else Sum.inr (Nat.succ (List.headI v) :: List.tail v)))
            a'
m : ℕ
h' : m < Nat.succ n
h : m < n
⊢ ¬f (m ::ᵥ v) = 0

case intro.mp.intro.intro.inr.inr
n✝ : ℕ
f✝ : Vector ℕ n✝ →. ℕ
n : ℕ
f : Vector ℕ (n + 1) → ℕ
a✝ : Nat.Partrec' ↑f
cf : Code
v : Vector ℕ n
hf : ∀ (a : ℕ), eval cf (a :: ↑v) = Part.some [f (a ::ᵥ v)]
v' v₀ : List ℕ
m : ℕ
h2 :
  v' ∈
    PFun.fix
      (fun v =>
        Part.bind (eval cf v) fun y =>
          Part.some
            (if List.headI y = 0 then Sum.inl (Nat.succ (List.headI v) :: List.tail v)
            else Sum.inr (Nat.succ (List.headI v) :: List.tail v)))
      (m :: ↑v)
IH :
  ∀ (a'' : List ℕ),
    (Sum.inr a'' ∈
        Part.bind (eval cf (m :: ↑v)) fun y =>
          Part.some
            (if List.headI y = 0 then Sum.inl (Nat.succ (List.headI (m :: ↑v)) :: List.tail (m :: ↑v))
            else Sum.inr (Nat.succ (List.headI (m :: ↑v)) :: List.tail (m :: ↑v)))) →
      ∀ (n_1 : ℕ),
        a'' = n_1 :: ↑v →
          (∀ (m : ℕ), m < n_1 → ¬f (m ::ᵥ v) = 0) →
            ∃ a, (f (a ::ᵥ v) = 0 ∧ ∀ {m : ℕ}, m < a → ¬f (m ::ᵥ v) = 0) ∧ [a] = [Nat.pred (List.headI v')]
hm : ∀ (m_1 : ℕ), m_1 < m → ¬f (m_1 ::ᵥ v) = 0
h : ¬List.headI [f (m ::ᵥ v)] = 0
this :
  Sum.inl v' ∈ Part.some (Sum.inr (Nat.succ (List.headI (m :: ↑v)) :: List.tail (m :: ↑v))) ∨
    ∃ a',
      Sum.inr a' ∈ Part.some (Sum.inr (Nat.succ (List.headI (m :: ↑v)) :: List.tail (m :: ↑v))) ∧
        v' ∈
          PFun.fix
            (fun v =>
              Part.bind (eval cf v) fun y =>
                Part.some
                  (if List.headI y = 0 then Sum.inl (Nat.succ (List.headI v) :: List.tail v)
                  else Sum.inr (Nat.succ (List.headI v) :: List.tail v)))
            a'
h' : m < Nat.succ m
⊢ ¬f (m ::ᵥ v) = 0

tactic: simp_all
state_before: n✝¹ : ℕ
f✝ : Vector ℕ n✝¹ →. ℕ
n✝ : ℕ
f : Vector ℕ (n✝ + 1) → ℕ
a✝ : Nat.Partrec' ↑f
cf : Code
v : Vector ℕ n✝
hf : ∀ (a : ℕ), eval cf (a :: ↑v) = Part.some [f (a ::ᵥ v)]
v' v₀ : List ℕ
n : ℕ
h2 :
  v' ∈
    PFun.fix
      (fun v =>
        Part.bind (eval cf v) fun y =>
          Part.some
            (if List.headI y = 0 then Sum.inl (Nat.succ (List.headI v) :: List.tail v)
            else Sum.inr (Nat.succ (List.headI v) :: List.tail v)))
      (n :: ↑v)
IH :
  ∀ (a'' : List ℕ),
    (Sum.inr a'' ∈
        Part.bind (eval cf (n :: ↑v)) fun y =>
          Part.some
            (if List.headI y = 0 then Sum.inl (Nat.succ (List.headI (n :: ↑v)) :: List.tail (n :: ↑v))
            else Sum.inr (Nat.succ (List.headI (n :: ↑v)) :: List.tail (n :: ↑v)))) →
      ∀ (n : ℕ),
        a'' = n :: ↑v →
          (∀ (m : ℕ), m < n → ¬f (m ::ᵥ v) = 0) →
            ∃ a, (f (a ::ᵥ v) = 0 ∧ ∀ {m : ℕ}, m < a → ¬f (m ::ᵥ v) = 0) ∧ [a] = [Nat.pred (List.headI v')]
hm : ∀ (m : ℕ), m < n → ¬f (m ::ᵥ v) = 0
h : ¬List.headI [f (n ::ᵥ v)] = 0
this :
  Sum.inl v' ∈ Part.some (Sum.inr (Nat.succ (List.headI (n :: ↑v)) :: List.tail (n :: ↑v))) ∨
    ∃ a',
      Sum.inr a' ∈ Part.some (Sum.inr (Nat.succ (List.headI (n :: ↑v)) :: List.tail (n :: ↑v))) ∧
        v' ∈
          PFun.fix
            (fun v =>
              Part.bind (eval cf v) fun y =>
                Part.some
                  (if List.headI y = 0 then Sum.inl (Nat.succ (List.headI v) :: List.tail v)
                  else Sum.inr (Nat.succ (List.headI v) :: List.tail v)))
            a'
⊢ Sum.inr (Nat.succ n :: ↑v) ∈
    Part.bind (eval cf (n :: ↑v)) fun y =>
      Part.some
        (if List.headI y = 0 then Sum.inl (Nat.succ (List.headI (n :: ↑v)) :: List.tail (n :: ↑v))
        else Sum.inr (Nat.succ (List.headI (n :: ↑v)) :: List.tail (n :: ↑v)))

tactic: rintro ⟨n, ⟨hn, hm⟩, rfl⟩
state_before: case intro.mpr
n✝ : ℕ
f✝ : Vector ℕ n✝ →. ℕ
n : ℕ
f : Vector ℕ (n + 1) → ℕ
a✝ : Nat.Partrec' ↑f
cf : Code
v : Vector ℕ n
hf : ∀ (a : ℕ), eval cf (a :: ↑v) = Part.some [f (a ::ᵥ v)]
x : List ℕ
⊢ (∃ a, (f (a ::ᵥ v) = 0 ∧ ∀ {m : ℕ}, m < a → ¬f (m ::ᵥ v) = 0) ∧ pure a = x) →
    ∃ a,
      a ∈
          PFun.fix
            (fun v =>
              Part.bind (eval cf v) fun y =>
                Part.some
                  (if List.headI y = 0 then Sum.inl (Nat.succ (List.headI v) :: List.tail v)
                  else Sum.inr (Nat.succ (List.headI v) :: List.tail v)))
            (0 :: ↑v) ∧
        x = [Nat.pred (List.headI a)]

tactic: refine' ⟨n.succ::v.1, _, rfl⟩
state_before: case intro.mpr.intro.intro.intro
n✝¹ : ℕ
f✝ : Vector ℕ n✝¹ →. ℕ
n✝ : ℕ
f : Vector ℕ (n✝ + 1) → ℕ
a✝ : Nat.Partrec' ↑f
cf : Code
v : Vector ℕ n✝
hf : ∀ (a : ℕ), eval cf (a :: ↑v) = Part.some [f (a ::ᵥ v)]
n : ℕ
hn : f (n ::ᵥ v) = 0
hm : ∀ {m : ℕ}, m < n → ¬f (m ::ᵥ v) = 0
⊢ ∃ a,
    a ∈
        PFun.fix
          (fun v =>
            Part.bind (eval cf v) fun y =>
              Part.some
                (if List.headI y = 0 then Sum.inl (Nat.succ (List.headI v) :: List.tail v)
                else Sum.inr (Nat.succ (List.headI v) :: List.tail v)))
          (0 :: ↑v) ∧
      pure n = [Nat.pred (List.headI a)]

tactic: have : (n.succ::v.1 : List ℕ) ∈
  PFun.fix (fun v =>
    (cf.eval v).bind fun y =>
      Part.some <|
        if y.headI = 0 then Sum.inl (v.headI.succ :: v.tail)
          else Sum.inr (v.headI.succ :: v.tail))
      (n::v.val) :=
  PFun.mem_fix_iff.2 (Or.inl (by simp [hf, hn]))
state_before: case intro.mpr.intro.intro.intro
n✝¹ : ℕ
f✝ : Vector ℕ n✝¹ →. ℕ
n✝ : ℕ
f : Vector ℕ (n✝ + 1) → ℕ
a✝ : Nat.Partrec' ↑f
cf : Code
v : Vector ℕ n✝
hf : ∀ (a : ℕ), eval cf (a :: ↑v) = Part.some [f (a ::ᵥ v)]
n : ℕ
hn : f (n ::ᵥ v) = 0
hm : ∀ {m : ℕ}, m < n → ¬f (m ::ᵥ v) = 0
⊢ Nat.succ n :: ↑v ∈
    PFun.fix
      (fun v =>
        Part.bind (eval cf v) fun y =>
          Part.some
            (if List.headI y = 0 then Sum.inl (Nat.succ (List.headI v) :: List.tail v)
            else Sum.inr (Nat.succ (List.headI v) :: List.tail v)))
      (0 :: ↑v)

tactic: generalize (n.succ :: v.1 : List ℕ) = w at this ⊢
state_before: case intro.mpr.intro.intro.intro
n✝¹ : ℕ
f✝ : Vector ℕ n✝¹ →. ℕ
n✝ : ℕ
f : Vector ℕ (n✝ + 1) → ℕ
a✝ : Nat.Partrec' ↑f
cf : Code
v : Vector ℕ n✝
hf : ∀ (a : ℕ), eval cf (a :: ↑v) = Part.some [f (a ::ᵥ v)]
n : ℕ
hn : f (n ::ᵥ v) = 0
hm : ∀ {m : ℕ}, m < n → ¬f (m ::ᵥ v) = 0
this :
  Nat.succ n :: ↑v ∈
    PFun.fix
      (fun v =>
        Part.bind (eval cf v) fun y =>
          Part.some
            (if List.headI y = 0 then Sum.inl (Nat.succ (List.headI v) :: List.tail v)
            else Sum.inr (Nat.succ (List.headI v) :: List.tail v)))
      (n :: ↑v)
⊢ Nat.succ n :: ↑v ∈
    PFun.fix
      (fun v =>
        Part.bind (eval cf v) fun y =>
          Part.some
            (if List.headI y = 0 then Sum.inl (Nat.succ (List.headI v) :: List.tail v)
            else Sum.inr (Nat.succ (List.headI v) :: List.tail v)))
      (0 :: ↑v)

tactic: clear hn
state_before: case intro.mpr.intro.intro.intro
n✝¹ : ℕ
f✝ : Vector ℕ n✝¹ →. ℕ
n✝ : ℕ
f : Vector ℕ (n✝ + 1) → ℕ
a✝ : Nat.Partrec' ↑f
cf : Code
v : Vector ℕ n✝
hf : ∀ (a : ℕ), eval cf (a :: ↑v) = Part.some [f (a ::ᵥ v)]
n : ℕ
hn : f (n ::ᵥ v) = 0
hm : ∀ {m : ℕ}, m < n → ¬f (m ::ᵥ v) = 0
w : List ℕ
this :
  w ∈
    PFun.fix
      (fun v =>
        Part.bind (eval cf v) fun y =>
          Part.some
            (if List.headI y = 0 then Sum.inl (Nat.succ (List.headI v) :: List.tail v)
            else Sum.inr (Nat.succ (List.headI v) :: List.tail v)))
      (n :: ↑v)
⊢ w ∈
    PFun.fix
      (fun v =>
        Part.bind (eval cf v) fun y =>
          Part.some
            (if List.headI y = 0 then Sum.inl (Nat.succ (List.headI v) :: List.tail v)
            else Sum.inr (Nat.succ (List.headI v) :: List.tail v)))
      (0 :: ↑v)

tactic: induction' n with n IH
state_before: case intro.mpr.intro.intro.intro
n✝¹ : ℕ
f✝ : Vector ℕ n✝¹ →. ℕ
n✝ : ℕ
f : Vector ℕ (n✝ + 1) → ℕ
a✝ : Nat.Partrec' ↑f
cf : Code
v : Vector ℕ n✝
hf : ∀ (a : ℕ), eval cf (a :: ↑v) = Part.some [f (a ::ᵥ v)]
n : ℕ
hm : ∀ {m : ℕ}, m < n → ¬f (m ::ᵥ v) = 0
w : List ℕ
this :
  w ∈
    PFun.fix
      (fun v =>
        Part.bind (eval cf v) fun y =>
          Part.some
            (if List.headI y = 0 then Sum.inl (Nat.succ (List.headI v) :: List.tail v)
            else Sum.inr (Nat.succ (List.headI v) :: List.tail v)))
      (n :: ↑v)
⊢ w ∈
    PFun.fix
      (fun v =>
        Part.bind (eval cf v) fun y =>
          Part.some
            (if List.headI y = 0 then Sum.inl (Nat.succ (List.headI v) :: List.tail v)
            else Sum.inr (Nat.succ (List.headI v) :: List.tail v)))
      (0 :: ↑v)

tactic: refine' IH (fun {m} h' => hm (Nat.lt_succ_of_lt h'))
  (PFun.mem_fix_iff.2 (Or.inr ⟨_, _, this⟩))
state_before: case intro.mpr.intro.intro.intro.succ
n✝² : ℕ
f✝ : Vector ℕ n✝² →. ℕ
n✝¹ : ℕ
f : Vector ℕ (n✝¹ + 1) → ℕ
a✝ : Nat.Partrec' ↑f
cf : Code
v : Vector ℕ n✝¹
hf : ∀ (a : ℕ), eval cf (a :: ↑v) = Part.some [f (a ::ᵥ v)]
n✝ : ℕ
hm✝ : ∀ {m : ℕ}, m < n✝ → ¬f (m ::ᵥ v) = 0
w : List ℕ
this✝ :
  w ∈
    PFun.fix
      (fun v =>
        Part.bind (eval cf v) fun y =>
          Part.some
            (if List.headI y = 0 then Sum.inl (Nat.succ (List.headI v) :: List.tail v)
            else Sum.inr (Nat.succ (List.headI v) :: List.tail v)))
      (n✝ :: ↑v)
n : ℕ
IH :
  (∀ {m : ℕ}, m < n → ¬f (m ::ᵥ v) = 0) →
    w ∈
        PFun.fix
          (fun v =>
            Part.bind (eval cf v) fun y =>
              Part.some
                (if List.headI y = 0 then Sum.inl (Nat.succ (List.headI v) :: List.tail v)
                else Sum.inr (Nat.succ (List.headI v) :: List.tail v)))
          (n :: ↑v) →
      w ∈
        PFun.fix
          (fun v =>
            Part.bind (eval cf v) fun y =>
              Part.some
                (if List.headI y = 0 then Sum.inl (Nat.succ (List.headI v) :: List.tail v)
                else Sum.inr (Nat.succ (List.headI v) :: List.tail v)))
          (0 :: ↑v)
hm : ∀ {m : ℕ}, m < Nat.succ n → ¬f (m ::ᵥ v) = 0
this :
  w ∈
    PFun.fix
      (fun v =>
        Part.bind (eval cf v) fun y =>
          Part.some
            (if List.headI y = 0 then Sum.inl (Nat.succ (List.headI v) :: List.tail v)
            else Sum.inr (Nat.succ (List.headI v) :: List.tail v)))
      (Nat.succ n :: ↑v)
⊢ w ∈
    PFun.fix
      (fun v =>
        Part.bind (eval cf v) fun y =>
          Part.some
            (if List.headI y = 0 then Sum.inl (Nat.succ (List.headI v) :: List.tail v)
            else Sum.inr (Nat.succ (List.headI v) :: List.tail v)))
      (0 :: ↑v)

tactic: simp only [hf, hm n.lt_succ_self, Part.bind_some, List.headI, eq_self_iff_true, if_false,
  Part.mem_some_iff, and_self_iff, List.tail_cons]
state_before: case intro.mpr.intro.intro.intro.succ
n✝² : ℕ
f✝ : Vector ℕ n✝² →. ℕ
n✝¹ : ℕ
f : Vector ℕ (n✝¹ + 1) → ℕ
a✝ : Nat.Partrec' ↑f
cf : Code
v : Vector ℕ n✝¹
hf : ∀ (a : ℕ), eval cf (a :: ↑v) = Part.some [f (a ::ᵥ v)]
n✝ : ℕ
hm✝ : ∀ {m : ℕ}, m < n✝ → ¬f (m ::ᵥ v) = 0
w : List ℕ
this✝ :
  w ∈
    PFun.fix
      (fun v =>
        Part.bind (eval cf v) fun y =>
          Part.some
            (if List.headI y = 0 then Sum.inl (Nat.succ (List.headI v) :: List.tail v)
            else Sum.inr (Nat.succ (List.headI v) :: List.tail v)))
      (n✝ :: ↑v)
n : ℕ
IH :
  (∀ {m : ℕ}, m < n → ¬f (m ::ᵥ v) = 0) →
    w ∈
        PFun.fix
          (fun v =>
            Part.bind (eval cf v) fun y =>
              Part.some
                (if List.headI y = 0 then Sum.inl (Nat.succ (List.headI v) :: List.tail v)
                else Sum.inr (Nat.succ (List.headI v) :: List.tail v)))
          (n :: ↑v) →
      w ∈
        PFun.fix
          (fun v =>
            Part.bind (eval cf v) fun y =>
              Part.some
                (if List.headI y = 0 then Sum.inl (Nat.succ (List.headI v) :: List.tail v)
                else Sum.inr (Nat.succ (List.headI v) :: List.tail v)))
          (0 :: ↑v)
hm : ∀ {m : ℕ}, m < Nat.succ n → ¬f (m ::ᵥ v) = 0
this :
  w ∈
    PFun.fix
      (fun v =>
        Part.bind (eval cf v) fun y =>
          Part.some
            (if List.headI y = 0 then Sum.inl (Nat.succ (List.headI v) :: List.tail v)
            else Sum.inr (Nat.succ (List.headI v) :: List.tail v)))
      (Nat.succ n :: ↑v)
⊢ Sum.inr (Nat.succ n :: ↑v) ∈
    Part.bind (eval cf (n :: ↑v)) fun y =>
      Part.some
        (if List.headI y = 0 then Sum.inl (Nat.succ (List.headI (n :: ↑v)) :: List.tail (n :: ↑v))
        else Sum.inr (Nat.succ (List.headI (n :: ↑v)) :: List.tail (n :: ↑v)))

tactic: simp [hf, hn]
state_before: n✝¹ : ℕ
f✝ : Vector ℕ n✝¹ →. ℕ
n✝ : ℕ
f : Vector ℕ (n✝ + 1) → ℕ
a✝ : Nat.Partrec' ↑f
cf : Code
v : Vector ℕ n✝
hf : ∀ (a : ℕ), eval cf (a :: ↑v) = Part.some [f (a ::ᵥ v)]
n : ℕ
hn : f (n ::ᵥ v) = 0
hm : ∀ {m : ℕ}, m < n → ¬f (m ::ᵥ v) = 0
⊢ Sum.inl (Nat.succ n :: ↑v) ∈
    Part.bind (eval cf (n :: ↑v)) fun y =>
      Part.some
        (if List.headI y = 0 then Sum.inl (Nat.succ (List.headI (n :: ↑v)) :: List.tail (n :: ↑v))
        else Sum.inr (Nat.succ (List.headI (n :: ↑v)) :: List.tail (n :: ↑v)))

tactic: exact this
state_before: case intro.mpr.intro.intro.intro.zero
n✝¹ : ℕ
f✝ : Vector ℕ n✝¹ →. ℕ
n✝ : ℕ
f : Vector ℕ (n✝ + 1) → ℕ
a✝ : Nat.Partrec' ↑f
cf : Code
v : Vector ℕ n✝
hf : ∀ (a : ℕ), eval cf (a :: ↑v) = Part.some [f (a ::ᵥ v)]
n : ℕ
hm✝ : ∀ {m : ℕ}, m < n → ¬f (m ::ᵥ v) = 0
w : List ℕ
this✝ :
  w ∈
    PFun.fix
      (fun v =>
        Part.bind (eval cf v) fun y =>
          Part.some
            (if List.headI y = 0 then Sum.inl (Nat.succ (List.headI v) :: List.tail v)
            else Sum.inr (Nat.succ (List.headI v) :: List.tail v)))
      (n :: ↑v)
hm : ∀ {m : ℕ}, m < Nat.zero → ¬f (m ::ᵥ v) = 0
this :
  w ∈
    PFun.fix
      (fun v =>
        Part.bind (eval cf v) fun y =>
          Part.some
            (if List.headI y = 0 then Sum.inl (Nat.succ (List.headI v) :: List.tail v)
            else Sum.inr (Nat.succ (List.headI v) :: List.tail v)))
      (Nat.zero :: ↑v)
⊢ w ∈
    PFun.fix
      (fun v =>
        Part.bind (eval cf v) fun y =>
          Part.some
            (if List.headI y = 0 then Sum.inl (Nat.succ (List.headI v) :: List.tail v)
            else Sum.inr (Nat.succ (List.headI v) :: List.tail v)))
      (0 :: ↑v)