Cap´ıtulo 3
Funciones Recursivas
3.1.
La clase de las funciones recursivas
Comenzaremos presentando tres procedimientos de definici´on de funciones. Intuitivamente, resultar´a evidente que si las funciones que se toman de partida para cada definici´on son com-putables tambi´en lo es la nueva funci´on obtenida (m´as adelante daremos una prueba de ello). Definici´on: Dadas f : Nk− → N y g
1, ..., gk : Nn− → N diremos que h : Nn− → N se obtiene
por composici´on a partir de f, g1, ..., gk si para todo (x1, ..., xn) ∈ Nn
h(x1, ..., xn) ' f (g1(x1, ..., xn), ..., gk(x1, ..., xn))
Diremos tambi´en que h es la composici´on de f y g1, ..., gk, y lo notaremos por h = C(f ; g1, ..., gk).
Definici´on: Si g : Nn− → N y h : Nn+2− → N diremos que f : Nn+1− → N se obtiene por
recursi´on primitiva a partir de g y h si para todo (x1, ..., xn) ∈ Nn
f (x1, ..., xn, 0) ' g(x1, ..., xn)
f (x1, ..., xn, y + 1) ' h(x1, ..., xn, y, f (x1, ..., xn, y)), par a todo y ∈ N
Observaciones:
1. Dadas g y h como en la definici´on de la recursi´on primitiva, existe una ´unica funci´on f verificando las condiciones expuestas. La unicidad puede probarse por inducci´on, pues si
f1, f2 son tales que:
fi(~x, 0) ' g(~x)
fi(~x, y + 1) ' h(~x, y, fi(~x, y))
Entonces, ∀y ∈ N ∀~x ∈ Nn(f
1(~x, y) ' f2(~x, y)) (por inducci´on en y).
Esto nos permite introducir la notaci´on f = R(g, h), que leemos como f es la funci´on
definida por recursi´on primitiva a partir de g y h.
2. Si las funciones auxiliares usadas en la composici´on y recursi´on primitiva son totales, las obtenidas tambi´en lo son.
3. Como caso especial admitimos que en la definici´on por recursi´on primitiva sea n = 0. En dicho caso las ecuaciones que definen la funci´on f : N − → N son:
f (0) = a
f (x + 1) = h(x, f (x))
Es decir, en vez de la funci´on g tenemos una constante a ∈ N y la funci´on h es de aridad 2. Expresaremos que f ha sido definida por recursi´on primitiva a partir de a y h, escribiendo
Definici´on: Dada f : Nn+1− → N, la funci´on definida a partir de f por µ-recursi´on es la funci´on fµ: Nn− → N dada por: fµ(~x) = ( min{y : f (~x, y) = 0 ∧ ∀ z < y (f (~x, z) ↓)} si existe ↑ en otro caso Escribiremos fµ(~x) = (µy)(f (~x, y) = 0)
Nota: La condici´on ∀ z < y (f (~x, z) ↓) es importante para poder calcular g de manera efectiva. Recordemos que µ puede verse como una b´usqueda, ya que buscamos un y tal que
f (~x, y) = 0, y si existe z < y tal que f (~x, z) ↑, entonces la b´usqueda no termina. Definici´on: Llamaremos funciones b´asicas a las siguientes:
1. La funci´on sucesor: S : N → N, S(x) = x + 1.
2. La funci´on id´enticamente nula (´o cero): O : N → N, O(x) = 0.
3. Las proyecciones: Para cada n ≥ 1, y cada i (1 ≤ i ≤ n), definimos Πn
i : Nn → N, como
Πn
i(x1, ..., xn) = xi.
Definici´on: La clase de las funciones recursivas, P, es la menor clase de funciones tal que:
1. Contiene a las funciones b´asicas.
2. Es cerrada bajo composici´on, recursi´on primitiva y µ–recursi´on, es decir: Si f : Nk− → N, g 1, ..., gk: Nn− → N ∈ P, entonces C(f ; g1, ..., gk) ∈ P. Si g : Nn− → N, h : Nn+2− → N pertenecen a C, entonces R(g, h) ∈ P. Si f : Nk+1− → N ∈ P, entonces f µ∈ P. Observaciones:
1. Puesto que P es la menor clase de funciones que verifica (1) y (2), si deseamos probar una propiedad para todas las funciones recursivas podemos hacerlo por inducci´on sobre
funciones recursivas. Para ello probaremos que:
a) La propiedad es cierta para las funciones b´asicas.
b) Si f, g1, ..., gk son k + 1 funciones recursivas verificando la propiedad, y que est´an en las condiciones en que se defini´o la composici´on, entonces C(f ; g1, ..., gk) tambi´en
verifica dicha propiedad.
c) Si g y h son dos funciones recursivas que verifican la propiedad y est´an en las condi-ciones de la definici´on por recursi´on primitiva, entonces R(g, h) tambi´en verifica la propiedad.
d) Si f es recursiva y verifica la propiedad, entonces fµ tambi´en.
2. Dada una funci´on, f , son equivalentes:
a) f ∈ P.
b) Existen f1, ..., fn tales que fn= f y para cada i ≤ n se tiene una de las situaciones
siguientes:
fi es una funci´on b´asica, o bien,
Existen j1, ..., jr, k < i tales que fi = C(fk; fj1, ..., fjr), o bien,
Existe k < i tal que fi = (fj)µ.
Existen dos clases de funciones recursivas que merecen destacarse: las funciones recursivas totales y las funciones primitivas recursivas.
La clase de las funciones recursivas totales se denotar´a por R.
La clase de las funciones primitivas recursivas, PR, es la menor clase de funciones tal que: (1) contiene las funciones b´asicas y (2) es cerrada bajo composici´on y recursi´on primitiva. Observaciones:
1. Puesto que PR es la menor clase de funciones que verifica (1) y (2), si deseamos probar una propiedad para todas las funciones recursivas podemos hacerlo por inducci´on sobre
funciones primitivas recursivas.
2. Si f ∈ PR, entonces f es total (se prueba por inducci´on sobre funciones primitivas recur-sivas).
3. Sabemos que PR ⊆ R ⊆ P. De hecho, como veremos m´as adelante, PR ⊂ R ⊂ P.
Ejemplos:
1. Para cada n ≥ 1, y cada a ∈ N la funci´on constante Cn
a : Nn → N, definida como Cn a(~x) = a, ∀~x ∈ Nn, es primitiva recursiva: Por inducci´on en a: a = 0: C0n(~x) = O(Πn1(~v)) a → a + 1: Cn a+1(~x) = S(Can(~x))
2. La funci´on predecesor pr : N → N, dada por:
pr(x) =
(
0 si x = 0
x − 1 si x 6= 0
Basta observar que pr(0) = 0 y pr(x + 1) = x, luego pr = R(0, Π2
1) (se trata de una
definici´on por recursi´on, en el caso especial n = 0).
3. La funci´on diferencia aritm´etica, −−• : N2 → N, definida como:
x −−• y =
(
0 si x ≤ y
x − y si x > y Sea f : N2 → N, dada por f = R(Π1
1, C(pr, Π33)), se verifica que f (x, y) = x −−• y (por
inducci´on sobre y). Luego −−• ∈ PR.
4. La funci´on signo, sg : N → N, dada por:
sg(x) =
(
0 si x = 0 1 si x 6= 0 Basta observar que sg = R(0, C2
5. La funci´on signo inverso, sg : N → N, dada por: sg(x) = ( 1 si x = 0 0 si x 6= 0 Ahora se tiene sg = R(1, C2 0) ∈ PR. 6. La funci´on suma: x + 0 = x x + (y + 1) = (x + y) + 1 sum(x, 0) = x
sum(x, y + 1) = sum(x, y) + 1 = S(sum(x, y))
Es decir, sum = R(Π1 1, C(S; Π31)) ∈ PR. 7. La funci´on producto: x · 0 = 0 x · (y + 1) = (x · y) + x f (x, 0) = 0 f (x, y + 1) = f (x, y) + x = sum(f (x, y), x) = sum(Π3 3(x, y, f (x, y)), Π31(x, y, , f (x, y)))
Es decir, f = R(O, C(sum; Π3
3, Π31)) ∈ PR.
8. F (x, y) = |x − y| es recursiva.
En efecto, F (x, y) = |x − y| = (x −−• y) + (y −−• x), luego
F = C(+; C( −−• ; Π21, Π22), C( −−• ; Π22, Π21))) ∈ R.
9. Existen funciones recursivas que no son totales.
Si f (x, y) = x + y, entonces g(x) = (µy)(f (x, y) = 0) = (
0 si x = 0
↑ si x 6= 0
A continuaci´on probaremos que toda funci´on recursiva es GOTO–computable. Proposici´on: Las funciones b´asicas son GOTO-computables.
Demostraci´on: Para cada funci´on b´asica definiremos un programa que la calcula: La funci´on nula: Y ← 0
Las funciones de proyecci´on: Y ← Xi
La funci´on sucesor: ½
Y ← X
Y ← Y + 1 ¤
Proposici´on: Sean f : Nk → N y g
1, ..., gk : Nn → N funciones GOTO-computables, entonces
h = C(f ; g1, ..., gk) es GOTO-computable.
Demostraci´on: El siguiente programa calcula la composici´on:
Z1← g1(X1, ..., Xn) .. . Zk← gk(X1, ..., Xn) Y ← f (Z1, ..., Zk) ¤ Proposici´on: Sean g : Nn → N y h : Nn+2 → N funciones GOTO-computables, entonces f =
R(g, h) es GOTO-computable.
Y ← g(X1, ..., Xn) [A] IF Xn+1= 0 GOT O E Z2 ← Y Y ← h(X1, ..., Xn, Z, Z2) Z ← Z + 1 Xn+1 ← Xn+1− 1 GOT O A ¤ Proposici´on: Si f : Nk+1− → N es GOTO–computable, entonces f
µtambi´en es GOTO–computable.
Demostraci´on: El siguiente programa calcula fµ(~x) = (µy)(f (~x, y) = 0):
[A] Z2 ← f (X1, ..., Xn, Y ) IF Z2 = 0 GOT O E
Y ← Y + 1 GOT O A
¤ Teorema: Toda funci´on recursiva es GOTO-computable.
Demostraci´on: Por inducci´on sobre funciones recursivas. Basta observar que, como acabamos de probar, las funciones b´asicas son GOTO-computables, y la clase de las funciones GOTO-computables
es cerrada bajo composici´on, recursi´on primitiva y µ–recursi´on. ¤
Problema: ¿Es toda funci´on GOTO-computable recursiva?
Veremos que la respuesta es S´I: la clase de las funciones GOTO-computables es igual a la de las funciones recursivas. De hecho, la clase P se identifica con la clase de las funciones computables algor´ıtmicamente. ´Este es el contenido de lo que se conoce como Tesis de Church:
Una funci´on es algor´ıtmicamente computable si y s´olo si es recursiva
Todos los modelos de computaci´on conocidos dan lugar a la misma clase de funciones computa-bles: la clase de las funciones recursivas.
3.2.
Predicados y conjuntos recursivos
Definici´on: Dado A ⊆ Nn, diremos que A es un conjunto (primitivo) recursivo si la funci´on caracter´ıstica de A es (primitiva) recursiva, es decir, si χA∈ PR.
La clase de los conjuntos recursivos se notar´a por R∗ y las de los conjuntos primitivos recursivos por PR∗. Como es habitual identificaremos predicados sobre Nncon subconjuntos de
Nn y, en consecuencia, R
∗ denotar´a tambi´en a la clase de los predicados recursivos y PR∗ a la
clase de los predicados primitivos recursivos. Teorema: Dado A ⊆ Nn, son equivalentes:
1. A ∈ R∗.
2. Existe f ∈ R tal que: ∀~x ∈ Nn(f (~x) = 0 ⇔ ~x ∈ A).
3. Existen k ∈ N y h ∈ R tales que: ∀~x ∈ Nn(~x ∈ A ⇔ h(~x) = k).
Demostraci´on:
(1 ⇒ 2) Sea f (~x) = 1 −−• χ
A(~x) = C1n(~x) −−• CA(~x) = C( −−• ; C1n, χA)(~x).
(3 ⇒ 1) Sean h y k como en (3). Entonces χA(~x) = sg(|h(~x) − Ckn(~x)|) y, por tanto,
χA= C(sg; C(F ; h, Ckn)) ∈ R, siendo F (x, y) = |x − y|. ¤
Proposici´on: Sea P1 y P2 dos predicados sobre Nn. Se verifica que:
1. Si P1, P2 ∈ R∗, entonces P1∨ P2, P1∧ P2 ∈ R∗. 2. Si P1∈ R∗, entonces ¬P1 ∈ R∗. Demostraci´on: 1. P1∧ P2 = P1· P2 = C(•; P1, P2) ∈ R. (P1∨ P2)(~x) = sg(P1(~x) + P2(~x)). 2. ¬P1(~x) = sg(P1(~x)) = C(sg; P1)(~x) ∈ R. ¤ Proposici´on: Sean f : Nn→ N y g : Nm→ N. Si f, g ∈ R, entonces
B = {(~x, ~y) ∈ Nn+m: f (~x) = g(~y)} ∈ R∗.
Demostraci´on: Basta observar que
(~x, ~y) ∈ B ⇔ f (~x) = g(~y)
⇔ |f (~x) − g(~y)| = 0
¤ Proposici´on: (Definici´on por casos) Sean f1, ..., fk∈ R, funciones de Nnen N, y sean A1, ..., Ak⊆
Nn conjuntos recursivos tales que:
k
[
i=1
Ai= Nn
i 6= j ⇒ Ai∩ Aj = ∅
Sea g : Nn→ N definida por: g(~x) =
f1(~x) si ~x ∈ A1 .. . ... fk(~x) si ~x ∈ Ak Entonces g ∈ R.
Demostraci´on: Basta observar que:
g(~x) = f1(~x) · χA1(~x) + f2(~x) · χA2(~x) + ... + fk(~x) · χAk(~x).
¤ Nota: En todos los resultados presentados hasta ahora en esta secci´on, si los conjunto y funciones considerados en las hip´otesis son primitivos recursivos, entonces las funciones y conjuntos que aparecen en la conclusi´on son tambi´en primitivos recursivos.
Proposici´on: Dada f : Nn→ N total, son equivalentes:
1. f ∈ R. 2. G(f ) ∈ R∗. Demostraci´on: (1 ⇒ 2) G(f ) = {(~x, y) : f (~x) = y} = {(~x, y) : f (~x) = Π1 1(y)} ∈ R∗ (2 ⇒ 1) f (~x) = (µy)((~x, y) ∈ G(f )), luego f ∈ R. ¤
3.3.
Suma, producto y cuantificaci´
on acotada
Definici´on: Dada f : Nn+1 → N, la suma acotada definida por f es la funci´on (Pf ) : Nn+1→ N,
definida por:
(Xf )(~x, y) =X
k≤y
f (~x, k)
El producto acotado definido por f es la funci´on (Qf ) : Nn+1→ N, definida por:
(Yf )(~x, y) = Y
k≤y
f (~x, k)
Proposici´on: Si f es (primitiva) recursiva, entoncesPf, Qf son (primitivas) recursivas.
Demostraci´on: Para la suma acotada consideremos la siguiente definici´on por recursi´on: (Pf )(~x, 0) = f (~x, 0) = g(~x) = f (~x, O(~x))
(Pf )(~x, y + 1) = (Pf )(~x, y) + f (~x, y + 1)
Y para el producto, la definici´on por recursi´on queda: (Qf )(~x, 0) = f (~x, 0)
(Qf )(~x, 0) = (Qf )(~x, y) · f (~x, y + 1)
¤ Proposici´on: R∗ es cerrada bajo cuantificaci´on acotada; es decir, si P es un predicado sobre Nn+1 recursivo, entonces (∃y)≤zP y (∀y)≤zP son recursivos. Lo mismo es cierto para PR∗.
Demostraci´on: Basta tener en cuenta que: (∃y)≤zP (~x, z) = sg( X y≤z P (~x, y)) = sg((XP )(~x, z)) (∀y)≤zP (~x, z) = Y y≤z P (~x, y) = (YP )(~x, z) ¤ Definici´on: Sea P (x1, ..., xn, y) un predicado sobre Nn+1. La funci´on definida por minimizaci´on
acotada a partir de P es la funci´on g : Nn+1 → N dada por:
g(~x, z) =
(
min{y ≤ z : P (~x, y)} si existe y ≤ z tal que P (~x, y)
0 en otro caso
Escribiremos g(~x, z) = miny≤zP (~x, y) = (µy)≤zP (~x, y)
Proposici´on: Si P es un predicado recursivo, entonces g ∈ R.
Demostraci´on: Consideremos la funci´on h : Nn+1 → N definida por µ–recursi´on de tal
modo que h(~x, z) = (µy)(P (~x, y) ∨ z > y). Entonces h ∈ R. Puesto que P es recursivo, el predicado (∃y)≤zP es recursivo y g queda determinada por la siguiente definici´on por casos:
g(~x, z) = h(~x, z) si (∃y)≤zP (~x, y) 0 en otro caso ¤
Corolario: Si P (~x, y) es un predicado (primitivo) recursivo sobre Nn+1, y h : Nn → N es
(primitiva) recursiva, entonces f : Nn→ N definida por:
f (~x) = (µy)≤h(~x)P (~x, y)
es (primitiva) recursiva.
Demostraci´on: Sea g(~x, z) = (µy)≤zP (~x, y), entonces f (~x) = g(~x, h(~x)). ¤
Ejemplos: 1. La funci´on cociente: bx yc = mint≤x((t + 1) · y > x) Ya que P (x, y, t) ≡ ((t + 1) · y > x) ≡ ((t + 1) · y −−• (x + 1) = 0) es primitivo recursivo. 2. La funci´on resto: rm(x, y) = x −−• (bx yc · y)
3. f : N → N, definida por f (x) =“el menor primo mayor que x”.
El predicado P rimo(y) ≡ (y > 1 ∧ (∀x)≤y(x - y ∨ x = y ∨ x = 1)), donde
x | y ≡ (rm(x, y) = 0) (y por tanto x - y ≡ ¬(x | y) es primitivo recursivo).
Sabemos que f (x) ≤ x! + 1, por tanto, f (x) = (µy)≤x!+1(P rimo(y) ∧ y > x)
4. Pn=“el n-´esimo primo”, se define por recursi´on como:
(
p0 = 0
pn+1 = f (pn)
3.4.
N´
umeros de G¨
odel
Denotaremos por hx, yi = 2x· (2y + 1) −−• 1, la llamada funci´on par, que verifica:
Es una funci´on de N2 en N biyectiva y primitiva recursiva. Si definimos l, r : N → N como
l(z) = (µx)≤z((∃y)≤z(z = hx, yi)), r(z) = (µy)≤z((∃x)≤z(z = hx, yi))
se tiene que: (a) l, r ∈ PR, (b) hl(z), r(z)i = z, (c) l(hx, yi) = x, (d) r(hx, yi) = y, (e) l(z), r(z) ≤ z.
Definici´on: Dada (k1, ..., kn) ∈ Nn, el n´umero de G¨odel de (k
1, ..., kn) se define como: [k1, ...., kn] = n Y i=1 pkii
Por tanto a cada sucesi´on num´erica finita se le asocia un n´umero (que la codifica), y cada n´umero puede ser visto como una sucesi´on.
Ejemplos:
[3, 1, 2, 0, 1] = p3
1· p12· p23· p04· p51= 23· 31· 52· 70· 111 = 8 · 3 · 25 · 11 = 6600
Teorema: [a1, ..., an] = [b1, ..., bn] ⇔ ∀i (1 ≤ i ≤ n → ai= bi)
Definici´on: Se define la longitud de una sucesi´on como:
Lt(x) = (µi)≤x((x)i 6= 0 ∧ (∀j)≤x(j ≤ i ∨ (x)j = 0))
donde (x)i = (µt)≤x¬(pt+1i | x).
Observaciones:
Las funciones Lt(x) y (x)i son primitivas recursivas.
Para todo i ≥ 1 se tiene que (0)i = 0 y (1)i= 0.
Si k > Lt(x), entonces (x)k= 0. ([a1, ..., an])i= ( ai 1 ≤ i ≤ n 0 en otro caso Si n ≥ Lt(x), entonces [(x)1, ..., (x)n] = x.
3.5.
Codificaci´
on de programas: Aritmetizaci´
on
A continuaci´on veremos c´omo asignar un n´umero a cada GOTO-programa de modo que se establezca una aplicaci´on biyectiva entre el conjunto de los GOTO-programas y N.
1. Comenzamos asignando un n´umero no nulo a cada variable y etiqueta. Para ello, ordenamos las variables y etiquetas de la siguiente forma:
Y, X1, Z1, X2, Z2, ..., Xn, Zn, ...
A1, B1, C1, D1, E1, A2, B2, C2, ...
Dada un variable, V , o etiqueta, L, el n´umero correspondiente lo denotaremos por #(V ) o #(L), y se define como:
#(Y ) = 1, #(Xi) = 2i, #(Zi) = 2i + 1
#(Ai) = 5(i − 1) + 1, #(Bi) = 5(i − 1) + 2
#(Ci) = 5(i − 1) + 3, #(Di) = 5(i − 1) + 4, #(Ei) = 5i
As´ı, a cada variable corresponde un ´unico n´umero, y a cada n´umero una ´unica variable; y lo mismo puede decirse de las etiquetas.
2. Ahora asignamos un n´umero a cada instrucci´on de GOTO (etiquetada o no), de la siguiente forma:
Si I es una instrucci´on de GOTO, el n´umero de I es: #(I) = ha, hb, cii donde:
a) Si I tiene etiqueta L, entonces a = #(L) (a = 0 si no tiene etiqueta).
b) Si V = var(I), entonces c = #(V ) − 1.
Si I es del tipo V ← V , entonces b = 0. Si I es del tipo V ← V + 1, entonces b = 1. Si I es del tipo V ← V − 1, entonces b = 2.
Si I es del tipo IF V 6= 0 GOT O L, entonces b = #(L) + 2.
De este modo se define una aplicaci´on biyectiva del conjunto de instrucciones de GOTO en N.
Ejemplos:
I1 : X ← X + 1 → #(I1) = h0, h1, 1ii = h0, 5i = 10
I2 : [B] X ← X − 1 → #(I2) = h2, h2, 1ii = h2, 11i = 91
#(I3) = 231, hemos de calcular x, y tales que hx, yi = 231, para ello, buscamos el mayor
x tal que 2x | (231 + 1), en nuestro caso x = 3, y despejamos el valor de y, resultando
que 231 = h3, 14i; repetimos el proceso con 14, resultando que 14 = h0, 7i, por tanto 231 = h3, h0, 7ii, de donde: I3: [C] X4← X4.
3. Por ´ultimo asignamos un n´umero a cada programa P de GOTO. Si P es I1, ..., In entonces:
#(P ) = [#(I1), ..., #(In)] − 1
Todo n´umero determina un programa y n´umeros distintos determinan programas distintos: Dado n ∈ N, escribimos la factorizaci´on prima de n + 1 = Qki=1paii . Si I1, ..., Ik son
instrucciones tales que #(Ii) = ai, entonces el programa P : I1, ..., Ik es tal que #(P ) = n.
Si n1, n2 son dos n´umeros que codifican el mismo programa P , entonces:
k = Lt(n1+ 1) = Lt(n2+ 1) ∧ ∀ i ≤ k (n1+ 1)i = (n2+ 1)i Luego n1+ 1 = Qk i=1p#(Ii i)= QLt(n1+1) i=1 p#(Ii i)= QLt(n2+1)
i=1 p#(Ii i)= n2+ 1, y as´ı, n1 = n2.
Ejemplo: Se P el programa:
[B] X ← X − 1
IF X 6= 0 GOT O B
Entonces el c´odigo asociado es: #(I1) = 91, #(I2) = 94, y por tanto, #(P ) = [91, 94]−1 =
291· 394− 1
3.6.
El teorema de la forma normal
Teorema: Para cada n > 0 existe una funci´on, Un : Nn+1− → N, GOTO-computable tal que
para cada GOTO-programa, P , si #(P ) = m entonces:
∀ ~x ∈ Nn, Un(~x, m) ' ψP(n)(~x)
Demostraci´on: La demostraci´on consiste en escribir un programa, Un, que para cada
pro-grama, P , simule P sobre cada entrada X1, ..., Xn. Tomaremos entonces Un= ψ(n+1)Un .
Dado un programa, P , una computaci´on de P es una sucesi´on de descripciones instant´aneas cada una de las cuales es el sucesor de la descripci´on anterior. Cada descripci´on instant´anea est´a a su vez dada por un n´umero (la instrucci´on que debe ejecutarse a continuaci´on) y un estado (que guarda los valores de las variables que est´an siendo usadas en el momento actual).
Dado que cada variable tiene asignado un n´umero distinto de 0, a trav´es de la sucesi´on:
Y, X1, Z1, X2, Z2, ..., Xn, Zn, ...
podemos representar un estado, σ, por un n´umero:
m = [σ(Y ), σ(X1), σ(Z1), ...]
Por ejemplo, σ = {Y = 3, X1 = 2, Z1 = 0, X2 = 1} corresponde al n´umero de G¨odel: [3, 2, 0, 1] = 23325071 = 504.
Modificar el estado de una descripci´on instant´anea a la siguiente s´olo conlleva sumar o restar 1 a una de las variables , para llevar esto a cabo solo debemos multiplicar o dividir por el primo adecuado. Por ejemplo, en el caso anterior, sumar 1 a Z1 es equivalente a hacer el producto
m · 5 = [3, 2, 1, 1]; restar 1 a X1 es equivalente a hacer el calcular m3 = [3, 1, 0, 1]; sumar 1 a Z3
es equivalente a hacer el producto m · 17 = [3, 1, 0, 1, 0, 0, 1].
Para guardar una descripci´on instant´anea del programa P necesitamos dos variables:
K: para guardar el n´umero de la siguiente instrucci´on a ejecutar.
S: para guardar el estado actual de las variables (n´umero de G¨odel).
El programa Unrecibe como entrada los valores X1, ..., Xn y el n´umero que codifica el programa
P (en la variable Xn+1) y asignamos valores iniciales a las variables auxiliares b´asicas:
Z ← Xn+1+ 1 (Z = [#(I1), ..., #(Ir)])
S ←Qni=1(p(2i))Xi (estado inicial:[0, X
1, 0, X2, 0, ..., 0, Xn])
K ← 1
[C] IF K = Lt(Z) + 1 ∨ K = 0 GOT O F
Creamos un bucle que ir´a pasando de una descripci´on instant´anea a la siguiente hasta alcanzar una descripci´on instant´anea terminal. El valor de K = 0 se utilizar´a para las etiquetas de salida.
En Z = [#(I1), ..., #(Ir)] est´an codificadas las instrucciones de P .
La K-´esima instrucci´on es (Z)K = #(IK), que adem´as, tendr´a la forma: #(IK) = ha, hb, cii, donde a, b y c reflejan la estructura de dicha instrucci´on seg´un hab´ıamos visto en la secci´on anterior.
Si llamamos U = r((Z)K), entonces U = hb, ci, y por tanto, r(U ) + 1 = c + 1 = #(var(IK)), y l(U ) = b, el tipo de instrucci´on que ocupa la l´ınea K.
El programa Universal Un quedar´ıa entonces:
Z ← Xn+1+ 1 S ← Πni=1(p(2i))Xi K ← 1 [C] IF K = Lt(Z) + 1 ∨ K = 0 GOT O F U ← r((Z)K) P ← pr(U )+1 IF l(U ) = 0 GOT O N IF l(U ) = 1 GOT O A IF ¬(P | S) GOT O N IF l(U ) = 2 GOT O M
k ← mini≤Lt(Z)[l((Z)i) + 2 = l(U )]
GOT O C [M ] S ← bS Pc GOT O N [A] S ← S · P [N ] K ← K + 1 GOT O C [F ] Y ← (S)1 ¤
Teorema: Para cada n > 0 el predicado ST P(n)(x1, ..., xn, y, t) definido en Nn+2 como:
ST P(n)(x1, ..., xn, y, t) ⇔
(
existe una computaci´on del programa que codifica y de longitud ≤ t + 1 comenzando por x1, ..., xn
es primitivo recursivo.
Demostraci´on: Una computaci´on es una sucesi´on de descripciones instant´aneas cada una de las cuales es el sucesor de la anterior. Cada descripci´on puede escribirse como un par hi, zi, donde i refleja el n´umero de l´ınea y z la codificaci´on del estado de las variables. Y viceversa, Todo n´umero puede ser visto como una descripci´on instant´anea. Veamos c´omo definir una funci´on
Suc : N2 → N que nos devuelva el c´odigo de la descripci´on instant´anea sucesora.
En primer lugar describiremos algunas funciones ´utiles:
LBL(i, y) = l((y + 1)i), que refleja la etiqueta de la i-´esima instrucci´on del programa codificado por y (0 si no est´a etiquetada).
V AR(i, y) = r(r((y +1)i))+1, que refleja la variable de la i-´esima instrucci´on del programa codificado por y.
IN ST R(i, y) = l(r((y + 1)i)), que refleja el tipo de instrucci´on de la l´ınea i-´esima del programa codificado por y.
LBL0(i, y) = l(r((y + 1)
i)) −−• 2, que refleja la etiqueta a la que env´ıa la instrucci´on i-´esima
del programa en caso de ser de tipo condicional.
Est´a claro que todas estas funciones con primitivas recursivas. La definici´on de la funci´on sucesora ser´ıa (k es la longitud de P ):
suc((i, σ), P ) = (i + 1, σ) si i ≤ k ∧ Ii es de tipo V ← V (i + 1, σ+) si i ≤ k ∧ I i es de tipo V ← V + 1 (i + 1, σ−) si i ≤ k ∧ Ii es de tipo V ← V − 1 (j, σ) si i ≤ k ∧ Ii es de tipo IF V 6= 0 GOT O L ∧ j = m´ın{n ≤ k : L es la etiqueta de In} (k + 1, σ) en otro caso La expresi´on num´erica de cada caso anterior ser´ıa:
SKIP (x, y) ≡ (IN ST R(l(x), y) = 0 ∧ l(x) ≤ Lt(y + 1)) ∨
∨ (IN ST R(l(x), y) ≥ 2 ∧ (pV ar(l(x),y) | r(x))) IN CR(x, y) ≡ IN ST R(l(x), y) = 1
DECR(x, y) ≡ IN ST R(l(x), y) = 2 ∧ pV ar(l(x),y) | r(x) CON D(x, y) ≡ IN ST R(l(x), y) > 2 ∧ pV ar(l(x),y) | r(x) ∧
(∃i)≤Lt(y+1) (LBL(i, y) = LBL0(l(x), y))
Quedando, por tanto, la funci´on sucesor como la definici´on por casos:
Suc(x, y) = hl(x) + 1, r(x)i si SKIP (x, y) hl(x) + 1, r(x) · pV ar(l(x),y)i si IN CR(x, y) hl(x) + 1, bpV ar(l(x),y)r(x) ci si DECR(x, y)
hm´ınk≤Lt(y+1) (LBL(k, y) = LBL0(l(x), y)), r(x)i si CON D(x, y)
hLt(y + 1) + 1, r(x)i en otro caso Por tanto, Suc ∈ PR, ya que se tiene de una definici´on por casos primitiva recursiva.
Sea ahora IN IT(n)(x1, ..., xn) = h1, Qn i=1(p2i)xii, y definimos: ( DESCIN ST(n)(x 1, ..., xn, y, 0) = IN IT(n)(x1, ..., xn) DESCIN ST(n)(x1, ..., xn, y, k + 1) = Suc(DESCIN ST(n)(x1, ..., xn, y, k), y)
Por tanto, DESCIN ST ∈ PR. Por ´ultimo, si definimos la propiedad ser sucesi´on terminal como:
T ERM (x, y) ≡ (l(x) > Lt(y + 1))
que es primitiva recursiva, se obtiene que:
ST P(n)(x1, ..., xn, y, t) ⇔ T ERM (DESCIN ST (x1, ..., xn, y, t), y)
¤ Teorema de la forma normal: (Kleene) Existe G ∈ PR, y para cada n ≥ 1 un predicado primitivo recursivo Tn⊆ Nn+2 tal que para cada funci´on f : Nn− → N GOTO-computable existe
e ∈ N verificando:
1. f (~x) ↓ ⇔ (∃z)(Tn(~x, e, z))
2. f (~x) ' G((µz)Tn(~x, e, z))
Demostraci´on: Dada f en las condiciones anteriores, sea P un programa tal que f = ψ(n)P , y sea e = #(P ). Entonces, si f (~x) ↓, existe t ∈ N tal que ST P(n)(~x, e, t), y adem´as si f (~x) = m,
entonces
m = (r(DESCIN ST(n)(x1, ..., xn, e, t)))1
Sea Tn(~x, e, z) el predicado:
ST P(n)(x1, ..., xn, e, r(z)) ∧ (r(DESCIN ST(n)(x1, ..., xn, e, r(z)))1= l(z))
Entonces, Tn∈ PR y verifica el teorema. ¤
Corolario: Una funci´on es GOTO-computable si y s´olo si es recursiva.
Demostraci´on: Nos falta probar que si es GOTO-computable entonces es recursiva. Para ello, dada f : Nn → N GOTO-computable, existe e ∈ N tal que f (~x) ' G((µz)T
n(~x, e, z)). Puesto que
G ∈ PR, Tn∈ PR∗, se tiene que h(~x) = (µz)Tn(~x, e, z) es recursiva, y por tanto f ∈ P. ¤ Corolario: R es la menor clase de funciones, C, que verifica:
1. Contiene a las funciones b´asicas.
2. Es cerrada bajo composici´on y recursi´on primitiva.
3. Si g ∈ C y ∀~x ∃y (g(~x, y) = 0), entonces gµ∈ C.
Demostraci´on: Obviamente, si C es una clase verificando las condiciones anteriores, en-tonces C ⊆ R.
Dada f : Nn → N, f ∈ R, por el teorema de la forma normal existe e ∈ N tal que:
f (~x) ↓ ⇔ (∃z)(Tn(~x, e, z)), y f (~x) = G((µz)(Tn(~x, e, z))). Sea g(~x, z) = 1 −−• T
n(~x, e, z), entonces g ∈ R y ∀~x ∃z (g(~x, z) = 0). Luego h = gµ∈ C, y se
tiene el resultado. ¤
Definici´on: La funci´on recursiva de ´ındice e (en n variables) es:
ϕ(n)e (~x) = Un(~x, e) = G((µz)Tn(~x, e, z))
Teorema: Para cada n ∈ N, n ≥ 1, la sucesi´on hϕne : e ∈ Ni es una enumeraci´on efectiva de las funciones recursivas n-arias, es decir:
∀e ∈ N, ϕn
e ∈ P(n)
Si f ∈ P(n), entonces ∃e ∈ N, ϕne ' f
(Funci´on universal) Existe Un∈ P(n), tal que ∀~x ∈ Nn, U
n(~x, e) ' ϕne(~x)
Teorema de la funci´on universal: Existe U : N2− → N recursiva tal que: ∀n ∀f ∈ P(n) ∃e ∈ N(f (~x) ' U ([~x], e))
Demostraci´on: Basta cambiar en el programa Un las dos primeras l´ıneas por:
Z ← X2+ 1
S ←QLt(X1)
i=1 (p2i)(X1)i
Lo que nos da un programa U , tal que la funci´on buscada es ψU(2). ¤
La funci´on de Ackerman:
Definamos las siguientes funciones por recursi´on:
A0(x) = x + 2
An+1(x) = Axn(2) =
x veces
z }| {
An(2)(....(An(2))...)
Esto define una sucesi´on de funciones An: N → N, todas ellas primitivas recursivas. Sea A : N2 → N, definida por A(n, x) = A
n(x), esto es: A(0, y) = y + 2 A(n + 1, 0) = 2
A(n + 1, y + 1) = A(n, A(n + 1, y))