/-- Recursion on `Nat.Partrec.Code` is primitive recursive. -/
theorem rec_prim {α σ} [Primcodable α] [Primcodable σ] {c : α → Code} (hc : Primrec c) {z : α → σ}
    (hz : Primrec z) {s : α → σ} (hs : Primrec s) {l : α → σ} (hl : Primrec l) {r : α → σ}
    (hr : Primrec r) {pr : α → Code → Code → σ → σ → σ}
    (hpr : Primrec fun a : α × Code × Code × σ × σ => pr a.1 a.2.1 a.2.2.1 a.2.2.2.1 a.2.2.2.2)
    {co : α → Code → Code → σ → σ → σ}
    (hco : Primrec fun a : α × Code × Code × σ × σ => co a.1 a.2.1 a.2.2.1 a.2.2.2.1 a.2.2.2.2)
    {pc : α → Code → Code → σ → σ → σ}
    (hpc : Primrec fun a : α × Code × Code × σ × σ => pc a.1 a.2.1 a.2.2.1 a.2.2.2.1 a.2.2.2.2)
    {rf : α → Code → σ → σ} (hrf : Primrec fun a : α × Code × σ => rf a.1 a.2.1 a.2.2) :
    let F (a : α) (c : Code) : σ :=
      Nat.Partrec.Code.recOn c (z a) (s a) (l a) (r a) (pr a) (co a) (pc a) (rf a)
    Primrec fun a => F a (c a) := by
  intros F
  let G₁ : (α × List σ) × ℕ × ℕ → Option σ := fun p =>
    let a := p.1.1
    let IH := p.1.2
    let n := p.2.1
    let m := p.2.2
    (IH.get? m).bind fun s =>
      (IH.get? m.unpair.1).bind fun s₁ =>
        (IH.get? m.unpair.2).map fun s₂ =>
          cond n.bodd
            (cond n.div2.bodd (rf a (ofNat Code m) s)
              (pc a (ofNat Code m.unpair.1) (ofNat Code m.unpair.2) s₁ s₂))
            (cond n.div2.bodd (co a (ofNat Code m.unpair.1) (ofNat Code m.unpair.2) s₁ s₂)
              (pr a (ofNat Code m.unpair.1) (ofNat Code m.unpair.2) s₁ s₂))
  have : Primrec G₁ := by
    refine' option_bind (list_get?.comp (snd.comp fst) (snd.comp snd)) _
    unfold Primrec₂
    refine' option_bind ((list_get?.comp (snd.comp fst) (fst.comp <| Primrec.unpair.comp
            (snd.comp snd))).comp fst) _
    unfold Primrec₂
    refine'
      option_map
        ((list_get?.comp (snd.comp fst) (snd.comp <| Primrec.unpair.comp (snd.comp snd))).comp <|
          fst.comp fst)
        _
    have a : Primrec (fun p : ((((α × List σ) × ℕ × ℕ) × σ) × σ) × σ => p.1.1.1.1.1) :=
      fst.comp (fst.comp <| fst.comp <| fst.comp fst)
    have n : Primrec (fun p : ((((α × List σ) × ℕ × ℕ) × σ) × σ) × σ => p.1.1.1.2.1) :=
      fst.comp (snd.comp <| fst.comp <| fst.comp fst)
    have m : Primrec (fun p : ((((α × List σ) × ℕ × ℕ) × σ) × σ) × σ => p.1.1.1.2.2) :=
      snd.comp (snd.comp <| fst.comp <| fst.comp fst)
    have m₁ := fst.comp (Primrec.unpair.comp m)
    have m₂ := snd.comp (Primrec.unpair.comp m)
    have s : Primrec (fun p : ((((α × List σ) × ℕ × ℕ) × σ) × σ) × σ => p.1.1.2) :=
      snd.comp (fst.comp fst)
    have s₁ : Primrec (fun p : ((((α × List σ) × ℕ × ℕ) × σ) × σ) × σ => p.1.2) :=
      snd.comp fst
    have s₂ : Primrec (fun p : ((((α × List σ) × ℕ × ℕ) × σ) × σ) × σ => p.2) :=
      snd
    have h₁ := hrf.comp <| a.pair (((Primrec.ofNat Code).comp m).pair s)
    have h₂ := hpc.comp <| a.pair (((Primrec.ofNat Code).comp m₁).pair <|
      ((Primrec.ofNat Code).comp m₂).pair <| s₁.pair s₂)
    have h₃ := hco.comp <| a.pair
      (((Primrec.ofNat Code).comp m₁).pair <| ((Primrec.ofNat Code).comp m₂).pair <| s₁.pair s₂)
    have h₄ := hpr.comp <| a.pair
      (((Primrec.ofNat Code).comp m₁).pair <| ((Primrec.ofNat Code).comp m₂).pair <| s₁.pair s₂)
    unfold Primrec₂
    exact
      (nat_bodd.comp n).cond
        ((nat_bodd.comp <| nat_div2.comp n).cond h₁ h₂)
        (cond (nat_bodd.comp <| nat_div2.comp n) h₃ h₄)
  let G : α → List σ → Option σ := fun a IH =>
    IH.length.casesOn (some (z a)) fun n =>
      n.casesOn (some (s a)) fun n =>
        n.casesOn (some (l a)) fun n =>
          n.casesOn (some (r a)) fun n => G₁ ((a, IH), n, n.div2.div2)
  have : Primrec₂ G := by
    unfold Primrec₂
    refine nat_casesOn (list_length.comp snd) (option_some_iff.2 (hz.comp fst)) ?_
    unfold Primrec₂
    refine nat_casesOn snd (option_some_iff.2 (hs.comp (fst.comp fst))) ?_
    unfold Primrec₂
    refine nat_casesOn snd (option_some_iff.2 (hl.comp (fst.comp <| fst.comp fst))) ?_
    unfold Primrec₂
    refine nat_casesOn snd (option_some_iff.2 (hr.comp (fst.comp <| fst.comp <| fst.comp fst))) ?_
    unfold Primrec₂
    exact this.comp <|
      ((fst.pair snd).comp <| fst.comp <| fst.comp <| fst.comp <| fst).pair <|
          snd.pair <| nat_div2.comp <| nat_div2.comp snd
  refine'
    ((nat_strong_rec (fun a n => F a (ofNat Code n)) this.to₂ fun a n => _).comp
      _root_.Primrec.id <| encode_iff.2 hc).of_eq
      fun a => by simp
  simp (config := { zeta := false })
  iterate 4 cases' n with n; · simp (config := { zeta := false }) [ofNatCode_eq, ofNatCode]; rfl
  simp only []
  rw [List.length_map, List.length_range]
  let m := n.div2.div2
  show
    G₁ ((a, (List.range (n + 4)).map fun n => F a (ofNat Code n)), n, m) =
      some (F a (ofNat Code (n + 4)))
  have hm : m < n + 4 := by
    simp only [div2_val]
    exact
      lt_of_le_of_lt (le_trans (Nat.div_le_self _ _) (Nat.div_le_self _ _))
        (Nat.succ_le_succ (Nat.le_add_right _ _))
  have m1 : m.unpair.1 < n + 4 := lt_of_le_of_lt m.unpair_left_le hm
  have m2 : m.unpair.2 < n + 4 := lt_of_le_of_lt m.unpair_right_le hm
  simp [List.get?_map, List.get?_range, hm, m1, m2]
  rw [show ofNat Code (n + 4) = ofNatCode (n + 4) from rfl]
  

