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

tactic: intros _ _ _ _ F
state_before: α : Type u_1
σ : Type u_2
inst✝¹ : Primcodable α
inst✝ : Primcodable σ
c : α → Code
hc : Computable c
z : α → σ
hz : Computable z
s : α → σ
hs : Computable s
l : α → σ
hl : Computable l
r : α → σ
hr : Computable r
pr : α → Code × Code × σ × σ → σ
hpr : Computable₂ pr
co : α → Code × Code × σ × σ → σ
hco : Computable₂ co
pc : α → Code × Code × σ × σ → σ
hpc : Computable₂ pc
rf : α → Code × σ → σ
hrf : Computable₂ rf
⊢ let PR := fun a cf cg hf hg => pr a (cf, cg, hf, hg);
  let CO := fun a cf cg hf hg => co a (cf, cg, hf, hg);
  let PC := fun a cf cg hf hg => pc a (cf, cg, hf, hg);
  let RF := fun a cf hf => rf a (cf, hf);
  let F := fun a c => Code.recOn c (z a) (s a) (l a) (r a) (PR a) (CO a) (PC a) (RF a);
  Computable fun a => F a (c a)

tactic: let G₁ : (α × List σ) × ℕ × ℕ → Option σ := fun p =>
  let a := p.1.1
  let IH := p.1.2
  let n := p.2.1
  let m := p.2.2
  (IH.get? m).bind fun s =>
    (IH.get? m.unpair.1).bind fun s₁ =>
      (IH.get? m.unpair.2).map fun s₂ =>
        cond n.bodd
          (cond n.div2.bodd (rf a (ofNat Code m, s))
            (pc a (ofNat Code m.unpair.1, ofNat Code m.unpair.2, s₁, s₂)))
          (cond n.div2.bodd (co a (ofNat Code m.unpair.1, ofNat Code m.unpair.2, s₁, s₂))
            (pr a (ofNat Code m.unpair.1, ofNat Code m.unpair.2, s₁, s₂)))
state_before: α : Type u_1
σ : Type u_2
inst✝¹ : Primcodable α
inst✝ : Primcodable σ
c : α → Code
hc : Computable c
z : α → σ
hz : Computable z
s : α → σ
hs : Computable s
l : α → σ
hl : Computable l
r : α → σ
hr : Computable r
pr : α → Code × Code × σ × σ → σ
hpr : Computable₂ pr
co : α → Code × Code × σ × σ → σ
hco : Computable₂ co
pc : α → Code × Code × σ × σ → σ
hpc : Computable₂ pc
rf : α → Code × σ → σ
hrf : Computable₂ rf
PR✝ : α → Code → Code → σ → σ → σ := fun a cf cg hf hg => pr a (cf, cg, hf, hg)
CO✝ : α → Code → Code → σ → σ → σ := fun a cf cg hf hg => co a (cf, cg, hf, hg)
PC✝ : α → Code → Code → σ → σ → σ := fun a cf cg hf hg => pc a (cf, cg, hf, hg)
RF✝ : α → Code → σ → σ := fun a cf hf => rf a (cf, hf)
F : α → Code → σ := fun a c => Code.recOn c (z a) (s a) (l a) (r a) (PR✝ a) (CO✝ a) (PC✝ a) (RF✝ a)
⊢ Computable fun a => F a (c a)

tactic: have : Computable G₁ := by
  refine' option_bind (list_get?.comp (snd.comp fst) (snd.comp snd)) _
  unfold Computable₂
  refine'
    option_bind
      ((list_get?.comp (snd.comp fst)
        (fst.comp <| Computable.unpair.comp (snd.comp snd))).comp fst) _
  unfold Computable₂
  refine'
    option_map
      ((list_get?.comp (snd.comp fst)
        (snd.comp <| Computable.unpair.comp (snd.comp snd))).comp <| fst.comp fst) _
  have a : Computable (fun p : ((((α × List σ) × ℕ × ℕ) × σ) × σ) × σ => p.1.1.1.1.1) :=
    fst.comp (fst.comp <| fst.comp <| fst.comp fst)
  have n : Computable (fun p : ((((α × List σ) × ℕ × ℕ) × σ) × σ) × σ => p.1.1.1.2.1) :=
    fst.comp (snd.comp <| fst.comp <| fst.comp fst)
  have m : Computable (fun p : ((((α × List σ) × ℕ × ℕ) × σ) × σ) × σ => p.1.1.1.2.2) :=
    snd.comp (snd.comp <| fst.comp <| fst.comp fst)
  have m₁ := fst.comp (Computable.unpair.comp m)
  have m₂ := snd.comp (Computable.unpair.comp m)
  have s : Computable (fun p : ((((α × List σ) × ℕ × ℕ) × σ) × σ) × σ => p.1.1.2) :=
    snd.comp (fst.comp fst)
  have s₁ : Computable (fun p : ((((α × List σ) × ℕ × ℕ) × σ) × σ) × σ => p.1.2) :=
    snd.comp fst
  have s₂ : Computable (fun p : ((((α × List σ) × ℕ × ℕ) × σ) × σ) × σ => p.2) :=
    snd
  exact
    (nat_bodd.comp n).cond
      ((nat_bodd.comp <| nat_div2.comp n).cond
        (hrf.comp a (((Computable.ofNat Code).comp m).pair s))
        (hpc.comp a
          (((Computable.ofNat Code).comp m₁).pair <|
            ((Computable.ofNat Code).comp m₂).pair <| s₁.pair s₂)))
      (Computable.cond (nat_bodd.comp <| nat_div2.comp n)
        (hco.comp a
          (((Computable.ofNat Code).comp m₁).pair <|
            ((Computable.ofNat Code).comp m₂).pair <| s₁.pair s₂))
        (hpr.comp a
          (((Computable.ofNat Code).comp m₁).pair <|
            ((Computable.ofNat Code).comp m₂).pair <| s₁.pair s₂)))
state_before: α : Type u_1
σ : Type u_2
inst✝¹ : Primcodable α
inst✝ : Primcodable σ
c : α → Code
hc : Computable c
z : α → σ
hz : Computable z
s : α → σ
hs : Computable s
l : α → σ
hl : Computable l
r : α → σ
hr : Computable r
pr : α → Code × Code × σ × σ → σ
hpr : Computable₂ pr
co : α → Code × Code × σ × σ → σ
hco : Computable₂ co
pc : α → Code × Code × σ × σ → σ
hpc : Computable₂ pc
rf : α → Code × σ → σ
hrf : Computable₂ rf
PR✝ : α → Code → Code → σ → σ → σ := fun a cf cg hf hg => pr a (cf, cg, hf, hg)
CO✝ : α → Code → Code → σ → σ → σ := fun a cf cg hf hg => co a (cf, cg, hf, hg)
PC✝ : α → Code → Code → σ → σ → σ := fun a cf cg hf hg => pc a (cf, cg, hf, hg)
RF✝ : α → Code → σ → σ := fun a cf hf => rf a (cf, hf)
F : α → Code → σ := fun a c => Code.recOn c (z a) (s a) (l a) (r a) (PR✝ a) (CO✝ a) (PC✝ a) (RF✝ a)
G₁ : (α × List σ) × ℕ × ℕ → Option σ :=
  fun p =>
    let a := p.fst.fst;
    let IH := p.fst.snd;
    let n := p.snd.fst;
    let m := p.snd.snd;
    Option.bind (List.get? IH m) fun s =>
      Option.bind (List.get? IH (unpair m).fst) fun s₁ =>
        Option.map
          (fun s₂ =>
            bif bodd n then
              bif bodd (div2 n) then rf a (ofNat Code m, s)
              else pc a (ofNat Code (unpair m).fst, ofNat Code (unpair m).snd, s₁, s₂)
            else
              bif bodd (div2 n) then co a (ofNat Code (unpair m).fst, ofNat Code (unpair m).snd, s₁, s₂)
              else pr a (ofNat Code (unpair m).fst, ofNat Code (unpair m).snd, s₁, s₂))
          (List.get? IH (unpair m).snd)
⊢ Computable fun a => F a (c a)

tactic: let G : α → List σ → Option σ := fun a IH =>
  IH.length.casesOn (some (z a)) fun n =>
    n.casesOn (some (s a)) fun n =>
      n.casesOn (some (l a)) fun n =>
        n.casesOn (some (r a)) fun n => G₁ ((a, IH), n, n.div2.div2)
state_before: α : Type u_1
σ : Type u_2
inst✝¹ : Primcodable α
inst✝ : Primcodable σ
c : α → Code
hc : Computable c
z : α → σ
hz : Computable z
s : α → σ
hs : Computable s
l : α → σ
hl : Computable l
r : α → σ
hr : Computable r
pr : α → Code × Code × σ × σ → σ
hpr : Computable₂ pr
co : α → Code × Code × σ × σ → σ
hco : Computable₂ co
pc : α → Code × Code × σ × σ → σ
hpc : Computable₂ pc
rf : α → Code × σ → σ
hrf : Computable₂ rf
PR✝ : α → Code → Code → σ → σ → σ := fun a cf cg hf hg => pr a (cf, cg, hf, hg)
CO✝ : α → Code → Code → σ → σ → σ := fun a cf cg hf hg => co a (cf, cg, hf, hg)
PC✝ : α → Code → Code → σ → σ → σ := fun a cf cg hf hg => pc a (cf, cg, hf, hg)
RF✝ : α → Code → σ → σ := fun a cf hf => rf a (cf, hf)
F : α → Code → σ := fun a c => Code.recOn c (z a) (s a) (l a) (r a) (PR✝ a) (CO✝ a) (PC✝ a) (RF✝ a)
G₁ : (α × List σ) × ℕ × ℕ → Option σ :=
  fun p =>
    let a := p.fst.fst;
    let IH := p.fst.snd;
    let n := p.snd.fst;
    let m := p.snd.snd;
    Option.bind (List.get? IH m) fun s =>
      Option.bind (List.get? IH (unpair m).fst) fun s₁ =>
        Option.map
          (fun s₂ =>
            bif bodd n then
              bif bodd (div2 n) then rf a (ofNat Code m, s)
              else pc a (ofNat Code (unpair m).fst, ofNat Code (unpair m).snd, s₁, s₂)
            else
              bif bodd (div2 n) then co a (ofNat Code (unpair m).fst, ofNat Code (unpair m).snd, s₁, s₂)
              else pr a (ofNat Code (unpair m).fst, ofNat Code (unpair m).snd, s₁, s₂))
          (List.get? IH (unpair m).snd)
this : Computable G₁
⊢ Computable fun a => F a (c a)

tactic: have : Computable₂ G :=
  Computable.nat_casesOn (list_length.comp snd) (option_some_iff.2 (hz.comp fst)) <|
    Computable.nat_casesOn snd (option_some_iff.2 (hs.comp (fst.comp fst))) <|
      Computable.nat_casesOn snd (option_some_iff.2 (hl.comp (fst.comp <| fst.comp fst))) <|
        Computable.nat_casesOn snd
          (option_some_iff.2 (hr.comp (fst.comp <| fst.comp <| fst.comp fst)))
          (this.comp <|
            ((Computable.fst.pair snd).comp <| fst.comp <| fst.comp <| fst.comp <| fst).pair <|
              snd.pair <| nat_div2.comp <| nat_div2.comp snd)
state_before: α : Type u_1
σ : Type u_2
inst✝¹ : Primcodable α
inst✝ : Primcodable σ
c : α → Code
hc : Computable c
z : α → σ
hz : Computable z
s : α → σ
hs : Computable s
l : α → σ
hl : Computable l
r : α → σ
hr : Computable r
pr : α → Code × Code × σ × σ → σ
hpr : Computable₂ pr
co : α → Code × Code × σ × σ → σ
hco : Computable₂ co
pc : α → Code × Code × σ × σ → σ
hpc : Computable₂ pc
rf : α → Code × σ → σ
hrf : Computable₂ rf
PR✝ : α → Code → Code → σ → σ → σ := fun a cf cg hf hg => pr a (cf, cg, hf, hg)
CO✝ : α → Code → Code → σ → σ → σ := fun a cf cg hf hg => co a (cf, cg, hf, hg)
PC✝ : α → Code → Code → σ → σ → σ := fun a cf cg hf hg => pc a (cf, cg, hf, hg)
RF✝ : α → Code → σ → σ := fun a cf hf => rf a (cf, hf)
F : α → Code → σ := fun a c => Code.recOn c (z a) (s a) (l a) (r a) (PR✝ a) (CO✝ a) (PC✝ a) (RF✝ a)
G₁ : (α × List σ) × ℕ × ℕ → Option σ :=
  fun p =>
    let a := p.fst.fst;
    let IH := p.fst.snd;
    let n := p.snd.fst;
    let m := p.snd.snd;
    Option.bind (List.get? IH m) fun s =>
      Option.bind (List.get? IH (unpair m).fst) fun s₁ =>
        Option.map
          (fun s₂ =>
            bif bodd n then
              bif bodd (div2 n) then rf a (ofNat Code m, s)
              else pc a (ofNat Code (unpair m).fst, ofNat Code (unpair m).snd, s₁, s₂)
            else
              bif bodd (div2 n) then co a (ofNat Code (unpair m).fst, ofNat Code (unpair m).snd, s₁, s₂)
              else pr a (ofNat Code (unpair m).fst, ofNat Code (unpair m).snd, s₁, s₂))
          (List.get? IH (unpair m).snd)
this : Computable G₁
G : α → List σ → Option σ :=
  fun a IH =>
    Nat.casesOn (List.length IH) (some (z a)) fun n =>
      Nat.casesOn n (some (s a)) fun n =>
        Nat.casesOn n (some (l a)) fun n => Nat.casesOn n (some (r a)) fun n => G₁ ((a, IH), n, div2 (div2 n))
⊢ Computable fun a => F a (c a)

tactic: refine'
  ((nat_strong_rec (fun a n => F a (ofNat Code n)) this.to₂ fun a n => _).comp Computable.id <|
    encode_iff.2 hc).of_eq fun a => by simp
state_before: α : Type u_1
σ : Type u_2
inst✝¹ : Primcodable α
inst✝ : Primcodable σ
c : α → Code
hc : Computable c
z : α → σ
hz : Computable z
s : α → σ
hs : Computable s
l : α → σ
hl : Computable l
r : α → σ
hr : Computable r
pr : α → Code × Code × σ × σ → σ
hpr : Computable₂ pr
co : α → Code × Code × σ × σ → σ
hco : Computable₂ co
pc : α → Code × Code × σ × σ → σ
hpc : Computable₂ pc
rf : α → Code × σ → σ
hrf : Computable₂ rf
PR✝ : α → Code → Code → σ → σ → σ := fun a cf cg hf hg => pr a (cf, cg, hf, hg)
CO✝ : α → Code → Code → σ → σ → σ := fun a cf cg hf hg => co a (cf, cg, hf, hg)
PC✝ : α → Code → Code → σ → σ → σ := fun a cf cg hf hg => pc a (cf, cg, hf, hg)
RF✝ : α → Code → σ → σ := fun a cf hf => rf a (cf, hf)
F : α → Code → σ := fun a c => Code.recOn c (z a) (s a) (l a) (r a) (PR✝ a) (CO✝ a) (PC✝ a) (RF✝ a)
G₁ : (α × List σ) × ℕ × ℕ → Option σ :=
  fun p =>
    let a := p.fst.fst;
    let IH := p.fst.snd;
    let n := p.snd.fst;
    let m := p.snd.snd;
    Option.bind (List.get? IH m) fun s =>
      Option.bind (List.get? IH (unpair m).fst) fun s₁ =>
        Option.map
          (fun s₂ =>
            bif bodd n then
              bif bodd (div2 n) then rf a (ofNat Code m, s)
              else pc a (ofNat Code (unpair m).fst, ofNat Code (unpair m).snd, s₁, s₂)
            else
              bif bodd (div2 n) then co a (ofNat Code (unpair m).fst, ofNat Code (unpair m).snd, s₁, s₂)
              else pr a (ofNat Code (unpair m).fst, ofNat Code (unpair m).snd, s₁, s₂))
          (List.get? IH (unpair m).snd)
this✝ : Computable G₁
G : α → List σ → Option σ :=
  fun a IH =>
    Nat.casesOn (List.length IH) (some (z a)) fun n =>
      Nat.casesOn n (some (s a)) fun n =>
        Nat.casesOn n (some (l a)) fun n => Nat.casesOn n (some (r a)) fun n => G₁ ((a, IH), n, div2 (div2 n))
this : Computable₂ G
⊢ Computable fun a => F a (c a)

