• Non ci sono risultati.

Ricorsione e Iterazione

N/A
N/A
Protected

Academic year: 2022

Condividi "Ricorsione e Iterazione"

Copied!
5
0
0

Testo completo

(1)

Fondamenti dell’Informatica

Ricorsione e Iterazione

Simona Ronchi Della Rocca

(dal testo: Kfoury, Moll and Arbib, cap.5.2)

Definiamo innanzitutto una relazione d’ordine tra le funzioni. Siano φ e ψ funzioni unarie da naturali a naturali:

φ ≤ ψ (φ `e minore di ψ, o φ approssima ψ) se e solo se ∀x ∈ dom(φ).φ(x) = ψ(x). Cio`e, dove la minore `e definita, `e definita anche la maggiore, e assumono entrambe lo stesso valore. Diciamo inoltre che φ < ψ (φ `e strettamente minore di ψ) se e solo se φ ≤ ψ ed esiste ameno un valore x dove ψ `e definita e φ no.

Ad esempio, la funzione:

h(x) =

 x se x `e pari

⊥ altrimenti

`e tale che h ≤ Id e anche h < Id (Id `e la funzione identit`a).

Consideriamo una semplice funzione ricorsiva:

f att(x) = se x = 0 allora 1 altrimenti x ∗ f att(x − 1) fatt pu`o essere approssimata dalla seguente catena di funzioni parziali:

f att(0)(x) =

 1 se x = 0

⊥ altrimenti

f att(1)(x) =

 1 se x = 0, 1

⊥ altrimenti f att(n)(x) =

 1 ∗ 2 ∗ ... ∗ x se x ≤ n

⊥ altrimenti

tali che:

f att(0) < f att(1)< ... < f att(n)< f att(n+1)< ...

Se dobbiamo calcolare il fattoriale del numero m, ci baster`a usare una approssi- mazione f att(n), con n ≥ m. In altre parole, la definizione ricorsiva di una funzione pu`o essere sviluppata all’infinito, ma ogni volta che vogliamo calco- larla su di uno specifico valore, il numero degli sviluppi (chiamate ricorsive) `e sempre finito e dipende dal valore in input. In altre parole nella computazione reale non ci serve mai tutta la potenza della ricursione.

Fatte queste considerazioni preliminari, vogliamo ora mostrare l’equivalenza tra ricursione e iterazione. Cio`e vogliamo dimostrare il seguente teorema:

Teorema. Dato un programma ricorsivo, esiste un programma iterativo che calcola la stessa funzione.

(2)

Estendiamo il linguaggio WHILE con una nozione di procedura ricorsiva, come fatto nel testo a pag. 110 (versione inglese), con la semantica operazionale come data informalmente nel testo. Sia FATT il programma cos`ı ottenuto.

Possiamo scrivere, per ogni n, il programma iterativo che calcola la funzione f att(n). Sia e l’indice del seguente programma, che calcola la funzione ovunque indefinita:

Pe= begin X1 = 1; while X1 6= 0 do begin end end Sia F AT T0=

begin if X1 = 0 then X1 := 1 else begin X2 := X1; X1 := pred(X1);

Pe;

X1 := X2 ∗ X1 end

end

Ovviamente F AT T0 calcola la funzione f att0. Sia ora F AT T+0 il programma F AT T0 con X3 al posto di X2, cio`e modificato nel seguente modo:

begin if X1 = 0 then X1 := 1 else begin X3 := X1; X1 := pred(X1);

Pe;

X1 := X3 ∗ X1 end

end Sia F AT T1=

begin if X1 = 0 then X1 := 1 else begin X2 := X1; X1 := pred(X1);

F AT T+0; X1 := X2 ∗ X1

end end

La ridenomina della variabile X2 in X3 `e necessaria per poter effettuare il passaggio dei parametri, senza cancellare il dato iniziale. Ovviamente F AT T1 calcola la funzione f att1.

Sia f la funzione di riscrittura di programmi tale che, applicata ad un pro- gramma di indice i, lo riscrive nel modo seguente, ottenendo cos`ı il programma di indice f (i):

begin if X1 = 0 then X1 := 1 else begin X2:= X1; X1 := pred(X1);

Pi dove ogni variabile Xj, con j ≥ 2 `e rimpiazzata da Xj+1; X1 := X2 ∗ X1

end end

(3)

Quindi F AT T0= Pf (e), e possiamo allora scrivere F AT T1 nel modo seguente:

begin if X1 = 0 then X1 := 1 else begin X2 := X1; X1 := pred(X1);

Pf (e);

X1 := X2 ∗ X1 end

end

cio`e F AT T1= Pf2(e), usando la notazione:

f0(e) = e, fn+1(e) = f (fn(e)).

In generale, la funzione f att(n)sar`a quindi calcolata dal programma F AT Tn = Pfn+1(e), definito nel modo seguente:

begin if X1 = 0 then X1 := 1 else begin X2 := X1; X1 := pred(X1);

Pfn(e);

X1 := X2 ∗ X1 end

end In altre parole,

φfn+1(e)(a) = f attn(a)

Teorema. Per ogni n, esiste m tale che f att(m)(n) = f att(n).

Dimostrazione. Ovvia, basta prendere m = n.

Possiamo quindi scrivere un programma iterativo, che calcola il fattoriale, calcolando prima quale `e l’approssimazione necessaria, e poi applicando questa all’input? Invece di riferirci solo alla funzione fattoriale, vediamo di porci il problema nel caso pi`u generale.

Sia k una funzione definita in modo ricorsivo. k `e approssimata da una catena infinita di funzioni parziali:

k(0)< k(1)< ... < k(n)< k(n+1)< ...

Vale in generale un teorema simile al precedente:

Teorema. Per ogni n, esiste m tale che k(m)(n) = k(n).

Possiamo scrivere, analogamente a quanto fatto per il fattoriale, un pro- gramma iterativo che calcola ciascuna delle approssimazioni k(i)(i ≥ 0). Siano Ki questi programmi. Ricordiamo che ciscuno di questi programmi richiama al suo interno il programma Pe, che cicla indefinitamente. Analogamente a quanto fatto per la funzione fattoriale, possiamo definire una sequenza di programmi, K0, K1, ... tali che Ki calcola la funzione k(i). Esiste quindi una funzione di

(4)

riscrittura di programmi, sia fk, tale che Kn= Pfn+1

k (e). Possiamo scrivere un programma iterativo, che calcola k, calcolando prima quale `e l’approssimazione necessaria, e poi applicando il programma corrispondente all’input?

Cio`e, `e possibile implementare il seguente algoritmo, per ogni funzione k e programmi Ki?

Algoritmo A:

1. sia a il dato in input;

2. calcola quale `e il minimo m tale che k(m)(a) = k(a);

3. esegui il programma Kmsull’input a.

NOTA. Questo programma NON `e ricorsivo, perch`e i programmi che cal- colano le approssimazioni k(n) sono programmi iterativi.

Il problema, per implementare l’algoritmo A, `e che non possiamo procedere per tentativi, ad esempio provando ad eseguirlo nel modo seguente:

1. sia a il dato in input;

2. poni n = 0;

3. esegui Kn sull’input a e va a 4;

4. se l’esecuzione di Kn sull’input a `e terminata normalmente, esci dando in output il contenuto di X1;

5. se l’esecuzione di Kn non termina, incrementa n di 1 e torna a 3.

infatti tale algoritmo non `e implementabile, data l’indecidibilit`a del problema dell’alt.

Possiamo per`o rendere effettivo l’algoritmo, trasformandolo nel modo seguente.

Sia F LAG una variabile speciale e sia Pu il seguente programma:

Pu= begin F LAG := 1 end

e trasformiamo ogni programma Kn sostituendo, al posto di Pe, il programma Pu. Quindi Kn = Pfn+1

k (u).

Ricordiamoci che ogni programma Kn ha come indice fkn+1(e), e quindi il programma trasformato avr`a come indice fkn+1(u).

La differenza tra Pfn

k(e) e il programma trasformato Pfn

k(u) `e che, mentre il primo pu`o ciclare, per particolari valori di input, il programma trasformato termina sempre, e in particolare pone F LAG = 1 in corrispondenza ai valori di input per cui Pfn

k(e)cicla.

Possiamo quindi scrivere il seguente algoritmo B:

1. sia a il dato in input;

2. n:=1;

(5)

3. FLAG:=0; esegui Pfn

k(u) (cio`e il trasformato di Kn) sull’input a. Se e quando la computazione si ferma, va a 4;

4. Se FLAG =1, incrementa n di 1 e va a 3;

5. Se FLAG=0, restituisci in output il valore di X1.

Infatti FLAG =1 indica che `e stato eseguito Pu, il che corrisponderebbe all’esecuzione di Penel programma originale Kn.

Possiamo scrivere un programma WHILE che realizza l’algoritmo B. Sia h la funzione di riscrittura di programmi tale che Ph(x) `e il programma seguente:

begin F LAG := 0;

{Px dove ogni test C `e trasformato in C AND FLAG=0}

if F LAG = 0 then X1 := succ(X1) else X1 := 0 end

Il programma Ph(fn+1

k (u)) calcola la seguente funzione:

φh(fn+1

k (u))(a) =

 φfn+1

k (e)(a) + 1 = kn(a) + 1 se Pfn

k(e)su a non cicla

0 altrimenti

Quindi l’algoritmo B `e implementato dal seguente programma:

begin N := 0; while Φ(h(fkN(u)), X1) = 0 do N := succ(N );

X1 := pred(Φ(h(fkN(u)), X1)) end

che calcola quindi, in modo iterativo, la funzione k.

Quindi abbiamo dimostrato il teorema voluto:

Theorema Per ogni programma ricorsivo, c’`e un programma iterativo che calcola la stessa funzione.

Riferimenti

Documenti correlati

Graf, “The Role of Shielding in Interference Control”, IEEE Transactions on Electromagnetic Compatibility vol.. Brush, “Shielding Theory and

Questa ` e l’unica primitiva dispari (le funzioni dispari in zero

Nella sua argomentazione, l’autore approfondisce la questione, mettendo bene in risalto come non si tratti d’una mera questione di gusti: un’opera può piacerci immensamente,

La regola di Cramer segue dalle proprieta’ dei determinanti nel caso n ar- bitrario sostanzialmente lungo le stesse linee del caso n = 2 in precedenza

Esibire il prodotto di tre matrici che diagonalizza la matrice di f nelle basi canoniche (senza calcolare il prodotto) e scrivere la matrice risultante.. Calcolare il seno

Proviamo a risolvere un sistema lineare usando la function del Matlab, l’algoritmo ` e stabile, ma la soluzione numerica ` e molto diversa da quella teorica... Calcoliamo

La verifica di questo fatto `e immediata usando l’asso- ciativit`a del prodotto tra matrici, l’importante `e che si usi sempre la stessa base di W sia per la f che per la g..

[r]