Theorem: Nat.Partrec.Code.hG
File: Mathlib/Computability/PartrecCode.lean

tactic: have a := (Primrec.ofNat (ℕ × Code)).comp (Primrec.list_length (α := List (Option ℕ)))
state_before: ⊢ Primrec Nat.Partrec.Code.G

tactic: have k := Primrec.fst.comp a
state_before: a : Primrec fun a => ofNat (ℕ × Code) (List.length a)
⊢ Primrec Nat.Partrec.Code.G

tactic: refine' Primrec.option_some.comp (Primrec.list_map (Primrec.list_range.comp k) (_ : Primrec _))
state_before: a : Primrec fun a => ofNat (ℕ × Code) (List.length a)
k : Primrec fun a => (ofNat (ℕ × Code) (List.length a)).fst
⊢ Primrec Nat.Partrec.Code.G

tactic: replace k := k.comp (Primrec.fst (β := ℕ))
state_before: a : Primrec fun a => ofNat (ℕ × Code) (List.length a)
k : Primrec fun a => (ofNat (ℕ × Code) (List.length a)).fst
⊢ Primrec fun p =>
    (fun a n =>
        Nat.casesOn (ofNat (ℕ × Code) (List.length a)).fst Option.none fun k' =>
          Code.recOn (ofNat (ℕ × Code) (List.length a)).snd (some 0) (some (Nat.succ n)) (some (unpair n).fst)
            (some (unpair n).snd)
            (fun cf cg x x => do
              let x ← Nat.Partrec.Code.lup a ((ofNat (ℕ × Code) (List.length a)).fst, cf) n
              let y ← Nat.Partrec.Code.lup a ((ofNat (ℕ × Code) (List.length a)).fst, cg) n
              some (Nat.pair x y))
            (fun cf cg x x => do
              let x ← Nat.Partrec.Code.lup a ((ofNat (ℕ × Code) (List.length a)).fst, cg) n
              Nat.Partrec.Code.lup a ((ofNat (ℕ × Code) (List.length a)).fst, cf) x)
            (fun cf cg x x =>
              let z := (unpair n).fst;
              Nat.casesOn (unpair n).snd (Nat.Partrec.Code.lup a ((ofNat (ℕ × Code) (List.length a)).fst, cf) z)
                fun y => do
                let i ← Nat.Partrec.Code.lup a (k', (ofNat (ℕ × Code) (List.length a)).snd) (Nat.pair z y)
                Nat.Partrec.Code.lup a ((ofNat (ℕ × Code) (List.length a)).fst, cg) (Nat.pair z (Nat.pair y i)))
            fun cf x =>
            let z := (unpair n).fst;
            let m := (unpair n).snd;
            do
            let x ← Nat.Partrec.Code.lup a ((ofNat (ℕ × Code) (List.length a)).fst, cf) (Nat.pair z m)
            Nat.casesOn x (some m) fun x =>
                Nat.Partrec.Code.lup a (k', (ofNat (ℕ × Code) (List.length a)).snd) (Nat.pair z (m + 1)))
      p.fst p.snd

tactic: have n := Primrec.snd (α := List (List (Option ℕ))) (β := ℕ)
state_before: a : Primrec fun a => ofNat (ℕ × Code) (List.length a)
k : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst)).fst
⊢ Primrec fun p =>
    (fun a n =>
        Nat.casesOn (ofNat (ℕ × Code) (List.length a)).fst Option.none fun k' =>
          Code.recOn (ofNat (ℕ × Code) (List.length a)).snd (some 0) (some (Nat.succ n)) (some (unpair n).fst)
            (some (unpair n).snd)
            (fun cf cg x x => do
              let x ← Nat.Partrec.Code.lup a ((ofNat (ℕ × Code) (List.length a)).fst, cf) n
              let y ← Nat.Partrec.Code.lup a ((ofNat (ℕ × Code) (List.length a)).fst, cg) n
              some (Nat.pair x y))
            (fun cf cg x x => do
              let x ← Nat.Partrec.Code.lup a ((ofNat (ℕ × Code) (List.length a)).fst, cg) n
              Nat.Partrec.Code.lup a ((ofNat (ℕ × Code) (List.length a)).fst, cf) x)
            (fun cf cg x x =>
              let z := (unpair n).fst;
              Nat.casesOn (unpair n).snd (Nat.Partrec.Code.lup a ((ofNat (ℕ × Code) (List.length a)).fst, cf) z)
                fun y => do
                let i ← Nat.Partrec.Code.lup a (k', (ofNat (ℕ × Code) (List.length a)).snd) (Nat.pair z y)
                Nat.Partrec.Code.lup a ((ofNat (ℕ × Code) (List.length a)).fst, cg) (Nat.pair z (Nat.pair y i)))
            fun cf x =>
            let z := (unpair n).fst;
            let m := (unpair n).snd;
            do
            let x ← Nat.Partrec.Code.lup a ((ofNat (ℕ × Code) (List.length a)).fst, cf) (Nat.pair z m)
            Nat.casesOn x (some m) fun x =>
                Nat.Partrec.Code.lup a (k', (ofNat (ℕ × Code) (List.length a)).snd) (Nat.pair z (m + 1)))
      p.fst p.snd

tactic: refine' Primrec.nat_casesOn k (_root_.Primrec.const Option.none) (_ : Primrec _)
state_before: a : Primrec fun a => ofNat (ℕ × Code) (List.length a)
k : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst)).fst
n : Primrec Prod.snd
⊢ Primrec fun p =>
    (fun a n =>
        Nat.casesOn (ofNat (ℕ × Code) (List.length a)).fst Option.none fun k' =>
          Code.recOn (ofNat (ℕ × Code) (List.length a)).snd (some 0) (some (Nat.succ n)) (some (unpair n).fst)
            (some (unpair n).snd)
            (fun cf cg x x => do
              let x ← Nat.Partrec.Code.lup a ((ofNat (ℕ × Code) (List.length a)).fst, cf) n
              let y ← Nat.Partrec.Code.lup a ((ofNat (ℕ × Code) (List.length a)).fst, cg) n
              some (Nat.pair x y))
            (fun cf cg x x => do
              let x ← Nat.Partrec.Code.lup a ((ofNat (ℕ × Code) (List.length a)).fst, cg) n
              Nat.Partrec.Code.lup a ((ofNat (ℕ × Code) (List.length a)).fst, cf) x)
            (fun cf cg x x =>
              let z := (unpair n).fst;
              Nat.casesOn (unpair n).snd (Nat.Partrec.Code.lup a ((ofNat (ℕ × Code) (List.length a)).fst, cf) z)
                fun y => do
                let i ← Nat.Partrec.Code.lup a (k', (ofNat (ℕ × Code) (List.length a)).snd) (Nat.pair z y)
                Nat.Partrec.Code.lup a ((ofNat (ℕ × Code) (List.length a)).fst, cg) (Nat.pair z (Nat.pair y i)))
            fun cf x =>
            let z := (unpair n).fst;
            let m := (unpair n).snd;
            do
            let x ← Nat.Partrec.Code.lup a ((ofNat (ℕ × Code) (List.length a)).fst, cf) (Nat.pair z m)
            Nat.casesOn x (some m) fun x =>
                Nat.Partrec.Code.lup a (k', (ofNat (ℕ × Code) (List.length a)).snd) (Nat.pair z (m + 1)))
      p.fst p.snd

tactic: have k := k.comp (Primrec.fst (β := ℕ))
state_before: a : Primrec fun a => ofNat (ℕ × Code) (List.length a)
k : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst)).fst
n : Primrec Prod.snd
⊢ Primrec fun p =>
    (fun p n =>
        (fun k' =>
            Code.recOn (ofNat (ℕ × Code) (List.length p.fst)).snd (some 0) (some (Nat.succ p.snd))
              (some (unpair p.snd).fst) (some (unpair p.snd).snd)
              (fun cf cg x x => do
                let x ← Nat.Partrec.Code.lup p.fst ((ofNat (ℕ × Code) (List.length p.fst)).fst, cf) p.snd
                let y ← Nat.Partrec.Code.lup p.fst ((ofNat (ℕ × Code) (List.length p.fst)).fst, cg) p.snd
                some (Nat.pair x y))
              (fun cf cg x x => do
                let x ← Nat.Partrec.Code.lup p.fst ((ofNat (ℕ × Code) (List.length p.fst)).fst, cg) p.snd
                Nat.Partrec.Code.lup p.fst ((ofNat (ℕ × Code) (List.length p.fst)).fst, cf) x)
              (fun cf cg x x =>
                let z := (unpair p.snd).fst;
                Nat.casesOn (unpair p.snd).snd
                  (Nat.Partrec.Code.lup p.fst ((ofNat (ℕ × Code) (List.length p.fst)).fst, cf) z) fun y => do
                  let i ← Nat.Partrec.Code.lup p.fst (k', (ofNat (ℕ × Code) (List.length p.fst)).snd) (Nat.pair z y)
                  Nat.Partrec.Code.lup p.fst ((ofNat (ℕ × Code) (List.length p.fst)).fst, cg)
                      (Nat.pair z (Nat.pair y i)))
              fun cf x =>
              let z := (unpair p.snd).fst;
              let m := (unpair p.snd).snd;
              do
              let x ← Nat.Partrec.Code.lup p.fst ((ofNat (ℕ × Code) (List.length p.fst)).fst, cf) (Nat.pair z m)
              Nat.casesOn x (some m) fun x =>
                  Nat.Partrec.Code.lup p.fst (k', (ofNat (ℕ × Code) (List.length p.fst)).snd) (Nat.pair z (m + 1)))
          n)
      p.fst p.snd

tactic: have n := n.comp (Primrec.fst (β := ℕ))
state_before: a : Primrec fun a => ofNat (ℕ × Code) (List.length a)
k✝ : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst)).fst
n : Primrec Prod.snd
k : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst.fst)).fst
⊢ Primrec fun p =>
    (fun p n =>
        (fun k' =>
            Code.recOn (ofNat (ℕ × Code) (List.length p.fst)).snd (some 0) (some (Nat.succ p.snd))
              (some (unpair p.snd).fst) (some (unpair p.snd).snd)
              (fun cf cg x x => do
                let x ← Nat.Partrec.Code.lup p.fst ((ofNat (ℕ × Code) (List.length p.fst)).fst, cf) p.snd
                let y ← Nat.Partrec.Code.lup p.fst ((ofNat (ℕ × Code) (List.length p.fst)).fst, cg) p.snd
                some (Nat.pair x y))
              (fun cf cg x x => do
                let x ← Nat.Partrec.Code.lup p.fst ((ofNat (ℕ × Code) (List.length p.fst)).fst, cg) p.snd
                Nat.Partrec.Code.lup p.fst ((ofNat (ℕ × Code) (List.length p.fst)).fst, cf) x)
              (fun cf cg x x =>
                let z := (unpair p.snd).fst;
                Nat.casesOn (unpair p.snd).snd
                  (Nat.Partrec.Code.lup p.fst ((ofNat (ℕ × Code) (List.length p.fst)).fst, cf) z) fun y => do
                  let i ← Nat.Partrec.Code.lup p.fst (k', (ofNat (ℕ × Code) (List.length p.fst)).snd) (Nat.pair z y)
                  Nat.Partrec.Code.lup p.fst ((ofNat (ℕ × Code) (List.length p.fst)).fst, cg)
                      (Nat.pair z (Nat.pair y i)))
              fun cf x =>
              let z := (unpair p.snd).fst;
              let m := (unpair p.snd).snd;
              do
              let x ← Nat.Partrec.Code.lup p.fst ((ofNat (ℕ × Code) (List.length p.fst)).fst, cf) (Nat.pair z m)
              Nat.casesOn x (some m) fun x =>
                  Nat.Partrec.Code.lup p.fst (k', (ofNat (ℕ × Code) (List.length p.fst)).snd) (Nat.pair z (m + 1)))
          n)
      p.fst p.snd

tactic: have k' := Primrec.snd (α := List (List (Option ℕ)) × ℕ) (β := ℕ)
state_before: a : Primrec fun a => ofNat (ℕ × Code) (List.length a)
k✝ : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst)).fst
n✝ : Primrec Prod.snd
k : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst.fst)).fst
n : Primrec fun a => a.fst.snd
⊢ Primrec fun p =>
    (fun p n =>
        (fun k' =>
            Code.recOn (ofNat (ℕ × Code) (List.length p.fst)).snd (some 0) (some (Nat.succ p.snd))
              (some (unpair p.snd).fst) (some (unpair p.snd).snd)
              (fun cf cg x x => do
                let x ← Nat.Partrec.Code.lup p.fst ((ofNat (ℕ × Code) (List.length p.fst)).fst, cf) p.snd
                let y ← Nat.Partrec.Code.lup p.fst ((ofNat (ℕ × Code) (List.length p.fst)).fst, cg) p.snd
                some (Nat.pair x y))
              (fun cf cg x x => do
                let x ← Nat.Partrec.Code.lup p.fst ((ofNat (ℕ × Code) (List.length p.fst)).fst, cg) p.snd
                Nat.Partrec.Code.lup p.fst ((ofNat (ℕ × Code) (List.length p.fst)).fst, cf) x)
              (fun cf cg x x =>
                let z := (unpair p.snd).fst;
                Nat.casesOn (unpair p.snd).snd
                  (Nat.Partrec.Code.lup p.fst ((ofNat (ℕ × Code) (List.length p.fst)).fst, cf) z) fun y => do
                  let i ← Nat.Partrec.Code.lup p.fst (k', (ofNat (ℕ × Code) (List.length p.fst)).snd) (Nat.pair z y)
                  Nat.Partrec.Code.lup p.fst ((ofNat (ℕ × Code) (List.length p.fst)).fst, cg)
                      (Nat.pair z (Nat.pair y i)))
              fun cf x =>
              let z := (unpair p.snd).fst;
              let m := (unpair p.snd).snd;
              do
              let x ← Nat.Partrec.Code.lup p.fst ((ofNat (ℕ × Code) (List.length p.fst)).fst, cf) (Nat.pair z m)
              Nat.casesOn x (some m) fun x =>
                  Nat.Partrec.Code.lup p.fst (k', (ofNat (ℕ × Code) (List.length p.fst)).snd) (Nat.pair z (m + 1)))
          n)
      p.fst p.snd

tactic: have c := Primrec.snd.comp (a.comp <| (Primrec.fst (β := ℕ)).comp (Primrec.fst (β := ℕ)))
state_before: a : Primrec fun a => ofNat (ℕ × Code) (List.length a)
k✝ : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst)).fst
n✝ : Primrec Prod.snd
k : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst.fst)).fst
n : Primrec fun a => a.fst.snd
k' : Primrec Prod.snd
⊢ Primrec fun p =>
    (fun p n =>
        (fun k' =>
            Code.recOn (ofNat (ℕ × Code) (List.length p.fst)).snd (some 0) (some (Nat.succ p.snd))
              (some (unpair p.snd).fst) (some (unpair p.snd).snd)
              (fun cf cg x x => do
                let x ← Nat.Partrec.Code.lup p.fst ((ofNat (ℕ × Code) (List.length p.fst)).fst, cf) p.snd
                let y ← Nat.Partrec.Code.lup p.fst ((ofNat (ℕ × Code) (List.length p.fst)).fst, cg) p.snd
                some (Nat.pair x y))
              (fun cf cg x x => do
                let x ← Nat.Partrec.Code.lup p.fst ((ofNat (ℕ × Code) (List.length p.fst)).fst, cg) p.snd
                Nat.Partrec.Code.lup p.fst ((ofNat (ℕ × Code) (List.length p.fst)).fst, cf) x)
              (fun cf cg x x =>
                let z := (unpair p.snd).fst;
                Nat.casesOn (unpair p.snd).snd
                  (Nat.Partrec.Code.lup p.fst ((ofNat (ℕ × Code) (List.length p.fst)).fst, cf) z) fun y => do
                  let i ← Nat.Partrec.Code.lup p.fst (k', (ofNat (ℕ × Code) (List.length p.fst)).snd) (Nat.pair z y)
                  Nat.Partrec.Code.lup p.fst ((ofNat (ℕ × Code) (List.length p.fst)).fst, cg)
                      (Nat.pair z (Nat.pair y i)))
              fun cf x =>
              let z := (unpair p.snd).fst;
              let m := (unpair p.snd).snd;
              do
              let x ← Nat.Partrec.Code.lup p.fst ((ofNat (ℕ × Code) (List.length p.fst)).fst, cf) (Nat.pair z m)
              Nat.casesOn x (some m) fun x =>
                  Nat.Partrec.Code.lup p.fst (k', (ofNat (ℕ × Code) (List.length p.fst)).snd) (Nat.pair z (m + 1)))
          n)
      p.fst p.snd

tactic: apply
  Nat.Partrec.Code.rec_prim c
    (_root_.Primrec.const (some 0))
    (Primrec.option_some.comp (_root_.Primrec.succ.comp n))
    (Primrec.option_some.comp (Primrec.fst.comp <| Primrec.unpair.comp n))
    (Primrec.option_some.comp (Primrec.snd.comp <| Primrec.unpair.comp n))
state_before: a : Primrec fun a => ofNat (ℕ × Code) (List.length a)
k✝ : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst)).fst
n✝ : Primrec Prod.snd
k : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst.fst)).fst
n : Primrec fun a => a.fst.snd
k' : Primrec Prod.snd
c : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst.fst)).snd
⊢ Primrec fun p =>
    (fun p n =>
        (fun k' =>
            Code.recOn (ofNat (ℕ × Code) (List.length p.fst)).snd (some 0) (some (Nat.succ p.snd))
              (some (unpair p.snd).fst) (some (unpair p.snd).snd)
              (fun cf cg x x => do
                let x ← Nat.Partrec.Code.lup p.fst ((ofNat (ℕ × Code) (List.length p.fst)).fst, cf) p.snd
                let y ← Nat.Partrec.Code.lup p.fst ((ofNat (ℕ × Code) (List.length p.fst)).fst, cg) p.snd
                some (Nat.pair x y))
              (fun cf cg x x => do
                let x ← Nat.Partrec.Code.lup p.fst ((ofNat (ℕ × Code) (List.length p.fst)).fst, cg) p.snd
                Nat.Partrec.Code.lup p.fst ((ofNat (ℕ × Code) (List.length p.fst)).fst, cf) x)
              (fun cf cg x x =>
                let z := (unpair p.snd).fst;
                Nat.casesOn (unpair p.snd).snd
                  (Nat.Partrec.Code.lup p.fst ((ofNat (ℕ × Code) (List.length p.fst)).fst, cf) z) fun y => do
                  let i ← Nat.Partrec.Code.lup p.fst (k', (ofNat (ℕ × Code) (List.length p.fst)).snd) (Nat.pair z y)
                  Nat.Partrec.Code.lup p.fst ((ofNat (ℕ × Code) (List.length p.fst)).fst, cg)
                      (Nat.pair z (Nat.pair y i)))
              fun cf x =>
              let z := (unpair p.snd).fst;
              let m := (unpair p.snd).snd;
              do
              let x ← Nat.Partrec.Code.lup p.fst ((ofNat (ℕ × Code) (List.length p.fst)).fst, cf) (Nat.pair z m)
              Nat.casesOn x (some m) fun x =>
                  Nat.Partrec.Code.lup p.fst (k', (ofNat (ℕ × Code) (List.length p.fst)).snd) (Nat.pair z (m + 1)))
          n)
      p.fst p.snd

tactic: have L := (Primrec.fst.comp Primrec.fst).comp
  (Primrec.fst (α := (List (List (Option ℕ)) × ℕ) × ℕ)
    (β := Code × Code × Option ℕ × Option ℕ))
state_before: case hpr
a : Primrec fun a => ofNat (ℕ × Code) (List.length a)
k✝ : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst)).fst
n✝ : Primrec Prod.snd
k : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst.fst)).fst
n : Primrec fun a => a.fst.snd
k' : Primrec Prod.snd
c : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst.fst)).snd
⊢ Primrec fun a => do
    let x ←
      Nat.Partrec.Code.lup a.fst.fst.fst ((ofNat (ℕ × Code) (List.length a.fst.fst.fst)).fst, a.snd.fst) a.fst.fst.snd
    let y ←
      Nat.Partrec.Code.lup a.fst.fst.fst ((ofNat (ℕ × Code) (List.length a.fst.fst.fst)).fst, a.snd.snd.fst)
          a.fst.fst.snd
    some (Nat.pair x y)

