IL MODELLO CLIENTE / SERVITORE - PowerPoint PPT Presentation

About This Presentation
Title:

IL MODELLO CLIENTE / SERVITORE

Description:

IL MODELLO CLIENTE / SERVITORE CLIENTI E SERVITORI Servitore: un qualunque ente computazionale capace di nascondere la propria organizzazione interna presentando ai ... – PowerPoint PPT presentation

Number of Views:83
Avg rating:3.0/5.0
Slides: 115
Provided by: unib180
Category:

less

Transcript and Presenter's Notes

Title: IL MODELLO CLIENTE / SERVITORE


1
IL MODELLO CLIENTE / SERVITORE
2
CLIENTI E SERVITORI
  • Servitore
  • un qualunque ente computazionale capace di
    nascondere la propria organizzazione interna
  • presentando ai clienti una precisa interfaccia
    per lo scambio di informazioni.
  • Cliente
  • qualunque ente in grado di invocare uno o più
    servitori per svolgere il proprio compito.

3
SERVITORI
  • Un servitore può
  • essere passivo o attivo
  • servire molti clienti oppure costituire la
    risorsa privata di uno specifico cliente
  • in particolare può servire un cliente alla
    volta, in sequenza, oppure più clienti per volta,
    in parallelo
  • trasformarsi a sua volta in cliente, invocando
    altri servitori o anche se stesso.

4
COMUNICAZIONE CLIENTE / SERVITORE
  • Lo scambio di informazioni tra un
  • cliente e un servitore può avvenire
  • in modo esplicito tramite le interfacce stabilite
    dal servitore
  • in modo implicito tramite aree-dati accessibili
    ad entrambi.

5
FUNZIONI
  • Una funzione permette di
  • dare un nome a una espressione
  • rendendola parametrica
  • Esempi (pseudo-C)
  • float f() 2 3 sin(0.75)
  • float f1(int x)
  • 2 x sin(0.75)

6
FUNZIONI come COMPONENTI SW
  • Una funzione è un componente
  • software che cattura lidea mate-
  • matica di funzione
  • f A ? B ? ... ? Q ? S
  • molti possibili ingressi (che non vengono
    modificati!)
  • una sola uscita (il risultato)

7
FUNZIONI come SERVITORI
  • Una funzione
  • riceve dati di ingresso in corrispondenza ai
    parametri
  • ha come corpo una espressione, la cui valutazione
    fornisce un risultato
  • denota un valore in corrispondenza al suo nome

8
FUNZIONI come SERVITORI
  • Esempio
  • se x vale 1
  • e f è la funzione R ? R
  • f 3 x2 x - 3
  • allora f(x) denota il valore 1.

9
FUNZIONI come SERVITORI
  • Una funzione è un servitore
  • passivo
  • che serve un cliente per volta
  • che può trasformarsi in cliente invocando se
    stessa

10
FUNZIONI come SERVITORI
  • Una funzione è un servitore dotato di nome che
    incapsula le istruzioni che realizzano un certo
    servizio.
  • Per chiedere al servitore di svolgere il servizio
    occorre
  • chiamare tale servitore (per nome)
  • fornirgli le necessarie informazioni
  • Come far comunicare cliente e servitore?

11
COMUNICAZIONE CLIENTE/SERVITORE
  • Nel caso di una funzione,
  • cliente e servitore comunicano mediante
    linterfaccia della funzione.

12
FUNZIONI INTERFACCIA
  • Linterfaccia di una funzione comprende
  • nome della funzione
  • lista dei parametri
  • tipo del valore da essa denotato
  • è spesso chiamata firma (signature)
  • esplicita il contratto di servizio fra cliente e
    servitore.

13
COMUNICAZIONE CLIENTE/SERVITORE
  • Cliente e servitore comunicano quindi
  • mediante
  • i parametri trasmessi dal cliente al servitore
    allatto della chiamata(direzione dal cliente
    al servitore)
  • il valore restituito dal servitore al
    cliente(direzione dal servitore al cliente)

14
UN ESEMPIO
  • int max (int x, int y )
  • return xgty ? x y
  • Il simbolo max denota il nome della
    nuovafunzione
  • Le variabili intere x e y sono i parametridella
    nuova funzione
  • Il valore restituito è un intero.

15
FUNZIONI INFORMATION HIDING
  • La struttura interna (corpo) di una funzione è
    completamente inaccessibile dallesterno.
  • Così facendo si garantisce protezione
    dellinformazione secondo il principio del suo
    nascondimento (information hiding)

