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
state_after: a : Primrec fun a => ofNat (ℕ × Code) a.length
⊢ Primrec Nat.Partrec.Code.G

tactic: have k := Primrec.fst.comp a
state_before: a : Primrec fun a => ofNat (ℕ × Code) a.length
⊢ Primrec Nat.Partrec.Code.G
state_after: a : Primrec fun a => ofNat (ℕ × Code) a.length
k : Primrec fun a => (ofNat (ℕ × Code) a.length).1
⊢ 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) a.length
k : Primrec fun a => (ofNat (ℕ × Code) a.length).1
⊢ Primrec Nat.Partrec.Code.G
state_after: a : Primrec fun a => ofNat (ℕ × Code) a.length
k : Primrec fun a => (ofNat (ℕ × Code) a.length).1
⊢ Primrec fun p =>
    (fun a n =>
        Nat.casesOn (ofNat (ℕ × Code) a.length).1 Option.none fun k' =>
          Code.recOn (ofNat (ℕ × Code) a.length).2 (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 a ((ofNat (ℕ × Code) a.length).1, cf) n
              let y ← Nat.Partrec.Code.lup a ((ofNat (ℕ × Code) a.length).1, cg) n
              some (Nat.pair x y))
            (fun cf cg x x => do
              let x ← Nat.Partrec.Code.lup a ((ofNat (ℕ × Code) a.length).1, cg) n
              Nat.Partrec.Code.lup a ((ofNat (ℕ × Code) a.length).1, cf) x)
            (fun cf cg x x =>
              let z := (unpair n).1;
              Nat.casesOn (unpair n).2 (Nat.Partrec.Code.lup a ((ofNat (ℕ × Code) a.length).1, cf) z) fun y => do
                let i ← Nat.Partrec.Code.lup a (k', (ofNat (ℕ × Code) a.length).2) (Nat.pair z y)
                Nat.Partrec.Code.lup a ((ofNat (ℕ × Code) a.length).1, cg) (Nat.pair z (Nat.pair y i)))
            fun cf x =>
            let z := (unpair n).1;
            let m := (unpair n).2;
            do
            let x ← Nat.Partrec.Code.lup a ((ofNat (ℕ × Code) a.length).1, cf) (Nat.pair z m)
            Nat.casesOn x (some m) fun x =>
                Nat.Partrec.Code.lup a (k', (ofNat (ℕ × Code) a.length).2) (Nat.pair z (m + 1)))
      p.1 p.2

tactic: replace k := k.comp (Primrec.fst (β := ℕ))
state_before: a : Primrec fun a => ofNat (ℕ × Code) a.length
k : Primrec fun a => (ofNat (ℕ × Code) a.length).1
⊢ Primrec fun p =>
    (fun a n =>
        Nat.casesOn (ofNat (ℕ × Code) a.length).1 Option.none fun k' =>
          Code.recOn (ofNat (ℕ × Code) a.length).2 (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 a ((ofNat (ℕ × Code) a.length).1, cf) n
              let y ← Nat.Partrec.Code.lup a ((ofNat (ℕ × Code) a.length).1, cg) n
              some (Nat.pair x y))
            (fun cf cg x x => do
              let x ← Nat.Partrec.Code.lup a ((ofNat (ℕ × Code) a.length).1, cg) n
              Nat.Partrec.Code.lup a ((ofNat (ℕ × Code) a.length).1, cf) x)
            (fun cf cg x x =>
              let z := (unpair n).1;
              Nat.casesOn (unpair n).2 (Nat.Partrec.Code.lup a ((ofNat (ℕ × Code) a.length).1, cf) z) fun y => do
                let i ← Nat.Partrec.Code.lup a (k', (ofNat (ℕ × Code) a.length).2) (Nat.pair z y)
                Nat.Partrec.Code.lup a ((ofNat (ℕ × Code) a.length).1, cg) (Nat.pair z (Nat.pair y i)))
            fun cf x =>
            let z := (unpair n).1;
            let m := (unpair n).2;
            do
            let x ← Nat.Partrec.Code.lup a ((ofNat (ℕ × Code) a.length).1, cf) (Nat.pair z m)
            Nat.casesOn x (some m) fun x =>
                Nat.Partrec.Code.lup a (k', (ofNat (ℕ × Code) a.length).2) (Nat.pair z (m + 1)))
      p.1 p.2
state_after: a : Primrec fun a => ofNat (ℕ × Code) a.length
k : Primrec fun a => (ofNat (ℕ × Code) a.1.length).1
⊢ Primrec fun p =>
    (fun a n =>
        Nat.casesOn (ofNat (ℕ × Code) a.length).1 Option.none fun k' =>
          Code.recOn (ofNat (ℕ × Code) a.length).2 (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 a ((ofNat (ℕ × Code) a.length).1, cf) n
              let y ← Nat.Partrec.Code.lup a ((ofNat (ℕ × Code) a.length).1, cg) n
              some (Nat.pair x y))
            (fun cf cg x x => do
              let x ← Nat.Partrec.Code.lup a ((ofNat (ℕ × Code) a.length).1, cg) n
              Nat.Partrec.Code.lup a ((ofNat (ℕ × Code) a.length).1, cf) x)
            (fun cf cg x x =>
              let z := (unpair n).1;
              Nat.casesOn (unpair n).2 (Nat.Partrec.Code.lup a ((ofNat (ℕ × Code) a.length).1, cf) z) fun y => do
                let i ← Nat.Partrec.Code.lup a (k', (ofNat (ℕ × Code) a.length).2) (Nat.pair z y)
                Nat.Partrec.Code.lup a ((ofNat (ℕ × Code) a.length).1, cg) (Nat.pair z (Nat.pair y i)))
            fun cf x =>
            let z := (unpair n).1;
            let m := (unpair n).2;
            do
            let x ← Nat.Partrec.Code.lup a ((ofNat (ℕ × Code) a.length).1, cf) (Nat.pair z m)
            Nat.casesOn x (some m) fun x =>
                Nat.Partrec.Code.lup a (k', (ofNat (ℕ × Code) a.length).2) (Nat.pair z (m + 1)))
      p.1 p.2

tactic: have n := Primrec.snd (α := List (List (Option ℕ))) (β := ℕ)
state_before: a : Primrec fun a => ofNat (ℕ × Code) a.length
k : Primrec fun a => (ofNat (ℕ × Code) a.1.length).1
⊢ Primrec fun p =>
    (fun a n =>
        Nat.casesOn (ofNat (ℕ × Code) a.length).1 Option.none fun k' =>
          Code.recOn (ofNat (ℕ × Code) a.length).2 (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 a ((ofNat (ℕ × Code) a.length).1, cf) n
              let y ← Nat.Partrec.Code.lup a ((ofNat (ℕ × Code) a.length).1, cg) n
              some (Nat.pair x y))
            (fun cf cg x x => do
              let x ← Nat.Partrec.Code.lup a ((ofNat (ℕ × Code) a.length).1, cg) n
              Nat.Partrec.Code.lup a ((ofNat (ℕ × Code) a.length).1, cf) x)
            (fun cf cg x x =>
              let z := (unpair n).1;
              Nat.casesOn (unpair n).2 (Nat.Partrec.Code.lup a ((ofNat (ℕ × Code) a.length).1, cf) z) fun y => do
                let i ← Nat.Partrec.Code.lup a (k', (ofNat (ℕ × Code) a.length).2) (Nat.pair z y)
                Nat.Partrec.Code.lup a ((ofNat (ℕ × Code) a.length).1, cg) (Nat.pair z (Nat.pair y i)))
            fun cf x =>
            let z := (unpair n).1;
            let m := (unpair n).2;
            do
            let x ← Nat.Partrec.Code.lup a ((ofNat (ℕ × Code) a.length).1, cf) (Nat.pair z m)
            Nat.casesOn x (some m) fun x =>
                Nat.Partrec.Code.lup a (k', (ofNat (ℕ × Code) a.length).2) (Nat.pair z (m + 1)))
      p.1 p.2
state_after: a : Primrec fun a => ofNat (ℕ × Code) a.length
k : Primrec fun a => (ofNat (ℕ × Code) a.1.length).1
n : Primrec Prod.snd
⊢ Primrec fun p =>
    (fun a n =>
        Nat.casesOn (ofNat (ℕ × Code) a.length).1 Option.none fun k' =>
          Code.recOn (ofNat (ℕ × Code) a.length).2 (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 a ((ofNat (ℕ × Code) a.length).1, cf) n
              let y ← Nat.Partrec.Code.lup a ((ofNat (ℕ × Code) a.length).1, cg) n
              some (Nat.pair x y))
            (fun cf cg x x => do
              let x ← Nat.Partrec.Code.lup a ((ofNat (ℕ × Code) a.length).1, cg) n
              Nat.Partrec.Code.lup a ((ofNat (ℕ × Code) a.length).1, cf) x)
            (fun cf cg x x =>
              let z := (unpair n).1;
              Nat.casesOn (unpair n).2 (Nat.Partrec.Code.lup a ((ofNat (ℕ × Code) a.length).1, cf) z) fun y => do
                let i ← Nat.Partrec.Code.lup a (k', (ofNat (ℕ × Code) a.length).2) (Nat.pair z y)
                Nat.Partrec.Code.lup a ((ofNat (ℕ × Code) a.length).1, cg) (Nat.pair z (Nat.pair y i)))
            fun cf x =>
            let z := (unpair n).1;
            let m := (unpair n).2;
            do
            let x ← Nat.Partrec.Code.lup a ((ofNat (ℕ × Code) a.length).1, cf) (Nat.pair z m)
            Nat.casesOn x (some m) fun x =>
                Nat.Partrec.Code.lup a (k', (ofNat (ℕ × Code) a.length).2) (Nat.pair z (m + 1)))
      p.1 p.2

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

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

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

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

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

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) a.length
k✝ : Primrec fun a => (ofNat (ℕ × Code) a.1.length).1
n✝ : Primrec Prod.snd
k : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).1
n : Primrec fun a => a.1.2
k' : Primrec Prod.snd
c : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).2
⊢ Primrec fun p =>
    (fun p k' =>
        Code.recOn (ofNat (ℕ × Code) p.1.length).2 (some 0) (some p.2.succ) (some (unpair p.2).1) (some (unpair p.2).2)
          (fun cf cg x x => do
            let x ← Nat.Partrec.Code.lup p.1 ((ofNat (ℕ × Code) p.1.length).1, cf) p.2
            let y ← Nat.Partrec.Code.lup p.1 ((ofNat (ℕ × Code) p.1.length).1, cg) p.2
            some (Nat.pair x y))
          (fun cf cg x x => do
            let x ← Nat.Partrec.Code.lup p.1 ((ofNat (ℕ × Code) p.1.length).1, cg) p.2
            Nat.Partrec.Code.lup p.1 ((ofNat (ℕ × Code) p.1.length).1, cf) x)
          (fun cf cg x x =>
            let z := (unpair p.2).1;
            Nat.casesOn (unpair p.2).2 (Nat.Partrec.Code.lup p.1 ((ofNat (ℕ × Code) p.1.length).1, cf) z) fun y => do
              let i ← Nat.Partrec.Code.lup p.1 (k', (ofNat (ℕ × Code) p.1.length).2) (Nat.pair z y)
              Nat.Partrec.Code.lup p.1 ((ofNat (ℕ × Code) p.1.length).1, cg) (Nat.pair z (Nat.pair y i)))
          fun cf x =>
          let z := (unpair p.2).1;
          let m := (unpair p.2).2;
          do
          let x ← Nat.Partrec.Code.lup p.1 ((ofNat (ℕ × Code) p.1.length).1, cf) (Nat.pair z m)
          Nat.casesOn x (some m) fun x =>
              Nat.Partrec.Code.lup p.1 (k', (ofNat (ℕ × Code) p.1.length).2) (Nat.pair z (m + 1)))
      p.1 p.2
state_after: case hpr
a : Primrec fun a => ofNat (ℕ × Code) a.length
k✝ : Primrec fun a => (ofNat (ℕ × Code) a.1.length).1
n✝ : Primrec Prod.snd
k : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).1
n : Primrec fun a => a.1.2
k' : Primrec Prod.snd
c : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).2
⊢ Primrec fun a => do
    let x ← Nat.Partrec.Code.lup a.1.1.1 ((ofNat (ℕ × Code) a.1.1.1.length).1, a.2.1) a.1.1.2
    let y ← Nat.Partrec.Code.lup a.1.1.1 ((ofNat (ℕ × Code) a.1.1.1.length).1, a.2.2.1) a.1.1.2
    some (Nat.pair x y)

case hco
a : Primrec fun a => ofNat (ℕ × Code) a.length
k✝ : Primrec fun a => (ofNat (ℕ × Code) a.1.length).1
n✝ : Primrec Prod.snd
k : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).1
n : Primrec fun a => a.1.2
k' : Primrec Prod.snd
c : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).2
⊢ Primrec fun a => do
    let x ← Nat.Partrec.Code.lup a.1.1.1 ((ofNat (ℕ × Code) a.1.1.1.length).1, a.2.2.1) a.1.1.2
    Nat.Partrec.Code.lup a.1.1.1 ((ofNat (ℕ × Code) a.1.1.1.length).1, a.2.1) x

case hpc
a : Primrec fun a => ofNat (ℕ × Code) a.length
k✝ : Primrec fun a => (ofNat (ℕ × Code) a.1.length).1
n✝ : Primrec Prod.snd
k : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).1
n : Primrec fun a => a.1.2
k' : Primrec Prod.snd
c : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).2
⊢ Primrec fun a =>
    let z := (unpair a.1.1.2).1;
    Nat.casesOn (unpair a.1.1.2).2 (Nat.Partrec.Code.lup a.1.1.1 ((ofNat (ℕ × Code) a.1.1.1.length).1, a.2.1) z)
      fun y => do
      let i ← Nat.Partrec.Code.lup a.1.1.1 (a.1.2, (ofNat (ℕ × Code) a.1.1.1.length).2) (Nat.pair z y)
      Nat.Partrec.Code.lup a.1.1.1 ((ofNat (ℕ × Code) a.1.1.1.length).1, a.2.2.1) (Nat.pair z (Nat.pair y i))

case hrf
a : Primrec fun a => ofNat (ℕ × Code) a.length
k✝ : Primrec fun a => (ofNat (ℕ × Code) a.1.length).1
n✝ : Primrec Prod.snd
k : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).1
n : Primrec fun a => a.1.2
k' : Primrec Prod.snd
c : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).2
⊢ Primrec fun a =>
    let z := (unpair a.1.1.2).1;
    let m := (unpair a.1.1.2).2;
    do
    let x ← Nat.Partrec.Code.lup a.1.1.1 ((ofNat (ℕ × Code) a.1.1.1.length).1, a.2.1) (Nat.pair z m)
    Nat.casesOn x (some m) fun x =>
        Nat.Partrec.Code.lup a.1.1.1 (a.1.2, (ofNat (ℕ × Code) a.1.1.1.length).2) (Nat.pair z (m + 1))

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) a.length
k✝ : Primrec fun a => (ofNat (ℕ × Code) a.1.length).1
n✝ : Primrec Prod.snd
k : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).1
n : Primrec fun a => a.1.2
k' : Primrec Prod.snd
c : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).2
⊢ Primrec fun a => do
    let x ← Nat.Partrec.Code.lup a.1.1.1 ((ofNat (ℕ × Code) a.1.1.1.length).1, a.2.1) a.1.1.2
    let y ← Nat.Partrec.Code.lup a.1.1.1 ((ofNat (ℕ × Code) a.1.1.1.length).1, a.2.2.1) a.1.1.2
    some (Nat.pair x y)
state_after: case hpr
a : Primrec fun a => ofNat (ℕ × Code) a.length
k✝ : Primrec fun a => (ofNat (ℕ × Code) a.1.length).1
n✝ : Primrec Prod.snd
k : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).1
n : Primrec fun a => a.1.2
k' : Primrec Prod.snd
c : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).2
L : Primrec fun a => a.1.1.1
⊢ Primrec fun a => do
    let x ← Nat.Partrec.Code.lup a.1.1.1 ((ofNat (ℕ × Code) a.1.1.1.length).1, a.2.1) a.1.1.2
    let y ← Nat.Partrec.Code.lup a.1.1.1 ((ofNat (ℕ × Code) a.1.1.1.length).1, a.2.2.1) a.1.1.2
    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) a.length
k✝ : Primrec fun a => (ofNat (ℕ × Code) a.1.length).1
n✝ : Primrec Prod.snd
k : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).1
n : Primrec fun a => a.1.2
k' : Primrec Prod.snd
c : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).2
L : Primrec fun a => a.1.1.1
⊢ Primrec fun a => do
    let x ← Nat.Partrec.Code.lup a.1.1.1 ((ofNat (ℕ × Code) a.1.1.1.length).1, a.2.1) a.1.1.2
    let y ← Nat.Partrec.Code.lup a.1.1.1 ((ofNat (ℕ × Code) a.1.1.1.length).1, a.2.2.1) a.1.1.2
    some (Nat.pair x y)