tactic: have k := k.comp (Primrec.fst (β := Code × Code × Option ℕ × Option ℕ))
state_before: case hpr
a : Primrec fun a => ofNat (ℕ × Code) (List.length a)
k✝ : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst)).fst
n✝ : Primrec Prod.snd
k : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst.fst)).fst
n : Primrec fun a => a.fst.snd
k' : Primrec Prod.snd
c : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst.fst)).snd
L : Primrec fun a => a.fst.fst.fst
⊢ Primrec fun a => do
    let x ←
      Nat.Partrec.Code.lup a.fst.fst.fst ((ofNat (ℕ × Code) (List.length a.fst.fst.fst)).fst, a.snd.fst) a.fst.fst.snd
    let y ←
      Nat.Partrec.Code.lup a.fst.fst.fst ((ofNat (ℕ × Code) (List.length a.fst.fst.fst)).fst, a.snd.snd.fst)
          a.fst.fst.snd
    some (Nat.pair x y)

tactic: have n := n.comp (Primrec.fst (β := Code × Code × Option ℕ × Option ℕ))
state_before: case hpr
a : Primrec fun a => ofNat (ℕ × Code) (List.length a)
k✝¹ : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst)).fst
n✝ : Primrec Prod.snd
k✝ : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst.fst)).fst
n : Primrec fun a => a.fst.snd
k' : Primrec Prod.snd
c : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst.fst)).snd
L : Primrec fun a => a.fst.fst.fst
k : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst.fst.fst)).fst
⊢ Primrec fun a => do
    let x ←
      Nat.Partrec.Code.lup a.fst.fst.fst ((ofNat (ℕ × Code) (List.length a.fst.fst.fst)).fst, a.snd.fst) a.fst.fst.snd
    let y ←
      Nat.Partrec.Code.lup a.fst.fst.fst ((ofNat (ℕ × Code) (List.length a.fst.fst.fst)).fst, a.snd.snd.fst)
          a.fst.fst.snd
    some (Nat.pair x y)