16
FUNZIONI IN UN PROGRAMMA C
  • Un programma C è un insieme di funzioni
  • ltprogrammagt
  • ltunità-di-traduzionegt
  • ltunità-di-traduzionegt ltdefinizione-di-funzio
    negt ltdichiarazione-di-funzionegt
  • Il main è semplicemente la funzione, di no-me
    prefissato, dove inizia lelaborazione.

17
DEFINIZIONE DI FUNZIONE struttura
  • Una ltdefinizione-di-funzionegt è definita
  • dalla produzione
  • ltdefinizione-di-funzionegt
  • lttipoValoregt ltnomegt(ltparametrigt) ltcorpogt

18
DEFINIZIONE DI FUNZIONE parametri
  • Una ltdefinizione-di-funzionegt è definita
  • dalla produzione
  • ltdefinizione-di-funzionegt
  • lttipoValoregt ltnomegt(lt parametri gt) ltcorpogt
  • o una lista vuota void
  • o una lista di variabili (separate da virgole)
    visibili soloentro il corpo della funzione.

19
DEFINIZIONE DI FUNZIONE corpo
  • Una ltdefinizione-di-funzionegt è definita
  • dalla produzione
  • ltdefinizione-di-funzionegt
  • lttipoValoregt ltnomegt(lt parametri gt) ltcorpogt

ltcorpogt è tutto ciò che sta fra La forma base
è return ltespressionegt
20
DEFINIZIONE DI FUNZIONE tipo
  • Una ltdefinizione-di-funzionegt è definita
  • dalla produzione
  • ltdefinizione-di-funzionegt
  • lttipoValoregt ltnomegt(lt parametri gt) ltcorpogt

il tipo della funzione deve coinci- dere col tipo
dellespressione che costituisce il corpo della
funzione
21
FUNZIONI COME COMPONENTI SOFTWARE NASCITA E MORTE
  • Allatto della chiamata, lesecuzione del cliente
    viene sospesa e il controllo passa al servitore.
  • Il servitore vive solo per il tempo necessario
    a svolgere il servizio.
  • Al termine, il servitore muore,e lesecuzione
    torna al cliente.

22
CHIAMATA DI FUNZIONE
  • La chiamata di funzione è unespressione
  • della forma
  • ltnomefunzionegt ( ltparametri-attualigt )
  • dove
  • ltparametri-attualigt ltespressionegt ,
    ltespressionegt

23
CHIAMATE DI FUNZIONE ESPRESSIONI
  • Linvocazione di una funzione da parte di un
    cliente costituisce un particolare tipo di
    espressione.

24
RITORNO DA FUNZIONE
  • Listruzione return provoca la restitu-zione del
    controllo al cliente, unitamente al valore
    dellespres-sione che la segue.
  • Eventuali istruzioni successive alla return non
    saranno mai eseguite!

25
IL PROBLEMA DEI SIMBOLI
  • f(x) g( f(x), q( x f(y)))
  • Per fornire il risultato, dobbiamo conoscere
  • la definizione delle funzioni f, g, q
  • i valori di x e y
  • Come conoscerli?

26
SIMBOLI SIGNIFICATO
  • Come conoscere il significato di un simbolo?
  • o esiste una convenzione diffusa,una cultura
    comune, che associa ad un simbolo un preciso
    significato
  • o esiste un ente di riferimento che specifica in
    modo esplicito il significato di un simbolo.

27
BINDING ENVIRONMENT
  • La conoscenza di cosa un simbolo denota viene
    espressa da una legame (binding) tra il simbolo e
    uno o più attributi.
  • La collezione dei binding valida in (un certo
    punto di) un programma si chiama environment.

28
UN ESEMPIO
  • Sia f N-gtN f(x)xx
  • Sia z 2
  • f(z) f(z) vale 8
  • f(2) f(y) vale ???
  • g(z) vale ???

29
SCOPE SCOPE RULES
  • Tutte le occorrenze di un nome nel testo di un
    programma a cui si applica un dato binding si
    dicono essere entro la stessa portata o scope del
    binding.
  • Le regole in base a cui si stabilisce la portata
    di un binding si dicono regole di visibilità o
    scope rules.

30
ESEMPIO
  • Sia f N-gtN f(x)xx
  • Sia z 2
  • f(z) f(z) vale 8
  • f(2) f(y) vale ???
  • Sia g N-gtN g(x)xx
  • g(z) vale 4
  • f(g(z)) vale 8

31
DEFINIZIONE DI NUOVE FUNZIONI
  • Per dare un nome alla nuova funzione,
  • il linguaggio deve introdurre costrutti per
    estendere un environment
  • aggiungendo ad esso il nuovo binding che lega il
    nome scelto per la funzione allentità che
    realizza quella specifica funzione.