state_after: case hpr
a : Primrec fun a => ofNat (ℕ × Code) a.length
k✝¹ : Primrec fun a => (ofNat (ℕ × Code) a.1.length).1
n✝ : Primrec Prod.snd
k✝ : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).1
n : Primrec fun a => a.1.2
k' : Primrec Prod.snd
c : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).2
L : Primrec fun a => a.1.1.1
k : Primrec fun a => (ofNat (ℕ × Code) a.1.1.1.length).1
⊢ Primrec fun a => do
    let x ← Nat.Partrec.Code.lup a.1.1.1 ((ofNat (ℕ × Code) a.1.1.1.length).1, a.2.1) a.1.1.2
    let y ← Nat.Partrec.Code.lup a.1.1.1 ((ofNat (ℕ × Code) a.1.1.1.length).1, a.2.2.1) a.1.1.2
    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) a.length
k✝¹ : Primrec fun a => (ofNat (ℕ × Code) a.1.length).1
n✝ : Primrec Prod.snd
k✝ : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).1
n : Primrec fun a => a.1.2
k' : Primrec Prod.snd
c : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).2
L : Primrec fun a => a.1.1.1
k : Primrec fun a => (ofNat (ℕ × Code) a.1.1.1.length).1
⊢ Primrec fun a => do
    let x ← Nat.Partrec.Code.lup a.1.1.1 ((ofNat (ℕ × Code) a.1.1.1.length).1, a.2.1) a.1.1.2
    let y ← Nat.Partrec.Code.lup a.1.1.1 ((ofNat (ℕ × Code) a.1.1.1.length).1, a.2.2.1) a.1.1.2
    some (Nat.pair x y)
state_after: case hpr
a : Primrec fun a => ofNat (ℕ × Code) a.length
k✝¹ : Primrec fun a => (ofNat (ℕ × Code) a.1.length).1
n✝¹ : Primrec Prod.snd
k✝ : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).1
n✝ : Primrec fun a => a.1.2
k' : Primrec Prod.snd
c : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).2
L : Primrec fun a => a.1.1.1
k : Primrec fun a => (ofNat (ℕ × Code) a.1.1.1.length).1
n : Primrec fun a => a.1.1.2
⊢ Primrec fun a => do
    let x ← Nat.Partrec.Code.lup a.1.1.1 ((ofNat (ℕ × Code) a.1.1.1.length).1, a.2.1) a.1.1.2
    let y ← Nat.Partrec.Code.lup a.1.1.1 ((ofNat (ℕ × Code) a.1.1.1.length).1, a.2.2.1) a.1.1.2
    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) a.length
k✝¹ : Primrec fun a => (ofNat (ℕ × Code) a.1.length).1
n✝¹ : Primrec Prod.snd
k✝ : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).1
n✝ : Primrec fun a => a.1.2
k' : Primrec Prod.snd
c : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).2
L : Primrec fun a => a.1.1.1
k : Primrec fun a => (ofNat (ℕ × Code) a.1.1.1.length).1
n : Primrec fun a => a.1.1.2
⊢ Primrec fun a => do
    let x ← Nat.Partrec.Code.lup a.1.1.1 ((ofNat (ℕ × Code) a.1.1.1.length).1, a.2.1) a.1.1.2
    let y ← Nat.Partrec.Code.lup a.1.1.1 ((ofNat (ℕ × Code) a.1.1.1.length).1, a.2.2.1) a.1.1.2
    some (Nat.pair x y)
state_after: case hpr
a : Primrec fun a => ofNat (ℕ × Code) a.length
k✝¹ : Primrec fun a => (ofNat (ℕ × Code) a.1.length).1
n✝¹ : Primrec Prod.snd
k✝ : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).1
n✝ : Primrec fun a => a.1.2
k' : Primrec Prod.snd
c : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).2
L : Primrec fun a => a.1.1.1
k : Primrec fun a => (ofNat (ℕ × Code) a.1.1.1.length).1
n : Primrec fun a => a.1.1.2
cf : Primrec fun a => a.2.1
⊢ Primrec fun a => do
    let x ← Nat.Partrec.Code.lup a.1.1.1 ((ofNat (ℕ × Code) a.1.1.1.length).1, a.2.1) a.1.1.2
    let y ← Nat.Partrec.Code.lup a.1.1.1 ((ofNat (ℕ × Code) a.1.1.1.length).1, a.2.2.1) a.1.1.2
    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) a.length
k✝¹ : Primrec fun a => (ofNat (ℕ × Code) a.1.length).1
n✝¹ : Primrec Prod.snd
k✝ : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).1
n✝ : Primrec fun a => a.1.2
k' : Primrec Prod.snd
c : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).2
L : Primrec fun a => a.1.1.1
k : Primrec fun a => (ofNat (ℕ × Code) a.1.1.1.length).1
n : Primrec fun a => a.1.1.2
cf : Primrec fun a => a.2.1
⊢ Primrec fun a => do
    let x ← Nat.Partrec.Code.lup a.1.1.1 ((ofNat (ℕ × Code) a.1.1.1.length).1, a.2.1) a.1.1.2
    let y ← Nat.Partrec.Code.lup a.1.1.1 ((ofNat (ℕ × Code) a.1.1.1.length).1, a.2.2.1) a.1.1.2
    some (Nat.pair x y)
state_after: case hpr
a : Primrec fun a => ofNat (ℕ × Code) a.length
k✝¹ : Primrec fun a => (ofNat (ℕ × Code) a.1.length).1
n✝¹ : Primrec Prod.snd
k✝ : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).1
n✝ : Primrec fun a => a.1.2
k' : Primrec Prod.snd
c : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).2
L : Primrec fun a => a.1.1.1
k : Primrec fun a => (ofNat (ℕ × Code) a.1.1.1.length).1
n : Primrec fun a => a.1.1.2
cf : Primrec fun a => a.2.1
cg : Primrec fun a => a.2.2.1
⊢ Primrec fun a => do
    let x ← Nat.Partrec.Code.lup a.1.1.1 ((ofNat (ℕ × Code) a.1.1.1.length).1, a.2.1) a.1.1.2
    let y ← Nat.Partrec.Code.lup a.1.1.1 ((ofNat (ℕ × Code) a.1.1.1.length).1, a.2.2.1) a.1.1.2
    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) a.length
k✝¹ : Primrec fun a => (ofNat (ℕ × Code) a.1.length).1
n✝¹ : Primrec Prod.snd
k✝ : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).1
n✝ : Primrec fun a => a.1.2
k' : Primrec Prod.snd
c : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).2
L : Primrec fun a => a.1.1.1
k : Primrec fun a => (ofNat (ℕ × Code) a.1.1.1.length).1
n : Primrec fun a => a.1.1.2
cf : Primrec fun a => a.2.1
cg : Primrec fun a => a.2.2.1
⊢ Primrec fun a => do
    let x ← Nat.Partrec.Code.lup a.1.1.1 ((ofNat (ℕ × Code) a.1.1.1.length).1, a.2.1) a.1.1.2
    let y ← Nat.Partrec.Code.lup a.1.1.1 ((ofNat (ℕ × Code) a.1.1.1.length).1, a.2.2.1) a.1.1.2
    some (Nat.pair x y)
state_after: case hpr
a : Primrec fun a => ofNat (ℕ × Code) a.length
k✝¹ : Primrec fun a => (ofNat (ℕ × Code) a.1.length).1
n✝¹ : Primrec Prod.snd
k✝ : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).1
n✝ : Primrec fun a => a.1.2
k' : Primrec Prod.snd
c : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).2
L : Primrec fun a => a.1.1.1
k : Primrec fun a => (ofNat (ℕ × Code) a.1.1.1.length).1
n : Primrec fun a => a.1.1.2
cf : Primrec fun a => a.2.1
cg : Primrec fun a => a.2.2.1
⊢ Primrec₂ fun a x => do
    let y ← Nat.Partrec.Code.lup a.1.1.1 ((ofNat (ℕ × Code) a.1.1.1.length).1, a.2.2.1) a.1.1.2
    some (Nat.pair x y)

tactic: unfold Primrec₂
state_before: case hpr
a : Primrec fun a => ofNat (ℕ × Code) a.length
k✝¹ : Primrec fun a => (ofNat (ℕ × Code) a.1.length).1
n✝¹ : Primrec Prod.snd
k✝ : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).1
n✝ : Primrec fun a => a.1.2
k' : Primrec Prod.snd
c : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).2
L : Primrec fun a => a.1.1.1
k : Primrec fun a => (ofNat (ℕ × Code) a.1.1.1.length).1
n : Primrec fun a => a.1.1.2
cf : Primrec fun a => a.2.1
cg : Primrec fun a => a.2.2.1
⊢ Primrec₂ fun a x => do
    let y ← Nat.Partrec.Code.lup a.1.1.1 ((ofNat (ℕ × Code) a.1.1.1.length).1, a.2.2.1) a.1.1.2
    some (Nat.pair x y)
state_after: case hpr
a : Primrec fun a => ofNat (ℕ × Code) a.length
k✝¹ : Primrec fun a => (ofNat (ℕ × Code) a.1.length).1
n✝¹ : Primrec Prod.snd
k✝ : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).1
n✝ : Primrec fun a => a.1.2
k' : Primrec Prod.snd
c : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).2
L : Primrec fun a => a.1.1.1
k : Primrec fun a => (ofNat (ℕ × Code) a.1.1.1.length).1
n : Primrec fun a => a.1.1.2
cf : Primrec fun a => a.2.1
cg : Primrec fun a => a.2.2.1
⊢ Primrec fun p =>
    (fun a x => do
        let y ← Nat.Partrec.Code.lup a.1.1.1 ((ofNat (ℕ × Code) a.1.1.1.length).1, a.2.2.1) a.1.1.2
        some (Nat.pair x y))
      p.1 p.2

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) a.length
k✝¹ : Primrec fun a => (ofNat (ℕ × Code) a.1.length).1
n✝¹ : Primrec Prod.snd
k✝ : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).1
n✝ : Primrec fun a => a.1.2
k' : Primrec Prod.snd
c : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).2
L : Primrec fun a => a.1.1.1
k : Primrec fun a => (ofNat (ℕ × Code) a.1.1.1.length).1
n : Primrec fun a => a.1.1.2
cf : Primrec fun a => a.2.1
cg : Primrec fun a => a.2.2.1
⊢ Primrec fun p =>
    Option.map (Nat.pair p.2)
      (Nat.Partrec.Code.lup p.1.1.1.1 ((ofNat (ℕ × Code) p.1.1.1.1.length).1, p.1.2.2.1) p.1.1.1.2)