tactic: have cf := Primrec.fst.comp (Primrec.snd (α := (List (List (Option ℕ)) × ℕ) × ℕ)
    (β := Code × Code × Option ℕ × Option ℕ))
state_before: case hpr
a : Primrec fun a => ofNat (ℕ × Code) (List.length a)
k✝¹ : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst)).fst
n✝¹ : Primrec Prod.snd
k✝ : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst.fst)).fst
n✝ : Primrec fun a => a.fst.snd
k' : Primrec Prod.snd
c : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst.fst)).snd
L : Primrec fun a => a.fst.fst.fst
k : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst.fst.fst)).fst
n : Primrec fun a => a.fst.fst.snd
⊢ Primrec fun a => do
    let x ←
      Nat.Partrec.Code.lup a.fst.fst.fst ((ofNat (ℕ × Code) (List.length a.fst.fst.fst)).fst, a.snd.fst) a.fst.fst.snd
    let y ←
      Nat.Partrec.Code.lup a.fst.fst.fst ((ofNat (ℕ × Code) (List.length a.fst.fst.fst)).fst, a.snd.snd.fst)
          a.fst.fst.snd
    some (Nat.pair x y)

tactic: have cg := (Primrec.fst.comp Primrec.snd).comp
  (Primrec.snd (α := (List (List (Option ℕ)) × ℕ) × ℕ)
    (β := Code × Code × Option ℕ × Option ℕ))
state_before: case hpr
a : Primrec fun a => ofNat (ℕ × Code) (List.length a)
k✝¹ : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst)).fst
n✝¹ : Primrec Prod.snd
k✝ : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst.fst)).fst
n✝ : Primrec fun a => a.fst.snd
k' : Primrec Prod.snd
c : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst.fst)).snd
L : Primrec fun a => a.fst.fst.fst
k : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst.fst.fst)).fst
n : Primrec fun a => a.fst.fst.snd
cf : Primrec fun a => a.snd.fst
⊢ Primrec fun a => do
    let x ←
      Nat.Partrec.Code.lup a.fst.fst.fst ((ofNat (ℕ × Code) (List.length a.fst.fst.fst)).fst, a.snd.fst) a.fst.fst.snd
    let y ←
      Nat.Partrec.Code.lup a.fst.fst.fst ((ofNat (ℕ × Code) (List.length a.fst.fst.fst)).fst, a.snd.snd.fst)
          a.fst.fst.snd
    some (Nat.pair x y)

tactic: refine Primrec.option_bind (hlup.comp <| L.pair <| (k.pair cf).pair n) ?_
state_before: case hpr
a : Primrec fun a => ofNat (ℕ × Code) (List.length a)
k✝¹ : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst)).fst
n✝¹ : Primrec Prod.snd
k✝ : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst.fst)).fst
n✝ : Primrec fun a => a.fst.snd
k' : Primrec Prod.snd
c : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst.fst)).snd
L : Primrec fun a => a.fst.fst.fst
k : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst.fst.fst)).fst
n : Primrec fun a => a.fst.fst.snd
cf : Primrec fun a => a.snd.fst
cg : Primrec fun a => a.snd.snd.fst
⊢ Primrec fun a => do
    let x ←
      Nat.Partrec.Code.lup a.fst.fst.fst ((ofNat (ℕ × Code) (List.length a.fst.fst.fst)).fst, a.snd.fst) a.fst.fst.snd
    let y ←
      Nat.Partrec.Code.lup a.fst.fst.fst ((ofNat (ℕ × Code) (List.length a.fst.fst.fst)).fst, a.snd.snd.fst)
          a.fst.fst.snd
    some (Nat.pair x y)

tactic: unfold Primrec₂
state_before: case hpr
a : Primrec fun a => ofNat (ℕ × Code) (List.length a)
k✝¹ : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst)).fst
n✝¹ : Primrec Prod.snd
k✝ : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst.fst)).fst
n✝ : Primrec fun a => a.fst.snd
k' : Primrec Prod.snd
c : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst.fst)).snd
L : Primrec fun a => a.fst.fst.fst
k : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst.fst.fst)).fst
n : Primrec fun a => a.fst.fst.snd
cf : Primrec fun a => a.snd.fst
cg : Primrec fun a => a.snd.snd.fst
⊢ Primrec₂ fun a x => do
    let y ←
      Nat.Partrec.Code.lup a.fst.fst.fst ((ofNat (ℕ × Code) (List.length a.fst.fst.fst)).fst, a.snd.snd.fst)
          a.fst.fst.snd
    some (Nat.pair x y)

tactic: refine Primrec.option_map ((hlup.comp <| L.pair <| (k.pair cg).pair n).comp Primrec.fst) ?_
state_before: case hpr
a : Primrec fun a => ofNat (ℕ × Code) (List.length a)
k✝¹ : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst)).fst
n✝¹ : Primrec Prod.snd
k✝ : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst.fst)).fst
n✝ : Primrec fun a => a.fst.snd
k' : Primrec Prod.snd
c : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst.fst)).snd
L : Primrec fun a => a.fst.fst.fst
k : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst.fst.fst)).fst
n : Primrec fun a => a.fst.fst.snd
cf : Primrec fun a => a.snd.fst
cg : Primrec fun a => a.snd.snd.fst
⊢ Primrec fun p =>
    Option.map (fun y => Nat.pair p.snd y)
      (Nat.Partrec.Code.lup p.fst.fst.fst.fst
        ((ofNat (ℕ × Code) (List.length p.fst.fst.fst.fst)).fst, p.fst.snd.snd.fst) p.fst.fst.fst.snd)

tactic: unfold Primrec₂
state_before: case hpr
a : Primrec fun a => ofNat (ℕ × Code) (List.length a)
k✝¹ : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst)).fst
n✝¹ : Primrec Prod.snd
k✝ : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst.fst)).fst
n✝ : Primrec fun a => a.fst.snd
k' : Primrec Prod.snd
c : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst.fst)).snd
L : Primrec fun a => a.fst.fst.fst
k : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst.fst.fst)).fst
n : Primrec fun a => a.fst.fst.snd
cf : Primrec fun a => a.snd.fst
cg : Primrec fun a => a.snd.snd.fst
⊢ Primrec₂ fun p y => Nat.pair p.snd y

tactic: exact Primrec₂.natPair.comp (Primrec.snd.comp Primrec.fst) Primrec.snd
state_before: case hpr
a : Primrec fun a => ofNat (ℕ × Code) (List.length a)
k✝¹ : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst)).fst
n✝¹ : Primrec Prod.snd
k✝ : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst.fst)).fst
n✝ : Primrec fun a => a.fst.snd
k' : Primrec Prod.snd
c : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst.fst)).snd
L : Primrec fun a => a.fst.fst.fst
k : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst.fst.fst)).fst
n : Primrec fun a => a.fst.fst.snd
cf : Primrec fun a => a.snd.fst
cg : Primrec fun a => a.snd.snd.fst
⊢ Primrec fun p => (fun p y => Nat.pair p.snd y) p.fst p.snd

tactic: have L := (Primrec.fst.comp Primrec.fst).comp
  (Primrec.fst (α := (List (List (Option ℕ)) × ℕ) × ℕ)
    (β := Code × Code × Option ℕ × Option ℕ))
state_before: case hco
a : Primrec fun a => ofNat (ℕ × Code) (List.length a)
k✝ : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst)).fst
n✝ : Primrec Prod.snd
k : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst.fst)).fst
n : Primrec fun a => a.fst.snd
k' : Primrec Prod.snd
c : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst.fst)).snd
⊢ Primrec fun a => do
    let x ←
      Nat.Partrec.Code.lup a.fst.fst.fst ((ofNat (ℕ × Code) (List.length a.fst.fst.fst)).fst, a.snd.snd.fst)
          a.fst.fst.snd
    Nat.Partrec.Code.lup a.fst.fst.fst ((ofNat (ℕ × Code) (List.length a.fst.fst.fst)).fst, a.snd.fst) x

tactic: have k := k.comp (Primrec.fst (β := Code × Code × Option ℕ × Option ℕ))
state_before: case hco
a : Primrec fun a => ofNat (ℕ × Code) (List.length a)
k✝ : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst)).fst
n✝ : Primrec Prod.snd
k : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst.fst)).fst
n : Primrec fun a => a.fst.snd
k' : Primrec Prod.snd
c : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst.fst)).snd
L : Primrec fun a => a.fst.fst.fst
⊢ Primrec fun a => do
    let x ←
      Nat.Partrec.Code.lup a.fst.fst.fst ((ofNat (ℕ × Code) (List.length a.fst.fst.fst)).fst, a.snd.snd.fst)
          a.fst.fst.snd
    Nat.Partrec.Code.lup a.fst.fst.fst ((ofNat (ℕ × Code) (List.length a.fst.fst.fst)).fst, a.snd.fst) x

tactic: have n := n.comp (Primrec.fst (β := Code × Code × Option ℕ × Option ℕ))
state_before: case hco
a : Primrec fun a => ofNat (ℕ × Code) (List.length a)
k✝¹ : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst)).fst
n✝ : Primrec Prod.snd
k✝ : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst.fst)).fst
n : Primrec fun a => a.fst.snd
k' : Primrec Prod.snd
c : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst.fst)).snd
L : Primrec fun a => a.fst.fst.fst
k : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst.fst.fst)).fst
⊢ Primrec fun a => do
    let x ←
      Nat.Partrec.Code.lup a.fst.fst.fst ((ofNat (ℕ × Code) (List.length a.fst.fst.fst)).fst, a.snd.snd.fst)
          a.fst.fst.snd
    Nat.Partrec.Code.lup a.fst.fst.fst ((ofNat (ℕ × Code) (List.length a.fst.fst.fst)).fst, a.snd.fst) x

tactic: have cf := Primrec.fst.comp (Primrec.snd (α := (List (List (Option ℕ)) × ℕ) × ℕ)
    (β := Code × Code × Option ℕ × Option ℕ))
state_before: case hco
a : Primrec fun a => ofNat (ℕ × Code) (List.length a)
k✝¹ : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst)).fst
n✝¹ : Primrec Prod.snd
k✝ : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst.fst)).fst
n✝ : Primrec fun a => a.fst.snd
k' : Primrec Prod.snd
c : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst.fst)).snd
L : Primrec fun a => a.fst.fst.fst
k : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst.fst.fst)).fst
n : Primrec fun a => a.fst.fst.snd
⊢ Primrec fun a => do
    let x ←
      Nat.Partrec.Code.lup a.fst.fst.fst ((ofNat (ℕ × Code) (List.length a.fst.fst.fst)).fst, a.snd.snd.fst)
          a.fst.fst.snd
    Nat.Partrec.Code.lup a.fst.fst.fst ((ofNat (ℕ × Code) (List.length a.fst.fst.fst)).fst, a.snd.fst) x

