/-- Recursion on `Nat.Partrec.Code` is computable. -/
theorem rec_computable {α σ} [Primcodable α] [Primcodable σ] {c : α → Code} (hc : Computable c)
    {z : α → σ} (hz : Computable z) {s : α → σ} (hs : Computable s) {l : α → σ} (hl : Computable l)
    {r : α → σ} (hr : Computable r) {pr : α → Code × Code × σ × σ → σ} (hpr : Computable₂ pr)
    {co : α → Code × Code × σ × σ → σ} (hco : Computable₂ co) {pc : α → Code × Code × σ × σ → σ}
    (hpc : Computable₂ pc) {rf : α → Code × σ → σ} (hrf : Computable₂ rf) :
    let PR (a) cf cg hf hg := pr a (cf, cg, hf, hg)
    let CO (a) cf cg hf hg := co a (cf, cg, hf, hg)
    let PC (a) cf cg hf hg := pc a (cf, cg, hf, hg)
    let RF (a) cf hf := rf a (cf, hf)
    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)
    Computable fun a => F a (c a) := by
  -- TODO(Mario): less copy-paste from previous proof
  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 : Computable G₁ := by
    refine' option_bind (list_get?.comp (snd.comp fst) (snd.comp snd)) _
    unfold Computable₂
    refine'
      option_bind
        ((list_get?.comp (snd.comp fst)
          (fst.comp <| Computable.unpair.comp (snd.comp snd))).comp fst) _
    unfold Computable₂
    refine'
      option_map
        ((list_get?.comp (snd.comp fst)
          (snd.comp <| Computable.unpair.comp (snd.comp snd))).comp <| fst.comp fst) _
    have a : Computable (fun p : ((((α × List σ) × ℕ × ℕ) × σ) × σ) × σ => p.1.1.1.1.1) :=
      fst.comp (fst.comp <| fst.comp <| fst.comp fst)
    have n : Computable (fun p : ((((α × List σ) × ℕ × ℕ) × σ) × σ) × σ => p.1.1.1.2.1) :=
      fst.comp (snd.comp <| fst.comp <| fst.comp fst)
    have m : Computable (fun p : ((((α × List σ) × ℕ × ℕ) × σ) × σ) × σ => p.1.1.1.2.2) :=
      snd.comp (snd.comp <| fst.comp <| fst.comp fst)
    have m₁ := fst.comp (Computable.unpair.comp m)
    have m₂ := snd.comp (Computable.unpair.comp m)
    have s : Computable (fun p : ((((α × List σ) × ℕ × ℕ) × σ) × σ) × σ => p.1.1.2) :=
      snd.comp (fst.comp fst)
    have s₁ : Computable (fun p : ((((α × List σ) × ℕ × ℕ) × σ) × σ) × σ => p.1.2) :=
      snd.comp fst
    have s₂ : Computable (fun p : ((((α × List σ) × ℕ × ℕ) × σ) × σ) × σ => p.2) :=
      snd
    exact
      (nat_bodd.comp n).cond
        ((nat_bodd.comp <| nat_div2.comp n).cond
          (hrf.comp a (((Computable.ofNat Code).comp m).pair s))
          (hpc.comp a
            (((Computable.ofNat Code).comp m₁).pair <|
              ((Computable.ofNat Code).comp m₂).pair <| s₁.pair s₂)))
        (Computable.cond (nat_bodd.comp <| nat_div2.comp n)
          (hco.comp a
            (((Computable.ofNat Code).comp m₁).pair <|
              ((Computable.ofNat Code).comp m₂).pair <| s₁.pair s₂))
          (hpr.comp a
            (((Computable.ofNat Code).comp m₁).pair <|
              ((Computable.ofNat Code).comp m₂).pair <| s₁.pair s₂)))
  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 : Computable₂ G :=
    Computable.nat_casesOn (list_length.comp snd) (option_some_iff.2 (hz.comp fst)) <|
      Computable.nat_casesOn snd (option_some_iff.2 (hs.comp (fst.comp fst))) <|
        Computable.nat_casesOn snd (option_some_iff.2 (hl.comp (fst.comp <| fst.comp fst))) <|
          Computable.nat_casesOn snd
            (option_some_iff.2 (hr.comp (fst.comp <| fst.comp <| fst.comp fst)))
            (this.comp <|
              ((Computable.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 Computable.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
  

Proof state:
case succ.succ.succ.succ
α : Type u_1
σ : Type u_2
inst✝¹ : Primcodable α
inst✝ : Primcodable σ
c : α → Code
hc : Computable c
z : α → σ
hz : Computable z
s : α → σ
hs : Computable s
l : α → σ
hl : Computable l
r : α → σ
hr : Computable r
pr : α → Code × Code × σ × σ → σ
hpr : Computable₂ pr
co : α → Code × Code × σ × σ → σ
hco : Computable₂ co
pc : α → Code × Code × σ × σ → σ
hpc : Computable₂ pc
rf : α → Code × σ → σ
hrf : Computable₂ rf
PR✝ : α → Code → Code → σ → σ → σ := fun a cf cg hf hg => pr a (cf, cg, hf, hg)
CO✝ : α → Code → Code → σ → σ → σ := fun a cf cg hf hg => co a (cf, cg, hf, hg)
PC✝ : α → Code → Code → σ → σ → σ := fun a cf cg hf hg => pc a (cf, cg, hf, hg)
RF✝ : α → Code → σ → σ := fun a cf hf => rf a (cf, hf)
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✝ : Computable 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 : Computable₂ G
a : α
n : ℕ
m : ℕ := div2 (div2 n)
⊢ Nat.rec (some (z a))
      (fun n_1 n_ih =>
        Nat.rec (some (s a))
          (fun n_2 n_ih =>
            Nat.rec (some (l a))
              (fun n_3 n_ih =>
                Nat.rec (some (r a))
                  (fun n_4 n_ih =>
                    Option.bind
                      (List.get?
                        (List.map
                          (fun n =>
                            rec (z a) (s a) (l a) (r a) (fun cf cg hf hg => pr a (cf, cg, hf, hg))
                              (fun cf cg hf hg => co a (cf, cg, hf, hg)) (fun cf cg hf hg => pc a (cf, cg, hf, hg))
                              (fun cf hf => rf a (cf, hf)) (ofNat Code n))
                          (List.range (Nat.succ (Nat.succ (Nat.succ (Nat.succ n))))))
                        (div2 (div2 n_4)))
                      fun s_1 =>
                      Option.bind
                        (List.get?
                          (List.map
                            (fun n =>
                              rec (z a) (s a) (l a) (r a) (fun cf cg hf hg => pr a (cf, cg, hf, hg))
                                (fun cf cg hf hg => co a (cf, cg, hf, hg)) (fun cf cg hf hg => pc a (cf, cg, hf, hg))
                                (fun cf hf => rf a (cf, hf)) (ofNat Code n))
                            (List.range (Nat.succ (Nat.succ (Nat.succ (Nat.succ n))))))
                          (unpair (div2 (div2 n_4))).1)
                        fun s₁ =>
                        Option.map
                          (fun s₂ =>
                            bif bodd n_4 then
                              bif bodd (div2 n_4) then rf a (ofNat Code (div2 (div2 n_4)), s_1)
                              else
                                pc a
                                  (ofNat Code (unpair (div2 (div2 n_4))).1, ofNat Code (unpair (div2 (div2 n_4))).2, s₁,
                                    s₂)
                            else
                              bif bodd (div2 n_4) then
                                co a
                                  (ofNat Code (unpair (div2 (div2 n_4))).1, ofNat Code (unpair (div2 (div2 n_4))).2, s₁,
                                    s₂)
                              else
                                pr a
                                  (ofNat Code (unpair (div2 (div2 n_4))).1, ofNat Code (unpair (div2 (div2 n_4))).2, s₁,
                                    s₂))
                          (List.get?
                            (List.map
                              (fun n =>
                                rec (z a) (s a) (l a) (r a) (fun cf cg hf hg => pr a (cf, cg, hf, hg))
                                  (fun cf cg hf hg => co a (cf, cg, hf, hg)) (fun cf cg hf hg => pc a (cf, cg, hf, hg))
                                  (fun cf hf => rf a (cf, hf)) (ofNat Code n))
                              (List.range (Nat.succ (Nat.succ (Nat.succ (Nat.succ n))))))
                            (unpair (div2 (div2 n_4))).2))
                  n_3)
              n_2)
          n_1)
      (Nat.succ (Nat.succ (Nat.succ (Nat.succ n)))) =
    some
      (rec (z a) (s a) (l a) (r a) (fun cf cg hf hg => pr a (cf, cg, hf, hg)) (fun cf cg hf hg => co a (cf, cg, hf, hg))
        (fun cf cg hf hg => pc a (cf, cg, hf, hg)) (fun cf hf => rf a (cf, hf))
        (ofNat Code (Nat.succ (Nat.succ (Nat.succ (Nat.succ n))))))

Next tactic:
show
    G₁ ((a, (List.range (n + 4)).map fun n => F a (ofNat Code n)), n, m) =
      some (F a (ofNat Code (n + 4)))