l3lab/ntp-mathlib huggingface dataset:
/-- A function is partial recursive if and only if there is a code implementing it. -/
theorem exists_code {f : ℕ →. ℕ} : Nat.Partrec f ↔ ∃ c : Code, eval c = f :=
  ⟨fun h => by
    induction h
    case zero => exact ⟨zero, rfl⟩
    case succ => exact ⟨succ, rfl⟩
    case left => exact ⟨left, rfl⟩
    case right => exact ⟨right, rfl⟩
    case pair f g pf pg hf hg =>
      rcases hf with ⟨cf, rfl⟩; rcases hg with ⟨cg, rfl⟩
      exact ⟨pair cf cg, rfl⟩
    case comp f g pf pg hf hg =>
      rcases hf with ⟨cf, rfl⟩; rcases hg with ⟨cg, rfl⟩
      exact ⟨comp cf cg, rfl⟩
    case prec f g pf pg hf hg =>
      rcases hf with ⟨cf, rfl⟩; rcases hg with ⟨cg, rfl⟩
      exact ⟨prec cf cg, rfl⟩
    case rfind f pf hf =>
      rcases hf with ⟨cf, rfl⟩
      refine' ⟨comp (rfind' cf) (pair Code.id zero), _⟩
      simp [eval, Seq.seq, pure, PFun.pure, Part.map_id'],
    fun h => by
    rcases h with ⟨c, rfl⟩; induction c
    case zero => exact Nat.Partrec.zero
    case succ => exact Nat.Partrec.succ
    case left => exact Nat.Partrec.left
    case right => exact Nat.Partrec.right
    

Proof state:
case intro.pair
a✝¹ a✝ : Code
a_ih✝¹ : Partrec (eval a✝¹)
a_ih✝ : Partrec (eval a✝)
⊢ Partrec (eval (pair a✝¹ a✝))
case intro.comp
a✝¹ a✝ : Code
a_ih✝¹ : Partrec (eval a✝¹)
a_ih✝ : Partrec (eval a✝)
⊢ Partrec (eval (comp a✝¹ a✝))
case intro.prec
a✝¹ a✝ : Code
a_ih✝¹ : Partrec (eval a✝¹)
a_ih✝ : Partrec (eval a✝)
⊢ Partrec (eval (prec a✝¹ a✝))
case intro.rfind' a✝ : Code a_ih✝ : Partrec (eval a✝) ⊢ Partrec (eval (rfind' a✝))