tactic: simp (config := { zeta := false })
state_before: α : Type u_1
σ : Type u_2
inst✝¹ : Primcodable α
inst✝ : Primcodable σ
c : α → Code
hc : Computable c
z : α → σ
hz : Computable z
s : α → σ
hs : Computable s
l : α → σ
hl : Computable l
r : α → σ
hr : Computable r
pr : α → Code × Code × σ × σ → σ
hpr : Computable₂ pr
co : α → Code × Code × σ × σ → σ
hco : Computable₂ co
pc : α → Code × Code × σ × σ → σ
hpc : Computable₂ pc
rf : α → Code × σ → σ
hrf : Computable₂ rf
PR✝ : α → Code → Code → σ → σ → σ := fun a cf cg hf hg => pr a (cf, cg, hf, hg)
CO✝ : α → Code → Code → σ → σ → σ := fun a cf cg hf hg => co a (cf, cg, hf, hg)
PC✝ : α → Code → Code → σ → σ → σ := fun a cf cg hf hg => pc a (cf, cg, hf, hg)
RF✝ : α → Code → σ → σ := fun a cf hf => rf a (cf, hf)
F : α → Code → σ := fun a c => Code.recOn c (z a) (s a) (l a) (r a) (PR✝ a) (CO✝ a) (PC✝ a) (RF✝ a)
G₁ : (α × List σ) × ℕ × ℕ → Option σ :=
  fun p =>
    let a := p.fst.fst;
    let IH := p.fst.snd;
    let n := p.snd.fst;
    let m := p.snd.snd;
    Option.bind (List.get? IH m) fun s =>
      Option.bind (List.get? IH (unpair m).fst) fun s₁ =>
        Option.map
          (fun s₂ =>
            bif bodd n then
              bif bodd (div2 n) then rf a (ofNat Code m, s)
              else pc a (ofNat Code (unpair m).fst, ofNat Code (unpair m).snd, s₁, s₂)
            else
              bif bodd (div2 n) then co a (ofNat Code (unpair m).fst, ofNat Code (unpair m).snd, s₁, s₂)
              else pr a (ofNat Code (unpair m).fst, ofNat Code (unpair m).snd, s₁, s₂))
          (List.get? IH (unpair m).snd)
this✝ : Computable G₁
G : α → List σ → Option σ :=
  fun a IH =>
    Nat.casesOn (List.length IH) (some (z a)) fun n =>
      Nat.casesOn n (some (s a)) fun n =>
        Nat.casesOn n (some (l a)) fun n => Nat.casesOn n (some (r a)) fun n => G₁ ((a, IH), n, div2 (div2 n))
this : Computable₂ G
a : α
n : ℕ
⊢ G (a, List.map ((fun a n => F a (ofNat Code n)) a) (List.range n)).fst
      (a, List.map ((fun a n => F a (ofNat Code n)) a) (List.range n)).snd =
    some ((fun a n => F a (ofNat Code n)) a n)

tactic: simp only []
state_before: case succ.succ.succ.succ
α : Type u_1
σ : Type u_2
inst✝¹ : Primcodable α
inst✝ : Primcodable σ
c : α → Code
hc : Computable c
z : α → σ
hz : Computable z
s : α → σ
hs : Computable s
l : α → σ
hl : Computable l
r : α → σ
hr : Computable r
pr : α → Code × Code × σ × σ → σ
hpr : Computable₂ pr
co : α → Code × Code × σ × σ → σ
hco : Computable₂ co
pc : α → Code × Code × σ × σ → σ
hpc : Computable₂ pc
rf : α → Code × σ → σ
hrf : Computable₂ rf
PR✝ : α → Code → Code → σ → σ → σ := fun a cf cg hf hg => pr a (cf, cg, hf, hg)
CO✝ : α → Code → Code → σ → σ → σ := fun a cf cg hf hg => co a (cf, cg, hf, hg)
PC✝ : α → Code → Code → σ → σ → σ := fun a cf cg hf hg => pc a (cf, cg, hf, hg)
RF✝ : α → Code → σ → σ := fun a cf hf => rf a (cf, hf)
F : α → Code → σ := fun a c => Code.recOn c (z a) (s a) (l a) (r a) (PR✝ a) (CO✝ a) (PC✝ a) (RF✝ a)
G₁ : (α × List σ) × ℕ × ℕ → Option σ :=
  fun p =>
    let a := p.fst.fst;
    let IH := p.fst.snd;
    let n := p.snd.fst;
    let m := p.snd.snd;
    Option.bind (List.get? IH m) fun s =>
      Option.bind (List.get? IH (unpair m).fst) fun s₁ =>
        Option.map
          (fun s₂ =>
            bif bodd n then
              bif bodd (div2 n) then rf a (ofNat Code m, s)
              else pc a (ofNat Code (unpair m).fst, ofNat Code (unpair m).snd, s₁, s₂)
            else
              bif bodd (div2 n) then co a (ofNat Code (unpair m).fst, ofNat Code (unpair m).snd, s₁, s₂)
              else pr a (ofNat Code (unpair m).fst, ofNat Code (unpair m).snd, s₁, s₂))
          (List.get? IH (unpair m).snd)
this✝ : Computable G₁
G : α → List σ → Option σ :=
  fun a IH =>
    Nat.casesOn (List.length IH) (some (z a)) fun n =>
      Nat.casesOn n (some (s a)) fun n =>
        Nat.casesOn n (some (l a)) fun n => Nat.casesOn n (some (r a)) fun n => G₁ ((a, IH), n, div2 (div2 n))
this : Computable₂ G
a : α
n : ℕ
⊢ G a (List.map (fun n => F a (ofNat Code n)) (List.range (Nat.succ (Nat.succ (Nat.succ (Nat.succ n)))))) =
    some (F a (ofNat Code (Nat.succ (Nat.succ (Nat.succ (Nat.succ n))))))

tactic: rw [List.length_map, List.length_range]
state_before: case succ.succ.succ.succ
α : Type u_1
σ : Type u_2
inst✝¹ : Primcodable α
inst✝ : Primcodable σ
c : α → Code
hc : Computable c
z : α → σ
hz : Computable z
s : α → σ
hs : Computable s
l : α → σ
hl : Computable l
r : α → σ
hr : Computable r
pr : α → Code × Code × σ × σ → σ
hpr : Computable₂ pr
co : α → Code × Code × σ × σ → σ
hco : Computable₂ co
pc : α → Code × Code × σ × σ → σ
hpc : Computable₂ pc
rf : α → Code × σ → σ
hrf : Computable₂ rf
PR✝ : α → Code → Code → σ → σ → σ := fun a cf cg hf hg => pr a (cf, cg, hf, hg)
CO✝ : α → Code → Code → σ → σ → σ := fun a cf cg hf hg => co a (cf, cg, hf, hg)
PC✝ : α → Code → Code → σ → σ → σ := fun a cf cg hf hg => pc a (cf, cg, hf, hg)
RF✝ : α → Code → σ → σ := fun a cf hf => rf a (cf, hf)
F : α → Code → σ := fun a c => Code.recOn c (z a) (s a) (l a) (r a) (PR✝ a) (CO✝ a) (PC✝ a) (RF✝ a)
G₁ : (α × List σ) × ℕ × ℕ → Option σ :=
  fun p =>
    let a := p.fst.fst;
    let IH := p.fst.snd;
    let n := p.snd.fst;
    let m := p.snd.snd;
    Option.bind (List.get? IH m) fun s =>
      Option.bind (List.get? IH (unpair m).fst) fun s₁ =>
        Option.map
          (fun s₂ =>
            bif bodd n then
              bif bodd (div2 n) then rf a (ofNat Code m, s)
              else pc a (ofNat Code (unpair m).fst, ofNat Code (unpair m).snd, s₁, s₂)
            else
              bif bodd (div2 n) then co a (ofNat Code (unpair m).fst, ofNat Code (unpair m).snd, s₁, s₂)
              else pr a (ofNat Code (unpair m).fst, ofNat Code (unpair m).snd, s₁, s₂))
          (List.get? IH (unpair m).snd)
this✝ : Computable G₁
G : α → List σ → Option σ :=
  fun a IH =>
    Nat.casesOn (List.length IH) (some (z a)) fun n =>
      Nat.casesOn n (some (s a)) fun n =>
        Nat.casesOn n (some (l a)) fun n => Nat.casesOn n (some (r a)) fun n => G₁ ((a, IH), n, div2 (div2 n))
this : Computable₂ G
a : α
n : ℕ
⊢ Nat.rec (some (z a))
      (fun n_1 n_ih =>
        Nat.rec (some (s a))
          (fun n_2 n_ih =>
            Nat.rec (some (l a))
              (fun n_3 n_ih =>
                Nat.rec (some (r a))
                  (fun n_4 n_ih =>
                    Option.bind
                      (List.get?
                        (List.map
                          (fun n =>
                            rec (z a) (s a) (l a) (r a) (fun cf cg hf hg => pr a (cf, cg, hf, hg))
                              (fun cf cg hf hg => co a (cf, cg, hf, hg)) (fun cf cg hf hg => pc a (cf, cg, hf, hg))
                              (fun cf hf => rf a (cf, hf)) (ofNat Code n))
                          (List.range (Nat.succ (Nat.succ (Nat.succ (Nat.succ n))))))
                        (div2 (div2 n_4)))
                      fun s_1 =>
                      Option.bind
                        (List.get?
                          (List.map
                            (fun n =>
                              rec (z a) (s a) (l a) (r a) (fun cf cg hf hg => pr a (cf, cg, hf, hg))
                                (fun cf cg hf hg => co a (cf, cg, hf, hg)) (fun cf cg hf hg => pc a (cf, cg, hf, hg))
                                (fun cf hf => rf a (cf, hf)) (ofNat Code n))
                            (List.range (Nat.succ (Nat.succ (Nat.succ (Nat.succ n))))))
                          (unpair (div2 (div2 n_4))).fst)
                        fun s₁ =>
                        Option.map
                          (fun s₂ =>
                            bif bodd n_4 then
                              bif bodd (div2 n_4) then rf a (ofNat Code (div2 (div2 n_4)), s_1)
                              else
                                pc a
                                  (ofNat Code (unpair (div2 (div2 n_4))).fst, ofNat Code (unpair (div2 (div2 n_4))).snd,
                                    s₁, s₂)
                            else
                              bif bodd (div2 n_4) then
                                co a
                                  (ofNat Code (unpair (div2 (div2 n_4))).fst, ofNat Code (unpair (div2 (div2 n_4))).snd,
                                    s₁, s₂)
                              else
                                pr a
                                  (ofNat Code (unpair (div2 (div2 n_4))).fst, ofNat Code (unpair (div2 (div2 n_4))).snd,
                                    s₁, s₂))
                          (List.get?
                            (List.map
                              (fun n =>
                                rec (z a) (s a) (l a) (r a) (fun cf cg hf hg => pr a (cf, cg, hf, hg))
                                  (fun cf cg hf hg => co a (cf, cg, hf, hg)) (fun cf cg hf hg => pc a (cf, cg, hf, hg))
                                  (fun cf hf => rf a (cf, hf)) (ofNat Code n))
                              (List.range (Nat.succ (Nat.succ (Nat.succ (Nat.succ n))))))
                            (unpair (div2 (div2 n_4))).snd))
                  n_3)
              n_2)
          n_1)
      (List.length
        (List.map
          (fun n =>
            rec (z a) (s a) (l a) (r a) (fun cf cg hf hg => pr a (cf, cg, hf, hg))
              (fun cf cg hf hg => co a (cf, cg, hf, hg)) (fun cf cg hf hg => pc a (cf, cg, hf, hg))
              (fun cf hf => rf a (cf, hf)) (ofNat Code n))
          (List.range (Nat.succ (Nat.succ (Nat.succ (Nat.succ n))))))) =
    some
      (rec (z a) (s a) (l a) (r a) (fun cf cg hf hg => pr a (cf, cg, hf, hg)) (fun cf cg hf hg => co a (cf, cg, hf, hg))
        (fun cf cg hf hg => pc a (cf, cg, hf, hg)) (fun cf hf => rf a (cf, hf))
        (ofNat Code (Nat.succ (Nat.succ (Nat.succ (Nat.succ n))))))

tactic: let m := n.div2.div2
state_before: case succ.succ.succ.succ
α : Type u_1
σ : Type u_2
inst✝¹ : Primcodable α
inst✝ : Primcodable σ
c : α → Code
hc : Computable c
z : α → σ
hz : Computable z
s : α → σ
hs : Computable s
l : α → σ
hl : Computable l
r : α → σ
hr : Computable r
pr : α → Code × Code × σ × σ → σ
hpr : Computable₂ pr
co : α → Code × Code × σ × σ → σ
hco : Computable₂ co
pc : α → Code × Code × σ × σ → σ
hpc : Computable₂ pc
rf : α → Code × σ → σ
hrf : Computable₂ rf
PR✝ : α → Code → Code → σ → σ → σ := fun a cf cg hf hg => pr a (cf, cg, hf, hg)
CO✝ : α → Code → Code → σ → σ → σ := fun a cf cg hf hg => co a (cf, cg, hf, hg)
PC✝ : α → Code → Code → σ → σ → σ := fun a cf cg hf hg => pc a (cf, cg, hf, hg)
RF✝ : α → Code → σ → σ := fun a cf hf => rf a (cf, hf)
F : α → Code → σ := fun a c => Code.recOn c (z a) (s a) (l a) (r a) (PR✝ a) (CO✝ a) (PC✝ a) (RF✝ a)
G₁ : (α × List σ) × ℕ × ℕ → Option σ :=
  fun p =>
    let a := p.fst.fst;
    let IH := p.fst.snd;
    let n := p.snd.fst;
    let m := p.snd.snd;
    Option.bind (List.get? IH m) fun s =>
      Option.bind (List.get? IH (unpair m).fst) fun s₁ =>
        Option.map
          (fun s₂ =>
            bif bodd n then
              bif bodd (div2 n) then rf a (ofNat Code m, s)
              else pc a (ofNat Code (unpair m).fst, ofNat Code (unpair m).snd, s₁, s₂)
            else
              bif bodd (div2 n) then co a (ofNat Code (unpair m).fst, ofNat Code (unpair m).snd, s₁, s₂)
              else pr a (ofNat Code (unpair m).fst, ofNat Code (unpair m).snd, s₁, s₂))
          (List.get? IH (unpair m).snd)
this✝ : Computable G₁
G : α → List σ → Option σ :=
  fun a IH =>
    Nat.casesOn (List.length IH) (some (z a)) fun n =>
      Nat.casesOn n (some (s a)) fun n =>
        Nat.casesOn n (some (l a)) fun n => Nat.casesOn n (some (r a)) fun n => G₁ ((a, IH), n, div2 (div2 n))
this : Computable₂ G
a : α
n : ℕ
⊢ Nat.rec (some (z a))
      (fun n_1 n_ih =>
        Nat.rec (some (s a))
          (fun n_2 n_ih =>
            Nat.rec (some (l a))
              (fun n_3 n_ih =>
                Nat.rec (some (r a))
                  (fun n_4 n_ih =>
                    Option.bind
                      (List.get?
                        (List.map
                          (fun n =>
                            rec (z a) (s a) (l a) (r a) (fun cf cg hf hg => pr a (cf, cg, hf, hg))
                              (fun cf cg hf hg => co a (cf, cg, hf, hg)) (fun cf cg hf hg => pc a (cf, cg, hf, hg))
                              (fun cf hf => rf a (cf, hf)) (ofNat Code n))
                          (List.range (Nat.succ (Nat.succ (Nat.succ (Nat.succ n))))))
                        (div2 (div2 n_4)))
                      fun s_1 =>
                      Option.bind
                        (List.get?
                          (List.map
                            (fun n =>
                              rec (z a) (s a) (l a) (r a) (fun cf cg hf hg => pr a (cf, cg, hf, hg))
                                (fun cf cg hf hg => co a (cf, cg, hf, hg)) (fun cf cg hf hg => pc a (cf, cg, hf, hg))
                                (fun cf hf => rf a (cf, hf)) (ofNat Code n))
                            (List.range (Nat.succ (Nat.succ (Nat.succ (Nat.succ n))))))
                          (unpair (div2 (div2 n_4))).fst)
                        fun s₁ =>
                        Option.map
                          (fun s₂ =>
                            bif bodd n_4 then
                              bif bodd (div2 n_4) then rf a (ofNat Code (div2 (div2 n_4)), s_1)
                              else
                                pc a
                                  (ofNat Code (unpair (div2 (div2 n_4))).fst, ofNat Code (unpair (div2 (div2 n_4))).snd,
                                    s₁, s₂)
                            else
                              bif bodd (div2 n_4) then
                                co a
                                  (ofNat Code (unpair (div2 (div2 n_4))).fst, ofNat Code (unpair (div2 (div2 n_4))).snd,
                                    s₁, s₂)
                              else
                                pr a
                                  (ofNat Code (unpair (div2 (div2 n_4))).fst, ofNat Code (unpair (div2 (div2 n_4))).snd,
                                    s₁, s₂))
                          (List.get?
                            (List.map
                              (fun n =>
                                rec (z a) (s a) (l a) (r a) (fun cf cg hf hg => pr a (cf, cg, hf, hg))
                                  (fun cf cg hf hg => co a (cf, cg, hf, hg)) (fun cf cg hf hg => pc a (cf, cg, hf, hg))
                                  (fun cf hf => rf a (cf, hf)) (ofNat Code n))
                              (List.range (Nat.succ (Nat.succ (Nat.succ (Nat.succ n))))))
                            (unpair (div2 (div2 n_4))).snd))
                  n_3)
              n_2)
          n_1)
      (Nat.succ (Nat.succ (Nat.succ (Nat.succ n)))) =
    some
      (rec (z a) (s a) (l a) (r a) (fun cf cg hf hg => pr a (cf, cg, hf, hg)) (fun cf cg hf hg => co a (cf, cg, hf, hg))
        (fun cf cg hf hg => pc a (cf, cg, hf, hg)) (fun cf hf => rf a (cf, hf))
        (ofNat Code (Nat.succ (Nat.succ (Nat.succ (Nat.succ n))))))