Proof state:
case succ.succ.succ.succ
α : Type u_1
σ : Type u_2
inst✝¹ : Primcodable α
inst✝ : Primcodable σ
c : α → Code
hc : Primrec c
z : α → σ
hz : Primrec z
s : α → σ
hs : Primrec s
l : α → σ
hl : Primrec l
r : α → σ
hr : Primrec r
pr : α → Code → Code → σ → σ → σ
hpr : Primrec fun a => pr a.1 a.2.1 a.2.2.1 a.2.2.2.1 a.2.2.2.2
co : α → Code → Code → σ → σ → σ
hco : Primrec fun a => co a.1 a.2.1 a.2.2.1 a.2.2.2.1 a.2.2.2.2
pc : α → Code → Code → σ → σ → σ
hpc : Primrec fun a => pc a.1 a.2.1 a.2.2.1 a.2.2.2.1 a.2.2.2.2
rf : α → Code → σ → σ
hrf : Primrec fun a => rf a.1 a.2.1 a.2.2
F : α → Code → σ := fun a c => Code.recOn c (z a) (s a) (l a) (r a) (pr a) (co a) (pc a) (rf a)
G₁ : (α × List σ) × ℕ × ℕ → Option σ :=
  fun p =>
    let a := p.1.1;
    let IH := p.1.2;
    let n := p.2.1;
    let m := p.2.2;
    Option.bind (List.get? IH m) fun s =>
      Option.bind (List.get? IH (unpair m).1) fun s₁ =>
        Option.map
          (fun s₂ =>
            bif bodd n then
              bif bodd (div2 n) then rf a (ofNat Code m) s
              else pc a (ofNat Code (unpair m).1) (ofNat Code (unpair m).2) s₁ s₂
            else
              bif bodd (div2 n) then co a (ofNat Code (unpair m).1) (ofNat Code (unpair m).2) s₁ s₂
              else pr a (ofNat Code (unpair m).1) (ofNat Code (unpair m).2) s₁ s₂)
          (List.get? IH (unpair m).2)