state_after: case hpr
a : Primrec fun a => ofNat (ℕ × Code) a.length
k✝¹ : Primrec fun a => (ofNat (ℕ × Code) a.1.length).1
n✝¹ : Primrec Prod.snd
k✝ : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).1
n✝ : Primrec fun a => a.1.2
k' : Primrec Prod.snd
c : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).2
L : Primrec fun a => a.1.1.1
k : Primrec fun a => (ofNat (ℕ × Code) a.1.1.1.length).1
n : Primrec fun a => a.1.1.2
cf : Primrec fun a => a.2.1
cg : Primrec fun a => a.2.2.1
⊢ Primrec₂ fun p => Nat.pair p.2

tactic: unfold Primrec₂
state_before: case hpr
a : Primrec fun a => ofNat (ℕ × Code) a.length
k✝¹ : Primrec fun a => (ofNat (ℕ × Code) a.1.length).1
n✝¹ : Primrec Prod.snd
k✝ : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).1
n✝ : Primrec fun a => a.1.2
k' : Primrec Prod.snd
c : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).2
L : Primrec fun a => a.1.1.1
k : Primrec fun a => (ofNat (ℕ × Code) a.1.1.1.length).1
n : Primrec fun a => a.1.1.2
cf : Primrec fun a => a.2.1
cg : Primrec fun a => a.2.2.1
⊢ Primrec₂ fun p => Nat.pair p.2
state_after: case hpr
a : Primrec fun a => ofNat (ℕ × Code) a.length
k✝¹ : Primrec fun a => (ofNat (ℕ × Code) a.1.length).1
n✝¹ : Primrec Prod.snd
k✝ : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).1
n✝ : Primrec fun a => a.1.2
k' : Primrec Prod.snd
c : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).2
L : Primrec fun a => a.1.1.1
k : Primrec fun a => (ofNat (ℕ × Code) a.1.1.1.length).1
n : Primrec fun a => a.1.1.2
cf : Primrec fun a => a.2.1
cg : Primrec fun a => a.2.2.1
⊢ Primrec fun p => (fun p => Nat.pair p.2) p.1 p.2

tactic: exact Primrec₂.natPair.comp (Primrec.snd.comp Primrec.fst) Primrec.snd
state_before: case hpr
a : Primrec fun a => ofNat (ℕ × Code) a.length
k✝¹ : Primrec fun a => (ofNat (ℕ × Code) a.1.length).1
n✝¹ : Primrec Prod.snd
k✝ : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).1
n✝ : Primrec fun a => a.1.2
k' : Primrec Prod.snd
c : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).2
L : Primrec fun a => a.1.1.1
k : Primrec fun a => (ofNat (ℕ × Code) a.1.1.1.length).1
n : Primrec fun a => a.1.1.2
cf : Primrec fun a => a.2.1
cg : Primrec fun a => a.2.2.1
⊢ Primrec fun p => (fun p => Nat.pair p.2) p.1 p.2
state_after: no goals

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) a.length
k✝ : Primrec fun a => (ofNat (ℕ × Code) a.1.length).1
n✝ : Primrec Prod.snd
k : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).1
n : Primrec fun a => a.1.2
k' : Primrec Prod.snd
c : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).2
⊢ Primrec fun a => do
    let x ← Nat.Partrec.Code.lup a.1.1.1 ((ofNat (ℕ × Code) a.1.1.1.length).1, a.2.2.1) a.1.1.2
    Nat.Partrec.Code.lup a.1.1.1 ((ofNat (ℕ × Code) a.1.1.1.length).1, a.2.1) x
state_after: case hco
a : Primrec fun a => ofNat (ℕ × Code) a.length
k✝ : Primrec fun a => (ofNat (ℕ × Code) a.1.length).1
n✝ : Primrec Prod.snd
k : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).1
n : Primrec fun a => a.1.2
k' : Primrec Prod.snd
c : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).2
L : Primrec fun a => a.1.1.1
⊢ Primrec fun a => do
    let x ← Nat.Partrec.Code.lup a.1.1.1 ((ofNat (ℕ × Code) a.1.1.1.length).1, a.2.2.1) a.1.1.2
    Nat.Partrec.Code.lup a.1.1.1 ((ofNat (ℕ × Code) a.1.1.1.length).1, a.2.1) x

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

tactic: have n := n.comp (Primrec.fst (β := Code × Code × Option ℕ × Option ℕ))
state_before: case hco
a : Primrec fun a => ofNat (ℕ × Code) a.length
k✝¹ : Primrec fun a => (ofNat (ℕ × Code) a.1.length).1
n✝ : Primrec Prod.snd
k✝ : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).1
n : Primrec fun a => a.1.2
k' : Primrec Prod.snd
c : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).2
L : Primrec fun a => a.1.1.1
k : Primrec fun a => (ofNat (ℕ × Code) a.1.1.1.length).1
⊢ Primrec fun a => do
    let x ← Nat.Partrec.Code.lup a.1.1.1 ((ofNat (ℕ × Code) a.1.1.1.length).1, a.2.2.1) a.1.1.2
    Nat.Partrec.Code.lup a.1.1.1 ((ofNat (ℕ × Code) a.1.1.1.length).1, a.2.1) x
state_after: case hco
a : Primrec fun a => ofNat (ℕ × Code) a.length
k✝¹ : Primrec fun a => (ofNat (ℕ × Code) a.1.length).1
n✝¹ : Primrec Prod.snd
k✝ : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).1
n✝ : Primrec fun a => a.1.2
k' : Primrec Prod.snd
c : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).2
L : Primrec fun a => a.1.1.1
k : Primrec fun a => (ofNat (ℕ × Code) a.1.1.1.length).1
n : Primrec fun a => a.1.1.2
⊢ Primrec fun a => do
    let x ← Nat.Partrec.Code.lup a.1.1.1 ((ofNat (ℕ × Code) a.1.1.1.length).1, a.2.2.1) a.1.1.2
    Nat.Partrec.Code.lup a.1.1.1 ((ofNat (ℕ × Code) a.1.1.1.length).1, a.2.1) 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) a.length
k✝¹ : Primrec fun a => (ofNat (ℕ × Code) a.1.length).1
n✝¹ : Primrec Prod.snd
k✝ : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).1
n✝ : Primrec fun a => a.1.2
k' : Primrec Prod.snd
c : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).2
L : Primrec fun a => a.1.1.1
k : Primrec fun a => (ofNat (ℕ × Code) a.1.1.1.length).1
n : Primrec fun a => a.1.1.2
⊢ Primrec fun a => do
    let x ← Nat.Partrec.Code.lup a.1.1.1 ((ofNat (ℕ × Code) a.1.1.1.length).1, a.2.2.1) a.1.1.2
    Nat.Partrec.Code.lup a.1.1.1 ((ofNat (ℕ × Code) a.1.1.1.length).1, a.2.1) x
state_after: case hco
a : Primrec fun a => ofNat (ℕ × Code) a.length
k✝¹ : Primrec fun a => (ofNat (ℕ × Code) a.1.length).1
n✝¹ : Primrec Prod.snd
k✝ : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).1
n✝ : Primrec fun a => a.1.2
k' : Primrec Prod.snd
c : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).2
L : Primrec fun a => a.1.1.1
k : Primrec fun a => (ofNat (ℕ × Code) a.1.1.1.length).1
n : Primrec fun a => a.1.1.2
cf : Primrec fun a => a.2.1
⊢ Primrec fun a => do
    let x ← Nat.Partrec.Code.lup a.1.1.1 ((ofNat (ℕ × Code) a.1.1.1.length).1, a.2.2.1) a.1.1.2
    Nat.Partrec.Code.lup a.1.1.1 ((ofNat (ℕ × Code) a.1.1.1.length).1, a.2.1) 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) a.length
k✝¹ : Primrec fun a => (ofNat (ℕ × Code) a.1.length).1
n✝¹ : Primrec Prod.snd
k✝ : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).1
n✝ : Primrec fun a => a.1.2
k' : Primrec Prod.snd
c : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).2
L : Primrec fun a => a.1.1.1
k : Primrec fun a => (ofNat (ℕ × Code) a.1.1.1.length).1
n : Primrec fun a => a.1.1.2
cf : Primrec fun a => a.2.1
⊢ Primrec fun a => do
    let x ← Nat.Partrec.Code.lup a.1.1.1 ((ofNat (ℕ × Code) a.1.1.1.length).1, a.2.2.1) a.1.1.2
    Nat.Partrec.Code.lup a.1.1.1 ((ofNat (ℕ × Code) a.1.1.1.length).1, a.2.1) x
state_after: case hco
a : Primrec fun a => ofNat (ℕ × Code) a.length
k✝¹ : Primrec fun a => (ofNat (ℕ × Code) a.1.length).1
n✝¹ : Primrec Prod.snd
k✝ : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).1
n✝ : Primrec fun a => a.1.2
k' : Primrec Prod.snd
c : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).2
L : Primrec fun a => a.1.1.1
k : Primrec fun a => (ofNat (ℕ × Code) a.1.1.1.length).1
n : Primrec fun a => a.1.1.2
cf : Primrec fun a => a.2.1
cg : Primrec fun a => a.2.2.1
⊢ Primrec fun a => do
    let x ← Nat.Partrec.Code.lup a.1.1.1 ((ofNat (ℕ × Code) a.1.1.1.length).1, a.2.2.1) a.1.1.2
    Nat.Partrec.Code.lup a.1.1.1 ((ofNat (ℕ × Code) a.1.1.1.length).1, a.2.1) 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) a.length
k✝¹ : Primrec fun a => (ofNat (ℕ × Code) a.1.length).1
n✝¹ : Primrec Prod.snd
k✝ : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).1
n✝ : Primrec fun a => a.1.2
k' : Primrec Prod.snd
c : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).2
L : Primrec fun a => a.1.1.1
k : Primrec fun a => (ofNat (ℕ × Code) a.1.1.1.length).1
n : Primrec fun a => a.1.1.2
cf : Primrec fun a => a.2.1
cg : Primrec fun a => a.2.2.1
⊢ Primrec fun a => do
    let x ← Nat.Partrec.Code.lup a.1.1.1 ((ofNat (ℕ × Code) a.1.1.1.length).1, a.2.2.1) a.1.1.2
    Nat.Partrec.Code.lup a.1.1.1 ((ofNat (ℕ × Code) a.1.1.1.length).1, a.2.1) x
state_after: case hco
a : Primrec fun a => ofNat (ℕ × Code) a.length
k✝¹ : Primrec fun a => (ofNat (ℕ × Code) a.1.length).1
n✝¹ : Primrec Prod.snd
k✝ : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).1
n✝ : Primrec fun a => a.1.2
k' : Primrec Prod.snd
c : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).2
L : Primrec fun a => a.1.1.1
k : Primrec fun a => (ofNat (ℕ × Code) a.1.1.1.length).1
n : Primrec fun a => a.1.1.2
cf : Primrec fun a => a.2.1
cg : Primrec fun a => a.2.2.1
⊢ Primrec₂ fun a x => Nat.Partrec.Code.lup a.1.1.1 ((ofNat (ℕ × Code) a.1.1.1.length).1, a.2.1) x

tactic: unfold Primrec₂
state_before: case hco
a : Primrec fun a => ofNat (ℕ × Code) a.length
k✝¹ : Primrec fun a => (ofNat (ℕ × Code) a.1.length).1
n✝¹ : Primrec Prod.snd
k✝ : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).1
n✝ : Primrec fun a => a.1.2
k' : Primrec Prod.snd
c : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).2
L : Primrec fun a => a.1.1.1
k : Primrec fun a => (ofNat (ℕ × Code) a.1.1.1.length).1
n : Primrec fun a => a.1.1.2
cf : Primrec fun a => a.2.1
cg : Primrec fun a => a.2.2.1
⊢ Primrec₂ fun a x => Nat.Partrec.Code.lup a.1.1.1 ((ofNat (ℕ × Code) a.1.1.1.length).1, a.2.1) x
state_after: case hco
a : Primrec fun a => ofNat (ℕ × Code) a.length
k✝¹ : Primrec fun a => (ofNat (ℕ × Code) a.1.length).1
n✝¹ : Primrec Prod.snd
k✝ : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).1
n✝ : Primrec fun a => a.1.2
k' : Primrec Prod.snd
c : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).2
L : Primrec fun a => a.1.1.1
k : Primrec fun a => (ofNat (ℕ × Code) a.1.1.1.length).1
n : Primrec fun a => a.1.1.2
cf : Primrec fun a => a.2.1
cg : Primrec fun a => a.2.2.1
⊢ Primrec fun p => (fun a x => Nat.Partrec.Code.lup a.1.1.1 ((ofNat (ℕ × Code) a.1.1.1.length).1, a.2.1) x) p.1 p.2

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) a.length
k✝¹ : Primrec fun a => (ofNat (ℕ × Code) a.1.length).1
n✝¹ : Primrec Prod.snd
k✝ : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).1
n✝ : Primrec fun a => a.1.2
k' : Primrec Prod.snd
c : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).2
L : Primrec fun a => a.1.1.1
k : Primrec fun a => (ofNat (ℕ × Code) a.1.1.1.length).1
n : Primrec fun a => a.1.1.2
cf : Primrec fun a => a.2.1
cg : Primrec fun a => a.2.2.1
⊢ Primrec fun p => (fun a x => Nat.Partrec.Code.lup a.1.1.1 ((ofNat (ℕ × Code) a.1.1.1.length).1, a.2.1) x) p.1 p.2
state_after: case hco
a : Primrec fun a => ofNat (ℕ × Code) a.length
k✝¹ : Primrec fun a => (ofNat (ℕ × Code) a.1.length).1
n✝¹ : Primrec Prod.snd
k✝ : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).1
n✝ : Primrec fun a => a.1.2
k' : Primrec Prod.snd
c : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).2
L : Primrec fun a => a.1.1.1
k : Primrec fun a => (ofNat (ℕ × Code) a.1.1.1.length).1
n : Primrec fun a => a.1.1.2
cf : Primrec fun a => a.2.1
cg : Primrec fun a => a.2.2.1
h :
  Primrec fun a =>
    Nat.Partrec.Code.lup (a.1.1.1.1, ((ofNat (ℕ × Code) a.1.1.1.1.length).1, a.1.2.1), a.2).1
      (a.1.1.1.1, ((ofNat (ℕ × Code) a.1.1.1.1.length).1, a.1.2.1), a.2).2.1
      (a.1.1.1.1, ((ofNat (ℕ × Code) a.1.1.1.1.length).1, a.1.2.1), a.2).2.2