32
DEFINIZIONE DI NUOVE FUNZIONI
  • La definizione di funzione unisce
  • la denotazione di una nuova funzione
  • lattribuzione di un nome ad essa
  • Lenvironment corrente viene arricchito con uno
    nuovo binding tra
  • il nome della funzione, e
  • la sua rappresentazione interna

33
FUNZIONI IL MODELLO APPLICATIVO
  • 1) Valutazione, nellenvironment corrente, del
    simbolo che denota il nome della funzione
  • 2) Valutazione, nellenvironment corrente, delle
    espressioni che denotano i parametri
  • 3) Commutazione allenvironment di definizione
    della funzione.

34
FUNZIONI IL MODELLO APPLICATIVO
  • 4) Chiamata della funzione
  • 5) Esecuzione del corpo della funzione (nel suo
    environment di definizione)
  • 6) Restituzione al chiamante di
  • controllo
  • risultato
  • con ripristino dellenvironment esistente al
    momento della chiamata.

35
LENVIRONMENT
  • La definizione di una funzione introduce un
    nuovo binding nellenvironment di definizione
    della funzione
  • in C, il global environment
  • Al momento dellinvocazione, si crea un nuovo
    environment
  • una struttura che contiene i binding dei
    parametri e degli identificatori dichiarati
    localmente alla funzione.

36
ESEMPIO
  • int max (int x, int y )
  • return xgty ? x y
  • Lenvironment corrente viene arricchito di un
    nuovo binding max / CodiceDellaFunzione
  • Quando max viene chiamata, si commuta a un nuovo
    environment, in cui sono definite le variabili
    intere x e y

37
COMUNICAZIONE CLIENTE ? SERVITORE
  • Il cliente passa informazioni al servitore
  • mediante una serie di parametri attuali.
  • Parametri formali
  • sono specificati nella dichiarazione del
    servitore
  • esplicitano il contratto fra servitore e cliente
  • indicano cosa il servitore si aspetta dal cliente
  • Parametri attuali
  • sono trasmessi dal cliente allatto della
    chiamata
  • devono corrispondere ai parametri formali in
    numero, posizione e tipo

38
COMUNICAZIONE CLIENTE ? SERVITORE
  • Il cliente passa informazioni al servitore
  • mediante una serie di parametri attuali.
  • I Parametri attuali sono legati ai parametri
    formali al momento della chiamata,in modo
    dinamico.
  • Tale legame
  • vale solo per linvocazione corrente
  • vale solo per la durata della funzione.

39
IL NOSTRO ESEMPIO
  • Il servitore...
  • int max (int x, int y )
  • return xgty ? x y
  • e un possibile cliente
  • main()
  • int z 8
  • int m max(2z,13)

40
IL NOSTRO ESEMPIO
  • Il servitore...
  • int max (int x, int y )
  • return xgty ? x y
  • e un possibile cliente
  • main()
  • int z 8
  • int m max(2z,13)

1) Valutazione del simbolo znellenvironment
corrente Si trova che z vale 8.
41
IL NOSTRO ESEMPIO
  • Il servitore...
  • int max (int x, int y )
  • return xgty ? x y
  • e un possibile cliente
  • main()
  • int z 8
  • int m max(2z,13)

2) Calcolo dellespressione 2znellenvironment
corrente Si trova che vale 16.
42
IL NOSTRO ESEMPIO
  • Il servitore...
  • int max (int x, int y )
  • return xgty ? x y
  • e un possibile cliente
  • main()
  • int z 8
  • int m max(2z,13)

3) Invocazione della funzione max con parametri
attuali16 e 13. Il controllo passa al servitore.
43
IL NOSTRO ESEMPIO
  • Il servitore...
  • int max (int x, int y )
  • return xgty ? x y
  • e un possibile cliente
  • main()
  • int z 8
  • int m max(2z,13)

4) I parametri formali x e y vengono legati ai
parametriattuali 16 e 13. Inizia lesecuzione
del servitore.
44
IL NOSTRO ESEMPIO
  • Il servitore...
  • int max (int x, int y )
  • return xgty ? x y
  • e un possibile cliente
  • main()
  • int z 8
  • int m max(2z,13)

5) Viene valutata lespressionecondizionale
nellenvironment del servitore. Il risultato è
16.
45
IL NOSTRO ESEMPIO
  • Il servitore...
  • int max (int x, int y )
  • return xgty ? x y
  • e un possibile cliente
  • main()
  • int z 8
  • int m max(2z,13)

