Documentation

Mathlib.Computability.PartrecCode

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 evaluation 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 #

Main Results #

References #

theorem Nat.Partrec.rfind' {f : →. } (hf : Partrec f) :
Partrec (unpaired fun (a m : ) => Part.map (fun (x : ) => x + m) (Nat.rfind fun (n : ) => (fun (m : ) => decide (m = 0)) <$> f (Nat.pair a (n + m))))

Code for partial recursive functions from ℕ to ℕ. See Nat.Partrec.Code.eval for the interpretation of these constructors.

Instances For

    Returns a code for the constant function outputting a particular natural.

    Equations
    Instances For
      theorem Nat.Partrec.Code.const_inj {n₁ n₂ : } :
      Code.const n₁ = Code.const n₂n₁ = n₂

      A code for the identity function.

      Equations
      Instances For

        Given a code c taking a pair as input, returns a code using n as the first argument to c.

        Equations
        Instances For

          An encoding of a Nat.Partrec.Code as a ℕ.

          Equations
          Instances For
            Equations
            • One or more equations did not get rendered due to their size.
            theorem Nat.Partrec.Code.rec_prim' {α : Type u_1} {σ : Type u_2} [Primcodable α] [Primcodable σ] {c : αCode} (hc : Primrec c) {z : ασ} (hz : Primrec z) {s : ασ} (hs : Primrec s) {l : ασ} (hl : Primrec l) {r : ασ} (hr : Primrec r) {pr : αCode × Code × σ × σσ} (hpr : Primrec₂ pr) {co : αCode × Code × σ × σσ} (hco : Primrec₂ co) {pc : αCode × Code × σ × σσ} (hpc : Primrec₂ pc) {rf : αCode × σσ} (hrf : Primrec₂ rf) :
            let PR := fun (a : α) (cf cg : Code) (hf hg : σ) => pr a (cf, cg, hf, hg); let CO := fun (a : α) (cf cg : Code) (hf hg : σ) => co a (cf, cg, hf, hg); let PC := fun (a : α) (cf cg : Code) (hf hg : σ) => pc a (cf, cg, hf, hg); let RF := fun (a : α) (cf : Code) (hf : σ) => rf a (cf, hf); let F := fun (a : α) (c : Code) => Code.recOn c (z a) (s a) (l a) (r a) (PR a) (CO a) (PC a) (RF a); Primrec fun (a : α) => F a (c a)
            theorem Nat.Partrec.Code.rec_prim {α : Type u_1} {σ : Type u_2} [Primcodable α] [Primcodable σ] {c : αCode} (hc : Primrec c) {z : ασ} (hz : Primrec z) {s : ασ} (hs : Primrec s) {l : ασ} (hl : Primrec l) {r : ασ} (hr : Primrec r) {pr : αCodeCodeσσσ} (hpr : Primrec fun (a : α × Code × Code × σ × σ) => pr a.1 a.2.1 a.2.2.1 a.2.2.2.1 a.2.2.2.2) {co : αCodeCodeσσσ} (hco : Primrec fun (a : α × Code × Code × σ × σ) => co a.1 a.2.1 a.2.2.1 a.2.2.2.1 a.2.2.2.2) {pc : αCodeCodeσσσ} (hpc : Primrec fun (a : α × Code × Code × σ × σ) => pc a.1 a.2.1 a.2.2.1 a.2.2.2.1 a.2.2.2.2) {rf : αCodeσσ} (hrf : Primrec fun (a : α × Code × σ) => rf a.1 a.2.1 a.2.2) :
            let F := fun (a : α) (c : Code) => Code.recOn c (z a) (s a) (l a) (r a) (pr a) (co a) (pc a) (rf a); Primrec fun (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 : α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 : Code) (hf hg : σ) => pr a (cf, cg, hf, hg); let CO := fun (a : α) (cf cg : Code) (hf hg : σ) => co a (cf, cg, hf, hg); let PC := fun (a : α) (cf cg : Code) (hf hg : σ) => pc a (cf, cg, hf, hg); let RF := fun (a : α) (cf : Code) (hf : σ) => rf a (cf, hf); let F := fun (a : α) (c : Code) => 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)

            Recursion on Nat.Partrec.Code is computable.

            The interpretation of a Nat.Partrec.Code as a partial function.

            Equations
            Instances For
              @[simp]
              theorem Nat.Partrec.Code.eval_prec_zero (cf cg : Code) (a : ) :
              (cf.prec cg).eval (Nat.pair a 0) = cf.eval a

              Helper lemma for the evaluation of prec in the base case.

              theorem Nat.Partrec.Code.eval_prec_succ (cf cg : Code) (a k : ) :
              (cf.prec cg).eval (Nat.pair a k.succ) = do let ih(cf.prec cg).eval (Nat.pair a k) cg.eval (Nat.pair a (Nat.pair k ih))

              Helper lemma for the evaluation of prec in the recursive case.

              @[simp]
              theorem Nat.Partrec.Code.eval_const (n m : ) :
              (Code.const n).eval m = Part.some n
              @[simp]
              @[simp]
              theorem Nat.Partrec.Code.eval_curry (c : Code) (n x : ) :
              (c.curry n).eval x = c.eval (Nat.pair n x)
              theorem Nat.Partrec.Code.curry_inj {c₁ c₂ : Code} {n₁ n₂ : } (h : c₁.curry n₁ = c₂.curry n₂) :
              c₁ = c₂ n₁ = n₂
              theorem Nat.Partrec.Code.smn :
              ∃ (f : CodeCode), Computable₂ f ∀ (c : Code) (n x : ), (f c n).eval x = c.eval (Nat.pair n 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.

              theorem Nat.Partrec.Code.exists_code {f : →. } :
              Partrec f ∃ (c : Code), c.eval = f

              A function is partial recursive if and only if there is a code implementing it. Therefore, eval is a universal partial recursive function.

              @[irreducible]

              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
              Instances For
                theorem Nat.Partrec.Code.evaln_bound {k : } {c : Code} {n x : } :
                x evaln k c nn < k
                theorem Nat.Partrec.Code.evaln_mono {k₁ k₂ : } {c : Code} {n x : } :
                k₁ k₂x evaln k₁ c nx evaln k₂ c n
                theorem Nat.Partrec.Code.evaln_sound {k : } {c : Code} {n x : } :
                x evaln k c nx c.eval n
                theorem Nat.Partrec.Code.evaln_complete {c : Code} {n x : } :
                x c.eval n ∃ (k : ), x evaln k c n
                theorem Nat.Partrec.Code.evaln_prim :
                Primrec fun (a : ( × Code) × ) => evaln a.1.1 a.1.2 a.2

                The Nat.Partrec.Code.evaln function is primitive recursive.

                theorem Nat.Partrec.Code.eval_eq_rfindOpt (c : Code) (n : ) :
                c.eval n = rfindOpt fun (k : ) => evaln k c n
                theorem Nat.Partrec.Code.fixed_point {f : CodeCode} (hf : Computable f) :
                ∃ (c : 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 : Code →. } (hf : Partrec₂ f) :
                ∃ (c : Code), c.eval = f c

                There are only countably many partial recursive partial functions ℕ →. ℕ.

                There are only countably many computable functions ℕ → ℕ.