⊢ Primrec fun p => (fun a x => Nat.Partrec.Code.lup a.1.1.1 ((ofNat (ℕ × Code) a.1.1.1.length).1, a.2.1) x) p.1 p.2

tactic: exact h
state_before: case hco
a : Primrec fun a => ofNat (ℕ × Code) a.length
k✝¹ : Primrec fun a => (ofNat (ℕ × Code) a.1.length).1
n✝¹ : Primrec Prod.snd
k✝ : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).1
n✝ : Primrec fun a => a.1.2
k' : Primrec Prod.snd
c : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).2
L : Primrec fun a => a.1.1.1
k : Primrec fun a => (ofNat (ℕ × Code) a.1.1.1.length).1
n : Primrec fun a => a.1.1.2
cf : Primrec fun a => a.2.1
cg : Primrec fun a => a.2.2.1
h :
  Primrec fun a =>
    Nat.Partrec.Code.lup (a.1.1.1.1, ((ofNat (ℕ × Code) a.1.1.1.1.length).1, a.1.2.1), a.2).1
      (a.1.1.1.1, ((ofNat (ℕ × Code) a.1.1.1.1.length).1, a.1.2.1), a.2).2.1
      (a.1.1.1.1, ((ofNat (ℕ × Code) a.1.1.1.1.length).1, a.1.2.1), a.2).2.2
⊢ Primrec fun p => (fun a x => Nat.Partrec.Code.lup a.1.1.1 ((ofNat (ℕ × Code) a.1.1.1.length).1, a.2.1) x) p.1 p.2
state_after: no goals

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) a.length
k✝ : Primrec fun a => (ofNat (ℕ × Code) a.1.length).1
n✝ : Primrec Prod.snd
k : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).1
n : Primrec fun a => a.1.2
k' : Primrec Prod.snd
c : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).2
⊢ Primrec fun a =>
    let z := (unpair a.1.1.2).1;
    Nat.casesOn (unpair a.1.1.2).2 (Nat.Partrec.Code.lup a.1.1.1 ((ofNat (ℕ × Code) a.1.1.1.length).1, a.2.1) z)
      fun y => do
      let i ← Nat.Partrec.Code.lup a.1.1.1 (a.1.2, (ofNat (ℕ × Code) a.1.1.1.length).2) (Nat.pair z y)
      Nat.Partrec.Code.lup a.1.1.1 ((ofNat (ℕ × Code) a.1.1.1.length).1, a.2.2.1) (Nat.pair z (Nat.pair y i))
state_after: case hpc
a : Primrec fun a => ofNat (ℕ × Code) a.length
k✝ : Primrec fun a => (ofNat (ℕ × Code) a.1.length).1
n✝ : Primrec Prod.snd
k : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).1
n : Primrec fun a => a.1.2
k' : Primrec Prod.snd
c : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).2
L : Primrec fun a => a.1.1.1
⊢ Primrec fun a =>
    let z := (unpair a.1.1.2).1;
    Nat.casesOn (unpair a.1.1.2).2 (Nat.Partrec.Code.lup a.1.1.1 ((ofNat (ℕ × Code) a.1.1.1.length).1, a.2.1) z)
      fun y => do
      let i ← Nat.Partrec.Code.lup a.1.1.1 (a.1.2, (ofNat (ℕ × Code) a.1.1.1.length).2) (Nat.pair z y)
      Nat.Partrec.Code.lup a.1.1.1 ((ofNat (ℕ × Code) a.1.1.1.length).1, a.2.2.1) (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) a.length
k✝ : Primrec fun a => (ofNat (ℕ × Code) a.1.length).1
n✝ : Primrec Prod.snd
k : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).1
n : Primrec fun a => a.1.2
k' : Primrec Prod.snd
c : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).2
L : Primrec fun a => a.1.1.1
⊢ Primrec fun a =>
    let z := (unpair a.1.1.2).1;
    Nat.casesOn (unpair a.1.1.2).2 (Nat.Partrec.Code.lup a.1.1.1 ((ofNat (ℕ × Code) a.1.1.1.length).1, a.2.1) z)
      fun y => do
      let i ← Nat.Partrec.Code.lup a.1.1.1 (a.1.2, (ofNat (ℕ × Code) a.1.1.1.length).2) (Nat.pair z y)
      Nat.Partrec.Code.lup a.1.1.1 ((ofNat (ℕ × Code) a.1.1.1.length).1, a.2.2.1) (Nat.pair z (Nat.pair y i))
state_after: case hpc
a : Primrec fun a => ofNat (ℕ × Code) a.length
k✝¹ : Primrec fun a => (ofNat (ℕ × Code) a.1.length).1
n✝ : Primrec Prod.snd
k✝ : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).1
n : Primrec fun a => a.1.2
k' : Primrec Prod.snd
c : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).2
L : Primrec fun a => a.1.1.1
k : Primrec fun a => (ofNat (ℕ × Code) a.1.1.1.length).1
⊢ Primrec fun a =>
    let z := (unpair a.1.1.2).1;
    Nat.casesOn (unpair a.1.1.2).2 (Nat.Partrec.Code.lup a.1.1.1 ((ofNat (ℕ × Code) a.1.1.1.length).1, a.2.1) z)
      fun y => do
      let i ← Nat.Partrec.Code.lup a.1.1.1 (a.1.2, (ofNat (ℕ × Code) a.1.1.1.length).2) (Nat.pair z y)
      Nat.Partrec.Code.lup a.1.1.1 ((ofNat (ℕ × Code) a.1.1.1.length).1, a.2.2.1) (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) a.length
k✝¹ : Primrec fun a => (ofNat (ℕ × Code) a.1.length).1
n✝ : Primrec Prod.snd
k✝ : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).1
n : Primrec fun a => a.1.2
k' : Primrec Prod.snd
c : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).2
L : Primrec fun a => a.1.1.1
k : Primrec fun a => (ofNat (ℕ × Code) a.1.1.1.length).1
⊢ Primrec fun a =>
    let z := (unpair a.1.1.2).1;
    Nat.casesOn (unpair a.1.1.2).2 (Nat.Partrec.Code.lup a.1.1.1 ((ofNat (ℕ × Code) a.1.1.1.length).1, a.2.1) z)
      fun y => do
      let i ← Nat.Partrec.Code.lup a.1.1.1 (a.1.2, (ofNat (ℕ × Code) a.1.1.1.length).2) (Nat.pair z y)
      Nat.Partrec.Code.lup a.1.1.1 ((ofNat (ℕ × Code) a.1.1.1.length).1, a.2.2.1) (Nat.pair z (Nat.pair y i))
state_after: case hpc
a : Primrec fun a => ofNat (ℕ × Code) a.length
k✝¹ : Primrec fun a => (ofNat (ℕ × Code) a.1.length).1
n✝¹ : Primrec Prod.snd
k✝ : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).1
n✝ : Primrec fun a => a.1.2
k' : Primrec Prod.snd
c : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).2
L : Primrec fun a => a.1.1.1
k : Primrec fun a => (ofNat (ℕ × Code) a.1.1.1.length).1
n : Primrec fun a => a.1.1.2
⊢ Primrec fun a =>
    let z := (unpair a.1.1.2).1;
    Nat.casesOn (unpair a.1.1.2).2 (Nat.Partrec.Code.lup a.1.1.1 ((ofNat (ℕ × Code) a.1.1.1.length).1, a.2.1) z)
      fun y => do
      let i ← Nat.Partrec.Code.lup a.1.1.1 (a.1.2, (ofNat (ℕ × Code) a.1.1.1.length).2) (Nat.pair z y)
      Nat.Partrec.Code.lup a.1.1.1 ((ofNat (ℕ × Code) a.1.1.1.length).1, a.2.2.1) (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) a.length
k✝¹ : Primrec fun a => (ofNat (ℕ × Code) a.1.length).1
n✝¹ : Primrec Prod.snd
k✝ : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).1
n✝ : Primrec fun a => a.1.2
k' : Primrec Prod.snd
c : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).2
L : Primrec fun a => a.1.1.1
k : Primrec fun a => (ofNat (ℕ × Code) a.1.1.1.length).1
n : Primrec fun a => a.1.1.2
⊢ Primrec fun a =>
    let z := (unpair a.1.1.2).1;
    Nat.casesOn (unpair a.1.1.2).2 (Nat.Partrec.Code.lup a.1.1.1 ((ofNat (ℕ × Code) a.1.1.1.length).1, a.2.1) z)
      fun y => do
      let i ← Nat.Partrec.Code.lup a.1.1.1 (a.1.2, (ofNat (ℕ × Code) a.1.1.1.length).2) (Nat.pair z y)
      Nat.Partrec.Code.lup a.1.1.1 ((ofNat (ℕ × Code) a.1.1.1.length).1, a.2.2.1) (Nat.pair z (Nat.pair y i))
state_after: case hpc
a : Primrec fun a => ofNat (ℕ × Code) a.length
k✝¹ : Primrec fun a => (ofNat (ℕ × Code) a.1.length).1
n✝¹ : Primrec Prod.snd
k✝ : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).1
n✝ : Primrec fun a => a.1.2
k' : Primrec Prod.snd
c : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).2
L : Primrec fun a => a.1.1.1
k : Primrec fun a => (ofNat (ℕ × Code) a.1.1.1.length).1
n : Primrec fun a => a.1.1.2
cf : Primrec fun a => a.2.1
⊢ Primrec fun a =>
    let z := (unpair a.1.1.2).1;
    Nat.casesOn (unpair a.1.1.2).2 (Nat.Partrec.Code.lup a.1.1.1 ((ofNat (ℕ × Code) a.1.1.1.length).1, a.2.1) z)
      fun y => do
      let i ← Nat.Partrec.Code.lup a.1.1.1 (a.1.2, (ofNat (ℕ × Code) a.1.1.1.length).2) (Nat.pair z y)
      Nat.Partrec.Code.lup a.1.1.1 ((ofNat (ℕ × Code) a.1.1.1.length).1, a.2.2.1) (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) a.length
k✝¹ : Primrec fun a => (ofNat (ℕ × Code) a.1.length).1
n✝¹ : Primrec Prod.snd
k✝ : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).1
n✝ : Primrec fun a => a.1.2
k' : Primrec Prod.snd
c : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).2
L : Primrec fun a => a.1.1.1
k : Primrec fun a => (ofNat (ℕ × Code) a.1.1.1.length).1
n : Primrec fun a => a.1.1.2
cf : Primrec fun a => a.2.1
⊢ Primrec fun a =>
    let z := (unpair a.1.1.2).1;
    Nat.casesOn (unpair a.1.1.2).2 (Nat.Partrec.Code.lup a.1.1.1 ((ofNat (ℕ × Code) a.1.1.1.length).1, a.2.1) z)
      fun y => do
      let i ← Nat.Partrec.Code.lup a.1.1.1 (a.1.2, (ofNat (ℕ × Code) a.1.1.1.length).2) (Nat.pair z y)
      Nat.Partrec.Code.lup a.1.1.1 ((ofNat (ℕ × Code) a.1.1.1.length).1, a.2.2.1) (Nat.pair z (Nat.pair y i))
state_after: case hpc
a : Primrec fun a => ofNat (ℕ × Code) a.length
k✝¹ : Primrec fun a => (ofNat (ℕ × Code) a.1.length).1
n✝¹ : Primrec Prod.snd
k✝ : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).1
n✝ : Primrec fun a => a.1.2
k' : Primrec Prod.snd
c : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).2
L : Primrec fun a => a.1.1.1
k : Primrec fun a => (ofNat (ℕ × Code) a.1.1.1.length).1
n : Primrec fun a => a.1.1.2
cf : Primrec fun a => a.2.1
cg : Primrec fun a => a.2.2.1
⊢ Primrec fun a =>
    let z := (unpair a.1.1.2).1;
    Nat.casesOn (unpair a.1.1.2).2 (Nat.Partrec.Code.lup a.1.1.1 ((ofNat (ℕ × Code) a.1.1.1.length).1, a.2.1) z)
      fun y => do
      let i ← Nat.Partrec.Code.lup a.1.1.1 (a.1.2, (ofNat (ℕ × Code) a.1.1.1.length).2) (Nat.pair z y)
      Nat.Partrec.Code.lup a.1.1.1 ((ofNat (ℕ × Code) a.1.1.1.length).1, a.2.2.1) (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) a.length
k✝¹ : Primrec fun a => (ofNat (ℕ × Code) a.1.length).1
n✝¹ : Primrec Prod.snd
k✝ : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).1
n✝ : Primrec fun a => a.1.2
k' : Primrec Prod.snd
c : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).2
L : Primrec fun a => a.1.1.1
k : Primrec fun a => (ofNat (ℕ × Code) a.1.1.1.length).1
n : Primrec fun a => a.1.1.2
cf : Primrec fun a => a.2.1
cg : Primrec fun a => a.2.2.1
⊢ Primrec fun a =>
    let z := (unpair a.1.1.2).1;
    Nat.casesOn (unpair a.1.1.2).2 (Nat.Partrec.Code.lup a.1.1.1 ((ofNat (ℕ × Code) a.1.1.1.length).1, a.2.1) z)
      fun y => do
      let i ← Nat.Partrec.Code.lup a.1.1.1 (a.1.2, (ofNat (ℕ × Code) a.1.1.1.length).2) (Nat.pair z y)
      Nat.Partrec.Code.lup a.1.1.1 ((ofNat (ℕ × Code) a.1.1.1.length).1, a.2.2.1) (Nat.pair z (Nat.pair y i))