6) Il valore così determinato (16)viene
restituito al cliente. Il servitore termina e il
controllo torna al cliente.
46
IL NOSTRO ESEMPIO
7) Il valore restituito (16) viene usato per
inizializzare lavariabile m (nellenvironment
del cliente)
  • Il servitore...
  • int max (int x, int y )
  • return xgty ? x y
  • e un possibile cliente
  • main()
  • int z 8
  • int m max(2z,13)

47
RIASSUNTO
  • Allatto dellinvocazione di una funzione
  • si crea una nuova attivazione (istanza) del
    servitore
  • si alloca la memoria per i parametri (e le
    eventuali variabili locali)
  • si trasferiscono i parametri al servitore
  • si trasferisce il controllo al servitore
  • si esegue il codice della funzione.

48
PASSAGGIO DEI PARAMETRI
  • In generale, un parametro può essere
  • trasferito
  • per valore o copia (by value)
  • si trasferisce il valore del parametro attuale
  • per riferimento (by reference)
  • si trasferisce un riferimento al parametro attuale

49
PASSAGGIO PER VALORE
  • si trasferisce una copia del valore del parametro
    attuale

z
45
cliente
50
PASSAGGIO PER VALORE
  • si trasferisce una copia del valore del parametro
    attuale

valore (copiato) di z
copia
z
45
w
45
istanza del servitore
cliente
servitore
51
PASSAGGIO PER VALORE
Ogni azione fatta su w è strettamente locale al
servitore
  • si trasferisce una copia del valore del parametro
    attuale

valore (copiato) di z
copia
z
45
w
45
istanza del servitore
cliente
servitore
52
PASSAGGIO PER RIFERIMENTO
  • si trasferisce un riferimento al parametro attuale

z
45
cliente
53
PASSAGGIO PER RIFERIMENTO
  • si trasferisce un riferimento al parametro attuale

riferimento a z (indirizzo)
?
riferimento
z
45
w
?
istanza del servitore
cliente
servitore
54
PASSAGGIO PER RIFERIMENTO
Ogni azione fatta su w è in realtà fatta
sulla variabile z del cliente!
  • si trasferisce un riferimento al parametro attuale

riferimento a z (indirizzo)
?
riferimento
z
45
w
?
istanza del servitore
cliente
servitore
55
PASSAGGIO DEI PARAMETRI IN C
  • In C, i parametri sono trasferiti sempre e solo
  • per valore (by value)
  • si trasferisce una copia del parametro attuale,
    non loriginale!
  • tale copia è strettamente privata e locale a quel
    servitore
  • il servitore potrebbe quindi alterare il valore
    ricevuto, senza che ciò abbia alcun impatto sul
    cliente

56
PASSAGGIO DEI PARAMETRI IN C
  • In C, i parametri sono trasferiti sempre e solo
  • per valore (by value)
  • Conseguenza
  • è impossibile usare un parametro per trasferire
    informazioni verso il cliente
  • per trasferire (una) informazione al cliente si
    sfrutta il valore di ritorno della funzione

57
ESEMPIO VALORE ASSOLUTO
  • Definizione formale
  • x N ? N
  • x vale x se x ? 0
  • x vale -x se x ? 0
  • Codifica sotto forma di funzione C
  • int valAss(int x)
  • return (xlt0) ? -x x

58
ESEMPIO VALORE ASSOLUTO
  • Servitore Cliente
  • int valAss(int x) return (xlt0) ? -x x
  • main()
  • int z -87
  • int absz valAss(z)
  • int abs4 valAss(4)

59
ESEMPIO VALORE ASSOLUTO
Quando valAss(z) viene chiamata, il valore
attuale di z, valutato nel- lenvironment
corrente (-87), viene copiato e passato a valAss.
  • Servitore Cliente
  • int valAss(int x) return (xlt0) ? -x x
  • main()
  • int z -87
  • int absz valAss(z)
  • int abs4 valAss(4)

60
ESEMPIO VALORE ASSOLUTO
  • Servitore Cliente
  • int valAss(int x) return (xlt0) ? -x x
  • main()
  • int z -87
  • int absz valAss(z)
  • int abs4 valAss(4)

valAss riceve quindi una copia del valore -87 e
la lega al simbolo x. Poi si valuta
lespressione, che qui vale 87, e si restituisce
questo valore.
61
ESEMPIO VALORE ASSOLUTO
  • Servitore Cliente
  • int valAss(int x) return (xlt0) ? -x x
  • main()
  • int z -87
  • int absz valAss(z)
  • int abs4 valAss(4)