Next tactic:
case pair cf cg pf pg => exact pf.pair pg
/-- A function is partial recursive if and only if there is a code implementing it. -/
theorem exists_code {f : ℕ →. ℕ} : Nat.Partrec f ↔ ∃ c : Code, eval c = f :=
  ⟨fun h => by
    induction h
    case zero => exact ⟨zero, rfl⟩
    case succ => exact ⟨succ, rfl⟩
    case left => exact ⟨left, rfl⟩
    case right => exact ⟨right, rfl⟩
    case pair f g pf pg hf hg =>
      rcases hf with ⟨cf, rfl⟩; rcases hg with ⟨cg, rfl⟩
      exact ⟨pair cf cg, rfl⟩
    case comp f g pf pg hf hg =>
      rcases hf with ⟨cf, rfl⟩; rcases hg with ⟨cg, rfl⟩
      exact ⟨comp cf cg, rfl⟩
    case prec f g pf pg hf hg =>
      rcases hf with ⟨cf, rfl⟩; rcases hg with ⟨cg, rfl⟩
      exact ⟨prec cf cg, rfl⟩
    case rfind f pf hf =>
      rcases hf with ⟨cf, rfl⟩
      refine' ⟨comp (rfind' cf) (pair Code.id zero), _⟩
      simp [eval, Seq.seq, pure, PFun.pure, Part.map_id'],
    fun h => by
    rcases h with ⟨c, rfl⟩; induction c
    case zero => exact Nat.Partrec.zero
    case succ => exact Nat.Partrec.succ
    case left => exact Nat.Partrec.left
    case right => exact Nat.Partrec.right
    

Proof state:
cf cg : Code
pf : Partrec (eval cf)
pg : Partrec (eval cg)
⊢ Partrec (eval (pair cf cg))

Next tactic:
case pair cf cg pf pg => exact pf.pair pg
/-- A function is partial recursive if and only if there is a code implementing it. -/
theorem exists_code {f : ℕ →. ℕ} : Nat.Partrec f ↔ ∃ c : Code, eval c = f :=
  ⟨fun h => by
    induction h
    case zero => exact ⟨zero, rfl⟩
    case succ => exact ⟨succ, rfl⟩
    case left => exact ⟨left, rfl⟩
    case right => exact ⟨right, rfl⟩
    case pair f g pf pg hf hg =>
      rcases hf with ⟨cf, rfl⟩; rcases hg with ⟨cg, rfl⟩
      exact ⟨pair cf cg, rfl⟩
    case comp f g pf pg hf hg =>
      rcases hf with ⟨cf, rfl⟩; rcases hg with ⟨cg, rfl⟩
      exact ⟨comp cf cg, rfl⟩
    case prec f g pf pg hf hg =>
      rcases hf with ⟨cf, rfl⟩; rcases hg with ⟨cg, rfl⟩
      exact ⟨prec cf cg, rfl⟩
    case rfind f pf hf =>
      rcases hf with ⟨cf, rfl⟩
      refine' ⟨comp (rfind' cf) (pair Code.id zero), _⟩
      simp [eval, Seq.seq, pure, PFun.pure, Part.map_id'],
    fun h => by
    rcases h with ⟨c, rfl⟩; induction c
    case zero => exact Nat.Partrec.zero
    case succ => exact Nat.Partrec.succ
    case left => exact Nat.Partrec.left
    case right => exact Nat.Partrec.right
    case pair cf cg pf pg => 

Proof state:
cf cg : Code
pf : Partrec (eval cf)
pg : Partrec (eval cg)
⊢ Partrec (eval (pair cf cg))

Next tactic:
exact pf.pair pg
/-- A function is partial recursive if and only if there is a code implementing it. -/
theorem exists_code {f : ℕ →. ℕ} : Nat.Partrec f ↔ ∃ c : Code, eval c = f :=
  ⟨fun h => by
    induction h
    case zero => exact ⟨zero, rfl⟩
    case succ => exact ⟨succ, rfl⟩
    case left => exact ⟨left, rfl⟩
    case right => exact ⟨right, rfl⟩
    case pair f g pf pg hf hg =>
      rcases hf with ⟨cf, rfl⟩; rcases hg with ⟨cg, rfl⟩
      exact ⟨pair cf cg, rfl⟩
    case comp f g pf pg hf hg =>
      rcases hf with ⟨cf, rfl⟩; rcases hg with ⟨cg, rfl⟩
      exact ⟨comp cf cg, rfl⟩
    case prec f g pf pg hf hg =>
      rcases hf with ⟨cf, rfl⟩; rcases hg with ⟨cg, rfl⟩
      exact ⟨prec cf cg, rfl⟩
    case rfind f pf hf =>
      rcases hf with ⟨cf, rfl⟩
      refine' ⟨comp (rfind' cf) (pair Code.id zero), _⟩
      simp [eval, Seq.seq, pure, PFun.pure, Part.map_id'],
    fun h => by
    rcases h with ⟨c, rfl⟩; induction c
    case zero => exact Nat.Partrec.zero
    case succ => exact Nat.Partrec.succ
    case left => exact Nat.Partrec.left
    case right => exact Nat.Partrec.right
    case pair cf cg pf pg => exact pf.pair pg
    

Proof state:
case intro.comp
a✝¹ a✝ : Code
a_ih✝¹ : Partrec (eval a✝¹)
a_ih✝ : Partrec (eval a✝)
⊢ Partrec (eval (comp a✝¹ a✝))
case intro.prec
a✝¹ a✝ : Code
a_ih✝¹ : Partrec (eval a✝¹)
a_ih✝ : Partrec (eval a✝)
⊢ Partrec (eval (prec a✝¹ a✝))
case intro.rfind' a✝ : Code a_ih✝ : Partrec (eval a✝) ⊢ Partrec (eval (rfind' a✝))