tactic: show
  G₁ ((a, (List.range (n + 4)).map fun n => F a (ofNat Code n)), n, m) =
    some (F a (ofNat Code (n + 4)))
state_before: case succ.succ.succ.succ
α : Type u_1
σ : Type u_2
inst✝¹ : Primcodable α
inst✝ : Primcodable σ
c : α → Code
hc : Computable c
z : α → σ
hz : Computable z
s : α → σ
hs : Computable s
l : α → σ
hl : Computable l
r : α → σ
hr : Computable r
pr : α → Code × Code × σ × σ → σ
hpr : Computable₂ pr
co : α → Code × Code × σ × σ → σ
hco : Computable₂ co
pc : α → Code × Code × σ × σ → σ
hpc : Computable₂ pc
rf : α → Code × σ → σ
hrf : Computable₂ rf
PR✝ : α → Code → Code → σ → σ → σ := fun a cf cg hf hg => pr a (cf, cg, hf, hg)
CO✝ : α → Code → Code → σ → σ → σ := fun a cf cg hf hg => co a (cf, cg, hf, hg)
PC✝ : α → Code → Code → σ → σ → σ := fun a cf cg hf hg => pc a (cf, cg, hf, hg)
RF✝ : α → Code → σ → σ := fun a cf hf => rf a (cf, hf)
F : α → Code → σ := fun a c => Code.recOn c (z a) (s a) (l a) (r a) (PR✝ a) (CO✝ a) (PC✝ a) (RF✝ a)
G₁ : (α × List σ) × ℕ × ℕ → Option σ :=
  fun p =>
    let a := p.fst.fst;
    let IH := p.fst.snd;
    let n := p.snd.fst;
    let m := p.snd.snd;
    Option.bind (List.get? IH m) fun s =>
      Option.bind (List.get? IH (unpair m).fst) fun s₁ =>
        Option.map
          (fun s₂ =>
            bif bodd n then
              bif bodd (div2 n) then rf a (ofNat Code m, s)
              else pc a (ofNat Code (unpair m).fst, ofNat Code (unpair m).snd, s₁, s₂)
            else
              bif bodd (div2 n) then co a (ofNat Code (unpair m).fst, ofNat Code (unpair m).snd, s₁, s₂)
              else pr a (ofNat Code (unpair m).fst, ofNat Code (unpair m).snd, s₁, s₂))
          (List.get? IH (unpair m).snd)
this✝ : Computable G₁
G : α → List σ → Option σ :=
  fun a IH =>
    Nat.casesOn (List.length IH) (some (z a)) fun n =>
      Nat.casesOn n (some (s a)) fun n =>
        Nat.casesOn n (some (l a)) fun n => Nat.casesOn n (some (r a)) fun n => G₁ ((a, IH), n, div2 (div2 n))
this : Computable₂ G
a : α
n : ℕ
m : ℕ := div2 (div2 n)
⊢ Nat.rec (some (z a))
      (fun n_1 n_ih =>
        Nat.rec (some (s a))
          (fun n_2 n_ih =>
            Nat.rec (some (l a))
              (fun n_3 n_ih =>
                Nat.rec (some (r a))
                  (fun n_4 n_ih =>
                    Option.bind
                      (List.get?
                        (List.map
                          (fun n =>
                            rec (z a) (s a) (l a) (r a) (fun cf cg hf hg => pr a (cf, cg, hf, hg))
                              (fun cf cg hf hg => co a (cf, cg, hf, hg)) (fun cf cg hf hg => pc a (cf, cg, hf, hg))
                              (fun cf hf => rf a (cf, hf)) (ofNat Code n))
                          (List.range (Nat.succ (Nat.succ (Nat.succ (Nat.succ n))))))
                        (div2 (div2 n_4)))
                      fun s_1 =>
                      Option.bind
                        (List.get?
                          (List.map
                            (fun n =>
                              rec (z a) (s a) (l a) (r a) (fun cf cg hf hg => pr a (cf, cg, hf, hg))
                                (fun cf cg hf hg => co a (cf, cg, hf, hg)) (fun cf cg hf hg => pc a (cf, cg, hf, hg))
                                (fun cf hf => rf a (cf, hf)) (ofNat Code n))
                            (List.range (Nat.succ (Nat.succ (Nat.succ (Nat.succ n))))))
                          (unpair (div2 (div2 n_4))).fst)
                        fun s₁ =>
                        Option.map
                          (fun s₂ =>
                            bif bodd n_4 then
                              bif bodd (div2 n_4) then rf a (ofNat Code (div2 (div2 n_4)), s_1)
                              else
                                pc a
                                  (ofNat Code (unpair (div2 (div2 n_4))).fst, ofNat Code (unpair (div2 (div2 n_4))).snd,
                                    s₁, s₂)
                            else
                              bif bodd (div2 n_4) then
                                co a
                                  (ofNat Code (unpair (div2 (div2 n_4))).fst, ofNat Code (unpair (div2 (div2 n_4))).snd,
                                    s₁, s₂)
                              else
                                pr a
                                  (ofNat Code (unpair (div2 (div2 n_4))).fst, ofNat Code (unpair (div2 (div2 n_4))).snd,
                                    s₁, s₂))
                          (List.get?
                            (List.map
                              (fun n =>
                                rec (z a) (s a) (l a) (r a) (fun cf cg hf hg => pr a (cf, cg, hf, hg))
                                  (fun cf cg hf hg => co a (cf, cg, hf, hg)) (fun cf cg hf hg => pc a (cf, cg, hf, hg))
                                  (fun cf hf => rf a (cf, hf)) (ofNat Code n))
                              (List.range (Nat.succ (Nat.succ (Nat.succ (Nat.succ n))))))
                            (unpair (div2 (div2 n_4))).snd))
                  n_3)
              n_2)
          n_1)
      (Nat.succ (Nat.succ (Nat.succ (Nat.succ n)))) =
    some
      (rec (z a) (s a) (l a) (r a) (fun cf cg hf hg => pr a (cf, cg, hf, hg)) (fun cf cg hf hg => co a (cf, cg, hf, hg))
        (fun cf cg hf hg => pc a (cf, cg, hf, hg)) (fun cf hf => rf a (cf, hf))
        (ofNat Code (Nat.succ (Nat.succ (Nat.succ (Nat.succ n))))))

tactic: have hm : m < n + 4 := by
  simp [Nat.div2_val]
  exact
    lt_of_le_of_lt (le_trans (Nat.div_le_self _ _) (Nat.div_le_self _ _))
      (Nat.succ_le_succ (Nat.le_add_right _ _))
state_before: case succ.succ.succ.succ
α : Type u_1
σ : Type u_2
inst✝¹ : Primcodable α
inst✝ : Primcodable σ
c : α → Code
hc : Computable c
z : α → σ
hz : Computable z
s : α → σ
hs : Computable s
l : α → σ
hl : Computable l
r : α → σ
hr : Computable r
pr : α → Code × Code × σ × σ → σ
hpr : Computable₂ pr
co : α → Code × Code × σ × σ → σ
hco : Computable₂ co
pc : α → Code × Code × σ × σ → σ
hpc : Computable₂ pc
rf : α → Code × σ → σ
hrf : Computable₂ rf
PR✝ : α → Code → Code → σ → σ → σ := fun a cf cg hf hg => pr a (cf, cg, hf, hg)
CO✝ : α → Code → Code → σ → σ → σ := fun a cf cg hf hg => co a (cf, cg, hf, hg)
PC✝ : α → Code → Code → σ → σ → σ := fun a cf cg hf hg => pc a (cf, cg, hf, hg)
RF✝ : α → Code → σ → σ := fun a cf hf => rf a (cf, hf)
F : α → Code → σ := fun a c => Code.recOn c (z a) (s a) (l a) (r a) (PR✝ a) (CO✝ a) (PC✝ a) (RF✝ a)
G₁ : (α × List σ) × ℕ × ℕ → Option σ :=
  fun p =>
    let a := p.fst.fst;
    let IH := p.fst.snd;
    let n := p.snd.fst;
    let m := p.snd.snd;
    Option.bind (List.get? IH m) fun s =>
      Option.bind (List.get? IH (unpair m).fst) fun s₁ =>
        Option.map
          (fun s₂ =>
            bif bodd n then
              bif bodd (div2 n) then rf a (ofNat Code m, s)
              else pc a (ofNat Code (unpair m).fst, ofNat Code (unpair m).snd, s₁, s₂)
            else
              bif bodd (div2 n) then co a (ofNat Code (unpair m).fst, ofNat Code (unpair m).snd, s₁, s₂)
              else pr a (ofNat Code (unpair m).fst, ofNat Code (unpair m).snd, s₁, s₂))
          (List.get? IH (unpair m).snd)
this✝ : Computable G₁
G : α → List σ → Option σ :=
  fun a IH =>
    Nat.casesOn (List.length IH) (some (z a)) fun n =>
      Nat.casesOn n (some (s a)) fun n =>
        Nat.casesOn n (some (l a)) fun n => Nat.casesOn n (some (r a)) fun n => G₁ ((a, IH), n, div2 (div2 n))
this : Computable₂ G
a : α
n : ℕ
m : ℕ := div2 (div2 n)
⊢ G₁ ((a, List.map (fun n => F a (ofNat Code n)) (List.range (n + 4))), n, m) = some (F a (ofNat Code (n + 4)))

tactic: have m1 : m.unpair.1 < n + 4 := lt_of_le_of_lt m.unpair_left_le hm
state_before: case succ.succ.succ.succ
α : Type u_1
σ : Type u_2
inst✝¹ : Primcodable α
inst✝ : Primcodable σ
c : α → Code
hc : Computable c
z : α → σ
hz : Computable z
s : α → σ
hs : Computable s
l : α → σ
hl : Computable l
r : α → σ
hr : Computable r
pr : α → Code × Code × σ × σ → σ
hpr : Computable₂ pr
co : α → Code × Code × σ × σ → σ
hco : Computable₂ co
pc : α → Code × Code × σ × σ → σ
hpc : Computable₂ pc
rf : α → Code × σ → σ
hrf : Computable₂ rf
PR✝ : α → Code → Code → σ → σ → σ := fun a cf cg hf hg => pr a (cf, cg, hf, hg)
CO✝ : α → Code → Code → σ → σ → σ := fun a cf cg hf hg => co a (cf, cg, hf, hg)
PC✝ : α → Code → Code → σ → σ → σ := fun a cf cg hf hg => pc a (cf, cg, hf, hg)
RF✝ : α → Code → σ → σ := fun a cf hf => rf a (cf, hf)
F : α → Code → σ := fun a c => Code.recOn c (z a) (s a) (l a) (r a) (PR✝ a) (CO✝ a) (PC✝ a) (RF✝ a)
G₁ : (α × List σ) × ℕ × ℕ → Option σ :=
  fun p =>
    let a := p.fst.fst;
    let IH := p.fst.snd;
    let n := p.snd.fst;
    let m := p.snd.snd;
    Option.bind (List.get? IH m) fun s =>
      Option.bind (List.get? IH (unpair m).fst) fun s₁ =>
        Option.map
          (fun s₂ =>
            bif bodd n then
              bif bodd (div2 n) then rf a (ofNat Code m, s)
              else pc a (ofNat Code (unpair m).fst, ofNat Code (unpair m).snd, s₁, s₂)
            else
              bif bodd (div2 n) then co a (ofNat Code (unpair m).fst, ofNat Code (unpair m).snd, s₁, s₂)
              else pr a (ofNat Code (unpair m).fst, ofNat Code (unpair m).snd, s₁, s₂))
          (List.get? IH (unpair m).snd)
this✝ : Computable G₁
G : α → List σ → Option σ :=
  fun a IH =>
    Nat.casesOn (List.length IH) (some (z a)) fun n =>
      Nat.casesOn n (some (s a)) fun n =>
        Nat.casesOn n (some (l a)) fun n => Nat.casesOn n (some (r a)) fun n => G₁ ((a, IH), n, div2 (div2 n))
this : Computable₂ G
a : α
n : ℕ
m : ℕ := div2 (div2 n)
hm : m < n + 4
⊢ G₁ ((a, List.map (fun n => F a (ofNat Code n)) (List.range (n + 4))), n, m) = some (F a (ofNat Code (n + 4)))

tactic: have m2 : m.unpair.2 < n + 4 := lt_of_le_of_lt m.unpair_right_le hm
state_before: case succ.succ.succ.succ
α : Type u_1
σ : Type u_2
inst✝¹ : Primcodable α
inst✝ : Primcodable σ
c : α → Code
hc : Computable c
z : α → σ
hz : Computable z
s : α → σ
hs : Computable s
l : α → σ
hl : Computable l
r : α → σ
hr : Computable r
pr : α → Code × Code × σ × σ → σ
hpr : Computable₂ pr
co : α → Code × Code × σ × σ → σ
hco : Computable₂ co
pc : α → Code × Code × σ × σ → σ
hpc : Computable₂ pc
rf : α → Code × σ → σ
hrf : Computable₂ rf
PR✝ : α → Code → Code → σ → σ → σ := fun a cf cg hf hg => pr a (cf, cg, hf, hg)
CO✝ : α → Code → Code → σ → σ → σ := fun a cf cg hf hg => co a (cf, cg, hf, hg)
PC✝ : α → Code → Code → σ → σ → σ := fun a cf cg hf hg => pc a (cf, cg, hf, hg)
RF✝ : α → Code → σ → σ := fun a cf hf => rf a (cf, hf)
F : α → Code → σ := fun a c => Code.recOn c (z a) (s a) (l a) (r a) (PR✝ a) (CO✝ a) (PC✝ a) (RF✝ a)
G₁ : (α × List σ) × ℕ × ℕ → Option σ :=
  fun p =>
    let a := p.fst.fst;
    let IH := p.fst.snd;
    let n := p.snd.fst;
    let m := p.snd.snd;
    Option.bind (List.get? IH m) fun s =>
      Option.bind (List.get? IH (unpair m).fst) fun s₁ =>
        Option.map
          (fun s₂ =>
            bif bodd n then
              bif bodd (div2 n) then rf a (ofNat Code m, s)
              else pc a (ofNat Code (unpair m).fst, ofNat Code (unpair m).snd, s₁, s₂)
            else
              bif bodd (div2 n) then co a (ofNat Code (unpair m).fst, ofNat Code (unpair m).snd, s₁, s₂)
              else pr a (ofNat Code (unpair m).fst, ofNat Code (unpair m).snd, s₁, s₂))
          (List.get? IH (unpair m).snd)
this✝ : Computable G₁
G : α → List σ → Option σ :=
  fun a IH =>
    Nat.casesOn (List.length IH) (some (z a)) fun n =>
      Nat.casesOn n (some (s a)) fun n =>
        Nat.casesOn n (some (l a)) fun n => Nat.casesOn n (some (r a)) fun n => G₁ ((a, IH), n, div2 (div2 n))
this : Computable₂ G
a : α
n : ℕ
m : ℕ := div2 (div2 n)
hm : m < n + 4
m1 : (unpair m).fst < n + 4
⊢ G₁ ((a, List.map (fun n => F a (ofNat Code n)) (List.range (n + 4))), n, m) = some (F a (ofNat Code (n + 4)))

tactic: simp [List.get?_map, List.get?_range, hm, m1, m2]
state_before: case succ.succ.succ.succ
α : Type u_1
σ : Type u_2
inst✝¹ : Primcodable α
inst✝ : Primcodable σ
c : α → Code
hc : Computable c
z : α → σ
hz : Computable z
s : α → σ
hs : Computable s
l : α → σ
hl : Computable l
r : α → σ
hr : Computable r
pr : α → Code × Code × σ × σ → σ
hpr : Computable₂ pr
co : α → Code × Code × σ × σ → σ
hco : Computable₂ co
pc : α → Code × Code × σ × σ → σ
hpc : Computable₂ pc
rf : α → Code × σ → σ
hrf : Computable₂ rf
PR✝ : α → Code → Code → σ → σ → σ := fun a cf cg hf hg => pr a (cf, cg, hf, hg)
CO✝ : α → Code → Code → σ → σ → σ := fun a cf cg hf hg => co a (cf, cg, hf, hg)
PC✝ : α → Code → Code → σ → σ → σ := fun a cf cg hf hg => pc a (cf, cg, hf, hg)
RF✝ : α → Code → σ → σ := fun a cf hf => rf a (cf, hf)
F : α → Code → σ := fun a c => Code.recOn c (z a) (s a) (l a) (r a) (PR✝ a) (CO✝ a) (PC✝ a) (RF✝ a)
G₁ : (α × List σ) × ℕ × ℕ → Option σ :=
  fun p =>
    let a := p.fst.fst;
    let IH := p.fst.snd;
    let n := p.snd.fst;
    let m := p.snd.snd;
    Option.bind (List.get? IH m) fun s =>
      Option.bind (List.get? IH (unpair m).fst) fun s₁ =>
        Option.map
          (fun s₂ =>
            bif bodd n then
              bif bodd (div2 n) then rf a (ofNat Code m, s)
              else pc a (ofNat Code (unpair m).fst, ofNat Code (unpair m).snd, s₁, s₂)
            else
              bif bodd (div2 n) then co a (ofNat Code (unpair m).fst, ofNat Code (unpair m).snd, s₁, s₂)
              else pr a (ofNat Code (unpair m).fst, ofNat Code (unpair m).snd, s₁, s₂))
          (List.get? IH (unpair m).snd)
