l3lab/ntp-mathlib huggingface dataset:
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 =>
    simpa [Part.bind_eq_bind] using exists_code.comp IHf IHg
  

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

Next tactic:
case prim.prec n f g _ _ IHf IHg =>
    obtain ⟨cf, hf⟩ := IHf
    obtain ⟨cg, hg⟩ := IHg
    simp only [Part.map_eq_map, Part.map_some, PFun.coe_val] at hf hg
    refine' ⟨prec cf cg, fun v => _⟩
    rw [← v.cons_head_tail]
    specialize hf v.tail
    replace hg := fun a b => hg (a ::ᵥ b ::ᵥ v.tail)
    simp only [Vector.cons_val, Vector.tail_val] at hf hg
    simp only [Part.map_eq_map, Part.map_some, Vector.cons_val, Vector.tail_cons, Vector.head_cons,
      PFun.coe_val, Vector.tail_val]
    simp only [← Part.pure_eq_some] at hf hg ⊢
    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]
    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]
    intro a b e
    induction' b with b IH generalizing a
    · refine' PFun.mem_fix_iff.2 (Or.inl <| Part.eq_some_iff.1 _)
      simp only [hg, ← e, Part.bind_some, List.tail_cons, pure]
      rfl
    · refine' PFun.mem_fix_iff.2 (Or.inr ⟨_, _, IH (a + 1) (by rwa [add_right_comm])⟩)
      simp only [hg, eval, Part.bind_some, Nat.rec_add_one, List.tail_nil, List.tail_cons, pure]
      exact Part.mem_some_iff.2 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⟩
    · 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 =>
    simpa [Part.bind_eq_bind] using exists_code.comp IHf IHg
  case prim.prec n f g _ _ IHf IHg =>
    

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

Next tactic:
obtain ⟨cf, hf⟩ := IHf
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 =>
    simpa [Part.bind_eq_bind] using exists_code.comp IHf IHg
  case prim.prec n f g _ _ IHf IHg =>
    obtain ⟨cf, hf⟩ := IHf
    

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

Next tactic:
obtain ⟨cg, hg⟩ := 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 =>
    simpa [Part.bind_eq_bind] using exists_code.comp IHf IHg
  case prim.prec n f g _ _ IHf IHg =>
    obtain ⟨cf, hf⟩ := IHf
    obtain ⟨cg, hg⟩ := IHg
    

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

Next tactic:
simp only [Part.map_eq_map, Part.map_some, PFun.coe_val] at hf hg
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 =>
    simpa [Part.bind_eq_bind] using exists_code.comp IHf IHg
  case prim.prec n f g _ _ IHf IHg =>
    obtain ⟨cf, hf⟩ := IHf
    obtain ⟨cg, hg⟩ := IHg
    simp only [Part.map_eq_map, Part.map_some, PFun.coe_val] at hf hg
    

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

Next tactic:
refine' ⟨prec cf cg, fun v => _⟩
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 =>
    simpa [Part.bind_eq_bind] using exists_code.comp IHf IHg
  case prim.prec n f g _ _ IHf IHg =>
    obtain ⟨cf, hf⟩ := IHf
    obtain ⟨cg, hg⟩ := IHg
    simp only [Part.map_eq_map, Part.map_some, PFun.coe_val] at hf hg
    refine' ⟨prec cf cg, fun v => _⟩
    

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