Next tactic:
case comp cf cg pf pg => exact pf.comp pg
/-- A function is partial recursive if and only if there is a code implementing it. -/
theorem exists_code {f : ℕ →. ℕ} : Nat.Partrec f ↔ ∃ c : Code, eval c = f :=
  ⟨fun h => by
    induction h
    case zero => exact ⟨zero, rfl⟩
    case succ => exact ⟨succ, rfl⟩
    case left => exact ⟨left, rfl⟩
    case right => exact ⟨right, rfl⟩
    case pair f g pf pg hf hg =>
      rcases hf with ⟨cf, rfl⟩; rcases hg with ⟨cg, rfl⟩
      exact ⟨pair cf cg, rfl⟩
    case comp f g pf pg hf hg =>
      rcases hf with ⟨cf, rfl⟩; rcases hg with ⟨cg, rfl⟩
      exact ⟨comp cf cg, rfl⟩
    case prec f g pf pg hf hg =>
      rcases hf with ⟨cf, rfl⟩; rcases hg with ⟨cg, rfl⟩
      exact ⟨prec cf cg, rfl⟩
    case rfind f pf hf =>
      rcases hf with ⟨cf, rfl⟩
      refine' ⟨comp (rfind' cf) (pair Code.id zero), _⟩
      simp [eval, Seq.seq, pure, PFun.pure, Part.map_id'],
    fun h => by
    rcases h with ⟨c, rfl⟩; induction c
    case zero => exact Nat.Partrec.zero
    case succ => exact Nat.Partrec.succ
    case left => exact Nat.Partrec.left
    case right => exact Nat.Partrec.right
    case pair cf cg pf pg => exact pf.pair pg
    

Proof state:
cf cg : Code
pf : Partrec (eval cf)
pg : Partrec (eval cg)
⊢ Partrec (eval (comp cf cg))

Next tactic:
case comp cf cg pf pg => exact pf.comp pg
/-- A function is partial recursive if and only if there is a code implementing it. -/
theorem exists_code {f : ℕ →. ℕ} : Nat.Partrec f ↔ ∃ c : Code, eval c = f :=
  ⟨fun h => by
    induction h
    case zero => exact ⟨zero, rfl⟩
    case succ => exact ⟨succ, rfl⟩
    case left => exact ⟨left, rfl⟩
    case right => exact ⟨right, rfl⟩
    case pair f g pf pg hf hg =>
      rcases hf with ⟨cf, rfl⟩; rcases hg with ⟨cg, rfl⟩
      exact ⟨pair cf cg, rfl⟩
    case comp f g pf pg hf hg =>
      rcases hf with ⟨cf, rfl⟩; rcases hg with ⟨cg, rfl⟩
      exact ⟨comp cf cg, rfl⟩
    case prec f g pf pg hf hg =>
      rcases hf with ⟨cf, rfl⟩; rcases hg with ⟨cg, rfl⟩
      exact ⟨prec cf cg, rfl⟩
    case rfind f pf hf =>
      rcases hf with ⟨cf, rfl⟩
      refine' ⟨comp (rfind' cf) (pair Code.id zero), _⟩
      simp [eval, Seq.seq, pure, PFun.pure, Part.map_id'],
    fun h => by
    rcases h with ⟨c, rfl⟩; induction c
    case zero => exact Nat.Partrec.zero
    case succ => exact Nat.Partrec.succ
    case left => exact Nat.Partrec.left
    case right => exact Nat.Partrec.right
    case pair cf cg pf pg => exact pf.pair pg
    case comp cf cg pf pg => 

Proof state:
cf cg : Code
pf : Partrec (eval cf)
pg : Partrec (eval cg)
⊢ Partrec (eval (comp cf cg))

Next tactic:
exact pf.comp pg
/-- A function is partial recursive if and only if there is a code implementing it. -/
theorem exists_code {f : ℕ →. ℕ} : Nat.Partrec f ↔ ∃ c : Code, eval c = f :=
  ⟨fun h => by
    induction h
    case zero => exact ⟨zero, rfl⟩
    case succ => exact ⟨succ, rfl⟩
    case left => exact ⟨left, rfl⟩
    case right => exact ⟨right, rfl⟩
    case pair f g pf pg hf hg =>
      rcases hf with ⟨cf, rfl⟩; rcases hg with ⟨cg, rfl⟩
      exact ⟨pair cf cg, rfl⟩
    case comp f g pf pg hf hg =>
      rcases hf with ⟨cf, rfl⟩; rcases hg with ⟨cg, rfl⟩
      exact ⟨comp cf cg, rfl⟩
    case prec f g pf pg hf hg =>
      rcases hf with ⟨cf, rfl⟩; rcases hg with ⟨cg, rfl⟩
      exact ⟨prec cf cg, rfl⟩
    case rfind f pf hf =>
      rcases hf with ⟨cf, rfl⟩
      refine' ⟨comp (rfind' cf) (pair Code.id zero), _⟩
      simp [eval, Seq.seq, pure, PFun.pure, Part.map_id'],
    fun h => by
    rcases h with ⟨c, rfl⟩; induction c
    case zero => exact Nat.Partrec.zero
    case succ => exact Nat.Partrec.succ
    case left => exact Nat.Partrec.left
    case right => exact Nat.Partrec.right
    case pair cf cg pf pg => exact pf.pair pg
    case comp cf cg pf pg => exact pf.comp pg
    

Proof state:
case intro.prec
a✝¹ a✝ : Code
a_ih✝¹ : Partrec (eval a✝¹)
a_ih✝ : Partrec (eval a✝)
⊢ Partrec (eval (prec a✝¹ a✝))
case intro.rfind' a✝ : Code a_ih✝ : Partrec (eval a✝) ⊢ Partrec (eval (rfind' a✝))

