l3lab/ntp-mathlib huggingface dataset:
theorem exists_code.comp {m n} {f : Vector ℕ n →. ℕ} {g : Fin n → Vector ℕ m →. ℕ}
    (hf : ∃ c : Code, ∀ v : Vector ℕ n, c.eval v.1 = pure <$> f v)
    (hg : ∀ i, ∃ c : Code, ∀ v : Vector ℕ m, c.eval v.1 = pure <$> g i v) :
    ∃ c : Code, ∀ v : Vector ℕ m, c.eval v.1 = pure <$> ((Vector.mOfFn fun i => g i v) >>= f) := by
  rsuffices ⟨cg, hg⟩ :
    ∃ c : Code, ∀ v : Vector ℕ m, c.eval v.1 = Subtype.val <$> Vector.mOfFn fun i => g i v
  · obtain ⟨cf, hf⟩ := hf
    exact
      ⟨cf.comp cg, fun v => by
        simp [hg, hf, map_bind, seq_bind_eq, Function.comp]
        rfl⟩
  clear hf f; induction' n with n IH
  · exact ⟨nil, fun v => by simp [Vector.mOfFn, Bind.bind]; rfl⟩
  · obtain ⟨cg, hg₁⟩ := hg 0
    obtain ⟨cl, hl⟩ := IH fun i => hg i.succ
    exact
      ⟨cons cg cl, fun v => by
        simp [Vector.mOfFn, hg₁, map_bind, seq_bind_eq, bind_assoc, (· ∘ ·), hl]
        

Proof state:
m n : ℕ
IH :
  ∀ {g : Fin n → Vector ℕ m →. ℕ},
    (∀ (i : Fin n), ∃ c, ∀ (v : Vector ℕ m), eval c ↑v = pure <$> g i v) →
      ∃ c, ∀ (v : Vector ℕ m), eval c ↑v = Subtype.val <$> Vector.mOfFn fun i => g i v
g : Fin (Nat.succ n) → Vector ℕ m →. ℕ
hg : ∀ (i : Fin (Nat.succ n)), ∃ c, ∀ (v : Vector ℕ m), eval c ↑v = pure <$> g i v
cg : Code
hg₁ : ∀ (v : Vector ℕ m), eval cg ↑v = pure <$> g 0 v
cl : Code
hl : ∀ (v : Vector ℕ m), eval cl ↑v = Subtype.val <$> Vector.mOfFn fun i => g (Fin.succ i) v
v : Vector ℕ m
⊢ (do
      let x ← g 0 v
      let x_1 ← Vector.mOfFn fun i => g (Fin.succ i) v
      Part.some (List.headI (pure x) :: ↑x_1)) =
    do
    let a ← g 0 v
    let a_1 ← Vector.mOfFn fun i => g (Fin.succ i) v
    Subtype.val <$> Part.some (a ::ᵥ a_1)