tactic: have cg := (Primrec.fst.comp Primrec.snd).comp
  (Primrec.snd (α := (List (List (Option ℕ)) × ℕ) × ℕ)
    (β := Code × Code × Option ℕ × Option ℕ))
state_before: case hco
a : Primrec fun a => ofNat (ℕ × Code) (List.length a)
k✝¹ : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst)).fst
n✝¹ : Primrec Prod.snd
k✝ : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst.fst)).fst
n✝ : Primrec fun a => a.fst.snd
k' : Primrec Prod.snd
c : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst.fst)).snd
L : Primrec fun a => a.fst.fst.fst
k : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst.fst.fst)).fst
n : Primrec fun a => a.fst.fst.snd
cf : Primrec fun a => a.snd.fst
⊢ Primrec fun a => do
    let x ←
      Nat.Partrec.Code.lup a.fst.fst.fst ((ofNat (ℕ × Code) (List.length a.fst.fst.fst)).fst, a.snd.snd.fst)
          a.fst.fst.snd
    Nat.Partrec.Code.lup a.fst.fst.fst ((ofNat (ℕ × Code) (List.length a.fst.fst.fst)).fst, a.snd.fst) x

tactic: refine Primrec.option_bind (hlup.comp <| L.pair <| (k.pair cg).pair n) ?_
state_before: case hco
a : Primrec fun a => ofNat (ℕ × Code) (List.length a)
k✝¹ : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst)).fst
n✝¹ : Primrec Prod.snd
k✝ : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst.fst)).fst
n✝ : Primrec fun a => a.fst.snd
k' : Primrec Prod.snd
c : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst.fst)).snd
L : Primrec fun a => a.fst.fst.fst
k : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst.fst.fst)).fst
n : Primrec fun a => a.fst.fst.snd
cf : Primrec fun a => a.snd.fst
cg : Primrec fun a => a.snd.snd.fst
⊢ Primrec fun a => do
    let x ←
      Nat.Partrec.Code.lup a.fst.fst.fst ((ofNat (ℕ × Code) (List.length a.fst.fst.fst)).fst, a.snd.snd.fst)
          a.fst.fst.snd
    Nat.Partrec.Code.lup a.fst.fst.fst ((ofNat (ℕ × Code) (List.length a.fst.fst.fst)).fst, a.snd.fst) x

tactic: unfold Primrec₂
state_before: case hco
a : Primrec fun a => ofNat (ℕ × Code) (List.length a)
k✝¹ : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst)).fst
n✝¹ : Primrec Prod.snd
k✝ : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst.fst)).fst
n✝ : Primrec fun a => a.fst.snd
k' : Primrec Prod.snd
c : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst.fst)).snd
L : Primrec fun a => a.fst.fst.fst
k : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst.fst.fst)).fst
n : Primrec fun a => a.fst.fst.snd
cf : Primrec fun a => a.snd.fst
cg : Primrec fun a => a.snd.snd.fst
⊢ Primrec₂ fun a x =>
    Nat.Partrec.Code.lup a.fst.fst.fst ((ofNat (ℕ × Code) (List.length a.fst.fst.fst)).fst, a.snd.fst) x

tactic: have h :=
  hlup.comp ((L.comp Primrec.fst).pair <| ((k.pair cf).comp Primrec.fst).pair Primrec.snd)
state_before: case hco
a : Primrec fun a => ofNat (ℕ × Code) (List.length a)
k✝¹ : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst)).fst
n✝¹ : Primrec Prod.snd
k✝ : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst.fst)).fst
n✝ : Primrec fun a => a.fst.snd
k' : Primrec Prod.snd
c : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst.fst)).snd
L : Primrec fun a => a.fst.fst.fst
k : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst.fst.fst)).fst
n : Primrec fun a => a.fst.fst.snd
cf : Primrec fun a => a.snd.fst
cg : Primrec fun a => a.snd.snd.fst
⊢ Primrec fun p =>
    (fun a x => Nat.Partrec.Code.lup a.fst.fst.fst ((ofNat (ℕ × Code) (List.length a.fst.fst.fst)).fst, a.snd.fst) x)
      p.fst p.snd

tactic: exact h
state_before: case hco
a : Primrec fun a => ofNat (ℕ × Code) (List.length a)
k✝¹ : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst)).fst
n✝¹ : Primrec Prod.snd
k✝ : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst.fst)).fst
n✝ : Primrec fun a => a.fst.snd
k' : Primrec Prod.snd
c : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst.fst)).snd
L : Primrec fun a => a.fst.fst.fst
k : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst.fst.fst)).fst
n : Primrec fun a => a.fst.fst.snd
cf : Primrec fun a => a.snd.fst
cg : Primrec fun a => a.snd.snd.fst
h :
  Primrec fun a =>
    Nat.Partrec.Code.lup
      (a.fst.fst.fst.fst, ((ofNat (ℕ × Code) (List.length a.fst.fst.fst.fst)).fst, a.fst.snd.fst), a.snd).fst
      (a.fst.fst.fst.fst, ((ofNat (ℕ × Code) (List.length a.fst.fst.fst.fst)).fst, a.fst.snd.fst), a.snd).snd.fst
      (a.fst.fst.fst.fst, ((ofNat (ℕ × Code) (List.length a.fst.fst.fst.fst)).fst, a.fst.snd.fst), a.snd).snd.snd
⊢ Primrec fun p =>
    (fun a x => Nat.Partrec.Code.lup a.fst.fst.fst ((ofNat (ℕ × Code) (List.length a.fst.fst.fst)).fst, a.snd.fst) x)
      p.fst p.snd

tactic: have L := (Primrec.fst.comp Primrec.fst).comp
  (Primrec.fst (α := (List (List (Option ℕ)) × ℕ) × ℕ)
    (β := Code × Code × Option ℕ × Option ℕ))
state_before: case hpc
a : Primrec fun a => ofNat (ℕ × Code) (List.length a)
k✝ : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst)).fst
n✝ : Primrec Prod.snd
k : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst.fst)).fst
n : Primrec fun a => a.fst.snd
k' : Primrec Prod.snd
c : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst.fst)).snd
⊢ Primrec fun a =>
    let z := (unpair a.fst.fst.snd).fst;
    Nat.casesOn (unpair a.fst.fst.snd).snd
      (Nat.Partrec.Code.lup a.fst.fst.fst ((ofNat (ℕ × Code) (List.length a.fst.fst.fst)).fst, a.snd.fst) z) fun y => do
      let i ←
        Nat.Partrec.Code.lup a.fst.fst.fst (a.fst.snd, (ofNat (ℕ × Code) (List.length a.fst.fst.fst)).snd)
            (Nat.pair z y)
      Nat.Partrec.Code.lup a.fst.fst.fst ((ofNat (ℕ × Code) (List.length a.fst.fst.fst)).fst, a.snd.snd.fst)
          (Nat.pair z (Nat.pair y i))

tactic: have k := k.comp (Primrec.fst (β := Code × Code × Option ℕ × Option ℕ))
state_before: case hpc
a : Primrec fun a => ofNat (ℕ × Code) (List.length a)
k✝ : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst)).fst
n✝ : Primrec Prod.snd
k : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst.fst)).fst
n : Primrec fun a => a.fst.snd
k' : Primrec Prod.snd
c : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst.fst)).snd
L : Primrec fun a => a.fst.fst.fst
⊢ Primrec fun a =>
    let z := (unpair a.fst.fst.snd).fst;
    Nat.casesOn (unpair a.fst.fst.snd).snd
      (Nat.Partrec.Code.lup a.fst.fst.fst ((ofNat (ℕ × Code) (List.length a.fst.fst.fst)).fst, a.snd.fst) z) fun y => do
      let i ←
        Nat.Partrec.Code.lup a.fst.fst.fst (a.fst.snd, (ofNat (ℕ × Code) (List.length a.fst.fst.fst)).snd)
            (Nat.pair z y)
      Nat.Partrec.Code.lup a.fst.fst.fst ((ofNat (ℕ × Code) (List.length a.fst.fst.fst)).fst, a.snd.snd.fst)
          (Nat.pair z (Nat.pair y i))

tactic: have n := n.comp (Primrec.fst (β := Code × Code × Option ℕ × Option ℕ))
state_before: case hpc
a : Primrec fun a => ofNat (ℕ × Code) (List.length a)
k✝¹ : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst)).fst
n✝ : Primrec Prod.snd
k✝ : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst.fst)).fst
n : Primrec fun a => a.fst.snd
k' : Primrec Prod.snd
c : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst.fst)).snd
L : Primrec fun a => a.fst.fst.fst
k : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst.fst.fst)).fst
⊢ Primrec fun a =>
    let z := (unpair a.fst.fst.snd).fst;
    Nat.casesOn (unpair a.fst.fst.snd).snd
      (Nat.Partrec.Code.lup a.fst.fst.fst ((ofNat (ℕ × Code) (List.length a.fst.fst.fst)).fst, a.snd.fst) z) fun y => do
      let i ←
        Nat.Partrec.Code.lup a.fst.fst.fst (a.fst.snd, (ofNat (ℕ × Code) (List.length a.fst.fst.fst)).snd)
            (Nat.pair z y)
      Nat.Partrec.Code.lup a.fst.fst.fst ((ofNat (ℕ × Code) (List.length a.fst.fst.fst)).fst, a.snd.snd.fst)
          (Nat.pair z (Nat.pair y i))

tactic: have cf := Primrec.fst.comp (Primrec.snd (α := (List (List (Option ℕ)) × ℕ) × ℕ)
    (β := Code × Code × Option ℕ × Option ℕ))
state_before: case hpc
a : Primrec fun a => ofNat (ℕ × Code) (List.length a)
k✝¹ : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst)).fst
n✝¹ : Primrec Prod.snd
k✝ : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst.fst)).fst
n✝ : Primrec fun a => a.fst.snd
k' : Primrec Prod.snd
c : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst.fst)).snd
L : Primrec fun a => a.fst.fst.fst
k : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst.fst.fst)).fst
n : Primrec fun a => a.fst.fst.snd
⊢ Primrec fun a =>
    let z := (unpair a.fst.fst.snd).fst;
    Nat.casesOn (unpair a.fst.fst.snd).snd
      (Nat.Partrec.Code.lup a.fst.fst.fst ((ofNat (ℕ × Code) (List.length a.fst.fst.fst)).fst, a.snd.fst) z) fun y => do
      let i ←
        Nat.Partrec.Code.lup a.fst.fst.fst (a.fst.snd, (ofNat (ℕ × Code) (List.length a.fst.fst.fst)).snd)
            (Nat.pair z y)
      Nat.Partrec.Code.lup a.fst.fst.fst ((ofNat (ℕ × Code) (List.length a.fst.fst.fst)).fst, a.snd.snd.fst)
          (Nat.pair z (Nat.pair y i))

tactic: have cg := (Primrec.fst.comp Primrec.snd).comp
  (Primrec.snd (α := (List (List (Option ℕ)) × ℕ) × ℕ)
    (β := Code × Code × Option ℕ × Option ℕ))