Next tactic:
case prec cf cg pf pg => exact pf.prec pg
/-- A function is partial recursive if and only if there is a code implementing it. -/
theorem exists_code {f : ℕ →. ℕ} : Nat.Partrec f ↔ ∃ c : Code, eval c = f :=
  ⟨fun h => by
    induction h
    case zero => exact ⟨zero, rfl⟩
    case succ => exact ⟨succ, rfl⟩
    case left => exact ⟨left, rfl⟩
    case right => exact ⟨right, rfl⟩
    case pair f g pf pg hf hg =>
      rcases hf with ⟨cf, rfl⟩; rcases hg with ⟨cg, rfl⟩
      exact ⟨pair cf cg, rfl⟩
    case comp f g pf pg hf hg =>
      rcases hf with ⟨cf, rfl⟩; rcases hg with ⟨cg, rfl⟩
      exact ⟨comp cf cg, rfl⟩
    case prec f g pf pg hf hg =>
      rcases hf with ⟨cf, rfl⟩; rcases hg with ⟨cg, rfl⟩
      exact ⟨prec cf cg, rfl⟩
    case rfind f pf hf =>
      rcases hf with ⟨cf, rfl⟩
      refine' ⟨comp (rfind' cf) (pair Code.id zero), _⟩
      simp [eval, Seq.seq, pure, PFun.pure, Part.map_id'],
    fun h => by
    rcases h with ⟨c, rfl⟩; induction c
    case zero => exact Nat.Partrec.zero
    case succ => exact Nat.Partrec.succ
    case left => exact Nat.Partrec.left
    case right => exact Nat.Partrec.right
    case pair cf cg pf pg => exact pf.pair pg
    case comp cf cg pf pg => exact pf.comp pg
    

Proof state:
cf cg : Code
pf : Partrec (eval cf)
pg : Partrec (eval cg)
⊢ Partrec (eval (prec cf cg))

Next tactic:
case prec cf cg pf pg => exact pf.prec pg
/-- A function is partial recursive if and only if there is a code implementing it. -/
theorem exists_code {f : ℕ →. ℕ} : Nat.Partrec f ↔ ∃ c : Code, eval c = f :=
  ⟨fun h => by
    induction h
    case zero => exact ⟨zero, rfl⟩
    case succ => exact ⟨succ, rfl⟩
    case left => exact ⟨left, rfl⟩
    case right => exact ⟨right, rfl⟩
    case pair f g pf pg hf hg =>
      rcases hf with ⟨cf, rfl⟩; rcases hg with ⟨cg, rfl⟩
      exact ⟨pair cf cg, rfl⟩
    case comp f g pf pg hf hg =>
      rcases hf with ⟨cf, rfl⟩; rcases hg with ⟨cg, rfl⟩
      exact ⟨comp cf cg, rfl⟩
    case prec f g pf pg hf hg =>
      rcases hf with ⟨cf, rfl⟩; rcases hg with ⟨cg, rfl⟩
      exact ⟨prec cf cg, rfl⟩
    case rfind f pf hf =>
      rcases hf with ⟨cf, rfl⟩
      refine' ⟨comp (rfind' cf) (pair Code.id zero), _⟩
      simp [eval, Seq.seq, pure, PFun.pure, Part.map_id'],
    fun h => by
    rcases h with ⟨c, rfl⟩; induction c
    case zero => exact Nat.Partrec.zero
    case succ => exact Nat.Partrec.succ
    case left => exact Nat.Partrec.left
    case right => exact Nat.Partrec.right
    case pair cf cg pf pg => exact pf.pair pg
    case comp cf cg pf pg => exact pf.comp pg
    case prec cf cg pf pg => 

Proof state:
cf cg : Code
pf : Partrec (eval cf)
pg : Partrec (eval cg)
⊢ Partrec (eval (prec cf cg))

Next tactic:
exact pf.prec pg
/-- A function is partial recursive if and only if there is a code implementing it. -/
theorem exists_code {f : ℕ →. ℕ} : Nat.Partrec f ↔ ∃ c : Code, eval c = f :=
  ⟨fun h => by
    induction h
    case zero => exact ⟨zero, rfl⟩
    case succ => exact ⟨succ, rfl⟩
    case left => exact ⟨left, rfl⟩
    case right => exact ⟨right, rfl⟩
    case pair f g pf pg hf hg =>
      rcases hf with ⟨cf, rfl⟩; rcases hg with ⟨cg, rfl⟩
      exact ⟨pair cf cg, rfl⟩
    case comp f g pf pg hf hg =>
      rcases hf with ⟨cf, rfl⟩; rcases hg with ⟨cg, rfl⟩
      exact ⟨comp cf cg, rfl⟩
    case prec f g pf pg hf hg =>
      rcases hf with ⟨cf, rfl⟩; rcases hg with ⟨cg, rfl⟩
      exact ⟨prec cf cg, rfl⟩
    case rfind f pf hf =>
      rcases hf with ⟨cf, rfl⟩
      refine' ⟨comp (rfind' cf) (pair Code.id zero), _⟩
      simp [eval, Seq.seq, pure, PFun.pure, Part.map_id'],
    fun h => by
    rcases h with ⟨c, rfl⟩; induction c
    case zero => exact Nat.Partrec.zero
    case succ => exact Nat.Partrec.succ
    case left => exact Nat.Partrec.left
    case right => exact Nat.Partrec.right
    case pair cf cg pf pg => exact pf.pair pg
    case comp cf cg pf pg => exact pf.comp pg
    case prec cf cg pf pg => exact pf.prec pg
    

Proof state:
case intro.rfind'
a✝ : Code
a_ih✝ : Partrec (eval a✝)
⊢ Partrec (eval (rfind' a✝))

Next tactic:
case rfind' cf pf => exact pf.rfind'
/-- A function is partial recursive if and only if there is a code implementing it. -/
theorem exists_code {f : ℕ →. ℕ} : Nat.Partrec f ↔ ∃ c : Code, eval c = f :=
  ⟨fun h => by
    induction h
    case zero => exact ⟨zero, rfl⟩
    case succ => exact ⟨succ, rfl⟩
    case left => exact ⟨left, rfl⟩
    case right => exact ⟨right, rfl⟩
    case pair f g pf pg hf hg =>
      rcases hf with ⟨cf, rfl⟩; rcases hg with ⟨cg, rfl⟩
      exact ⟨pair cf cg, rfl⟩
    case comp f g pf pg hf hg =>
      rcases hf with ⟨cf, rfl⟩; rcases hg with ⟨cg, rfl⟩
      exact ⟨comp cf cg, rfl⟩
    case prec f g pf pg hf hg =>
      rcases hf with ⟨cf, rfl⟩; rcases hg with ⟨cg, rfl⟩
      exact ⟨prec cf cg, rfl⟩
    case rfind f pf hf =>
      rcases hf with ⟨cf, rfl⟩
      refine' ⟨comp (rfind' cf) (pair Code.id zero), _⟩
      simp [eval, Seq.seq, pure, PFun.pure, Part.map_id'],
    fun h => by
    rcases h with ⟨c, rfl⟩; induction c
    case zero => exact Nat.Partrec.zero
    case succ => exact Nat.Partrec.succ
    case left => exact Nat.Partrec.left
    case right => exact Nat.Partrec.right
    case pair cf cg pf pg => exact pf.pair pg
    case comp cf cg pf pg => exact pf.comp pg
    case prec cf cg pf pg => exact pf.prec pg
    

Proof state:
cf : Code
pf : Partrec (eval cf)
⊢ Partrec (eval (rfind' cf))

Next tactic:
case rfind' cf pf => exact pf.rfind'
/-- A function is partial recursive if and only if there is a code implementing it. -/
theorem exists_code {f : ℕ →. ℕ} : Nat.Partrec f ↔ ∃ c : Code, eval c = f :=
  ⟨fun h => by
    induction h
    case zero => exact ⟨zero, rfl⟩
    case succ => exact ⟨succ, rfl⟩
    case left => exact ⟨left, rfl⟩
    case right => exact ⟨right, rfl⟩
    case pair f g pf pg hf hg =>
      rcases hf with ⟨cf, rfl⟩; rcases hg with ⟨cg, rfl⟩
      exact ⟨pair cf cg, rfl⟩
    case comp f g pf pg hf hg =>
      rcases hf with ⟨cf, rfl⟩; rcases hg with ⟨cg, rfl⟩
      exact ⟨comp cf cg, rfl⟩
    case prec f g pf pg hf hg =>
      rcases hf with ⟨cf, rfl⟩; rcases hg with ⟨cg, rfl⟩
      exact ⟨prec cf cg, rfl⟩
    case rfind f pf hf =>
      rcases hf with ⟨cf, rfl⟩
      refine' ⟨comp (rfind' cf) (pair Code.id zero), _⟩
      simp [eval, Seq.seq, pure, PFun.pure, Part.map_id'],
    fun h => by
    rcases h with ⟨c, rfl⟩; induction c
    case zero => exact Nat.Partrec.zero
    case succ => exact Nat.Partrec.succ
    case left => exact Nat.Partrec.left
    case right => exact Nat.Partrec.right
    case pair cf cg pf pg => exact pf.pair pg
    case comp cf cg pf pg => exact pf.comp pg
    case prec cf cg pf pg => exact pf.prec pg
    case rfind' cf pf => 

Proof state:
cf : Code
pf : Partrec (eval cf)
⊢ Partrec (eval (rfind' cf))

Next tactic:
exact pf.rfind'
/-- A modified evaluation for the code which returns an `Option ℕ` instead of a `Part ℕ`. To avoid
undecidability, `evaln` takes a parameter `k` and fails if it encounters a number ≥ k in the course
of its execution. Other than this, the semantics are the same as in `Nat.Partrec.Code.eval`.
-/
def evaln : ℕ → Code → ℕ → Option ℕ
  | 0, _ => fun _ => Option.none
  | k + 1, zero => fun n => do
    guard (n ≤ k)
    return 0
  | k + 1, succ => fun n => do
    guard (n ≤ k)
    return (Nat.succ n)
  | k + 1, left => fun n => do
    guard (n ≤ k)
    return n.unpair.1
  | k + 1, right => fun n => do
    guard (n ≤ k)
    pure n.unpair.2
  | k + 1, pair cf cg => fun n => do
    guard (n ≤ k)
    Nat.pair <$> evaln (k + 1) cf n <*> evaln (k + 1) cg n
  | k + 1, comp cf cg => fun n => do
    guard (n ≤ k)
    let x ← evaln (k + 1) cg n
    evaln (k + 1) cf x
  | k + 1, prec cf cg => fun n => do
    guard (n ≤ k)
    n.unpaired fun a n =>
      n.casesOn (evaln (k + 1) cf a) fun y => do
        let i ← evaln k (prec cf cg) (Nat.pair a y)
        evaln (k + 1) cg (Nat.pair a (Nat.pair y i))
  | k + 1, rfind' cf => fun n => do
    guard (n ≤ k)
    n.unpaired fun a m => do
      let x ← evaln (k + 1) cf (Nat.pair a m)
      if x = 0 then
        pure m
      else
        evaln k (rfind' cf) (Nat.pair a (m + 1))
  termination_by evaln k c => (k, c)
  decreasing_by 

Proof state:
k : ℕ
cf cg : Code
⊢ (invImage (fun a => PSigma.casesOn a fun k snd => (k, snd)) Prod.instWellFoundedRelationProd).1
    { fst := k + 1, snd := cf } { fst := Nat.succ k, snd := pair cf cg }

Next tactic:
{ decreasing_with simp (config := { arith := true }) [Zero.zero]; done }
/-- A modified evaluation for the code which returns an `Option ℕ` instead of a `Part ℕ`. To avoid
undecidability, `evaln` takes a parameter `k` and fails if it encounters a number ≥ k in the course
of its execution. Other than this, the semantics are the same as in `Nat.Partrec.Code.eval`.
-/
def evaln : ℕ → Code → ℕ → Option ℕ
  | 0, _ => fun _ => Option.none
  | k + 1, zero => fun n => do
    guard (n ≤ k)
    return 0
  | k + 1, succ => fun n => do
    guard (n ≤ k)
    return (Nat.succ n)
  | k + 1, left => fun n => do
    guard (n ≤ k)
    return n.unpair.1
  | k + 1, right => fun n => do
    guard (n ≤ k)
    pure n.unpair.2
  | k + 1, pair cf cg => fun n => do
    guard (n ≤ k)
    Nat.pair <$> evaln (k + 1) cf n <*> evaln (k + 1) cg n
  | k + 1, comp cf cg => fun n => do
    guard (n ≤ k)
    let x ← evaln (k + 1) cg n
    evaln (k + 1) cf x
  | k + 1, prec cf cg => fun n => do
    guard (n ≤ k)
    n.unpaired fun a n =>
      n.casesOn (evaln (k + 1) cf a) fun y => do
        let i ← evaln k (prec cf cg) (Nat.pair a y)
        evaln (k + 1) cg (Nat.pair a (Nat.pair y i))
  | k + 1, rfind' cf => fun n => do
    guard (n ≤ k)
    n.unpaired fun a m => do
      let x ← evaln (k + 1) cf (Nat.pair a m)
      if x = 0 then
        pure m
      else
        evaln k (rfind' cf) (Nat.pair a (m + 1))
  termination_by evaln k c => (k, c)
  decreasing_by { 

Proof state:
k : ℕ
cf cg : Code
⊢ (invImage (fun a => PSigma.casesOn a fun k snd => (k, snd)) Prod.instWellFoundedRelationProd).1
    { fst := k + 1, snd := cf } { fst := Nat.succ k, snd := pair cf cg }

Next tactic:
decreasing_with simp (config := { arith := true }) [Zero.zero]; done
/-- A modified evaluation for the code which returns an `Option ℕ` instead of a `Part ℕ`. To avoid
undecidability, `evaln` takes a parameter `k` and fails if it encounters a number ≥ k in the course
of its execution. Other than this, the semantics are the same as in `Nat.Partrec.Code.eval`.
-/
def evaln : ℕ → Code → ℕ → Option ℕ
  | 0, _ => fun _ => Option.none
  | k + 1, zero => fun n => do
    guard (n ≤ k)
    return 0
  | k + 1, succ => fun n => do
    guard (n ≤ k)
    return (Nat.succ n)
  | k + 1, left => fun n => do
    guard (n ≤ k)
    return n.unpair.1
  | k + 1, right => fun n => do
    guard (n ≤ k)
    pure n.unpair.2
  | k + 1, pair cf cg => fun n => do
    guard (n ≤ k)
    Nat.pair <$> evaln (k + 1) cf n <*> evaln (k + 1) cg n
  | k + 1, comp cf cg => fun n => do
    guard (n ≤ k)
    let x ← evaln (k + 1) cg n
    evaln (k + 1) cf x
  | k + 1, prec cf cg => fun n => do
    guard (n ≤ k)
    n.unpaired fun a n =>
      n.casesOn (evaln (k + 1) cf a) fun y => do
        let i ← evaln k (prec cf cg) (Nat.pair a y)
        evaln (k + 1) cg (Nat.pair a (Nat.pair y i))
  | k + 1, rfind' cf => fun n => do
    guard (n ≤ k)
    n.unpaired fun a m => do
      let x ← evaln (k + 1) cf (Nat.pair a m)
      if x = 0 then
        pure m
      else
        evaln k (rfind' cf) (Nat.pair a (m + 1))
  termination_by evaln k c => (k, c)
  decreasing_by { decreasing_with 

Proof state:
case h
k : ℕ
cf cg : Code
⊢ sizeOf cf < sizeOf (pair cf cg)

Next tactic:
simp (config := { arith := true }) [Zero.zero]
/-- A modified evaluation for the code which returns an `Option ℕ` instead of a `Part ℕ`. To avoid
undecidability, `evaln` takes a parameter `k` and fails if it encounters a number ≥ k in the course
of its execution. Other than this, the semantics are the same as in `Nat.Partrec.Code.eval`.
-/
def evaln : ℕ → Code → ℕ → Option ℕ
  | 0, _ => fun _ => Option.none
  | k + 1, zero => fun n => do
    guard (n ≤ k)
    return 0
  | k + 1, succ => fun n => do
    guard (n ≤ k)
    return (Nat.succ n)
  | k + 1, left => fun n => do
    guard (n ≤ k)
    return n.unpair.1
  | k + 1, right => fun n => do
    guard (n ≤ k)
    pure n.unpair.2
  | k + 1, pair cf cg => fun n => do
    guard (n ≤ k)
    Nat.pair <$> evaln (k + 1) cf n <*> evaln (k + 1) cg n
  | k + 1, comp cf cg => fun n => do
    guard (n ≤ k)
    let x ← evaln (k + 1) cg n
    evaln (k + 1) cf x
  | k + 1, prec cf cg => fun n => do
    guard (n ≤ k)
    n.unpaired fun a n =>
      n.casesOn (evaln (k + 1) cf a) fun y => do
        let i ← evaln k (prec cf cg) (Nat.pair a y)
        evaln (k + 1) cg (Nat.pair a (Nat.pair y i))
  | k + 1, rfind' cf => fun n => do
    guard (n ≤ k)
    n.unpaired fun a m => do
      let x ← evaln (k + 1) cf (Nat.pair a m)
      if x = 0 then
        pure m
      else
        evaln k (rfind' cf) (Nat.pair a (m + 1))
  termination_by evaln k c => (k, c)
  decreasing_by { decreasing_with simp (config := { arith := true }) [Zero.zero]; 

Proof state:

Next tactic:
done
/-- A modified evaluation for the code which returns an `Option ℕ` instead of a `Part ℕ`. To avoid
undecidability, `evaln` takes a parameter `k` and fails if it encounters a number ≥ k in the course
of its execution. Other than this, the semantics are the same as in `Nat.Partrec.Code.eval`.
-/
def evaln : ℕ → Code → ℕ → Option ℕ
  | 0, _ => fun _ => Option.none
  | k + 1, zero => fun n => do
    guard (n ≤ k)
    return 0
  | k + 1, succ => fun n => do
    guard (n ≤ k)
    return (Nat.succ n)
  | k + 1, left => fun n => do
    guard (n ≤ k)
    return n.unpair.1
  | k + 1, right => fun n => do
    guard (n ≤ k)
    pure n.unpair.2
  | k + 1, pair cf cg => fun n => do
    guard (n ≤ k)
    Nat.pair <$> evaln (k + 1) cf n <*> evaln (k + 1) cg n
  | k + 1, comp cf cg => fun n => do
    guard (n ≤ k)
    let x ← evaln (k + 1) cg n
    evaln (k + 1) cf x
  | k + 1, prec cf cg => fun n => do
    guard (n ≤ k)
    n.unpaired fun a n =>
      n.casesOn (evaln (k + 1) cf a) fun y => do
        let i ← evaln k (prec cf cg) (Nat.pair a y)
        evaln (k + 1) cg (Nat.pair a (Nat.pair y i))
  | k + 1, rfind' cf => fun n => do
    guard (n ≤ k)
    n.unpaired fun a m => do
      let x ← evaln (k + 1) cf (Nat.pair a m)
      if x = 0 then
        pure m
      else
        evaln k (rfind' cf) (Nat.pair a (m + 1))
  termination_by evaln k c => (k, c)
  decreasing_by 

Proof state:
k : ℕ
cf cg : Code
⊢ (invImage (fun a => PSigma.casesOn a fun k snd => (k, snd)) Prod.instWellFoundedRelationProd).1
    { fst := k + 1, snd := cg } { fst := Nat.succ k, snd := pair cf cg }

Next tactic:
{ decreasing_with simp (config := { arith := true }) [Zero.zero]; done }