Il valore restituito (87) viene usato per
inizializzare la variabile absz.
62
ESEMPIO MASSIMO DI DUE NUMERI
  • Definizione formale
  • max N ? N ? N
  • max(x,y) vale x se x ? y
  • max(x,y) vale y se x lt y
  • Codifica sotto forma di funzione C
  • int max(int x, int y)
  • return (xlty) ? y x

63
ESEMPIO MASSIMO DI DUE NUMERI
  • Servitore Cliente
  • int max(int x, int y) return (xlty) ? y x
  • main()
  • int z -87, y 12
  • int m max(z,18)
  • int n max(4y,z100)

64
ESEMPIO MASSIMO DI DUE NUMERI
Si valutano le due espressioni che costituiscono
i parametri attuali (nel- lenvironment del main)
e si trasmette alla funzione copia dei valori
ottenuti.
  • Servitore Cliente
  • int max(int x, int y) return (xlty) ? y x
  • main()
  • int z -87, y 12
  • int m max(z,18)
  • int n max(4y,z100)

65
ESEMPIO MASSIMO DI DUE NUMERI
  • Servitore Cliente
  • int max(int x, int y) return (xlty) ? y x
  • main()
  • int z -87, y 12
  • int m max(z,18)
  • int n max(4y,z100)

La funzione riceve copia dei valori -87 e 18, e
li lega ai simboli x e y. Poi si valuta
lespressione. Il risultato (18) è restituito al
main chiamante.
66
PASSAGGIO DEI PARAMETRI IN C
  • Perché il C adotta sempre e solo il passaggio
  • per valore (by value)?
  • è sicuro le variabili del chiamante e del
    chiamato sono completamente disac-coppiate
  • consente di ragionare per componenti e servizi
    la struttura interna dei singoli componenti è
    irrilevante

67
PASSAGGIO DEI PARAMETRI IN C
  • Limiti
  • consente di restituire al cliente solo valori di
    tipo (relativamente) semplice
  • non consente di restituire collezioni di valori
  • non consente di scrivere componenti software il
    cui scopo sia diverso dal calcolo di una
    espressione

68
PASSAGGIO DEI PARAMETRI
  • Molti linguaggi mettono a disposizione il
  • passaggio per riferimento (by reference)
  • non si trasferisce una copia del valore del
    parametro attuale
  • si trasferisce un riferimento al parametro, in
    modo da dare al servitore accesso di- retto al
    parametro in possesso del cliente
  • il servitore accede e modifica direttamente il
    dato del cliente.

69
PASSAGGIO DEI PARAMETRI IN C
  • Il C non supporta direttamente il passaggio
  • per riferimento
  • è una grave mancanza!
  • il C lo fornisce indirettamente solo per alcuni
    tipi di dati
  • ergo, occorre costruirselo quando serve.(vedremo
    dei casi)
  • Il C e Java invece lo forniscono.

70
DEFINIZIONE DI NUOVE FUNZIONI STRATEGIE DI
COMPOSIZIONE
  • La capacità di definire nuove funzioni
  • permette
  • di definire nuove operazioni
  • di introdurre variabili per denotare i dati in
    modo simbolico
  • di esprimere la ripetizione di una espressione
    per un numero (prefissatoo meno) di volte.

71
STRATEGIE DI COMPOSIZIONE
  • Tre grandi approcci
  • 1) la composizione di funzioni
  • 2) le espressioni condizionali
  • 3) la ricorsione.
  • Le funzioni definibili in termini di un insieme
  • prescelto di primitive e delle precedenti
  • strategie di composizione costituiscono un
  • insieme detto delle funzioni ricorsive generali.

72
1) COMPOSIZIONE DI FUNZIONI
  • I parametri in una chiamata di funzione pos-
  • sono consistere/comprendere altre funzioni
  • Es f(x) g(f(x), q(x f(y)))
  • x1 f(x)
  • x2 f(x) (mossa evitabile da un automa
    intelligente)
  • x3 f(y)
  • x4 x x3
  • x5 q( x4 )
  • x6 g( x2,x5 )
  • x7 x1 x6

73
2) ESPRESSIONE CONDIZIONALE
  • Lespressione condizionale riflette la
    consuetudine matematica di definire le funzioni
    per elencazione di casi.
  • Esempio
  • abs N -gt N
  • abs(x) vale x se x ? 0
  • abs(x) vale -x se x ? 0

74
3) LA RICORSIONE
  • La ricorsione consiste nella pos-sibilità di
    definire una funzione in termini di se stessa.
  • È basata sul principio di induzione matematica
  • se una proprietà P vale per nn0
  • e si può provare che, assumendola valida per n,
    allora vale per n1
  • allora P vale per ogni n?n0

