Scaricare la presentazione
La presentazione è in caricamento. Aspetta per favore
PubblicatoSalvatrice Grossi Modificato 11 anni fa
1
LAPPROCCIO FUNZIONALE Obiettivo: esprimere la soluzione di un problema sotto forma di funzione. Quali funzioni primitive? Quali meccanismi di combinazione?
2
UN POSSIBILE INSIEME DI PRIMITIVE La funzione zero: zero: N N La funzione successore: succ: N N una famiglia di funzioni proiezione: p ni : N n N(1 i n) la funzione p ni seleziona li-esimo para- metro fra gli n parametri di ingresso p 3,2 (x1, x2, x3) = x2
3
MECCANISMI DI COMBINAZIONE Partendo da le funzioni primitive sui naturali loperatore di uguaglianza le espressioni condizionali la ricorsione è possibile definire alcune funzioni che siamo abituati da sempre a considerare date a priori.
4
FUNZIONI ELEMENTARI In questi esempi: non avremo bisogno delle funzioni di proiezione p ni, perché possediamo la capacità espressiva di denotare ogni singolo parametro nel corpo della funzione per nome denoteremo con 0 il valore restituito dalla funzione zero.
5
PREDECESSORE Precedessore in termini del successore: y = pred(x) x = succ(y) int pred (int x){ return (x==1) ? 0 : raggiungi(x,0); } int raggiungi(int x, int y){ return (x==succ(y)) ? y : raggiungi(x,succ(y)); }
6
PREDECESSORE: FUNZIONAMENTO ClienteChiama (main)Pred(3) Pred(3)raggiungi(3,0) raggiungi(3,0)raggiungi(3,1) raggiungi(3,1)raggiungi(3,2) raggiungi(3,2) 2
7
SOMMA Somma in termini di successore e precedessore : x + y = 1+((x-1)+y) int sum (int x, int y){ return (x==0) ? y : succ(sum(pred(x),y)); }
8
SOMMA: FUNZIONAMENTO ClienteChiama (main) sum(3,5) sum(3,5)succ(sum(2,5)) sum(2,5)succ(sum(1,5)) sum(1,5)succ(sum(0,5)) sum(0,5) 5 succ(5) 6 succ(6) 7 succ(7) 8
9
MOLTIPLICAZIONE Prodotto in termini di precedessore e somma: x * y = y + (x-1)*y int mul (int x, int y){ return (x==0) ? 0 : sum(mul(pred(x),y),y); }
10
MOLTIPLICAZIONE: FUNZIONAMENTO ClienteChiama (main) mul(3,6) mul(3,6)sum(mul(2,6),6) mul(2,6)sum(mul(1,6),6) mul(1,6)sum(mul(0,6),6) mul(0,6) 0 sum(0,6) 6 sum(6,6) 12 sum(12,6) 18
11
SOTTRAZIONE Differenza in termini del precedessore : x - y = (x-(y-1))-1 int diff (int x, int y){ return (y==0) ? x : pred(diff(x,pred(y))); }
12
SOTTRAZIONE: FUNZIONAMENTO ClienteChiama (main) diff(2,3) diff(2,3)pred(diff(2,2)) diff(2,2)pred(diff(2,1)) diff(2,1)pred(diff(2,0)) diff(2,0) 2 pred(2) 1 pred(1) 0 pred(0) -1
13
OPERATORI RELAZIONALI int maggioreDiZero(int x){ return (x==0) ? 0 : succ(0); } int minoreDiZero(int x, int y){ return maggioreDiZero(diff(y,x)); }
14
OPERATORI LOGICI int and(int p, int q){ return p ? q : 0; } int or(int p, int q){ return p ? p : q; }
15
ALCUNI ESERCIZI Obiettivo: esprimere la soluzione di alcuni problemi per via funzionale, sfruttando la ricorsione. Calcolo della funzione H(n) = 1 + 1/2 + 1/3 + … + 1/n Calcolo della potenza n-esima b k con b Z, k 0
16
PROBLEMA 1: H(n) H: N R(int double) H(n) = 1 + 1/2 +1/3 +... + 1/n Per n>1 la funzione si riscrive come: H(n) = (1 + 1/2 +1/3 +... + 1/(n-1)) + 1/n ossia come H(n) = H(n-1) + 1/n mentre, ovviamente, H(1)=1.
17
PROBLEMA 1: H(n) Dunque, H(n) = 1per n=1 H(n) = 1/n + H(n-1)per n>1 da cui: double H(int n){ return (n==1) ? 1 : 1.0/n + H(n-1); }
18
PROBLEMA 2: b k con b Z, k 0 power: R N R(double int double) b k = 1per k=0 b k = b * b k-1 per k>0 da cui: double power(double b, int k){ return (k==0) ? 1 : b*power(b,k-1); }
19
ALTRI ESERCIZI Obiettivo: esprimere la soluzione di alcuni problemi per via funzionale, sfruttando la ricorsione. Calcolo del valore di un polinomio di grado n a coefficienti unitari P(x,n) = x 0 + x 1 + … x n Fattoriale innovativo
20
PROBLEMA 3: POLINOMIO Calcolo del valore di un polinomio di grado n 0 a coefficienti unitari P(x,n) = x 0 + x 1 + … x n Per n>0 P(x,n) si riscrive come: P(x,n) = (x 0 + x 1 + … x n-1 ) + x n ossia come P(x,n) = P(x,n-1) + x n mentre, ovviamente, P(x,0)=1.
21
PROBLEMA 3: POLINOMIO Dunque, pol(x,n) = 1 per n=0 pol(x,n) = x n + pol(x,n-1) per n>0 da cui: double pol(double x, int n){ return (n==0) ? 1 : power(x,n) + pol(x,n-1); }
22
UN DIVERSO APPROCCIO Raccogliendo x a fattore comune, il polinomio si può riscrivere come: P(x,n) = 1 + x 1 + … x n = = 1+ x * (1 + x 1 + x 2 + … x n-1 ) = = 1+ x * (1 + x * (1 + x + … x n-2 )) =... = 1+ x *(1+ x * (…( 1+(x+1)*x)…))
23
UN DIVERSO APPROCCIO Questo suggerisce un diverso modo di procedere: P(x,n) = = 1+ x *(1+ x * (…( 1+(x+1)*x)…)) Detto v il valore tra parentesi: P(x,0) = v 0 = 1 P(x,n) = v n = 1 + x * v n-1 v
24
UN DIVERSO APPROCCIO - ESEMPIO x 4 + x 3 + x 2 + x 1 + x 0 = (( ( x + 1 ) *x + 1 ) * x +1) *x +1 v 0 = 1 v 1 = v 0 *x + 1 v 2 = v 1 *x + 1 v 3 = v 2 *x + 1 v 4 = v 3 *x + 1 0 1 2 3 4
25
UN DIVERSO APPROCCIO La relazione: P(x,0) = v 0 = 1 P(x,n) = v n = 1 + x * v n-1 può essere interpretata dicendo: –al passo k=0, il valore del polinomio è 1 –al passo k, il valore corrente del polinomio è 1+x*v (v = valore del polinomio al passo k-1) –il valore v dopo il passo k=n dà il valore finale del polinomio.
26
UN DIVERSO APPROCCIO Nuova codifica con due funzioni: –una funzione pol(), inalterata rispetto a prima, per mascherare la differenza agli occhi del cliente –una funzione polin() come servitore privato di pol(), che opera secondo il nuovo principio di accumulo.
27
UN DIVERSO APPROCCIO Al passo k il valore del polinomio è 1+x*v il valore v dopo il passo k=n dà il valore finale di P(x,n) double polin(double x, int n, double v, int k){ return (k==n) ? v : polin(x,n,1+x*v,k+1); }
28
UN DIVERSO APPROCCIO Al passo k il valore del polinomio è 1+x*v il valore v dopo il passo k=n dà il valore finale di P(x,n) double polin(double x, int n, double v, int k){ return (k==n) ? v : polin(x,n,1+x*v,k+1); } v rappresenta v k, cioè il valore del polinomio quando il passo k-esimo è già stato svolto Quindi, il valore finale desiderato v n è il valore di v quando k=n.
29
UN DIVERSO APPROCCIO double pol(double x, int n){ return polin(x,n,1,0); } double polin(double x, int n, double v, int k){ return (k==n) ? v : polin(x,n,1+x*v,k+1); } situazione iniziale: v k=0 = 1
30
UN FATTORIALE… INNOVATIVO! Definizione: n! = 1 * 2 * 3 *… * n Detto v n = 1 * 2 * 3 *… * n, si può scrivere: 1! = v 1 = 1 n! = v n = v n-1 * n
31
UN FATTORIALE… INNOVATIVO! La relazione: 1! = v 1 = 1 n! = v n = n * v n-1 può essere interpretata dicendo: –al passo k=1, il valore del fattoriale è 1 –al passo k, il valore del fattoriale è k*v (v = valore del fattoriale al passo k-1) –il valore v dopo il passo k=n dà il valore finale del fattoriale.
32
UN FATTORIALE… INNOVATIVO! Nuova codifica con due funzioni: –una funzione fact(), inalterata rispetto a prima, per mascherare la differenza agli occhi del cliente –una funzione factIter() come servitore privato di fact(), che opera secondo il nuovo principio di accumulo.
33
UN FATTORIALE… INNOVATIVO! int fact(int n){ return factIter(n,1,1); } int factIter(int n, int v, int k){ return (k==n) ? v : factIter(n, (k+1)*v, k+1); }
34
UN FATTORIALE… INNOVATIVO! int fact(int n){ return factIter(n,1,1); } int factIter(int n, int v, int k){ return (k==n) ? v : factIter(n, (k+1)*v, k+1); } Situazione iniziale: v k=1 = 1
35
UN FATTORIALE… INNOVATIVO! int fact(int n){ return factIter(n,1,1); } int factIter(int n, int v, int k){ return (k==n) ? v : factIter(n, (k+1)*v, k+1); } v rappresenta il valore del fattoriale dopo il passo k-esimo Quindi, il valore dopo il passo n è disponibile quando k=n.
36
UN FATTORIALE… INNOVATIVO? Perché questo esempio è innovativo ? il risultato viene sintetizzato via via che le chiamate si aprono, in avanti. È una soluzione sintatticamente ricorsiva.. … ma che dà luogo a un un processo computazionale iterativo. infatti, dopo k passi, abbiamo a disposizione il risultato parziale relativo a fact(k)
37
UN FATTORIALE… INNOVATIVO? Perché questo esempio è innovativo ? il risultato viene sintetizzato via via che le chiamate si aprono, in avanti. È una soluzione sintatticamente ricorsiva.. … ma che dà luogo a un un processo computazionale iterativo. infatti, dopo k passi, abbiamo a disposizione il risultato parziale relativo a fact(k) È un caso di RICORSIONE TAIL
Presentazioni simili
© 2024 SlidePlayer.it Inc.
All rights reserved.