Next tactic:
rfl
theorem exists_code {n} {f : Vector ℕ n →. ℕ} (hf : Nat.Partrec' f) :
    ∃ c : Code, ∀ v : Vector ℕ n, c.eval v.1 = pure <$> f v := by
  

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

Next tactic:
induction' hf with n f hf
theorem exists_code {n} {f : Vector ℕ n →. ℕ} (hf : Nat.Partrec' f) :
    ∃ c : Code, ∀ v : Vector ℕ n, c.eval v.1 = pure <$> f v := by
  induction' hf with n f hf
  

Proof state:
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

Next tactic:
induction hf
theorem exists_code {n} {f : Vector ℕ n →. ℕ} (hf : Nat.Partrec' f) :
    ∃ c : Code, ∀ v : Vector ℕ n, c.eval v.1 = pure <$> f v := by
  induction' hf with n f hf
  induction hf
  

Proof state:
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

Next tactic:
case prim.zero => exact ⟨zero', fun ⟨[], _⟩ => rfl⟩
theorem exists_code {n} {f : Vector ℕ n →. ℕ} (hf : Nat.Partrec' f) :
    ∃ c : Code, ∀ v : Vector ℕ n, c.eval v.1 = pure <$> f v := by
  induction' hf with n f hf
  induction hf
  

Proof state:
n✝ : ℕ
f✝ : Vector ℕ n✝ →. ℕ
n : ℕ
f : Vector ℕ n → ℕ
⊢ ∃ c, ∀ (v : Vector ℕ 0), eval c ↑v = pure <$> (↑fun x => 0) v

Next tactic:
case prim.zero => exact ⟨zero', fun ⟨[], _⟩ => rfl⟩
theorem exists_code {n} {f : Vector ℕ n →. ℕ} (hf : Nat.Partrec' f) :
    ∃ c : Code, ∀ v : Vector ℕ n, c.eval v.1 = pure <$> f v := by
  induction' hf with n f hf
  induction hf
  case prim.zero => 

Proof state:
n✝ : ℕ
f✝ : Vector ℕ n✝ →. ℕ
n : ℕ
f : Vector ℕ n → ℕ
⊢ ∃ c, ∀ (v : Vector ℕ 0), eval c ↑v = pure <$> (↑fun x => 0) v

Next tactic:
exact ⟨zero', fun ⟨[], _⟩ => rfl⟩
theorem exists_code {n} {f : Vector ℕ n →. ℕ} (hf : Nat.Partrec' f) :
    ∃ c : Code, ∀ v : Vector ℕ n, c.eval v.1 = pure <$> f v := by
  induction' hf with n f hf
  induction hf
  case prim.zero => exact ⟨zero', fun ⟨[], _⟩ => rfl⟩
  

Proof state:
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

Next tactic:
case prim.succ => exact ⟨succ, fun ⟨[v], _⟩ => rfl⟩
theorem exists_code {n} {f : Vector ℕ n →. ℕ} (hf : Nat.Partrec' f) :
    ∃ c : Code, ∀ v : Vector ℕ n, c.eval v.1 = pure <$> f v := by
  induction' hf with n f hf
  induction hf
  case prim.zero => exact ⟨zero', fun ⟨[], _⟩ => rfl⟩
  

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

Next tactic:
case prim.succ => exact ⟨succ, fun ⟨[v], _⟩ => rfl⟩
theorem exists_code {n} {f : Vector ℕ n →. ℕ} (hf : Nat.Partrec' f) :
    ∃ c : Code, ∀ v : Vector ℕ n, c.eval v.1 = pure <$> f v := by
  induction' hf with n f hf
  induction hf
  case prim.zero => exact ⟨zero', fun ⟨[], _⟩ => rfl⟩
  case prim.succ => 

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

Next tactic:
exact ⟨succ, fun ⟨[v], _⟩ => rfl⟩
theorem exists_code {n} {f : Vector ℕ n →. ℕ} (hf : Nat.Partrec' f) :
    ∃ c : Code, ∀ v : Vector ℕ n, c.eval v.1 = pure <$> f v := by
  induction' hf with n f hf
  induction hf
  case prim.zero => exact ⟨zero', fun ⟨[], _⟩ => rfl⟩
  case prim.succ => exact ⟨succ, fun ⟨[v], _⟩ => rfl⟩
  

Proof state:
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

Next tactic:
case prim.get n i =>
    refine' Fin.succRec (fun n => _) (fun n i IH => _) i
    · exact ⟨head, fun ⟨List.cons a as, _⟩ => by simp [Bind.bind]; rfl⟩
    · obtain ⟨c, h⟩ := IH
      exact ⟨c.comp tail, fun v => by simpa [← Vector.get_tail, Bind.bind] using h v.tail⟩
theorem exists_code {n} {f : Vector ℕ n →. ℕ} (hf : Nat.Partrec' f) :
    ∃ c : Code, ∀ v : Vector ℕ n, c.eval v.1 = pure <$> f v := by
  induction' hf with n f hf
  induction hf
  case prim.zero => exact ⟨zero', fun ⟨[], _⟩ => rfl⟩
  case prim.succ => exact ⟨succ, fun ⟨[v], _⟩ => rfl⟩
  

Proof state:
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

Next tactic:
case prim.get n i =>
    refine' Fin.succRec (fun n => _) (fun n i IH => _) i
    · exact ⟨head, fun ⟨List.cons a as, _⟩ => by simp [Bind.bind]; rfl⟩
    · obtain ⟨c, h⟩ := IH
      exact ⟨c.comp tail, fun v => by simpa [← Vector.get_tail, Bind.bind] using h v.tail⟩
theorem exists_code {n} {f : Vector ℕ n →. ℕ} (hf : Nat.Partrec' f) :
    ∃ c : Code, ∀ v : Vector ℕ n, c.eval v.1 = pure <$> f v := by
  induction' hf with n f hf
  induction hf
  case prim.zero => exact ⟨zero', fun ⟨[], _⟩ => rfl⟩
  case prim.succ => exact ⟨succ, fun ⟨[v], _⟩ => rfl⟩
  case prim.get n i =>
    

Proof state:
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

Next tactic:
refine' Fin.succRec (fun n => _) (fun n i IH => _) i
theorem exists_code {n} {f : Vector ℕ n →. ℕ} (hf : Nat.Partrec' f) :
    ∃ c : Code, ∀ v : Vector ℕ n, c.eval v.1 = pure <$> f v := by
  induction' hf with n f hf
  induction hf
  case prim.zero => exact ⟨zero', fun ⟨[], _⟩ => rfl⟩
  case prim.succ => exact ⟨succ, fun ⟨[v], _⟩ => rfl⟩
  case prim.get n i =>
    refine' Fin.succRec (fun n => _) (fun n i IH => _) i
    · 

Proof state:
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

Next tactic:
exact ⟨head, fun ⟨List.cons a as, _⟩ => by simp [Bind.bind]; rfl⟩
theorem exists_code {n} {f : Vector ℕ n →. ℕ} (hf : Nat.Partrec' f) :
    ∃ c : Code, ∀ v : Vector ℕ n, c.eval v.1 = pure <$> f v := by
  induction' hf with n f hf
  induction hf
  case prim.zero => exact ⟨zero', fun ⟨[], _⟩ => rfl⟩
  case prim.succ => exact ⟨succ, fun ⟨[v], _⟩ => rfl⟩
  case prim.get n i =>
    refine' Fin.succRec (fun n => _) (fun n i IH => _) i
    · exact ⟨head, fun ⟨List.cons a as, _⟩ => by 

Proof state:
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✝ }

Next tactic:
simp [Bind.bind]
theorem exists_code {n} {f : Vector ℕ n →. ℕ} (hf : Nat.Partrec' f) :
    ∃ c : Code, ∀ v : Vector ℕ n, c.eval v.1 = pure <$> f v := by
  induction' hf with n f hf
  induction hf
  case prim.zero => exact ⟨zero', fun ⟨[], _⟩ => rfl⟩
  case prim.succ => exact ⟨succ, fun ⟨[v], _⟩ => rfl⟩
  case prim.get n i =>
    refine' Fin.succRec (fun n => _) (fun n i IH => _) i
    · exact ⟨head, fun ⟨List.cons a as, _⟩ => by simp [Bind.bind]; 

Proof state:
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✝ })

Next tactic:
rfl
theorem exists_code {n} {f : Vector ℕ n →. ℕ} (hf : Nat.Partrec' f) :
    ∃ c : Code, ∀ v : Vector ℕ n, c.eval v.1 = pure <$> f v := by
  induction' hf with n f hf
  induction hf
  case prim.zero => exact ⟨zero', fun ⟨[], _⟩ => rfl⟩
  case prim.succ => exact ⟨succ, fun ⟨[v], _⟩ => rfl⟩
  case prim.get n i =>
    refine' Fin.succRec (fun n => _) (fun n i IH => _) i
    · exact ⟨head, fun ⟨List.cons a as, _⟩ => by simp [Bind.bind]; rfl⟩
    · 

Proof state:
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

Next tactic:
obtain ⟨c, h⟩ := IH
theorem exists_code {n} {f : Vector ℕ n →. ℕ} (hf : Nat.Partrec' f) :
    ∃ c : Code, ∀ v : Vector ℕ n, c.eval v.1 = pure <$> f v := by
  induction' hf with n f hf
  induction hf
  case prim.zero => exact ⟨zero', fun ⟨[], _⟩ => rfl⟩
  case prim.succ => exact ⟨succ, fun ⟨[v], _⟩ => rfl⟩
  case prim.get n i =>
    refine' Fin.succRec (fun n => _) (fun n i IH => _) i
    · exact ⟨head, fun ⟨List.cons a as, _⟩ => by simp [Bind.bind]; rfl⟩
    · obtain ⟨c, h⟩ := IH
      

Proof state:
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

Next tactic:
exact ⟨c.comp tail, fun v => by simpa [← Vector.get_tail, Bind.bind] using h v.tail⟩
theorem exists_code {n} {f : Vector ℕ n →. ℕ} (hf : Nat.Partrec' f) :
    ∃ c : Code, ∀ v : Vector ℕ n, c.eval v.1 = pure <$> f v := by
  induction' hf with n f hf
  induction hf
  case prim.zero => exact ⟨zero', fun ⟨[], _⟩ => rfl⟩
  case prim.succ => exact ⟨succ, fun ⟨[v], _⟩ => rfl⟩
  case prim.get n i =>
    refine' Fin.succRec (fun n => _) (fun n i IH => _) i
    · exact ⟨head, fun ⟨List.cons a as, _⟩ => by simp [Bind.bind]; rfl⟩
    · obtain ⟨c, h⟩ := IH
      exact ⟨c.comp tail, fun v => by 

Proof state:
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

Next tactic:
simpa [← Vector.get_tail, Bind.bind] using h v.tail
theorem exists_code {n} {f : Vector ℕ n →. ℕ} (hf : Nat.Partrec' f) :
    ∃ c : Code, ∀ v : Vector ℕ n, c.eval v.1 = pure <$> f v := by
  induction' hf with n f hf
  induction hf
  case prim.zero => exact ⟨zero', fun ⟨[], _⟩ => rfl⟩
  case prim.succ => exact ⟨succ, fun ⟨[v], _⟩ => rfl⟩
  case prim.get n i =>
    refine' Fin.succRec (fun n => _) (fun n i IH => _) i
    · exact ⟨head, fun ⟨List.cons a as, _⟩ => by simp [Bind.bind]; rfl⟩
    · obtain ⟨c, h⟩ := IH
      exact ⟨c.comp tail, fun v => by simpa [← Vector.get_tail, Bind.bind] using h v.tail⟩
  

Proof state:
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

Next tactic:
case prim.comp m n f g hf hg IHf IHg =>
    simpa [Part.bind_eq_bind] using exists_code.comp IHf IHg
theorem exists_code {n} {f : Vector ℕ n →. ℕ} (hf : Nat.Partrec' f) :
    ∃ c : Code, ∀ v : Vector ℕ n, c.eval v.1 = pure <$> f v := by
  induction' hf with n f hf
  induction hf
  case prim.zero => exact ⟨zero', fun ⟨[], _⟩ => rfl⟩
  case prim.succ => exact ⟨succ, fun ⟨[v], _⟩ => rfl⟩
  case prim.get n i =>
    refine' Fin.succRec (fun n => _) (fun n i IH => _) i
    · exact ⟨head, fun ⟨List.cons a as, _⟩ => by simp [Bind.bind]; rfl⟩
    · obtain ⟨c, h⟩ := IH
      exact ⟨c.comp tail, fun v => by simpa [← Vector.get_tail, Bind.bind] using h v.tail⟩
  

Proof state:
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

Next tactic:
case prim.comp m n f g hf hg IHf IHg =>
    simpa [Part.bind_eq_bind] using exists_code.comp IHf IHg
theorem exists_code {n} {f : Vector ℕ n →. ℕ} (hf : Nat.Partrec' f) :
    ∃ c : Code, ∀ v : Vector ℕ n, c.eval v.1 = pure <$> f v := by
  induction' hf with n f hf
  induction hf
  case prim.zero => exact ⟨zero', fun ⟨[], _⟩ => rfl⟩
  case prim.succ => exact ⟨succ, fun ⟨[v], _⟩ => rfl⟩
  case prim.get n i =>
    refine' Fin.succRec (fun n => _) (fun n i IH => _) i
    · exact ⟨head, fun ⟨List.cons a as, _⟩ => by simp [Bind.bind]; rfl⟩
    · obtain ⟨c, h⟩ := IH
      exact ⟨c.comp tail, fun v => by simpa [← Vector.get_tail, Bind.bind] using h v.tail⟩
  case prim.comp m n f g hf hg IHf IHg =>
    

Proof state:
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

Next tactic:
simpa [Part.bind_eq_bind] using exists_code.comp IHf IHg