state_before: case hpc
a : Primrec fun a => ofNat (ℕ × Code) (List.length a)
k✝¹ : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst)).fst
n✝¹ : Primrec Prod.snd
k✝ : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst.fst)).fst
n✝ : Primrec fun a => a.fst.snd
k' : Primrec Prod.snd
c : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst.fst)).snd
L : Primrec fun a => a.fst.fst.fst
k : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst.fst.fst)).fst
n : Primrec fun a => a.fst.fst.snd
cf : Primrec fun a => a.snd.fst
⊢ Primrec fun a =>
    let z := (unpair a.fst.fst.snd).fst;
    Nat.casesOn (unpair a.fst.fst.snd).snd
      (Nat.Partrec.Code.lup a.fst.fst.fst ((ofNat (ℕ × Code) (List.length a.fst.fst.fst)).fst, a.snd.fst) z) fun y => do
      let i ←
        Nat.Partrec.Code.lup a.fst.fst.fst (a.fst.snd, (ofNat (ℕ × Code) (List.length a.fst.fst.fst)).snd)
            (Nat.pair z y)
      Nat.Partrec.Code.lup a.fst.fst.fst ((ofNat (ℕ × Code) (List.length a.fst.fst.fst)).fst, a.snd.snd.fst)
          (Nat.pair z (Nat.pair y i))

tactic: have z := Primrec.fst.comp (Primrec.unpair.comp n)
state_before: case hpc
a : Primrec fun a => ofNat (ℕ × Code) (List.length a)
k✝¹ : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst)).fst
n✝¹ : Primrec Prod.snd
k✝ : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst.fst)).fst
n✝ : Primrec fun a => a.fst.snd
k' : Primrec Prod.snd
c : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst.fst)).snd
L : Primrec fun a => a.fst.fst.fst
k : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst.fst.fst)).fst
n : Primrec fun a => a.fst.fst.snd
cf : Primrec fun a => a.snd.fst
cg : Primrec fun a => a.snd.snd.fst
⊢ Primrec fun a =>
    let z := (unpair a.fst.fst.snd).fst;
    Nat.casesOn (unpair a.fst.fst.snd).snd
      (Nat.Partrec.Code.lup a.fst.fst.fst ((ofNat (ℕ × Code) (List.length a.fst.fst.fst)).fst, a.snd.fst) z) fun y => do
      let i ←
        Nat.Partrec.Code.lup a.fst.fst.fst (a.fst.snd, (ofNat (ℕ × Code) (List.length a.fst.fst.fst)).snd)
            (Nat.pair z y)
      Nat.Partrec.Code.lup a.fst.fst.fst ((ofNat (ℕ × Code) (List.length a.fst.fst.fst)).fst, a.snd.snd.fst)
          (Nat.pair z (Nat.pair y i))

tactic: refine'
  Primrec.nat_casesOn (Primrec.snd.comp (Primrec.unpair.comp n))
    (hlup.comp <| L.pair <| (k.pair cf).pair z)
    (_ : Primrec _)
state_before: case hpc
a : Primrec fun a => ofNat (ℕ × Code) (List.length a)
k✝¹ : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst)).fst
n✝¹ : Primrec Prod.snd
k✝ : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst.fst)).fst
n✝ : Primrec fun a => a.fst.snd
k' : Primrec Prod.snd
c : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst.fst)).snd
L : Primrec fun a => a.fst.fst.fst
k : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst.fst.fst)).fst
n : Primrec fun a => a.fst.fst.snd
cf : Primrec fun a => a.snd.fst
cg : Primrec fun a => a.snd.snd.fst
z : Primrec fun a => (unpair a.fst.fst.snd).fst
⊢ Primrec fun a =>
    let z := (unpair a.fst.fst.snd).fst;
    Nat.casesOn (unpair a.fst.fst.snd).snd
      (Nat.Partrec.Code.lup a.fst.fst.fst ((ofNat (ℕ × Code) (List.length a.fst.fst.fst)).fst, a.snd.fst) z) fun y => do
      let i ←
        Nat.Partrec.Code.lup a.fst.fst.fst (a.fst.snd, (ofNat (ℕ × Code) (List.length a.fst.fst.fst)).snd)
            (Nat.pair z y)
      Nat.Partrec.Code.lup a.fst.fst.fst ((ofNat (ℕ × Code) (List.length a.fst.fst.fst)).fst, a.snd.snd.fst)
          (Nat.pair z (Nat.pair y i))

tactic: have L := L.comp (Primrec.fst (β := ℕ))
state_before: case hpc
a : Primrec fun a => ofNat (ℕ × Code) (List.length a)
k✝¹ : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst)).fst
n✝¹ : Primrec Prod.snd
k✝ : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst.fst)).fst
n✝ : Primrec fun a => a.fst.snd
k' : Primrec Prod.snd
c : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst.fst)).snd
L : Primrec fun a => a.fst.fst.fst
k : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst.fst.fst)).fst
n : Primrec fun a => a.fst.fst.snd
cf : Primrec fun a => a.snd.fst
cg : Primrec fun a => a.snd.snd.fst
z : Primrec fun a => (unpair a.fst.fst.snd).fst
⊢ Primrec fun p =>
    (fun a n =>
        (fun y => do
            let i ←
              Nat.Partrec.Code.lup a.fst.fst.fst (a.fst.snd, (ofNat (ℕ × Code) (List.length a.fst.fst.fst)).snd)
                  (Nat.pair (unpair a.fst.fst.snd).fst y)
            Nat.Partrec.Code.lup a.fst.fst.fst ((ofNat (ℕ × Code) (List.length a.fst.fst.fst)).fst, a.snd.snd.fst)
                (Nat.pair (unpair a.fst.fst.snd).fst (Nat.pair y i)))
          n)
      p.fst p.snd

tactic: have z := z.comp (Primrec.fst (β := ℕ))
state_before: case hpc
a : Primrec fun a => ofNat (ℕ × Code) (List.length a)
k✝¹ : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst)).fst
n✝¹ : Primrec Prod.snd
k✝ : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst.fst)).fst
n✝ : Primrec fun a => a.fst.snd
k' : Primrec Prod.snd
c : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst.fst)).snd
L✝ : Primrec fun a => a.fst.fst.fst
k : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst.fst.fst)).fst
n : Primrec fun a => a.fst.fst.snd
cf : Primrec fun a => a.snd.fst
cg : Primrec fun a => a.snd.snd.fst
z : Primrec fun a => (unpair a.fst.fst.snd).fst
L : Primrec fun a => a.fst.fst.fst.fst
⊢ Primrec fun p =>
    (fun a n =>
        (fun y => do
            let i ←
              Nat.Partrec.Code.lup a.fst.fst.fst (a.fst.snd, (ofNat (ℕ × Code) (List.length a.fst.fst.fst)).snd)
                  (Nat.pair (unpair a.fst.fst.snd).fst y)
            Nat.Partrec.Code.lup a.fst.fst.fst ((ofNat (ℕ × Code) (List.length a.fst.fst.fst)).fst, a.snd.snd.fst)
                (Nat.pair (unpair a.fst.fst.snd).fst (Nat.pair y i)))
          n)
      p.fst p.snd

tactic: have y := Primrec.snd
  (α := ((List (List (Option ℕ)) × ℕ) × ℕ) × Code × Code × Option ℕ × Option ℕ) (β := ℕ)
state_before: case hpc
a : Primrec fun a => ofNat (ℕ × Code) (List.length a)
k✝¹ : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst)).fst
n✝¹ : Primrec Prod.snd
k✝ : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst.fst)).fst
n✝ : Primrec fun a => a.fst.snd
k' : Primrec Prod.snd
c : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst.fst)).snd
L✝ : Primrec fun a => a.fst.fst.fst
k : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst.fst.fst)).fst
n : Primrec fun a => a.fst.fst.snd
cf : Primrec fun a => a.snd.fst
cg : Primrec fun a => a.snd.snd.fst
z✝ : Primrec fun a => (unpair a.fst.fst.snd).fst
L : Primrec fun a => a.fst.fst.fst.fst
z : Primrec fun a => (unpair a.fst.fst.fst.snd).fst
⊢ Primrec fun p =>
    (fun a n =>
        (fun y => do
            let i ←
              Nat.Partrec.Code.lup a.fst.fst.fst (a.fst.snd, (ofNat (ℕ × Code) (List.length a.fst.fst.fst)).snd)
                  (Nat.pair (unpair a.fst.fst.snd).fst y)
            Nat.Partrec.Code.lup a.fst.fst.fst ((ofNat (ℕ × Code) (List.length a.fst.fst.fst)).fst, a.snd.snd.fst)
                (Nat.pair (unpair a.fst.fst.snd).fst (Nat.pair y i)))
          n)
      p.fst p.snd

tactic: have h₁ := hlup.comp <| L.pair <| (((k'.pair c).comp Primrec.fst).comp Primrec.fst).pair
  (Primrec₂.natPair.comp z y)
state_before: case hpc
a : Primrec fun a => ofNat (ℕ × Code) (List.length a)
k✝¹ : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst)).fst
n✝¹ : Primrec Prod.snd
k✝ : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst.fst)).fst
n✝ : Primrec fun a => a.fst.snd
k' : Primrec Prod.snd
c : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst.fst)).snd
L✝ : Primrec fun a => a.fst.fst.fst
k : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst.fst.fst)).fst
n : Primrec fun a => a.fst.fst.snd
cf : Primrec fun a => a.snd.fst
cg : Primrec fun a => a.snd.snd.fst
z✝ : Primrec fun a => (unpair a.fst.fst.snd).fst
L : Primrec fun a => a.fst.fst.fst.fst
z : Primrec fun a => (unpair a.fst.fst.fst.snd).fst
y : Primrec Prod.snd
⊢ Primrec fun p =>
    (fun a n =>
        (fun y => do
            let i ←
              Nat.Partrec.Code.lup a.fst.fst.fst (a.fst.snd, (ofNat (ℕ × Code) (List.length a.fst.fst.fst)).snd)
                  (Nat.pair (unpair a.fst.fst.snd).fst y)
            Nat.Partrec.Code.lup a.fst.fst.fst ((ofNat (ℕ × Code) (List.length a.fst.fst.fst)).fst, a.snd.snd.fst)
                (Nat.pair (unpair a.fst.fst.snd).fst (Nat.pair y i)))
          n)
      p.fst p.snd

