mathlibdocumentation

computability.partrec_code

Gödel Numbering for Partial Recursive Functions. #

This file defines nat.partrec.code, an inductive datatype describing code for partial recursive functions on ℕ. It defines an encoding for these codes, and proves that the constructors are primitive recursive with respect to the encoding.

It also defines the evalution of these codes as partial functions using pfun, and proves that a function is partially recursive (as defined by nat.partrec) if and only if it is the evaluation of some code.

Main Definitions #

• nat.partrec.code: Inductive datatype for partial recursive codes.
• nat.partrec.code.encode_code: A (computable) encoding of codes as natural numbers.
• nat.partrec.code.of_nat_code: The inverse of this encoding.
• nat.partrec.code.eval: The interpretation of a nat.partrec.code as a partial function.

Main Results #

• nat.partrec.code.rec_prim: Recursion on nat.partrec.code is primitive recursive.
• nat.partrec.code.rec_computable: Recursion on nat.partrec.code is computable.
• nat.partrec.code.smn: The $S_n^m$ theorem.
• nat.partrec.code.exists_code: Partial recursiveness is equivalent to being the eval of a code.
• nat.partrec.code.evaln_prim: evaln is primitive recursive.
• nat.partrec.code.fixed_point: Roger's fixed point theorem.

References #