state_after: case hpc
a : Primrec fun a => ofNat (ℕ × Code) a.length
k✝¹ : Primrec fun a => (ofNat (ℕ × Code) a.1.length).1
n✝¹ : Primrec Prod.snd
k✝ : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).1
n✝ : Primrec fun a => a.1.2
k' : Primrec Prod.snd
c : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).2
L : Primrec fun a => a.1.1.1
k : Primrec fun a => (ofNat (ℕ × Code) a.1.1.1.length).1
n : Primrec fun a => a.1.1.2
cf : Primrec fun a => a.2.1
cg : Primrec fun a => a.2.2.1
z : Primrec fun a => (unpair a.1.1.2).1
⊢ Primrec fun a =>
    let z := (unpair a.1.1.2).1;
    Nat.casesOn (unpair a.1.1.2).2 (Nat.Partrec.Code.lup a.1.1.1 ((ofNat (ℕ × Code) a.1.1.1.length).1, a.2.1) z)
      fun y => do
      let i ← Nat.Partrec.Code.lup a.1.1.1 (a.1.2, (ofNat (ℕ × Code) a.1.1.1.length).2) (Nat.pair z y)
      Nat.Partrec.Code.lup a.1.1.1 ((ofNat (ℕ × Code) a.1.1.1.length).1, a.2.2.1) (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) a.length
k✝¹ : Primrec fun a => (ofNat (ℕ × Code) a.1.length).1
n✝¹ : Primrec Prod.snd
k✝ : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).1
n✝ : Primrec fun a => a.1.2
k' : Primrec Prod.snd
c : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).2
L : Primrec fun a => a.1.1.1
k : Primrec fun a => (ofNat (ℕ × Code) a.1.1.1.length).1
n : Primrec fun a => a.1.1.2
cf : Primrec fun a => a.2.1
cg : Primrec fun a => a.2.2.1
z : Primrec fun a => (unpair a.1.1.2).1
⊢ Primrec fun a =>
    let z := (unpair a.1.1.2).1;
    Nat.casesOn (unpair a.1.1.2).2 (Nat.Partrec.Code.lup a.1.1.1 ((ofNat (ℕ × Code) a.1.1.1.length).1, a.2.1) z)
      fun y => do
      let i ← Nat.Partrec.Code.lup a.1.1.1 (a.1.2, (ofNat (ℕ × Code) a.1.1.1.length).2) (Nat.pair z y)
      Nat.Partrec.Code.lup a.1.1.1 ((ofNat (ℕ × Code) a.1.1.1.length).1, a.2.2.1) (Nat.pair z (Nat.pair y i))
state_after: case hpc
a : Primrec fun a => ofNat (ℕ × Code) a.length
k✝¹ : Primrec fun a => (ofNat (ℕ × Code) a.1.length).1
n✝¹ : Primrec Prod.snd
k✝ : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).1
n✝ : Primrec fun a => a.1.2
k' : Primrec Prod.snd
c : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).2
L : Primrec fun a => a.1.1.1
k : Primrec fun a => (ofNat (ℕ × Code) a.1.1.1.length).1
n : Primrec fun a => a.1.1.2
cf : Primrec fun a => a.2.1
cg : Primrec fun a => a.2.2.1
z : Primrec fun a => (unpair a.1.1.2).1
⊢ Primrec fun p =>
    (fun a y => do
        let i ←
          Nat.Partrec.Code.lup a.1.1.1 (a.1.2, (ofNat (ℕ × Code) a.1.1.1.length).2) (Nat.pair (unpair a.1.1.2).1 y)
        Nat.Partrec.Code.lup a.1.1.1 ((ofNat (ℕ × Code) a.1.1.1.length).1, a.2.2.1)
            (Nat.pair (unpair a.1.1.2).1 (Nat.pair y i)))
      p.1 p.2

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

tactic: have z := z.comp (Primrec.fst (β := ℕ))
state_before: case hpc
a : Primrec fun a => ofNat (ℕ × Code) a.length
k✝¹ : Primrec fun a => (ofNat (ℕ × Code) a.1.length).1
n✝¹ : Primrec Prod.snd
k✝ : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).1
n✝ : Primrec fun a => a.1.2
k' : Primrec Prod.snd
c : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).2
L✝ : Primrec fun a => a.1.1.1
k : Primrec fun a => (ofNat (ℕ × Code) a.1.1.1.length).1
n : Primrec fun a => a.1.1.2
cf : Primrec fun a => a.2.1
cg : Primrec fun a => a.2.2.1
z : Primrec fun a => (unpair a.1.1.2).1
L : Primrec fun a => a.1.1.1.1
⊢ Primrec fun p =>
    (fun a y => do
        let i ←
          Nat.Partrec.Code.lup a.1.1.1 (a.1.2, (ofNat (ℕ × Code) a.1.1.1.length).2) (Nat.pair (unpair a.1.1.2).1 y)
        Nat.Partrec.Code.lup a.1.1.1 ((ofNat (ℕ × Code) a.1.1.1.length).1, a.2.2.1)
            (Nat.pair (unpair a.1.1.2).1 (Nat.pair y i)))
      p.1 p.2
state_after: case hpc
a : Primrec fun a => ofNat (ℕ × Code) a.length
k✝¹ : Primrec fun a => (ofNat (ℕ × Code) a.1.length).1
n✝¹ : Primrec Prod.snd
k✝ : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).1
n✝ : Primrec fun a => a.1.2
k' : Primrec Prod.snd
c : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).2
L✝ : Primrec fun a => a.1.1.1
k : Primrec fun a => (ofNat (ℕ × Code) a.1.1.1.length).1
n : Primrec fun a => a.1.1.2
cf : Primrec fun a => a.2.1
cg : Primrec fun a => a.2.2.1
z✝ : Primrec fun a => (unpair a.1.1.2).1
L : Primrec fun a => a.1.1.1.1
z : Primrec fun a => (unpair a.1.1.1.2).1
⊢ Primrec fun p =>
    (fun a y => do
        let i ←
          Nat.Partrec.Code.lup a.1.1.1 (a.1.2, (ofNat (ℕ × Code) a.1.1.1.length).2) (Nat.pair (unpair a.1.1.2).1 y)
        Nat.Partrec.Code.lup a.1.1.1 ((ofNat (ℕ × Code) a.1.1.1.length).1, a.2.2.1)
            (Nat.pair (unpair a.1.1.2).1 (Nat.pair y i)))
      p.1 p.2

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

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) a.length
k✝¹ : Primrec fun a => (ofNat (ℕ × Code) a.1.length).1
n✝¹ : Primrec Prod.snd
k✝ : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).1
n✝ : Primrec fun a => a.1.2
k' : Primrec Prod.snd
c : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).2
L✝ : Primrec fun a => a.1.1.1
k : Primrec fun a => (ofNat (ℕ × Code) a.1.1.1.length).1
n : Primrec fun a => a.1.1.2
cf : Primrec fun a => a.2.1
cg : Primrec fun a => a.2.2.1
z✝ : Primrec fun a => (unpair a.1.1.2).1
L : Primrec fun a => a.1.1.1.1
z : Primrec fun a => (unpair a.1.1.1.2).1
y : Primrec Prod.snd
⊢ Primrec fun p =>
    (fun a y => do
        let i ←
          Nat.Partrec.Code.lup a.1.1.1 (a.1.2, (ofNat (ℕ × Code) a.1.1.1.length).2) (Nat.pair (unpair a.1.1.2).1 y)
        Nat.Partrec.Code.lup a.1.1.1 ((ofNat (ℕ × Code) a.1.1.1.length).1, a.2.2.1)
            (Nat.pair (unpair a.1.1.2).1 (Nat.pair y i)))
      p.1 p.2
state_after: case hpc
a : Primrec fun a => ofNat (ℕ × Code) a.length
k✝¹ : Primrec fun a => (ofNat (ℕ × Code) a.1.length).1
n✝¹ : Primrec Prod.snd
k✝ : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).1
n✝ : Primrec fun a => a.1.2
k' : Primrec Prod.snd
c : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).2
L✝ : Primrec fun a => a.1.1.1
k : Primrec fun a => (ofNat (ℕ × Code) a.1.1.1.length).1
n : Primrec fun a => a.1.1.2
cf : Primrec fun a => a.2.1
cg : Primrec fun a => a.2.2.1
z✝ : Primrec fun a => (unpair a.1.1.2).1
L : Primrec fun a => a.1.1.1.1
z : Primrec fun a => (unpair a.1.1.1.2).1
y : Primrec Prod.snd
h₁ :
  Primrec fun a =>
    Nat.Partrec.Code.lup
      (a.1.1.1.1, (a.1.1.2, (ofNat (ℕ × Code) a.1.1.1.1.length).2), Nat.pair (unpair a.1.1.1.2).1 a.2).1
      (a.1.1.1.1, (a.1.1.2, (ofNat (ℕ × Code) a.1.1.1.1.length).2), Nat.pair (unpair a.1.1.1.2).1 a.2).2.1
      (a.1.1.1.1, (a.1.1.2, (ofNat (ℕ × Code) a.1.1.1.1.length).2), Nat.pair (unpair a.1.1.1.2).1 a.2).2.2
⊢ Primrec fun p =>
    (fun a y => do
        let i ←
          Nat.Partrec.Code.lup a.1.1.1 (a.1.2, (ofNat (ℕ × Code) a.1.1.1.length).2) (Nat.pair (unpair a.1.1.2).1 y)
        Nat.Partrec.Code.lup a.1.1.1 ((ofNat (ℕ × Code) a.1.1.1.length).1, a.2.2.1)
            (Nat.pair (unpair a.1.1.2).1 (Nat.pair y i)))
      p.1 p.2

tactic: refine Primrec.option_bind h₁ (?_ : Primrec _)
state_before: case hpc
a : Primrec fun a => ofNat (ℕ × Code) a.length
k✝¹ : Primrec fun a => (ofNat (ℕ × Code) a.1.length).1
n✝¹ : Primrec Prod.snd
k✝ : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).1
n✝ : Primrec fun a => a.1.2
k' : Primrec Prod.snd
c : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).2
L✝ : Primrec fun a => a.1.1.1
k : Primrec fun a => (ofNat (ℕ × Code) a.1.1.1.length).1
n : Primrec fun a => a.1.1.2
cf : Primrec fun a => a.2.1
cg : Primrec fun a => a.2.2.1
z✝ : Primrec fun a => (unpair a.1.1.2).1
L : Primrec fun a => a.1.1.1.1
z : Primrec fun a => (unpair a.1.1.1.2).1
y : Primrec Prod.snd
h₁ :
  Primrec fun a =>
    Nat.Partrec.Code.lup
      (a.1.1.1.1, (a.1.1.2, (ofNat (ℕ × Code) a.1.1.1.1.length).2), Nat.pair (unpair a.1.1.1.2).1 a.2).1
      (a.1.1.1.1, (a.1.1.2, (ofNat (ℕ × Code) a.1.1.1.1.length).2), Nat.pair (unpair a.1.1.1.2).1 a.2).2.1
      (a.1.1.1.1, (a.1.1.2, (ofNat (ℕ × Code) a.1.1.1.1.length).2), Nat.pair (unpair a.1.1.1.2).1 a.2).2.2
⊢ Primrec fun p =>
    (fun a y => do
        let i ←
          Nat.Partrec.Code.lup a.1.1.1 (a.1.2, (ofNat (ℕ × Code) a.1.1.1.length).2) (Nat.pair (unpair a.1.1.2).1 y)
        Nat.Partrec.Code.lup a.1.1.1 ((ofNat (ℕ × Code) a.1.1.1.length).1, a.2.2.1)
            (Nat.pair (unpair a.1.1.2).1 (Nat.pair y i)))
      p.1 p.2
state_after: case hpc
a : Primrec fun a => ofNat (ℕ × Code) a.length
k✝¹ : Primrec fun a => (ofNat (ℕ × Code) a.1.length).1
n✝¹ : Primrec Prod.snd
k✝ : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).1
n✝ : Primrec fun a => a.1.2
k' : Primrec Prod.snd
c : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).2
L✝ : Primrec fun a => a.1.1.1
k : Primrec fun a => (ofNat (ℕ × Code) a.1.1.1.length).1
n : Primrec fun a => a.1.1.2
cf : Primrec fun a => a.2.1
cg : Primrec fun a => a.2.2.1
z✝ : Primrec fun a => (unpair a.1.1.2).1
L : Primrec fun a => a.1.1.1.1
z : Primrec fun a => (unpair a.1.1.1.2).1
y : Primrec Prod.snd
h₁ :
  Primrec fun a =>
    Nat.Partrec.Code.lup
      (a.1.1.1.1, (a.1.1.2, (ofNat (ℕ × Code) a.1.1.1.1.length).2), Nat.pair (unpair a.1.1.1.2).1 a.2).1
      (a.1.1.1.1, (a.1.1.2, (ofNat (ℕ × Code) a.1.1.1.1.length).2), Nat.pair (unpair a.1.1.1.2).1 a.2).2.1
      (a.1.1.1.1, (a.1.1.2, (ofNat (ℕ × Code) a.1.1.1.1.length).2), Nat.pair (unpair a.1.1.1.2).1 a.2).2.2
⊢ Primrec fun p =>
    (fun p i =>
        Nat.Partrec.Code.lup p.1.1.1.1 ((ofNat (ℕ × Code) p.1.1.1.1.length).1, p.1.2.2.1)
          (Nat.pair (unpair p.1.1.1.2).1 (Nat.pair p.2 i)))
      p.1 p.2