tactic: refine' Primrec.option_bind h₁ (_ : Primrec _)
state_before: case hpc
a : Primrec fun a => ofNat (ℕ × Code) (List.length a)
k✝¹ : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst)).fst
n✝¹ : Primrec Prod.snd
k✝ : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst.fst)).fst
n✝ : Primrec fun a => a.fst.snd
k' : Primrec Prod.snd
c : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst.fst)).snd
L✝ : Primrec fun a => a.fst.fst.fst
k : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst.fst.fst)).fst
n : Primrec fun a => a.fst.fst.snd
cf : Primrec fun a => a.snd.fst
cg : Primrec fun a => a.snd.snd.fst
z✝ : Primrec fun a => (unpair a.fst.fst.snd).fst
L : Primrec fun a => a.fst.fst.fst.fst
z : Primrec fun a => (unpair a.fst.fst.fst.snd).fst
y : Primrec Prod.snd
h₁ :
  Primrec fun a =>
    Nat.Partrec.Code.lup
      (a.fst.fst.fst.fst, (a.fst.fst.snd, (ofNat (ℕ × Code) (List.length a.fst.fst.fst.fst)).snd),
          Nat.pair (unpair a.fst.fst.fst.snd).fst a.snd).fst
      (a.fst.fst.fst.fst, (a.fst.fst.snd, (ofNat (ℕ × Code) (List.length a.fst.fst.fst.fst)).snd),
            Nat.pair (unpair a.fst.fst.fst.snd).fst a.snd).snd.fst
      (a.fst.fst.fst.fst, (a.fst.fst.snd, (ofNat (ℕ × Code) (List.length a.fst.fst.fst.fst)).snd),
            Nat.pair (unpair a.fst.fst.fst.snd).fst a.snd).snd.snd
⊢ Primrec fun p =>
    (fun a n =>
        (fun y => do
            let i ←
              Nat.Partrec.Code.lup a.fst.fst.fst (a.fst.snd, (ofNat (ℕ × Code) (List.length a.fst.fst.fst)).snd)
                  (Nat.pair (unpair a.fst.fst.snd).fst y)
            Nat.Partrec.Code.lup a.fst.fst.fst ((ofNat (ℕ × Code) (List.length a.fst.fst.fst)).fst, a.snd.snd.fst)
                (Nat.pair (unpair a.fst.fst.snd).fst (Nat.pair y i)))
          n)
      p.fst p.snd

tactic: have z := z.comp (Primrec.fst (β := ℕ))
state_before: case hpc
a : Primrec fun a => ofNat (ℕ × Code) (List.length a)
k✝¹ : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst)).fst
n✝¹ : Primrec Prod.snd
k✝ : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst.fst)).fst
n✝ : Primrec fun a => a.fst.snd
k' : Primrec Prod.snd
c : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst.fst)).snd
L✝ : Primrec fun a => a.fst.fst.fst
k : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst.fst.fst)).fst
n : Primrec fun a => a.fst.fst.snd
cf : Primrec fun a => a.snd.fst
cg : Primrec fun a => a.snd.snd.fst
z✝ : Primrec fun a => (unpair a.fst.fst.snd).fst
L : Primrec fun a => a.fst.fst.fst.fst
z : Primrec fun a => (unpair a.fst.fst.fst.snd).fst
y : Primrec Prod.snd
h₁ :
  Primrec fun a =>
    Nat.Partrec.Code.lup
      (a.fst.fst.fst.fst, (a.fst.fst.snd, (ofNat (ℕ × Code) (List.length a.fst.fst.fst.fst)).snd),
          Nat.pair (unpair a.fst.fst.fst.snd).fst a.snd).fst
      (a.fst.fst.fst.fst, (a.fst.fst.snd, (ofNat (ℕ × Code) (List.length a.fst.fst.fst.fst)).snd),
            Nat.pair (unpair a.fst.fst.fst.snd).fst a.snd).snd.fst
      (a.fst.fst.fst.fst, (a.fst.fst.snd, (ofNat (ℕ × Code) (List.length a.fst.fst.fst.fst)).snd),
            Nat.pair (unpair a.fst.fst.fst.snd).fst a.snd).snd.snd
⊢ Primrec fun p =>
    (fun p i =>
        Nat.Partrec.Code.lup p.fst.fst.fst.fst
          ((ofNat (ℕ × Code) (List.length p.fst.fst.fst.fst)).fst, p.fst.snd.snd.fst)
          (Nat.pair (unpair p.fst.fst.fst.snd).fst (Nat.pair p.snd i)))
      p.fst p.snd

tactic: have y := y.comp (Primrec.fst (β := ℕ))
state_before: case hpc
a : Primrec fun a => ofNat (ℕ × Code) (List.length a)
k✝¹ : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst)).fst
n✝¹ : Primrec Prod.snd
k✝ : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst.fst)).fst
n✝ : Primrec fun a => a.fst.snd
k' : Primrec Prod.snd
c : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst.fst)).snd
L✝ : Primrec fun a => a.fst.fst.fst
k : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst.fst.fst)).fst
n : Primrec fun a => a.fst.fst.snd
cf : Primrec fun a => a.snd.fst
cg : Primrec fun a => a.snd.snd.fst
z✝¹ : Primrec fun a => (unpair a.fst.fst.snd).fst
L : Primrec fun a => a.fst.fst.fst.fst
z✝ : Primrec fun a => (unpair a.fst.fst.fst.snd).fst
y : Primrec Prod.snd
h₁ :
  Primrec fun a =>
    Nat.Partrec.Code.lup
      (a.fst.fst.fst.fst, (a.fst.fst.snd, (ofNat (ℕ × Code) (List.length a.fst.fst.fst.fst)).snd),
          Nat.pair (unpair a.fst.fst.fst.snd).fst a.snd).fst
      (a.fst.fst.fst.fst, (a.fst.fst.snd, (ofNat (ℕ × Code) (List.length a.fst.fst.fst.fst)).snd),
            Nat.pair (unpair a.fst.fst.fst.snd).fst a.snd).snd.fst
      (a.fst.fst.fst.fst, (a.fst.fst.snd, (ofNat (ℕ × Code) (List.length a.fst.fst.fst.fst)).snd),
            Nat.pair (unpair a.fst.fst.fst.snd).fst a.snd).snd.snd
z : Primrec fun a => (unpair a.fst.fst.fst.fst.snd).fst
⊢ Primrec fun p =>
    (fun p i =>
        Nat.Partrec.Code.lup p.fst.fst.fst.fst
          ((ofNat (ℕ × Code) (List.length p.fst.fst.fst.fst)).fst, p.fst.snd.snd.fst)
          (Nat.pair (unpair p.fst.fst.fst.snd).fst (Nat.pair p.snd i)))
      p.fst p.snd

tactic: have i := Primrec.snd
  (α := (((List (List (Option ℕ)) × ℕ) × ℕ) × Code × Code × Option ℕ × Option ℕ) × ℕ)
  (β := ℕ)
state_before: case hpc
a : Primrec fun a => ofNat (ℕ × Code) (List.length a)
k✝¹ : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst)).fst
n✝¹ : Primrec Prod.snd
k✝ : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst.fst)).fst
n✝ : Primrec fun a => a.fst.snd
k' : Primrec Prod.snd
c : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst.fst)).snd
L✝ : Primrec fun a => a.fst.fst.fst
k : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst.fst.fst)).fst
n : Primrec fun a => a.fst.fst.snd
cf : Primrec fun a => a.snd.fst
cg : Primrec fun a => a.snd.snd.fst
z✝¹ : Primrec fun a => (unpair a.fst.fst.snd).fst
L : Primrec fun a => a.fst.fst.fst.fst
z✝ : Primrec fun a => (unpair a.fst.fst.fst.snd).fst
y✝ : Primrec Prod.snd
h₁ :
  Primrec fun a =>
    Nat.Partrec.Code.lup
      (a.fst.fst.fst.fst, (a.fst.fst.snd, (ofNat (ℕ × Code) (List.length a.fst.fst.fst.fst)).snd),
          Nat.pair (unpair a.fst.fst.fst.snd).fst a.snd).fst
      (a.fst.fst.fst.fst, (a.fst.fst.snd, (ofNat (ℕ × Code) (List.length a.fst.fst.fst.fst)).snd),
            Nat.pair (unpair a.fst.fst.fst.snd).fst a.snd).snd.fst
      (a.fst.fst.fst.fst, (a.fst.fst.snd, (ofNat (ℕ × Code) (List.length a.fst.fst.fst.fst)).snd),
            Nat.pair (unpair a.fst.fst.fst.snd).fst a.snd).snd.snd
z : Primrec fun a => (unpair a.fst.fst.fst.fst.snd).fst
y : Primrec fun a => a.fst.snd
⊢ Primrec fun p =>
    (fun p i =>
        Nat.Partrec.Code.lup p.fst.fst.fst.fst
          ((ofNat (ℕ × Code) (List.length p.fst.fst.fst.fst)).fst, p.fst.snd.snd.fst)
          (Nat.pair (unpair p.fst.fst.fst.snd).fst (Nat.pair p.snd i)))
      p.fst p.snd

tactic: have h₂ := hlup.comp ((L.comp Primrec.fst).pair <|
  ((k.pair cg).comp <| Primrec.fst.comp Primrec.fst).pair <|
    Primrec₂.natPair.comp z <| Primrec₂.natPair.comp y i)
state_before: case hpc
a : Primrec fun a => ofNat (ℕ × Code) (List.length a)
k✝¹ : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst)).fst
n✝¹ : Primrec Prod.snd
k✝ : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst.fst)).fst
n✝ : Primrec fun a => a.fst.snd
k' : Primrec Prod.snd
c : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst.fst)).snd
L✝ : Primrec fun a => a.fst.fst.fst
k : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst.fst.fst)).fst
n : Primrec fun a => a.fst.fst.snd
cf : Primrec fun a => a.snd.fst
cg : Primrec fun a => a.snd.snd.fst
z✝¹ : Primrec fun a => (unpair a.fst.fst.snd).fst
L : Primrec fun a => a.fst.fst.fst.fst
z✝ : Primrec fun a => (unpair a.fst.fst.fst.snd).fst
y✝ : Primrec Prod.snd
h₁ :
  Primrec fun a =>
    Nat.Partrec.Code.lup
      (a.fst.fst.fst.fst, (a.fst.fst.snd, (ofNat (ℕ × Code) (List.length a.fst.fst.fst.fst)).snd),
          Nat.pair (unpair a.fst.fst.fst.snd).fst a.snd).fst
      (a.fst.fst.fst.fst, (a.fst.fst.snd, (ofNat (ℕ × Code) (List.length a.fst.fst.fst.fst)).snd),
            Nat.pair (unpair a.fst.fst.fst.snd).fst a.snd).snd.fst
      (a.fst.fst.fst.fst, (a.fst.fst.snd, (ofNat (ℕ × Code) (List.length a.fst.fst.fst.fst)).snd),
            Nat.pair (unpair a.fst.fst.fst.snd).fst a.snd).snd.snd
z : Primrec fun a => (unpair a.fst.fst.fst.fst.snd).fst
y : Primrec fun a => a.fst.snd
i : Primrec Prod.snd
⊢ Primrec fun p =>
    (fun p i =>
        Nat.Partrec.Code.lup p.fst.fst.fst.fst
          ((ofNat (ℕ × Code) (List.length p.fst.fst.fst.fst)).fst, p.fst.snd.snd.fst)
          (Nat.pair (unpair p.fst.fst.fst.snd).fst (Nat.pair p.snd i)))
      p.fst p.snd