75
LA RICORSIONE
  • Operativamente, risolvere un problema con un
    approccio ricorsivo comporta
  • di identificare un caso base la cui soluzione
    sia ovvia
  • di riuscire a esprimere la soluzione al caso
    generico n in termini dello stesso problema in
    uno o più casi più semplici (n-1, n-2, etc).

76
LA RICORSIONE ESEMPIO
Esempio ! N ? N n! vale 1 se n ? 0 n! vale
n(n-1)! se n gt 0 Codifica int fact(int n)
return n0 ? 1 nfact(n-1)
77
LA RICORSIONE ESEMPIO
Attenzione la codifica non corrisponde alla
specifica!! Il 2 caso si applica per n?0,cioè
anche per nlt0 !!MA COSÌ PUÒ NON TERMINARE!
Esempio ! N ? N n! vale 1 se n ? 0 n! vale
n(n-1)! se n gt 0 Codifica int fact(int n)
return n0 ? 1 nfact(n-1)
78
LA RICORSIONE ESEMPIO
Esempio ! N ? N n! vale 1 se n ? 0 n! vale
n(n-1)! se n gt 0 Codifica int fact(int n)
/ return n0 ? 1 nfact(n-1) / return ngt0
? nfact(n-1) 1
Nuova codifica
79
ESEMPIO FATTORIALE
  • Servitore Cliente
  • int fatt(int n) return (ngt0) ? nfatt(n-1)
    1
  • main()
  • int z 5
  • int fz fatt(z2)
  • int f6 fatt(6)

80
ESEMPIO FATTORIALE
Si valuta lespressione che costituisce
il parametro attuale (nellenvironment del main)
e si trasmette alla funzione fatt una copia del
valore così ottenuto (7).
  • Servitore Cliente
  • int fatt(int n) return (ngt0) ? nfatt(n-1)
    1
  • main()
  • int z 5
  • int fz fatt(z2)
  • int f6 fatt(6)

81
ESEMPIO FATTORIALE
  • Servitore Cliente
  • int fatt(int n) return (ngt0) ? nfatt(n-1)
    1
  • main()
  • int z 5
  • int fz fatt(z2)
  • int f6 fatt(6)

La funzione riceve una copia del valore 7 e la
lega al simbolo n. Poi valuta lespres- sione
condizionale ciò impone di valutare una
espressione che contiene una nuova chiamata di
funzione.
82
ESEMPIO FATTORIALE
  • Servitore Cliente
  • int fatt(int n) return (ngt0) ? nfatt(n-1)
    1
  • main()
  • int z 5
  • int fz fatt(z2)
  • int f6 fatt(6)

Si valuta quindi, nellenvironment di
fatt, lespressione n-1 (che vale 6), e si
effettua una nuova chiamata al servitore fatt,
pas- sandogli una copia del valore 6.
83
ESEMPIO FATTORIALE
  • Servitore Cliente
  • int fatt(int n) return (ngt0) ? nfatt(n-1)
    1
  • main()
  • int z 5
  • int fz fatt(z2)
  • int f6 fatt(6)

Il (nuovo) servitore riceve quindi una copia del
valore 6 e, come sopra, valuta lespres- sione
condizionale. Ciò lo porta a dover fare una nuova
chiamata passando 5.
84
ESEMPIO FATTORIALE
  • Servitore Cliente
  • int fatt(int n) return (ngt0) ? nfatt(n-1)
    1
  • main()
  • int z 5
  • int fz fatt(z2)
  • int f6 fatt(6)

la cosa prosegue, servitore dopo
servitore.. ...
85
ESEMPIO FATTORIALE
  • Servitore Cliente
  • int fatt(int n) return (ngt0) ? nfatt(n-1)
    1
  • main()
  • int z 5
  • int fz fatt(z2)
  • int f6 fatt(6)

Prima o poi, dato che il valore passato cala ogni
volta, si giunge a invocare fatt con parametro 1.
In questo caso, la valutazione dellespressione
dà come risultato 1.
86
ESEMPIO FATTORIALE
  • Servitore Cliente
  • int fatt(int n) return (ngt0) ? nfatt(n-1)
    1
  • main()
  • int z 5
  • int fz fatt(z2)
  • int f6 fatt(6)