tactic: have z := z.comp (Primrec.fst (β := ℕ))
state_before: case hpc
a : Primrec fun a => ofNat (ℕ × Code) a.length
k✝¹ : Primrec fun a => (ofNat (ℕ × Code) a.1.length).1
n✝¹ : Primrec Prod.snd
k✝ : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).1
n✝ : Primrec fun a => a.1.2
k' : Primrec Prod.snd
c : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).2
L✝ : Primrec fun a => a.1.1.1
k : Primrec fun a => (ofNat (ℕ × Code) a.1.1.1.length).1
n : Primrec fun a => a.1.1.2
cf : Primrec fun a => a.2.1
cg : Primrec fun a => a.2.2.1
z✝ : Primrec fun a => (unpair a.1.1.2).1
L : Primrec fun a => a.1.1.1.1
z : Primrec fun a => (unpair a.1.1.1.2).1
y : Primrec Prod.snd
h₁ :
  Primrec fun a =>
    Nat.Partrec.Code.lup
      (a.1.1.1.1, (a.1.1.2, (ofNat (ℕ × Code) a.1.1.1.1.length).2), Nat.pair (unpair a.1.1.1.2).1 a.2).1
      (a.1.1.1.1, (a.1.1.2, (ofNat (ℕ × Code) a.1.1.1.1.length).2), Nat.pair (unpair a.1.1.1.2).1 a.2).2.1
      (a.1.1.1.1, (a.1.1.2, (ofNat (ℕ × Code) a.1.1.1.1.length).2), Nat.pair (unpair a.1.1.1.2).1 a.2).2.2
⊢ Primrec fun p =>
    (fun p i =>
        Nat.Partrec.Code.lup p.1.1.1.1 ((ofNat (ℕ × Code) p.1.1.1.1.length).1, p.1.2.2.1)
          (Nat.pair (unpair p.1.1.1.2).1 (Nat.pair p.2 i)))
      p.1 p.2
state_after: case hpc
a : Primrec fun a => ofNat (ℕ × Code) a.length
k✝¹ : Primrec fun a => (ofNat (ℕ × Code) a.1.length).1
n✝¹ : Primrec Prod.snd
k✝ : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).1
n✝ : Primrec fun a => a.1.2
k' : Primrec Prod.snd
c : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).2
L✝ : Primrec fun a => a.1.1.1
k : Primrec fun a => (ofNat (ℕ × Code) a.1.1.1.length).1
n : Primrec fun a => a.1.1.2
cf : Primrec fun a => a.2.1
cg : Primrec fun a => a.2.2.1
z✝¹ : Primrec fun a => (unpair a.1.1.2).1
L : Primrec fun a => a.1.1.1.1
z✝ : Primrec fun a => (unpair a.1.1.1.2).1
y : Primrec Prod.snd
h₁ :
  Primrec fun a =>
    Nat.Partrec.Code.lup
      (a.1.1.1.1, (a.1.1.2, (ofNat (ℕ × Code) a.1.1.1.1.length).2), Nat.pair (unpair a.1.1.1.2).1 a.2).1
      (a.1.1.1.1, (a.1.1.2, (ofNat (ℕ × Code) a.1.1.1.1.length).2), Nat.pair (unpair a.1.1.1.2).1 a.2).2.1
      (a.1.1.1.1, (a.1.1.2, (ofNat (ℕ × Code) a.1.1.1.1.length).2), Nat.pair (unpair a.1.1.1.2).1 a.2).2.2
z : Primrec fun a => (unpair a.1.1.1.1.2).1
⊢ Primrec fun p =>
    (fun p i =>
        Nat.Partrec.Code.lup p.1.1.1.1 ((ofNat (ℕ × Code) p.1.1.1.1.length).1, p.1.2.2.1)
          (Nat.pair (unpair p.1.1.1.2).1 (Nat.pair p.2 i)))
      p.1 p.2

tactic: have y := y.comp (Primrec.fst (β := ℕ))
state_before: case hpc
a : Primrec fun a => ofNat (ℕ × Code) a.length
k✝¹ : Primrec fun a => (ofNat (ℕ × Code) a.1.length).1
n✝¹ : Primrec Prod.snd
k✝ : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).1
n✝ : Primrec fun a => a.1.2
k' : Primrec Prod.snd
c : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).2
L✝ : Primrec fun a => a.1.1.1
k : Primrec fun a => (ofNat (ℕ × Code) a.1.1.1.length).1
n : Primrec fun a => a.1.1.2
cf : Primrec fun a => a.2.1
cg : Primrec fun a => a.2.2.1
z✝¹ : Primrec fun a => (unpair a.1.1.2).1
L : Primrec fun a => a.1.1.1.1
z✝ : Primrec fun a => (unpair a.1.1.1.2).1
y : Primrec Prod.snd
h₁ :
  Primrec fun a =>
    Nat.Partrec.Code.lup
      (a.1.1.1.1, (a.1.1.2, (ofNat (ℕ × Code) a.1.1.1.1.length).2), Nat.pair (unpair a.1.1.1.2).1 a.2).1
      (a.1.1.1.1, (a.1.1.2, (ofNat (ℕ × Code) a.1.1.1.1.length).2), Nat.pair (unpair a.1.1.1.2).1 a.2).2.1
      (a.1.1.1.1, (a.1.1.2, (ofNat (ℕ × Code) a.1.1.1.1.length).2), Nat.pair (unpair a.1.1.1.2).1 a.2).2.2
z : Primrec fun a => (unpair a.1.1.1.1.2).1
⊢ Primrec fun p =>
    (fun p i =>
        Nat.Partrec.Code.lup p.1.1.1.1 ((ofNat (ℕ × Code) p.1.1.1.1.length).1, p.1.2.2.1)
          (Nat.pair (unpair p.1.1.1.2).1 (Nat.pair p.2 i)))
      p.1 p.2
state_after: case hpc
a : Primrec fun a => ofNat (ℕ × Code) a.length
k✝¹ : Primrec fun a => (ofNat (ℕ × Code) a.1.length).1
n✝¹ : Primrec Prod.snd
k✝ : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).1
n✝ : Primrec fun a => a.1.2
k' : Primrec Prod.snd
c : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).2
L✝ : Primrec fun a => a.1.1.1
k : Primrec fun a => (ofNat (ℕ × Code) a.1.1.1.length).1
n : Primrec fun a => a.1.1.2
cf : Primrec fun a => a.2.1
cg : Primrec fun a => a.2.2.1
z✝¹ : Primrec fun a => (unpair a.1.1.2).1
L : Primrec fun a => a.1.1.1.1
z✝ : Primrec fun a => (unpair a.1.1.1.2).1
y✝ : Primrec Prod.snd
h₁ :
  Primrec fun a =>
    Nat.Partrec.Code.lup
      (a.1.1.1.1, (a.1.1.2, (ofNat (ℕ × Code) a.1.1.1.1.length).2), Nat.pair (unpair a.1.1.1.2).1 a.2).1
      (a.1.1.1.1, (a.1.1.2, (ofNat (ℕ × Code) a.1.1.1.1.length).2), Nat.pair (unpair a.1.1.1.2).1 a.2).2.1
      (a.1.1.1.1, (a.1.1.2, (ofNat (ℕ × Code) a.1.1.1.1.length).2), Nat.pair (unpair a.1.1.1.2).1 a.2).2.2
z : Primrec fun a => (unpair a.1.1.1.1.2).1
y : Primrec fun a => a.1.2
⊢ Primrec fun p =>
    (fun p i =>
        Nat.Partrec.Code.lup p.1.1.1.1 ((ofNat (ℕ × Code) p.1.1.1.1.length).1, p.1.2.2.1)
          (Nat.pair (unpair p.1.1.1.2).1 (Nat.pair p.2 i)))
      p.1 p.2

tactic: have i := Primrec.snd
  (α := (((List (List (Option ℕ)) × ℕ) × ℕ) × Code × Code × Option ℕ × Option ℕ) × ℕ)
  (β := ℕ)
state_before: case hpc
a : Primrec fun a => ofNat (ℕ × Code) a.length
k✝¹ : Primrec fun a => (ofNat (ℕ × Code) a.1.length).1
n✝¹ : Primrec Prod.snd
k✝ : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).1
n✝ : Primrec fun a => a.1.2
k' : Primrec Prod.snd
c : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).2
L✝ : Primrec fun a => a.1.1.1
k : Primrec fun a => (ofNat (ℕ × Code) a.1.1.1.length).1
n : Primrec fun a => a.1.1.2
cf : Primrec fun a => a.2.1
cg : Primrec fun a => a.2.2.1
z✝¹ : Primrec fun a => (unpair a.1.1.2).1
L : Primrec fun a => a.1.1.1.1
z✝ : Primrec fun a => (unpair a.1.1.1.2).1
y✝ : Primrec Prod.snd
h₁ :
  Primrec fun a =>
    Nat.Partrec.Code.lup
      (a.1.1.1.1, (a.1.1.2, (ofNat (ℕ × Code) a.1.1.1.1.length).2), Nat.pair (unpair a.1.1.1.2).1 a.2).1
      (a.1.1.1.1, (a.1.1.2, (ofNat (ℕ × Code) a.1.1.1.1.length).2), Nat.pair (unpair a.1.1.1.2).1 a.2).2.1
      (a.1.1.1.1, (a.1.1.2, (ofNat (ℕ × Code) a.1.1.1.1.length).2), Nat.pair (unpair a.1.1.1.2).1 a.2).2.2
z : Primrec fun a => (unpair a.1.1.1.1.2).1
y : Primrec fun a => a.1.2
⊢ Primrec fun p =>
    (fun p i =>
        Nat.Partrec.Code.lup p.1.1.1.1 ((ofNat (ℕ × Code) p.1.1.1.1.length).1, p.1.2.2.1)
          (Nat.pair (unpair p.1.1.1.2).1 (Nat.pair p.2 i)))
      p.1 p.2
state_after: case hpc
a : Primrec fun a => ofNat (ℕ × Code) a.length
k✝¹ : Primrec fun a => (ofNat (ℕ × Code) a.1.length).1
n✝¹ : Primrec Prod.snd
k✝ : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).1
n✝ : Primrec fun a => a.1.2
k' : Primrec Prod.snd
c : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).2
L✝ : Primrec fun a => a.1.1.1
k : Primrec fun a => (ofNat (ℕ × Code) a.1.1.1.length).1
n : Primrec fun a => a.1.1.2
cf : Primrec fun a => a.2.1
cg : Primrec fun a => a.2.2.1
z✝¹ : Primrec fun a => (unpair a.1.1.2).1
L : Primrec fun a => a.1.1.1.1
z✝ : Primrec fun a => (unpair a.1.1.1.2).1
y✝ : Primrec Prod.snd
h₁ :
  Primrec fun a =>
    Nat.Partrec.Code.lup
      (a.1.1.1.1, (a.1.1.2, (ofNat (ℕ × Code) a.1.1.1.1.length).2), Nat.pair (unpair a.1.1.1.2).1 a.2).1
      (a.1.1.1.1, (a.1.1.2, (ofNat (ℕ × Code) a.1.1.1.1.length).2), Nat.pair (unpair a.1.1.1.2).1 a.2).2.1
      (a.1.1.1.1, (a.1.1.2, (ofNat (ℕ × Code) a.1.1.1.1.length).2), Nat.pair (unpair a.1.1.1.2).1 a.2).2.2
z : Primrec fun a => (unpair a.1.1.1.1.2).1
y : Primrec fun a => a.1.2
i : Primrec Prod.snd
⊢ Primrec fun p =>
    (fun p i =>
        Nat.Partrec.Code.lup p.1.1.1.1 ((ofNat (ℕ × Code) p.1.1.1.1.length).1, p.1.2.2.1)
          (Nat.pair (unpair p.1.1.1.2).1 (Nat.pair p.2 i)))
      p.1 p.2

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) a.length
k✝¹ : Primrec fun a => (ofNat (ℕ × Code) a.1.length).1
n✝¹ : Primrec Prod.snd
k✝ : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).1
n✝ : Primrec fun a => a.1.2
k' : Primrec Prod.snd
c : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).2
L✝ : Primrec fun a => a.1.1.1
k : Primrec fun a => (ofNat (ℕ × Code) a.1.1.1.length).1
n : Primrec fun a => a.1.1.2
cf : Primrec fun a => a.2.1
cg : Primrec fun a => a.2.2.1
z✝¹ : Primrec fun a => (unpair a.1.1.2).1
L : Primrec fun a => a.1.1.1.1
z✝ : Primrec fun a => (unpair a.1.1.1.2).1
y✝ : Primrec Prod.snd
h₁ :
  Primrec fun a =>
    Nat.Partrec.Code.lup
      (a.1.1.1.1, (a.1.1.2, (ofNat (ℕ × Code) a.1.1.1.1.length).2), Nat.pair (unpair a.1.1.1.2).1 a.2).1
      (a.1.1.1.1, (a.1.1.2, (ofNat (ℕ × Code) a.1.1.1.1.length).2), Nat.pair (unpair a.1.1.1.2).1 a.2).2.1
      (a.1.1.1.1, (a.1.1.2, (ofNat (ℕ × Code) a.1.1.1.1.length).2), Nat.pair (unpair a.1.1.1.2).1 a.2).2.2
z : Primrec fun a => (unpair a.1.1.1.1.2).1
y : Primrec fun a => a.1.2
i : Primrec Prod.snd
⊢ Primrec fun p =>
    (fun p i =>
        Nat.Partrec.Code.lup p.1.1.1.1 ((ofNat (ℕ × Code) p.1.1.1.1.length).1, p.1.2.2.1)
          (Nat.pair (unpair p.1.1.1.2).1 (Nat.pair p.2 i)))
      p.1 p.2