Next tactic:
rw [← v.cons_head_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⟩
  case prim.comp m n f g hf hg IHf IHg =>
    simpa [Part.bind_eq_bind] using exists_code.comp IHf IHg
  case prim.prec n f g _ _ IHf IHg =>
    obtain ⟨cf, hf⟩ := IHf
    obtain ⟨cg, hg⟩ := IHg
    simp only [Part.map_eq_map, Part.map_some, PFun.coe_val] at hf hg
    refine' ⟨prec cf cg, fun v => _⟩
    rw [← v.cons_head_tail]
    

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

Next tactic:
specialize hf 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⟩
  case prim.comp m n f g hf hg IHf IHg =>
    simpa [Part.bind_eq_bind] using exists_code.comp IHf IHg
  case prim.prec n f g _ _ IHf IHg =>
    obtain ⟨cf, hf⟩ := IHf
    obtain ⟨cg, hg⟩ := IHg
    simp only [Part.map_eq_map, Part.map_some, PFun.coe_val] at hf hg
    refine' ⟨prec cf cg, fun v => _⟩
    rw [← v.cons_head_tail]
    specialize hf v.tail
    

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

Next tactic:
replace hg := fun a b => hg (a ::ᵥ b ::ᵥ 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⟩
  case prim.comp m n f g hf hg IHf IHg =>
    simpa [Part.bind_eq_bind] using exists_code.comp IHf IHg
  case prim.prec n f g _ _ IHf IHg =>
    obtain ⟨cf, hf⟩ := IHf
    obtain ⟨cg, hg⟩ := IHg
    simp only [Part.map_eq_map, Part.map_some, PFun.coe_val] at hf hg
    refine' ⟨prec cf cg, fun v => _⟩
    rw [← v.cons_head_tail]
    specialize hf v.tail
    replace hg := fun a b => hg (a ::ᵥ b ::ᵥ v.tail)
    

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

Next tactic:
simp only [Vector.cons_val, Vector.tail_val] at hf hg
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 =>
    simpa [Part.bind_eq_bind] using exists_code.comp IHf IHg
  case prim.prec n f g _ _ IHf IHg =>
    obtain ⟨cf, hf⟩ := IHf
    obtain ⟨cg, hg⟩ := IHg
    simp only [Part.map_eq_map, Part.map_some, PFun.coe_val] at hf hg
    refine' ⟨prec cf cg, fun v => _⟩
    rw [← v.cons_head_tail]
    specialize hf v.tail
    replace hg := fun a b => hg (a ::ᵥ b ::ᵥ v.tail)
    simp only [Vector.cons_val, Vector.tail_val] at hf hg
    

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

Next 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]
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 =>
    simpa [Part.bind_eq_bind] using exists_code.comp IHf IHg
  case prim.prec n f g _ _ IHf IHg =>
    obtain ⟨cf, hf⟩ := IHf
    obtain ⟨cg, hg⟩ := IHg
    simp only [Part.map_eq_map, Part.map_some, PFun.coe_val] at hf hg
    refine' ⟨prec cf cg, fun v => _⟩
    rw [← v.cons_head_tail]
    specialize hf v.tail
    replace hg := fun a b => hg (a ::ᵥ b ::ᵥ v.tail)
    simp only [Vector.cons_val, Vector.tail_val] at hf hg
    simp only [Part.map_eq_map, Part.map_some, Vector.cons_val, Vector.tail_cons, Vector.head_cons,
      PFun.coe_val, Vector.tail_val]
    

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

Next tactic:
simp only [← Part.pure_eq_some] at hf hg ⊢
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 =>
    simpa [Part.bind_eq_bind] using exists_code.comp IHf IHg
  case prim.prec n f g _ _ IHf IHg =>
    obtain ⟨cf, hf⟩ := IHf
    obtain ⟨cg, hg⟩ := IHg
    simp only [Part.map_eq_map, Part.map_some, PFun.coe_val] at hf hg
    refine' ⟨prec cf cg, fun v => _⟩
    rw [← v.cons_head_tail]
    specialize hf v.tail
    replace hg := fun a b => hg (a ::ᵥ b ::ᵥ v.tail)
    simp only [Vector.cons_val, Vector.tail_val] at hf hg
    simp only [Part.map_eq_map, Part.map_some, Vector.cons_val, Vector.tail_cons, Vector.head_cons,
      PFun.coe_val, Vector.tail_val]
    simp only [← Part.pure_eq_some] at hf hg ⊢
    

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

Next tactic:
induction' v.head with n _
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 =>
    simpa [Part.bind_eq_bind] using exists_code.comp IHf IHg
  case prim.prec n f g _ _ IHf IHg =>
    obtain ⟨cf, hf⟩ := IHf
    obtain ⟨cg, hg⟩ := IHg
    simp only [Part.map_eq_map, Part.map_some, PFun.coe_val] at hf hg
    refine' ⟨prec cf cg, fun v => _⟩
    rw [← v.cons_head_tail]
    specialize hf v.tail
    replace hg := fun a b => hg (a ::ᵥ b ::ᵥ v.tail)
    simp only [Vector.cons_val, Vector.tail_val] at hf hg
    simp only [Part.map_eq_map, Part.map_some, Vector.cons_val, Vector.tail_cons, Vector.head_cons,
      PFun.coe_val, Vector.tail_val]
    simp only [← Part.pure_eq_some] at hf hg ⊢
    induction' v.head with n _ <;>
      

Proof state:
case intro.intro.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)))
⊢ eval (prec cf cg) (Nat.zero :: List.tail ↑v) =
    pure (pure (Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) Nat.zero))

Next tactic:
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]
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 =>
    simpa [Part.bind_eq_bind] using exists_code.comp IHf IHg
  case prim.prec n f g _ _ IHf IHg =>
    obtain ⟨cf, hf⟩ := IHf
    obtain ⟨cg, hg⟩ := IHg
    simp only [Part.map_eq_map, Part.map_some, PFun.coe_val] at hf hg
    refine' ⟨prec cf cg, fun v => _⟩
    rw [← v.cons_head_tail]
    specialize hf v.tail
    replace hg := fun a b => hg (a ::ᵥ b ::ᵥ v.tail)
    simp only [Vector.cons_val, Vector.tail_val] at hf hg
    simp only [Part.map_eq_map, Part.map_some, Vector.cons_val, Vector.tail_cons, Vector.head_cons,
      PFun.coe_val, Vector.tail_val]
    simp only [← Part.pure_eq_some] at hf hg ⊢
    induction' v.head with n _ <;>
      

Proof state:
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))
⊢ eval (prec cf cg) (Nat.succ n :: List.tail ↑v) =
    pure (pure (Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) (Nat.succ n)))

Next tactic:
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]