-- Mathlib/Computability/PartrecCode.lean
theorem evaln_prim : Primrec fun a : (ℕ × Code) × ℕ => evaln a.1.1 a.1.2 a.2 :=
  have :
    Primrec₂ fun (_ : Unit) (n : ℕ) =>
      let a := ofNat (ℕ × Code) n
      (List.range a.1).map (evaln a.1 a.2) :=
    Primrec.nat_strong_rec _ (hG.comp Primrec.snd).to₂ fun _ p => by
      simp only [G, prod_ofNat_val, ofNat_nat, List.length_map, List.length_range,
        Nat.pair_unpair, Option.some_inj]
      refine List.map_congr_left fun n => ?_
      have : List.range p = List.range (Nat.pair p.unpair.1 (encode (ofNat Code p.unpair.2)))

Proof state:
case succ.comp.intro.none
x✝ : Unit
p n : ℕ
this : List.range p = List.range (Nat.pair (unpair p).1 (encode (ofNat Code (unpair p).2)))
k' : ℕ
k : ℕ := k' + 1
nk : n ≤ k'
cf cg : Code
hg :
  ∀ {k' : ℕ} {c' : Code} {n : ℕ},
    Nat.pair k' (encode c') < Nat.pair k (encode (cf.comp cg)) →
      Nat.Partrec.Code.lup
          (List.map (fun n => List.map (evaln (unpair n).1 (ofNat Code (unpair n).2)) (List.range (unpair n).1))
            (List.range (Nat.pair k (encode (cf.comp cg)))))
          (k', c') n =
        evaln k' c' n