state_after: case hpc
a : Primrec fun a => ofNat (ℕ × Code) a.length
k✝¹ : Primrec fun a => (ofNat (ℕ × Code) a.1.length).1
n✝¹ : Primrec Prod.snd
k✝ : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).1
n✝ : Primrec fun a => a.1.2
k' : Primrec Prod.snd
c : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).2
L✝ : Primrec fun a => a.1.1.1
k : Primrec fun a => (ofNat (ℕ × Code) a.1.1.1.length).1
n : Primrec fun a => a.1.1.2
cf : Primrec fun a => a.2.1
cg : Primrec fun a => a.2.2.1
z✝¹ : Primrec fun a => (unpair a.1.1.2).1
L : Primrec fun a => a.1.1.1.1
z✝ : Primrec fun a => (unpair a.1.1.1.2).1
y✝ : Primrec Prod.snd
h₁ :
  Primrec fun a =>
    Nat.Partrec.Code.lup
      (a.1.1.1.1, (a.1.1.2, (ofNat (ℕ × Code) a.1.1.1.1.length).2), Nat.pair (unpair a.1.1.1.2).1 a.2).1
      (a.1.1.1.1, (a.1.1.2, (ofNat (ℕ × Code) a.1.1.1.1.length).2), Nat.pair (unpair a.1.1.1.2).1 a.2).2.1
      (a.1.1.1.1, (a.1.1.2, (ofNat (ℕ × Code) a.1.1.1.1.length).2), Nat.pair (unpair a.1.1.1.2).1 a.2).2.2
z : Primrec fun a => (unpair a.1.1.1.1.2).1
y : Primrec fun a => a.1.2
i : Primrec Prod.snd
h₂ :
  Primrec fun a =>
    Nat.Partrec.Code.lup
      (a.1.1.1.1.1, ((ofNat (ℕ × Code) a.1.1.1.1.1.length).1, a.1.1.2.2.1),
          Nat.pair (unpair a.1.1.1.1.2).1 (Nat.pair a.1.2 a.2)).1
      (a.1.1.1.1.1, ((ofNat (ℕ × Code) a.1.1.1.1.1.length).1, a.1.1.2.2.1),
            Nat.pair (unpair a.1.1.1.1.2).1 (Nat.pair a.1.2 a.2)).2.1
      (a.1.1.1.1.1, ((ofNat (ℕ × Code) a.1.1.1.1.1.length).1, a.1.1.2.2.1),
            Nat.pair (unpair a.1.1.1.1.2).1 (Nat.pair a.1.2 a.2)).2.2
⊢ Primrec fun p =>
    (fun p i =>
        Nat.Partrec.Code.lup p.1.1.1.1 ((ofNat (ℕ × Code) p.1.1.1.1.length).1, p.1.2.2.1)
          (Nat.pair (unpair p.1.1.1.2).1 (Nat.pair p.2 i)))
      p.1 p.2

tactic: exact h₂
state_before: case hpc
a : Primrec fun a => ofNat (ℕ × Code) a.length
k✝¹ : Primrec fun a => (ofNat (ℕ × Code) a.1.length).1
n✝¹ : Primrec Prod.snd
k✝ : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).1
n✝ : Primrec fun a => a.1.2
k' : Primrec Prod.snd
c : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).2
L✝ : Primrec fun a => a.1.1.1
k : Primrec fun a => (ofNat (ℕ × Code) a.1.1.1.length).1
n : Primrec fun a => a.1.1.2
cf : Primrec fun a => a.2.1
cg : Primrec fun a => a.2.2.1
z✝¹ : Primrec fun a => (unpair a.1.1.2).1
L : Primrec fun a => a.1.1.1.1
z✝ : Primrec fun a => (unpair a.1.1.1.2).1
y✝ : Primrec Prod.snd
h₁ :
  Primrec fun a =>
    Nat.Partrec.Code.lup
      (a.1.1.1.1, (a.1.1.2, (ofNat (ℕ × Code) a.1.1.1.1.length).2), Nat.pair (unpair a.1.1.1.2).1 a.2).1
      (a.1.1.1.1, (a.1.1.2, (ofNat (ℕ × Code) a.1.1.1.1.length).2), Nat.pair (unpair a.1.1.1.2).1 a.2).2.1
      (a.1.1.1.1, (a.1.1.2, (ofNat (ℕ × Code) a.1.1.1.1.length).2), Nat.pair (unpair a.1.1.1.2).1 a.2).2.2
z : Primrec fun a => (unpair a.1.1.1.1.2).1
y : Primrec fun a => a.1.2
i : Primrec Prod.snd
h₂ :
  Primrec fun a =>
    Nat.Partrec.Code.lup
      (a.1.1.1.1.1, ((ofNat (ℕ × Code) a.1.1.1.1.1.length).1, a.1.1.2.2.1),
          Nat.pair (unpair a.1.1.1.1.2).1 (Nat.pair a.1.2 a.2)).1
      (a.1.1.1.1.1, ((ofNat (ℕ × Code) a.1.1.1.1.1.length).1, a.1.1.2.2.1),
            Nat.pair (unpair a.1.1.1.1.2).1 (Nat.pair a.1.2 a.2)).2.1
      (a.1.1.1.1.1, ((ofNat (ℕ × Code) a.1.1.1.1.1.length).1, a.1.1.2.2.1),
            Nat.pair (unpair a.1.1.1.1.2).1 (Nat.pair a.1.2 a.2)).2.2
⊢ Primrec fun p =>
    (fun p i =>
        Nat.Partrec.Code.lup p.1.1.1.1 ((ofNat (ℕ × Code) p.1.1.1.1.length).1, p.1.2.2.1)
          (Nat.pair (unpair p.1.1.1.2).1 (Nat.pair p.2 i)))
      p.1 p.2
state_after: no goals

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) a.length
k✝ : Primrec fun a => (ofNat (ℕ × Code) a.1.length).1
n✝ : Primrec Prod.snd
k : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).1
n : Primrec fun a => a.1.2
k' : Primrec Prod.snd
c : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).2
⊢ Primrec fun a =>
    let z := (unpair a.1.1.2).1;
    let m := (unpair a.1.1.2).2;
    do
    let x ← Nat.Partrec.Code.lup a.1.1.1 ((ofNat (ℕ × Code) a.1.1.1.length).1, a.2.1) (Nat.pair z m)
    Nat.casesOn x (some m) fun x =>
        Nat.Partrec.Code.lup a.1.1.1 (a.1.2, (ofNat (ℕ × Code) a.1.1.1.length).2) (Nat.pair z (m + 1))
state_after: case hrf
a : Primrec fun a => ofNat (ℕ × Code) a.length
k✝ : Primrec fun a => (ofNat (ℕ × Code) a.1.length).1
n✝ : Primrec Prod.snd
k : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).1
n : Primrec fun a => a.1.2
k' : Primrec Prod.snd
c : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).2
L : Primrec fun a => a.1.1.1
⊢ Primrec fun a =>
    let z := (unpair a.1.1.2).1;
    let m := (unpair a.1.1.2).2;
    do
    let x ← Nat.Partrec.Code.lup a.1.1.1 ((ofNat (ℕ × Code) a.1.1.1.length).1, a.2.1) (Nat.pair z m)
    Nat.casesOn x (some m) fun x =>
        Nat.Partrec.Code.lup a.1.1.1 (a.1.2, (ofNat (ℕ × Code) a.1.1.1.length).2) (Nat.pair z (m + 1))

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

tactic: have n := n.comp (Primrec.fst (β := Code × Option ℕ))
state_before: case hrf
a : Primrec fun a => ofNat (ℕ × Code) a.length
k✝¹ : Primrec fun a => (ofNat (ℕ × Code) a.1.length).1
n✝ : Primrec Prod.snd
k✝ : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).1
n : Primrec fun a => a.1.2
k' : Primrec Prod.snd
c : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).2
L : Primrec fun a => a.1.1.1
k : Primrec fun a => (ofNat (ℕ × Code) a.1.1.1.length).1
⊢ Primrec fun a =>
    let z := (unpair a.1.1.2).1;
    let m := (unpair a.1.1.2).2;
    do
    let x ← Nat.Partrec.Code.lup a.1.1.1 ((ofNat (ℕ × Code) a.1.1.1.length).1, a.2.1) (Nat.pair z m)
    Nat.casesOn x (some m) fun x =>
        Nat.Partrec.Code.lup a.1.1.1 (a.1.2, (ofNat (ℕ × Code) a.1.1.1.length).2) (Nat.pair z (m + 1))
state_after: case hrf
a : Primrec fun a => ofNat (ℕ × Code) a.length
k✝¹ : Primrec fun a => (ofNat (ℕ × Code) a.1.length).1
n✝¹ : Primrec Prod.snd
k✝ : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).1
n✝ : Primrec fun a => a.1.2
k' : Primrec Prod.snd
c : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).2
L : Primrec fun a => a.1.1.1
k : Primrec fun a => (ofNat (ℕ × Code) a.1.1.1.length).1
n : Primrec fun a => a.1.1.2
⊢ Primrec fun a =>
    let z := (unpair a.1.1.2).1;
    let m := (unpair a.1.1.2).2;
    do
    let x ← Nat.Partrec.Code.lup a.1.1.1 ((ofNat (ℕ × Code) a.1.1.1.length).1, a.2.1) (Nat.pair z m)
    Nat.casesOn x (some m) fun x =>
        Nat.Partrec.Code.lup a.1.1.1 (a.1.2, (ofNat (ℕ × Code) a.1.1.1.length).2) (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) a.length
k✝¹ : Primrec fun a => (ofNat (ℕ × Code) a.1.length).1
n✝¹ : Primrec Prod.snd
k✝ : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).1
n✝ : Primrec fun a => a.1.2
k' : Primrec Prod.snd
c : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).2
L : Primrec fun a => a.1.1.1
k : Primrec fun a => (ofNat (ℕ × Code) a.1.1.1.length).1
n : Primrec fun a => a.1.1.2
⊢ Primrec fun a =>
    let z := (unpair a.1.1.2).1;
    let m := (unpair a.1.1.2).2;
    do
    let x ← Nat.Partrec.Code.lup a.1.1.1 ((ofNat (ℕ × Code) a.1.1.1.length).1, a.2.1) (Nat.pair z m)
    Nat.casesOn x (some m) fun x =>
        Nat.Partrec.Code.lup a.1.1.1 (a.1.2, (ofNat (ℕ × Code) a.1.1.1.length).2) (Nat.pair z (m + 1))
state_after: case hrf
a : Primrec fun a => ofNat (ℕ × Code) a.length
k✝¹ : Primrec fun a => (ofNat (ℕ × Code) a.1.length).1
n✝¹ : Primrec Prod.snd
k✝ : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).1
n✝ : Primrec fun a => a.1.2
k' : Primrec Prod.snd
c : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).2
L : Primrec fun a => a.1.1.1
k : Primrec fun a => (ofNat (ℕ × Code) a.1.1.1.length).1
n : Primrec fun a => a.1.1.2
cf : Primrec fun a => a.2.1
⊢ Primrec fun a =>
    let z := (unpair a.1.1.2).1;
    let m := (unpair a.1.1.2).2;
    do
    let x ← Nat.Partrec.Code.lup a.1.1.1 ((ofNat (ℕ × Code) a.1.1.1.length).1, a.2.1) (Nat.pair z m)
    Nat.casesOn x (some m) fun x =>
        Nat.Partrec.Code.lup a.1.1.1 (a.1.2, (ofNat (ℕ × Code) a.1.1.1.length).2) (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) a.length
k✝¹ : Primrec fun a => (ofNat (ℕ × Code) a.1.length).1
n✝¹ : Primrec Prod.snd
k✝ : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).1
n✝ : Primrec fun a => a.1.2
k' : Primrec Prod.snd
c : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).2
L : Primrec fun a => a.1.1.1
k : Primrec fun a => (ofNat (ℕ × Code) a.1.1.1.length).1
n : Primrec fun a => a.1.1.2
cf : Primrec fun a => a.2.1
⊢ Primrec fun a =>
    let z := (unpair a.1.1.2).1;
    let m := (unpair a.1.1.2).2;
    do
    let x ← Nat.Partrec.Code.lup a.1.1.1 ((ofNat (ℕ × Code) a.1.1.1.length).1, a.2.1) (Nat.pair z m)
    Nat.casesOn x (some m) fun x =>
        Nat.Partrec.Code.lup a.1.1.1 (a.1.2, (ofNat (ℕ × Code) a.1.1.1.length).2) (Nat.pair z (m + 1))
state_after: case hrf
a : Primrec fun a => ofNat (ℕ × Code) a.length
k✝¹ : Primrec fun a => (ofNat (ℕ × Code) a.1.length).1
n✝¹ : Primrec Prod.snd
k✝ : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).1
n✝ : Primrec fun a => a.1.2
k' : Primrec Prod.snd
c : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).2
L : Primrec fun a => a.1.1.1
k : Primrec fun a => (ofNat (ℕ × Code) a.1.1.1.length).1
n : Primrec fun a => a.1.1.2
cf : Primrec fun a => a.2.1
z : Primrec fun a => (unpair a.1.1.2).1
⊢ Primrec fun a =>
    let z := (unpair a.1.1.2).1;
    let m := (unpair a.1.1.2).2;
    do
    let x ← Nat.Partrec.Code.lup a.1.1.1 ((ofNat (ℕ × Code) a.1.1.1.length).1, a.2.1) (Nat.pair z m)
    Nat.casesOn x (some m) fun x =>
        Nat.Partrec.Code.lup a.1.1.1 (a.1.2, (ofNat (ℕ × Code) a.1.1.1.length).2) (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) a.length
