FUNZIONI RICORSIVE Caratterizzazione matematica delle funzioni computabili. Introdotta da Godel e Kleene negli annni ’30, ha ispirato, ancora negli anni ’50, modelli e linguaggi di programmazione funzionale (formalismo di McCarthy e LISP). Consideriamo l’insieme di tutte le funzioni intere: F ={f | f: Nn → N, n ≥ 0} Se n = 0 la funzione è una costante. Def. Sono funzioni base le funzioni: - zero, cioè le funzioni O(n) (x1, ... , xn) = 0 (se n = 0 la funzione O(0)( ) corrisponde a 0) - successore, cioè la funzione S (x) = x + 1 - selettive (o identita), cioè le funzioni Ui(n) (x1, ... , xn) = xi Def. La classe delle funzioni ricorsive primitive è la piu piccola classe di funzioni che contiene le funzioni base ed è chiusa rispetto alle operazioni di: - composizione: a partire da m funzioni g1, ..., gm di n argomenti e da una funzione h di m argomenti: f(x1,..., xn) = h(g1(x1,..., xn),..., gm (x1,..., xn)) - ricorsione primitiva: a partire da una funzioni g di n argomenti e da una h di n+2 argomenti: f(x1,..., xn, 0) = g(x1,..., xn) { f(x1,..., xn, y+1) = h(x1,..., xn, y, f(x1,..., xn, y)) Es. Dimostrare che sono primitive ricorsive le funzioni seguenti: 0. qualunque funzione costante 1. incr2 (x) = x+2 2. somma (x, y) = x+y 3. prod (x, y) = x*y 4. s(x, y) = ∑ f(x,t) t<y f pri. ric. e convenzione standard che ∑ f(x, t) =0 t<0 5. p(x, y) = ∏ f(x,t) t<y f pri. ric. e convenzione standard che ∏ f(x, t) =1 6. esp(x,y) = xy pse (x, y) = yx 7. f(x, y, z)=g(y, 3, x, x) 8. Ogni funzione ottenuta da una prim. ric. per “trasformazione esplicita”, come scambio di colonne, variabili ripetute, variabili omesse, sostituzione di costanti, ecc. 9. f(0) e =c t<0 a partire da g pri. ric. c∈N { f(y+1) = h (y, f(y)) 10. f(n) = n! con h prim. ric. 11. pred (0) = 0 { pred (x+1) = x 12. - (x, y) = x-y 0 se x > y altrimenti 13. f(x) = g(x) h(x) se p(x)=1 se p(x)=0 g, h prim. ric. e p(x) ∈ {0,1} pred. prim. ric. f(x) = g(x) h(x) t(x) se p(x)=1 se q(x)=1 se r(x)=1 g, h, t prim. ric. p, q, r pred. prim. ric con p(x)+q(x)+r(x) = 1 Qualche predicato primitivo ricorsivo: 14. zero(x) = 1 0 se x = 0 se x > 0 15. pos(x) 16. mineq (x, y) = 1 0 se x ≤ y altr. 17. min (x, y) = 1 18. eq (x, y) = 1 0 se x = y altr. 19. 20. f(0) f(1) f(2) f(x+1) = c0 = c1 = c2 = h (x, f(x)) =1 0 se x > 0 se x = 0 0 neq (x, y) = 1 0 se x < y altr. se x≠ y altr. x ≥ 2, h prim. ric. 21. Teorema Siano h e g funzioni ricorsive primitive. È ricorsiva primitiva la funzione cosi defnita μ t ≤ h(x1,..., xn) [g(x1,..., xn, t) = 0] se esiste un tale t 0 altrimenti f(x1,..., xn) = { Alternativamente a partire da h, g ed r ricorsive primitive: μ r(x1,..., xn) ≤ t ≤ h(x1,..., xn) [g(x1,..., xn, t) = 0] se esiste un tale t f(x1,..., xn) = { 0 22. f(n) = ⎣√n⎦ 23. dip(m, n)= 1 0 24. mindip(n) = minimo divisore proprio di n, se esiste, 0 altrimenti 23 bis div(m, n) = 1 0 altrimenti se m divide propriamente n altr. se m divide n altr. 25. prime (n) = 1 0 se n è primo altr. 26. p(n) = n-esimo numero primo, n ≥ 0 { p(0) = 2, p(1)=3, …....} 27. E(i, x) = esponente dell'i-esimo primo p(i) nella decomposizione di x in fattori primi 28. M(x) = massimo intero m tale che il primo p(m) divide x > 1, 0 altrimenti. La funzione di Ackermann A(m, n, p) è una funzione di tre variabili totale e calcolabile. Alla fine del 1920 Hilbert ipotizzò che la funzione non fosse primitiva ricorsiva ma fu Ackermann, segretario personale di Hilbert e suo studente, che lo dimostrò. Una funzione simile, definita più tardi da Rozsa Peter e Raphael Robinson, totale ma non pr. rec. è: A(0, n) = n+1 A (m+1, 0) = A (m,1) A(m+1, n+1) = A (m, A(m+1, n) m\n 0 1 2 3 0 1 2 3 5 1 2 3 5 13 4 13 65533 Valori di A(m, n) 2 3 3 4 4 5 7 9 29 61 265536 − 3 5 65533 A(4, 65533) A(4, A(5, 1)) A(4, A(5, 2)) 6 A(5, 1) A(5, A(5, 1)) A(5, A(6, 1)) A(5, A(6, 2)) 4 5 6 11 125 n n+1 n+2 2n + 3 (n + 3) 2 −3 A(3, A(4, 3)) A(4, A(5, 3)) A(4, A(5, n-1)) A(5, A(6, 3)) A(5, A(6, n-1) La ricorsione primitiva non è quindi suffcientemente potente per descrivere tutte le funzioni calcolabili. Infatti: 1. esistono funzioni totali che sono calcolabili mediante algoritmi ma non sono ricorsive primitive. 2. esistono funzioni parziali calcolabili, ad esempio la funzione: f(dM, x) = 1 se la macchina di Turing M si arresta su input x, indefnita altrimenti Def. La classe delle funzioni ricorsive (dette anche parziali o generali) è la piu piccola classe di funzioni che contiene le funzioni base ed è chiusa rispetto alle operazioni di composizione, ricorsione primitiva e: - minimizzazione: a partire da una funzione g di n+1 argomenti : μ t [g(x1,..., xn, t) = 0] se esiste un tale t U altrimenti indefinita f(x1,..., xn) = { Alternativamente: a partire da funzioni h e g di n+1 argomenti : μ t [h(x1,..., xn, t) > g (x1,..., xn, t)] se esiste un tale t U altrimenti indefinita f(x1,..., xn) = { Funzioni ricorsive e linguaggi imperativi Si puo facilmente verifcare che le funzioni ricorsive sono calcolabili mediante macchine di Turing o mediante macchine a registri. Piu diffcile è mostrare il risultato opposto e cioè: Teorema. Ogni funzione calcolabile con una macchina a registri è ricorsiva. Dim. Per semplifcare la dimostrazione mostriamo che la funzione calcolata da una macchina a registri elementare è ricorsiva. Ricordiamo che una MREL viene inizializzata con i valori x1 ,..., xn nei registri R1,..., Rn e quando termina (se esegue un salto all’istruzione 0) il valore del risultato è contenuto nel registro R1. Osserviamo innanzitutto che la confgurazione di una MREL, è completamente determinata se forniamo il contenuto dei suoi registri e il contenuto del ‘program counter’, cioè il numero d’ordine della prossima istruzione da eseguire. Per trasformare tali valori in numeri interi adottiamo le seguenti codifche. Data una sequenza di interi z0, ..., zn denotiamo con < z0, ..., zn > l’intero 2x03x15x2 ... pnxn Se t è un intero positivo indichiamo con (t)k l’esponente del primo pk nella decomposizione di t in fattori primi. Cosi se pm è il massimo numero primo che divide t, abbiamo che t = <(t)0,..., (t)m> . Possiamo codifcare il contenuto dei registri e la confgurazione di una MREL nel seguente modo: cod(registri) = < R[1], ..., R[n] > cod(confgurazione) = < PC, cod(registri) > e codifcare una computazione eseguita dalla MREL, cioè una sequenza di confgurazioni c 0, ..., ck, ( c0 confgurazione iniziale) come: cod(computazione) = < cod(c0),..., cod(ck) > A questo punto, dato un programma π per MREL si puo defnire un predicato T π che, data una sequenza di interi x1, ..., xn ed un intero t, verifca se t codifca la computazione compiuta dal programma π con input x1, ..., xn. Il predicato Tπ (x1, ..., xn, t), con t = <(t)0,..., (t)m>, assume quindi valore vero se e solo se: • (t)0 è codifca della confgurazione iniziale • per ogni i ≥ 0, (t)i+1 è la codifca della confgurazione seguente alla confgurazione codifcata con (t)i in base a quanto previsto dalle istruzioni del programma π. • (t)m è codifca di confgurazione fnale (cioè m è il massimo numero primo che divide t ed il PC contiene 0). Supponendo che un intero t soddisf il predicato T π, per il dato input x1, ..., xn, il valore della funzione calcolata dal programma π è recuperabile facilmente dalla codifca (t)m poiche non è altro che il contenuto del registro R1 nella confgurazione fnale della computazione, cioè è il valore Uπ(t) = (((t)m)1)0 In defnitiva avremo che la funzione f calcolata dalla MREL soddisfa la seguente forma (Forma Normale di Kleene): f(x1, ..., xn) = Uπ (μt (Tπ (x1, ..., xn, t) = 1)) . Funzioni ricorsive e linguaggi funzionali Sul libro viene introdotto un semplice linguaggio di programmazione funzionale chiamato SLF e viene dimostrato che: Th. Il linguaggio SFL consente la definizione di tutte le funzioni ricorsive. I linguaggi di programmazione funzionale permettono di descrivere funzioni senza fare riferimento esplicito ai modelli di macchina che eseguono il calcolo. In questo contesto il concetto di esecuzione di una computazione viene sostituito da quello di valutazione di una espressione. Insiemi ricorsivi e insiemi ricorsivamente enumerabili Le seguenti formulazioni sono date per insiemi di interi, ma valgono per altre tipologie di insiemi, come i linguaggi defniti su alfabeti opportuni. Def. Un insieme è detto ricorsivo se la sua funzione caratteristica è ricorsiva. Th. Un insieme S ⊆ N è ricorsivo ⇔ è decidibile. Dim. Basta osservare che la funzione carattteristica è ricorsiva ⇔ esiste una MT che la calcola, e che quindi accetta ogni input x in S e rifuta ogni x non in S. Def. Un insieme S ⊆ N è ricorsivamente enumerabile (r.e.), se è vuoto oppure è l'immagine di una funzione f totale computabile; in tal caso diciamo che la funzione f lo enumera. Teorema. Le seguenti affermazioni sono equivalenti: i) S è ricorsivamente enumerabile. ii) S è semidecidibile (accettato da una macchina di Turing M) iii) S è il dominio di una funzione calcolabile parziale g iv) S è l'immagine di una funzione calcolabile parziale h Dim. i) ⇒ ii) Se S è vuoto è ovviamente semidecidibile. Se S non è vuoto per decidere se un intero n appartiene ad S basta calcolare f(0), f(1), ecc., cioè enumera gli elementi di S ed accettare n se compare nell'enumerazione. ii) ⇒ iii) La funzione g è defnita nel seguente modo: g(n) = 1 se M accetta n, indefnita altrimenti iii) ⇒ iv) La funzione h puo essere defnita cosi: h(n) = n se g(n) è defnita, indefnita altrimenti. iv) ⇒ i) Se l'immagine di h è vuota è r.e. per defnizione. Altrimenti essa contiene almeno un elemento z; una macchina puo essere defnita che opera cosi, per fasi: fase 1: 1 passo di h(0); se termina ritorna h(0); fase 2: 2 passi di h(0), 2 passi di h(1); per ogni computazione che termina (in al piu 2 passi) ritorna il valore trovato; fase 3: 3 passi di h(0), 3 passi di h(1), 3 passi di h(2); per ogni computazione che termina ( (in al piu 3 passi) ritorna il valore trovato; ecc. Allora la funzione seguente è totale, computabile ed enumera S: f(n) = y se y è l’(n+1)-esimo valore restituito
© Copyright 2024 Paperzz