this✝ : Primrec G₁
G : α → List σ → Option σ :=
  fun a IH =>
    Nat.casesOn (List.length IH) (some (z a)) fun n =>
      Nat.casesOn n (some (s a)) fun n =>
        Nat.casesOn n (some (l a)) fun n => Nat.casesOn n (some (r a)) fun n => G₁ ((a, IH), n, div2 (div2 n))
this : Primrec₂ G
a : α
n : ℕ
m : ℕ := div2 (div2 n)
hm : m < n + 4
m1 : (unpair m).1 < n + 4
m2 : (unpair m).2 < n + 4
⊢ (bif bodd n then
      bif bodd (div2 n) then
        rf a (ofNat Code (div2 (div2 n)))
          (rec (z a) (s a) (l a) (r a) (pr a) (co a) (pc a) (rf a) (ofNat Code (div2 (div2 n))))
      else
        pc a (ofNat Code (unpair (div2 (div2 n))).1) (ofNat Code (unpair (div2 (div2 n))).2)
          (rec (z a) (s a) (l a) (r a) (pr a) (co a) (pc a) (rf a) (ofNat Code (unpair (div2 (div2 n))).1))
          (rec (z a) (s a) (l a) (r a) (pr a) (co a) (pc a) (rf a) (ofNat Code (unpair (div2 (div2 n))).2))
    else
      bif bodd (div2 n) then
        co a (ofNat Code (unpair (div2 (div2 n))).1) (ofNat Code (unpair (div2 (div2 n))).2)
          (rec (z a) (s a) (l a) (r a) (pr a) (co a) (pc a) (rf a) (ofNat Code (unpair (div2 (div2 n))).1))
          (rec (z a) (s a) (l a) (r a) (pr a) (co a) (pc a) (rf a) (ofNat Code (unpair (div2 (div2 n))).2))
      else
        pr a (ofNat Code (unpair (div2 (div2 n))).1) (ofNat Code (unpair (div2 (div2 n))).2)
          (rec (z a) (s a) (l a) (r a) (pr a) (co a) (pc a) (rf a) (ofNat Code (unpair (div2 (div2 n))).1))
          (rec (z a) (s a) (l a) (r a) (pr a) (co a) (pc a) (rf a) (ofNat Code (unpair (div2 (div2 n))).2))) =
    rec (z a) (s a) (l a) (r a) (pr a) (co a) (pc a) (rf a) (ofNatCode (n + 4))

Next tactic:
simp [ofNatCode]