this✝ : Computable G₁
G : α → List σ → Option σ :=
  fun a IH =>
    Nat.casesOn (List.length IH) (some (z a)) fun n =>
      Nat.casesOn n (some (s a)) fun n =>
        Nat.casesOn n (some (l a)) fun n => Nat.casesOn n (some (r a)) fun n => G₁ ((a, IH), n, div2 (div2 n))
this : Computable₂ G
a : α
n : ℕ
m : ℕ := div2 (div2 n)
hm : m < n + 4
m1 : (unpair m).fst < n + 4
m2 : (unpair m).snd < n + 4
⊢ G₁ ((a, List.map (fun n => F a (ofNat Code n)) (List.range (n + 4))), n, m) = some (F a (ofNat Code (n + 4)))

tactic: rw [show ofNat Code (n + 4) = ofNatCode (n + 4) from rfl]
state_before: case succ.succ.succ.succ
α : Type u_1
σ : Type u_2
inst✝¹ : Primcodable α
inst✝ : Primcodable σ
c : α → Code
hc : Computable c
z : α → σ
hz : Computable z
s : α → σ
hs : Computable s
l : α → σ
hl : Computable l
r : α → σ
hr : Computable r
pr : α → Code × Code × σ × σ → σ
hpr : Computable₂ pr
co : α → Code × Code × σ × σ → σ
hco : Computable₂ co
pc : α → Code × Code × σ × σ → σ
hpc : Computable₂ pc
rf : α → Code × σ → σ
hrf : Computable₂ rf
PR✝ : α → Code → Code → σ → σ → σ := fun a cf cg hf hg => pr a (cf, cg, hf, hg)
CO✝ : α → Code → Code → σ → σ → σ := fun a cf cg hf hg => co a (cf, cg, hf, hg)
PC✝ : α → Code → Code → σ → σ → σ := fun a cf cg hf hg => pc a (cf, cg, hf, hg)
RF✝ : α → Code → σ → σ := fun a cf hf => rf a (cf, hf)
F : α → Code → σ := fun a c => Code.recOn c (z a) (s a) (l a) (r a) (PR✝ a) (CO✝ a) (PC✝ a) (RF✝ a)
G₁ : (α × List σ) × ℕ × ℕ → Option σ :=
  fun p =>
    let a := p.fst.fst;
    let IH := p.fst.snd;
    let n := p.snd.fst;
    let m := p.snd.snd;
    Option.bind (List.get? IH m) fun s =>
      Option.bind (List.get? IH (unpair m).fst) fun s₁ =>
        Option.map
          (fun s₂ =>
            bif bodd n then
              bif bodd (div2 n) then rf a (ofNat Code m, s)
              else pc a (ofNat Code (unpair m).fst, ofNat Code (unpair m).snd, s₁, s₂)
            else
              bif bodd (div2 n) then co a (ofNat Code (unpair m).fst, ofNat Code (unpair m).snd, s₁, s₂)
              else pr a (ofNat Code (unpair m).fst, ofNat Code (unpair m).snd, s₁, s₂))
          (List.get? IH (unpair m).snd)
this✝ : Computable G₁
G : α → List σ → Option σ :=
  fun a IH =>
    Nat.casesOn (List.length IH) (some (z a)) fun n =>
      Nat.casesOn n (some (s a)) fun n =>
        Nat.casesOn n (some (l a)) fun n => Nat.casesOn n (some (r a)) fun n => G₁ ((a, IH), n, div2 (div2 n))
this : Computable₂ G
a : α
n : ℕ
m : ℕ := div2 (div2 n)
hm : m < n + 4
m1 : (unpair m).fst < n + 4
m2 : (unpair m).snd < n + 4
⊢ (bif bodd n then
      bif bodd (div2 n) then
        rf a
          (ofNat Code (div2 (div2 n)),
            rec (z a) (s a) (l a) (r a) (fun cf cg hf hg => pr a (cf, cg, hf, hg))
              (fun cf cg hf hg => co a (cf, cg, hf, hg)) (fun cf cg hf hg => pc a (cf, cg, hf, hg))
              (fun cf hf => rf a (cf, hf)) (ofNat Code (div2 (div2 n))))
      else
        pc a
          (ofNat Code (unpair (div2 (div2 n))).fst, ofNat Code (unpair (div2 (div2 n))).snd,
            rec (z a) (s a) (l a) (r a) (fun cf cg hf hg => pr a (cf, cg, hf, hg))
              (fun cf cg hf hg => co a (cf, cg, hf, hg)) (fun cf cg hf hg => pc a (cf, cg, hf, hg))
              (fun cf hf => rf a (cf, hf)) (ofNat Code (unpair (div2 (div2 n))).fst),
            rec (z a) (s a) (l a) (r a) (fun cf cg hf hg => pr a (cf, cg, hf, hg))
              (fun cf cg hf hg => co a (cf, cg, hf, hg)) (fun cf cg hf hg => pc a (cf, cg, hf, hg))
              (fun cf hf => rf a (cf, hf)) (ofNat Code (unpair (div2 (div2 n))).snd))
    else
      bif bodd (div2 n) then
        co a
          (ofNat Code (unpair (div2 (div2 n))).fst, ofNat Code (unpair (div2 (div2 n))).snd,
            rec (z a) (s a) (l a) (r a) (fun cf cg hf hg => pr a (cf, cg, hf, hg))
              (fun cf cg hf hg => co a (cf, cg, hf, hg)) (fun cf cg hf hg => pc a (cf, cg, hf, hg))
              (fun cf hf => rf a (cf, hf)) (ofNat Code (unpair (div2 (div2 n))).fst),
            rec (z a) (s a) (l a) (r a) (fun cf cg hf hg => pr a (cf, cg, hf, hg))
              (fun cf cg hf hg => co a (cf, cg, hf, hg)) (fun cf cg hf hg => pc a (cf, cg, hf, hg))
              (fun cf hf => rf a (cf, hf)) (ofNat Code (unpair (div2 (div2 n))).snd))
      else
        pr a
          (ofNat Code (unpair (div2 (div2 n))).fst, ofNat Code (unpair (div2 (div2 n))).snd,
            rec (z a) (s a) (l a) (r a) (fun cf cg hf hg => pr a (cf, cg, hf, hg))
              (fun cf cg hf hg => co a (cf, cg, hf, hg)) (fun cf cg hf hg => pc a (cf, cg, hf, hg))
              (fun cf hf => rf a (cf, hf)) (ofNat Code (unpair (div2 (div2 n))).fst),
            rec (z a) (s a) (l a) (r a) (fun cf cg hf hg => pr a (cf, cg, hf, hg))
              (fun cf cg hf hg => co a (cf, cg, hf, hg)) (fun cf cg hf hg => pc a (cf, cg, hf, hg))
              (fun cf hf => rf a (cf, hf)) (ofNat Code (unpair (div2 (div2 n))).snd))) =
    rec (z a) (s a) (l a) (r a) (fun cf cg hf hg => pr a (cf, cg, hf, hg)) (fun cf cg hf hg => co a (cf, cg, hf, hg))
      (fun cf cg hf hg => pc a (cf, cg, hf, hg)) (fun cf hf => rf a (cf, hf)) (ofNat Code (n + 4))

tactic: simp [ofNatCode]
state_before: case succ.succ.succ.succ
α : Type u_1
σ : Type u_2
inst✝¹ : Primcodable α
inst✝ : Primcodable σ
c : α → Code
hc : Computable c
z : α → σ
hz : Computable z
s : α → σ
hs : Computable s
l : α → σ
hl : Computable l
r : α → σ
hr : Computable r
pr : α → Code × Code × σ × σ → σ
hpr : Computable₂ pr
co : α → Code × Code × σ × σ → σ
hco : Computable₂ co
pc : α → Code × Code × σ × σ → σ
hpc : Computable₂ pc
rf : α → Code × σ → σ
hrf : Computable₂ rf
PR✝ : α → Code → Code → σ → σ → σ := fun a cf cg hf hg => pr a (cf, cg, hf, hg)
CO✝ : α → Code → Code → σ → σ → σ := fun a cf cg hf hg => co a (cf, cg, hf, hg)
PC✝ : α → Code → Code → σ → σ → σ := fun a cf cg hf hg => pc a (cf, cg, hf, hg)
RF✝ : α → Code → σ → σ := fun a cf hf => rf a (cf, hf)
F : α → Code → σ := fun a c => Code.recOn c (z a) (s a) (l a) (r a) (PR✝ a) (CO✝ a) (PC✝ a) (RF✝ a)
G₁ : (α × List σ) × ℕ × ℕ → Option σ :=
  fun p =>
    let a := p.fst.fst;
    let IH := p.fst.snd;
    let n := p.snd.fst;
    let m := p.snd.snd;
    Option.bind (List.get? IH m) fun s =>
      Option.bind (List.get? IH (unpair m).fst) fun s₁ =>
        Option.map
          (fun s₂ =>
            bif bodd n then
              bif bodd (div2 n) then rf a (ofNat Code m, s)
              else pc a (ofNat Code (unpair m).fst, ofNat Code (unpair m).snd, s₁, s₂)
            else
              bif bodd (div2 n) then co a (ofNat Code (unpair m).fst, ofNat Code (unpair m).snd, s₁, s₂)
              else pr a (ofNat Code (unpair m).fst, ofNat Code (unpair m).snd, s₁, s₂))
          (List.get? IH (unpair m).snd)
this✝ : Computable G₁
G : α → List σ → Option σ :=
  fun a IH =>
    Nat.casesOn (List.length IH) (some (z a)) fun n =>
      Nat.casesOn n (some (s a)) fun n =>
        Nat.casesOn n (some (l a)) fun n => Nat.casesOn n (some (r a)) fun n => G₁ ((a, IH), n, div2 (div2 n))
this : Computable₂ G
a : α
n : ℕ
m : ℕ := div2 (div2 n)
hm : m < n + 4
m1 : (unpair m).fst < n + 4
m2 : (unpair m).snd < n + 4
⊢ (bif bodd n then
      bif bodd (div2 n) then
        rf a
          (ofNat Code (div2 (div2 n)),
            rec (z a) (s a) (l a) (r a) (fun cf cg hf hg => pr a (cf, cg, hf, hg))
              (fun cf cg hf hg => co a (cf, cg, hf, hg)) (fun cf cg hf hg => pc a (cf, cg, hf, hg))
              (fun cf hf => rf a (cf, hf)) (ofNat Code (div2 (div2 n))))
      else
        pc a
          (ofNat Code (unpair (div2 (div2 n))).fst, ofNat Code (unpair (div2 (div2 n))).snd,
            rec (z a) (s a) (l a) (r a) (fun cf cg hf hg => pr a (cf, cg, hf, hg))
              (fun cf cg hf hg => co a (cf, cg, hf, hg)) (fun cf cg hf hg => pc a (cf, cg, hf, hg))
              (fun cf hf => rf a (cf, hf)) (ofNat Code (unpair (div2 (div2 n))).fst),
            rec (z a) (s a) (l a) (r a) (fun cf cg hf hg => pr a (cf, cg, hf, hg))
              (fun cf cg hf hg => co a (cf, cg, hf, hg)) (fun cf cg hf hg => pc a (cf, cg, hf, hg))
              (fun cf hf => rf a (cf, hf)) (ofNat Code (unpair (div2 (div2 n))).snd))
    else
      bif bodd (div2 n) then
        co a
          (ofNat Code (unpair (div2 (div2 n))).fst, ofNat Code (unpair (div2 (div2 n))).snd,
            rec (z a) (s a) (l a) (r a) (fun cf cg hf hg => pr a (cf, cg, hf, hg))
              (fun cf cg hf hg => co a (cf, cg, hf, hg)) (fun cf cg hf hg => pc a (cf, cg, hf, hg))
              (fun cf hf => rf a (cf, hf)) (ofNat Code (unpair (div2 (div2 n))).fst),
            rec (z a) (s a) (l a) (r a) (fun cf cg hf hg => pr a (cf, cg, hf, hg))
              (fun cf cg hf hg => co a (cf, cg, hf, hg)) (fun cf cg hf hg => pc a (cf, cg, hf, hg))
              (fun cf hf => rf a (cf, hf)) (ofNat Code (unpair (div2 (div2 n))).snd))
      else
        pr a
          (ofNat Code (unpair (div2 (div2 n))).fst, ofNat Code (unpair (div2 (div2 n))).snd,
            rec (z a) (s a) (l a) (r a) (fun cf cg hf hg => pr a (cf, cg, hf, hg))
              (fun cf cg hf hg => co a (cf, cg, hf, hg)) (fun cf cg hf hg => pc a (cf, cg, hf, hg))
              (fun cf hf => rf a (cf, hf)) (ofNat Code (unpair (div2 (div2 n))).fst),
            rec (z a) (s a) (l a) (r a) (fun cf cg hf hg => pr a (cf, cg, hf, hg))
              (fun cf cg hf hg => co a (cf, cg, hf, hg)) (fun cf cg hf hg => pc a (cf, cg, hf, hg))
              (fun cf hf => rf a (cf, hf)) (ofNat Code (unpair (div2 (div2 n))).snd))) =
    rec (z a) (s a) (l a) (r a) (fun cf cg hf hg => pr a (cf, cg, hf, hg)) (fun cf cg hf hg => co a (cf, cg, hf, hg))
      (fun cf cg hf hg => pc a (cf, cg, hf, hg)) (fun cf hf => rf a (cf, hf)) (ofNatCode (n + 4))

tactic: cases n.bodd <;> cases n.div2.bodd <;> rfl
state_before: case succ.succ.succ.succ
α : Type u_1
σ : Type u_2
inst✝¹ : Primcodable α
inst✝ : Primcodable σ
c : α → Code
hc : Computable c
z : α → σ
hz : Computable z
s : α → σ
hs : Computable s
l : α → σ
hl : Computable l
r : α → σ
hr : Computable r
pr : α → Code × Code × σ × σ → σ
hpr : Computable₂ pr
co : α → Code × Code × σ × σ → σ
hco : Computable₂ co
pc : α → Code × Code × σ × σ → σ
hpc : Computable₂ pc
rf : α → Code × σ → σ
hrf : Computable₂ rf
PR✝ : α → Code → Code → σ → σ → σ := fun a cf cg hf hg => pr a (cf, cg, hf, hg)
CO✝ : α → Code → Code → σ → σ → σ := fun a cf cg hf hg => co a (cf, cg, hf, hg)
PC✝ : α → Code → Code → σ → σ → σ := fun a cf cg hf hg => pc a (cf, cg, hf, hg)
RF✝ : α → Code → σ → σ := fun a cf hf => rf a (cf, hf)
F : α → Code → σ := fun a c => Code.recOn c (z a) (s a) (l a) (r a) (PR✝ a) (CO✝ a) (PC✝ a) (RF✝ a)
G₁ : (α × List σ) × ℕ × ℕ → Option σ :=
  fun p =>
    let a := p.fst.fst;
    let IH := p.fst.snd;
    let n := p.snd.fst;
    let m := p.snd.snd;
    Option.bind (List.get? IH m) fun s =>
      Option.bind (List.get? IH (unpair m).fst) fun s₁ =>
        Option.map
          (fun s₂ =>
            bif bodd n then
              bif bodd (div2 n) then rf a (ofNat Code m, s)
              else pc a (ofNat Code (unpair m).fst, ofNat Code (unpair m).snd, s₁, s₂)
            else
              bif bodd (div2 n) then co a (ofNat Code (unpair m).fst, ofNat Code (unpair m).snd, s₁, s₂)
              else pr a (ofNat Code (unpair m).fst, ofNat Code (unpair m).snd, s₁, s₂))
          (List.get? IH (unpair m).snd)
this✝ : Computable G₁
G : α → List σ → Option σ :=
  fun a IH =>
    Nat.casesOn (List.length IH) (some (z a)) fun n =>
      Nat.casesOn n (some (s a)) fun n =>
        Nat.casesOn n (some (l a)) fun n => Nat.casesOn n (some (r a)) fun n => G₁ ((a, IH), n, div2 (div2 n))