Ciò chiude la sequenza di chiamate ricorsive. Il
controllo torna al servitore precedente, che può
finalmente valutare lespressione n1 (valutando
n nel suo environment, dove vale 2) ottenendo 2.
87
ESEMPIO FATTORIALE
  • Servitore Cliente
  • int fatt(int n) return (ngt0) ? nfatt(n-1)
    1
  • main()
  • int z 5
  • int fz fatt(z2)
  • int f6 fatt(6)

Il valore 2 viene restituito al servitore
pre- cedente, che a sua volta può così
valutare lespressione n2 (valutando n nel suo
environment, dove vale 3) ottenendo 6.
88
ESEMPIO FATTORIALE
  • Servitore Cliente
  • int fatt(int n) return (ngt0) ? nfatt(n-1)
    1
  • main()
  • int z 5
  • int fz fatt(z2)
  • int f6 fatt(6)

la cosa prosegue ...
89
ESEMPIO FATTORIALE
  • Servitore Cliente
  • int fatt(int n) return (ngt0) ? nfatt(n-1)
    1
  • main()
  • int z 5
  • int fz fatt(z2)
  • int f6 fatt(6)

Prima o poi, a forza di retrocedere, si torna al
primo servitore attivato, che può quindi valutare
lespressione n720 (valutando n nel suo
environment, dove vale 7), giun- gendo così a
trovare il valore 5040.
90
ESEMPIO FATTORIALE
  • Servitore Cliente
  • int fatt(int n) return (ngt0) ? nfatt(n-1)
    1
  • main()
  • int z 5
  • int fz fatt(z2)
  • int f6 fatt(6)