lf : encode cf < encode (cf.comp cg)
lg : encode cg < encode (cf.comp cg)
⊢ (Option.none.bind fun x =>
      Nat.Partrec.Code.lup
        (List.map (fun n => List.map (evaln (unpair n).1 (ofNat Code (unpair n).2)) (List.range (unpair n).1))
          (List.range (Nat.pair (k' + 1) (encode (cf.comp cg)))))
        (k' + 1, cf) x) =
    Option.none.bind fun x => evaln (k' + 1) cf x

Tactic:
rfl

Result:
no goals

Proof state:
x✝ : Unit
p : ℕ
⊢ Nat.Partrec.Code.G
      (x✝,
          List.map
            (fun n =>
              let a := ofNat (ℕ × Code) n;
              List.map (evaln a.1 a.2) (List.range a.1))
            (List.range p)).2 =
    some
      (let a := ofNat (ℕ × Code) p;
      List.map (evaln a.1 a.2) (List.range a.1))

Tactic:
simp only [G, prod_ofNat_val, ofNat_nat, List.length_map, List.length_range,
  Nat.pair_unpair, Option.some_inj]

Result:
x✝ : Unit
p : ℕ
⊢ List.map
      (fun n =>
        Nat.rec Option.none
          (fun n_1 n_ih =>
            rec (some 0) (some n.succ) (some (unpair n).1) (some (unpair n).2)
              (fun cf cg x x => do
                let x ←
                  Nat.Partrec.Code.lup
                      (List.map
                        (fun n => List.map (evaln (unpair n).1 (ofNat Code (unpair n).2)) (List.range (unpair n).1))
                        (List.range p))
                      ((unpair p).1, cf) n
                let y ←
                  Nat.Partrec.Code.lup
                      (List.map
                        (fun n => List.map (evaln (unpair n).1 (ofNat Code (unpair n).2)) (List.range (unpair n).1))
                        (List.range p))
                      ((unpair p).1, cg) n
                some (Nat.pair x y))
              (fun cf cg x x => do
                let x ←
                  Nat.Partrec.Code.lup
                      (List.map
                        (fun n => List.map (evaln (unpair n).1 (ofNat Code (unpair n).2)) (List.range (unpair n).1))
                        (List.range p))
                      ((unpair p).1, cg) n
                Nat.Partrec.Code.lup
                    (List.map
                      (fun n => List.map (evaln (unpair n).1 (ofNat Code (unpair n).2)) (List.range (unpair n).1))
                      (List.range p))
                    ((unpair p).1, cf) x)
              (fun cf cg x x =>
                Nat.rec
                  (Nat.Partrec.Code.lup
                    (List.map
                      (fun n => List.map (evaln (unpair n).1 (ofNat Code (unpair n).2)) (List.range (unpair n).1))
                      (List.range p))
                    ((unpair p).1, cf) (unpair n).1)
                  (fun n_2 n_ih => do
                    let i ←
                      Nat.Partrec.Code.lup
                          (List.map
                            (fun n => List.map (evaln (unpair n).1 (ofNat Code (unpair n).2)) (List.range (unpair n).1))
                            (List.range p))
                          (n_1, ofNat Code (unpair p).2) (Nat.pair (unpair n).1 n_2)
                    Nat.Partrec.Code.lup
                        (List.map
                          (fun n => List.map (evaln (unpair n).1 (ofNat Code (unpair n).2)) (List.range (unpair n).1))
                          (List.range p))
                        ((unpair p).1, cg) (Nat.pair (unpair n).1 (Nat.pair n_2 i)))
                  (unpair n).2)
              (fun cf x => do
                let x ←
                  Nat.Partrec.Code.lup
                      (List.map
                        (fun n => List.map (evaln (unpair n).1 (ofNat Code (unpair n).2)) (List.range (unpair n).1))
                        (List.range p))
                      ((unpair p).1, cf) n
                Nat.rec (some (unpair n).2)
                    (fun n_2 n_ih =>
                      Nat.Partrec.Code.lup
                        (List.map
                          (fun n => List.map (evaln (unpair n).1 (ofNat Code (unpair n).2)) (List.range (unpair n).1))
                          (List.range p))
                        (n_1, ofNat Code (unpair p).2) (Nat.pair (unpair n).1 ((unpair n).2 + 1)))
                    x)
              (ofNat Code (unpair p).2))
          (unpair p).1)
      (List.range (unpair p).1) =
    List.map (evaln (unpair p).1 (ofNat Code (unpair p).2)) (List.range (unpair p).1)

Proof state:
case succ.pair.intro
x✝ : Unit
p n : ℕ
this : List.range p = List.range (Nat.pair (unpair p).1 (encode (ofNat Code (unpair p).2)))
k' : ℕ
k : ℕ := k' + 1
nk : n ≤ k'
cf cg : Code
hg :
  ∀ {k' : ℕ} {c' : Code} {n : ℕ},
    Nat.pair k' (encode c') < Nat.pair k (encode (cf.pair cg)) →
      Nat.Partrec.Code.lup
          (List.map (fun n => List.map (evaln (unpair n).1 (ofNat Code (unpair n).2)) (List.range (unpair n).1))
            (List.range (Nat.pair k (encode (cf.pair cg)))))
          (k', c') n =
        evaln k' c' n
lf : encode cf < encode (cf.pair cg)
lg : encode cg < encode (cf.pair cg)
⊢ ((evaln k cf n).bind fun a => (evaln k cg n).bind fun y => some (Nat.pair a y)) =
    (Option.map Nat.pair (evaln (k' + 1) cf n)).bind fun a => Option.map a (evaln (k' + 1) cg n)

Tactic:
cases evaln k cf n

Result:
case succ.pair.intro.none
x✝ : Unit
p n : ℕ
this : List.range p = List.range (Nat.pair (unpair p).1 (encode (ofNat Code (unpair p).2)))
k' : ℕ
k : ℕ := k' + 1
nk : n ≤ k'
cf cg : Code
hg :
  ∀ {k' : ℕ} {c' : Code} {n : ℕ},
    Nat.pair k' (encode c') < Nat.pair k (encode (cf.pair cg)) →
      Nat.Partrec.Code.lup
          (List.map (fun n => List.map (evaln (unpair n).1 (ofNat Code (unpair n).2)) (List.range (unpair n).1))
            (List.range (Nat.pair k (encode (cf.pair cg)))))
          (k', c') n =
        evaln k' c' n
lf : encode cf < encode (cf.pair cg)
lg : encode cg < encode (cf.pair cg)
⊢ (Option.none.bind fun a => (evaln k cg n).bind fun y => some (Nat.pair a y)) =
    (Option.map Nat.pair Option.none).bind fun a => Option.map a (evaln (k' + 1) cg n)

case succ.pair.intro.some
x✝ : Unit
p n : ℕ
this : List.range p = List.range (Nat.pair (unpair p).1 (encode (ofNat Code (unpair p).2)))
k' : ℕ
k : ℕ := k' + 1
nk : n ≤ k'
cf cg : Code
hg :
  ∀ {k' : ℕ} {c' : Code} {n : ℕ},
    Nat.pair k' (encode c') < Nat.pair k (encode (cf.pair cg)) →
      Nat.Partrec.Code.lup
          (List.map (fun n => List.map (evaln (unpair n).1 (ofNat Code (unpair n).2)) (List.range (unpair n).1))
            (List.range (Nat.pair k (encode (cf.pair cg)))))
          (k', c') n =
        evaln k' c' n
lf : encode cf < encode (cf.pair cg)
lg : encode cg < encode (cf.pair cg)
val✝ : ℕ
⊢ ((some val✝).bind fun a => (evaln k cg n).bind fun y => some (Nat.pair a y)) =
    (Option.map Nat.pair (some val✝)).bind fun a => Option.map a (evaln (k' + 1) cg n)