l3lab/ntp-mathlib huggingface dataset:
theorem evaln_complete {c n x} : x ∈ eval c n ↔ ∃ k, x ∈ evaln k c n :=
  ⟨fun h => by
    rsuffices ⟨k, h⟩ : ∃ k, x ∈ evaln (k + 1) c n
    · exact ⟨k + 1, h⟩
    induction c generalizing n x <;> simp [eval, evaln, pure, PFun.pure, Seq.seq, Bind.bind] at h ⊢
    iterate 4 exact ⟨⟨_, le_rfl⟩, h.symm⟩
    case pair cf cg hf hg =>
      rcases h with ⟨x, hx, y, hy, rfl⟩
      rcases hf hx with ⟨k₁, hk₁⟩; rcases hg hy with ⟨k₂, hk₂⟩
      refine' ⟨max k₁ k₂, _⟩
      refine'
        ⟨le_max_of_le_left <| Nat.le_of_lt_succ <| evaln_bound hk₁, _,
          evaln_mono (Nat.succ_le_succ <| le_max_left _ _) hk₁, _,
          evaln_mono (Nat.succ_le_succ <| le_max_right _ _) hk₂, rfl⟩
    case comp cf cg hf hg =>
      rcases h with ⟨y, hy, hx⟩
      rcases hg hy with ⟨k₁, hk₁⟩; rcases hf hx with ⟨k₂, hk₂⟩
      refine' ⟨max k₁ k₂, _⟩
      exact
        ⟨le_max_of_le_left <| Nat.le_of_lt_succ <| evaln_bound hk₁, _,
          evaln_mono (Nat.succ_le_succ <| le_max_left _ _) hk₁,
          evaln_mono (Nat.succ_le_succ <| le_max_right _ _) hk₂⟩
    case prec cf cg hf hg =>
      revert h
      generalize n.unpair.1 = n₁; generalize n.unpair.2 = n₂
      induction' n₂ with m IH generalizing x n <;> simp
      · intro h
        rcases hf h with ⟨k, hk⟩
        exact ⟨_, le_max_left _ _, evaln_mono (Nat.succ_le_succ <| le_max_right _ _) hk⟩
      · intro y hy hx
        rcases IH hy with ⟨k₁, nk₁, hk₁⟩
        rcases hg hx with ⟨k₂, hk₂⟩
        refine'
          ⟨(max k₁ k₂).succ,
            Nat.le_succ_of_le <| le_max_of_le_left <|
              le_trans (le_max_left _ (Nat.pair n₁ m)) nk₁, y,
            evaln_mono (Nat.succ_le_succ <| le_max_left _ _) _,
            evaln_mono (Nat.succ_le_succ <| Nat.le_succ_of_le <| le_max_right _ _) hk₂⟩
        simp only [evaln._eq_8, bind, unpaired, unpair_pair, Option.mem_def, Option.bind_eq_some,
          Option.guard_eq_some', exists_and_left, exists_const]
        exact ⟨le_trans (le_max_right _ _) nk₁, hk₁⟩
    case rfind' cf hf =>
      rcases h with ⟨y, ⟨hy₁, hy₂⟩, rfl⟩
      suffices ∃ k, y + n.unpair.2 ∈ evaln (k + 1) (rfind' cf) (Nat.pair n.unpair.1 n.unpair.2) by
        simpa [evaln, Bind.bind]
      revert hy₁ hy₂
      generalize n.unpair.2 = m
      intro hy₁ hy₂
      induction' y with y IH generalizing m <;> simp [evaln, Bind.bind]
      · 

Proof state:
case intro.intro.intro.zero
cf : Code
hf : ∀ {n x : ℕ}, x ∈ eval cf n → ∃ k, x ∈ evaln (k + 1) cf n
n m : ℕ
hy₁ : 0 ∈ eval cf (Nat.pair (unpair n).1 (Nat.zero + m))
hy₂ : ∀ {m_1 : ℕ}, m_1 < Nat.zero → ∃ a ∈ eval cf (Nat.pair (unpair n).1 (m_1 + m)), ¬a = 0
⊢ ∃ k,
    Nat.pair (unpair n).1 m ≤ k ∧
      ∃ a,
        evaln (k + 1) cf (Nat.pair (unpair n).1 m) = some a ∧
          (if a = 0 then pure m else evaln k (rfind' cf) (Nat.pair (unpair n).1 (m + 1))) = some m

Next tactic:
simp at hy₁
theorem evaln_complete {c n x} : x ∈ eval c n ↔ ∃ k, x ∈ evaln k c n :=
  ⟨fun h => by
    rsuffices ⟨k, h⟩ : ∃ k, x ∈ evaln (k + 1) c n
    · exact ⟨k + 1, h⟩
    induction c generalizing n x <;> simp [eval, evaln, pure, PFun.pure, Seq.seq, Bind.bind] at h ⊢
    iterate 4 exact ⟨⟨_, le_rfl⟩, h.symm⟩
    case pair cf cg hf hg =>
      rcases h with ⟨x, hx, y, hy, rfl⟩
      rcases hf hx with ⟨k₁, hk₁⟩; rcases hg hy with ⟨k₂, hk₂⟩
      refine' ⟨max k₁ k₂, _⟩
      refine'
        ⟨le_max_of_le_left <| Nat.le_of_lt_succ <| evaln_bound hk₁, _,
          evaln_mono (Nat.succ_le_succ <| le_max_left _ _) hk₁, _,
          evaln_mono (Nat.succ_le_succ <| le_max_right _ _) hk₂, rfl⟩
    case comp cf cg hf hg =>
      rcases h with ⟨y, hy, hx⟩
      rcases hg hy with ⟨k₁, hk₁⟩; rcases hf hx with ⟨k₂, hk₂⟩
      refine' ⟨max k₁ k₂, _⟩
      exact
        ⟨le_max_of_le_left <| Nat.le_of_lt_succ <| evaln_bound hk₁, _,
          evaln_mono (Nat.succ_le_succ <| le_max_left _ _) hk₁,
          evaln_mono (Nat.succ_le_succ <| le_max_right _ _) hk₂⟩
    case prec cf cg hf hg =>
      revert h
      generalize n.unpair.1 = n₁; generalize n.unpair.2 = n₂
      induction' n₂ with m IH generalizing x n <;> simp
      · intro h
        rcases hf h with ⟨k, hk⟩
        exact ⟨_, le_max_left _ _, evaln_mono (Nat.succ_le_succ <| le_max_right _ _) hk⟩
      · intro y hy hx
        rcases IH hy with ⟨k₁, nk₁, hk₁⟩
        rcases hg hx with ⟨k₂, hk₂⟩
        refine'
          ⟨(max k₁ k₂).succ,
            Nat.le_succ_of_le <| le_max_of_le_left <|
              le_trans (le_max_left _ (Nat.pair n₁ m)) nk₁, y,
            evaln_mono (Nat.succ_le_succ <| le_max_left _ _) _,
            evaln_mono (Nat.succ_le_succ <| Nat.le_succ_of_le <| le_max_right _ _) hk₂⟩
        simp only [evaln._eq_8, bind, unpaired, unpair_pair, Option.mem_def, Option.bind_eq_some,
          Option.guard_eq_some', exists_and_left, exists_const]
        exact ⟨le_trans (le_max_right _ _) nk₁, hk₁⟩
    case rfind' cf hf =>
      rcases h with ⟨y, ⟨hy₁, hy₂⟩, rfl⟩
      suffices ∃ k, y + n.unpair.2 ∈ evaln (k + 1) (rfind' cf) (Nat.pair n.unpair.1 n.unpair.2) by
        simpa [evaln, Bind.bind]
      revert hy₁ hy₂
      generalize n.unpair.2 = m
      intro hy₁ hy₂
      induction' y with y IH generalizing m <;> simp [evaln, Bind.bind]
      · simp at hy₁
        

Proof state:
case intro.intro.intro.zero
cf : Code
hf : ∀ {n x : ℕ}, x ∈ eval cf n → ∃ k, x ∈ evaln (k + 1) cf n
n m : ℕ
hy₂ : ∀ {m_1 : ℕ}, m_1 < Nat.zero → ∃ a ∈ eval cf (Nat.pair (unpair n).1 (m_1 + m)), ¬a = 0
hy₁ : 0 ∈ eval cf (Nat.pair (unpair n).1 m)
⊢ ∃ k,
    Nat.pair (unpair n).1 m ≤ k ∧
      ∃ a,
        evaln (k + 1) cf (Nat.pair (unpair n).1 m) = some a ∧
          (if a = 0 then pure m else evaln k (rfind' cf) (Nat.pair (unpair n).1 (m + 1))) = some m

Next tactic:
rcases hf hy₁ with ⟨k, hk⟩
theorem evaln_complete {c n x} : x ∈ eval c n ↔ ∃ k, x ∈ evaln k c n :=
  ⟨fun h => by
    rsuffices ⟨k, h⟩ : ∃ k, x ∈ evaln (k + 1) c n
    · exact ⟨k + 1, h⟩
    induction c generalizing n x <;> simp [eval, evaln, pure, PFun.pure, Seq.seq, Bind.bind] at h ⊢
    iterate 4 exact ⟨⟨_, le_rfl⟩, h.symm⟩
    case pair cf cg hf hg =>
      rcases h with ⟨x, hx, y, hy, rfl⟩
      rcases hf hx with ⟨k₁, hk₁⟩; rcases hg hy with ⟨k₂, hk₂⟩
      refine' ⟨max k₁ k₂, _⟩
      refine'
        ⟨le_max_of_le_left <| Nat.le_of_lt_succ <| evaln_bound hk₁, _,
          evaln_mono (Nat.succ_le_succ <| le_max_left _ _) hk₁, _,
          evaln_mono (Nat.succ_le_succ <| le_max_right _ _) hk₂, rfl⟩
    case comp cf cg hf hg =>
      rcases h with ⟨y, hy, hx⟩
      rcases hg hy with ⟨k₁, hk₁⟩; rcases hf hx with ⟨k₂, hk₂⟩
      refine' ⟨max k₁ k₂, _⟩
      exact
        ⟨le_max_of_le_left <| Nat.le_of_lt_succ <| evaln_bound hk₁, _,
          evaln_mono (Nat.succ_le_succ <| le_max_left _ _) hk₁,
          evaln_mono (Nat.succ_le_succ <| le_max_right _ _) hk₂⟩
    case prec cf cg hf hg =>
      revert h
      generalize n.unpair.1 = n₁; generalize n.unpair.2 = n₂
      induction' n₂ with m IH generalizing x n <;> simp
      · intro h
        rcases hf h with ⟨k, hk⟩
        exact ⟨_, le_max_left _ _, evaln_mono (Nat.succ_le_succ <| le_max_right _ _) hk⟩
      · intro y hy hx
        rcases IH hy with ⟨k₁, nk₁, hk₁⟩
        rcases hg hx with ⟨k₂, hk₂⟩
        refine'
          ⟨(max k₁ k₂).succ,
            Nat.le_succ_of_le <| le_max_of_le_left <|
              le_trans (le_max_left _ (Nat.pair n₁ m)) nk₁, y,
            evaln_mono (Nat.succ_le_succ <| le_max_left _ _) _,
            evaln_mono (Nat.succ_le_succ <| Nat.le_succ_of_le <| le_max_right _ _) hk₂⟩
        simp only [evaln._eq_8, bind, unpaired, unpair_pair, Option.mem_def, Option.bind_eq_some,
          Option.guard_eq_some', exists_and_left, exists_const]
        exact ⟨le_trans (le_max_right _ _) nk₁, hk₁⟩
    case rfind' cf hf =>
      rcases h with ⟨y, ⟨hy₁, hy₂⟩, rfl⟩
      suffices ∃ k, y + n.unpair.2 ∈ evaln (k + 1) (rfind' cf) (Nat.pair n.unpair.1 n.unpair.2) by
        simpa [evaln, Bind.bind]
      revert hy₁ hy₂
      generalize n.unpair.2 = m
      intro hy₁ hy₂
      induction' y with y IH generalizing m <;> simp [evaln, Bind.bind]
      · simp at hy₁
        rcases hf hy₁ with ⟨k, hk⟩
        

Proof state:
case intro.intro.intro.zero.intro
cf : Code
hf : ∀ {n x : ℕ}, x ∈ eval cf n → ∃ k, x ∈ evaln (k + 1) cf n
n m : ℕ
hy₂ : ∀ {m_1 : ℕ}, m_1 < Nat.zero → ∃ a ∈ eval cf (Nat.pair (unpair n).1 (m_1 + m)), ¬a = 0
hy₁ : 0 ∈ eval cf (Nat.pair (unpair n).1 m)
k : ℕ
hk : 0 ∈ evaln (k + 1) cf (Nat.pair (unpair n).1 m)
⊢ ∃ k,
    Nat.pair (unpair n).1 m ≤ k ∧
      ∃ a,
        evaln (k + 1) cf (Nat.pair (unpair n).1 m) = some a ∧
          (if a = 0 then pure m else evaln k (rfind' cf) (Nat.pair (unpair n).1 (m + 1))) = some m

Next tactic:
exact ⟨_, Nat.le_of_lt_succ <| evaln_bound hk, _, hk, by simp; rfl⟩
theorem evaln_complete {c n x} : x ∈ eval c n ↔ ∃ k, x ∈ evaln k c n :=
  ⟨fun h => by
    rsuffices ⟨k, h⟩ : ∃ k, x ∈ evaln (k + 1) c n
    · exact ⟨k + 1, h⟩
    induction c generalizing n x <;> simp [eval, evaln, pure, PFun.pure, Seq.seq, Bind.bind] at h ⊢
    iterate 4 exact ⟨⟨_, le_rfl⟩, h.symm⟩
    case pair cf cg hf hg =>
      rcases h with ⟨x, hx, y, hy, rfl⟩
      rcases hf hx with ⟨k₁, hk₁⟩; rcases hg hy with ⟨k₂, hk₂⟩
      refine' ⟨max k₁ k₂, _⟩
      refine'
        ⟨le_max_of_le_left <| Nat.le_of_lt_succ <| evaln_bound hk₁, _,
          evaln_mono (Nat.succ_le_succ <| le_max_left _ _) hk₁, _,
          evaln_mono (Nat.succ_le_succ <| le_max_right _ _) hk₂, rfl⟩
    case comp cf cg hf hg =>
      rcases h with ⟨y, hy, hx⟩
      rcases hg hy with ⟨k₁, hk₁⟩; rcases hf hx with ⟨k₂, hk₂⟩
      refine' ⟨max k₁ k₂, _⟩
      exact
        ⟨le_max_of_le_left <| Nat.le_of_lt_succ <| evaln_bound hk₁, _,
          evaln_mono (Nat.succ_le_succ <| le_max_left _ _) hk₁,
          evaln_mono (Nat.succ_le_succ <| le_max_right _ _) hk₂⟩
    case prec cf cg hf hg =>
      revert h
      generalize n.unpair.1 = n₁; generalize n.unpair.2 = n₂
      induction' n₂ with m IH generalizing x n <;> simp
      · intro h
        rcases hf h with ⟨k, hk⟩
        exact ⟨_, le_max_left _ _, evaln_mono (Nat.succ_le_succ <| le_max_right _ _) hk⟩
      · intro y hy hx
        rcases IH hy with ⟨k₁, nk₁, hk₁⟩
        rcases hg hx with ⟨k₂, hk₂⟩
        refine'
          ⟨(max k₁ k₂).succ,
            Nat.le_succ_of_le <| le_max_of_le_left <|
              le_trans (le_max_left _ (Nat.pair n₁ m)) nk₁, y,
            evaln_mono (Nat.succ_le_succ <| le_max_left _ _) _,
            evaln_mono (Nat.succ_le_succ <| Nat.le_succ_of_le <| le_max_right _ _) hk₂⟩
        simp only [evaln._eq_8, bind, unpaired, unpair_pair, Option.mem_def, Option.bind_eq_some,
          Option.guard_eq_some', exists_and_left, exists_const]
        exact ⟨le_trans (le_max_right _ _) nk₁, hk₁⟩
    case rfind' cf hf =>
      rcases h with ⟨y, ⟨hy₁, hy₂⟩, rfl⟩
      suffices ∃ k, y + n.unpair.2 ∈ evaln (k + 1) (rfind' cf) (Nat.pair n.unpair.1 n.unpair.2) by
        simpa [evaln, Bind.bind]
      revert hy₁ hy₂
      generalize n.unpair.2 = m
      intro hy₁ hy₂
      induction' y with y IH generalizing m <;> simp [evaln, Bind.bind]
      · simp at hy₁
        rcases hf hy₁ with ⟨k, hk⟩
        exact ⟨_, Nat.le_of_lt_succ <| evaln_bound hk, _, hk, by 

Proof state:
cf : Code
hf : ∀ {n x : ℕ}, x ∈ eval cf n → ∃ k, x ∈ evaln (k + 1) cf n
n m : ℕ
hy₂ : ∀ {m_1 : ℕ}, m_1 < Nat.zero → ∃ a ∈ eval cf (Nat.pair (unpair n).1 (m_1 + m)), ¬a = 0
hy₁ : 0 ∈ eval cf (Nat.pair (unpair n).1 m)
k : ℕ
hk : 0 ∈ evaln (k + 1) cf (Nat.pair (unpair n).1 m)
⊢ (if 0 = 0 then pure m else evaln k (rfind' cf) (Nat.pair (unpair n).1 (m + 1))) = some m

Next tactic:
simp
theorem evaln_complete {c n x} : x ∈ eval c n ↔ ∃ k, x ∈ evaln k c n :=
  ⟨fun h => by
    rsuffices ⟨k, h⟩ : ∃ k, x ∈ evaln (k + 1) c n
    · exact ⟨k + 1, h⟩
    induction c generalizing n x <;> simp [eval, evaln, pure, PFun.pure, Seq.seq, Bind.bind] at h ⊢
    iterate 4 exact ⟨⟨_, le_rfl⟩, h.symm⟩
    case pair cf cg hf hg =>
      rcases h with ⟨x, hx, y, hy, rfl⟩
      rcases hf hx with ⟨k₁, hk₁⟩; rcases hg hy with ⟨k₂, hk₂⟩
      refine' ⟨max k₁ k₂, _⟩
      refine'
        ⟨le_max_of_le_left <| Nat.le_of_lt_succ <| evaln_bound hk₁, _,
          evaln_mono (Nat.succ_le_succ <| le_max_left _ _) hk₁, _,
          evaln_mono (Nat.succ_le_succ <| le_max_right _ _) hk₂, rfl⟩
    case comp cf cg hf hg =>
      rcases h with ⟨y, hy, hx⟩
      rcases hg hy with ⟨k₁, hk₁⟩; rcases hf hx with ⟨k₂, hk₂⟩
      refine' ⟨max k₁ k₂, _⟩
      exact
        ⟨le_max_of_le_left <| Nat.le_of_lt_succ <| evaln_bound hk₁, _,
          evaln_mono (Nat.succ_le_succ <| le_max_left _ _) hk₁,
          evaln_mono (Nat.succ_le_succ <| le_max_right _ _) hk₂⟩
    case prec cf cg hf hg =>
      revert h
      generalize n.unpair.1 = n₁; generalize n.unpair.2 = n₂
      induction' n₂ with m IH generalizing x n <;> simp
      · intro h
        rcases hf h with ⟨k, hk⟩
        exact ⟨_, le_max_left _ _, evaln_mono (Nat.succ_le_succ <| le_max_right _ _) hk⟩
      · intro y hy hx
        rcases IH hy with ⟨k₁, nk₁, hk₁⟩
        rcases hg hx with ⟨k₂, hk₂⟩
        refine'
          ⟨(max k₁ k₂).succ,
            Nat.le_succ_of_le <| le_max_of_le_left <|
              le_trans (le_max_left _ (Nat.pair n₁ m)) nk₁, y,
            evaln_mono (Nat.succ_le_succ <| le_max_left _ _) _,
            evaln_mono (Nat.succ_le_succ <| Nat.le_succ_of_le <| le_max_right _ _) hk₂⟩
        simp only [evaln._eq_8, bind, unpaired, unpair_pair, Option.mem_def, Option.bind_eq_some,
          Option.guard_eq_some', exists_and_left, exists_const]
        exact ⟨le_trans (le_max_right _ _) nk₁, hk₁⟩
    case rfind' cf hf =>
      rcases h with ⟨y, ⟨hy₁, hy₂⟩, rfl⟩
      suffices ∃ k, y + n.unpair.2 ∈ evaln (k + 1) (rfind' cf) (Nat.pair n.unpair.1 n.unpair.2) by
        simpa [evaln, Bind.bind]
      revert hy₁ hy₂
      generalize n.unpair.2 = m
      intro hy₁ hy₂
      induction' y with y IH generalizing m <;> simp [evaln, Bind.bind]
      · simp at hy₁
        rcases hf hy₁ with ⟨k, hk⟩
        exact ⟨_, Nat.le_of_lt_succ <| evaln_bound hk, _, hk, by simp; 

Proof state:
cf : Code
hf : ∀ {n x : ℕ}, x ∈ eval cf n → ∃ k, x ∈ evaln (k + 1) cf n
n m : ℕ
hy₂ : ∀ {m_1 : ℕ}, m_1 < Nat.zero → ∃ a ∈ eval cf (Nat.pair (unpair n).1 (m_1 + m)), ¬a = 0
hy₁ : 0 ∈ eval cf (Nat.pair (unpair n).1 m)
k : ℕ
hk : 0 ∈ evaln (k + 1) cf (Nat.pair (unpair n).1 m)
⊢ pure m = some m

Next tactic:
rfl
private theorem hG : Primrec G := by
  

Proof state:
⊢ Primrec Nat.Partrec.Code.G

Next tactic:
have a := (Primrec.ofNat (ℕ × Code)).comp (Primrec.list_length (α := List (Option ℕ)))
private theorem hG : Primrec G := by
  have a := (Primrec.ofNat (ℕ × Code)).comp (Primrec.list_length (α := List (Option ℕ)))
  

Proof state:
a : Primrec fun a => ofNat (ℕ × Code) (List.length a)
⊢ Primrec Nat.Partrec.Code.G

Next tactic:
have k := Primrec.fst.comp a
private theorem hG : Primrec G := by
  have a := (Primrec.ofNat (ℕ × Code)).comp (Primrec.list_length (α := List (Option ℕ)))
  have k := Primrec.fst.comp a
  

Proof state:
a : Primrec fun a => ofNat (ℕ × Code) (List.length a)
k : Primrec fun a => (ofNat (ℕ × Code) (List.length a)).1
⊢ Primrec Nat.Partrec.Code.G

Next tactic:
refine' Primrec.option_some.comp (Primrec.list_map (Primrec.list_range.comp k) (_ : Primrec _))
private theorem hG : Primrec G := by
  have a := (Primrec.ofNat (ℕ × Code)).comp (Primrec.list_length (α := List (Option ℕ)))
  have k := Primrec.fst.comp a
  refine' Primrec.option_some.comp (Primrec.list_map (Primrec.list_range.comp k) (_ : Primrec _))
  

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

Next tactic:
replace k := k.comp (Primrec.fst (β := ℕ))
private theorem hG : Primrec G := by
  have a := (Primrec.ofNat (ℕ × Code)).comp (Primrec.list_length (α := List (Option ℕ)))
  have k := Primrec.fst.comp a
  refine' Primrec.option_some.comp (Primrec.list_map (Primrec.list_range.comp k) (_ : Primrec _))
  replace k := k.comp (Primrec.fst (β := ℕ))
  

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

Next tactic:
have n := Primrec.snd (α := List (List (Option ℕ))) (β := ℕ)
private theorem hG : Primrec G := by
  have a := (Primrec.ofNat (ℕ × Code)).comp (Primrec.list_length (α := List (Option ℕ)))
  have k := Primrec.fst.comp a
  refine' Primrec.option_some.comp (Primrec.list_map (Primrec.list_range.comp k) (_ : Primrec _))
  replace k := k.comp (Primrec.fst (β := ℕ))
  have n := Primrec.snd (α := List (List (Option ℕ))) (β := ℕ)
  

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

Next tactic:
refine' Primrec.nat_casesOn k (_root_.Primrec.const Option.none) (_ : Primrec _)
private theorem hG : Primrec G := by
  have a := (Primrec.ofNat (ℕ × Code)).comp (Primrec.list_length (α := List (Option ℕ)))
  have k := Primrec.fst.comp a
  refine' Primrec.option_some.comp (Primrec.list_map (Primrec.list_range.comp k) (_ : Primrec _))
  replace k := k.comp (Primrec.fst (β := ℕ))
  have n := Primrec.snd (α := List (List (Option ℕ))) (β := ℕ)
  refine' Primrec.nat_casesOn k (_root_.Primrec.const Option.none) (_ : Primrec _)
  

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

Next tactic:
have k := k.comp (Primrec.fst (β := ℕ))