k✝¹ : Primrec fun a => (ofNat (ℕ × Code) a.1.length).1
n✝¹ : Primrec Prod.snd
k✝ : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).1
n✝ : Primrec fun a => a.1.2
k' : Primrec Prod.snd
c : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).2
L : Primrec fun a => a.1.1.1
k : Primrec fun a => (ofNat (ℕ × Code) a.1.1.1.length).1
n : Primrec fun a => a.1.1.2
cf : Primrec fun a => a.2.1
z : Primrec fun a => (unpair a.1.1.2).1
⊢ Primrec fun a =>
    let z := (unpair a.1.1.2).1;
    let m := (unpair a.1.1.2).2;
    do
    let x ← Nat.Partrec.Code.lup a.1.1.1 ((ofNat (ℕ × Code) a.1.1.1.length).1, a.2.1) (Nat.pair z m)
    Nat.casesOn x (some m) fun x =>
        Nat.Partrec.Code.lup a.1.1.1 (a.1.2, (ofNat (ℕ × Code) a.1.1.1.length).2) (Nat.pair z (m + 1))
state_after: case hrf
a : Primrec fun a => ofNat (ℕ × Code) a.length
k✝¹ : Primrec fun a => (ofNat (ℕ × Code) a.1.length).1
n✝¹ : Primrec Prod.snd
k✝ : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).1
n✝ : Primrec fun a => a.1.2
k' : Primrec Prod.snd
c : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).2
L : Primrec fun a => a.1.1.1
k : Primrec fun a => (ofNat (ℕ × Code) a.1.1.1.length).1
n : Primrec fun a => a.1.1.2
cf : Primrec fun a => a.2.1
z : Primrec fun a => (unpair a.1.1.2).1
m : Primrec fun a => (unpair a.1.1.2).2
⊢ Primrec fun a =>
    let z := (unpair a.1.1.2).1;
    let m := (unpair a.1.1.2).2;
    do
    let x ← Nat.Partrec.Code.lup a.1.1.1 ((ofNat (ℕ × Code) a.1.1.1.length).1, a.2.1) (Nat.pair z m)
    Nat.casesOn x (some m) fun x =>
        Nat.Partrec.Code.lup a.1.1.1 (a.1.2, (ofNat (ℕ × Code) a.1.1.1.length).2) (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) a.length
k✝¹ : Primrec fun a => (ofNat (ℕ × Code) a.1.length).1
n✝¹ : Primrec Prod.snd
k✝ : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).1
n✝ : Primrec fun a => a.1.2
k' : Primrec Prod.snd
c : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).2
L : Primrec fun a => a.1.1.1
k : Primrec fun a => (ofNat (ℕ × Code) a.1.1.1.length).1
n : Primrec fun a => a.1.1.2
cf : Primrec fun a => a.2.1
z : Primrec fun a => (unpair a.1.1.2).1
m : Primrec fun a => (unpair a.1.1.2).2
⊢ Primrec fun a =>
    let z := (unpair a.1.1.2).1;
    let m := (unpair a.1.1.2).2;
    do
    let x ← Nat.Partrec.Code.lup a.1.1.1 ((ofNat (ℕ × Code) a.1.1.1.length).1, a.2.1) (Nat.pair z m)
    Nat.casesOn x (some m) fun x =>
        Nat.Partrec.Code.lup a.1.1.1 (a.1.2, (ofNat (ℕ × Code) a.1.1.1.length).2) (Nat.pair z (m + 1))
state_after: case hrf
a : Primrec fun a => ofNat (ℕ × Code) a.length
k✝¹ : Primrec fun a => (ofNat (ℕ × Code) a.1.length).1
n✝¹ : Primrec Prod.snd
k✝ : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).1
n✝ : Primrec fun a => a.1.2
k' : Primrec Prod.snd
c : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).2
L : Primrec fun a => a.1.1.1
k : Primrec fun a => (ofNat (ℕ × Code) a.1.1.1.length).1
n : Primrec fun a => a.1.1.2
cf : Primrec fun a => a.2.1
z : Primrec fun a => (unpair a.1.1.2).1
m : Primrec fun a => (unpair a.1.1.2).2
h₁ :
  Primrec fun a =>
    Nat.Partrec.Code.lup
      (a.1.1.1, ((ofNat (ℕ × Code) a.1.1.1.length).1, a.2.1), Nat.pair (unpair a.1.1.2).1 (unpair a.1.1.2).2).1
      (a.1.1.1, ((ofNat (ℕ × Code) a.1.1.1.length).1, a.2.1), Nat.pair (unpair a.1.1.2).1 (unpair a.1.1.2).2).2.1
      (a.1.1.1, ((ofNat (ℕ × Code) a.1.1.1.length).1, a.2.1), Nat.pair (unpair a.1.1.2).1 (unpair a.1.1.2).2).2.2
⊢ Primrec fun a =>
    let z := (unpair a.1.1.2).1;
    let m := (unpair a.1.1.2).2;
    do
    let x ← Nat.Partrec.Code.lup a.1.1.1 ((ofNat (ℕ × Code) a.1.1.1.length).1, a.2.1) (Nat.pair z m)
    Nat.casesOn x (some m) fun x =>
        Nat.Partrec.Code.lup a.1.1.1 (a.1.2, (ofNat (ℕ × Code) a.1.1.1.length).2) (Nat.pair z (m + 1))

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

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

tactic: refine Primrec.nat_casesOn Primrec.snd (Primrec.option_some.comp m) ?_
state_before: case hrf
a : Primrec fun a => ofNat (ℕ × Code) a.length
k✝¹ : Primrec fun a => (ofNat (ℕ × Code) a.1.length).1
n✝¹ : Primrec Prod.snd
k✝ : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).1
n✝ : Primrec fun a => a.1.2
k' : Primrec Prod.snd
c : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).2
L : Primrec fun a => a.1.1.1
k : Primrec fun a => (ofNat (ℕ × Code) a.1.1.1.length).1
n : Primrec fun a => a.1.1.2
cf : Primrec fun a => a.2.1
z : Primrec fun a => (unpair a.1.1.2).1
m✝ : Primrec fun a => (unpair a.1.1.2).2
h₁ :
  Primrec fun a =>
    Nat.Partrec.Code.lup
      (a.1.1.1, ((ofNat (ℕ × Code) a.1.1.1.length).1, a.2.1), Nat.pair (unpair a.1.1.2).1 (unpair a.1.1.2).2).1
      (a.1.1.1, ((ofNat (ℕ × Code) a.1.1.1.length).1, a.2.1), Nat.pair (unpair a.1.1.2).1 (unpair a.1.1.2).2).2.1
      (a.1.1.1, ((ofNat (ℕ × Code) a.1.1.1.length).1, a.2.1), Nat.pair (unpair a.1.1.2).1 (unpair a.1.1.2).2).2.2
m : Primrec fun a => (unpair a.1.1.1.2).2
⊢ Primrec fun p =>
    (fun a x =>
        Nat.casesOn x (some (unpair a.1.1.2).2) fun x =>
          Nat.Partrec.Code.lup a.1.1.1 (a.1.2, (ofNat (ℕ × Code) a.1.1.1.length).2)
            (Nat.pair (unpair a.1.1.2).1 ((unpair a.1.1.2).2 + 1)))
      p.1 p.2
state_after: case hrf
a : Primrec fun a => ofNat (ℕ × Code) a.length
k✝¹ : Primrec fun a => (ofNat (ℕ × Code) a.1.length).1
n✝¹ : Primrec Prod.snd
k✝ : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).1
n✝ : Primrec fun a => a.1.2
k' : Primrec Prod.snd
c : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).2
L : Primrec fun a => a.1.1.1
k : Primrec fun a => (ofNat (ℕ × Code) a.1.1.1.length).1
n : Primrec fun a => a.1.1.2
cf : Primrec fun a => a.2.1
z : Primrec fun a => (unpair a.1.1.2).1
m✝ : Primrec fun a => (unpair a.1.1.2).2
h₁ :
  Primrec fun a =>
    Nat.Partrec.Code.lup
      (a.1.1.1, ((ofNat (ℕ × Code) a.1.1.1.length).1, a.2.1), Nat.pair (unpair a.1.1.2).1 (unpair a.1.1.2).2).1
      (a.1.1.1, ((ofNat (ℕ × Code) a.1.1.1.length).1, a.2.1), Nat.pair (unpair a.1.1.2).1 (unpair a.1.1.2).2).2.1
      (a.1.1.1, ((ofNat (ℕ × Code) a.1.1.1.length).1, a.2.1), Nat.pair (unpair a.1.1.2).1 (unpair a.1.1.2).2).2.2
m : Primrec fun a => (unpair a.1.1.1.2).2
⊢ Primrec₂ fun p x =>
    Nat.Partrec.Code.lup p.1.1.1.1 (p.1.1.2, (ofNat (ℕ × Code) p.1.1.1.1.length).2)
      (Nat.pair (unpair p.1.1.1.2).1 ((unpair p.1.1.1.2).2 + 1))

tactic: unfold Primrec₂
state_before: case hrf
a : Primrec fun a => ofNat (ℕ × Code) a.length
k✝¹ : Primrec fun a => (ofNat (ℕ × Code) a.1.length).1
n✝¹ : Primrec Prod.snd
k✝ : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).1
n✝ : Primrec fun a => a.1.2
k' : Primrec Prod.snd
c : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).2
L : Primrec fun a => a.1.1.1
k : Primrec fun a => (ofNat (ℕ × Code) a.1.1.1.length).1
n : Primrec fun a => a.1.1.2
cf : Primrec fun a => a.2.1
z : Primrec fun a => (unpair a.1.1.2).1
m✝ : Primrec fun a => (unpair a.1.1.2).2
h₁ :
  Primrec fun a =>
    Nat.Partrec.Code.lup
      (a.1.1.1, ((ofNat (ℕ × Code) a.1.1.1.length).1, a.2.1), Nat.pair (unpair a.1.1.2).1 (unpair a.1.1.2).2).1
      (a.1.1.1, ((ofNat (ℕ × Code) a.1.1.1.length).1, a.2.1), Nat.pair (unpair a.1.1.2).1 (unpair a.1.1.2).2).2.1
      (a.1.1.1, ((ofNat (ℕ × Code) a.1.1.1.length).1, a.2.1), Nat.pair (unpair a.1.1.2).1 (unpair a.1.1.2).2).2.2
m : Primrec fun a => (unpair a.1.1.1.2).2
⊢ Primrec₂ fun p x =>
    Nat.Partrec.Code.lup p.1.1.1.1 (p.1.1.2, (ofNat (ℕ × Code) p.1.1.1.1.length).2)
      (Nat.pair (unpair p.1.1.1.2).1 ((unpair p.1.1.1.2).2 + 1))
state_after: case hrf
a : Primrec fun a => ofNat (ℕ × Code) a.length
k✝¹ : Primrec fun a => (ofNat (ℕ × Code) a.1.length).1
n✝¹ : Primrec Prod.snd
k✝ : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).1
n✝ : Primrec fun a => a.1.2
k' : Primrec Prod.snd
c : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).2
L : Primrec fun a => a.1.1.1
k : Primrec fun a => (ofNat (ℕ × Code) a.1.1.1.length).1
n : Primrec fun a => a.1.1.2
cf : Primrec fun a => a.2.1
z : Primrec fun a => (unpair a.1.1.2).1
m✝ : Primrec fun a => (unpair a.1.1.2).2
h₁ :
  Primrec fun a =>
    Nat.Partrec.Code.lup
      (a.1.1.1, ((ofNat (ℕ × Code) a.1.1.1.length).1, a.2.1), Nat.pair (unpair a.1.1.2).1 (unpair a.1.1.2).2).1
      (a.1.1.1, ((ofNat (ℕ × Code) a.1.1.1.length).1, a.2.1), Nat.pair (unpair a.1.1.2).1 (unpair a.1.1.2).2).2.1
      (a.1.1.1, ((ofNat (ℕ × Code) a.1.1.1.length).1, a.2.1), Nat.pair (unpair a.1.1.2).1 (unpair a.1.1.2).2).2.2
m : Primrec fun a => (unpair a.1.1.1.2).2
⊢ Primrec fun p =>
    (fun p x =>
        Nat.Partrec.Code.lup p.1.1.1.1 (p.1.1.2, (ofNat (ℕ × Code) p.1.1.1.1.length).2)
          (Nat.pair (unpair p.1.1.1.2).1 ((unpair p.1.1.1.2).2 + 1)))
      p.1 p.2

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) a.length
k✝¹ : Primrec fun a => (ofNat (ℕ × Code) a.1.length).1
n✝¹ : Primrec Prod.snd
k✝ : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).1
n✝ : Primrec fun a => a.1.2
k' : Primrec Prod.snd
c : Primrec fun a => (ofNat (ℕ × Code) a.1.1.length).2
L : Primrec fun a => a.1.1.1
k : Primrec fun a => (ofNat (ℕ × Code) a.1.1.1.length).1
n : Primrec fun a => a.1.1.2
cf : Primrec fun a => a.2.1
z : Primrec fun a => (unpair a.1.1.2).1
m✝ : Primrec fun a => (unpair a.1.1.2).2
h₁ :
  Primrec fun a =>
    Nat.Partrec.Code.lup
      (a.1.1.1, ((ofNat (ℕ × Code) a.1.1.1.length).1, a.2.1), Nat.pair (unpair a.1.1.2).1 (unpair a.1.1.2).2).1
      (a.1.1.1, ((ofNat (ℕ × Code) a.1.1.1.length).1, a.2.1), Nat.pair (unpair a.1.1.2).1 (unpair a.1.1.2).2).2.1
      (a.1.1.1, ((ofNat (ℕ × Code) a.1.1.1.length).1, a.2.1), Nat.pair (unpair a.1.1.2).1 (unpair a.1.1.2).2).2.2
m : Primrec fun a => (unpair a.1.1.1.2).2
⊢ Primrec fun p =>
    (fun p x =>
        Nat.Partrec.Code.lup p.1.1.1.1 (p.1.1.2, (ofNat (ℕ × Code) p.1.1.1.1.length).2)
          (Nat.pair (unpair p.1.1.1.2).1 ((unpair p.1.1.1.2).2 + 1)))
      p.1 p.2
state_after: no goals