Tema 5: Funciones recursivas Dpto. Ciencias de la Computación e Inteligencia Artificial Universidad de Sevilla Lógica y Computabilidad Curso 2005 06 LC, 2005 06 Funciones Recursivas 5.1
Procedimientos de definición Estudiaremos procedimientos para definir funciones, que nos permitan obtener nuevas funciones computables a partir de otras funciones computables ya conocidas. Es deseable que estos procedimientos de definición permitan obtener todas las funciones GOTO computables a partir de algunas funciones básicas cuya computabilidad sea indiscutible. Esto proporcionará una caracterización de las funciones GOTO-computables independiente de todo modelo de computación particular. Consideramos tres procedimientos básicos: Composición. Recursión primitiva. µ recursión (o minimización). LC, 2005 06 Funciones Recursivas 5.2
Composición Composición: Dadas g : N n N, h 1,.., h n : N m N, decimos que f : N m N es la composición de g y h 1,..., h n, si Para todo x N m, f ( x) = g(h 1 ( x),..., h n ( x)) Usamos como notación f = C(g; h 1,..., h n ). Lema. GCOMP es cerrado bajo composición: En efecto, sean g : N n N, h 1,..., h n : N m N G-computables. El siguiente programa calcula f = C(g; h 1,..., h n ): Z 1 h 1 (X 1,..., X m ). Z n h n (X 1,..., X m ) Y g(z 1,..., Z n ) LC, 2005 06 Funciones Recursivas 5.3
Recursión primitiva (I) Recursión Primitiva: Dadas g : N m N, h : N m+2 N, decimos que f : N m+1 N se define por recursión primitiva a partir de g y h (y escribimos f = R(g, h)), si Para todo x N m, y N { f ( x, 0) = g( x) f ( x, y + 1) = h( x, y, f ( x, y)) Esta definición se extiende al caso m = 0: { f (0) = k f (x + 1) = h(x, f (x)) donde k N. En este caso escribimos: f = R(k, h), y diremos que f se obtiene por recursión primitiva a partir de la constante k y de h. LC, 2005 06 Funciones Recursivas 5.4
Recursión primitiva (II) Lema. GCOMP es cerrado bajo recursión primitiva: En efecto, sean g : N m N, h : N m+2 N G-computables. El siguiente programa calcula f = R(g; h): [A] Y g(x 1,..., X m ) IF X m+1 = 0 GOTO E Y h(x 1,..., X m, Z, Y ) Z Z + 1 X m+1 X m+1 1 GOTO A LC, 2005 06 Funciones Recursivas 5.5
µ recursión (I) µ-recursión. Sea f : N n+1 N, (n 1). La función definida por µ recursión a partir de f es la función f µ : N n N dada por { min{y : f ( x, y) = 0 z < y (f ( x, z) )} si existe f µ ( x) = e.o.c. Nota. Usualmente escribiremos: µy(f ( x, y) = 0). Lema. GCOMP es cerrada bajo µ recursión. En efecto, sea f : N n+1 N, (n 1), GOTO computable. El siguiente programa calcula f µ : [A] Z f (X 1,..., X n, Y ) IF Z = 0 GOTO E Y Y + 1 GOTO A LC, 2005 06 Funciones Recursivas 5.6
µ recursión (II) Si θ es un predicado n + 1-ario, definimos: { min{y : θ( x, y)} si existe el minimo θ µ ( x) µy(θ( x, y)) = e.c.o.c. Lema. θ GCOMP = µy(θ( x, y)) GCOMP Observaciones: La µ recursión permite obtener funciones que no son totales aunque las de partida sí lo sean. Ejemplo. Sea f : N 2 N la función GOTO-computable { 1 si x = 0 f (x, y) = 0 e.o.c. { 0 si x 0 Entonces, f µ (x) = (µy)(f (x, y) = 0) = si x = 0 LC, 2005 06 Funciones Recursivas 5.7
Funciones básicas Llamaremos funciones básicas a las siguientes funciones: Siguiente: S : N N; S(x) = x + 1 Idénticamente nula: O : N N; O(x) = 0 Proyecciones: Para cada i, n N (1 i n), n i : N N; n i (x 1,..., x n ) = x i Lema. Las funciones básicas son G-computables: Siguiente, S : { X X + 1 Y X Nula, O : Programa vacío, p Proyecciones, (n) j : Y X j LC, 2005 06 Funciones Recursivas 5.8
Funciones recursivas Definición. La clase de las funciones recursivas, P, es la menor clase de funciones que contiene a las funciones básicas y es cerrada bajo composición, recursión primitiva y µ recursión. La clase de las funciones recursivas totales se denota por R. Denotaremos por P (n) a la clase de las funciones recursivas de aridad n, y por R (n) a la clase de las funciones recursivas totales de aridad n. La clase de las funciones primitivas recursivas, PR, es la menor clase de funciones que contiene a las funciones básicas y es cerrada bajo composición y recursión primitiva. Lema. Toda función primitiva recursiva es total. LC, 2005 06 Funciones Recursivas 5.9
Ejemplos (I) Las siguientes funciones son (primitivas) recursivas: La función identidad IN : N N Las funciones constantes: C n a : N n N, Ca n ( x) = a La función predecesor: pr : N N { 0 si x = 0 pr(x) = x 1 si x > 0 La función diferencia reducida: : N 2 N { x 0 si x y y = x y e.c.o.c. La función signo: sg : N N sg(x) = { 0 si x = 0 1 e.c.o.c. LC, 2005 06 Funciones Recursivas 5.10
Ejemplos (II) Las siguientes funciones son (primitivas) recursivas: La función signo inverso: sg : N N sg (x) = 1 sg(x) La función suma: + : N 2 N +(x, y) = x + y La función producto: : N 2 N (x, y) = x y La función mínimo: min : N 2 N { x si x y min(x, y) = y e.c.o.c. La función máximo: max : N 2 N { x si x y max(x, y) = y e.c.o.c. LC, 2005 06 Funciones Recursivas 5.11
Ejemplos (III) La función distancia: : N 2 N { x y si x y x y = y x e.c.o.c. La función exponencial: exp : N 2 N { 1 si x = 0 y = 0 exp(x, y) = x y e.c.o.c. La función factorial: fact : N N 1 si x = 0 fact(x) = j e.c.o.c. 1 j x LC, 2005 06 Funciones Recursivas 5.12
GOTO y P Proposición. P GCOMP. Observaciones: PR R P GCOMP Hay funciones no totales que son recursivas y, por tanto, GOTO computables. Hay funciones totales y GOTO computables que NO son PR, por ejemplo, la función de Ackermann. La función Ackermann, A : N 2 N, se define por A(n, x) = A n (x), siendo para cada n N { A0 (x) = x + 1 ( x N) A n+1 (x) = (A n A n (x+1)... A n )(1) ( x N) LC, 2005 06 Funciones Recursivas 5.13
Predicados GOTO computables y recursivos Un predicado sobre N es recursivo (resp. primitivo recursivo o GOTO computable) si la función que lo define está en R (resp. en PR o en GCOMP). Un conjunto A N n es recursivo (resp. primitivo recursivo o GOTO computable) si su función característica, C A, está en R (resp. en PR o en GCOMP). Ejemplos: Los conjuntos y N n son PR. Los predicados: θ1 (x, y) x = y; θ 2 (x, y) x y; θ 3 (x, y) x < y son PR. Dada f : N n N; f R, los predicados (n + 1)-arios siguientes son recursivos: θ( x, y) f ( x) = y; θ ( x, y) f ( x) y; θ ( x, y) f ( x) < y. LC, 2005 06 Funciones Recursivas 5.14
Operaciones con conjuntos y predicados Proposición. Sean θ, θ predicados sobre N, n arios y recursivos entonces θ, θ θ, θ θ, θ θ y θ θ son predicados recursivos. θ( x) = sg(θ( x)). (θ θ )( x) = θ( x) θ ( x) (θ θ )( x) = sg(θ( x) + θ ( x)) θ θ θ θ. θ θ θ θ θ θ Corolario. Si A, B N n son conjuntos recursivos, entonces: N n A; A B; A B son recursivos. CN n A = C A ; CA B = C A C B ; CA B = C A C B LC, 2005 06 Funciones Recursivas 5.15
Definiciones por casos Proposición. Sean k 2 y f 1,..., f k : N n N funciones reccursivas totales. Sea {A 1,..., A k } una partición de N n en conjuntos recursivos, es decir, N n = k i=1 A i y i, j = 1,..., k, i j A i A j = Entonces, la función g : N n N definida por f 1 ( x) si x A 1 g( x) =... f k ( x) si x A k es recursiva total. Basta observar que g = f1 C A1 +... + f k C Ak que está en R. La proposición anterior puede expresarse con predicados recursivos θ 1,..., θ k, que sean exhaustivos y excluyentes, es decir, tales que, para todo x N n : θ 1 ( x) +... + θ k ( x) = 1 LC, 2005 06 Funciones Recursivas 5.16
Suma y producto acotados Sea f : N n+1 N total. Definimos: Suma acotada: f ( x, y) = ( x, z) z yf Producto acotado: f ( x, y) = z yf ( x, z) Proposición. Si f R (n+1) entonces f, f R (n+1). Observaciones: 1. En vez de la última variable, podría utilizarse cualquier otra como cota de la suma o del producto. 2. Para n = 0: f (y) = z y f (z) y f (y) = z y f (z). Corolario. Si f : N n+1 N; g : N n+k N están en R, entonces también están en R las funciones F 1, F 2 : N n+k N definidas por: F 1 ( x, y) = f ( x, z); F 2 ( x, y) = f ( x, z) z g( x, y) z g( x, y) LC, 2005 06 Funciones Recursivas 5.17
Cuantificación acotada Proposición. Sea θ R un predicado n+1-ario. Los siguientes predicados son recursivos: θ 1 ( x, y) z y θ( x, z); θ 2 ( x, y) z y θ( x, z) En efecto: θ 1 ( x, y) = z y θ( x, z); θ 2 ( x, y) = sg( z yθ( x, z)) Ejemplos. Los siguientes predicados son recursivos (de hecho, PR): Predicado de divisibilidad, x y: θ(x, y) z y(y = z x) Predicado de primalidad: primo(x) (x > 1) t x((t x) (t = 1 t = x)) LC, 2005 06 Funciones Recursivas 5.18
Minimización acotada (I) Definición. Sea θ( x, y) un predicado (n + 1) ario. Definimos la función θµ : N n+1 N, así: { θµ( x, min{z y : θ( x, z)} si existe tal mínimo y) = 0 e.c.o.c. Usualmente escribiremos: (µz) y (θ( x, z)) y diremos que θµ se obtiene de θ por minimización acotada. Definición. Sea f ( x, y) una función (n + 1) aria. Definimos la función de aridad n + 1, fµ, así: f µ ( x, y) = (µz) y (f ( x, z) = 0) Decimos que f µ se obtiene de f por minimización acotada. Proposición. Si θ R (n+1) entonces θµ R (n+1). Si f R (n+1) entonces f µ R (n+1). LC, 2005 06 Funciones Recursivas 5.19
Minimización acotada (II) Ejemplos. La función cociente: qt(x, y) = (µt) x (x < (t + 1) y). La función resto. rm(x, y) = { x (y qt(x, y)) si y 0 0 si y = 0 La sucesión de números primos. Sea p : N N la función tal que p(0) = 0 y para todo n 1, p(n) = p n es el n ésimo primo. Lema. n (pn+1 1 + p n!). Por tanto, 1 + p(x)! es una cota para p(x + 1) y tenemos: { p(0) = 0 p(x + 1) = (µy) (1+p(x)!) (y > p(x) primo(y)) Luego p PR. LC, 2005 06 Funciones Recursivas 5.20
Observación Observación. Los resultados presentados sobre sumas y productos acotados, cuantificación acotada y minimización acotada son también válidos para predicados y funciones primitivas recursivas (y también para predicados GOTO computables y funciones GOTO computables totales). El siguiente resultado NO es válido para funciones primitivas recursivas. Teorema. Sea f : N n N. Son equivalentes: f R (n). El grafo de f es un conjunto recursivo. G(f ) = {( x, y) N n+1 : f ( x) = y} LC, 2005 06 Funciones Recursivas 5.21
Codificación de sucesiones finitas Definición. Una codificación de N n a partir de N, es una función total f : N n N que verifica: 1. f es PR e inyectiva. 2. Para cada i, 1 i n, la función total, g i : N N: { ai si x rang(f ) x = f (a g i (x) = 1,..., a n ) 0 e.c.o.c. es PR. Sea, ahora, N = {ε} N = {ε} N N 2... N k..., donde ε es la sucesión vacía (de longitud 0). Definición. Una función f : N N, codifica N a partir de N, si: f es total. n 1, f N n es una codificación de N n, a partir de N. LC, 2005 06 Funciones Recursivas 5.22
La función par La función par es la función total, : N 2 N definida por x, y = 2 x (2y + 1) 1 La función par es PR y biyectiva. Para todo x y para todo y se verifica: x x, y, y x, y Existen l, r : N N tales que si z = x, y, l(z) = x; r(z) = y z = l(z), r(z) l y r son funciones decodificadoras de,. Las funciones l, r son PR (1) Nota. Usando la función par podemos codificar N 3 a partir de N: Y, en general, N k a partir de N. (x, y, z) x, y, z LC, 2005 06 Funciones Recursivas 5.23
Números de Gödel Sea {p n : n 1} la sucesión de números primos y [ ] : N N la función definida así: { [ε] = 1 [a 1,..., a n ] = p a 1 1...pan n Diremos que [a 1,..., a n ] es el número de Gödel de la sucesión finita a 1,..., a n. Propiedades: La función [ ] codifica N a partir de N. La función [ ] no es inyectiva. rang( [ ])= N {0}. Cada número natural codifica infinitas sucesiones. Para todo i, 1 i n se verifica: ai [a 1,..., a n ]. LC, 2005 06 Funciones Recursivas 5.24
Las funciones componente y longitud Lema. Si x N {0, 1} existen unos únicos a 1,..., a n N, a n 0, tales que x = [a 1,..., a n ]. Si i {1,..., n} el número ai es la componente i ésima de x. Escribiremos (x) i = a i. Si i / {1,..., n} entonces será: (x)i = 0. Definición. Denominaremos función componente a la función: ( ) : N 2 N, definida así: (x) i = (µt) x ( (p t+1 i x)) La función componente es PR. Definición. Definimos la función longitud, Long : N N, así: Long(x) = (µi) x ((x) i 0 j x (j > i (x) j = 0)) La función longitud es PR. LC, 2005 06 Funciones Recursivas 5.25
Codificación Nuestro siguiente objetivo es probar que P = GCOMP. Para ello será necesario manejar programas de manera efectiva, es decir, manejar los programas mediante programas. Esto requiere la codificación de programas mediante números. Codificaremos las instrucciones GOTO utilizando la función par. Codificaremos los programas GOTO mediante la función de Gödel [ ], usando la codificación de instrucciones previa. LC, 2005 06 Funciones Recursivas 5.26
Codificación de las Instrucciones (I) Una instrucción consta básicamente de tres elementos: Etiqueta, Variable, y Formato (o tipo) de la instrucción. Codificación de las etiquetas: Ordenamos las etiquetas: A 1, B 1, C 1, D 1, E 1, A 2,..., E 2, A 3,...E 3,... Asignamos un número a cada etiqueta como sigue: (k 1) : #(A k ) = 5(k 1) + 1 #(B k ) = 5(k 1) + 2 #(C k ) = 5(k 1) + 3 #(D k ) = 5(k 1) + 4 #(E k ) = 5k LC, 2005 06 Funciones Recursivas 5.27
Codificación de las Instrucciones (II) Codificación de las variables: Ordenamos las variables: Y, X 1, Z 1, X 2, Z 2, y asignamos un número a cada variable según este orden: Codificación del Formato: #(Y ) = 1 #(X k ) = 2k (k 1) #(Z k ) = 2k + 1 (k 1) 0 si el formato es V V 1 si el formato es V V + 1 2 si el formato es V V 1 #(L) + 2 si el formato es IF V 0 GOTO L LC, 2005 06 Funciones Recursivas 5.28
Codificación de las Instrucciones (III) Definición. Sea I una instrucción GOTO. Definimos su código #(I ) como: #(I ) = a, b, c en donde: a = { 0 si I no tiene etiqueta #(L) si I tiene etiqueta L b = Código del formato de I 0 si formato V V 1 si formato V V + 1 2 si formato V V 1 #(L) + 2 si formato IF V 0 GOTO L c = #(V ) 1 si V es la variable de I. Todo n N codifica una única instrucción. LC, 2005 06 Funciones Recursivas 5.29
Codificación de los Programas Sea P = (I 1, I 2,..., I n ). Definimos: #(P) = [#(I 1 ), #(I 2 ),..., #(I n )] 1 Si P es el programa vacío, #(P ) = [ε] 1 = 0 Observaciones: Puesto que #(Y Y ) = 0, 0, 0 = 0 y [a 1,..., a n ] = [a 1,..., a n, 0,..0], se tiene: [#(I 1 ),..., #(I n )] = [#(I 1 ),..., #(I n ), #(Y Y ),..., #(Y Y )] y, por tanto, la codificación no sería inyectiva si los programas GOTO pudiesen terminar con la instrucción Y Y. Por eso no se permite que dicha instrucción sea la última. Lema. Todo n N codifica un único programa GOTO. LC, 2005 06 Funciones Recursivas 5.30
Codificación de las d.i. Para describir la computación de P sobre x codificaremos numéricamente las descripciones instantáneas. Codificación de descripciones instantáneas. Estados: Dado el estado σ = {V1 = r 1, V 2 = r 2,..., V n = r n }, con #(V i ) = i, definimos el código de σ así: #(σ) = [r 1,..., r n ] Descripciones instantáneas: Sea (i, σ) una d.i. Definimos su código como: #(i, σ) = i, #(σ) LC, 2005 06 Funciones Recursivas 5.31
Programas universales Sean P GOTO y x N n. Es computable la función: ( x, #(P)) [[P]] (n) ( x)? Un programa que calcule esta función se denomina programa universal. Si fijamos la aridad y designamos por U n a dicho programa, tendremos: [[U n ]] (n+1) ( x, #(P)) = [[P]] (n) ( x) Esencialmente, un programa universal es un intérprete de GOTO, que simula la ejecución del programa P sobre la tupla x que recibe como entrada. Notación: U n = [[U n ]] (n+1). Teorema. Para cada n 1, existe un programa U n tal que para todo x N n y todo programa GOTO, P, se tiene [[U n ]] (n+1) ( x, #(P)) = [[P]] (n) ( x) LC, 2005 06 Funciones Recursivas 5.32
El programa universal U n Z X n+1 + 1 S n i=1 (p 2i) X i K 1 (1) [C] IF K = Long(Z) + 1 K = 0 GOTO F } (2) U r((z) k ) P p r(u)+1 IF l(u) = 0 GOTO N IF l(u) = 1 GOTO A IF P S GOTO N IF l(u) = 2 GOTO M K µi Long(Z)[l((Z) i ) + 2 = l(u)] GOTO C [M] S qt(s, P) GOTO N [A] S S P [N] K K + 1 GOTO C [F ] Y (S) 1 (4) (3) LC, 2005 06 Funciones Recursivas 5.33
Descripción de U n BLOQUE 1: Iniciación del programa Un En Z guardamos la información acerca del programa P. En S el estado actual En K la siguiente instrucción que debe ejecutarse. (Si K = k y S = s, el par (k, s) almacena una d.i.) BLOQUE 2: Test de salida. U n para cuando lleguemos a una d.i. de P terminal. Como la longitud de P es P = Long(Z), la instrucción de salida será: IF K = Long(Z) + 1 K = 0 GOTO F donde K =? 0 prevé que una instrucción condicional remita a una etiqueta que no exista. BLOQUE 3: Obtención del tipo de instrucción que debe ejecutarse. BLOQUE 4: Obtención de la nueva d.i. LC, 2005 06 Funciones Recursivas 5.34
Descripción PR de la computaciones Proposición. Para cada n 1 es PR el predicado: STEP (n) (x 1,..., x n, y, t) El programa y para sobre (x 1,..., x n ) en, a lo sumo, t pasos. Codifiquemos cada d.i. #(s) = (i, σ), mediante y = i, #(σ). La proposición es consecuencia del siguiente resultado: Lema. Las siguientes funciones son primitivas recursivas: La función suc : N 2 N dada por suc(x, y) = la d.i. siguiente de x en la computación del programa y. La función de iniciación, inic (n) : N n N dada por: inic (n) (x 1,..., x n ) = 1, n j=1 (p 2j) x i La función di (n) : N n+2 N dada por: { di (n) (x 1,..., x n, y, 0) = inic (n) (x 1,...x n ) di (n) (x 1,..., x n, y, k + 1) = suc(di (n) (x 1,..., x n, y, k), y) LC, 2005 06 Funciones Recursivas 5.35
Teorema de la forma normal de Kleene Teorema de la forma normal. Para cada n 1, existen Un predicado (n + 2)-ario, primitivo recursivo, Tn, y Una función H PR tales que, para cada función, f, n-aria y G-computable existe un e N verificando: 1. f ( x) zt n ( x, e, z) 2. f ( x) = H((µz)T n ( x, e, z)) Demostración: Dada f GCOMP (n), existe P GOTO P, [[P]] (n) = f. Sea e = #(P). Entonces f ( x) [[P]] (n) ( x) t STEP (n) ( x, e, t) Definamos el predicado (n+2)-ario, T n ( x, e, z) como: STEP (n) ( x, e, r(z)) (r(di (n) ( x, e, r(z)))) 1 = l(z) donde z = y, t es la codificación del valor almacenado en Y (y = l(z)) y el número de pasos (t = r(z)) de la computación de P para la entrada x. LC, 2005 06 Funciones Recursivas 5.36
La tesis de Church Turing Teorema. Toda función GOTO-computable es recursiva. En efecto, si f : N n N es GOTO computable, existe P GOTO P, [[P]] (n) = f y, por el teorema de Kleene: f ( x) = H((µz)T n ( x, #(P), z)) Corolario. GCOMP = P. Este resultado (junto con otros similares) apoyan la validez de la siguiente hipótesis: Tesis de Church Turing. La clase de las funciones numéricas que pueden calcularse mediante algún algoritmo es precisamente la clase de las funciones recursivas (o GOTO computables). LC, 2005 06 Funciones Recursivas 5.37
Enumeración efectiva Para n 1 y e N, la función recursiva n-aria de índice e es la función ϕ (n) e : N n N, dada por Obsérvese que: (n) ϕ #(P) = [[P]](n). ϕ (n) e ( x) = U n ( x, e) = H(µzT n ( x, e, z)) Proposición. Sea n 1. La sucesión {ϕ (n) e : e N} es una enumeración efectiva de P (n), es decir: 1. Para todo e N, ϕ (n) e P (n) 2. Si f P (n), entonces existe e N tal que f = ϕ (n) e ( x). 3. Existe F n P (n+1) tal que para cada x N n, e N, F n ( x, e) = ϕ (n) e ( x) LC, 2005 06 Funciones Recursivas 5.38
Función universal Teorema de la función Universal. Existe una función U P (2) tal que para cada n 1 y cada f P (n), existe e N: x N n (f ( x) = U([x 1,..., x n ], e)) U es la función que calcula el programa universal U, diseñado como U n pero cambiando el bloque de iniciación, S n i=1 px i 2i por S Long(x) i=1 p (x) i 2i LC, 2005 06 Funciones Recursivas 5.39