theorem nat.partrec.rfind' {f : →. } (hf : nat.partrec f) :
nat.partrec (nat.unpaired (λ (a m : ), part.map (λ (_x : ), _x + m) (nat.rfind (λ (n : ), (λ (m : ), decidable.to_bool (m = 0)) <$> f (n + m)))))) inductive nat.partrec.code : Type Code for partial recursive functions from ℕ to ℕ. See nat.partrec.code.eval for the interpretation of these constructors. Instances for nat.partrec.code @[protected, instance] Equations @[protected] Returns a code for the constant function outputting a particular natural. Equations theorem nat.partrec.code.const_inj {n₁ n₂ : } : n₁ = n₂ @[protected] A code for the identity function. Equations Given a code c taking a pair as input, returns a code using n as the first argument to c. Equations An encoding of a nat.partrec.code as a ℕ. Equations A decoder for nat.partrec.code.encode_code, taking any ℕ to the nat.partrec.code it represents. Equations @[protected, instance] Equations theorem nat.partrec.code.rec_prim' {α : Type u_1} {σ : Type u_2} [primcodable α] [primcodable σ] {c : α → nat.partrec.code} (hc : primrec c) {z : α → σ} (hz : primrec z) {s : α → σ} (hs : primrec s) {l : α → σ} (hl : primrec l) {r : α → σ} (hr : primrec r) {pr : α → → σ} (hpr : primrec₂ pr) {co : α → → σ} (hco : primrec₂ co) {pc : α → → σ} (hpc : primrec₂ pc) {rf : α → → σ} (hrf : primrec₂ rf) : let PR : α → nat.partrec.codenat.partrec.codeσ → σ → σ := λ (a : α) (cf cg : nat.partrec.code) (hf hg : σ), pr a (cf, cg, hf, hg), CO : α → nat.partrec.codenat.partrec.codeσ → σ → σ := λ (a : α) (cf cg : nat.partrec.code) (hf hg : σ), co a (cf, cg, hf, hg), PC : α → nat.partrec.codenat.partrec.codeσ → σ → σ := λ (a : α) (cf cg : nat.partrec.code) (hf hg : σ), pc a (cf, cg, hf, hg), RF : α → nat.partrec.codeσ → σ := λ (a : α) (cf : nat.partrec.code) (hf : σ), rf a (cf, hf), F : α → := λ (a : α) (c : nat.partrec.code), c.rec_on (z a) (s a) (l a) (r a) (PR a) (CO a) (PC a) (RF a) in primrec (λ (a : α), F a (c a)) theorem nat.partrec.code.rec_prim {α : Type u_1} {σ : Type u_2} [primcodable α] [primcodable σ] {c : α → nat.partrec.code} (hc : primrec c) {z : α → σ} (hz : primrec z) {s : α → σ} (hs : primrec s) {l : α → σ} (hl : primrec l) {r : α → σ} (hr : primrec r) {pr : α → nat.partrec.codenat.partrec.codeσ → σ → σ} (hpr : primrec (λ (a : α × , pr a.fst a.snd.fst a.snd.snd.fst a.snd.snd.snd.fst a.snd.snd.snd.snd)) {co : α → nat.partrec.codenat.partrec.codeσ → σ → σ} (hco : primrec (λ (a : α × , co a.fst a.snd.fst a.snd.snd.fst a.snd.snd.snd.fst a.snd.snd.snd.snd)) {pc : α → nat.partrec.codenat.partrec.codeσ → σ → σ} (hpc : primrec (λ (a : α × , pc a.fst a.snd.fst a.snd.snd.fst a.snd.snd.snd.fst a.snd.snd.snd.snd)) {rf : α → nat.partrec.codeσ → σ} (hrf : primrec (λ (a : α × , rf a.fst a.snd.fst a.snd.snd)) : let F : α → := λ (a : α) (c : nat.partrec.code), c.rec_on (z a) (s a) (l a) (r a) (pr a) (co a) (pc a) (rf a) in primrec (λ (a : α), F a (c a)) Recursion on nat.partrec.code is primitive recursive. theorem nat.partrec.code.rec_computable {α : Type u_1} {σ : Type u_2} [primcodable α] [primcodable σ] {c : α → nat.partrec.code} (hc : computable c) {z : α → σ} (hz : computable z) {s : α → σ} (hs : computable s) {l : α → σ} (hl : computable l) {r : α → σ} (hr : computable r) {pr : α → → σ} (hpr : computable₂ pr) {co : α → → σ} (hco : computable₂ co) {pc : α → → σ} (hpc : computable₂ pc) {rf : α → → σ} (hrf : computable₂ rf) : let PR : α → nat.partrec.codenat.partrec.codeσ → σ → σ := λ (a : α) (cf cg : nat.partrec.code) (hf hg : σ), pr a (cf, cg, hf, hg), CO : α → nat.partrec.codenat.partrec.codeσ → σ → σ := λ (a : α) (cf cg : nat.partrec.code) (hf hg : σ), co a (cf, cg, hf, hg), PC : α → nat.partrec.codenat.partrec.codeσ → σ → σ := λ (a : α) (cf cg : nat.partrec.code) (hf hg : σ), pc a (cf, cg, hf, hg), RF : α → nat.partrec.codeσ → σ := λ (a : α) (cf : nat.partrec.code) (hf : σ), rf a (cf, hf), F : α → := λ (a : α) (c : nat.partrec.code), c.rec_on (z a) (s a) (l a) (r a) (PR a) (CO a) (PC a) (RF a) in computable (λ (a : α), F a (c a)) Recursion on nat.partrec.code is computable. The interpretation of a nat.partrec.code as a partial function. • nat.partrec.code.zero: The constant zero function. • nat.partrec.code.succ: The successor function. • nat.partrec.code.left: Left unpairing of a pair of ℕ (encoded by nat.mkpair) • nat.partrec.code.right: Right unpairing of a pair of ℕ (encoded by nat.mkpair) • nat.partrec.code.pair: Pairs the outputs of argument codes using nat.mkpair. • nat.partrec.code.comp: Composition of two argument codes. • nat.partrec.code.prec: Primitive recursion. Given an argument of the form nat.mkpair a n: • If n = 0, returns eval cf a. • If n = succ k, returns eval cg (mkpair a (mkpair k (eval (prec cf cg) (mkpair a k)))) • nat.partrec.code.rfind': Minimization. For f an argument of the form nat.mkpair a m, rfind' f m returns the least a such that f a m = 0, if one exists and f b m terminates for b < a Equations @[simp] theorem nat.partrec.code.eval_prec_zero (cf cg : nat.partrec.code) (a : ) : (cf.prec cg).eval 0) = cf.eval a Helper lemma for the evaluation of prec in the base case. theorem nat.partrec.code.eval_prec_succ (cf cg : nat.partrec.code) (a k : ) : (cf.prec cg).eval k.succ) = (cf.prec cg).eval k) >>= λ (ih : ), cg.eval ih)) Helper lemma for the evaluation of prec in the recursive case. @[protected, instance] Equations @[simp] theorem nat.partrec.code.eval_const (n m : ) : = @[simp] theorem nat.partrec.code.eval_id (n : ) : @[simp] theorem nat.partrec.code.eval_curry (c : nat.partrec.code) (n x : ) : (c.curry n).eval x = c.eval x) theorem nat.partrec.code.curry_inj {c₁ c₂ : nat.partrec.code} {n₁ n₂ : } (h : c₁.curry n₁ = c₂.curry n₂) : c₁ = c₂ n₁ = n₂ theorem nat.partrec.code.smn : ∃ (f : , ∀ (c : nat.partrec.code) (n x : ), (f c n).eval x = c.eval x) The$S_n^m\$ theorem: There is a computable function, namely nat.partrec.code.curry, that takes a program and a ℕ n, and returns a new program using n as the first argument.

A function is partial recursive if and only if there is a code implementing it.

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.

Equations
theorem nat.partrec.code.evaln_bound {k : } {c : nat.partrec.code} {n x : } :
x n < k
theorem nat.partrec.code.evaln_mono {k₁ k₂ : } {c : nat.partrec.code} {n x : } :
k₁ k₂x nx n
theorem nat.partrec.code.evaln_sound {k : } {c : nat.partrec.code} {n x : } :
x x c.eval n
theorem nat.partrec.code.evaln_complete {c : nat.partrec.code} {n x : } :
x c.eval n ∃ (k : ), x
theorem nat.partrec.code.evaln_prim  :
primrec (λ (a : × ), a.snd)

The nat.partrec.code.evaln function is primitive recursive.

theorem nat.partrec.code.fixed_point (hf : computable f) :
∃ (c : nat.partrec.code), (f c).eval = c.eval

Roger's fixed-point theorem: Any total, computable f has a fixed point: That is, under the interpretation given by nat.partrec.code.eval, there is a code c such that c and f c have the same evaluation.

theorem nat.partrec.code.fixed_point₂ {f : nat.partrec.code} (hf : partrec₂ f) :
∃ (c : nat.partrec.code), c.eval = f c