this : Computable₂ G
a : α
n : ℕ
m : ℕ := div2 (div2 n)
hm : m < n + 4
m1 : (unpair m).fst < n + 4
m2 : (unpair m).snd < n + 4
⊢ (bif bodd n then
      bif bodd (div2 n) then
        rf a
          (ofNat Code (div2 (div2 n)),
            rec (z a) (s a) (l a) (r a) (fun cf cg hf hg => pr a (cf, cg, hf, hg))
              (fun cf cg hf hg => co a (cf, cg, hf, hg)) (fun cf cg hf hg => pc a (cf, cg, hf, hg))
              (fun cf hf => rf a (cf, hf)) (ofNat Code (div2 (div2 n))))
      else
        pc a
          (ofNat Code (unpair (div2 (div2 n))).fst, ofNat Code (unpair (div2 (div2 n))).snd,
            rec (z a) (s a) (l a) (r a) (fun cf cg hf hg => pr a (cf, cg, hf, hg))
              (fun cf cg hf hg => co a (cf, cg, hf, hg)) (fun cf cg hf hg => pc a (cf, cg, hf, hg))
              (fun cf hf => rf a (cf, hf)) (ofNat Code (unpair (div2 (div2 n))).fst),
            rec (z a) (s a) (l a) (r a) (fun cf cg hf hg => pr a (cf, cg, hf, hg))
              (fun cf cg hf hg => co a (cf, cg, hf, hg)) (fun cf cg hf hg => pc a (cf, cg, hf, hg))
              (fun cf hf => rf a (cf, hf)) (ofNat Code (unpair (div2 (div2 n))).snd))
    else
      bif bodd (div2 n) then
        co a
          (ofNat Code (unpair (div2 (div2 n))).fst, ofNat Code (unpair (div2 (div2 n))).snd,
            rec (z a) (s a) (l a) (r a) (fun cf cg hf hg => pr a (cf, cg, hf, hg))
              (fun cf cg hf hg => co a (cf, cg, hf, hg)) (fun cf cg hf hg => pc a (cf, cg, hf, hg))
              (fun cf hf => rf a (cf, hf)) (ofNat Code (unpair (div2 (div2 n))).fst),
            rec (z a) (s a) (l a) (r a) (fun cf cg hf hg => pr a (cf, cg, hf, hg))
              (fun cf cg hf hg => co a (cf, cg, hf, hg)) (fun cf cg hf hg => pc a (cf, cg, hf, hg))
              (fun cf hf => rf a (cf, hf)) (ofNat Code (unpair (div2 (div2 n))).snd))
      else
        pr a
          (ofNat Code (unpair (div2 (div2 n))).fst, ofNat Code (unpair (div2 (div2 n))).snd,
            rec (z a) (s a) (l a) (r a) (fun cf cg hf hg => pr a (cf, cg, hf, hg))
              (fun cf cg hf hg => co a (cf, cg, hf, hg)) (fun cf cg hf hg => pc a (cf, cg, hf, hg))
              (fun cf hf => rf a (cf, hf)) (ofNat Code (unpair (div2 (div2 n))).fst),
            rec (z a) (s a) (l a) (r a) (fun cf cg hf hg => pr a (cf, cg, hf, hg))
              (fun cf cg hf hg => co a (cf, cg, hf, hg)) (fun cf cg hf hg => pc a (cf, cg, hf, hg))
              (fun cf hf => rf a (cf, hf)) (ofNat Code (unpair (div2 (div2 n))).snd))) =
    rec (z a) (s a) (l a) (r a) (fun cf cg hf hg => pr a (cf, cg, hf, hg)) (fun cf cg hf hg => co a (cf, cg, hf, hg))
      (fun cf cg hf hg => pc a (cf, cg, hf, hg)) (fun cf hf => rf a (cf, hf))
      (match bodd n, bodd (div2 n) with
      | false, false => pair (ofNatCode (unpair (div2 (div2 n))).fst) (ofNatCode (unpair (div2 (div2 n))).snd)
      | false, true => comp (ofNatCode (unpair (div2 (div2 n))).fst) (ofNatCode (unpair (div2 (div2 n))).snd)
      | true, false => prec (ofNatCode (unpair (div2 (div2 n))).fst) (ofNatCode (unpair (div2 (div2 n))).snd)
      | true, true => rfind' (ofNatCode (div2 (div2 n))))

tactic: refine' option_bind (list_get?.comp (snd.comp fst) (snd.comp snd)) _
state_before: α : Type u_1
σ : Type u_2
inst✝¹ : Primcodable α
inst✝ : Primcodable σ
c : α → Code
hc : Computable c
z : α → σ
hz : Computable z
s : α → σ
hs : Computable s
l : α → σ
hl : Computable l
r : α → σ
hr : Computable r
pr : α → Code × Code × σ × σ → σ
hpr : Computable₂ pr
co : α → Code × Code × σ × σ → σ
hco : Computable₂ co
pc : α → Code × Code × σ × σ → σ
hpc : Computable₂ pc
rf : α → Code × σ → σ
hrf : Computable₂ rf
PR✝ : α → Code → Code → σ → σ → σ := fun a cf cg hf hg => pr a (cf, cg, hf, hg)
CO✝ : α → Code → Code → σ → σ → σ := fun a cf cg hf hg => co a (cf, cg, hf, hg)
PC✝ : α → Code → Code → σ → σ → σ := fun a cf cg hf hg => pc a (cf, cg, hf, hg)
RF✝ : α → Code → σ → σ := fun a cf hf => rf a (cf, hf)
F : α → Code → σ := fun a c => Code.recOn c (z a) (s a) (l a) (r a) (PR✝ a) (CO✝ a) (PC✝ a) (RF✝ a)
G₁ : (α × List σ) × ℕ × ℕ → Option σ :=
  fun p =>
    let a := p.fst.fst;
    let IH := p.fst.snd;
    let n := p.snd.fst;
    let m := p.snd.snd;
    Option.bind (List.get? IH m) fun s =>
      Option.bind (List.get? IH (unpair m).fst) fun s₁ =>
        Option.map
          (fun s₂ =>
            bif bodd n then
              bif bodd (div2 n) then rf a (ofNat Code m, s)
              else pc a (ofNat Code (unpair m).fst, ofNat Code (unpair m).snd, s₁, s₂)
            else
              bif bodd (div2 n) then co a (ofNat Code (unpair m).fst, ofNat Code (unpair m).snd, s₁, s₂)
              else pr a (ofNat Code (unpair m).fst, ofNat Code (unpair m).snd, s₁, s₂))
          (List.get? IH (unpair m).snd)
⊢ Computable G₁

tactic: unfold Computable₂
state_before: α : Type u_1
σ : Type u_2
inst✝¹ : Primcodable α
inst✝ : Primcodable σ
c : α → Code
hc : Computable c
z : α → σ
hz : Computable z
s : α → σ
hs : Computable s
l : α → σ
hl : Computable l
r : α → σ
hr : Computable r
pr : α → Code × Code × σ × σ → σ
hpr : Computable₂ pr
co : α → Code × Code × σ × σ → σ
hco : Computable₂ co
pc : α → Code × Code × σ × σ → σ
hpc : Computable₂ pc
rf : α → Code × σ → σ
hrf : Computable₂ rf
PR✝ : α → Code → Code → σ → σ → σ := fun a cf cg hf hg => pr a (cf, cg, hf, hg)
CO✝ : α → Code → Code → σ → σ → σ := fun a cf cg hf hg => co a (cf, cg, hf, hg)
PC✝ : α → Code → Code → σ → σ → σ := fun a cf cg hf hg => pc a (cf, cg, hf, hg)
RF✝ : α → Code → σ → σ := fun a cf hf => rf a (cf, hf)
F : α → Code → σ := fun a c => Code.recOn c (z a) (s a) (l a) (r a) (PR✝ a) (CO✝ a) (PC✝ a) (RF✝ a)
G₁ : (α × List σ) × ℕ × ℕ → Option σ :=
  fun p =>
    let a := p.fst.fst;
    let IH := p.fst.snd;
    let n := p.snd.fst;
    let m := p.snd.snd;
    Option.bind (List.get? IH m) fun s =>
      Option.bind (List.get? IH (unpair m).fst) fun s₁ =>
        Option.map
          (fun s₂ =>
            bif bodd n then
              bif bodd (div2 n) then rf a (ofNat Code m, s)
              else pc a (ofNat Code (unpair m).fst, ofNat Code (unpair m).snd, s₁, s₂)
            else
              bif bodd (div2 n) then co a (ofNat Code (unpair m).fst, ofNat Code (unpair m).snd, s₁, s₂)
              else pr a (ofNat Code (unpair m).fst, ofNat Code (unpair m).snd, s₁, s₂))
          (List.get? IH (unpair m).snd)
⊢ Computable₂ fun p s =>
    Option.bind (List.get? p.fst.snd (unpair p.snd.snd).fst) fun s₁ =>
      Option.map
        (fun s₂ =>
          bif bodd p.snd.fst then
            bif bodd (div2 p.snd.fst) then rf p.fst.fst (ofNat Code p.snd.snd, s)
            else pc p.fst.fst (ofNat Code (unpair p.snd.snd).fst, ofNat Code (unpair p.snd.snd).snd, s₁, s₂)
          else
            bif bodd (div2 p.snd.fst) then
              co p.fst.fst (ofNat Code (unpair p.snd.snd).fst, ofNat Code (unpair p.snd.snd).snd, s₁, s₂)
            else pr p.fst.fst (ofNat Code (unpair p.snd.snd).fst, ofNat Code (unpair p.snd.snd).snd, s₁, s₂))
        (List.get? p.fst.snd (unpair p.snd.snd).snd)

tactic: refine'
  option_bind
    ((list_get?.comp (snd.comp fst)
      (fst.comp <| Computable.unpair.comp (snd.comp snd))).comp fst) _
state_before: α : Type u_1
σ : Type u_2
inst✝¹ : Primcodable α
inst✝ : Primcodable σ
c : α → Code
hc : Computable c
z : α → σ
hz : Computable z
s : α → σ
hs : Computable s
l : α → σ
hl : Computable l
r : α → σ
hr : Computable r
pr : α → Code × Code × σ × σ → σ
hpr : Computable₂ pr
co : α → Code × Code × σ × σ → σ
hco : Computable₂ co
pc : α → Code × Code × σ × σ → σ
hpc : Computable₂ pc
rf : α → Code × σ → σ
hrf : Computable₂ rf
PR✝ : α → Code → Code → σ → σ → σ := fun a cf cg hf hg => pr a (cf, cg, hf, hg)
CO✝ : α → Code → Code → σ → σ → σ := fun a cf cg hf hg => co a (cf, cg, hf, hg)
PC✝ : α → Code → Code → σ → σ → σ := fun a cf cg hf hg => pc a (cf, cg, hf, hg)
RF✝ : α → Code → σ → σ := fun a cf hf => rf a (cf, hf)
F : α → Code → σ := fun a c => Code.recOn c (z a) (s a) (l a) (r a) (PR✝ a) (CO✝ a) (PC✝ a) (RF✝ a)
G₁ : (α × List σ) × ℕ × ℕ → Option σ :=
  fun p =>
    let a := p.fst.fst;
    let IH := p.fst.snd;
    let n := p.snd.fst;
    let m := p.snd.snd;
    Option.bind (List.get? IH m) fun s =>
      Option.bind (List.get? IH (unpair m).fst) fun s₁ =>
        Option.map
          (fun s₂ =>
            bif bodd n then
              bif bodd (div2 n) then rf a (ofNat Code m, s)
              else pc a (ofNat Code (unpair m).fst, ofNat Code (unpair m).snd, s₁, s₂)
            else
              bif bodd (div2 n) then co a (ofNat Code (unpair m).fst, ofNat Code (unpair m).snd, s₁, s₂)
              else pr a (ofNat Code (unpair m).fst, ofNat Code (unpair m).snd, s₁, s₂))
          (List.get? IH (unpair m).snd)
⊢ Computable fun p =>
    (fun p s =>
        Option.bind (List.get? p.fst.snd (unpair p.snd.snd).fst) fun s₁ =>
          Option.map
            (fun s₂ =>
              bif bodd p.snd.fst then
                bif bodd (div2 p.snd.fst) then rf p.fst.fst (ofNat Code p.snd.snd, s)
                else pc p.fst.fst (ofNat Code (unpair p.snd.snd).fst, ofNat Code (unpair p.snd.snd).snd, s₁, s₂)
              else
                bif bodd (div2 p.snd.fst) then
                  co p.fst.fst (ofNat Code (unpair p.snd.snd).fst, ofNat Code (unpair p.snd.snd).snd, s₁, s₂)
                else pr p.fst.fst (ofNat Code (unpair p.snd.snd).fst, ofNat Code (unpair p.snd.snd).snd, s₁, s₂))
            (List.get? p.fst.snd (unpair p.snd.snd).snd))
      p.fst p.snd

tactic: unfold Computable₂
state_before: α : Type u_1
σ : Type u_2
inst✝¹ : Primcodable α
inst✝ : Primcodable σ
c : α → Code
hc : Computable c
z : α → σ
hz : Computable z
s : α → σ
hs : Computable s
l : α → σ
hl : Computable l
r : α → σ
hr : Computable r
pr : α → Code × Code × σ × σ → σ
hpr : Computable₂ pr
co : α → Code × Code × σ × σ → σ
hco : Computable₂ co
pc : α → Code × Code × σ × σ → σ
hpc : Computable₂ pc
rf : α → Code × σ → σ
hrf : Computable₂ rf
PR✝ : α → Code → Code → σ → σ → σ := fun a cf cg hf hg => pr a (cf, cg, hf, hg)
CO✝ : α → Code → Code → σ → σ → σ := fun a cf cg hf hg => co a (cf, cg, hf, hg)
PC✝ : α → Code → Code → σ → σ → σ := fun a cf cg hf hg => pc a (cf, cg, hf, hg)
RF✝ : α → Code → σ → σ := fun a cf hf => rf a (cf, hf)
F : α → Code → σ := fun a c => Code.recOn c (z a) (s a) (l a) (r a) (PR✝ a) (CO✝ a) (PC✝ a) (RF✝ a)
G₁ : (α × List σ) × ℕ × ℕ → Option σ :=
  fun p =>
    let a := p.fst.fst;
    let IH := p.fst.snd;
    let n := p.snd.fst;
    let m := p.snd.snd;
    Option.bind (List.get? IH m) fun s =>
      Option.bind (List.get? IH (unpair m).fst) fun s₁ =>
        Option.map
          (fun s₂ =>
            bif bodd n then
              bif bodd (div2 n) then rf a (ofNat Code m, s)
              else pc a (ofNat Code (unpair m).fst, ofNat Code (unpair m).snd, s₁, s₂)
            else
              bif bodd (div2 n) then co a (ofNat Code (unpair m).fst, ofNat Code (unpair m).snd, s₁, s₂)
              else pr a (ofNat Code (unpair m).fst, ofNat Code (unpair m).snd, s₁, s₂))
          (List.get? IH (unpair m).snd)
⊢ Computable₂ fun p s₁ =>
    Option.map
      (fun s₂ =>
        bif bodd p.fst.snd.fst then
          bif bodd (div2 p.fst.snd.fst) then rf p.fst.fst.fst (ofNat Code p.fst.snd.snd, p.snd)
          else pc p.fst.fst.fst (ofNat Code (unpair p.fst.snd.snd).fst, ofNat Code (unpair p.fst.snd.snd).snd, s₁, s₂)
        else
          bif bodd (div2 p.fst.snd.fst) then
            co p.fst.fst.fst (ofNat Code (unpair p.fst.snd.snd).fst, ofNat Code (unpair p.fst.snd.snd).snd, s₁, s₂)
          else pr p.fst.fst.fst (ofNat Code (unpair p.fst.snd.snd).fst, ofNat Code (unpair p.fst.snd.snd).snd, s₁, s₂))
      (List.get? p.fst.fst.snd (unpair p.fst.snd.snd).snd)

tactic: refine'
  option_map
    ((list_get?.comp (snd.comp fst)
      (snd.comp <| Computable.unpair.comp (snd.comp snd))).comp <| fst.comp fst) _
state_before: α : Type u_1
σ : Type u_2
inst✝¹ : Primcodable α
inst✝ : Primcodable σ
c : α → Code
hc : Computable c
z : α → σ
hz : Computable z
s : α → σ
hs : Computable s
l : α → σ
hl : Computable l
r : α → σ
hr : Computable r
pr : α → Code × Code × σ × σ → σ
hpr : Computable₂ pr
co : α → Code × Code × σ × σ → σ
hco : Computable₂ co
pc : α → Code × Code × σ × σ → σ
hpc : Computable₂ pc
rf : α → Code × σ → σ
hrf : Computable₂ rf
PR✝ : α → Code → Code → σ → σ → σ := fun a cf cg hf hg => pr a (cf, cg, hf, hg)
CO✝ : α → Code → Code → σ → σ → σ := fun a cf cg hf hg => co a (cf, cg, hf, hg)
PC✝ : α → Code → Code → σ → σ → σ := fun a cf cg hf hg => pc a (cf, cg, hf, hg)
RF✝ : α → Code → σ → σ := fun a cf hf => rf a (cf, hf)
F : α → Code → σ := fun a c => Code.recOn c (z a) (s a) (l a) (r a) (PR✝ a) (CO✝ a) (PC✝ a) (RF✝ a)
G₁ : (α × List σ) × ℕ × ℕ → Option σ :=
  fun p =>
    let a := p.fst.fst;
    let IH := p.fst.snd;
    let n := p.snd.fst;
    let m := p.snd.snd;
    Option.bind (List.get? IH m) fun s =>
      Option.bind (List.get? IH (unpair m).fst) fun s₁ =>
        Option.map
          (fun s₂ =>
            bif bodd n then
              bif bodd (div2 n) then rf a (ofNat Code m, s)
              else pc a (ofNat Code (unpair m).fst, ofNat Code (unpair m).snd, s₁, s₂)
            else
              bif bodd (div2 n) then co a (ofNat Code (unpair m).fst, ofNat Code (unpair m).snd, s₁, s₂)
              else pr a (ofNat Code (unpair m).fst, ofNat Code (unpair m).snd, s₁, s₂))
          (List.get? IH (unpair m).snd)
⊢ Computable fun p =>
    (fun p s₁ =>
        Option.map
          (fun s₂ =>
            bif bodd p.fst.snd.fst then
              bif bodd (div2 p.fst.snd.fst) then rf p.fst.fst.fst (ofNat Code p.fst.snd.snd, p.snd)
              else
                pc p.fst.fst.fst (ofNat Code (unpair p.fst.snd.snd).fst, ofNat Code (unpair p.fst.snd.snd).snd, s₁, s₂)
            else
              bif bodd (div2 p.fst.snd.fst) then
                co p.fst.fst.fst (ofNat Code (unpair p.fst.snd.snd).fst, ofNat Code (unpair p.fst.snd.snd).snd, s₁, s₂)
              else
                pr p.fst.fst.fst (ofNat Code (unpair p.fst.snd.snd).fst, ofNat Code (unpair p.fst.snd.snd).snd, s₁, s₂))
          (List.get? p.fst.fst.snd (unpair p.fst.snd.snd).snd))
      p.fst p.snd

tactic: have a : Computable (fun p : ((((α × List σ) × ℕ × ℕ) × σ) × σ) × σ => p.1.1.1.1.1) :=
  fst.comp (fst.comp <| fst.comp <| fst.comp fst)
state_before: α : Type u_1
σ : Type u_2
inst✝¹ : Primcodable α
inst✝ : Primcodable σ
c : α → Code
hc : Computable c
z : α → σ
hz : Computable z
s : α → σ
hs : Computable s
l : α → σ
hl : Computable l
r : α → σ
hr : Computable r
pr : α → Code × Code × σ × σ → σ
hpr : Computable₂ pr
co : α → Code × Code × σ × σ → σ
hco : Computable₂ co
pc : α → Code × Code × σ × σ → σ
hpc : Computable₂ pc
rf : α → Code × σ → σ
hrf : Computable₂ rf
PR✝ : α → Code → Code → σ → σ → σ := fun a cf cg hf hg => pr a (cf, cg, hf, hg)
CO✝ : α → Code → Code → σ → σ → σ := fun a cf cg hf hg => co a (cf, cg, hf, hg)
PC✝ : α → Code → Code → σ → σ → σ := fun a cf cg hf hg => pc a (cf, cg, hf, hg)
RF✝ : α → Code → σ → σ := fun a cf hf => rf a (cf, hf)
F : α → Code → σ := fun a c => Code.recOn c (z a) (s a) (l a) (r a) (PR✝ a) (CO✝ a) (PC✝ a) (RF✝ a)
G₁ : (α × List σ) × ℕ × ℕ → Option σ :=
  fun p =>
    let a := p.fst.fst;
    let IH := p.fst.snd;
    let n := p.snd.fst;
    let m := p.snd.snd;
    Option.bind (List.get? IH m) fun s =>
      Option.bind (List.get? IH (unpair m).fst) fun s₁ =>
        Option.map
          (fun s₂ =>
            bif bodd n then
              bif bodd (div2 n) then rf a (ofNat Code m, s)
              else pc a (ofNat Code (unpair m).fst, ofNat Code (unpair m).snd, s₁, s₂)
            else
              bif bodd (div2 n) then co a (ofNat Code (unpair m).fst, ofNat Code (unpair m).snd, s₁, s₂)
              else pr a (ofNat Code (unpair m).fst, ofNat Code (unpair m).snd, s₁, s₂))
          (List.get? IH (unpair m).snd)
⊢ Computable₂ fun p s₂ =>
    bif bodd p.fst.fst.snd.fst then
      bif bodd (div2 p.fst.fst.snd.fst) then rf p.fst.fst.fst.fst (ofNat Code p.fst.fst.snd.snd, p.fst.snd)
      else
        pc p.fst.fst.fst.fst
          (ofNat Code (unpair p.fst.fst.snd.snd).fst, ofNat Code (unpair p.fst.fst.snd.snd).snd, p.snd, s₂)
    else
      bif bodd (div2 p.fst.fst.snd.fst) then
        co p.fst.fst.fst.fst
          (ofNat Code (unpair p.fst.fst.snd.snd).fst, ofNat Code (unpair p.fst.fst.snd.snd).snd, p.snd, s₂)
      else
        pr p.fst.fst.fst.fst
          (ofNat Code (unpair p.fst.fst.snd.snd).fst, ofNat Code (unpair p.fst.fst.snd.snd).snd, p.snd, s₂)

tactic: have n : Computable (fun p : ((((α × List σ) × ℕ × ℕ) × σ) × σ) × σ => p.1.1.1.2.1) :=
  fst.comp (snd.comp <| fst.comp <| fst.comp fst)
state_before: α : Type u_1
σ : Type u_2
inst✝¹ : Primcodable α
inst✝ : Primcodable σ
c : α → Code
hc : Computable c
z : α → σ
hz : Computable z
s : α → σ
hs : Computable s
l : α → σ
hl : Computable l
r : α → σ
hr : Computable r
pr : α → Code × Code × σ × σ → σ
hpr : Computable₂ pr
co : α → Code × Code × σ × σ → σ
hco : Computable₂ co
pc : α → Code × Code × σ × σ → σ
hpc : Computable₂ pc
rf : α → Code × σ → σ
hrf : Computable₂ rf
PR✝ : α → Code → Code → σ → σ → σ := fun a cf cg hf hg => pr a (cf, cg, hf, hg)
CO✝ : α → Code → Code → σ → σ → σ := fun a cf cg hf hg => co a (cf, cg, hf, hg)
PC✝ : α → Code → Code → σ → σ → σ := fun a cf cg hf hg => pc a (cf, cg, hf, hg)
RF✝ : α → Code → σ → σ := fun a cf hf => rf a (cf, hf)
F : α → Code → σ := fun a c => Code.recOn c (z a) (s a) (l a) (r a) (PR✝ a) (CO✝ a) (PC✝ a) (RF✝ a)
G₁ : (α × List σ) × ℕ × ℕ → Option σ :=
  fun p =>
    let a := p.fst.fst;
    let IH := p.fst.snd;
    let n := p.snd.fst;
    let m := p.snd.snd;
    Option.bind (List.get? IH m) fun s =>
      Option.bind (List.get? IH (unpair m).fst) fun s₁ =>
        Option.map
          (fun s₂ =>
            bif bodd n then
              bif bodd (div2 n) then rf a (ofNat Code m, s)
              else pc a (ofNat Code (unpair m).fst, ofNat Code (unpair m).snd, s₁, s₂)
            else
              bif bodd (div2 n) then co a (ofNat Code (unpair m).fst, ofNat Code (unpair m).snd, s₁, s₂)
              else pr a (ofNat Code (unpair m).fst, ofNat Code (unpair m).snd, s₁, s₂))
          (List.get? IH (unpair m).snd)
a : Computable fun p => p.fst.fst.fst.fst.fst
⊢ Computable₂ fun p s₂ =>
    bif bodd p.fst.fst.snd.fst then
      bif bodd (div2 p.fst.fst.snd.fst) then rf p.fst.fst.fst.fst (ofNat Code p.fst.fst.snd.snd, p.fst.snd)
      else
        pc p.fst.fst.fst.fst
          (ofNat Code (unpair p.fst.fst.snd.snd).fst, ofNat Code (unpair p.fst.fst.snd.snd).snd, p.snd, s₂)
    else
      bif bodd (div2 p.fst.fst.snd.fst) then
        co p.fst.fst.fst.fst
          (ofNat Code (unpair p.fst.fst.snd.snd).fst, ofNat Code (unpair p.fst.fst.snd.snd).snd, p.snd, s₂)
      else
        pr p.fst.fst.fst.fst
          (ofNat Code (unpair p.fst.fst.snd.snd).fst, ofNat Code (unpair p.fst.fst.snd.snd).snd, p.snd, s₂)

tactic: have m : Computable (fun p : ((((α × List σ) × ℕ × ℕ) × σ) × σ) × σ => p.1.1.1.2.2) :=
  snd.comp (snd.comp <| fst.comp <| fst.comp fst)
state_before: α : Type u_1
σ : Type u_2
inst✝¹ : Primcodable α
inst✝ : Primcodable σ
c : α → Code
hc : Computable c
z : α → σ
hz : Computable z
s : α → σ
hs : Computable s
l : α → σ
hl : Computable l
r : α → σ
hr : Computable r
pr : α → Code × Code × σ × σ → σ
hpr : Computable₂ pr
co : α → Code × Code × σ × σ → σ
hco : Computable₂ co
pc : α → Code × Code × σ × σ → σ
hpc : Computable₂ pc
rf : α → Code × σ → σ
hrf : Computable₂ rf
PR✝ : α → Code → Code → σ → σ → σ := fun a cf cg hf hg => pr a (cf, cg, hf, hg)
CO✝ : α → Code → Code → σ → σ → σ := fun a cf cg hf hg => co a (cf, cg, hf, hg)
PC✝ : α → Code → Code → σ → σ → σ := fun a cf cg hf hg => pc a (cf, cg, hf, hg)
RF✝ : α → Code → σ → σ := fun a cf hf => rf a (cf, hf)
F : α → Code → σ := fun a c => Code.recOn c (z a) (s a) (l a) (r a) (PR✝ a) (CO✝ a) (PC✝ a) (RF✝ a)
G₁ : (α × List σ) × ℕ × ℕ → Option σ :=
  fun p =>
    let a := p.fst.fst;
    let IH := p.fst.snd;
    let n := p.snd.fst;
    let m := p.snd.snd;
    Option.bind (List.get? IH m) fun s =>
      Option.bind (List.get? IH (unpair m).fst) fun s₁ =>
        Option.map
          (fun s₂ =>
            bif bodd n then
              bif bodd (div2 n) then rf a (ofNat Code m, s)
              else pc a (ofNat Code (unpair m).fst, ofNat Code (unpair m).snd, s₁, s₂)
            else
              bif bodd (div2 n) then co a (ofNat Code (unpair m).fst, ofNat Code (unpair m).snd, s₁, s₂)
              else pr a (ofNat Code (unpair m).fst, ofNat Code (unpair m).snd, s₁, s₂))
          (List.get? IH (unpair m).snd)
a : Computable fun p => p.fst.fst.fst.fst.fst
n : Computable fun p => p.fst.fst.fst.snd.fst
⊢ Computable₂ fun p s₂ =>
    bif bodd p.fst.fst.snd.fst then
      bif bodd (div2 p.fst.fst.snd.fst) then rf p.fst.fst.fst.fst (ofNat Code p.fst.fst.snd.snd, p.fst.snd)
      else
        pc p.fst.fst.fst.fst
          (ofNat Code (unpair p.fst.fst.snd.snd).fst, ofNat Code (unpair p.fst.fst.snd.snd).snd, p.snd, s₂)
    else
      bif bodd (div2 p.fst.fst.snd.fst) then
        co p.fst.fst.fst.fst
          (ofNat Code (unpair p.fst.fst.snd.snd).fst, ofNat Code (unpair p.fst.fst.snd.snd).snd, p.snd, s₂)
      else
        pr p.fst.fst.fst.fst
          (ofNat Code (unpair p.fst.fst.snd.snd).fst, ofNat Code (unpair p.fst.fst.snd.snd).snd, p.snd, s₂)

tactic: have m₁ := fst.comp (Computable.unpair.comp m)
state_before: α : Type u_1
σ : Type u_2
inst✝¹ : Primcodable α
inst✝ : Primcodable σ
c : α → Code
hc : Computable c
z : α → σ
hz : Computable z
s : α → σ
hs : Computable s
l : α → σ
hl : Computable l
r : α → σ
hr : Computable r
pr : α → Code × Code × σ × σ → σ
hpr : Computable₂ pr
co : α → Code × Code × σ × σ → σ
hco : Computable₂ co
pc : α → Code × Code × σ × σ → σ
hpc : Computable₂ pc
rf : α → Code × σ → σ
hrf : Computable₂ rf
PR✝ : α → Code → Code → σ → σ → σ := fun a cf cg hf hg => pr a (cf, cg, hf, hg)
CO✝ : α → Code → Code → σ → σ → σ := fun a cf cg hf hg => co a (cf, cg, hf, hg)
PC✝ : α → Code → Code → σ → σ → σ := fun a cf cg hf hg => pc a (cf, cg, hf, hg)
RF✝ : α → Code → σ → σ := fun a cf hf => rf a (cf, hf)
F : α → Code → σ := fun a c => Code.recOn c (z a) (s a) (l a) (r a) (PR✝ a) (CO✝ a) (PC✝ a) (RF✝ a)
G₁ : (α × List σ) × ℕ × ℕ → Option σ :=
  fun p =>
    let a := p.fst.fst;
    let IH := p.fst.snd;
    let n := p.snd.fst;
    let m := p.snd.snd;
    Option.bind (List.get? IH m) fun s =>
      Option.bind (List.get? IH (unpair m).fst) fun s₁ =>
        Option.map
          (fun s₂ =>
            bif bodd n then
              bif bodd (div2 n) then rf a (ofNat Code m, s)
              else pc a (ofNat Code (unpair m).fst, ofNat Code (unpair m).snd, s₁, s₂)
            else
              bif bodd (div2 n) then co a (ofNat Code (unpair m).fst, ofNat Code (unpair m).snd, s₁, s₂)
              else pr a (ofNat Code (unpair m).fst, ofNat Code (unpair m).snd, s₁, s₂))
          (List.get? IH (unpair m).snd)
a : Computable fun p => p.fst.fst.fst.fst.fst
n : Computable fun p => p.fst.fst.fst.snd.fst
m : Computable fun p => p.fst.fst.fst.snd.snd
⊢ Computable₂ fun p s₂ =>
    bif bodd p.fst.fst.snd.fst then
      bif bodd (div2 p.fst.fst.snd.fst) then rf p.fst.fst.fst.fst (ofNat Code p.fst.fst.snd.snd, p.fst.snd)
      else
        pc p.fst.fst.fst.fst
          (ofNat Code (unpair p.fst.fst.snd.snd).fst, ofNat Code (unpair p.fst.fst.snd.snd).snd, p.snd, s₂)
    else
      bif bodd (div2 p.fst.fst.snd.fst) then
        co p.fst.fst.fst.fst
          (ofNat Code (unpair p.fst.fst.snd.snd).fst, ofNat Code (unpair p.fst.fst.snd.snd).snd, p.snd, s₂)
      else
        pr p.fst.fst.fst.fst
          (ofNat Code (unpair p.fst.fst.snd.snd).fst, ofNat Code (unpair p.fst.fst.snd.snd).snd, p.snd, s₂)

tactic: have m₂ := snd.comp (Computable.unpair.comp m)
state_before: α : Type u_1
σ : Type u_2
inst✝¹ : Primcodable α
inst✝ : Primcodable σ
c : α → Code
hc : Computable c
z : α → σ
hz : Computable z
s : α → σ
hs : Computable s
l : α → σ
hl : Computable l
r : α → σ
hr : Computable r
pr : α → Code × Code × σ × σ → σ
hpr : Computable₂ pr
co : α → Code × Code × σ × σ → σ
hco : Computable₂ co
pc : α → Code × Code × σ × σ → σ
hpc : Computable₂ pc
rf : α → Code × σ → σ
hrf : Computable₂ rf
PR✝ : α → Code → Code → σ → σ → σ := fun a cf cg hf hg => pr a (cf, cg, hf, hg)
CO✝ : α → Code → Code → σ → σ → σ := fun a cf cg hf hg => co a (cf, cg, hf, hg)
PC✝ : α → Code → Code → σ → σ → σ := fun a cf cg hf hg => pc a (cf, cg, hf, hg)
RF✝ : α → Code → σ → σ := fun a cf hf => rf a (cf, hf)
F : α → Code → σ := fun a c => Code.recOn c (z a) (s a) (l a) (r a) (PR✝ a) (CO✝ a) (PC✝ a) (RF✝ a)
G₁ : (α × List σ) × ℕ × ℕ → Option σ :=
  fun p =>
    let a := p.fst.fst;
    let IH := p.fst.snd;
    let n := p.snd.fst;
    let m := p.snd.snd;
    Option.bind (List.get? IH m) fun s =>
      Option.bind (List.get? IH (unpair m).fst) fun s₁ =>
        Option.map
          (fun s₂ =>
            bif bodd n then
              bif bodd (div2 n) then rf a (ofNat Code m, s)
              else pc a (ofNat Code (unpair m).fst, ofNat Code (unpair m).snd, s₁, s₂)
            else
              bif bodd (div2 n) then co a (ofNat Code (unpair m).fst, ofNat Code (unpair m).snd, s₁, s₂)
              else pr a (ofNat Code (unpair m).fst, ofNat Code (unpair m).snd, s₁, s₂))
          (List.get? IH (unpair m).snd)
a : Computable fun p => p.fst.fst.fst.fst.fst
n : Computable fun p => p.fst.fst.fst.snd.fst
m : Computable fun p => p.fst.fst.fst.snd.snd
m₁ : Computable fun a => (unpair a.fst.fst.fst.snd.snd).fst
⊢ Computable₂ fun p s₂ =>
    bif bodd p.fst.fst.snd.fst then
      bif bodd (div2 p.fst.fst.snd.fst) then rf p.fst.fst.fst.fst (ofNat Code p.fst.fst.snd.snd, p.fst.snd)
      else
        pc p.fst.fst.fst.fst
          (ofNat Code (unpair p.fst.fst.snd.snd).fst, ofNat Code (unpair p.fst.fst.snd.snd).snd, p.snd, s₂)
    else
      bif bodd (div2 p.fst.fst.snd.fst) then
        co p.fst.fst.fst.fst
          (ofNat Code (unpair p.fst.fst.snd.snd).fst, ofNat Code (unpair p.fst.fst.snd.snd).snd, p.snd, s₂)
      else
        pr p.fst.fst.fst.fst
          (ofNat Code (unpair p.fst.fst.snd.snd).fst, ofNat Code (unpair p.fst.fst.snd.snd).snd, p.snd, s₂)

tactic: have s : Computable (fun p : ((((α × List σ) × ℕ × ℕ) × σ) × σ) × σ => p.1.1.2) :=
  snd.comp (fst.comp fst)
state_before: α : Type u_1
σ : Type u_2
inst✝¹ : Primcodable α
inst✝ : Primcodable σ
c : α → Code
hc : Computable c
z : α → σ
hz : Computable z
s : α → σ
hs : Computable s
l : α → σ
hl : Computable l
r : α → σ
hr : Computable r
pr : α → Code × Code × σ × σ → σ
hpr : Computable₂ pr
co : α → Code × Code × σ × σ → σ
hco : Computable₂ co
pc : α → Code × Code × σ × σ → σ
hpc : Computable₂ pc
rf : α → Code × σ → σ
hrf : Computable₂ rf
PR✝ : α → Code → Code → σ → σ → σ := fun a cf cg hf hg => pr a (cf, cg, hf, hg)
CO✝ : α → Code → Code → σ → σ → σ := fun a cf cg hf hg => co a (cf, cg, hf, hg)
PC✝ : α → Code → Code → σ → σ → σ := fun a cf cg hf hg => pc a (cf, cg, hf, hg)
RF✝ : α → Code → σ → σ := fun a cf hf => rf a (cf, hf)
F : α → Code → σ := fun a c => Code.recOn c (z a) (s a) (l a) (r a) (PR✝ a) (CO✝ a) (PC✝ a) (RF✝ a)
G₁ : (α × List σ) × ℕ × ℕ → Option σ :=
  fun p =>
    let a := p.fst.fst;
    let IH := p.fst.snd;
    let n := p.snd.fst;
    let m := p.snd.snd;
    Option.bind (List.get? IH m) fun s =>
      Option.bind (List.get? IH (unpair m).fst) fun s₁ =>
        Option.map
          (fun s₂ =>
            bif bodd n then
              bif bodd (div2 n) then rf a (ofNat Code m, s)
              else pc a (ofNat Code (unpair m).fst, ofNat Code (unpair m).snd, s₁, s₂)
            else
              bif bodd (div2 n) then co a (ofNat Code (unpair m).fst, ofNat Code (unpair m).snd, s₁, s₂)
              else pr a (ofNat Code (unpair m).fst, ofNat Code (unpair m).snd, s₁, s₂))
          (List.get? IH (unpair m).snd)
a : Computable fun p => p.fst.fst.fst.fst.fst
n : Computable fun p => p.fst.fst.fst.snd.fst
m : Computable fun p => p.fst.fst.fst.snd.snd
m₁ : Computable fun a => (unpair a.fst.fst.fst.snd.snd).fst
m₂ : Computable fun a => (unpair a.fst.fst.fst.snd.snd).snd
⊢ Computable₂ fun p s₂ =>
    bif bodd p.fst.fst.snd.fst then
      bif bodd (div2 p.fst.fst.snd.fst) then rf p.fst.fst.fst.fst (ofNat Code p.fst.fst.snd.snd, p.fst.snd)
      else
        pc p.fst.fst.fst.fst
          (ofNat Code (unpair p.fst.fst.snd.snd).fst, ofNat Code (unpair p.fst.fst.snd.snd).snd, p.snd, s₂)
    else
      bif bodd (div2 p.fst.fst.snd.fst) then
        co p.fst.fst.fst.fst
          (ofNat Code (unpair p.fst.fst.snd.snd).fst, ofNat Code (unpair p.fst.fst.snd.snd).snd, p.snd, s₂)
      else
        pr p.fst.fst.fst.fst
          (ofNat Code (unpair p.fst.fst.snd.snd).fst, ofNat Code (unpair p.fst.fst.snd.snd).snd, p.snd, s₂)

tactic: have s₁ : Computable (fun p : ((((α × List σ) × ℕ × ℕ) × σ) × σ) × σ => p.1.2) :=
  snd.comp fst
state_before: α : Type u_1
σ : Type u_2
inst✝¹ : Primcodable α
inst✝ : Primcodable σ
c : α → Code
hc : Computable c
z : α → σ
hz : Computable z
s✝ : α → σ
hs : Computable s✝
l : α → σ
hl : Computable l
r : α → σ
hr : Computable r
pr : α → Code × Code × σ × σ → σ
hpr : Computable₂ pr
co : α → Code × Code × σ × σ → σ
hco : Computable₂ co
pc : α → Code × Code × σ × σ → σ
hpc : Computable₂ pc
rf : α → Code × σ → σ
hrf : Computable₂ rf
PR✝ : α → Code → Code → σ → σ → σ := fun a cf cg hf hg => pr a (cf, cg, hf, hg)
CO✝ : α → Code → Code → σ → σ → σ := fun a cf cg hf hg => co a (cf, cg, hf, hg)
PC✝ : α → Code → Code → σ → σ → σ := fun a cf cg hf hg => pc a (cf, cg, hf, hg)
RF✝ : α → Code → σ → σ := fun a cf hf => rf a (cf, hf)
F : α → Code → σ := fun a c => Code.recOn c (z a) (s✝ a) (l a) (r a) (PR✝ a) (CO✝ a) (PC✝ a) (RF✝ a)
G₁ : (α × List σ) × ℕ × ℕ → Option σ :=
  fun p =>
    let a := p.fst.fst;
    let IH := p.fst.snd;
    let n := p.snd.fst;
    let m := p.snd.snd;
    Option.bind (List.get? IH m) fun s =>
      Option.bind (List.get? IH (unpair m).fst) fun s₁ =>
        Option.map
          (fun s₂ =>
            bif bodd n then
              bif bodd (div2 n) then rf a (ofNat Code m, s)
              else pc a (ofNat Code (unpair m).fst, ofNat Code (unpair m).snd, s₁, s₂)
            else
              bif bodd (div2 n) then co a (ofNat Code (unpair m).fst, ofNat Code (unpair m).snd, s₁, s₂)
              else pr a (ofNat Code (unpair m).fst, ofNat Code (unpair m).snd, s₁, s₂))
          (List.get? IH (unpair m).snd)
a : Computable fun p => p.fst.fst.fst.fst.fst
n : Computable fun p => p.fst.fst.fst.snd.fst
m : Computable fun p => p.fst.fst.fst.snd.snd
m₁ : Computable fun a => (unpair a.fst.fst.fst.snd.snd).fst
m₂ : Computable fun a => (unpair a.fst.fst.fst.snd.snd).snd
s : Computable fun p => p.fst.fst.snd
⊢ Computable₂ fun p s₂ =>
    bif bodd p.fst.fst.snd.fst then
      bif bodd (div2 p.fst.fst.snd.fst) then rf p.fst.fst.fst.fst (ofNat Code p.fst.fst.snd.snd, p.fst.snd)
      else
        pc p.fst.fst.fst.fst
          (ofNat Code (unpair p.fst.fst.snd.snd).fst, ofNat Code (unpair p.fst.fst.snd.snd).snd, p.snd, s₂)
    else
      bif bodd (div2 p.fst.fst.snd.fst) then
        co p.fst.fst.fst.fst
          (ofNat Code (unpair p.fst.fst.snd.snd).fst, ofNat Code (unpair p.fst.fst.snd.snd).snd, p.snd, s₂)
      else
        pr p.fst.fst.fst.fst
          (ofNat Code (unpair p.fst.fst.snd.snd).fst, ofNat Code (unpair p.fst.fst.snd.snd).snd, p.snd, s₂)

tactic: have s₂ : Computable (fun p : ((((α × List σ) × ℕ × ℕ) × σ) × σ) × σ => p.2) :=
  snd
state_before: α : Type u_1
σ : Type u_2
inst✝¹ : Primcodable α
inst✝ : Primcodable σ
c : α → Code
hc : Computable c
z : α → σ
hz : Computable z
s✝ : α → σ
hs : Computable s✝
l : α → σ
hl : Computable l
r : α → σ
hr : Computable r
pr : α → Code × Code × σ × σ → σ
hpr : Computable₂ pr
co : α → Code × Code × σ × σ → σ
hco : Computable₂ co
pc : α → Code × Code × σ × σ → σ
hpc : Computable₂ pc
rf : α → Code × σ → σ
hrf : Computable₂ rf
PR✝ : α → Code → Code → σ → σ → σ := fun a cf cg hf hg => pr a (cf, cg, hf, hg)
CO✝ : α → Code → Code → σ → σ → σ := fun a cf cg hf hg => co a (cf, cg, hf, hg)
PC✝ : α → Code → Code → σ → σ → σ := fun a cf cg hf hg => pc a (cf, cg, hf, hg)
RF✝ : α → Code → σ → σ := fun a cf hf => rf a (cf, hf)
F : α → Code → σ := fun a c => Code.recOn c (z a) (s✝ a) (l a) (r a) (PR✝ a) (CO✝ a) (PC✝ a) (RF✝ a)
G₁ : (α × List σ) × ℕ × ℕ → Option σ :=
  fun p =>
    let a := p.fst.fst;
    let IH := p.fst.snd;
    let n := p.snd.fst;
    let m := p.snd.snd;
    Option.bind (List.get? IH m) fun s =>
      Option.bind (List.get? IH (unpair m).fst) fun s₁ =>
        Option.map
          (fun s₂ =>
            bif bodd n then
              bif bodd (div2 n) then rf a (ofNat Code m, s)
              else pc a (ofNat Code (unpair m).fst, ofNat Code (unpair m).snd, s₁, s₂)
            else
              bif bodd (div2 n) then co a (ofNat Code (unpair m).fst, ofNat Code (unpair m).snd, s₁, s₂)
              else pr a (ofNat Code (unpair m).fst, ofNat Code (unpair m).snd, s₁, s₂))
          (List.get? IH (unpair m).snd)
a : Computable fun p => p.fst.fst.fst.fst.fst
n : Computable fun p => p.fst.fst.fst.snd.fst
m : Computable fun p => p.fst.fst.fst.snd.snd
m₁ : Computable fun a => (unpair a.fst.fst.fst.snd.snd).fst
m₂ : Computable fun a => (unpair a.fst.fst.fst.snd.snd).snd
s : Computable fun p => p.fst.fst.snd
s₁ : Computable fun p => p.fst.snd
⊢ Computable₂ fun p s₂ =>
    bif bodd p.fst.fst.snd.fst then
      bif bodd (div2 p.fst.fst.snd.fst) then rf p.fst.fst.fst.fst (ofNat Code p.fst.fst.snd.snd, p.fst.snd)
      else
        pc p.fst.fst.fst.fst
          (ofNat Code (unpair p.fst.fst.snd.snd).fst, ofNat Code (unpair p.fst.fst.snd.snd).snd, p.snd, s₂)
    else
      bif bodd (div2 p.fst.fst.snd.fst) then
        co p.fst.fst.fst.fst
          (ofNat Code (unpair p.fst.fst.snd.snd).fst, ofNat Code (unpair p.fst.fst.snd.snd).snd, p.snd, s₂)
      else
        pr p.fst.fst.fst.fst
          (ofNat Code (unpair p.fst.fst.snd.snd).fst, ofNat Code (unpair p.fst.fst.snd.snd).snd, p.snd, s₂)

tactic: exact
  (nat_bodd.comp n).cond
    ((nat_bodd.comp <| nat_div2.comp n).cond
      (hrf.comp a (((Computable.ofNat Code).comp m).pair s))
      (hpc.comp a
        (((Computable.ofNat Code).comp m₁).pair <|
          ((Computable.ofNat Code).comp m₂).pair <| s₁.pair s₂)))
    (Computable.cond (nat_bodd.comp <| nat_div2.comp n)
      (hco.comp a
        (((Computable.ofNat Code).comp m₁).pair <|
          ((Computable.ofNat Code).comp m₂).pair <| s₁.pair s₂))
      (hpr.comp a
        (((Computable.ofNat Code).comp m₁).pair <|
          ((Computable.ofNat Code).comp m₂).pair <| s₁.pair s₂)))
state_before: α : Type u_1
σ : Type u_2
inst✝¹ : Primcodable α
inst✝ : Primcodable σ
c : α → Code
hc : Computable c
z : α → σ
hz : Computable z
s✝ : α → σ
hs : Computable s✝
l : α → σ
hl : Computable l
r : α → σ
hr : Computable r
pr : α → Code × Code × σ × σ → σ
hpr : Computable₂ pr
co : α → Code × Code × σ × σ → σ
hco : Computable₂ co
pc : α → Code × Code × σ × σ → σ
hpc : Computable₂ pc
rf : α → Code × σ → σ
hrf : Computable₂ rf
PR✝ : α → Code → Code → σ → σ → σ := fun a cf cg hf hg => pr a (cf, cg, hf, hg)
CO✝ : α → Code → Code → σ → σ → σ := fun a cf cg hf hg => co a (cf, cg, hf, hg)
PC✝ : α → Code → Code → σ → σ → σ := fun a cf cg hf hg => pc a (cf, cg, hf, hg)
RF✝ : α → Code → σ → σ := fun a cf hf => rf a (cf, hf)
F : α → Code → σ := fun a c => Code.recOn c (z a) (s✝ a) (l a) (r a) (PR✝ a) (CO✝ a) (PC✝ a) (RF✝ a)
G₁ : (α × List σ) × ℕ × ℕ → Option σ :=
  fun p =>
    let a := p.fst.fst;
    let IH := p.fst.snd;
    let n := p.snd.fst;
    let m := p.snd.snd;
    Option.bind (List.get? IH m) fun s =>
      Option.bind (List.get? IH (unpair m).fst) fun s₁ =>
        Option.map
          (fun s₂ =>
            bif bodd n then
              bif bodd (div2 n) then rf a (ofNat Code m, s)
              else pc a (ofNat Code (unpair m).fst, ofNat Code (unpair m).snd, s₁, s₂)
            else
              bif bodd (div2 n) then co a (ofNat Code (unpair m).fst, ofNat Code (unpair m).snd, s₁, s₂)
              else pr a (ofNat Code (unpair m).fst, ofNat Code (unpair m).snd, s₁, s₂))
          (List.get? IH (unpair m).snd)
a : Computable fun p => p.fst.fst.fst.fst.fst
n : Computable fun p => p.fst.fst.fst.snd.fst
m : Computable fun p => p.fst.fst.fst.snd.snd
m₁ : Computable fun a => (unpair a.fst.fst.fst.snd.snd).fst
m₂ : Computable fun a => (unpair a.fst.fst.fst.snd.snd).snd
s : Computable fun p => p.fst.fst.snd
s₁ : Computable fun p => p.fst.snd
s₂ : Computable fun p => p.snd
⊢ Computable₂ fun p s₂ =>
    bif bodd p.fst.fst.snd.fst then
      bif bodd (div2 p.fst.fst.snd.fst) then rf p.fst.fst.fst.fst (ofNat Code p.fst.fst.snd.snd, p.fst.snd)
      else
        pc p.fst.fst.fst.fst
          (ofNat Code (unpair p.fst.fst.snd.snd).fst, ofNat Code (unpair p.fst.fst.snd.snd).snd, p.snd, s₂)
    else
      bif bodd (div2 p.fst.fst.snd.fst) then
        co p.fst.fst.fst.fst
          (ofNat Code (unpair p.fst.fst.snd.snd).fst, ofNat Code (unpair p.fst.fst.snd.snd).snd, p.snd, s₂)
      else
        pr p.fst.fst.fst.fst
          (ofNat Code (unpair p.fst.fst.snd.snd).fst, ofNat Code (unpair p.fst.fst.snd.snd).snd, p.snd, s₂)

tactic: simp
state_before: α : Type u_1
σ : Type u_2
inst✝¹ : Primcodable α
inst✝ : Primcodable σ
c : α → Code
hc : Computable c
z : α → σ
hz : Computable z
s : α → σ
hs : Computable s
l : α → σ
hl : Computable l
r : α → σ
hr : Computable r
pr : α → Code × Code × σ × σ → σ
hpr : Computable₂ pr
co : α → Code × Code × σ × σ → σ
hco : Computable₂ co
pc : α → Code × Code × σ × σ → σ
hpc : Computable₂ pc
rf : α → Code × σ → σ
hrf : Computable₂ rf
PR✝ : α → Code → Code → σ → σ → σ := fun a cf cg hf hg => pr a (cf, cg, hf, hg)
CO✝ : α → Code → Code → σ → σ → σ := fun a cf cg hf hg => co a (cf, cg, hf, hg)
PC✝ : α → Code → Code → σ → σ → σ := fun a cf cg hf hg => pc a (cf, cg, hf, hg)
RF✝ : α → Code → σ → σ := fun a cf hf => rf a (cf, hf)
F : α → Code → σ := fun a c => Code.recOn c (z a) (s a) (l a) (r a) (PR✝ a) (CO✝ a) (PC✝ a) (RF✝ a)
G₁ : (α × List σ) × ℕ × ℕ → Option σ :=
  fun p =>
    let a := p.fst.fst;
    let IH := p.fst.snd;
    let n := p.snd.fst;
    let m := p.snd.snd;
    Option.bind (List.get? IH m) fun s =>
      Option.bind (List.get? IH (unpair m).fst) fun s₁ =>
        Option.map
          (fun s₂ =>
            bif bodd n then
              bif bodd (div2 n) then rf a (ofNat Code m, s)
              else pc a (ofNat Code (unpair m).fst, ofNat Code (unpair m).snd, s₁, s₂)
            else
              bif bodd (div2 n) then co a (ofNat Code (unpair m).fst, ofNat Code (unpair m).snd, s₁, s₂)
              else pr a (ofNat Code (unpair m).fst, ofNat Code (unpair m).snd, s₁, s₂))
          (List.get? IH (unpair m).snd)
this✝ : Computable G₁
G : α → List σ → Option σ :=
  fun a IH =>
    Nat.casesOn (List.length IH) (some (z a)) fun n =>
      Nat.casesOn n (some (s a)) fun n =>
        Nat.casesOn n (some (l a)) fun n => Nat.casesOn n (some (r a)) fun n => G₁ ((a, IH), n, div2 (div2 n))
this : Computable₂ G
a : α
⊢ F (id a) (ofNat Code (encode (c a))) = F a (c a)

tactic: cases' n with n
state_before: case succ.succ.succ
α : Type u_1
σ : Type u_2
inst✝¹ : Primcodable α
inst✝ : Primcodable σ
c : α → Code
hc : Computable c
z : α → σ
hz : Computable z
s : α → σ
hs : Computable s
l : α → σ
hl : Computable l
r : α → σ
hr : Computable r
pr : α → Code × Code × σ × σ → σ
hpr : Computable₂ pr
co : α → Code × Code × σ × σ → σ
hco : Computable₂ co
pc : α → Code × Code × σ × σ → σ
hpc : Computable₂ pc
rf : α → Code × σ → σ
hrf : Computable₂ rf
PR✝ : α → Code → Code → σ → σ → σ := fun a cf cg hf hg => pr a (cf, cg, hf, hg)
CO✝ : α → Code → Code → σ → σ → σ := fun a cf cg hf hg => co a (cf, cg, hf, hg)
PC✝ : α → Code → Code → σ → σ → σ := fun a cf cg hf hg => pc a (cf, cg, hf, hg)
RF✝ : α → Code → σ → σ := fun a cf hf => rf a (cf, hf)
F : α → Code → σ := fun a c => Code.recOn c (z a) (s a) (l a) (r a) (PR✝ a) (CO✝ a) (PC✝ a) (RF✝ a)
G₁ : (α × List σ) × ℕ × ℕ → Option σ :=
  fun p =>
    let a := p.fst.fst;
    let IH := p.fst.snd;
    let n := p.snd.fst;
    let m := p.snd.snd;
    Option.bind (List.get? IH m) fun s =>
      Option.bind (List.get? IH (unpair m).fst) fun s₁ =>
        Option.map
          (fun s₂ =>
            bif bodd n then
              bif bodd (div2 n) then rf a (ofNat Code m, s)
              else pc a (ofNat Code (unpair m).fst, ofNat Code (unpair m).snd, s₁, s₂)
            else
              bif bodd (div2 n) then co a (ofNat Code (unpair m).fst, ofNat Code (unpair m).snd, s₁, s₂)
              else pr a (ofNat Code (unpair m).fst, ofNat Code (unpair m).snd, s₁, s₂))
          (List.get? IH (unpair m).snd)
this✝ : Computable G₁
G : α → List σ → Option σ :=
  fun a IH =>
    Nat.casesOn (List.length IH) (some (z a)) fun n =>
      Nat.casesOn n (some (s a)) fun n =>
        Nat.casesOn n (some (l a)) fun n => Nat.casesOn n (some (r a)) fun n => G₁ ((a, IH), n, div2 (div2 n))
this : Computable₂ G
a : α
n : ℕ
⊢ G a (List.map (fun n => F a (ofNat Code n)) (List.range (Nat.succ (Nat.succ (Nat.succ n))))) =
    some (F a (ofNat Code (Nat.succ (Nat.succ (Nat.succ n)))))

tactic: simp (config := { zeta := false }) [ofNatCode_eq, ofNatCode]
state_before: case succ.succ.succ.zero
α : Type u_1
σ : Type u_2
inst✝¹ : Primcodable α
inst✝ : Primcodable σ
c : α → Code
hc : Computable c
z : α → σ
hz : Computable z
s : α → σ
hs : Computable s
l : α → σ
hl : Computable l
r : α → σ
hr : Computable r
pr : α → Code × Code × σ × σ → σ
hpr : Computable₂ pr
co : α → Code × Code × σ × σ → σ
hco : Computable₂ co
pc : α → Code × Code × σ × σ → σ
hpc : Computable₂ pc
rf : α → Code × σ → σ
hrf : Computable₂ rf
PR✝ : α → Code → Code → σ → σ → σ := fun a cf cg hf hg => pr a (cf, cg, hf, hg)
CO✝ : α → Code → Code → σ → σ → σ := fun a cf cg hf hg => co a (cf, cg, hf, hg)
PC✝ : α → Code → Code → σ → σ → σ := fun a cf cg hf hg => pc a (cf, cg, hf, hg)
RF✝ : α → Code → σ → σ := fun a cf hf => rf a (cf, hf)
F : α → Code → σ := fun a c => Code.recOn c (z a) (s a) (l a) (r a) (PR✝ a) (CO✝ a) (PC✝ a) (RF✝ a)
G₁ : (α × List σ) × ℕ × ℕ → Option σ :=
  fun p =>
    let a := p.fst.fst;
    let IH := p.fst.snd;
    let n := p.snd.fst;
    let m := p.snd.snd;
    Option.bind (List.get? IH m) fun s =>
      Option.bind (List.get? IH (unpair m).fst) fun s₁ =>
        Option.map
          (fun s₂ =>
            bif bodd n then
              bif bodd (div2 n) then rf a (ofNat Code m, s)
              else pc a (ofNat Code (unpair m).fst, ofNat Code (unpair m).snd, s₁, s₂)
            else
              bif bodd (div2 n) then co a (ofNat Code (unpair m).fst, ofNat Code (unpair m).snd, s₁, s₂)
              else pr a (ofNat Code (unpair m).fst, ofNat Code (unpair m).snd, s₁, s₂))
          (List.get? IH (unpair m).snd)
this✝ : Computable G₁
G : α → List σ → Option σ :=
  fun a IH =>
    Nat.casesOn (List.length IH) (some (z a)) fun n =>
      Nat.casesOn n (some (s a)) fun n =>
        Nat.casesOn n (some (l a)) fun n => Nat.casesOn n (some (r a)) fun n => G₁ ((a, IH), n, div2 (div2 n))
this : Computable₂ G
a : α
⊢ G a (List.map (fun n => F a (ofNat Code n)) (List.range (Nat.succ (Nat.succ (Nat.succ Nat.zero))))) =
    some (F a (ofNat Code (Nat.succ (Nat.succ (Nat.succ Nat.zero)))))

tactic: rfl
state_before: case succ.succ.succ.zero
α : Type u_1
σ : Type u_2
inst✝¹ : Primcodable α
inst✝ : Primcodable σ
c : α → Code
hc : Computable c
z : α → σ
hz : Computable z
s : α → σ
hs : Computable s
l : α → σ
hl : Computable l
r : α → σ
hr : Computable r
pr : α → Code × Code × σ × σ → σ
hpr : Computable₂ pr
co : α → Code × Code × σ × σ → σ
hco : Computable₂ co
pc : α → Code × Code × σ × σ → σ
hpc : Computable₂ pc
rf : α → Code × σ → σ
hrf : Computable₂ rf
PR✝ : α → Code → Code → σ → σ → σ := fun a cf cg hf hg => pr a (cf, cg, hf, hg)
CO✝ : α → Code → Code → σ → σ → σ := fun a cf cg hf hg => co a (cf, cg, hf, hg)
PC✝ : α → Code → Code → σ → σ → σ := fun a cf cg hf hg => pc a (cf, cg, hf, hg)
RF✝ : α → Code → σ → σ := fun a cf hf => rf a (cf, hf)
F : α → Code → σ := fun a c => Code.recOn c (z a) (s a) (l a) (r a) (PR✝ a) (CO✝ a) (PC✝ a) (RF✝ a)
G₁ : (α × List σ) × ℕ × ℕ → Option σ :=
  fun p =>
    let a := p.fst.fst;
    let IH := p.fst.snd;
    let n := p.snd.fst;
    let m := p.snd.snd;
    Option.bind (List.get? IH m) fun s =>
      Option.bind (List.get? IH (unpair m).fst) fun s₁ =>
        Option.map
          (fun s₂ =>
            bif bodd n then
              bif bodd (div2 n) then rf a (ofNat Code m, s)
              else pc a (ofNat Code (unpair m).fst, ofNat Code (unpair m).snd, s₁, s₂)
            else
              bif bodd (div2 n) then co a (ofNat Code (unpair m).fst, ofNat Code (unpair m).snd, s₁, s₂)
              else pr a (ofNat Code (unpair m).fst, ofNat Code (unpair m).snd, s₁, s₂))
          (List.get? IH (unpair m).snd)
this✝ : Computable G₁
G : α → List σ → Option σ :=
  fun a IH =>
    Nat.casesOn (List.length IH) (some (z a)) fun n =>
      Nat.casesOn n (some (s a)) fun n =>
        Nat.casesOn n (some (l a)) fun n => Nat.casesOn n (some (r a)) fun n => G₁ ((a, IH), n, div2 (div2 n))
this : Computable₂ G
a : α
⊢ G a [F a zero, F a succ, F a left] = some (F a (ofNatCode (Nat.succ (Nat.succ (Nat.succ 0)))))

tactic: simp [Nat.div2_val]
state_before: α : Type u_1
σ : Type u_2
inst✝¹ : Primcodable α
inst✝ : Primcodable σ
c : α → Code
hc : Computable c
z : α → σ
hz : Computable z
s : α → σ
hs : Computable s
l : α → σ
hl : Computable l
r : α → σ
hr : Computable r
pr : α → Code × Code × σ × σ → σ
hpr : Computable₂ pr
co : α → Code × Code × σ × σ → σ
hco : Computable₂ co
pc : α → Code × Code × σ × σ → σ
hpc : Computable₂ pc
rf : α → Code × σ → σ
hrf : Computable₂ rf
PR✝ : α → Code → Code → σ → σ → σ := fun a cf cg hf hg => pr a (cf, cg, hf, hg)
CO✝ : α → Code → Code → σ → σ → σ := fun a cf cg hf hg => co a (cf, cg, hf, hg)
PC✝ : α → Code → Code → σ → σ → σ := fun a cf cg hf hg => pc a (cf, cg, hf, hg)
RF✝ : α → Code → σ → σ := fun a cf hf => rf a (cf, hf)
F : α → Code → σ := fun a c => Code.recOn c (z a) (s a) (l a) (r a) (PR✝ a) (CO✝ a) (PC✝ a) (RF✝ a)
G₁ : (α × List σ) × ℕ × ℕ → Option σ :=
  fun p =>
    let a := p.fst.fst;
    let IH := p.fst.snd;
    let n := p.snd.fst;
    let m := p.snd.snd;
    Option.bind (List.get? IH m) fun s =>
      Option.bind (List.get? IH (unpair m).fst) fun s₁ =>
        Option.map
          (fun s₂ =>
            bif bodd n then
              bif bodd (div2 n) then rf a (ofNat Code m, s)
              else pc a (ofNat Code (unpair m).fst, ofNat Code (unpair m).snd, s₁, s₂)
            else
              bif bodd (div2 n) then co a (ofNat Code (unpair m).fst, ofNat Code (unpair m).snd, s₁, s₂)
              else pr a (ofNat Code (unpair m).fst, ofNat Code (unpair m).snd, s₁, s₂))
          (List.get? IH (unpair m).snd)
this✝ : Computable G₁
G : α → List σ → Option σ :=
  fun a IH =>
    Nat.casesOn (List.length IH) (some (z a)) fun n =>
      Nat.casesOn n (some (s a)) fun n =>
        Nat.casesOn n (some (l a)) fun n => Nat.casesOn n (some (r a)) fun n => G₁ ((a, IH), n, div2 (div2 n))
this : Computable₂ G
a : α
n : ℕ
m : ℕ := div2 (div2 n)
⊢ m < n + 4

tactic: exact
  lt_of_le_of_lt (le_trans (Nat.div_le_self _ _) (Nat.div_le_self _ _))
    (Nat.succ_le_succ (Nat.le_add_right _ _))
state_before: α : Type u_1
σ : Type u_2
inst✝¹ : Primcodable α
inst✝ : Primcodable σ
c : α → Code
hc : Computable c
z : α → σ
hz : Computable z
s : α → σ
hs : Computable s
l : α → σ
hl : Computable l
r : α → σ
hr : Computable r
pr : α → Code × Code × σ × σ → σ
hpr : Computable₂ pr
co : α → Code × Code × σ × σ → σ
hco : Computable₂ co
pc : α → Code × Code × σ × σ → σ
hpc : Computable₂ pc
rf : α → Code × σ → σ
hrf : Computable₂ rf
PR✝ : α → Code → Code → σ → σ → σ := fun a cf cg hf hg => pr a (cf, cg, hf, hg)
CO✝ : α → Code → Code → σ → σ → σ := fun a cf cg hf hg => co a (cf, cg, hf, hg)
PC✝ : α → Code → Code → σ → σ → σ := fun a cf cg hf hg => pc a (cf, cg, hf, hg)
RF✝ : α → Code → σ → σ := fun a cf hf => rf a (cf, hf)
F : α → Code → σ := fun a c => Code.recOn c (z a) (s a) (l a) (r a) (PR✝ a) (CO✝ a) (PC✝ a) (RF✝ a)
G₁ : (α × List σ) × ℕ × ℕ → Option σ :=
  fun p =>
    let a := p.fst.fst;
    let IH := p.fst.snd;
    let n := p.snd.fst;
    let m := p.snd.snd;
    Option.bind (List.get? IH m) fun s =>
      Option.bind (List.get? IH (unpair m).fst) fun s₁ =>
        Option.map
          (fun s₂ =>
            bif bodd n then
              bif bodd (div2 n) then rf a (ofNat Code m, s)
              else pc a (ofNat Code (unpair m).fst, ofNat Code (unpair m).snd, s₁, s₂)
            else
              bif bodd (div2 n) then co a (ofNat Code (unpair m).fst, ofNat Code (unpair m).snd, s₁, s₂)
              else pr a (ofNat Code (unpair m).fst, ofNat Code (unpair m).snd, s₁, s₂))
          (List.get? IH (unpair m).snd)
this✝ : Computable G₁
G : α → List σ → Option σ :=
  fun a IH =>
    Nat.casesOn (List.length IH) (some (z a)) fun n =>
      Nat.casesOn n (some (s a)) fun n =>
        Nat.casesOn n (some (l a)) fun n => Nat.casesOn n (some (r a)) fun n => G₁ ((a, IH), n, div2 (div2 n))
this : Computable₂ G
a : α
n : ℕ
m : ℕ := div2 (div2 n)
⊢ n / 2 / 2 < n + 4