Il valore 5040, restituito dal servitore fatt,
può quindi essere usato per inizializzare la
variabile fz.
91
UN ALTRO ESEMPIO
  • Problema
  • calcolare la somma dei primi N interi
  • Specifica
  • Considera la somma (123...(N-1)N come
  • composta di due termini
  • (123...(N-1))
  • N
  • Esiste un caso banale assolutamente ovvio
  • la somma fino a 1 vale 1.

92
UN ALTRO ESEMPIO
Il primo termine non è altro che la soluzione
allo stesso problema inun caso più semplice
  • Problema
  • calcolare la somma dei primi N interi
  • Specifica
  • Considera la somma (123...(N-1)N come
  • composta di due termini
  • (123...(N-1))
  • N
  • Esiste un caso banale assolutamente ovvio
  • la somma fino a 1 vale 1.

Il secondo termine è un valore già noto.
93
UN ALTRO ESEMPIO
Problema calcolare la somma dei primi N
interi Codifica int sommaFinoA(int n) return
(n1) ? 1 sommaFinoA(n-1) n
94
UN TERZO ESEMPIO
Problema calcolare lN-esimo numero di Fibonacci
95
UN TERZO ESEMPIO
Problema calcolare lN-esimo numero di
Fibonacci Codifica unsigned fibonacci(unsigned
n) return (nlt2) n ? fibonacci(n-1)
fibonacci(n-2)
96
UN TERZO ESEMPIO
Ricorsione non lineare ogniinvocazione del
servitore causadue nuove chiamate al servitore
medesimo.
Problema calcolare lN-esimo numero di
Fibonacci Codifica unsigned fibonacci(unsigned
n) return (nlt2) n ? fibonacci(n-1)
fibonacci(n-2)
97
UNA RIFLESSIONE
  • Negli esempi di ricorsione visti finora
  • fattoriale
  • somma dei primi N interi
  • calcolo dellN-esimo numero di Fibonacci
  • si inizia a sintetizzare il risultato solo dopo
    che si sono aperte tutte le chiamate, a
    ritroso, mentre le chiamate si chiudono.

98
UNA RIFLESSIONE
  • Le chiamate ricorsive decompongono via via il
    problema, ma non calcolano nulla
  • Il risultato viene sintetizzato a partire dalla
    fine, perché prima occorre arrivare al caso
    banale
  • il caso banale fornisce il valore di partenza
  • poi, e solo poi, si sintetizzano, a ritroso, i
    successivi risultati parziali.

99
UNA RIFLESSIONE
  • Ciò indica che tali soluzioni
  • sono sintatticamente ricorsive
  • e danno luogo a un processo computa-zionale
    effettivamente ricorsivo.

100
UN ESEMPIO DIVERSO
Problema trovare il Massimo Comun Divisore tra N
e M
101
UN ESEMPIO DIVERSO
Problema calcolare il Massimo Comun Divisore tra
N e M Codifica int mcd(int m, int n) return
(mn) m ? (mgtn) ? mcd(m-n, n) mcd(m,
n-m)
102
UN ESEMPIO DIVERSO
  • Servitore Cliente
  • int mcd(int m, int n) return (mn) m ?
    (mgtn) ? mcd(m-n, n) mcd(m, n-m)
  • main()
  • int m mcd(36,15)

103
UN ESEMPIO DIVERSO
  • Servitore Cliente
  • int mcd(int m, int n) return (mn) m ?
    (mgtn) ? mcd(m-n, n) mcd(m, n-m)
  • main()
  • int m mcd(36,15)

Si valutano i parametri attuali e si invoca la
funzione con parametri 36 e 15
104
UN ESEMPIO DIVERSO
  • Servitore Cliente
  • int mcd(int m, int n) return (mn) m ?
    (mgtn) ? mcd(m-n, n) mcd(m, n-m)
  • main()
  • int m mcd(36,15)

Si legano i parametri 36 e 15 ai
parametri formali m e n, e si valuta
lespressione condizionale.
105
UN ESEMPIO DIVERSO
  • Servitore Cliente
  • int mcd(int m, int n) return (mn) m ?
    (mgtn) ? mcd(m-n, n) mcd(m, n-m)
  • main()
  • int m mcd(36,15)

Poiché 36 ? 15, si invoca nuovamente la funzione
con parametri m-n (21) e n (15).
106
UN ESEMPIO DIVERSO
  • Servitore Cliente
  • int mcd(int m, int n) return (mn) m ?
    (mgtn) ? mcd(m-n, n) mcd(m, n-m)
  • main()
  • int m mcd(36,15)

Il nuovo servitore, poiché 21 ? 15, fa la stessa
cosa e invoca nuovamente la funzione con
parametri m-n (6) e n (15).
107
UN ESEMPIO DIVERSO
  • Servitore Cliente
  • int mcd(int m, int n) return (mn) m ?
    (mgtn) ? mcd(m-n, n) mcd(m, n-m)
  • main()
  • int m mcd(36,15)

Il nuovo servitore, poiché 6 ? 15, invoca un
ulteriore servitore con parametri m (6) e n-m
(9).
108
UN ESEMPIO DIVERSO
  • Servitore Cliente
  • int mcd(int m, int n) return (mn) m ?
    (mgtn) ? mcd(m-n, n) mcd(m, n-m)
  • main()
  • int m mcd(36,15)

Poiché 6 ? 9, si ha una nuova chiamata con
parametri m (6) e n-m (3).
109
UN ESEMPIO DIVERSO
  • Servitore Cliente
  • int mcd(int m, int n) return (mn) m ?
    (mgtn) ? mcd(m-n, n) mcd(m, n-m)
  • main()
  • int m mcd(36,15)

Poiché 6 ? 3, si ha una nuova invocazione (lultim
a!) con parametri m-n (3) e n (3).
110
UN ESEMPIO DIVERSO
  • Servitore Cliente
  • int mcd(int m, int n) return (mn) m ?
    (mgtn) ? mcd(m-n, n) mcd(m, n-m)
  • main()
  • int m mcd(36,15)

Poiché 3 3, il servitore termina e restituisce
come risultato 3.
111
UN ESEMPIO DIVERSO
  • Perché questo esempio è diverso ?
  • il risultato viene sintetizzato via via che le
    chiamate si aprono, in avanti
  • quando le chiamate si chiudono non si fa altro
    che riportare indietro, fino al cliente, il
    risultato ottenuto.

112
UNA RIFLESSIONE
  • La soluzione ricorsiva individuata per lMCD è
    sintatticamente ricorsiva...
  • ma dà luogo a un processo computa-zionale
    diverso dal precedente
  • un processo computazionale ITERATIVO
  • Il risultato viene sintetizzato in avanti
  • ogni passo decompone e calcola
  • e porta in avanti il nuovo risultato parziale

113
UNA RIFLESSIONE
  • Ogni processo computazionale ITERATIVO
  • calcola a ogni passo un risultato parziale
  • dopo k passi, si ha a disposizione il risultato
    parziale relativo al caso k
  • questo non è vero nei processi computa-zionali
    ricorsivi
  • là, finché non si sono aperte tutte le chiamate,
    non è disponibile nessun risultato!

114
RICORSIONE TAIL
  • Una ricorsione che realizza un processo
  • computazionale ITERATIVO
  • è una ricorsione solo apparente
  • la chiamata ricorsiva è sempre lultima
    istruzione
  • i calcoli sono fatti prima
  • la chiamata serve solo, dopo averli fatti, per
    proseguire la computazione
  • questa forma di ricorsione si chiama RICORSIONE
    TAIL (ricorsione in coda)
Write a Comment
User Comments (0)
About PowerShow.com