Sei sulla pagina 1di 30

Cenni di programmazione ricorsiva

Appunti per gli studenti di Programmazione I e Laboratorio


(corsi A-B)

Corso di Laurea in Informatica


Università di Pisa
A.A. 2009/10

R. Barbuti, P. Mancarella
Indice
1 Definizioni Ricorsive 3
1.1 Il Teorema di Ricorsione . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
1.2 Esempi di applicazione del teorema di ricorsione . . . . . . . . . . . . . . . . . . 11
1.3 Applicazione del teorema di ricorsione alle grammatiche libere . . . . . . . . . . . 12
1.4 Grafici di funzioni . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
1 Definizioni Ricorsive
Nel paradigma funzionale siamo interessati alla definizione di funzioni, eventualmente ricorsive,
per la risoluzione di problemi. In effetti, molti problemi di calcolo possono essere formulati
ricorsivamente in modo naturale. Un esempio tipico è la seguente definizione della funzione
fattoriale, dai naturali nei naturali:
(
1 se n = 0
n! =
n ∗ (n − 1)! se n > 0

Un altro esempio è la definizione della successione dei numeri di Fibonacci:

f0 = 1
f1 = 1
fn = fn−1 + fn−2 per n ≥ 2

Anche nella definizione sintattica di linguaggi attraverso l’uso di grammatiche si utilizzano


definizioni ricorsive. Ad esempio, nella grammatica:
<S> ::= ab | a<S>b
la seconda produzione è ricorsiva, in quanto definisce le stringe generate dalla categoria sintattica
<S> in termini della categoria sintattica <S> stessa.
Un altro esempio sono definizioni ricorsive di insiemi. Prendiamo la seguente equazione

P = {0} ∪ {n | n ∈ N ∧ (n − 2) ∈ P}

Cosa possiamo dire sull’insieme definito da questa equazione?


(1) dal primo operando di ∪ concludiamo 0 ∈ P
(2) dal secondo operando concludiamo anche 2 ∈ P, essendo 2 − 2 = 0 e sapendo 0 ∈ P da (1)
(3) analogamente concludiamo anche 4 ∈ P, e cosı̀ via.

In pratica siamo in grado di costruire insiemi via via più grandi:

{0}
{0, 2}
{0, 2, 4}
{0, 2, 4, 6}
...

fino ad ottenere, in un numero infinito di iterazioni del procedimento descritto, l’insieme dei
numeri pari.

Un risultato fondamentale, noto come teorema di ricorsione, garantisce che definizioni ricor-
sive come le precedenti sono ben formulate, ovvero è possibile associare ad esse un significato
univoco. Una discussione approfondita del teorema di ricorsione esula dagli scopi del corso di
Programmazione I e Laboratorio. Tuttavia, ricordiamo qui di seguito l’intuizione alla base di
tale risultato con l’ausilio di esempi.

3
1.1 Il Teorema di Ricorsione
Per semplicità, ci concentriamo sul significato di definizioni ricorsive di insiemi: vedremo poi
come, in realtà, anche una definizione di funzione ricorsiva si possa ricondurre alla definizione
ricorsiva di un insieme (il grafico della funzione stessa). In generale, una definizione ricorsiva di
insieme è un’equazione del tipo
X = T (X)
dove T è una trasformazione da insiemi in insiemi.
Consideriamo, ad esempio, la seguente trasformazione che, dato un insieme di numeri naturali
restituisce un insieme di numeri naturali:

T (X) = {0} ∪ {n | n ∈ N ∧ (n − 2) ∈ X}

Applicando, ad esempio, la trasformazione T (·) all’insieme {3, 9, 4}, otteniamo:

T ({3, 9, 4})
=  { definizione di T (·) }
{0} ∪ n | n ∈ N ∧ (n − 2) ∈ {3, 9, 4}
= { (n − 2) ∈ {3, 9, 4} se e solo se n = 5 ∨ n = 11 ∨ n = 6 }
{0} ∪ {5, 6, 11}
= { unione insiemistica }
{0, 5, 6, 11}

A partire dalla trasformazione T (·) possiamo ottenere la seguente definizione ricorsiva di un


insieme di numeri naturali

X = {0} ∪ {n | n ∈ N ∧ (n − 2) ∈ X} (1)

Il problema che ci poniamo è come determinare una soluzione di un’equazione ricorsiva su insiemi
come la (1).
Nel caso di definizioni ricorsive che definiscono numeri reali, il calcolo analitico ci mette a
disposizione dei metodi per la risoluzione di equazioni analoghe. Data, ad esempio, la seguente
funzione dai reali nei reali
f (x) = 2x − 4
l’equazione
x = f (x)
non è altro che un’equazione di primo grado la cui (unica) soluzione è data da x = 4.
In generale, data un’equazione ricorsiva su insiemi X = T (X) vogliamo stabilire se essa ammette
una soluzione, ovvero determinare un insieme che sia invariante rispetto alla trasformazione T (·).
Un insieme siffatto viene detto punto fisso della trasformazione T (·).
Esempio 1.1. Consideriamo la funzione T : PN −→ PN cosı̀ definita:

T (X) = N \ X

dove \ è l’operazione di differenza insiemistica1 . È facile convincersi che non esiste soluzione
all’equazione ricorsiva
X = T (X)
1
Dati due insiemi A e B, A \ B è l’insieme di tutti e soli gli elementi di A che non sono elementi di B.

4
ovvero che la trasformazione T (·) non ammette punti fissi.
Consideriamo ora la trasformazione

add1(X) = X ∪ {1}.

Anche in questo caso è facile convincersi che un qualunque insieme Y con 1 ∈ Y è un punto fisso
di add1 e dunque una soluzione dell’equazione ricorsiva

X = add1(X).

Ne concludiamo che add1 ammette infiniti punti fissi.


Consideriamo infine la trasformazione

P(X) = {0} ∪ {n | n ∈ N ∧ (n − 2) ∈ X}

L’insieme dei numeri naturali pari è chiaramente un punto fisso di P. 

Gli esempi precedenti mostrano che equazioni ricorsive del tipo X = T (X) possono non ammet-
tere punti fissi, o ammetterne più d’uno (anche infiniti). Il problema è allora quello di studiare
in quali situazioni le nostre equazioni ricorsive ammettono punti fissi e, in caso affermativo,
individuarne uno come la soluzione canonica dell’equazione.
Il teorema di ricorsione garantisce che, se la trasformazione T (·) gode di certe proprietà, ammette
almeno un punto fisso e fornisce altresı̀ un modo per calcolare il minimo punto fisso, che può
essere dunque preso come l’insieme definito dall’equazione ricorsiva. L’apparato formale richiesto
nel caso generale è piuttosto complesso ed esula dagli scopi di queste note: ci limitiamo qui a
vedere il teorema di ricorsione nel solo caso di equazioni ricorsive su insiemi.
Sia allora A un insieme2 e sia PA l’insieme delle sue parti, ovvero l’insieme che contiene tutti i
possibili sottoinsiemi di A. Sia T (·) una trasformazione che mappa elementi di PA in elementi
di PA .

Definizione 1.1. (Monotonia e Continuità)


Una trasformazione T : PA −→ PA si dice:

(a) monotona se, presi X, Y ∈ PA , con X ⊆ Y , si ha T (X) ⊆ T (Y ).

(b) continua se, presa una qualunque sequenza (eventualmente infinita)

X0 ⊆ X1 ⊆ . . . ⊆ Xi ⊆ Xi+1 . . .
con Xi ∈ PA per ogni i ≥ 0, si ha
[ [
T( Xi ) = T (Xi ).
i≥0 i≥0

Vediamo alcuni esempi di trasformazioni su insiemi di naturali e studiamone monotonia e


continuità.
2
L’insieme A deve essere numerabile e in queste note sarà spesso l’insieme N dei numeri naturali.

5
Esempio 1.2. Consideriamo di nuovo la funzione

add1 : PN −→ PN

definita da
add1(X) = X ∪ {1}
che aggiunge l’elemento 1 al suo argomento. Ad esempio

add1({0, 4, 2}) = {0, 4, 2} ∪ {1} = {0, 4, 2, 1}

e
add1({1, 4, 2}) = {1, 4, 2} ∪ {1} = {1, 4, 2}.
Mostriamo che add1 è monotona. Siano X, Y ∈ PN con X ⊆ Y . Abbiamo:

add1(X)
= { definizione di add1 }
X ∪ {1}
⊆ { Ipotesi X ⊆ Y e proprietà di ∪ }
Y ∪ {1}
= { definizione di add1 }
add1(Y )

Mostriamo ora anche la continuità di add1. Sia

X0 ⊆ X1 ⊆ . . . ⊆ Xi ⊆ Xi+1 . . .

una sequenza non decrescente di insiemi di numeri naturali. Abbiamo:


S
add1(Xi )
i≥0
= S  { definizione di add1 }
Xi ∪ {1}
i≥0
= S  { Proprietà di ∪ }
{1} ∪ Xi
i≥0
= S  { definizione di add1 }
add1 Xi
i≥0

Vediamo ora un esempio di funzione non monotona.

Esempio 1.3. Sia T : PN −→ PN definita da


(
{} se #X ≥ 2
T (X) =
X se #X < 2

dove con la notazione #A indichiamo la cardinalità (ovvero il numero di elementi) di A. Con-


sideriamo gli insiemi {0} ⊆ {0, 1, 2}. Abbiamo:

6
T ({0})
= { definizione di T (·), essendo #{0} = 1 }
{0}

T ({0, 1, 2})
= { definizione di T (·), essendo #{0, 1, 2} = 3 }
{}

Dunque {0} ⊆ {0, 1, 2} ma T ({0}) 6⊆ T ({0, 1, 2}) e quindi la trasformazione non è monotona. 

Consideriamo infine una funzione monotona ma non continua.

Esempio 1.4. Sia F : PN −→ PN definita da


(
{} se X è un insieme finito
F(X) =
{1} se X è un insieme infinito

È facile vedere che F(·) è monotona. Consideriamo la sequenza

Xi = {n ∈ N | n ≤ i} con i ≥ 0

In altre parole

X0 = {0}
X1 = {0, 1}
X2 = {0, 1, 2}
..
.

e dunque X0 ⊆ X1 ⊆ X2 ⊆ . . .. È evidente che


[
Xi = N
i≥0

e quindi [
F( Xi ) = {1}.
i≥0

D’altra parte, per ciascun i ≥ 0, si ha F(Xi ) = {} e dunque


[
F(Xi ) = {},
i≥0

da cui concludiamo che F(·) non è continua. 

Un primo importante risultato è il seguente teorema che mostra come ogni funzione continua
sia anche monotona.

Teorema 1.1. Sia T : PA −→ PA una funzione continua. Allora T (·) è monotona.

Dimostrazione. Prendiamo X1 , X2 ∈ PA con X1 ⊆ X2 . Abbiamo:

7
T (X1 ) ∪ T (X2 ) S
= S { definizione di }
T (Xi )
i=1,2
= S { continuità di T (·) }
T( Xi )
i=1,2 S
= { definizione di }
T (X1 ∪ X2 )
= { Ipotesi X1 ⊆ X2 }
T (X2 )

Ma T (X1 ) ∪ T (X2 ) = T (X2 ) implica T (X1 ) ⊆ T (X2 ).

Mostriamo ora che l’operazione di unione è una funzione continua.

Teorema 1.2. Sia Y ∈ PA . La funzione FY : PA −→ PA definita da

FY (X) = X ∪ Y

è continua.

Dimostrazione. Sia X0 ⊆ X1 ⊆ X2 ⊆ . . . una sequenza di insiemi di PA . Allora:


S
FY (Xi )
i≥0
= S  { definizione di FY }
Xi ∪ Y
i≥0
= S  { proprietà di ∪ }
Xi ∪ Y
i≥0
= S  { definizione di FY (·) }
FY Xi
i≥0

Siano F : PA −→ PA e G : PA −→ PA due funzioni. La funzione composta F ◦ G : PA −→ PA


è cosı̀ definita:
(F ◦ G)(X) = F(G(X)).
È facile convincersi che la composizione di funzioni continue è essa stessa una funzione continua.

Teorema 1.3. La composizione di due funzioni continue è una funzione continua.

Dimostrazione. Siano F e G due funzioni continue. Consideriamo la sequenza

X0 ⊆ X1 ⊆ X2 ⊆ . . .

Abbiamo

8
S 
F G Xi
i≥0
= S  { continuità di G }
F G(Xi )
i≥0
= S  { monotonia di G, continuità di F }
F G(Xi )
i≥0

Torniamo al nostro problema di partenza che è quello di determinare l’esistenza o meno di


soluzioni, ovvero punti fissi, di equazioni ricorsive su insiemi del tipo X = T (X) e veniamo al
teorema fondamentale.
Data una trasformazione T : PA −→ PA ed un insieme A ∈ PA , con T i (A), i ≥ 0, indichiamo
la composizione di T con sé stessa i volte, ovvero

T i (A) = T (T (T (. . . T (A) . . .)))


| {z }
i volte

Per convenzione, assumeremo T 0 (A) = A. Ad esempio

T 2 (A) = T (T (A))

Teorema 1.4. (Teorema di Ricorsione)


Sia X = T (X) un’equazione ricorsiva con T : PA −→ PA . Se T (·) è continua allora:
S i
(a) l’insieme I = T ({}) è un punto fisso di T (·)
i≥0

(b) per ogni altro punto fisso J di T (·), si ha I ⊆ J.

L’insieme I è detto il minimo punto fisso della trasformazione T (·).

Prima di dimostrare il teorema di ricorsione, riflettiamo sul suo enunciato. Il punto (a) non
solo garantisce che, nel caso di trasformazioni continue, un punto fisso esiste, ma ci dà anche
un modo per costruirlo. Inoltre, il punto (b) ci garantisce che qualunque altro punto fisso è
un sovrainsieme del punto fisso costruito in (a) e dunque quest’ultimo può essere preso come la
soluzione canonica dell’equazione ricorsiva definita da X = T (X).
La dimostrazione del teorema di ricorsione si basa, tra l’altro, sul seguente Lemma.

Lemma 1.5. Sia T : PA −→ PA una trasformazione continua. Allora

T i ({}) ⊆ T i+1 ({}), per ogni i ≥ 0.

Dimostrazione. Dimostriamo l’asserto per induzione.


Passo base
Per i = 0 abbiamo

9
T 0 ({})
= { definizione di T i }
{}
⊆ { {} ⊆ A, per ogni insieme A }
T ({})
= { definizione di T i }
T 1 ({})

Passo induttivo
Supponiamo vero T n ({}) ⊆ T n+1 ({}) e dimostriamo T n+1 ({}) ⊆ T n+2 ({}).
T n+1 ({})
= { definizione di T i }
T (T n ({}))
⊆ { per l’ipotesi induttiva e la monotonia di T }
T (T n+1 ({}))
= { definizione di T i }
T n+2 ({})

Si noti che il Lemma mostra che, al crescere di i, gli insiemi T i ({}) sono approssimazioni sempre
migliori del minimo punto fisso.
Veniamo alla dimostrazione del teorema di ricorsione.

Dimostrazione. (del Teorema 1.4)


(a) Dimostriamo dapprima che l’insieme
[
I= T i ({})
i≥0

è un punto fisso di T (·). Abbiamo:


T (I)
= S { definizione di I }
T( T i ({}))
i≥0
= S { per continuità di T (·) }
T (T i ({}))
i≥0
= S { per definizione di T i (·) }
T i+1 ({})
i≥0
= S
T i ({})
i≥1
= S { {} ∪ A = A per ogni A }
{} ∪ T i ({})
i≥1
= S { {} = T 0 ({}) }
T 0 ({}) ∪ T i ({})
i≥1

10
= S
T i ({})
i≥0
= { definizione di I }
I
Mostriamo ora che I è il minimo punto fisso. Sia J un punto fisso di T (·), ovvero J = T (J).
Mostriamo per induzione che:
T i ({}) ⊆ J, per ogni i ≥ 0
Passo base
Per i = 0 abbiamo
T 0 ({})
= { definizione di T i }
{}
⊆ { {} ⊆ J, per ogni insieme J }
J

Passo induttivo
Supponiamo vero T n ({}) ⊆ J e dimostriamo T n+1 ({}) ⊆ J.
T n+1 ({})
= { definizione di T i }
T (T n ({}))

⊆ { per l’ipotesi induttiva e la monotonia di T }


T (J)
= { per ipotesi J è punto fisso di T (·) }
J
A questo punto è facile dimostrare che I ⊆ J. Infatti:
I
= S { definizione di I }
T i ({})
i≥0
⊆ { per ogni i, T i ({}) ⊆ J }
J

1.2 Esempi di applicazione del teorema di ricorsione


In questa sezione vediamo alcune applicazioni del teorema di ricorsione a definizioni ricorsive di
insiemi.

Esempio 1.5. Consideriamo di nuovo l’equazione dell’esempio 1

X = {0} ∪ {n | n ∈ N ∧ (n − 2) ∈ X} (2)

ovvero l’equazione X = P(X), dove P è la trasformazione:

P(X) = {0} ∪ {n | n ∈ N ∧ (n − 2) ∈ X}

11
Indichiamo per semplicità con P i l’insieme P i ({}), ovvero l’i−esima approssimazione del min-
imo punto fisso soluzione dell’equazione, e calcoliamo le prime approssimazioni che ci derivano
dall’applicazione del teorema di ricorsione.
P0 = P 0 ({}) = {}

P1 = P(P 0 ({})) = P(P 0 ) =


= {0} ∪ {n | n ∈ N ∧ (n − 2) ∈ {}} =
= {0} ∪ {} = {0}

P2 = P(P 1 ({})) = P(P 1 ) =


= {0} ∪ {n | n ∈ N ∧ (n − 2) ∈ P 1 } =
= {0} ∪ {n | n ∈ N ∧ (n − 2) ∈ {0}} = {0, 2}

P3 = P(P 2 ({})) = P(P 2 ) =


= {0} ∪ {n | n ∈ N ∧ (n − 2) ∈ {0, 2}} =
= {0, 2, 4}
...

È facile convincersi che


P i = {n | n ∈ N ∧ ∃k < i. n = 2 ∗ k}

Consideriamo ora l’equazione


X = add1(X)
dove add1(X) = X ∪ {1} è la funzione continua vista nell’esempio 1.2. Osserviamo che un
qualunque insieme di numeri che contiene {1} è un punto fisso dell’equazione. Calcoliamone il
minimo mediante approssimazioni successive.

X 0 = {}

X 1 = add1({}) = {} ∪ {1} = {1}

X 2 = add1(X 1 ) = add1({1}) = {1} ∪ {1} = {1}


Dunque X 2 = add1(X 2 ) è il minimo punto fisso cercato e viene preso come la soluzione dell’e-
quazione ricorsiva. Si noti che in questo caso la costruzione del minimo punto fisso ci consente
di determinarlo in un numero finito di iterazioni del procedimento suggerito dal teorema di
ricorsione. 

1.3 Applicazione del teorema di ricorsione alle grammatiche libere


Il teorema di ricorsione può essere utilizzato anche per dare significato alle definizioni di linguaggi
mediante grammatiche libere. L’idea consiste nell’interpretare le produzioni di una grammatica
come definizioni ricorsive.

12
Per fare ciò introduciamo dapprima l’operazione di concatenazione tra linguaggi.
Definizione 1.2. (Concatenazione di linguaggi)
Siano L, L′ ⊆ Λ∗ due linguaggi. La concatenazione di L e L′ , denotata da LL′ è il linguaggio

LL′ = {αβ | α ∈ L ∧ β ∈ L′ }

dove αβ è la stringa ottenuta concatenando le stringhe α e β.


Osserviamo che vale la seguente proprietà,

L{} = {}L = {}

ovvero la concatenazione di un linguaggio col linguaggio vuoto dà origine al linguaggio vuoto.
Vediamo allora come interpretare le produzioni di una grammatica come equazioni su linguaggi.

• ogni simbolo terminale a viene interpretato come il linguaggio {a};

• ogni simbolo non terminale A viene interpretato come variabile sui linguaggi;

• una sequenza di simboli viene interpretata come concatenazione dei linguaggi corrispon-
denti ai simboli stessi.

• il simbolo | viene interpretato come l’operazione di unione ∪

• il simbolo −→ (ovvero ::=) viene interpretato come l’uguaglianza

Un esempio aiuta a chiarire la costruzione.


Esempio 1.6. Consideriamo la seguente grammatica
S ::= ab | aSb
L’equazione ricorsiva che otteniamo è la seguente

S = {a}{b} ∪ {a}S{b}

che può essere riscritta come

S = {ab} ∪ {a}S{b}

L’esempio mostra come da un insieme di produzioni di una grammatica si possa costruire


un’equazione ricorsiva3 del tipo

S = T (S) (3)

dove T è una trasformazione da linguaggi in linguaggi, ottenuta mediante le operazioni di unione


e concatenazione (oltre che mediante composizione di funzioni). Nell’esempio precedente la
trasformazione ottenuta è
T (X) = {ab} ∪ {a}X{b}
3
Come vedremo più avanti si ottiene in generale un sistema di equazioni ricorsive, tante quante sono le categorie
sintattiche della grammatica di partenza.

13
Poiché unione e concatenazione di linguaggi sono operazioni continue (cosı̀ come la composizione
di funzioni continue come già visto), abbiamo la possibilità di utilizzare il teorema di ricorsione
per ottenere la soluzione di una equazione come la (3).
Torniamo al nostro esempio e, denotando al solito con S i l’insieme T i ({}), calcoliamo le prime
approssimazioni del minimo punto fisso dell’equazione ottenuta. Abbiamo:

S 0 = {}

S 1 = T ({}) = {ab} ∪ {a}{}{b} = {ab}

S 2 = T (S 1 ) = {ab} ∪ {a}S 1 {b} = {ab, aabb}

S 3 = T (S 2 ) = {ab} ∪ {a}S 2 {b} = {ab, aabb, aaabbb}

È facile vedere che


S i = {ak bk | k ≤ i}
e dunque che il minimo punto fisso è:
[
S i = {an bn | n > 0}
i≥0

Consideriamo ora una grammatica libera che utilizza più categorie sintattiche.

Esempio 1.7. Sia G la seguente grammatica

S ::= a | aS | B
B ::= b | bB

Dalla trasformazione vista otteniamo il seguente sistema di equazioni ricorsive

S = {a} ∪ {a}S ∪ B
B = {b} ∪ {b}B

In questo caso le trasformazioni in gioco sono due:

S = TS (S, B)
B = TB (S, B)

Osserviamo che, in questo caso particolare, la trasformazione TB non fa alcun uso del suo primo
argomento: tuttavia, nel caso generale, le variabili in gioco sono quelle corrispondenti a tutte le
categorie sintattiche della grammatica.

14
Il teorema di ricorsione si estende al caso di sistemi di equazioni ricorsive: calcoliamo le ap-
prossimazioni del minimo punto fisso nel nostro esempio.

S0 = {}
0
B = {}

S1 = TS ({}, {}) = {a} ∪ {a}{} ∪ {} = {a}


1
B = TB ({}, {}) = {b} ∪ {b}{} = {b}

S2 = TS (S 1 , B 1 ) = {a} ∪ {a}S 1 ∪ B 1 = {a, aa, b}


B2 = TB (S 1 , B 1 ) = {b} ∪ {b}B 1 = {b, bb}

S3 = TS (S 2 , B 2 ) = {a} ∪ {a}S 2 ∪ B 2 = {a, aa, aaa, ab, b, bb}


B3 = TB (S 2 , B 2 ) = {b} ∪ {b}B 2 = {b, bb, bbb}

...

1.4 Grafici di funzioni


Una qualunque funzione
f : A −→ B
può essere rappresentata mediante il suo grafico, ovvero l’insieme di coppie Gf , sottoinsieme del
prodotto cartesiano A × B, cosı̀ definito:

Gf = {(x, y) | x ∈ A ∧ y ∈ B ∧ y = f (x)}

Una definizione ricorsiva di funzione porta ad una definizione ricorsiva del suo grafico. Vediamo
un esempio.

Esempio 1.8. Consideriamo la funzione fattoriale dai naturali nei naturali.


(
1 se n = 0
n! =
n ∗ (n − 1)! se n > 0

Il suo grafico è allora il seguente insieme di coppie di naturali

G! = {(0, 1)} ∪ {(n, m) | n > 0 ∧ m = n ∗ m′ ∧ (n − 1, m′ ) ∈ G! }


| {z }
T

15
Si tratta, di nuovo, di un’equazione ricorsiva del tipo X = T (X) di cui calcoliamo la soluzione
determinando il minimo punto fisso della trasformazione T (·).

G0! = {}


G1! = T (G0! ) = {(0, 1)} ∪ (n, m) | n > 0 ∧ m = n ∗ m′ ∧ (n − 1, m′ ) ∈ {} =
= {(0, 1)} ∪ {} = {(0, 1)}


G2! = T (G1! ) = {(0, 1)} ∪ (n, m) | n > 0 ∧ m = n ∗ m′ ∧ (n − 1, m′ ) ∈ {(0, 1)} =

= {(0, 1)} ∪ (n, m) | n > 0 ∧ m = n ∗ m′ ∧ n − 1 = 0 ∧ m′ = 1 =

= {(0, 1)} ∪ (n, m) | n = 1 ∧ m = 1 ∗ 1 = {(0, 1), (1, 1)}


G3! = T (G2! ) = {(0, 1)} ∪ (n, m) | n > 0 ∧ m = n ∗ m′ ∧ (n − 1, m′ ) ∈ {(0, 1), (1, 1)} =
 
= {(0, 1)} ∪ (n, m) | n > 0 ∧ m = n ∗ m′ ∧ (n − 1 = 0 ∧ m′ = 1) ∨ (n − 1 = 1 ∧ m′ = 1) =
= {(0, 1)} ∪ {(1, 1), (2, 2)} = {(0, 1), (1, 1), (2, 2)}


G4! = T (G3! ) = {(0, 1)} ∪ (n, m) | n > 0 ∧ m = n ∗ m′ ∧ (n − 1, m′ ) ∈ {(0, 1), (1, 1), (2, 2)} =
= {(0, 1)} ∪ {(1, 1), (2, 2), (3, 6)} = {(0, 1), (1, 1), (2, 2), (3, 6)}

...

Dunque dalle prime approssimazioni del grafico concludiamo che

0! = 1 1! = 1 2! = 2 3! = 6

Il teorema di ricorsione ci garantisce dunque l’esistenza di una soluzione di equazioni ricorsive


che definiscono funzioni, ma non ci garantisce nulla circa la “bontà” di tali soluzioni.

Esempio 1.9. Consideriamo la seguente funzione dai naturali nei naturali


(
1 se x = 1
f (x) =
1 + f (x + 1) altrimenti

ed il suo grafico
F = {(1, 1)} ∪ {(x, y) | y = 1 + y ′ ∧ (x + 1, y ′ ) ∈ F }
| {z }
T

16
Calcoliamone la soluzione come minimo punto fisso di T (·).

F 0 = {}


F 1 = T (F 0 ) = {(1, 1)} ∪ (x, y) | y = 1 + y ′ ∧ (x + 1, y ′ ) ∈ {} =
= {(1, 1)}


F 2 = T (F 1 ) = {(1, 1)} ∪ (x, y) | y = 1 + y ′ ∧ (x + 1, y ′ ) ∈ {(1, 1)} =
= {(1, 1), (0, 2)}


F 3 = T (F 2 ) = {(1, 1)} ∪ (x, y) | y = 1 + y ′ ∧ (x + 1, y ′ ) ∈ {(1, 1), (0, 2)} =
= {(1, 1), (0, 2)} = F 2

Abbiamo cosı̀ ottenuto che l’insieme {(1, 1), (0, 2)} è il minimo punto fisso della trasformazione
T (·) e dunque la funzione f è tale che:

2
 se n = 0
f (n) = 1 se n = 1


indefinita altrimenti

Nell’esempio, il punto fisso esiste ma non è una funzione totale sul suo dominio. Ricordiamo che
una funzione
g : A −→ B
si dice totale se calcola un valore per ciascun elemento del suo dominio, ovvero se

∀x ∈ A. ∃y ∈ B.y = f (x)

È chiaro che, di solito, siamo interessati alla definizione di funzioni totali: come abbiamo appena
visto, il teorema di ricorsione ci garantisce l’esistenza di soluzioni di definizioni ricorsive di
funzioni, ma nulla ci dice circa il fatto che tali soluzioni siano o meno funzioni totali.

17
2 Progetto e realizzazione di funzioni ricorsive
Il procedimento costruttivo dato dal teorema di ricorsione suggerisce due fatti importanti. Una
buona definizione ricorsiva deve essere tale da garantire che
• la funzione sia immediatamente definita su alcuni casi semplici (n = 0 nel caso della
funzione fattoriale), i cosiddetti casi base della definizione;
• per tutti gli altri argomenti (non base) il calcolo della funzione deve poter essere ricondotto
al calcolo della funzione medesima su argomenti “più semplici” (ad esempio n − 1 nel caso
della funzione fattoriale).

Detto informalmente, il primo fatto garantisce che, nel calcolo della prima approssimazione
del minimo punto fisso non si riottenga l’insieme vuoto; il secondo fatto garantisce che, ad
ogni approssimazione successiva, è possibile ricondurre la costruzione al calcolo di valori della
funzione su argomenti per i quali è già noto il valore della funzione stessa. Si noti come la
funzione f dell’esempio (1.8), che abbiamo visto essere indefinita su tutti gli argomenti diversi
da 0 e 1, non rispetti il secondo requisito.
Scopo di questa sezione è formalizzare questi concetti intuitivi tramite il principio di induzione
ben fondata.

2.1 Relazioni di precedenza e insiemi ben fondati


Il primo problema da affrontare è dare sostanza ai concetti di caso base e argomento più semplice
introdotti sopra in modo informale. A questo scopo utilizziamo la nozione di insieme ben fondato
che si basa, a sua volta, sul concetto di relazione di precedenza ben fondata.
Definizione 2.1. (Relazione di precedenza)
Sia S un insieme. Una relazione di precedenza R su S è una relazione binaria su S, vale a dire
un insieme di coppie di elementi di S. Formalmente, R ⊆ S × S.

Data una relazione di precedenza R, useremo la usuale notazione infissa xRy per rappresentare
l’appartenenza della coppia (x, y) alla relazione medesima e diremo spesso che “x precede y”
secondo R. Scriveremo inoltre x R 6 y ad indicare che la coppia (x, y) non appartiene alla relazione
R e diremo in questo caso che “x non precede y” Inoltre faremo spesso uso di simboli quali
≺, , ⊏, . . . per denotare relazioni di precedenza.
In alcuni casi avremo bisogno di considerare la chiusura transitiva di una relazione di precedenza,
definita come segue.
Definizione 2.2. (Chiusura transitiva)
Sia R una relazione di precedenza su S. La sua chiusura transitiva R+ è la più piccola relazione
binaria su S che contiene R e che gode della proprietà transitiva, ovvero:
(a) R ⊆ R+
(b) se xR+ y e yR+ z allora xR+ z

Terminologia
Sia ≺ una relazione di precedenza su un insieme S. Allora un elemento x ∈ S si dice minimale
(rispetto a ≺) se non esiste y ∈ S tale che y ≺ x.
Vediamo qualche esempio.

18
Esempio 2.1. Sia N l’insieme dei numeri naturali e sia ≺ la relazione cosı̀ definita

x ≺ y se e solo se x = y − 1

Quindi, ad esempio, 2 ≺ 3, 3 ≺ 4, ma 2 6≺ 4. È facile osservare che 0 è minimale rispetto a


≺. Si noti poi che la chiusura transitiva della relazione ≺ non è altro che l’usuale relazione di
“minore” tra numeri naturali definita formalmente da x < y ≡ (∃k 6= 0.y = x + k).
Un altro esempio di relazione di precedenza su N è il seguente:

x ⊏ y ≡ x 6= y ∧ divide(x, y)

dove divide(x, y) esprime il fatto che x è un divisore di y. Quindi, ad esempio, 2 ⊏ 16, 3 ⊏ 9, e


cosı̀ via. Si noti che gli elementi minimali rispetto a ⊏ sono 0 e 1. Inoltre, la chiusura transitiva
di ⊏ coincide con ⊏ stessa. Siano infatti x, y, z ∈ N tali che divide(x, y) e divide(y, z), ovvero
y = k · x e z = h · y, per qualche h, k 6= 0. Dunque z = h · k · x, ovvero divide(x, z) e dunque
x ⊏ z. 

Definizione 2.3. (Relazione ben fondata)


Una relazione di precedenza ≺ su un insieme S si dice ben fondata se e solo se non esiste una
catena decrescente infinita
a0 ≻ a1 ≻ a2 ≻ . . .
di elementi ai ∈ S.

Nel seguito, dato un insieme S e una relazione binaria ≺ su S diremo che (S, ≺) è un insieme
ben fondato (risp. non è un insieme ben fondato) se la relazione ≺ è ben fondata (risp. non è
ben fondata).

Esempio 2.2. Consideriamo (N, ≺) con ≺ definita come nell’Esempio 2.1. Chiaramente (N, ≺)
è ben fondato, poiché ogni catena descrescente termina al più con 0. Lo stesso dicasi per l’insieme
(N, ⊏) dello stesso esempio (perché?).
Consideriamo ora l’insieme Z dei numeri interi e la relazione di precedenza ≺ definita, come nel
caso dei numeri naturali, da
x ≺ y se e solo se x = y − 1
È evidente che (Z, ≺) non è ben fondato. La seguente è, ad esempio, una catena decrescente
infinita
2 ≻ 1 ≻ 0 ≻ −1 ≻ −2 ≻ . . .
È invece ben fondato l’insieme (Z, ≪) dove ≪ è definita da

x ≪ y ≡ (y ∈ Z+ ∧ x = y − 1) ∨ (y ∈ Z− ∧ x = y + 1)

in cui Z+ e Z− indicano, rispettivamente, l’insieme degli interi positivi e negativi. Come nel
caso di (N, ≺) è facile convincersi che anche in questo caso ogni catena decrescente termina al
più con 0 (che è anche l’unico elemento minimale di Z rispetto a ≪). 

19
Come messo in luce dagli esempi precedenti, la “ben fondatezza” o meno di un insieme dipende
dalla relazione scelta (per esercizio invitiamo il lettore a definire una relazione di precedenza
non banale ⊲ su N in modo che (N, ⊲) non sia ben fondato). Né il fatto che esistano elementi
minimali rispetto ad una relazione di precedenza è condizione sufficiente per garantire la ben
fondatezza della medesima.
Un’ultima osservazione riguarda il fatto che, data una relazione  su un insieme S, se  non
è antiriflessiva, allora sicuramente (S, ) non è ben fondato4 . Preso infatti un elemento a ∈ S
tale che a  a, quella che segue è una catena decrescente infinita

a  a  a  a...

2.2 Rappresentazione grafica di relazioni di precedenza


In questa sezione mostriamo un’utile rappresentazione grafica di una relazione di precedenza,
che si ottiene tracciando un diagramma della relazione medesima, in cui si rappresenta con
y

il fatto che “x precede y”, ovvero che la coppia (x, y) appartiene alla relazione data.
Laddove ciò non crei ambiguità, per comodità faremo uso di linee semplici anziché di frecce
y

tracciando il “predecessore” x sotto il suo “successore” y. Vediamo qualche esempio.


Esempio 2.3. I diagrammi degli insiemi (Z, ≺) e (Z, ≪) dell’esempio 2.2 sono i seguenti.

−2 2
−1
−1 1
−2
0

4
Ricordiamo che una relazione R su un insieme S è antiriflessiva se nessun elemento in S è in relazione R con
sé stesso.

20
La rappresentazione mediante diagrammi consente spesso di verificare facilmente la ben fon-
datezza o meno di un insieme: nell’esempio si vede chiaramente che nel primo caso (Z, ≺) non
è ben fondato, mentre lo è (Z, ≪) nel secondo caso. 

Nel seguito, data una relazione di precedenza ≺ su un insieme S, ci accontenteremo di tracciarne


il diagramma per verificare la ben fondatezza o meno di (S, ≺). Nonostante tale rappresentazione
non possa necessariamente essere esaustiva nel caso di insiemi infiniti, l’utilizzo di opportune as-
trazioni e semplificazioni ci consente di ottenere diagrammi che, seppure parziali, sono sufficienti
per convincerci della ben fondatezza o meno della relazione.
Inoltre, la rappresentazione grafica di una relazione ≺ costituisce, ai fini della verifica di
ben fondatezza o meno, una buona rappresentazione anche della sua chiusura transitiva ≺+ ,
sebbene non siano esplicitamente rappresentate le coppie x ≺+ y tali che x 6≺ y. È infatti facile
convincersi che, se x ≺+ y è comunque possibile seguire, nel diagramma di ≺, un percorso da x
a y seguendo gli archi del diagramma.
Vediamo qualche esempio.

Esempio 2.4. Sia ⊏ la relazione di precedenza definita su N come segue:

n ⊏ m se e solo se m = n + A

dove A è un numero naturale non nullo. La rappresentazione grafica è la seguente

3A 3A+1 4A−1

2A 2A+1 3A−1

A A+1 2A−1

0 1 A−1

dalla quale è facile convincersi che (N, ⊏) è ben fondato. Si noti come il diagramma rappresenti
anche la chiusura transitiva ⊏+ di ⊏, definita da

n ⊏+ m se e solo se ∃k > 0.m = n + k · A.

mettendone in evidenza la ben fondatezza.


Consideriamo ora l’insieme N × N delle coppie di numeri naturali e la relazione binaria cosı̀
definita
(n, m) ≺ (x, y) se e solo se n = x ∧ m = y − 1
A partire da un generico elemento (x, y) di N×N, tracciamo la catena decrescente che ha origine
in (x, y).

21
(x, y)

(x, y−1)

(x, y−2)

(x, 1)

(x, 0)

Anche in questo caso la rappresentazione grafica ci è sufficiente per stabilire che la relazione
definita è ben fondata su N × N. 

2.3 Il principio di induzione ben fondata


Abbiamo finalmente tutti gli strumenti per enunciare il principio di induzione ben fondata. Dato
un insieme S, indichiamo con ϕ(x) una proprietà in cui x denota un generico elemento di S.

Definizione 2.4. (Principio di induzione ben fondata)


Sia (S, ≺) un insieme ben fondato e sia ϕ(x) una proprietà su S. Vale allora il seguente asserto:

∀x ∈ S. (∀y ∈ S. y ≺ x ⇒ ϕ(y)) ⇒ ϕ(x)


∀z ∈ S. ϕ(z)

Diamo una lettura informale del principio sopra enunciato:

“se ϕ(x) è conseguenza del fatto che ϕ(y) vale per tutti gli elementi y ≺ x
allora la proprietà ϕ(·) vale per qualunque elemento di S”.

Il principio sopra enunciato ci suggerisce che, per dimostrare che un asserto ϕ(·) vale su tutti
gli elementi di un insieme ben fondato, è sufficiente dimostrare che l’asserto vale su un generico
elemento x dell’insieme, nell’ipotesi che ϕ(·) valga su ogni elemento y che precede x nella relazione
di precedenza scelta (che, lo ricordiamo, deve essere ben fondata).
Fissato x, la formula
(∀y ∈ S. y ≺ x ⇒ ϕ(y))
viene detta ipotesi induttiva rispetto a x.
Osserviamo ora che, se scegliamo x elemento minimale rispetto a ≺, l’ipotesi induttiva si riduce
a true e non può essere di aiuto nella dimostrazione di ϕ(x): dobbiamo quindi essere in grado
di dimostrare direttamente ϕ(x) per tutti gli elementi minimali in (S, ≺).
In pratica, la dimostrazione per induzione ben fondata di un asserto del tipo ∀x ∈ S.ϕ(x) consiste
nei seguenti passi:

(i) Si sceglie una relazione di precedenza ≺ su S in modo che (S, ≺) sia ben fondato

(ii) Si dimostra che ϕ(x) vale per tutti gli elementi minimali rispetto a ≺

22
(iii) detto x un generico elemento di S non minimale rispetto a ≺, si dimostra che ϕ(x) vale
nell’ipotesi che valga ϕ(y) per ogni y che precede x nella relazione ≺.

Il passo (ii) viene comunemente detto caso base e il passo (iii) caso induttivo della di-
mostrazione.
Prima di vedere alcuni esempi d’uso del principo di induzione ben fondata, ne diamo una di-
mostrazione informale. Sia dunque (S, ≺) un insieme ben fondato e sia ϕ(·) una proprietà sugli
elementi di S. Supponiamo che:

(1) ϕ(x) valga per ogni elemento x minimale rispetto a ≺

(2) preso un generico x ∈ S, con x non minimale, valga l’asserto

∀y ∈ S. y ≺ x ⇒ ϕ(y)

Supponiamo ora per assurdo che esista a1 ∈ S per cui vale ¬ϕ(a1 ). Chiaramente, come con-
seguenza di (1), a1 non è minimale, e dunque esiste a2 ∈ S con a2 ≺ a1 tale che ¬ϕ(a2 ). Infatti,
se cosı̀ non fosse, (2) garantirebbe che vale ϕ(a1 ) contraddicendo la nostra ipotesi ¬ϕ(a1 ). Allo
stesso modo, a2 non è minimale ed esiste a3 ∈ S con a3 ≺ a2 tale che ¬ϕ(a3 ). Iterando il
ragionamento, andiamo a costruire una catena di elementi di S

a1 ≻ a2 ≻ a3 ≻ . . .

decrescente infinita, contraddicendo l’ipotesi di ben fondatezza di (S, ≺).

2.4 Dimostrazione di proprietà di definizioni ricorsive mediante induzione


ben fondata
Il principio di induzione ben fondata può essere utile per dimostrare interessanti proprietà di
definizioni ricorsive.

Funzioni totali
Come ricordato in precedenza, siamo interessati alla definizione di funzioni totali, cioè
che calcolino un risultato per qualunque valore del proprio dominio. Data una funzione
f : A −→ B, siamo cioè interessati a dimostrare, per induzione ben fondata, che vale un
asserto del tipo 
∀x ∈ A. ∃y ∈ B.y = f (x)
Si tratta dunque di un asserto del tipo

∀x ∈ A. P (x)

che ben si presta ad essere dimostrato per induzione ben fondata. A tale scopo dobbiamo:

(i) individuare una relazione ben fondata ≺ su A


(ii) dimostrare che esiste ba ∈ B tale che ba = f (a), per ogni elemento a ∈ A minimale
rispetto a ≺
(iii) dimostrare che esiste bx ∈ B tale che bx = f (x), per un generico elemento x ∈ A
non minimale rispetto a ≺, nell’ipotesi che per ogni y ≺ x esista by ∈ B tale che
by = f (y).

23
Correttezza di funzioni
Per convincersi che una definizione ricorsiva di funzione risolva correttamente il problema
per la quale è stata progettata, è spesso necessario ricorrere ad una dimostrazione formale
per induzione ben fondata analoga al caso precedente. In questo caso, la dimostrazione
relativa ai punti (ii) e (iii) deve essere tale da garantire non solo l’esistenza di elementi
del codominio B (quelli indicati con ba in (ii) e bx in (iii)), ma anche il fatto che siano gli
elementi desiderati. Si noti che una dimostrazione di correttezza cosı̀ formulata è anche
una dimostrazione di totalità della funzione in esame.

È molto comune chiamare caso base e caso induttivo rispettivamente la parte (ii) e la parte
(iii) della dimostrazione.
Illustriamo quanto detto con alcuni esempi.

Esempio 2.5. Consideriamo la seguente definizione ricorsiva di funzione: f : N −→ {0, 1}



0
 se n = 0
pari(n) = 1 se n = 1

pari(n − 2) altrimenti

Vogliamo dimostrare che vale il seguente asserto

∀n ∈ N. pari(n) = n mod 2

dove a mod b indica il resto della divisione intera tra a e b.


Scegliamo l’usuale relazione di < tra numeri naturali che sappiamo essere una relazione ben
fondata, il cui unico elemento minimale è 0.
Caso base.

pari(0)
= { definizione di pari, primo caso }
0
= { definizione di mod }
0 mod 2

Caso induttivo. Consideriamo un generico n ∈ N non minimale, ovvero n 6= 0 e consideriamo


vera la seguente ipotesi induttiva

∀m < n. pari(m) = m mod 2

È evidente che, data la definizione di pari, dobbiamo procedere per casi, distinguendo il caso
n = 1 da tutti gli altri.

Primo caso induttivo n = 1

pari(1)
= { definizione di pari, secondo caso }
1
= { definizione di mod }
1 mod 2

24
Secondo caso induttivo n 6= 1

pari(n)
= { definizione di pari, terzo caso }
pari(n − 2)
= { Ipotesi induttiva, poiché n − 2 < n }
(n − 2) mod 2
= { proprietà di mod }
n mod 2

Dunque, la funzione pari calcola il valore 0 se il suo argomento è un numero naturale pari;
calcola invece il valore 1 se il suo argomento è dispari. 

Esempio 2.6. Consideriamo ora la funzione sum : N × N −→ N cosı̀ definita:


(
n se m = 0
somma(n, m) =
1 + somma(n, m − 1) altrimenti
e dimostriamo per induzione ben fondata la seguente proprietà:

∀n, m ∈ N.somma(n, m) = n + m

A questo scopo, scegliamo la relazione di precedenza su N × N dell’esempio 2.4 che riportiamo


di seguito per comodità

(n, m) ≺ (x, y) se e solo se n = x ∧ m = y − 1

Abbiamo già osservato che (N × N, ≺) è ben fondato e che gli elementi minimali rispetto a ≺
sono tutte e sole le (infinite) coppie del tipo (n, 0). Procediamo allora per induzione ben fondata.
Caso base.

somma(n, 0)
= { definizione di somma, primo caso }
n
= { definizione di + }
n+0

Caso induttivo. Sia (n, m) una generica coppia non minimale, ovvero con m 6= 0. Possiamo
fare uso, nella dimostrazione della seguente ipotesi induttiva:

∀x, y ∈ N.(x, y) ≺ (n, m) ⇒ somma(x, y) = x + y.

somma(n, m)
= { definizione di somma, secondo caso }
1 + somma(n, m − 1)
= { Ipotesi induttiva, poiché (n, m − 1) ≺ (n, m) }
1 + (n + m − 1)
= { calcolo }
n+m

25
Osserviamo ancora che le dimostrazioni dei due esempi precedenti mostrano anche che le funzioni
in esame sono funzioni totali sul proprio dominio.
La differenza principale tra la dimostrazione dell’esempio 2.5 e quella dell’esempio 2.6 è che nella
seconda la relazione di precedenza considerata fa sı̀ che i casi base corrispondano esattamente ai
casi in cui la funzione è definita in modo immediato, mentre nella prima ciò non succede (pari(1)
è definita in modo immediato ma 1 non è minimale nella relazione scelta). In generale, nella
dimostrazione di proprietà di funzioni ricorsive è conveniente utilizzare una relazione di prece-
denza sul dominio della funzione che rifletta in modo naturale la struttura della definizione stessa
della funzione, cosı̀ che i casi base e induttivo della dimostrazione corrispondano in maniera di-
retta alle varie alternative nella definizione della struttura. Ciò rende più semplice e soprattutto
meno soggetta ad errori od omissioni la dimostrazione. Il problema è, allora, determinare una
relazione di precedenza che rispecchi la definizione della funzione, come vediamo nella prossima
sezione.

2.5 Relazione di precedenza indotta


Le considerazioini fatte e gli esempi visti mettono in luce il fatto che una buona definizione
ricorsiva di funzione deve essere tale che:
(i) su alcuni argomenti il calcolo della funzione sia definito in modo immediato

(ii) sui restanti argomenti il calcolo della funzione possa essere ricondotto al calcolo della
funzione stessa ma su argomenti “più semplici”.
Grazie all’apparato formale della sezione 2.3 possiamo ora dire che un argomento è “più semplice”
di un altro se il primo precede il secondo rispetto ad una relazione di precedenza sul dominio
della funzione.
Definizione 2.5. Sia f : A −→ B una funzione definita in modo ricorsivo. La relazione di
precedenza ≺f indotta su A dalla definizione di f è definita come segue:
per ogni x, y ∈ A x ≺f y se e solo se f (y) è definita in termini di f (x).
Esempio 2.7. Consideriamo la definizione della funzione pari nell’esempio 2.5. La relazione
≺pari indotta da tale definizione è la seguente:

x ≺pari y se e solo se y 6= 0 ∧ y 6= 1 ∧ x = y − 2

Le condizioni y 6= 0 e y 6= 1 riflettono il fatto che solo in quei casi la definizione di f (y) è


espressa in termini di f (x). Si noti tuttavia che tali condizioni possono essere omesse, in quanto
y − 2 ∈ N se e soltanto se y ≥ 2, ovvero se e soltanto se y 6= 0 ∧ y 6= 1. Tracciamo il diagramma
della relazione cosı̀ definita.

6 7

4 5

2 3

0 1

26
La relazione è chiaramente ben fondata. Inoltre gli elementi minimali coincidono con quelli
sui quali la funzione è definita in modo immediato. L’utilizzo di ≺pari nella dimostrazione per
induzione ben fondata dell’asserto
∀n ∈ N. pari(n) = n mod 2
ci guida a considerare come casi base proprio quelli per cui la funzione è definita in modo
immediato e come caso induttivo quello per cui la funzione è definita in modo ricorsivo. I
dettagli della dimostrazione sono lasciati per esercizio. 
Esempio 2.8. Consideriamo una funzione f ib : N −→ N per il calcolo dei numeri di Fibonacci
introdotti nella Sezione 1:

1
 se n = 0
f ib(n) = 1 se n = 1

f ib(n − 1) + f ib(n − 2) altrimenti

La relazione di precedenza ≺f ib indotta da tale definizione è la seguente:


m ≺f ib n se e solo se n 6= 0 ∧ n 6= 1 ∧ (m = n − 1 ∨ m = n − 2)
Si noti che ciascun elemento non minimale ha due predecessori nella relazione di precedenza, il
cui diagramma può essere rappresentato come segue

1 0

Anche in questo caso il diagramma evidenzia la ben fondatezza di (N, ≺f ib ). 

Vediamo ora un esempio di funzione non totale.


Esempio 2.9. Sia f oo : N −→ N la funzione cosı̀ definita
(
0 se n = 0
f oo(n) =
1 + f oo(n + 1) altrimenti
La relazione di precedenza ≺f oo indotta è la seguente:
m ≺f oo n se e solo se n 6= 0 ∧ m = n + 1
Si noti che ciascun elemento non minimale ha due predecessori nella relazione di precedenza, il
cui diagramma può essere rappresentato come segue:

27
1 0

Il diagramma mostra chiaramente che ≺f oo non è ben fondato. 

Tutti gli esempi visti finora mostrano che, nel diagramma corrispondente alla relazione indotta
dalla definizione ricorsiva di una funzione f , le catene che si ottengono percorrendo (in tutti i
possibili modi) il diagramma medesimo dall’alto verso il basso a partire da un generico elemento
x del dominio, consentono di “visitare” tutti e soli gli elementi del dominio stesso su cui deve
essere calcolato (ricorsivamente) il valore della funzione f per ottenere il valore di f (x). Di qui
la necessità che la relazione indotta sia ben fondata affinchè il calcolo abbia termine.
Esempio 2.10. Consideriamo la funzione pari dell’esempio 2.5 e calcoliamo il valore della
funzione sull’elemento 6.
pari(6)
= { definizione di pari, terzo caso }
pari(4)
= { definizione di pari, terzo caso }
pari(2)
= { definizione di pari, terzo caso }
pari(0)
= { definizione di pari, primo caso }
0
Gli elementi utilizzati nel calcolo sono proprio quelli che si incontrano percorrendo il diagramma
dell’esempio 2.7 dall’alto verso il basso a partire da 6.
Come ulteriore esempio, consideriamo il calcolo di f ib(4) utilizzando la definizione dell’esempio
2.8.
f ib(4)
= { definizione di f ib, terzo caso }
f ib(3) + f ib(2)
= { definizione di f ib, terzo caso (2 volte) }
f ib(2) + f ib(1) + f ib(1) + f ib(0)
= { definizione di f ib, tutti i casi }
f ib(1) + f ib(0) + 1 + 1
= { definizione di f ib, primo e secondo caso }
1+1+1+1
= { calcolo }
4
Di nuovo, gli elementi 1, 2, 3, 4 sono tutti e soli quelli che si incontrano percorrendo il diagramma
dell’esempio 2.8 dall’alto verso il basso a partire da 4.

28
Vediamo infine cosa accade nel caso della funzione f oo dell’esempio 2.9 in corrispondenza del
calcolo di f oo(3).
f oo(3)
= { definizione di f oo, secondo caso }
1 + f oo(4)
= { definizione di f oo, terzo caso }
1 + 1 + f oo(5)
= { definizione di f oo, terzo caso }
1 + 1 + 1 + f oo(6)
= { definizione di f oo, terzo caso }
...
Anche in questo esempio gli elementi che si utilizzano nel calcolo sono quelli che si incontrano
percorrendo il diagramma a partire dall’elemento 3, ovvero percorrendo una catena descrescente
infinita: il calcolo non produce alcun valore e procede all’infinito. 

Abbiamo appena visto un esempio di funzione non totale, il cui calcolo non termina mai in
corrispondenza di alcuni elementi del suo dominio e abbiamo osservato come ciò sia strettamente
correlato al fatto che la relazione di precedenza indotta dalla definizione ricorsiva non sia ben
fondata. È evidente che un buon programmatore dovrebbe evitare di definire funzioni di questo
tipo proprio perché, in alcuni casi, non producono alcun risultato.
Il fatto che la relazione indotta da una definizione di funzione sia ben fondata non ci dà purtroppo
la certezza che la funzione sia totale. Il calcolo della funzione, infatti, può ridursi ad operazioni
su argomenti per le quali le stesse non sono definite.
Esempio 2.11. Sia g : N −→ N la seguente funzione
(
10 se n = 0
g(n) =
g(n − 1) + 5 mod (n − 1) altrimenti

La relazione di precedenza ≺g è chiaramente ben fondata. Calcoliamo g(2).


g(2)
= { definizione di g, secondo caso }
g(1) + 5 mod 1
= { definizione di g, secondo caso }
g(0) + 5 mod 0 + 5 mod 1
= { definizione di g, primo caso }
10 + 5 mod 0 + 5 mod 1
= { calcolo, poiché 5 mod 1 = 0 }
10 + 5 mod 0
= { 5 mod 0 indefinito }
??
Il calcolo non può terminare correttamente dal momento che 5 mod 0 richiede una divisione per
0 che, come ben sappiamo, non è definita. Abbiamo in questo caso una situazione di errore. 

Rappresentiamo con il simbolo ⊥ una situazione di errore come quella dell’ultimo esempio.
Più precisamente, data una funzione f : A −→ B, indichiamo con B⊥ l’insieme B ∪ {⊥} ovvero

29
l’insieme ottenuto da B aggiungendo il valore “speciale” ⊥. L’idea è di considerare la definizione
di f dal dominio A al codominio B⊥ cosı̀ da fare in modo che, in casi come quelli dell’esempio
precedente, la funzione calcoli comunque un valore che è appunto ⊥ nelle situazioni di errore.
Con questa estensione, l’ultimo passo di calcolo dell’esempio diventa dunque

10 + 5 mod 0
= { 5 mod 0 indefinito }

Bisogna fare ben attenzione a non confondere la situazione in cui il calcolo termina ma in una
situazione di errore (il valore “calcolato” è ⊥) come nel caso della funzione g dell’esempio 2.12,
dalla situazione in cui il calcolo non termina come nel caso della funzione f oo dell’esempio 2.10.
Dagli esempi visti e dalle considerazioni fatte, possiamo stabilire la seguenti proprietà.

Proprietà Sia f : A −→ B una funzione definita in modo ricorsivo e sia ≺f la relazione di


precedenza indotta dalla definizione di f .

se ≺f è ben fondato allora la funzione f : A −→ B⊥ è totale

30

Potrebbero piacerti anche