tactic: exact h₂
state_before: case hpc
a : Primrec fun a => ofNat (ℕ × Code) (List.length a)
k✝¹ : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst)).fst
n✝¹ : Primrec Prod.snd
k✝ : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst.fst)).fst
n✝ : Primrec fun a => a.fst.snd
k' : Primrec Prod.snd
c : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst.fst)).snd
L✝ : Primrec fun a => a.fst.fst.fst
k : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst.fst.fst)).fst
n : Primrec fun a => a.fst.fst.snd
cf : Primrec fun a => a.snd.fst
cg : Primrec fun a => a.snd.snd.fst
z✝¹ : Primrec fun a => (unpair a.fst.fst.snd).fst
L : Primrec fun a => a.fst.fst.fst.fst
z✝ : Primrec fun a => (unpair a.fst.fst.fst.snd).fst
y✝ : Primrec Prod.snd
h₁ :
  Primrec fun a =>
    Nat.Partrec.Code.lup
      (a.fst.fst.fst.fst, (a.fst.fst.snd, (ofNat (ℕ × Code) (List.length a.fst.fst.fst.fst)).snd),
          Nat.pair (unpair a.fst.fst.fst.snd).fst a.snd).fst
      (a.fst.fst.fst.fst, (a.fst.fst.snd, (ofNat (ℕ × Code) (List.length a.fst.fst.fst.fst)).snd),
            Nat.pair (unpair a.fst.fst.fst.snd).fst a.snd).snd.fst
      (a.fst.fst.fst.fst, (a.fst.fst.snd, (ofNat (ℕ × Code) (List.length a.fst.fst.fst.fst)).snd),
            Nat.pair (unpair a.fst.fst.fst.snd).fst a.snd).snd.snd
z : Primrec fun a => (unpair a.fst.fst.fst.fst.snd).fst
y : Primrec fun a => a.fst.snd
i : Primrec Prod.snd
h₂ :
  Primrec fun a =>
    Nat.Partrec.Code.lup
      (a.fst.fst.fst.fst.fst, ((ofNat (ℕ × Code) (List.length a.fst.fst.fst.fst.fst)).fst, a.fst.fst.snd.snd.fst),
          Nat.pair (unpair a.fst.fst.fst.fst.snd).fst (Nat.pair a.fst.snd a.snd)).fst
      (a.fst.fst.fst.fst.fst, ((ofNat (ℕ × Code) (List.length a.fst.fst.fst.fst.fst)).fst, a.fst.fst.snd.snd.fst),
            Nat.pair (unpair a.fst.fst.fst.fst.snd).fst (Nat.pair a.fst.snd a.snd)).snd.fst
      (a.fst.fst.fst.fst.fst, ((ofNat (ℕ × Code) (List.length a.fst.fst.fst.fst.fst)).fst, a.fst.fst.snd.snd.fst),
            Nat.pair (unpair a.fst.fst.fst.fst.snd).fst (Nat.pair a.fst.snd a.snd)).snd.snd
⊢ Primrec fun p =>
    (fun p i =>
        Nat.Partrec.Code.lup p.fst.fst.fst.fst
          ((ofNat (ℕ × Code) (List.length p.fst.fst.fst.fst)).fst, p.fst.snd.snd.fst)
          (Nat.pair (unpair p.fst.fst.fst.snd).fst (Nat.pair p.snd i)))
      p.fst p.snd

tactic: have L := (Primrec.fst.comp Primrec.fst).comp
  (Primrec.fst (α := (List (List (Option ℕ)) × ℕ) × ℕ)
    (β := Code × Option ℕ))
state_before: case hrf
a : Primrec fun a => ofNat (ℕ × Code) (List.length a)
k✝ : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst)).fst
n✝ : Primrec Prod.snd
k : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst.fst)).fst
n : Primrec fun a => a.fst.snd
k' : Primrec Prod.snd
c : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst.fst)).snd
⊢ Primrec fun a =>
    let z := (unpair a.fst.fst.snd).fst;
    let m := (unpair a.fst.fst.snd).snd;
    do
    let x ←
      Nat.Partrec.Code.lup a.fst.fst.fst ((ofNat (ℕ × Code) (List.length a.fst.fst.fst)).fst, a.snd.fst) (Nat.pair z m)
    Nat.casesOn x (some m) fun x =>
        Nat.Partrec.Code.lup a.fst.fst.fst (a.fst.snd, (ofNat (ℕ × Code) (List.length a.fst.fst.fst)).snd)
          (Nat.pair z (m + 1))

tactic: have k := k.comp (Primrec.fst (β := Code × Option ℕ))
state_before: case hrf
a : Primrec fun a => ofNat (ℕ × Code) (List.length a)
k✝ : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst)).fst
n✝ : Primrec Prod.snd
k : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst.fst)).fst
n : Primrec fun a => a.fst.snd
k' : Primrec Prod.snd
c : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst.fst)).snd
L : Primrec fun a => a.fst.fst.fst
⊢ Primrec fun a =>
    let z := (unpair a.fst.fst.snd).fst;
    let m := (unpair a.fst.fst.snd).snd;
    do
    let x ←
      Nat.Partrec.Code.lup a.fst.fst.fst ((ofNat (ℕ × Code) (List.length a.fst.fst.fst)).fst, a.snd.fst) (Nat.pair z m)
    Nat.casesOn x (some m) fun x =>
        Nat.Partrec.Code.lup a.fst.fst.fst (a.fst.snd, (ofNat (ℕ × Code) (List.length a.fst.fst.fst)).snd)
          (Nat.pair z (m + 1))

tactic: have n := n.comp (Primrec.fst (β := Code × Option ℕ))
state_before: case hrf
a : Primrec fun a => ofNat (ℕ × Code) (List.length a)
k✝¹ : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst)).fst
n✝ : Primrec Prod.snd
k✝ : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst.fst)).fst
n : Primrec fun a => a.fst.snd
k' : Primrec Prod.snd
c : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst.fst)).snd
L : Primrec fun a => a.fst.fst.fst
k : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst.fst.fst)).fst
⊢ Primrec fun a =>
    let z := (unpair a.fst.fst.snd).fst;
    let m := (unpair a.fst.fst.snd).snd;
    do
    let x ←
      Nat.Partrec.Code.lup a.fst.fst.fst ((ofNat (ℕ × Code) (List.length a.fst.fst.fst)).fst, a.snd.fst) (Nat.pair z m)
    Nat.casesOn x (some m) fun x =>
        Nat.Partrec.Code.lup a.fst.fst.fst (a.fst.snd, (ofNat (ℕ × Code) (List.length a.fst.fst.fst)).snd)
          (Nat.pair z (m + 1))

tactic: have cf := Primrec.fst.comp (Primrec.snd (α := (List (List (Option ℕ)) × ℕ) × ℕ)
    (β := Code × Option ℕ))
state_before: case hrf
a : Primrec fun a => ofNat (ℕ × Code) (List.length a)
k✝¹ : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst)).fst
n✝¹ : Primrec Prod.snd
k✝ : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst.fst)).fst
n✝ : Primrec fun a => a.fst.snd
k' : Primrec Prod.snd
c : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst.fst)).snd
L : Primrec fun a => a.fst.fst.fst
k : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst.fst.fst)).fst
n : Primrec fun a => a.fst.fst.snd
⊢ Primrec fun a =>
    let z := (unpair a.fst.fst.snd).fst;
    let m := (unpair a.fst.fst.snd).snd;
    do
    let x ←
      Nat.Partrec.Code.lup a.fst.fst.fst ((ofNat (ℕ × Code) (List.length a.fst.fst.fst)).fst, a.snd.fst) (Nat.pair z m)
    Nat.casesOn x (some m) fun x =>
        Nat.Partrec.Code.lup a.fst.fst.fst (a.fst.snd, (ofNat (ℕ × Code) (List.length a.fst.fst.fst)).snd)
          (Nat.pair z (m + 1))

tactic: have z := Primrec.fst.comp (Primrec.unpair.comp n)
state_before: case hrf
a : Primrec fun a => ofNat (ℕ × Code) (List.length a)
k✝¹ : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst)).fst
n✝¹ : Primrec Prod.snd
k✝ : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst.fst)).fst
n✝ : Primrec fun a => a.fst.snd
k' : Primrec Prod.snd
c : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst.fst)).snd
L : Primrec fun a => a.fst.fst.fst
k : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst.fst.fst)).fst
n : Primrec fun a => a.fst.fst.snd
cf : Primrec fun a => a.snd.fst
⊢ Primrec fun a =>
    let z := (unpair a.fst.fst.snd).fst;
    let m := (unpair a.fst.fst.snd).snd;
    do
    let x ←
      Nat.Partrec.Code.lup a.fst.fst.fst ((ofNat (ℕ × Code) (List.length a.fst.fst.fst)).fst, a.snd.fst) (Nat.pair z m)
    Nat.casesOn x (some m) fun x =>
        Nat.Partrec.Code.lup a.fst.fst.fst (a.fst.snd, (ofNat (ℕ × Code) (List.length a.fst.fst.fst)).snd)
          (Nat.pair z (m + 1))

tactic: have m := Primrec.snd.comp (Primrec.unpair.comp n)
state_before: case hrf
a : Primrec fun a => ofNat (ℕ × Code) (List.length a)
k✝¹ : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst)).fst
n✝¹ : Primrec Prod.snd
k✝ : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst.fst)).fst
n✝ : Primrec fun a => a.fst.snd
k' : Primrec Prod.snd
c : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst.fst)).snd
L : Primrec fun a => a.fst.fst.fst
k : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst.fst.fst)).fst
n : Primrec fun a => a.fst.fst.snd
cf : Primrec fun a => a.snd.fst
z : Primrec fun a => (unpair a.fst.fst.snd).fst
⊢ Primrec fun a =>
    let z := (unpair a.fst.fst.snd).fst;
    let m := (unpair a.fst.fst.snd).snd;
    do
    let x ←
      Nat.Partrec.Code.lup a.fst.fst.fst ((ofNat (ℕ × Code) (List.length a.fst.fst.fst)).fst, a.snd.fst) (Nat.pair z m)
    Nat.casesOn x (some m) fun x =>
        Nat.Partrec.Code.lup a.fst.fst.fst (a.fst.snd, (ofNat (ℕ × Code) (List.length a.fst.fst.fst)).snd)
          (Nat.pair z (m + 1))

tactic: have h₁ := hlup.comp <| L.pair <| (k.pair cf).pair (Primrec₂.natPair.comp z m)
state_before: case hrf
a : Primrec fun a => ofNat (ℕ × Code) (List.length a)
k✝¹ : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst)).fst
n✝¹ : Primrec Prod.snd
k✝ : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst.fst)).fst
n✝ : Primrec fun a => a.fst.snd
k' : Primrec Prod.snd
c : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst.fst)).snd
L : Primrec fun a => a.fst.fst.fst
k : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst.fst.fst)).fst
n : Primrec fun a => a.fst.fst.snd
cf : Primrec fun a => a.snd.fst
z : Primrec fun a => (unpair a.fst.fst.snd).fst
m : Primrec fun a => (unpair a.fst.fst.snd).snd
⊢ Primrec fun a =>
    let z := (unpair a.fst.fst.snd).fst;
    let m := (unpair a.fst.fst.snd).snd;
    do
    let x ←
      Nat.Partrec.Code.lup a.fst.fst.fst ((ofNat (ℕ × Code) (List.length a.fst.fst.fst)).fst, a.snd.fst) (Nat.pair z m)
    Nat.casesOn x (some m) fun x =>
        Nat.Partrec.Code.lup a.fst.fst.fst (a.fst.snd, (ofNat (ℕ × Code) (List.length a.fst.fst.fst)).snd)
          (Nat.pair z (m + 1))

tactic: refine' Primrec.option_bind h₁ (_ : Primrec _)
state_before: case hrf
a : Primrec fun a => ofNat (ℕ × Code) (List.length a)
k✝¹ : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst)).fst
n✝¹ : Primrec Prod.snd
k✝ : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst.fst)).fst
n✝ : Primrec fun a => a.fst.snd
k' : Primrec Prod.snd
c : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst.fst)).snd
L : Primrec fun a => a.fst.fst.fst
k : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst.fst.fst)).fst
n : Primrec fun a => a.fst.fst.snd
cf : Primrec fun a => a.snd.fst
z : Primrec fun a => (unpair a.fst.fst.snd).fst
m : Primrec fun a => (unpair a.fst.fst.snd).snd
h₁ :
  Primrec fun a =>
    Nat.Partrec.Code.lup
      (a.fst.fst.fst, ((ofNat (ℕ × Code) (List.length a.fst.fst.fst)).fst, a.snd.fst),
          Nat.pair (unpair a.fst.fst.snd).fst (unpair a.fst.fst.snd).snd).fst
      (a.fst.fst.fst, ((ofNat (ℕ × Code) (List.length a.fst.fst.fst)).fst, a.snd.fst),
            Nat.pair (unpair a.fst.fst.snd).fst (unpair a.fst.fst.snd).snd).snd.fst
      (a.fst.fst.fst, ((ofNat (ℕ × Code) (List.length a.fst.fst.fst)).fst, a.snd.fst),
            Nat.pair (unpair a.fst.fst.snd).fst (unpair a.fst.fst.snd).snd).snd.snd
⊢ Primrec fun a =>
    let z := (unpair a.fst.fst.snd).fst;
    let m := (unpair a.fst.fst.snd).snd;
    do
    let x ←
      Nat.Partrec.Code.lup a.fst.fst.fst ((ofNat (ℕ × Code) (List.length a.fst.fst.fst)).fst, a.snd.fst) (Nat.pair z m)
    Nat.casesOn x (some m) fun x =>
        Nat.Partrec.Code.lup a.fst.fst.fst (a.fst.snd, (ofNat (ℕ × Code) (List.length a.fst.fst.fst)).snd)
          (Nat.pair z (m + 1))

tactic: have m := m.comp (Primrec.fst (β := ℕ))
state_before: case hrf
a : Primrec fun a => ofNat (ℕ × Code) (List.length a)
k✝¹ : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst)).fst
n✝¹ : Primrec Prod.snd
k✝ : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst.fst)).fst
n✝ : Primrec fun a => a.fst.snd
k' : Primrec Prod.snd
c : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst.fst)).snd
L : Primrec fun a => a.fst.fst.fst
k : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst.fst.fst)).fst
n : Primrec fun a => a.fst.fst.snd
cf : Primrec fun a => a.snd.fst
z : Primrec fun a => (unpair a.fst.fst.snd).fst
m : Primrec fun a => (unpair a.fst.fst.snd).snd
h₁ :
  Primrec fun a =>
    Nat.Partrec.Code.lup
      (a.fst.fst.fst, ((ofNat (ℕ × Code) (List.length a.fst.fst.fst)).fst, a.snd.fst),
          Nat.pair (unpair a.fst.fst.snd).fst (unpair a.fst.fst.snd).snd).fst
      (a.fst.fst.fst, ((ofNat (ℕ × Code) (List.length a.fst.fst.fst)).fst, a.snd.fst),
            Nat.pair (unpair a.fst.fst.snd).fst (unpair a.fst.fst.snd).snd).snd.fst
      (a.fst.fst.fst, ((ofNat (ℕ × Code) (List.length a.fst.fst.fst)).fst, a.snd.fst),
            Nat.pair (unpair a.fst.fst.snd).fst (unpair a.fst.fst.snd).snd).snd.snd
⊢ Primrec fun p =>
    (fun a x =>
        Nat.casesOn x (some (unpair a.fst.fst.snd).snd) fun x =>
          Nat.Partrec.Code.lup a.fst.fst.fst (a.fst.snd, (ofNat (ℕ × Code) (List.length a.fst.fst.fst)).snd)
            (Nat.pair (unpair a.fst.fst.snd).fst ((unpair a.fst.fst.snd).snd + 1)))
      p.fst p.snd

tactic: refine Primrec.nat_casesOn Primrec.snd (Primrec.option_some.comp m) ?_
state_before: case hrf
a : Primrec fun a => ofNat (ℕ × Code) (List.length a)
k✝¹ : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst)).fst
n✝¹ : Primrec Prod.snd
k✝ : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst.fst)).fst
n✝ : Primrec fun a => a.fst.snd
k' : Primrec Prod.snd
c : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst.fst)).snd
L : Primrec fun a => a.fst.fst.fst
k : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst.fst.fst)).fst
n : Primrec fun a => a.fst.fst.snd
cf : Primrec fun a => a.snd.fst
z : Primrec fun a => (unpair a.fst.fst.snd).fst
m✝ : Primrec fun a => (unpair a.fst.fst.snd).snd
h₁ :
  Primrec fun a =>
    Nat.Partrec.Code.lup
      (a.fst.fst.fst, ((ofNat (ℕ × Code) (List.length a.fst.fst.fst)).fst, a.snd.fst),
          Nat.pair (unpair a.fst.fst.snd).fst (unpair a.fst.fst.snd).snd).fst
      (a.fst.fst.fst, ((ofNat (ℕ × Code) (List.length a.fst.fst.fst)).fst, a.snd.fst),
            Nat.pair (unpair a.fst.fst.snd).fst (unpair a.fst.fst.snd).snd).snd.fst
      (a.fst.fst.fst, ((ofNat (ℕ × Code) (List.length a.fst.fst.fst)).fst, a.snd.fst),
            Nat.pair (unpair a.fst.fst.snd).fst (unpair a.fst.fst.snd).snd).snd.snd
m : Primrec fun a => (unpair a.fst.fst.fst.snd).snd
⊢ Primrec fun p =>
    (fun a x =>
        Nat.casesOn x (some (unpair a.fst.fst.snd).snd) fun x =>
          Nat.Partrec.Code.lup a.fst.fst.fst (a.fst.snd, (ofNat (ℕ × Code) (List.length a.fst.fst.fst)).snd)
            (Nat.pair (unpair a.fst.fst.snd).fst ((unpair a.fst.fst.snd).snd + 1)))
      p.fst p.snd

tactic: unfold Primrec₂
state_before: case hrf
a : Primrec fun a => ofNat (ℕ × Code) (List.length a)
k✝¹ : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst)).fst
n✝¹ : Primrec Prod.snd
k✝ : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst.fst)).fst
n✝ : Primrec fun a => a.fst.snd
k' : Primrec Prod.snd
c : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst.fst)).snd
L : Primrec fun a => a.fst.fst.fst
k : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst.fst.fst)).fst
n : Primrec fun a => a.fst.fst.snd
cf : Primrec fun a => a.snd.fst
z : Primrec fun a => (unpair a.fst.fst.snd).fst
m✝ : Primrec fun a => (unpair a.fst.fst.snd).snd
h₁ :
  Primrec fun a =>
    Nat.Partrec.Code.lup
      (a.fst.fst.fst, ((ofNat (ℕ × Code) (List.length a.fst.fst.fst)).fst, a.snd.fst),
          Nat.pair (unpair a.fst.fst.snd).fst (unpair a.fst.fst.snd).snd).fst
      (a.fst.fst.fst, ((ofNat (ℕ × Code) (List.length a.fst.fst.fst)).fst, a.snd.fst),
            Nat.pair (unpair a.fst.fst.snd).fst (unpair a.fst.fst.snd).snd).snd.fst
      (a.fst.fst.fst, ((ofNat (ℕ × Code) (List.length a.fst.fst.fst)).fst, a.snd.fst),
            Nat.pair (unpair a.fst.fst.snd).fst (unpair a.fst.fst.snd).snd).snd.snd
m : Primrec fun a => (unpair a.fst.fst.fst.snd).snd
⊢ Primrec₂ fun p n =>
    (fun x =>
        Nat.Partrec.Code.lup p.fst.fst.fst.fst (p.fst.fst.snd, (ofNat (ℕ × Code) (List.length p.fst.fst.fst.fst)).snd)
          (Nat.pair (unpair p.fst.fst.fst.snd).fst ((unpair p.fst.fst.fst.snd).snd + 1)))
      n

tactic: exact (hlup.comp ((L.comp Primrec.fst).pair <|
  ((k'.pair c).comp <| Primrec.fst.comp Primrec.fst).pair
    (Primrec₂.natPair.comp (z.comp Primrec.fst) (_root_.Primrec.succ.comp m)))).comp
  Primrec.fst
state_before: case hrf
a : Primrec fun a => ofNat (ℕ × Code) (List.length a)
k✝¹ : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst)).fst
n✝¹ : Primrec Prod.snd
k✝ : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst.fst)).fst
n✝ : Primrec fun a => a.fst.snd
k' : Primrec Prod.snd
c : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst.fst)).snd
L : Primrec fun a => a.fst.fst.fst
k : Primrec fun a => (ofNat (ℕ × Code) (List.length a.fst.fst.fst)).fst
n : Primrec fun a => a.fst.fst.snd
cf : Primrec fun a => a.snd.fst
z : Primrec fun a => (unpair a.fst.fst.snd).fst
m✝ : Primrec fun a => (unpair a.fst.fst.snd).snd
h₁ :
  Primrec fun a =>
    Nat.Partrec.Code.lup
      (a.fst.fst.fst, ((ofNat (ℕ × Code) (List.length a.fst.fst.fst)).fst, a.snd.fst),
          Nat.pair (unpair a.fst.fst.snd).fst (unpair a.fst.fst.snd).snd).fst
      (a.fst.fst.fst, ((ofNat (ℕ × Code) (List.length a.fst.fst.fst)).fst, a.snd.fst),
            Nat.pair (unpair a.fst.fst.snd).fst (unpair a.fst.fst.snd).snd).snd.fst
      (a.fst.fst.fst, ((ofNat (ℕ × Code) (List.length a.fst.fst.fst)).fst, a.snd.fst),
            Nat.pair (unpair a.fst.fst.snd).fst (unpair a.fst.fst.snd).snd).snd.snd
m : Primrec fun a => (unpair a.fst.fst.fst.snd).snd
⊢ Primrec fun p =>
    (fun p n =>
        (fun x =>
            Nat.Partrec.Code.lup p.fst.fst.fst.fst
              (p.fst.fst.snd, (ofNat (ℕ × Code) (List.length p.fst.fst.fst.fst)).snd)
              (Nat.pair (unpair p.fst.fst.fst.snd).fst ((unpair p.fst.fst.fst.snd).snd + 1)))
          n)
      p.fst p.snd