You are on page 1of 333

Universit degli Studi di Firenze

Scuola di Scienze Matematiche Fisiche e Naturali


Corso di Laurea Magistrale in Informatica

Note per il corso di


MODELLI DI SISTEMI SEQUENZIALI E CONCORRENTI
17 dicembre 2013

Rocco De Nicola Rosario Pugliese

Anno Accademico 20132014

Indice

1 Introduzione
1.1
Il problema della correttezza dei sistemi informatici . . .
1.2
Approcci alla semantica dei linguaggi di programmazione
1.3
Sistemi concorrenti . . . . . . . . . . . . . . . . . . . . .
1.4
Calcoli di processo . . . . . . . . . . . . . . . . . . . . . .
1.5
Schema delle note . . . . . . . . . . . . . . . . . . . . . .

. . . . . . .
sequenziali
. . . . . . .
. . . . . . .
. . . . . . .

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

Preliminari Matematici

2 Nozioni preliminari
2.1
Insiemi . . . . . . . . . . . . . . .
2.2
Relazioni e funzioni . . . . . . . .
2.3
Principi di induzione . . . . . . .
2.3.1 Induzione matematica . .
2.3.2 Induzione strutturale . . .
2.4
Sistemi di inferenza . . . . . . . .
2.4.1 Induzione sulle derivazioni
2.4.2 Induzione sulle regole . . .
2.5
Contesti e congruenze . . . . . . .
2.6
Esercizi . . . . . . . . . . . . . . .

7
7
8
11
14
18

21
.
.
.
.
.
.
.
.
.
.

23
23
25
29
29
32
35
37
38
39
41

.
.
.
.
.
.
.

43
43
50
52
54
57
60
62

4 Sintassi e denotazioni
4.1
Notazioni sintattiche e denotazioni semantiche . . . . . . . . . . . . . . . . .
4.2
Una calcolatrice tascabile . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

65
65
68

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

3 Sintassi e modelli semantici


3.1
Grammatiche . . . . . . . . . . . . . . . . . . . . . .
3.2
Sintassi concreta e sintassi astratta . . . . . . . . . .
3.3
Espressioni aritmetiche . . . . . . . . . . . . . . . . .
3.4
Automi . . . . . . . . . . . . . . . . . . . . . . . . . .
3.5
Sistemi di transizioni etichettate e strutture di Kripke
3.6
Semantica operazionale delle espressioni aritmetiche .
3.7
Esercizi . . . . . . . . . . . . . . . . . . . . . . . . . .

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

Indice
4.3
4.4
4.5

4.6

II
5

Il linguaggio della calcolatrice tascabile . . . . . . .


Semantica denotazionale della calcolatrice tascabile
Espressioni regolari . . . . . . . . . . . . . . . . . .
4.5.1 Semantica denotazionale . . . . . . . . . . .
4.5.2 Semantica operazionale . . . . . . . . . . . .
4.5.3 Semantica assiomatica . . . . . . . . . . . .
Esercizi . . . . . . . . . . . . . . . . . . . . . . . . .

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

Sistemi Sequenziali
-calculus
5.1
La -convenzioni semplificative .
5.2
Il principio di estensionalit . .
5.3
Operatori di n-upla . . . . . . .
5.4
Operatori di composizione . . .
5.5
Il sistema di calcolo . . . . . . .
5.5.1 Sintassi del -calculus . .
5.5.2 Semantica del -calculus
5.6
Esercizi . . . . . . . . . . . . . .

70
73
77
77
79
85
88

89
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

91
92
95
96
98
99
99
101
106

6 Domini per la semantica denotazionale


6.1
Esempi duso dei domini nella semantica denotazionale . . . . . .
6.2
Insiemi parzialmente ordinati completi . . . . . . . . . . . . . . .
6.3
Funzioni continue e minimo punto fisso . . . . . . . . . . . . . . .
6.4
Costruzioni di domini . . . . . . . . . . . . . . . . . . . . . . . . .
6.4.1 Domini elementari . . . . . . . . . . . . . . . . . . . . . . .
6.4.2 Prodotti finiti . . . . . . . . . . . . . . . . . . . . . . . . .
6.4.3 Somma disgiunta . . . . . . . . . . . . . . . . . . . . . . .
6.4.4 Spazio delle funzioni . . . . . . . . . . . . . . . . . . . . .
6.5
Un metalinguaggio per la definizione di funzioni di interpretazione
6.5.1 Una classe di domini . . . . . . . . . . . . . . . . . . . . .
6.5.2 Il metalinguaggio . . . . . . . . . . . . . . . . . . . . . . .
6.6
Esempi di funzioni sul dominio dei naturali . . . . . . . . . . . . .
6.7
Sistemi di equazioni mutuamente ricorsive . . . . . . . . . . . . .
6.8
Esercizi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.

109
110
113
117
122
122
123
127
128
132
133
135
139
143
145

.
.
.
.
.

147
147
148
152
156
161

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

7 Un semplice linguaggio funzionale


7.1
Sintassi di un semplice linguaggio funzionale . . . . .
7.2
Semantica operazionale . . . . . . . . . . . . . . . . .
7.3
Semantica denotazionale . . . . . . . . . . . . . . . .
7.4
Relazioni tra semantica operazionale e denotazionale
7.5
Esercizi . . . . . . . . . . . . . . . . . . . . . . . . . .

.
.
.
.
.
.
.
.

.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

8 Un semplice linguaggio imperativo


163
8.1
Il linguaggio TINY . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 163
8.2
Semantica operazionale di TINY . . . . . . . . . . . . . . . . . . . . . . . . . 164

Indice
8.3
8.4
8.5
8.6
8.7

Semantica denotazionale di TINY


Semantica delle espressioni . . . .
Semantica dei comandi . . . . . .
Equivalenza fra le semantiche . .
Esercizi . . . . . . . . . . . . . . .

9 Linguaggi con contesti


9.1
Il linguaggio SMALL . . . . . .
9.2
Ambienti e locazioni . . . . . .
9.3
Domini semantici per SMALL
9.4
Semantica di SMALL . . . . .
9.5
Semantica dei programmi . . .
9.6
Semantica delle dichiarazioni .
9.7
Semantica delle espressioni . .
9.8
Semantica dei comandi . . . .
9.9
Considerazioni conclusive . . .
9.10 Esercizi . . . . . . . . . . . . .

III

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

167
170
173
175
179

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

181
181
182
184
187
190
190
191
193
194
196

Sistemi Concorrenti

10 Operatori per concorrenza e nondeterminismo


10.1 Azioni esterne ed interne . . . . . . . . . . . .
10.2 Operatori sui processi . . . . . . . . . . . . . .
10.3 Processi di base . . . . . . . . . . . . . . . . .
10.4 Operatori di sequenzializzazione . . . . . . . .
10.5 Operatori di scelta . . . . . . . . . . . . . . .
10.6 Operatori di parallelismo . . . . . . . . . . . .
10.7 Operatori di astrazione . . . . . . . . . . . . .
10.8 Operatori per definire comportamenti infiniti .
10.9 Sincronia ed asincronia . . . . . . . . . . . . .
10.10 Operatori che manipolano valori . . . . . . . .
10.11 Esercizi . . . . . . . . . . . . . . . . . . . . . .

197
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

199
199
200
201
202
204
206
210
213
217
219
222

11 Equivalenze comportamentali e preordini di ranamento


11.1 Osservatori, equivalenze e preordini . . . . . . . . . . . . .
11.2 Relazioni forti . . . . . . . . . . . . . . . . . . . . . . . . .
11.2.1 Equivalenza basata sulle tracce . . . . . . . . . . .
11.2.2 Bisimilarit forte . . . . . . . . . . . . . . . . . . .
11.2.3 Equivalenze basate su testing . . . . . . . . . . . .
11.2.4 Preordini di ranamento . . . . . . . . . . . . . . .
11.2.5 Altre equivalenze forti . . . . . . . . . . . . . . . .
11.3 Relazioni deboli . . . . . . . . . . . . . . . . . . . . . . . .
11.3.1 Equivalenza basata sulle tracce deboli . . . . . . . .
11.3.2 Bisimulazione debole . . . . . . . . . . . . . . . . .
11.3.3 Bisimulazione di branching . . . . . . . . . . . . . .
11.3.4 Relazioni basate su testing . . . . . . . . . . . . . .

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

225
225
227
227
230
235
237
239
240
241
242
246
248

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

Indice

11.4
11.5
11.6

11.3.5 Relazioni basate sui fallimenti


Trattamento della divergenza . . . . .
Gerarchie tra le relazioni . . . . . . .
Esercizi . . . . . . . . . . . . . . . . .

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

12 Calculus of Communicating Systems (CCS)


12.1 Sintassi di CCS . . . . . . . . . . . . . . . . .
12.2 Semantica operazionale di CCS . . . . . . . .
12.3 CCS con passaggio di valori . . . . . . . . . .
12.4 Equivalenze e preordini osservazionali per CCS
12.4.1 Bisimulazioni e bisimilarit forte . . . .
12.4.2 Bisimulazioni, bisimilarit e congruenza
12.4.3 Equivalenze basate su testing . . . . .
12.5 Ragionamento equazionale in CCS . . . . . . .
12.5.1 Assiomatizzazione di . . . . . . . . .
12.5.2 Assiomatizzazione di
= . . . . . . . . .
12.5.3 Assiomatizzazione di vctest , vcM e vm .
12.6 Esercizi . . . . . . . . . . . . . . . . . . . . . .

.
.
.
.

.
.
.
.

.
.
.
.

. . . .
. . . .
. . . .
. . . .
. . . .
debole
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .

13 Logiche per i sistemi concorrenti


13.1 Logiche e propriet di sistemi . . . . . . . . . . . .
13.2 Logiche proposizionali, loro interpretazioni e modelli
13.3 Logiche modali proposizionali . . . . . . . . . . . .
13.4 La logica HML . . . . . . . . . . . . . . . . . . . . .
13.5 Logiche temporali . . . . . . . . . . . . . . . . . . .
13.6 La logica ACTL . . . . . . . . . . . . . . . . . . . .
13.7 Propriet infinitarie: HML con ricorsione . . . . . .
13.8 Il -calculus modale . . . . . . . . . . . . . . . . . .
Bibliografia

.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.

254
256
257
259

.
.
.
.
.
.
.
.
.
.
.
.

261
261
265
268
270
270
274
280
281
282
292
298
300

.
.
.
.
.
.
.
.

301
301
303
305
306
311
315
318
321
325

A Tabelle
329
A.1 Elenco degli operatori per la concorrenza . . . . . . . . . . . . . . . . . . . . 329
A.2 Alcuni calcoli di processi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 332

Capitolo 1

Introduzione

SOMMARIO
Questo capitolo introduttivo presenta le problematiche principali legate alla verifica della
correttezza dei sistemi informatici e di quelli concorrenti in particolare.

1.1

Il problema della correttezza dei sistemi informatici

Il problema della correttezza dei sistemi informatici, siano essi composti da componenti software e/o hardware, cio il problema di accertare se un sistema informatico si comporta effettivamente in accordo alle sue specifiche, uno dei problemi cruciali dellInformatica e sta
acquistando unimportanza sempre maggiore. Infatti, i sistemi informatici sono vitali per
la societ moderna dal momento che, ad esempio, gestiscono gli aspetti finanziari, regolano
le comunicazioni e la produzione di energia, controllano il traco aereo e i processi industriali, anche quelli critici da un punto di vista della sicurezza, ed elaborano informazioni
critiche. Inoltre, computer e microprocessori sono ormai usati per controllare ogni sorta di
dispositivo duso giornaliero, dai tablet ai telefonini, dalle automobili agli elettrodomestici.
In pratica si sta realizzando un nuovo modello di interazione persona-computer, denominato
ubiquitous computing (o anche pervasive computing), in cui lelaborazione dellinformazione
completamente integrata in tutti gli oggetti, le attivit e gli aspetti della vita quotidiana.
Tuttavia, malgrado la sua importanza sia da un punto di vista scientifico che pratico, il
problema di garantire la correttezza dei sistemi informatici non sempre riceve lattenzione che
merita. Spesso si privilegia lesigenza di mantenere bassi i costi di sviluppo. Di conseguenza
abbiamo che i sistemi informatici si guastano con una certa frequenza e talvolta tali guasti
hanno ripercussioni molto serie sia da un punto di vista economico che da quello della sicurezza
per la vita delluomo. Due esempi tra tutti sono il bug che ha aitto il processore Pentium-II
della Intel (1994), nel quale secondo una stima della rivista Byte lunit che si occupava della
divisione in virgola mobile generava un errore ogni nove miliardi di operazioni, e lesplosione
del vettore spaziale Ariane-5 (1996), la cui costruzione costata 7 miliardi di dollari allAgenzia
Spaziale Europea, causata da un overflow nella conversione di alcuni dati da rappresentazione
in virgola mobile in interi con segno a 16-bit. Tant che solo qualche anno fa il premio Turing
Tony Hoare scriveva:
programming is the only engineering profession that spends half its time and eort
on detecting and correcting mistakes made in the other half of its time [BHH+ 06].

Capitolo 1 Introduzione

Negli ultimi anni per, i metodi formali per la descrizione, la costruzione, lanalisi e la
verifica dei moderni sistemi informatici, basati soprattutto sulla logica ed altri strumenti matematici, sono diventati pi maturi. Secondo la definizione data da R. W. Butler
(Wikipedia),
in computer science, specifically software engineering and hardware engineering,
formal methods are a particular kind of mathematically-based techniques for the
specification, development and verification of software and hardware systems.
Tali metodi possono fornire un supporto fondamentale alla validazione dei sistemi informatici
fin dalle prime fasi del loro sviluppo. Sono praticamente indispensabili soprattutto nellambito
della verifica di sistemi critici da un punto di vista della sicurezza o da quello del costo. Sono
sempre pi usati in pratica e c da aspettarsi che in un prossimo futuro essi complementino,
ed in parte rimpiazzino, i metodi tradizionali dellingegneria del software.
Lo scopo principale di queste note quello di introdurre alcuni dei metodi formali utilizzati
per la verifica della correttezza dei programmi, sia sequenziali che concorrenti.
La prima parte di queste note dedicata alla introduzione di alcune nozioni preliminari
necessarie per la comprensione e lo sviluppo dei metodi formali che saranno introdotti nelle
due parti successive. Pi precisamente, tali nozioni riguardano matematica discreta e tecniche
di prova (Capitolo 2), grammatiche, sintassi, automi a stati finiti e sistemi di transizioni
etichettate (Capitolo 3), denotazioni e funzioni di interpretazione semantica (Capitolo 4).

1.2

Approcci alla semantica dei linguaggi di programmazione


sequenziali

Nel caso dei linguaggi di programmazione sequenziali introdurremo alcune tecniche ormai
ben consolidate per la definizione precisa e non ambigua della loro semantica. Diversamente
dal linguaggio naturale, che evolve nel tempo e risulta ricco di ambiguit, un linguaggio di
programmazione deve avere una definizione precisa e non ambigua, essendo progettato per
istruire una macchina priva di capacit di apprendimento e discernimento. Daltra parte
un linguaggio di programmazione ha in comune col linguaggio naturale alcune importanti
caratteristiche. Ogni linguaggio ha una sua sintassi ed una sua semantica: la sintassi definisce
la struttura delle frasi del linguaggio, la semantica attribuisce un significato a tali frasi.
La teoria riguardante le tecniche per specificare la sintassi stata sviluppata a lungo ed
ha portato a risultati chiari e importanti. I requisiti matematici di supporto alla specifica
sintattica (espressioni regolari, grammatiche libere dal contesto, ecc.) sono ormai ben noti ed
ampiamente applicati.
Per attribuire un significato a una frase di un linguaggio di programmazione bisogna
specificare il comportamento, in esecuzione, del programma che la frase rappresenta. Lo
sviluppo di metodologie per specificare precisamente (ossia, formalmente) il comportamento
di programmi in esecuzione risultato storicamente complesso. per questo che inizialmente
la semantica di un linguaggio di programmazione veniva data attraverso descrizioni informali,
in linguaggio naturale, dei vari costrutti. Tuttavia un tale approccio aveva gravi difetti. In
primo luogo il linguaggio naturale ambiguo, per cui capitava che implementazioni diverse
dello stesso linguaggio mostrassero comportamenti diversi. In secondo luogo le descrizioni
informali non potevano essere trattate formalmente con strumenti matematici per dimostrare

1.2 Approcci alla semantica dei linguaggi di programmazione sequenziali

propriet del linguaggio in questione o per dimostrare propriet di programmi scritti con tale
linguaggio.
per questo motivo che sono stati sviluppati strumenti teorici atti a dare definizioni
matematiche degli aspetti dinamici dei linguaggi di programmazione.
Descriviamo ora i tre approcci principali che si possono adottare per attribuire una semantica esatta ad un linguaggio di programmazione. Tali approcci vanno sotto il nome di
semantica denotazionale, semantica operazionale e semantica assiomatica (o algebrica).
Semantica denotazionale
Le idee alla base dellapproccio denotazionale alla semantica dei linguaggi di programmazione
sono due: definire delle funzioni che associano ad ogni frase del linguaggio un appropriato
oggetto matematico, che costituisce la semantica del frammento di programma rappresentato
dalla frase, e realizzare tale associazione in modo composizionale, ossia in modo che loggetto associato ad un costrutto del linguaggio sia costruito a partire dagli oggetti associati alle
componenti del costrutto stesso. Le funzioni suddette sono dette funzioni di interpretazione
semantica, i loro codomini sono detti domini semantici, e gli elementi di questi ultimi sono detti denotazioni. Le denotazioni sono oggetti matematici (insiemi, funzioni, ecc.) che
permettono di ragionare formalmente sui programmi. Ad esempio, le denotazioni possono
essere utilizzate per dimostrare la correttezza di un programma rispetto a determinate specifiche, per dimostrare la correttezza di determinate trasformazioni da un programma ad un
altro, e per dimostrare lequivalenza semantica di programmi diversi.
Generalmente una semantica denotazionale cerca di catturare il significato intrinseco dei
termini del linguaggio piuttosto che definire una strategia di valutazione dei termini stessi.
Il significato di un termine , secondo questo approccio, loggetto matematico ad esso associato (ossia loggetto matematico che esso implicitamente denota); per cui due termini sono
equivalenti se ad essi associato lo stesso oggetto matematico.
Questo approccio adatto a trasformare le questioni riguardanti i programmi in problemi
matematici. Come vedremo, nellambito dei linguaggi per la descrizione di sistemi concorrenti
questo approccio risulta poco utilizzabile perch esso tende a interpretare un programma come
una funzione che produce un valore e quindi, dicilmente, cattura il concetto di interazione
tra programmi.
Semantica operazionale
Lapproccio operazionale mette laccento su come i vari costrutti di un linguaggio possono
essere eseguiti da unipotetica macchina astratta. Il significato dei costrutti viene spiegato in
termini di passi elementari della macchina. Tipicamente, come modello per le macchine astratte, vengono usati gli automi a stati finiti o i sistemi di transizioni etichettate. Un passo di una
tale macchina consiste nel passaggio da uno stato allaltro del sistema tramite una transizione.
Una semantica operazionale pu quindi essere vista come una formalizzazione matematica di
una strategia di implementazione del linguaggio. In tal senso la semantica operazionale non
definisce completamente il significato dei termini ma ne descrive solo lesecuzione per mezzo
di computazioni.
Per definire completamente il significato dei termini possibile, come vedremo ampiamente nei prossimi capitoli, eettuare un processo di astrazione e definire una semantica
osservazionale che identifichi due termini se nessun osservatore esterno, interagendo con le

10

Capitolo 1 Introduzione

macchine associate a tali termini, pu distinguere il comportamento operazionale delle due


macchine.
Semantica assiomatica (o algebrica)
Lapproccio della semantica assiomatica (o algebrica) consiste nel definire un insieme di regole
(ossia un sistema di inferenza) che permette di dedurre quando due termini sono equivalenti.
Due termini avranno quindi lo stesso significato e saranno considerati interscambiabili se
usando il sistema di inferenza possibile dimostrare la loro equivalenza.
Lambito in cui la semantica assiomatica assume un ruolo pi rilevante quello della
verifica di propriet di programmi, infatti per mezzo della semantica assiomatica le questioni
riguardanti i programmi possono essere ricondotte a problemi di una qualche logica.
Osserviamo come, indipendentemente dallapproccio, dietro ad ogni possibile definizione
di una semantica, ci sia un concetto di equivalenza:
la semantica denotazionale identifica i programmi che denotano uno stesso oggetto
matematico,
la semantica operazionale identifica i programmi le cui macchine astratte associate danno
luogo alle stesse computazioni,
la semantica osservazionale identifica i programmi che risultano indistinguibili ad ogni
osservatore che interagisca con le corrispettive macchine astratte,
la semantica assiomatica identifica i programmi che il sistema di inferenza pu provare
essere equivalenti.
In altre parole non sempre si riesce a dire fino in fondo qual il significato dei programmi
ma si riesce comunque a stabilire quando due programmi hanno lo stesso significato. Facendo
un salto di astrazione si potrebbe dire che il significato di un programma la classe di tutti
i programmi ad esso equivalenti secondo una certa relazione di equivalenza1 . La relazione di
equivalenza risulter tanto pi plausibile quanto pi essa sar in qualche modo in accordo con
i costrutti del linguaggio e con il significato intuitivo ad essi associato.
La seconda parte di queste note dedicata alla semantica operazionale e denotazionale di
linguaggi sequenziali. A tale scopo, prima introdurremo la -notazione, nel Capitolo 5, e i
concetti di base della teoria dei domini, nel Capitolo 6. Quindi, nel Capitolo 8 presenteremo
la semantica denotazionale di TINY, un semplice linguaggio imperativo, e poi una semantica
operazionale equivalente. Infine, nel Capitolo 9 definiremo una semantica denotazionale per
SMALL, una estensione di TINY che prevede la dichiarazione esplicita di variabili e costanti
usate allinterno di un programma, la strutturazione in blocchi dei programmi stessi, e la
dichiarazione e luso di funzioni e procedure.
1

un po come se uno dicesse che il colore rosso in realt linsieme di tutti gli oggetti rossi. Questo
pu risultare strano ma se facciamo lo sforzo di pensare a quando abbiamo imparato le parole da bambini ci
accorgiamo che il processo simile: dopo che ci sono stati indicati molti oggetti dicendoci che erano rossi, la
nostra mente ha eettuato involontariamente unoperazione di quoziente, ossia si chiesta qual lunica cosa
in comune tra questi oggetti?. Il nome di questa cosa comune la parola rosso.

1.3 Sistemi concorrenti

1.3

11

Sistemi concorrenti

La nozione di sistema concorrente non esclusiva del mondo dei computer; una colonia di
formiche ed un aggregato di particelle elementari sono esempi di sistemi concorrenti nel campo
della biologia e della fisica. Da un punto di vista informatico, un sistema concorrente pu
astrattamente essere visto come un insieme di componenti autonome, hardware o software,
che possono interagire e comunicare.
Lutilizzo di sistemi concorrenti si molto ampliato negli ultimi decenni. Ci grazie al
fatto che la programmazione concorrente ore diversi vantaggi potenziali, quali, ad esempio,
performance (per via di un migliore sfruttamento del parallelismo oerto dallhardware), distribuzione (poich alcuni problemi richiedono soluzioni distribuite, si pensi ad esempio alle
applicazioni client-server ), facilit di programmazione (poich alcuni problemi hanno una soluzione naturale di tipo concorrente), risposte pi rapide, maggiore throughput, ed in generale
migliore strutturazione dei sistemi che interagiscono con lambiente, controllano varie attivit
e gestiscono eventi multipli (per il fatto di essere organizzati in pi thread di controllo).
La concorrenza, tradizionalmente ingrediente essenziale di componenti software quali sistemi operativi, basi di dati e sistemi di comunicazione, ha assunto un ruolo sempre pi rilevante
anche nellarea delle applicazioni. Per trarre vantaggio, anche a livello di programmazione,
del maggiore parallelismo disponibile, molti linguaggi di programmazione di pi recente concezione (per esempio, OCCAM, CML, Facile, Obliq, Telescript, Pict, Java, Aglets, Odissey)
sono stati dotati di primitive per la descrizione ed il controllo dellinterazione tra le varie
componenti.
Data la loro naturale capacit di modellizzare la realt, i sistemi concorrenti sono usati,
per esempio, per gestire processi industriali, per il controllo del traco aereo o per il controllo
di robot.
Naturalmente, cos come la programmazione sequenziale, anche la programmazione concorrente soggetta ad errori. Due esempi tra tutti sono il Therac-25, una macchina per
radioterapia controllata da un calcolatore che negli anni tra il 1985 ed il 1987 ha subito perlomeno sei incidenti che hanno causato gravi danni e persino la morte di alcuni pazienti (la
commissione di indagine ha concluso che il progetto del software era tale che fosse realisticamente impossibile testarlo in maniera chiara ed automatica), ed il rover Mars Pathfinder
(1997), in cui un problema ben noto in programmazione concorrente col nome di inversione
della priorit tra task concorrenti ha causato un continuo riavvio del computer di bordo,
riducendo cos la disponibilit per lesplorazione e la capacit della batteria, cosa che ha poi
impedito definitivamente la comunicazione dei dati raccolti alla base terrestre. Inoltre, a
tutti noi sar capitato di dover riavviare il calcolatore a causa del verificarsi di una qualche
situazione anomala che impediva di poter continuare ad usarlo!
Quindi, eventuali errori nelle applicazioni del tipo summenzionato possono avere importanti ripercussioni per la vita delluomo. Ne deriva che lo studio formale e la comprensione del comportamento dei sistemi concorrenti ha assunto unestrema importanza, cos come
agli albori dellinformatica si rese necessario comprendere il comportamento dei programmi
sequenziali. Come spesso accade lesigenza di una teoria nasce dalla pratica.
Lo studio di tecniche per la descrizione e lanalisi dei sistemi concorrenti emerso come
unarea della ricerca in informatica in risposta alle dicolt incontrate dai progettisti di
sistemi concorrenti. Uno dei principali fattori alla base di tali dicolt la presenza di pi
componenti, o thread di controllo, allinterno di uno stesso sistema che possono interagire in

12

Capitolo 1 Introduzione

maniera subdola ed imprevista. Mentre un programma sequenziale caratterizzato da un


singolo thread di controllo, un programma concorrente caratterizzato da pi thread che gli
permettono di eseguire varie attivit di calcolo in parallelo e di controllare simultaneamente
diverse attivit esterne. La complessit si origina dai modi in cui le diverse parti possono
interagire. Il progetto di tali sistemi richiede quindi delle tecniche che permettano di tenere
sotto controllo tali interazioni. La concorrenza, per la sua stessa natura, introduce fenomeni
che non sono presenti in programmazione sequenziale, quali il deadlock, dove un certo numero
di componenti sono ciascuna in attesa di una qualche interazione da qualche altra componente
prima di poter esse stesse continuare, ed il livelock, dove alcune componenti avviano una
sequenza infinita di interazioni tra loro escludendo di fatto altre componenti e lambiente
esterno. Tali fenomeni non si originano dalle singole componenti ma dal modo in cui esse
sono combinate insieme.
Anche il nondeterminismo si origina in maniera naturale dalla composizione parallela di
pi componenti, per esempio quando si hanno delle race condition. Una race condition un
comportamento anomalo causato da una dipendenza imprevista dal susseguirsi di eventi nel
tempo. Essa si verifica quando due o pi thread sono in grado di accedere dati condivisi
e tentano di modificarli simultaneamente, cio i thread gareggiano per accedere/modificare
i dati. Poich lalgoritmo di scheduling della CPU pu causare uno switch tra i thread in
qualsiasi momento della loro esecuzione, non possibile conoscere a priori lordine con cui i
thread accederanno eettivamente i dati condivisi. Perci, il risultato della modifica dei dati
dipendente dallalgoritmo di scheduling.
Illustriamo questo problema con un semplice esempio in cui due componenti, P e Q,
condividono una variabile intera x inizializzata con un certo valore v0 , ed eseguono ciascuno
il seguente frammento di codice:
x := 1;
x := x + 1;
Se P e Q vengono eseguiti sequenzialmente, fatto che denotiamo con P ; Q, allora possiamo
aermare con certezza che il valore di x dopo lesecuzione di P ; Q sar 2. Pi in dettaglio
abbiamo:
{x = v0 }
x := 1;
{x = 1}
x := x + 1;
{x = 2}
x := 1;
{x = 1}
x := x + 1;
{x = 2}

(P )
(P )
(Q)
(Q)

dove indichiamo tra {} le asserzioni sul valore assunto da x e tra () la componente che esegue
una data istruzione.
Supponiamo invece di eseguire P e Q simultaneamente, fatto che denotiamo come P |Q;
in questo caso c anche la possibilit che il valore finale di x sia 3, e non 2, infatti si potrebbe

13

1.3 Sistemi concorrenti


avere, per esempio, la computazione seguente:
{x = v0 }
x := 1;
{x = 1}
x := 1;
{x = 1}
x := x + 1;
{x = 2}
x := x + 1;
{x = 3}

(P )
(Q)
(P )
(Q)

Riassumendo, abbiamo che:


{x = v0 }
P;Q
{x = 2}

{x = v0 }
P |Q
{x = 2 _ x = 3}

Possiamo quindi concludere che il comportamento di P ; Q deterministico, mentre quello


di P |Q non deterministico e quindi non predicibile staticamente. In eetti, non dicile
convincersi che la pi stringente asserzione che possibile fare sul valore di x alla fine dellesecuzione di P |Q proprio x = 2 _ x = 3 infatti, ogni possibile interleaving delle istruzioni di
P e di Q porta a uno di questi due valori.
Il comportamento complessivo di un sistema concorrente quindi il risultato delle interazioni, non sempre prevedibili, delle sue componenti individuali. Lordine con cui le azioni delle
singole componenti sono eseguite dipende da vari fattori, come le interazioni con lambiente
esterno o lo scheduling dei processi nella CPU. Tutto ci fa si che un sistema concorrente
abbia un certo numero (spesso elevato) di computazioni possibili e che il suo comportamento
sia non deterministico. Risulta perci dicile capire staticamente quale sar levoluzione di
un tale sistema.
Unaltra delle complicazioni insite nella programmazione concorrente il fatto che molti
sistemi concorrenti, quali ad esempio i sistemi operativi, i data base, i sistemi di controllo
di impianti, sono sistemi che non lavorano isolatamente ma che, durante lo svolgimento dei
propri compiti, interagiscono con altri sistemi e reagiscono alle loro richieste. Per questo
motivo, tali sistemi sono stati anche chiamati sistemi reattivi [HP85]. Per i sistemi reattivi,
laspetto importante la capacit di interagire e di rispondere agli stimoli dellambiente esterno
mentre, dierentemente dai classici programmi sequenziali, non risulta essere in alcun modo
importante il risultato finale da essi prodotto al punto che, in molti casi, essi sono progettati
per eettuare una serie infinita di interazioni con lambiente senza raggiungere uno stato
terminale.
Il nondeterminismo (necessario nella descrizione di molti sistemi concorrenti per evitare
assunzioni restrittive sullambiente di esecuzione) e la necessit di modellare la natura reattiva di molti sistemi, hanno impedito che gli approcci formali sviluppati per la descrizione
e lanalisi di sistemi sequenziali potessero essere utilizzati anche per i sistemi concorrenti.
Approcci basati sulla descrizione delle funzioni che modellano le corrispondenze tra input
ed output, sulla semantica denotazionale con continuazioni o sulla semantica assiomatica con
pre e post-condizioni non risultano adeguati per garantire la composizionalit, per modellare

14

Capitolo 1 Introduzione

linterattivit e per tener conto del fatto che non sempre i sistemi concorrenti sono progettati
per raggiungere uno stato terminale o perch il risultato eventualmente prodotto sia unico.
Sistemi concorrenti, anche piccoli, possono essere dicili da analizzare. Perci abbiamo
bisogno di rispondere ad alcune domande:
1. Come possiamo sviluppare/progettare un sistema che funzioni correttamente?
2. Come possiamo analizzare/verificare tale sistema?
Nel campo dellinformatica teorica, si quindi presentata la necessit di estendere la teoria,
valida per i processi sequenziali algoritmici, a sistemi dove la concorrenza e linterazione
giocano un ruolo essenziale ed a volte predominante. necessaria a tale scopo una teoria
della concorrenza che comprenda:
1. modelli matematici per la descrizione e lanalisi formale di sistemi concorrenti;
2. linguaggi formali per la specifica del possibile comportamento dei sistemi;
3. strumenti di verifica (semi-)automatici e relative tecniche di implementazione.
Lambizione degli studiosi quella di fare per i sistemi concorrenti quello che agli albori
della scienza dei calcolatori stato fatto per spiegare il comportamento dei programmi sequenziali ed algoritmici. Allora furono sviluppati modelli computazionali basati sulle attivit
elementari di leggere e scrivere in memoria (macchine di Turing) e sulla possibilit di definire ed invocare funzioni ( -calcolo). Nel caso dei sistemi e dei programmi concorrenti, lo
scopo quindi quello di sviluppare un modello con un piccolo numero di concetti di base, in
termini dei quali sia possibile spiegare il comportamento interattivo e concorrente di diverse
componenti.
Uno dei primi modelli, sviluppato negli anni 60, sono le reti di Petri, che generalizzano la
teoria degli automi e permettono la descrizione delloccorrenza contemporanea di pi azioni
(transizioni tra stati). Nel modello delle reti di Petri, particolare attenzione riservata alle
nozioni di conflitto, indipendenza e dipendenza causale tra azioni.
per negli ultimi tre decenni che la teoria della concorrenza ha avuto il massimo sviluppo,
soprattutto grazie allapproccio basato sui calcoli di processo (o algebre di processo). Un
calcolo di processi costituito da una notazione per descrivere sistemi concorrenti e da un
insieme di strumenti matematici (algebrici o logici) che aiutano a studiare le propriet dei
sistemi descritti con tale notazione. Un sistema concorrente rappresentato in termini di
processi e la sua evoluzione consiste quindi nella trasformazione di un processo in un altro
tramite lesecuzione di unazione. Tale visione, dovuta a Tony Hoare e Robin Milner (1980),
pu essere riassunta nel motto qualsiasi cosa (o pu esser vista come) un processo. Tutte
le componenti di un sistema, sia attive che passive, quali ad esempio canali di comunicazione,
buer di memoria, memoria condivisa, spazi di tuple, mittenti, destinatari, client, server,
sono processi.

1.4

Calcoli di processo

Tra i vari modelli e metodi proposti per descrivere ed analizzare sistemi concorrenti, uno di
quelli che ha riscosso pi successo lapproccio basato sui calcoli di processo.

1.4 Calcoli di processo

15

Le idee alla base dei calcoli di processo sono due. Da un lato il principio secondo il quale
la comunicazione tra due processi debba essere di tipo handshake (stretta di mano), ossia
debba avvenire grazie ad azioni simultanee eseguite dai processi che comunicano attraverso
un canale (interfaccia). Dallaltro lidea che il linguaggio associato ad un calcolo di processi
debba basarsi su un numero ristretto di operatori corrispondenti ciascuno ad una qualche idea
intuitiva di composizione tra processi (quale, ad esempio, composizione sequenziale, composizione nondeterministica, composizione parallela) e sucienti nel loro insieme a raggiungere
un potere espressivo completamente generale.
Alcuni autori parlano di algebre di processo piuttosto che di calcoli, per alludere agli
strumenti dellalgebra che sono utilizzati da questi formalismi; noi preferiamo per chiamarli
calcoli perch molti di tali formalismi, oltre allalgebra, utilizzano strumenti di altre branche
della matematica (come, ad esempio, della logica). Un altro nome utilizzato in letteratura
linguaggi di descrizione di processi, ma anche questo riduttivo per le motivazioni che
abbiamo appena illustrato.
Il lavoro di Robin Milner sul Calculus of Communicating Processes (CCS, [Mil80, Mil89]
generalmente riconosciuto come liniziatore e il punto di riferimento di questa area. Ispirato
dal -calcolo, ma anche dal linguaggio CSP (un semplice linguaggio di programmazione concorrente basato sullo scambio esplicito di messaggi, [Hoa78]), CCS basato su un linguaggio
per la descrizione di processi con pochi costrutti primitivi ciascuno dei quali riflette semplici
idee operazionali: interazione sincrona tra processi concorrenti tramite canali di comunicazione, composizione sequenziale, parallela e non-deterministica, astrazione e ridenominazione
di canali, processi ricorsivi. I costrutti scelti sono quindi notevolmente diversi da quelli del
-calcolo. Ci dovuto ai dierenti obiettivi dei due calcoli: mentre il -calcolo studia le
funzioni ed il loro comportamento applicativo, quindi descrive essenzialmente computazioni
sequenziali, il CCS rivolto alle computazioni concorrenti, per cui interazione e parallelismo
sono le idee fondamentali.
Parallelamente al CCS, sono stati sviluppati altri calcoli di processo che condividono le
motivazioni del CCS; tra questi CSP [BHR84], ACP [BK84a, BK84b], Meije [AB84] e (ISOStandard) LOTOS [BB87].
Un calcolo di processi generalmente costituito da una sintassi per la descrizione formale
dei sistemi concorrenti, una semantica e un insieme di strumenti (tipicamente costituiti da
equivalenze e logiche) utili per studiare e dimostrare propriet dei sistemi descritti con la
notazione oerta dal calcolo.
A livello linguistico, vengono messi a disposizione un certo numero di costrutti che mirano
a cogliere il concetto di interazione tra processi concorrenti, il concetto di composizione
modulare dei processi per mezzo di operatori di composizione sequenziale, parallela o nondeterministica ed il concetto di astrazione per descrivere i sistemi a livelli di dettaglio dierenti.
Una novit rispetto ai modelli di calcolo sequenziali lintroduzione di operatori di astrazione
che permettono di fornire descrizioni di sistemi a diversi livelli di dettaglio e di concentrarsi
sugli aspetti pi rilevanti ai fini della validazione di specifiche propriet dei sistemi. Una
descrizione astratta potr essere vista come una specifica, mentre una descrizione pi dettagliata, che d informazioni sulla struttura logico/fisica del sistema, sar vista come una
implementazione.
Per definire un modello adeguato per la programmazione concorrente, una questione importante a cui bisogna rispondere quella di chiarire quando due sistemi hanno comportamenti equivalenti, nel senso che possiamo sostituire luno allaltro allinterno di un ambiente

16

Capitolo 1 Introduzione

di esecuzione e non notare alcuna dierenza. Questa una questione teorica che risulta di
vitale importanza nella pratica. Finch non viene stabilito con precisione il significato di
similarit o dierenza di comportamento di sistemi, non siamo in grado di dire cosa fa esattamente un certo sistema. Inoltre, la nozione di equivalenza di comportamenti pu essere usata
come mezzo per specificare come si dovrebbe comportare un sistema implementato: il sistema
implementato si potr dire corretto se il suo comportamento eettivo sar equivalente alla
specifica del comportamento.
Cerchiamo di chiarire con un esempio lutilit pratica della nozione di equivalenza di
comportamenti. In questo esempio introduciamo informalmente il CCS, che tratteremo in
maniera completa e dettagliata nel Capitolo 12.
Supponiamo che due processi A1 ed A2 debbano eseguire una porzione del loro programma
in mutua esclusione perch si tratta di sezioni critiche. Per far questo, si servono di un
semaforo S, realizzato tramite un altro processo. Per semplicit, rappresentiamo una sezione
critica semplicemente con la sequenza di azioni b.e di inizio e termine della sezione critica. In
CCS, possiamo scrivere A1 , A2 e S nel modo seguente:
A1 , p.b1 .e1 .v.A1
A2 , p.b2 .e2 .v.A2
S , p.v.S
In generale, se a un canale (o porta) di comunicazione, lazione di input sul canale rappresentata da a e quella di output corrispondente da a. Il processo A1 , per esempio, esegue:
un output su p, lazione b1 , lazione e1 , un output su v e poi ritorna allo stato iniziale. Lidea
che le primitive standard sui semafori sono qui realizzate tramite sincronizzazioni sui canali
p e v (in questo semplice esempio utilizziamo sincronizzazione pura sui canali, cio sincronizzazione senza scambio di dati). Il sistema complessivo risulta dalla composizione parallela di
tutti e tre i processi:
Sys , (A1 | S | A2 ) \ {p, v}
In realt, si vuole anche indicare che i canali p e v sono destinati ad uso interno del sistema,
per questo si usa loperatore di restrizione (\), che li rende invisibili allesterno.
A questo punto si pone il problema di verificare se il sistema ottenuto Sys si comporta
correttamente, cio se il semaforo utilizzato correttamente. In pratica, ci vuol dire che le
sezioni critiche dei processi A1 e A2 non sono mai sovrapposte (per esempio, non accade mai
che il sistema eettui la sequenza di azioni b1 .b2 .e1 .e2 ). In altre parole, le uniche sequenze di
azioni permesse devono essere quelle del tipo (b1 .e1 + b2 .e2 ) . Possiamo specificare questo
comportamento corretto come il processo
Spec , b1 .e1 .Spec

b2 .e2 .Spec

in grado di eettuare la sequenza b1 .e1 o la sequenza b2 .e2 per poi in ogni caso tornare allo
stato iniziale ( denota la composizione non-deterministica interna). Ci serve quindi una
teoria matematica che ci permetta di dimostrare che il sistema Sys e la specifica Spec sono
equivalenti:
Spec Sys
ossia che, a meno di sincronizzazioni interne (sui canali p e v), i due sistemi esibiscono lo stesso
comportamento esterno. Questo proprio il ruolo degli strumenti matematici che trattano il
concetto di equivalenza tra processi.

1.4 Calcoli di processo

17

Concludiamo questa breve introduzione ai calcoli di processo descrivendo il loro potere


computazionale ed espressivo. I calcoli di processo, come naturale aspettarsi, risultano
avere perlomeno lo stesso potere computazionale delle macchine di Turing. Essi sono anche
naturalmente completi, nel senso che possono essere estesi con altri costrutti (facilmente esprimibili in termini dei costrutti di base) per dare origine a veri e propri linguaggi di
programmazione concorrente. Per esempio, OCCAM (il linguaggio di programmazione dei
transputer) derivato dal CSP mentre il linguaggio di programmazione Pict derivato dal
-calculus.
Se nel caso dei linguaggi funzionali il -calcolo [Chu41] gioca il ruolo di modello di riferimento, nel caso dei linguaggi di programmazione di sistemi concorrenti, non al momento
emerso alcun modello canonico. Il fatto che i sistemi concorrenti possono essere descritti in termini di dierenti costrutti: per creare processi (fork/wait, cobegin/coend, . . . ), per
linterazione tra processi (message-passing, memoria condivisa, . . . ) e per gestire luso di
risorse condivise (semafori, monitor, transazioni, . . . ). Una ulteriore complicazione che
mentre nel caso della programmazione funzionale, per stabilire se due funzioni sono equivalenti, suciente osservare il comportamento input-output delle funzioni, nel caso della
programmazione concorrente il problema di cosa debba essere osservato di un sistema cambia
a seconda delle circostanze e ci porta a dierenti nozioni di equivalenza tra sistemi, tutte
ugualmente ragionevoli. Possibili propriet osservabili sono le sequenze di azioni che un sistema pu eettuare, le circostanze che conducono al deadlock, la robustezza nei confronti dei
fallimenti, ecc.
Questa problematica ha dato origine a vari calcoli di processo, ciascuno con un proprio
insieme di primitive ed una propria teoria matematica della concorrenza. Essi dovrebbero
svolgere per i linguaggi concorrenti un ruolo simile a quello svolto dal -calcolo per i linguaggi
funzionali. Lo scopo della terza parte delle note quello di presentare i pi noti calcoli di
processo in un framework semantico unico. In tale framework, la semantica di ogni operatore
definita in uno stile noto come Structural Operational Semantics (SOS) che utilizza insiemi
di regole di inferenza per descrivere le evoluzioni dei termini. Tali regole associano ad ogni
termine un grafo delle transizioni cosicch i comportamenti del termine sono dati da un insieme
di stati e transizioni tra stati. I due tipi di grafi pi comunemente utilizzati sono le strutture
di Kripke (KS) ed i sistemi di transizioni etichettati (LTS). Entrambi saranno introdotti nella
Sezione 3.5. Nel primo caso si etichettano gli stati del grafo per descrivere leetto delle
transizioni su di essi o sulle loro variabili; nel secondo caso, si etichettano le transizioni con
le azioni che causano il passaggio da uno stato allaltro. Noi useremo il secondo approccio.
La terza parte di queste note dedicata alla teoria della concorrenza che segue lapproccio
basato sui calcoli di processo. A tale scopo, nel Capitolo 10 descriveremo alcuni degli operatori utilizzati dai calcoli di processo pi conosciuti. Nel Capitolo 11 introdurremo diverse
relazioni per confrontare sistemi di transizioni etichettate, alcune saranno delle equivalenze,
altre dei preordini. Nel Capitolo 12 presenteremo CCS (Calculus of Communicating Systems,
Milner 1980), probabilmente il pi noto calcolo di processi, ed alcune teorie della concorrenza
sviluppate specificamente per esso. Nel Capitolo 13 introdurremo alcune logiche modali e temporali e mostreremo come utilizzarle per specificare propriet dei sistemi concorrenti. Infine,
in Appendice A presenteremo un elenco degli operatori per la concorrenza, in Sezione A.1,
ed una lista dei calcoli di processo pi noti con linsieme degli operatori usato da ciascuno di
essi, in Sezione A.2.

18

1.5

Capitolo 1 Introduzione

Schema delle note

Queste note sono divise in tre parti. La prima parte introduce alcune nozioni preliminari
riguardanti matematica discreta e tecniche di prova, grammatiche e sintassi, automi a stati
finiti e sistemi di transizioni etichettate. La seconda parte verte su semantica operazionale e
denotazionale di linguaggi sequenziali; a tale scopo introduce anche la -notazione e i concetti
di base della teoria dei domini. La terza ed ultima parte presenta alcuni formalismi per
progettare, specificare, implementare, analizzare e dimostrare propriet di sistemi concorrenti
e distribuiti. Tali formalismi includono operatori per formare processi e calcoli di processo,
equivalenze comportamentali e logiche modali e temporali.
Il resto di queste note organizzato come segue.
Capitolo 2: Nozioni preliminari. Si introducono alcune nozioni matematiche preliminari:
insiemi, relazioni, funzioni, induzione e sistemi di inferenza. Particolare attenzione
dedicata alle propriet delle relazioni, a vari principi di induzione, ai sistemi di inferenza
ed al concetto di congruenza. Tali argomenti giocheranno infatti un ruolo fondamentale
nel seguito.
Capitolo 3: Sintassi e modelli semantici. Si introducono alcune nozioni della teoria dei
linguaggi (grammatiche ed automi) e si definiscono i sistemi di transizioni etichettate.
Si mostra un esempio che illustra sintassi e semantica operazionale delle espressioni
aritmetiche.
Capitolo 4: Sintassi e denotazioni. Si introducono alcune nozioni e definizioni preliminari di semantica denotazionale e li si illustra tramite due esempi di descrizione della
semantica di semplici formalismi. Si mostrano anche i tre approcci alla semantica nel
caso del linguaggio delle espressioni regolari.
Capitolo 5: -calculus. Si presenta il -calculus, un sistema formale che ha un ruolo importante nello studio dei fondamenti dei linguaggi di programmazione. Il -calculus
fornisce infatti sia una notazione semplice per la rappresentazione di funzioni nonch di
altri importanti concetti di programmazione, sia un sistema di calcolo basato su un insieme di regole di riduzione che consente di studiare le propriet semantiche di funzioni
e programmi.
Capitolo 6: Domini per la semantica denotazionale. Si presentano le basi matematiche per la semantica denotazionale dei linguaggi di programmazione. Vengono prima
introdotti i concetti di insieme parzialmente ordinato completo, funzione continua, minimo punto fisso e soluzione di un sistema di equazioni mutuamente ricorsive. Quindi si
presentano i concetti di base della teoria dei domini ed alcuni operatori che permettono
di costruire domini a partire da domini pi semplici. Infine, viene definito un metalinguaggio per esprimere le funzioni utilizzate per descrivere la semantica denotazionale di
una vasta classe di linguaggi di programmazione e viene dimostrato che tutti i costrutti
del metalinguaggio preservano la continuit.
Capitolo 8: Un semplice linguaggio imperativo. Si presentano alcuni concetti comuni
a vari linguaggi di programmazione e le tecniche utilizzate per la loro descrizione formale.
Si considera TINY, un semplice linguaggio di programmazione imperativo, di cui viene

1.5 Schema delle note

19

presentata una semantica operazionale ed una semantica denotazionale. Viene infine


dimostrata lequivalenza delle due semantiche.
Capitolo 9: Linguaggi con contesti. Si introduce un altro linguaggio di programmazione,
SMALL, che una semplice estensione del linguaggio TINY considerato nel capitolo
precedente. Rispetto a TINY, il linguaggio SMALL prevede la dichiarazione esplicita
di variabili e costanti usate allinterno di un programma e la strutturazione in blocchi
dei programmi stessi; inoltre SMALL permette la dichiarazione e luso di funzioni e
procedure. Pertanto, SMALL si avvicina notevolmente al linguaggio Pascal.
Capitolo 10: Operatori per concorrenza e nondeterminismo. Si presenta unampia
panoramica degli operatori ricorrenti nei linguaggi concorrenti. Di ogni operatore
mostrata lutilit ed definita la semantica operazionale.
Capitolo 11: Equivalenze comportamentali e preordini di ranamento. Si
introducono alcuni criteri per confrontare sistemi di transizioni etichettate. Alcuni
di questi criteri costituiscono delle relazioni di equivalenza sullinsieme dei sistemi
di transizioni, altri invece costituiscono dei preordini. Tutti comunque sono basati
sullidea che due sistemi vanno considerati equivalenti se nessun osservatore esterno li
pu distinguere, cio se i due sistemi hanno lo stesso insieme di osservazioni. Ci sono
per diverse ragionevoli nozioni di osservazione e ci d origine a relazioni dierenti. In
particolare si studiano lequivalenza a tracce, la bisimulazione, e lequivalenza testing.
Di ciascuna di esse viene considerata una versione forte che considera le azioni
invisibili alla stessa stregua delle altre azioni ed una versione debole che tratta le
azioni invisibili in maniera speciale.
Capitolo 12: Calculus of Communicating Systems (CCS). Vine presentato il Calculus of Communicating Systems (CCS), uno dei calcoli di processo pi conosciuti ed
utilizzati, ed alcune teorie della concorrenza sviluppate specificamente per esso. Vengono presentate sintassi e semantica operazionale di CCS, ed una variante con passaggio
di valori. Quindi vengono presentate specificamente per CCS alcune delle equivalenze e
dei preordini comportamentali visti nel capitolo precedente, con particolare attenzioni a
quelle relazioni che sono preservate dagli operatori del calcolo. Infine, viene introdotto
un altro approccio alla definizione della semantica dei sistemi concorrenti, quello algebrico (o assiomatico), tramite caratterizzazioni (dis)equazionali alternative di alcune
delle relazioni osservazionali introdotte.
Capitolo 13: Logiche per i sistemi concorrenti. Si introducono alcune logiche modali e
temporali e si mostra come utilizzarle per specificare propriet dei sistemi concorrenti.
Vengono descritte in dettaglio la logica HML, la logica ACTL e il -calculus modale.
Viene anche esaminata la corrispondenza tra le equivalenze indotte dalle logiche e le
equivalenze comportamentali presentate nel Capitolo 11.
Per ulteriori approfondimenti si consiglia di consultare i seguenti testi: [Bar90, Gor79,
Sch86, Win99, Win09, Mil89, Hen88, Fok00, Hoa85, Sch99, HM85, AILS07, CGP99] ed i
riferimenti in essi contenuti.

20

Capitolo 1 Introduzione

Parte I

Preliminari Matematici

Capitolo 2

Nozioni preliminari

SOMMARIO
Questo capitolo introduce alcune nozioni preliminari di matematica. Particolare attenzione
dedicata alle propriet delle relazioni, a vari principi di induzione, ai sistemi di inferenza
ed al concetto di congruenza. Tali argomenti giocheranno infatti un ruolo fondamentale nel
seguito.

2.1

Insiemi

Un insieme A una qualunque collezione di oggetti, chiamati elementi di A.1 Un insieme non
pu contenere pi di una copia di un suo elemento e lordine degli elementi in un insieme non
ha alcuna rilevanza. Due insiemi A e B sono uguali se ogni elemento di A anche elemento
di B, e viceversa. La relazione di appartenenza di un elemento ad un insieme viene denotata
attraverso il simbolo 2. Se indichiamo con A linsieme dei numeri pari, 4 2 A e 7 62 A.
Scriveremo A B e diremo che A contenuto in B (anche, A un sottoinsieme di B) se
ogni elemento di A anche elemento di B (B A sinonimo di A B). Scriveremo invece
A B quando A B ed esiste un elemento di B che non appartiene ad A. Chiaramente A
uguale a B, e scriveremo A = B, quando A B e B A.
Linsieme vuoto linsieme che non contiene alcun elemento e viene indicato con il simbolo ; (o, in taluni contesti, con la notazione {}). Gli insiemi finiti (vedremo tra breve la
definizione di insieme finito) possono essere descritti attraverso la sequenza dei loro elementi
racchiusa fra parentesi grae. Ad esempio, {0, 1, 2} rappresenta linsieme finito i cui elementi
sono i numeri 0, 1 e 2.
Una propriet un predicato P che ad ogni elemento o insieme x associa un valore di
verit. Scriveremo P (x) per significare che x soddisfa il predicato P e, in tal caso, diremo
anche che P (x) vale.
Gli insiemi possono anche essere descritti utilizzando propriet dei loro elementi: la
notazione
{x | P (x)}
rappresenta linsieme costituito da tutti gli elementi x che soddisfano la propriet P . Con
questa notazione possibile descrivere anche insiemi infiniti come
{x | x 2 N e x

3}.

1
Le nozioni di insieme e di appartenenza a un insieme sono le uniche nozioni che le teorie matematiche
assumono come primitive e di cui non danno una definizione.

24

Capitolo 2 Nozioni preliminari

La notazione
{x 2 X | P (x)}

sinonimo di

{x | x 2 X e P (x)}.

Le operazioni definite solitamente su insiemi sono le seguenti.


1. Lunione di A e B linsieme
A [ B = {x | x 2 A oppure x 2 B}.
Pi in generale se {Ai } una famiglia di insiemi, al variare di i in un certo insieme di
indici I,lunione degli Ai linsieme
[
Ai = {x | 9 i 2 I tale che x 2 Ai }.
i2I

2. Lintersezione di A e B linsieme
A \ B = {x | x 2 A e x 2 B}.
Pi in generale se {Ai } una famiglia di insiemi, al variare di i in un certo insieme di
indici I, lintersezione degli Ai linsieme
\
Ai = {x | x 2 Ai per ogni i 2 I}.
i2I

3. La dierenza di A e B linsieme
A

B = {x | x 2 A e x 62 B}.

4. Il prodotto cartesiano di A e B linsieme


A B = {(a, b) | a 2 A e b 2 B}.
ossia linsieme delle coppie ordinate (a, b) tali che a 2 A e b 2 B.2

Pi in generale se A1 , . . . An sono n insiemi, il prodotto cartesiano degli Ai linsieme


n

Ai = {(a1 , . . . , an ) | ai 2 Ai per i = 1, . . . , n}.3

i=1

Nel caso in cui A1 , . . . An siano tutti uguali a un certo insieme A, il prodotto cartesiano
degli Ai si indica con An .
2

Volendo essere rigorosi bisognerebbe definire formalmente anche il concetto di coppia ordinata. Ci accontenteremo tuttavia di fare adamento allidea intuitiva che in generale si ha di tale concetto. Basti solo
ricordare che, contrariamente a quanto avviene per gli insiemi, una coppia ordinata (o, in generale, una n-upla)
una struttura in cui lordine degli elementi rilevante cos come la loro molteplicit. In tal senso (a, a)
una coppia ordinata valida e (a, b) 6= (b, a) quando a 6= b. Due coppie (a, b) e (c, d) sono uguali se e solo se
a = c e b = d. Per le coppie si usa in taluni contesti la notazione < a, b >.
3
possibile anche definire il prodotto cartesiano tra un numero infinito di insiemi ma la definizione risulta
piuttosto sofisticata. Non ne avremo comunque bisogno.

25

2.2 Relazioni e funzioni


5. Linsieme potenza o insieme delle parti di A linsieme
2A = {X | X A}.

ossia linsieme i cui elementi sono tutti i sottoinsiemi di A. Per questo insieme si usano
talvolta anche le notazioni Pow(A) o P(A).
Esempio 2.1. Siano A = {1, 2} e B = {2, 3}. Allora
A [ B = {1, 2, 3}, A \ B = {2}, A

B = {1},

A B = {(1, 2), (1, 3), (2, 2), (2, 3)}, 2A = {;, {1}, {2}, A}.
Due insiemi A e B si dicono avere la stessa cardinalit se esiste una funzione biunivoca fra
A e B (si veda la prossima sezione per la definizione di funzione biunivoca). Questa definizione
coglie il concetto intuitivo di insiemi con lo stesso numero di elementi.
Diremo che un insieme A finito se esiste n 2 N tale che A pu essere messo in corrispondenza biunivoca con linsieme {i 2 N | 1 i n}; in tal caso n sar detto cardinalit
di A. La cardinalit di un insieme A si indica con |A| o con #A.
Diremo che A infinito se non finito. Si consideri linsieme dei numeri naturali N
e linsieme dei numeri pari P . Essi hanno la stessa cardinalit, infatti la funzione che al
numero n associa il numero 2n una funzione biunivoca tra tali insiemi, tuttavia risulta
anche P N. Il fatto che un insieme possa essere messo in corrispondenza biunivoca con un
suo sottoinsieme proprio caratterizzante degli insiemi infiniti e potrebbe essere preso come
definizione di insieme infinito.
Un insieme si dice numerabile se pu essere messo in corrispondenza biunivoca con
linsieme N dei numeri naturali.
Se A e B sono finiti con |A| = n e |B| = m allora abbiamo
|2A | = 2n

2.2

|A B| = n m

Relazioni e funzioni

In questa sezione introduciamo la nozione di relazione e ne studiamo le propriet.


Definizione 2.2 (Relazione). Una relazione binaria R tra due insiemi (non necessariamente
distinti) A e B un sottoinsieme del prodotto cartesiano A B. Per indicare che (a, b) 2 R
si usa spesso la notazione R(a, b) o la notazione aRb.
Pi in generale una relazione n-aria tra gli insiemi A1 , . . . , An un sottoinsieme del
n
prodotto cartesiano Ai .
i=1

Tra tutte le relazioni possibili tra due insiemi A e B ve ne sono due speciali che sono
la relazione vuota ; e la relazione totale A B. Inoltre, ad ogni insieme A associata la
relazione (funzione) identit IdA dove IdA = {(a, a) | a 2 A}.
Introduciamo ora alcune operazioni sulle relazioni.
Definizione 2.3 (Operazioni sulle relazioni).

26

Capitolo 2 Nozioni preliminari


Data una relazione binaria R A B, la sua inversa , denotata con R
R

1,

la relazione

= {(y, x) | (x, y) 2 R} B A.

Date due relazioni binarie R1 A B e R2 B C, la loro composizione, denotata


con R1 R2 o anche con R1 R2 , la relazione binaria
R1 R2 = {(x, z) | 9 y 2 B tale che (x, y) 2 R1 e (y, z) 2 R2 } A C.
Se R A A una relazione binaria si pone
R0
Rn+1
R
R+

=
=
=
=

IdA ,
n
R
S R , n
R
Sn 0 n
n 1 R .

Si osservi che R1 = R R0 = R, R = IdA [ R+ e

R+ = {(x, y) | 9n, 9x1 , . . . , xn con xi Rxi+1 (1 i n

1), x1 = x, xn = y} .

Data una relazione binaria R A B ed un sottoinsieme X di A si dice immagine di


X tramite R, e la si denota con R(X), linsieme
R(X) = {b 2 B | 9x 2 X tale che (x, b) 2 R} .
Si dice immagine di R linsieme R(A).
Data una relazione binaria R A B ed un sottoinsieme Y di B si dice retroimmagine
di Y tramite R limmagine di Y tramite R 1 , ossia linsieme
R

(Y ) = {a 2 A | 9y 2 Y tale che (a, y) 2 R} .

Siano R ed S due relazioni tra A e B. Si dice che S estende R o che R implica S se


R S.
Studiamo adesso alcune propriet delle relazioni binarie.
Definizione 2.4 (Propriet delle relazioni binarie). Sia R A A una relazione binaria su
un insieme A. Si dice che R
riflessiva: se 8x 2 A, (x, x) 2 R,
simmetrica: se 8x, y 2 A, (x, y) 2 R implica (y, x) 2 R,
antisimmetrica: se 8x, y 2 A, (x, y) 2 R e (y, x) 2 R implica x = y;
transitiva: se 8x, y, z 2 A, (x, y) 2 R e (y, z) 2 R implicano (x, z) 2 R.
Quando una relazione R non soddisfa una propriet P pu avere senso considerare una
relazione in qualche modo legata a R e che soddisfa P . Questo lo scopo della prossima
definizione.

27

2.2 Relazioni e funzioni


Definizione 2.5. Sia R una relazione binaria su un insieme A.

La chiusura riflessiva di R la pi piccola relazione riflessiva che contiene R, essa pu


essere caratterizzata come la relazione
R [ IdA .
La chiusura simmetrica di R la pi piccola relazione simmetrica che contiene R, essa
pu essere caratterizzata come la relazione
R[R

La chiusura transitiva di R la pi piccola relazione transitiva che contiene R, essa pu


essere caratterizzata come la relazione
R+ .
Il nucleo simmetrico di R la pi grande relazione simmetrica contenuta in R, esso pu
essere caratterizzato come la relazione
R\R

Si osservi che se R riflessiva o simmetrica anche la chiusura transitiva di R riflessiva o


simmetrica. Data una generica relazione R, spesso saremo interessati alla chiusura riflessiva
e transitiva di R e tale chiusura coincide con la relazione R .
facile dimostrare che il nucleo simmetrico di una relazione riflessiva una relazione
riflessiva e che che il nucleo simmetrico di una relazione transitiva una relazione transitiva.
Vi sono alcuni tipi di relazioni che giocano un ruolo speciale ed ai quali sono stati dati
dei nomi specifici (si veda anche la Tabella 2.1).
Equivalenza
Ordine
Preordine

riflessiva
*
*
*

simmetrica
*

antisimmetrica
*

transitiva
*
*
*

Tabella 2.1: Propriet delle relazioni di equivalenza, di ordine e di preordine.


Definizione 2.6 (Relazione di preordine). Una relazione binaria R su un insieme A un
preordine se riflessiva e transitiva.
Definizione 2.7 (Relazione di ordine). Una relazione binaria R su un insieme A un ordine
se riflessiva, antisimmetrica e transitiva.
Definizione 2.8 (Relazione di equivalenza). Una relazione binaria R su un insieme A una
equivalenza se riflessiva, simmetrica e transitiva.

28

Capitolo 2 Nozioni preliminari


Esempi di relazioni di equivalenza su N sono
IdN

S = {(x, y) 2 N N | x mod 3 = y mod 3}

Data una relazione di equivalenza su un insieme A, ha senso considerare gli elementi di A a


meno di tale equivalenza. Pi formalmente si pone la seguente definizione (si veda anche la
Figura 2.1).
Definizione 2.9 (Classi di equivalenza e insieme quoziente). Sia R una relazione di equivalenza su un insieme A. Si definisce classe di equivalenza della relazione R ogni sottoinsieme
X di A tale che
x, y 2 X =) xRy (X coerente rispetto a R),
x 2 X, xRy

=) y 2 X (X saturo rispetto a R).

Si definisce insieme quoziente di A modulo R, e lo si indica con A/R, linsieme delle classi
di equivalenza, ossia
A/R = {X A | X una classe di equivalenza rispetto a R} .

Figura 2.1: Quoziente di un insieme A rispetto a una relazione di equivalenza R. Ogni classe
di equivalenza contiene elementi in relazione fra loro. Gli elementi di una classe non sono in
relazione con quelli di unaltra classe
facile provare che le classi di equivalenza di una relazione di equivalenza su A costituiscono una partizione di A nel senso che ogni elemento di A appartiene ad una ed una sola
classe di equivalenza.
Definizione 2.10 (Relazione di ordine). Una relazione binaria R su un insieme A si dice
essere una relazione dordine (parziale) se riflessiva, antisimmetrica e transitiva. La relazione R si dice relazione dordine totale se R una relazione dordine e se per ogni x, y 2 A
risulta (x, y) 2 R o (y, x) 2 R.
Un esempio di ordine parziale la relazione R sullinsieme delle parti di un insieme A
definita dallinclusione, vale a dire (X, Y ) 2 R se X Y per X, Y A.
Definizione 2.11 (Preordine). Una relazione binaria R su un insieme A si dice essere un
preordine se riflessiva e transitiva.

2.3 Principi di induzione

29

Poich un preordine una relazione binaria possibile definire il nucleo simmetrico di un


preordine. Spesso diremo semplicemente nucleo di preordine omettendo di specificare che si
tratta del nucleo simmetrico. Si ha il seguente facile ma utile risultato: il nucleo simmetrico
di un preordine una relazione di equivalenza.
Questo modo di generare una relazione di equivalenza a partire da un preordine sar
utilizzato spesso nel seguito.
Concludiamo questa sezione con il concetto di funzione.
Definizione 2.12 (Funzione). Una funzione costituita da un insieme A detto dominio,
da un insieme B detto codominio e da una relazione binaria f tra A e B (ossia, da un
sottoinsieme di A B) con la propriet che per ogni elemento a 2 A esiste un unico elemento
b tale che (a, b) 2 f . Comunemente si identifica una funzione con la relazione che la definisce.
Scriveremo f : A ! B per dire che f una funzione da A a B e, per a 2 A, scriveremo
f (a) per indicare lunico elemento b di B tale che (a, b) 2 f . Una funzione da An in A detta
operatore n-ario su A.
Definizione 2.13 (Propriet delle funzioni). Sia f : A ! B una funzione.
La funzione f si dice suriettiva se limmagine di f B, ossia se risulta f (A) = B.
La funzione f si dice iniettiva se per ogni a, a0 2 A si ha che f (a) = f (a0 ) implica
a = a0 . Se f iniettiva, linversa di f come relazione una funzione da f (A) in A.
La funzione f si dice biunivoca se suriettiva e iniettiva.
Definizione 2.14 (Composizione di funzioni). Siano f : A ! B e g : B ! C due funzioni. La
funzione composta, indicata con g f , la funzione da A a C definita da (g f )(a) = g(f (a)).
Si osservi linversione dellordine con cui appaiono f e g rispetto alla composizione di
relazioni.

2.3

Principi di induzione

I procedimenti induttivi, ossia che fanno uso del principio di induzione, sono strumenti fondamentali per descrivere insiemi infiniti o per dimostrarne le propriet. Illustreremo in questa
sezione le forme di induzione pi comunemente usate: linduzione matematica e linduzione
strutturale.

2.3.1

Induzione matematica

Cominciamo con il classico principio di induzione matematica.


Teorema 2.15 (Principio di induzione matematica). Una propriet P vera per ogni numero
naturale n 2 N se
1. P (0) vera (caso base),
2. P (k) implica P (k + 1) per ogni k 2 N (caso induttivo).

30

Capitolo 2 Nozioni preliminari

Dimostrazione. Supponiamo per assurdo che P non valga per tutti i numeri naturali e sia h
non vale. Abbiamo che h
6= 0 (dato che P (0)
il pi piccolo numero naturale tale che P (h)

vale) quindi h = h + 1 per un certo h. Siccome h il pi piccolo numero naturale per il quale
vale e questo
P non vale, abbiamo che P (h) vale ma allora, per il punto 2, P (h + 1) = P (h)
assurdo.
Il teorema aerma che per dimostrare che una propriet P vera per un qualsiasi numero
naturale n, suciente dimostrare che la propriet vale per il numero 0 e che il fatto che sia
vera per un numero k implica che vera per il numero successivo.
Esempio 2.16. Si dice che quando era bambino, Gauss deriv la seguente formula
sum(n) =

n
X
i=1

i=

n(n + 1)
2

per la somma dei primi n interi non-negativi. Proviamo la correttezza di questa formula per
induzione usando lo schema descritto in precedenza.
Scopo: Dimostrare sum(n) = n(n+1)
per ogni numero naturale n.
2
Caso base: Dobbiamo provare che sum(0) = 0(0+1)
= 0. Questo vero perch la somma
2
dei numeri da 0 a 0 0.
Passo induttivo: Dobbiamo provare che per ogni naturale n, se sum(n) = n(n+1)
allora
2
(n+1)(n+2)
n(n+1)
sum(n + 1) =
. Assumiamo allora che sum(n) =
per un n arbitrario e
2
2
proviamo che la formula valida per il successivo numero naturale n + 1. Siccome la somma
dei primi n+1 naturali non altro che la somma dei primi n cui viene aggiunto n+1, abbiamo
sum(n + 1) = sum(n) + (n + 1). Applichiamo a questo punto lipotesi induttiva, vale a dire
sum(n) = n(n+1)
. Otteniamo
2
sum(n + 1) = sum(n) + (n + 1) =

n(n + 1)
+ (n + 1)
2

e completiamo la prova osservando che


n(n + 1)
(n + 1)(n + 2)
+ (n + 1) =
.
2
2
Vi una forma leggermente diversa, ed apparentemente pi forte, di induzione matematica,
detta principio di induzione matematica completa, che dice che una propriet P vale per tutti
i numeri naturali se
1. P (0) vera (caso base),
2b. P (0), . . . , P (k) implicano P (k + 1) per ogni k 2 N (caso induttivo).

ossia se vera per il numero 0 e se dal fatto che sia vera per i numeri minori di k + 1 si riesce
a dedurre che vera per il numero k + 1.
Non dicile provare il principio di induzione matematica completa mimando la dimostrazione data per il principio di induzione matematica. Sussiste in realt un risultato pi
forte che dice che i due principi sono equivalenti nel senso che se possibile provare una
certa propriet dei numeri interi con linduzione completa allora possibile provare la stessa
propriet anche con linduzione standard (e viceversa). Abbiamo infatti il seguente risultato.

31

2.3 Principi di induzione

Proposizione 2.17 (Equivalenza tra induzione e induzione completa). Il principio di induzione matematica (PIM) e il principio di induzione matematica completa (PIMC) sono
equivalenti, ossia, per ogni propriet P sui numeri naturali risulta
P dimostrabile con PIM se e solo se dimostrabile con PIMC.
Dimostrazione. )) ovvio che se una propriet P soddisfa i punti 1) e 2) del PIM allora
soddisfa anche i punti 1) e 2b) del PIMC.
() Sia ora P una propriet che soddisfa i punti 1) e 2b) del PIMC, vogliamo provare che
P (n) vera per ogni n usando solo il PIM. Sia Q(n) la propriet
P (k) vale per ogni k n.

Vogliamo dimostrare (usando il PIM) che Q(n) vale per ogni n, dobbiamo quindi provare che
Q(0) vale e che Q(k) implica Q(k + 1) per ogni k. Dato che Q(0) asserisce che P (0) vale e
che P soddisfa il punto 1), Q(0) vale. Limplicazione Q(k) =) Q(k + 1) si traduce in
P (0), . . . , P (k) =) P (0), . . . , P (k + 1)
ma questo vero perch
P (0), . . . , P (k) =) P (0), . . . , P (k)
e, per il punto 2b),
P (0), . . . , P (k) =) P (k + 1).
Quindi abbiamo provato che Q(n) vale per ogni n e ci, per definizione di Q(n), implica che
P (n) vale per ogni n.
Osserviamo che le condizioni 1) e 2b) del principio di induzione matematica completa
possono essere riscritte con ununica condizione nel modo seguente:
P (i) per ogni i < k =) P (k), per ogni k 2 N.

Tale condizione infatti si riduce, per k = 0, a

; =) P (0),

ossia a P (0) vale.


Il principio di induzione matematica completa pu risultare utile quando per provare che
il numero k + 1 soddisfa una certa propriet necessario ricorrere alla stessa propriet dei
numeri pi piccoli come nel caso seguente.
Esempio 2.18. Vogliamo provare che ogni numero naturale maggiore di 1 prodotto di
numeri primi. Sia P la seguente propriet
P (n) = n 1 oppure esistono dei primi p1 , . . . , pk tali che n = p1 . . . pk .

Usando il principio di induzione matematica completa suciente provare, per k arbitrario,


che se P (i) vale per ogni i < k allora P (k) vale. Sia allora k un numero naturale. Se k 1
oppure se k un numero primo immediato concludere che P (k) vale. Altrimenti, k deve
essere maggiore di 1 e deve essere il prodotto di due numeri, ossia k = k1 k2 con k1 e k2
entrambi maggiori di 1. Lipotesi induttiva che P (i) vera per ogni i < k, per cui, essendo
k1 , k2 < k e k1 , k2 > 1, abbiamo che k1 e k2 sono entrambi prodotti di primi. Ne deriva che
anche k deve essere un prodotto di primi.

32

Capitolo 2 Nozioni preliminari

Per capire meglio la natura del principio di induzione matematica consideriamo la famiglia
di tutti gli insiemi X che soddisfano
a) 0 2 X,
b) k 2 X =) k + 1 2 X, per ogni k.
Elementi di tale famiglia sono per esempio N, Z, R. La particolarit di N, rispetto a tutti gli
altri insiemi X che soddisfano a) e b), di essere linsieme pi piccolo (ossia, se X soddisfa
a) e b) allora N X).
Proposizione 2.19. Il principio di induzione matematica implica che N il pi piccolo tra
gli insiemi X che soddisfano a) e b).
Dimostrazione. Sia X un insieme che soddisfa a) e b); dobbiamo dimostrare che, nellipotesi
che il principio di induzione matematica valga, N X. Si consideri la propriet P (n) definita
da n 2 X. Poich X soddisfa a) e b), si ha che P (n) soddisfa i punti 1) e 2) del principio
di induzione matematica. Lapplicazione del principio ci permette di concludere che P (n)
vera per ogni n 2 N e quindi, per definizione di P (n), che N X.
Possiamo anche dimostrare lasserzione opposta.
Proposizione 2.20. Se N il pi piccolo tra gli insiemi X che soddisfano a) e b), allora il
principio di induzione matematica vale.
Dimostrazione. Lipotesi N il pi piccolo tra gli insiemi X che soddisfano a) e b) implica
che se X un insieme che soddisfa a) e b) allora N X. Sia ora P (n) una propriet
che verifica i punti 1) e 2) del principio di induzione matematica. Dimostrare la validit
del principio stesso equivale a dimostrare che P (n) vera per ogni n 2 N. Poniamo ora
X = {k : P (k)}. Abbiamo che X soddisfa a) e b), quindi N X. Da ci, per definizione di
X, segue che P (n) vera per ogni n 2 N, che quanto volevamo dimostrare.
Il fatto che N sia il pi piccolo insieme che soddisfa a) e b) e che per N valga il principio
di induzione matematica non una coincidenza fortuita ma un caso particolare di uno schema
pi generale che illustriamo nella prossima sezione.

2.3.2

Induzione strutturale

La situazione vista nella sezione precedente per N vale pi in generale per gli insiemi definiti
per induzione tramite costruttori. Spiegheremo il significato di queste parole in questa sezione.
Cominciamo prima con qualche esempio4 .
Esempio 2.21. Linsieme Lists(N) delle liste di elementi in N pu essere definito come il
pi piccolo insieme tra gli insiemi X tali che
a. [ ] 2 X,
b. ` 2 X implica n :: ` 2 X, per ogni n 2 N .

4
Non saremo eccessivamente formali in questa sezione per non ouscare le idee che stanno dietro ai principi
con pesanti formalismi.

2.3 Principi di induzione

33

dove [ ] indica la lista vuota e n :: ` indica la lista ottenuta aggiungendo n in testa a `.


Il principio di induzione strutturale associato allinsieme delle liste con elementi in N il
seguente: una propriet P vera per tutti gli ` 2 Lists(N) se
1. P ([ ]) vera,
2. P (`) implica P (n :: `) per ogni ` 2 Lists(N ) e n 2 N .
Possiamo usare il principio appena enunciato per dimostrare, per esempio, la seguente
propriet:
sum(`) max(`) len(`), per ogni ` 2 Lists(N )

dove sum(`) indica la somma degli elementi della lista `, max(`) indica il pi grande elemento
di ` (con max([ ]) = 0) e len(`) indica il numero di elementi di `.
Ponendo P (x) = sum(x) max(x) len(x), abbiamo che:
1) P ([ ]) vera, infatti 0 = sum([ ]) max([ ]) len([ ]) = 0,
2) P (`) implica P (n :: `) vera, infatti supponendo sum(`) max(`) len(`) abbiamo
sum(n :: `) = n + sum(`) n + max(`) len(`)
max(n :: `) + max(n :: `) len(`)

= max(n :: `) (1 + len(`)) = max(n :: `) len(n :: `).


La tesi quindi dimostrata.
Prima di enunciare il principio generale vediamo un altro esempio.
Esempio 2.22. Linsieme Trees(N) degli alberi le cui foglie sono elementi di N pu essere
definito come il pi piccolo insieme tra gli insiemi X tali che
a. n 2 X per ogni n 2 N,
b. t1 , . . . , tk 2 X implica Tk (t1 , . . . , tk ) 2 X, per ogni k 2 N,
dove Tk la funzione, o meglio il costruttore, che dati k alberi t1 , . . . , tk costruisce lalbero
che ha t1 , . . . , tk come sottoalberi della radice.
Il principio di induzione strutturale associato allinsieme degli alberi con foglie in N il
seguente: una propriet P vera per tutti i t 2 Trees(N) se
1. P (n) vera per ogni n 2 N (ossia vera per le foglie),
2. P (t1 ), . . . , P (tk ) implicano P (Tk (t1 , . . . , tk )), per ogni k 2 N e per ogni t1 , . . . , tk 2
Trees(N).
Non entreremo qui nella discussione di capire quando una definizione per induzione ben
posta e nel problema di definire formalmente che cos un costruttore. Diremo solo che un
costruttore di ariet k una sorta di funzione che a partire da k valori (che possono essere
numeri, insiemi o qualunque altro oggetto matematico) costruisce un nuovo valore.5 Sono
5

Non si pu parlare di funzione perch il dominio e il codominio di un costruttore possono non essere
insiemi. Si consideri per esempio il costruttore che ad ogni insieme A associa linsieme {A}. Esso ha come
dominio la famiglia di tutti gli insiemi ma si pu dimostrare che tale famiglia non un insieme.

34

Capitolo 2 Nozioni preliminari

esempi di costruttori: il costruttore che, presi A e B, costruisce la coppia (A, B); il costruttore
che, senza prendere valori, rende il numero 0; il costruttore che, fissato n 2 N e preso `, rende
la scrittura formale n :: `.6
facile definire gli analoghi degli insiemi visti negli esempi precedenti per mezzo di costrut(n)
tori. Consideriamo per esempio linsieme degli alberi con foglie in N. Detto 0 il costruttore
che, presi 0 valori, rende il numero n e detto k il costruttore che, presi k valori A1 , . . . , Ak ,
rende la k-pla (A1 , . . . , Ak ), abbiamo che linsieme degli alberi con foglie in N pu essere
definito come il pi piccolo insieme tra gli insiemi X tali che
a.

(n)
0 ()

2 X per ogni n 2 N (ossia, n 2 X per ogni n 2 N),

b. t1 , . . . , tk 2 X implica

k (t1 , . . . , tk )

2 X, per ogni k 2 N.

In questa rappresentazione gli alberi sono oggetti del tipo (1, (2, (3)), (5, 5)).
Definizione 2.23 (Definizione per induzione tramite costruttori). Un insieme Y definito
per induzione tramite la famiglia di costruttori se la sua definizione della forma
Y il pi piccolo tra gli insiemi X che soddisfano:
s1 , . . . , sk 2 X =) k (s1 , . . . , sk ) 2 X per ogni k 2
dove k lariet di

k.

In altre parole Y il pi piccolo insieme chiuso (si veda Definizione 2.32) rispetto a ogni
2 .
Siamo ora in grado di enunciare il principio di induzione strutturale nella sua forma
generale.
Teorema 2.24 (Principio di induzione strutturale). Una propriet P vera per tutti gli
elementi di un insieme S definito per induzione tramite una famiglia di costruttori se
P (s1 ), . . . , P (sk ) =) P
per ogni

k (s1 , . . . , sk )

2 e per ogni s1 , . . . , sk 2 S, dove k lariet di

k.

Nel caso di Lists(N), abbiamo il costruttore [ ] (di ariet 0, non prende argomenti e rende
la lista vuota) e la famiglia dei costruttori della forma n :: _ (di ariet 1, prendono una lista
e rendono la lista con in pi il numero n in testa). Se istanziato sulle liste di naturali, il
principio di induzione strutturale aerma che per dimostrare che una propriet vera per
tutte le liste di naturali suciente dimostrare che essa vera per la lista vuota e che
preservata da tutti i costruttori utilizzati per formare liste di naturali.
Anche il principio di induzione matematica pu essere visto come un caso particolare del
principio di induzione strutturale. Infatti abbiamo visto che N pu essere caratterizzato come
il pi piccolo insieme tra gli insiemi X che soddisfano
a)
6

(0)
0 ()

2X

Una scrittura formale pu essere identificata con una ennupla. Per esempio, la scrittura formale n :: `
pu essere identificata con la terna (n, cod(::), `) dove cod(::) rappresenta il numero associato al carattere ::
secondo una qualche codifica.

35

2.4 Sistemi di inferenza


b) n 2 X =)

1 (n)

2 X, per ogni n

(0)

dove 0 il costruttore di ariet 0 che rende il numero 0 e 1 il costruttore di ariet 1


che preso n rende n + 1. Da questa caratterizzazione applicando il principio di induzione
strutturale discende il comune principio di induzione matematica.
Lidea alla base della dimostrazione del principio di induzione strutturale molto semplice:
nelle ipotesi del teorema, se ci fosse un elemento minimale (rispetto al numero di costruttori
usati nella sua costruzione) che non soddisfa la propriet P allora le sue sottocomponenti soddisferebbero la propriet P (perch esso minimale) e quindi esso stesso (in quanto
composizione) dovrebbe soddisfare la propriet P .7
Riassumendo: per dimostrare che una propriet vale per tutti gli elementi di un insieme
costruito in modo induttivo suciente dimostrare che la propriet vale per un elemento
qualsiasi tutte le volte che essa vale per tutti i suoi componenti.

2.4

Sistemi di inferenza

I sistemi di inferenza costituiscono una notazione descrittiva e intuitiva per le definizioni


induttive di insiemi (o relazioni).
Un sistema di inferenza formato da un insieme di regole di inferenza. Una regola di
inferenza, a sua volta, formata da un insieme (o, meglio, una n-pla) di premesse (p1 , . . . , pn )
e da una conclusione q. Una regola viene scritta come
p1 , , pn
q
oppure come (p1 , . . . , pn )/q.
Sia le premesse che le conclusioni sono (nel nostro contesto) predicati della forma
t2X
dove t un termine che pu avere delle variabili libere ed X linsieme che stiamo definendo.
Talvolta le conclusioni e le premesse vengono scritte omettendo la parte 2 X.
Una regola va intesa come una implicazione: se le premesse sono vere per certi valori delle
variabili libere, allora la conclusione vera per gli stessi valori delle variabili libere.
Una regola che ha un insieme di premesse vuoto viene detta assioma e viene scritta come
q
oppure come ;/q.
Chiariamo le idee con qualche esempio.
Esempio 2.25. Consideriamo il seguente insieme di regole:
k2N

Esse possono essere tradotte in

02N

k+12N

7
La dimostrazione formale richiederebbe di definire rigorosamente i costruttori per cui la omettiamo: lidea
comunque resta quella esposta.

36

Capitolo 2 Nozioni preliminari


a) 0 2 N ,
b) k 2 N =) k + 1 2 N .

e il loro scopo quello di definire N come il pi piccolo insieme che soddisfa a) e b).
Una regola pu avere delle condizioni collaterali per poter essere applicata. Le condizioni
collaterali vengono scritte accanto alla regola.
Esempio 2.26. Consideriamo la definizione dellinsieme Lists(N) della Sezione 2.3.2;
utilizzando le regole di inferenza essa diventa:
1. [ ] 2 Lists(N)
2.

l 2 Lists(N)

n :: l 2 Lists(N)

n2N

Esempio 2.27. Il sistema di regole:


k 2 Q, h 2 Q

k2Q

02Q

k+12Q

k/h 2 Q

h 6= 0

un modo di descrivere linsieme Q di tutte le frazioni maggiori o uguali a 0.


Unistanza di una regola il risultato della sostituzione, in una regola, delle variabili libere
con valori specifici. Anche le istanze vengono scritte con la stessa notazione usata per le regole.
Per esempio,
3 2 Q, 4 2 Q
3/4 2 Q

unistanza dellultima regola dellesempio precedente.


Dato un insieme R di regole e un insieme R di istanze di tali regole, una R-derivazione D
di y :
unistanza ;/y 2 R di un assioma di R, oppure
una scrittura della forma (D1 , . . . , Dn )/y dove D1 , . . . , Dn sono R-derivazioni di
x1 , . . . , xn con (x1 , . . . , xn )/y 2 R.8
Scriveremo D
;/y

y per indicare che D una R-derivazione di y, ossia scriviamo

y se ;/y 2 R,

(D1 , . . . , Dn )/y
8

y se (x1 , . . . , xn )/y 2 R e Di

xi .

Si osservi che linsieme delle R-derivazioni un insieme definito per induzione.

37

2.4 Sistemi di inferenza

Diremo anche che y deriva dallinsieme di istanze R, e scriveremo, R y, se esiste una Rderivazione D di y. Quando non rilevante, o quando chiaro dal contesto, si omette di
specificare linsieme R delle istanze usato in una derivazione.
Le derivazioni (anche dette dimostrazioni) vengono rappresentate in maniera naturale
come alberi.
Esempio 2.28. Consideriamo il sistema di regole

02Q

k 2 Q, h 2 Q

k2Q

k/h 2 Q

k+12Q

h 6= 0

La seguente una derivazione, rappresentata con un albero, di 1/2 2 Q


02Q

02Q 12Q
12Q 22Q
1/2 2 Q

Esempio 2.29. Sia DIV la pi piccola relazione binaria R che soddisfa le seguenti due
regole:
1.
2.

nR0

n2N

nRk
n R n+k

n, k 2 N

Allora,
3 DIV 0
3 DIV 3
3 DIV 6

(assioma 1)
(regola 2)
(regola 2)

una derivazione di 3 DIV 6.


Abbiamo anche, per esempio, che non esiste una derivazione di 3 DIV 4 poich cercando
di applicare unistanza della regola 2 per provarlo otteniamo che per farlo ci serve dimostrare
3 DIV 1 ma 3 DIV 1 non istanza dellassioma 1 e non pu essere generato sfruttando la 2.

2.4.1

Induzione sulle derivazioni

Definiamo, ricorsivamente, la profondit (o lunghezza) di una derivazione nel modo seguente:


la profondit di una derivazione della forma ;/y 0,
la profondit di una derivazione della forma (D1 , . . . , Dn )/y il massimo delle profondit
delle derivazioni D1 , . . . , Dn incrementato di 1.

38

Capitolo 2 Nozioni preliminari

Se D e D0 sono R-derivazioni diremo che D0 una sottoderivazione diretta di D, e scriveremo


D0 1 D, se D della forma (D1 , . . . , Dn )/y e D0 coincide con uno dei Di . Indicata con la
chiusura transitiva di 1 , diremo che D0 una sottoderivazione di D se D0 D.
Teorema 2.30 (Principio di induzione sulle derivazioni). Sia R un insieme di regole e sia R
un insieme di istanze di regole in R. Sia P una propriet delle derivazioni, allora
vale per ogni R-derivazione D

P (D)
se e solo se
P (D0 ) per ogni D0

D =) P (D)

vale per ogni R-derivazione D.

Dimostrazione. Dimostriamo solo la parte se poich laltra ovvia. Supponiamo per assurdo
che la propriet P non valga per tutte le R-derivazioni e sia D una R-derivazione di profondit
minima tra quelle per cui la propriet non vale.
La derivazione D non pu avere profondit 0 perch in tal caso D non avrebbe sottoderivazioni e quindi per ipotesi avremmo che P (D) vale. Supponiamo allora che D sia della
forma (D1 , . . . , Dn )/y. Poich D1 , . . . , Dn hanno profondit minore di D, abbiamo, per la
minimalit di D, che P (D1 ), . . . , P (Dn ) valgono, ma allora per ipotesi P (D) vale e questo
contraddice lipotesi che P (D) non vale.

2.4.2

Induzione sulle regole

Vi anche un principio di induzione sulle regole. Tale principio utile per dimostrare che
una propriet vera per tutti gli elementi che appartengono ad un insieme definito tramite
regole. Lidea che se una propriet preservata nel passaggio dalle premesse alla conclusione
di tutte le istanze di regole usate in una derivazione, allora la propriet resta valida anche per
la conclusione della derivazione.
Sia R un insieme di regole e sia X il pi piccolo insieme che le soddisfa. Dato un insieme
R di istanze di regole, di interesse considerare linsieme delle conclusioni che si possono
derivare usando tali istanze, pi precisamente poniamo
I(R) =

x:

x .

Si osservi che I(R) X (stiamo identificando una conclusione della forma x 2 X con
lelemento x).
Teorema 2.31 (Principio di induzione sulle regole). Sia R un insieme di istanze di regole e
sia P una propriet. Allora
P (x)
se e solo se
P (x1 ), . . . , P (xn ) =) P (x)

vale per ogni x 2 I(R)


vale per ogni (x1 , . . . , xn )/x 2 R con xi 2 I(R).

Dimostrazione. Dimostreremo la parte se, laltra ovvia. Procediamo per induzione sulla
profondit dellalbero di derivazione. Sia x 2 I(R) e sia D una R-derivazione di x. Se D
della forma ;/x (ossia D ha altezza 0) allora ;/x 2 R e quindi per ipotesi P (x) vale. Se
invece D della forma (D1 , . . . , Dn )/x dove D1 , . . . , Dn sono R-derivazioni di x1 , . . . , xn con
(x1 , . . . , xn )/x 2 R, allora, per induzione, P (x1 ), . . . , P (xn ) valgono e quindi, per ipotesi,
P (x) vale.

39

2.5 Contesti e congruenze

Vogliamo adesso mostrare che linsieme I(R) soddisfa una propriet di chiusura rispetto
alle istanze in R. Poniamo a questo scopo la seguente definizione.
Definizione 2.32. Sia R un insieme di istanze di regole. Un insieme Q si dice chiuso rispetto
a R, o semplicemente R-chiuso, se per ogni (x1 , . . . , xn )/x 2 R si ha
x1 , . . . , xn 2 Q =) x 2 Q.
In altre parole, un insieme Q R-chiuso se ogni volta che le premesse di unistanza in
R appartengono a Q anche la conclusione vi appartiene. In particolare, un insieme R-chiuso
deve contenere tutte le conclusioni delle istanze degli assiomi in R.
Dimostriamo ora che I(R) il minimo insieme chiuso rispetto ad R.
Proposizione 2.33. Sia R un insieme di istanze di regole. Allora
1. I(R) R-chiuso,
2. se Q un insieme R-chiuso allora I(R) Q.
Dimostrazione. (1.) Sia (x1 , . . . , xn )/x 2 R con xi 2 I(R). Dobbiamo provare che x 2 I(R).
Per definizione di I(R) esistono D1 , . . . , Dn tali che Di R xi per ogni i. Ne segue che
(D1 , . . . , Dn )/x una R-derivazione di x, cio x 2 I(R).
(2.) suciente considerare la propriet P (x), definita per x 2 I(R), e data da x 2 Q,
cio P (x) = {x 2 Q|x 2 I(R)} ed applicare il Teorema 2.31.
Il risultato precedente pu essere usato quando si deve provare che una propriet vale per
ogni elemento di I(R), infatti sar suciente provare che linsieme Q degli elementi per cui
la propriet vale R-chiuso per ottenere che I(R) Q e quindi che la propriet vale in tutto
I(R).
Finora abbiamo immaginato che un insieme di regole servisse a definire un unico insieme.
Nulla impedisce di generalizzare il meccanismo e considerare definizioni mutuamente ricorsive
di insiemi.
Esempio 2.34. Si considerino le regole
k2P

02P

12D

k+12D

k2D

k+12P

Esse definiscono simultaneamente linsieme P dei numeri pari e linsieme D dei numeri dispari.
Vedremo che la definizione simultanea di pi insiemi molto frequente quando si ha a che
fare con la definizione di categorie sintattiche di grammatiche.

2.5

Contesti e congruenze

Un insieme definito per induzione tramite costruttori (si veda la Sezione 2.3.2) pu essere esteso per mezzo dellaggiunta di altri costruttori. In questa sezione descriviamo una particolare
costruzione di cui avremo bisogno in seguito.

40

Capitolo 2 Nozioni preliminari

Sia X un insieme definito per induzione tramite una famiglia di costruttori. Sia c0 il
costruttore senza argomenti che rende la scrittura formale [ ]9 . Posto 0 = [ {c0 }, definiamo
X[ ] come il pi piccolo insieme chiuso rispetto ai costruttori di 0 . Gli elementi di X[ ] saranno
detti contesti di X.
Esempio 2.35. Abbiamo visto che linsieme Trees(N) degli alberi con foglie in N pu essere
definito per induzione tramite costruttori (si veda Sezione 2.3.2). Aggiungendo il costruttore
c0 che rende lelemento [ ], le regole diventano
a. [ ] 2 X,
b. n 2 X per ogni n 2 N,
c. t1 , . . . , tk 2 X implica (t1 , . . . , tk ) 2 X, per ogni k 2 N,

Il pi piccolo insieme che soddisfa tali regole linsieme Trees(N)[ ] dei contesti degli alberi
con foglie in N. Gli elementi di Trees(N)[ ] sono oggetti del tipo (1, ([ ], 3), (5, [ ], (8))), ossia
alberi le cui foglie sono elementi di N o lelemento speciale [ ].
Gli elementi di X[ ] vengono scritti nella forma c[ ] per indicare che possono avere al loro
interno dei buchi ossia, delle occorrenze di [ ]. Un elemento c[ ] 2 X[ ] pu essere visto come
una funzione da X in X, infatti dato x 2 X indichiamo con c[x] lelemento di X ottenuto
rimpiazzando in c[ ] ogni occorrenza del buco [ ] con x.
Tornando allesempio degli alberi, se

1
3

[]

[]
8

c[ ] = (1, ([ ], 3), (5, [ ], (8))) =


e

t = (2, 7) = 2

allora

1
3
c[t] = c[(2, 7)] = (1, ((2, 7), 3), (5, (2, 7), (8))) = 2

5
2

In seguito avremo bisogno delle seguenti definizioni.


Definizione 2.36 (Sostitutivit). Sia R una relazione binaria su un insieme X costruito per
induzione tramite costruttori. Si dice che R sostitutiva rispetto ai contesti di X se per ogni
contesto c[ ] 2 X[ ] e per ogni x, x0 2 X si ha che
x R x0 =) c[x] R c[x0 ].
9

Non si confonda questa notazione con quella usata per indicare la lista vuota.

41

2.6 Esercizi

Definizione 2.37 (Congruenza e precongruenza). Sia X un insieme definito per induzione tramite costruttori. Una congruenza su X una relazione di equivalenza su X che sia
sostitutiva rispetto ai contesti di X.
Una precongruenza su X una relazione di preordine su X che sia sostitutiva rispetto ai
contesti di X.

2.6

Esercizi

2.1 Data la relazione binaria


su N definita da a
b se b = a + 1, se ne determini la chiusura
riflessiva, quella transitiva, e quella riflessiva e transitiva.
2.2 Siano R A B e S, T B C relazioni. Si provi che
1. (R S)

=S

2. R (S [ T ) = R S [ R T ;

3. R (S \ T ) R S \ R T e che non vale necessariamente il viceversa.


2.3 Sia X un insieme e P una propriet definita sui sottoinsiemi di X. La propriet P si dice chiusa
per intersezioni se
1. P (X) vale,
2. se P (Yi ) vale per certi Yi X allora P (\i2I Yi ) vale.
Si dimostri che le propriet di riflessivit, simmetria e transitivit sono chiuse per intersezioni.
In altre parole: dato un insieme A, linsieme A A una relazione riflessiva su A e se R ed S
sono relazioni riflessive su A anche R \ S lo (ed analogamente per le altre propriet).

2.4 Sia X un insieme e P una propriet definita sui sottoinsiemi di X. La propriet P si dice chiusa
per unioni se
1. P (;) vale,
2. se P (Yi ) vale per certi Yi X allora P ([i2I Yi ) vale.
Si dimostri che la propriet di simmetria chiusa per unioni mentre la transitivit e la riflessivit
non lo sono.
2.5 Sia P una propriet definita sui sottoinsiemi di un certo insieme X e assumiamo che P sia
chiusa per intersezioni (vedere Esercizio 2.3). Se Y X, si definisce chiusura di Y rispetto alla
propriet P il sottoinsieme Y di X tale che
1. Y Y ,
2. P (Y ) vale,
3. se Z Y e P (Z) allora Z Y .
ossia il pi piccolo sottoinsieme di X tale che P (Y ) vale e Y Y . Si dimostri che risulta
\
Y =
Z.
P (Z), ZY

2.6 Sia P una propriet definita sui sottoinsiemi di un certo insieme X e assumiamo che P sia chiusa
per unioni (vedere Esercizio 2.4). Se Y X, si definisce nucleo di Y rispetto alla propriet P
il sottoinsieme Y di X tale che

42

Capitolo 2 Nozioni preliminari


1. Y Y ,
2. P (Y ) vale,
3. se Z Y e P (Z) allora Z Y .

ossia il pi grande sottoinsieme di X tale che P (Y ) vale e Y Y . Si dimostri che risulta


[
Y =
Z.
P (Z), ZY

2.7 Sia R una relazione binaria su A.


1. Si provi che la chiusura riflessiva di R coincide con la relazione
R [ IdA
dove IdA = {(x, x) : x 2 A}.

2. Si provi che la chiusura simmetrica di R coincide con la relazione


R[R

3. Si provi che la chiusura transitiva di R coincide con la relazione


{(x, y) : 9x1 , . . . , xn con xi R xi+1 per 1 i n

1, x1 = x e xn = y}.

2.8 Si provi che il nucleo simmetrico di un preordine una relazione di equivalenza.


2.9 Sia una relazione di equivalenza su un insieme A e sia R una relazione binaria su A. Si dice
relazione indotta da R sul quoziente A/ la relazione
R/ = { (X, Y ) 2 (A/ ) (A/ ) : 9x 2 X, y 2 Y tali che xRy } .
Ossia, due classi sono in relazione secondo R/ se esiste un elemento x della prima classe che
in relazione R con un elemento y della seconda classe.
1. Provare che se R riflessiva allora R/ riflessiva.

2. Provare che se R transitiva ed R allora R/ transitiva.


2.10 Sia R un preordine su un insieme A. Detto KR il nucleo simmetrico di R e indicata con R/KR la
relazione indotta (vedere Esercizio 2.9) si provi che R/KR una relazione dordine su A/KR .
Pn
2.11 Si dimostri per induzione che i=0 i2 = n(n+1)(2n+1)
.
6
2.12 Si dimostri, mimando la dimostrazione del principio di induzione matematica, il principio di
induzione matematica completa.

2.13 Formalizzare e provare la validit dellinduzione strutturale mutua, che consente la


dimostrazione simultanea di diverse propriet per diverse categorie sintattiche.

Capitolo 3

Sintassi e modelli semantici

SOMMARIO
Questo capitolo introduce gli strumenti per definire la sintassi e la semantica operazionale dei
linguaggi che studieremo in seguito. Cominceremo con i concetti riguardanti grammatiche
e sintassi, concreta e astratta. Quindi introdurremo gli automi a stati finiti, i sistemi di
transizioni etichettate e le strutture di Kripke, che risulteranno fondamentali per definire la
semantica operazionale di vari linguaggi. In particolare, studieremo i linguaggi come insiemi
di termini ben formati, le grammatiche come strumenti per generare tali insiemi e i sistemi di
transizioni come strumenti per definire la semantica operazionale. Concludiamo il capitolo
con un esempio che illustra sintassi e semantica operazionale delle espressioni aritmetiche.

3.1

Grammatiche

In questa sezione daremo la definizione formale di grammatica1 e di linguaggio da essa generato


ed introdurremo brevemente la classificazione delle grammatiche in base alla forma delle loro
produzioni.
Sia A un insieme finito non vuoto di simboli, detto alfabeto. Si indica con A linsieme di
tutte le possibili sequenze finite di simboli, dette stringhe, costruite sullalfabeto A, inclusa
la stringa vuota, che viene denotata dal simbolo ". Un linguaggio L su A un qualsiasi
sottoinsieme di A . Si definisce lunghezza di una stringa w, e la si denota con |w|, il numero
di simboli che la compongono; cos se w = a1 . . . an , allora |w| = n, in particolare |"| = 0.
Inoltre, se w = a1 . . . an e z = b1 . . . bm sono due stringhe, la loro concatenazione, denotata
con wz, la stringa ottenuta giustapponendo w e z, ossia
wz = a1 . . . an b1 . . . bm .
La concatenazione di una qualsiasi stringa con " la stringa stessa.
Il concetto di grammatica, pi precisamente di grammatica generativo-trasformazionale,
uno sviluppo delle ricerche condotte dal linguista americano Noam Chomsky (1928-) a
partire dagli anni 50 del secolo scorso. Il suo fine fondamentale quello di pervenire ad una
descrizione formale delle regole che, in singole lingue storico-naturali, consentono la produzione
di tutte le frasi che i parlanti considerano corrette e rendono possibile lindividuazione di quelle
1
(Diz.) Grammatica: studio degli elementi costitutivi di una lingua, dal greco grammatike techne, ossia
arte (techne) dello scritto (gramma).

44

Capitolo 3 Sintassi e modelli semantici

che non sono ritenute tali. Unimportante applicazione delle grammatiche la specifica della
sintassi dei linguaggi di programmazione: le grammatiche costituiscono, infatti, una notazione
concisa per descrivere la sintassi di un tipico linguaggio di programmazione.
Definizione 3.1 (Grammatica). Una grammatica una quadrupla G , hA, V, S, P i dove:
1. A un alfabeto i cui simboli sono detti terminali,
2. V un alfabeto, i cui simboli sono detti nonterminali, e V \ A = ;,
3. S 2 V un simbolo nonterminale, detto simbolo iniziale,
4. P (A [ V ) (A [ V ) un insieme di coppie, dette produzioni, tali che se (u, v) 2 P
allora u contiene almeno un simbolo nonterminale.
Una produzione (u, v) viene generalmente scritta u ! v o anche u ::= v. Per comodit,
se diverse produzioni hanno lo stesso membro sinistro, esse possono essere raggruppate in
ununica produzione il cui membro destro costituito dalla sequenza dei membri destri delle
produzioni originarie, separati dal simbolo | . Cos, se (u, v1 ), (u, v2 ), . . . , (u, vn ) 2 P , si scrive
u ! v1 | v2 | . . . | vn
o anche
u ::= v1 | v2 | . . . | vn .
Questo modo di rappresentare un insieme di produzioni detto forma di Backus-Naur,
abbreviato in BNF.
Per convenzione, useremo lettere minuscole o sequenze di lettere minuscole per indicare
i terminali della grammatica e lettere maiuscole o stringhe inizianti con la lettera maiuscola
per indicare i nonterminali. Questo permetter di presentare una grammatica fornendo solo
linsieme delle produzioni della grammatica stessa: i simboli terminali e non terminali saranno
riconoscibili grazie alla suddetta convenzione mentre si assumer che il simbolo iniziale sia il
primo simbolo nonterminale del membro sinistro della prima produzione.
Inoltre talvolta aggiungeremo dei pedici alle varie occorrenze di uno stesso nonterminale
per poterle distinguere e nominare.
Il seguente un esempio di grammatica:
P ::= aD | "
D ::= aP
Per poter definire il linguaggio generato da una grammatica abbiamo bisogno di specificare
formalmente il meccanismo di riscrittura di una stringa in unaltra. Le prossime due definizioni
sono dedicate a questo scopo.
Definizione 3.2. Sia G , hA, V, S, P i una grammatica, e siano y, z 2 (A [ V ) .
1. Scriviamo y ! z, e diciamo che z deriva direttamente (o in un passo) da y, se z
pu essere ottenuta da y rimpiazzando in y unoccorrenza del membro sinistro di una
produzione con il membro destro di tale produzione.

45

3.1 Grammatiche

2. Indichiamo con ! la chiusura riflessiva e transitiva di !, e diciamo che z deriva da y

se y ! z, ossia se z pu essere ottenuta da y tramite una sequenza finita (eventualmente


vuota) di derivazioni dirette.
Considerando la grammatica dellesempio precedente, abbiamo per esempio
P ! aD ! aaP ! aa
e quindi

P ! aa

Definizione 3.3. Sia G , hA, V, S, P i una grammatica. Il linguaggio generato da G, indicato


con L(G) linsieme di tutte le stringhe derivabili da S costituite solo da simboli terminali,
ossia
n
o

L(G) , w | w 2 A tale che S ! w .

Vediamo, grazie ad un paio di esempi, che tipo di ragionamento utilizzare per dimostrare
che un dato linguaggio generato da una data grammatica.
Esempio 3.4. Sia G1 la grammatica le cui produzioni sono
S ::= ab

aSb.

Vogliamo far vedere che L(G1 ) = L1 dove L1 , {an bn |n

1}.

Cominciamo col dimostrare che L1 L(G1 ), cio che una stringa an bn con n
1
qualsiasi pu essere generata da G1 . A questo proposito basta esibire una derivazione
per an bn a partire da S, come ad esempio la seguente:

S ! aSb ! aaSbb ! an

Sbn

! a n bn

dove tutte le derivazioni utilizzano la prima produzione in G1 , esclusa lultima che


utilizza la seconda produzione.
Dimostriamo ora che stringhe che non sono del tipo an bn non possono essere generate
da G1 . Infatti, allo scopo di ottenere una stringa che non sia del tipo an bn dobbiamo cominciare con la prima produzione (la seconda produrrebbe direttamente ab); dopodich
dovremmo continuare ad applicare la stessa produzione perch altrimenti otterremmo
aabb e questo ragionamento vale anche per i passi successivi. In pratica non c modo
di produrre in un numero finito di passi una stringa di terminali che non sia della forma
a n bn .
Esempio 3.5. Consideriamo di nuovo la grammatica G con le seguenti produzioni
P ::= aD | "
D ::= aP
Lasciamo come esercizio la prova del fatto che il linguaggio generato da G costituito da tutte
le stringhe di lunghezza pari sullalfabeto composto dal solo simbolo a, ossia
L(G) = w | w 2 {a} tale che |w| pari .
Si potrebbe anche dimostrare che se si considera D come simbolo iniziale, allora il linguaggio
generato costituito da tutte le stringhe di lunghezza dispari sullalfabeto composto dal solo
simbolo a.

46

Capitolo 3 Sintassi e modelli semantici

La forma generale delle produzioni insuciente per definire completamente i linguaggi


naturali (da cui lo studio di Chomsky ha preso spunto) con tutte le loro innumerevoli sottigliezze ed daltro canto troppo generale per essere impiegata nella definizione dei linguaggi di
programmazione (nella teoria dei linguaggi formali si dimostra infatti che i linguaggi generati
dalle grammatiche generali non sono decidibili). Da qui lidea di imporre delle restrizioni sulla forma delle produzioni di una grammatica in modo da ottenere varie sottoclassi di
grammatiche. Cominciamo a discutere alcune di queste sottoclassi. Poi organizzeremo le
sottoclassi in una gerarchia (quella di Chomsky, appunto).
Una grammatica G dipendente da contesto se tutte le sue produzioni sono del tipo:
1. yU z ! ywz, con U 2 V , y, z 2 (V [ A) e w 2 (V [ A)+ , oppure
2. S ! ", a patto che S non compaia nella parte destra di nessuna produzione.
Un linguaggio generato da una grammatica dipendente da contesto detto anchesso
dipendente da contesto.
Notiamo che la clausola (1) ci dice, informalmente, che il simbolo U pu essere rimpiazzato
da w a patto che appaia nel contesto y_z. La clausola (2) ci dice invece che la stringa vuota
" pu essere generata solo allinizio di una derivazione (dato che il simbolo iniziale S non pu
comparire nel lato destro di alcuna produzione). Poich lanalisi sintattica di questi linguaggi
pu richiedere lesame di una vasta porzione del contesto ogni volta che si deve scegliere una
produzione da applicare, linguaggi di programmazione dipendenti da contesto presentano in
genere notevoli dicolt di traduzione.
Imponiamo allora vincoli ancora pi restrittivi sulle produzioni di una grammatica.
Otteniamo cos la sottoclasse costituita dalle grammatiche libere dal contesto.
Una grammatica si dice libera dal contesto, o semplicemente libera, se ogni sua produzione
ha il membro sinistro costituito da un solo nonterminale, ossia della forma
U ! w,
con w 2 (A [ V ) e U 2 V . Un linguaggio generato da una grammatica libera dal contesto
detto anchesso libero dal contesto, o semplicemente libero.
Da un punto di vista strettamente formale non ogni grammatica libera dipendente da
contesto; le prime possono infatti contenere produzioni del tipo U ! " (con U 6= S) che non
sono permesse invece nel caso delle grammatiche dipendenti da contesto. Tuttavia, si pu
dimostrare che ogni linguaggio libero anche dipendente da contesto, nel senso che esiste una
grammatica dipendente da contesto che lo genera.
Le applicazioni delle grammatiche libere sono estremamente importanti; per esempio, diversamente da quanto accade per le grammatiche dipendenti dal contesto, le grammatiche
libere non richiedono lesame del contesto circostante per scegliere una produzione da applicare, quindi vengono spesso usate nella descrizione formale della sintassi dei linguaggi di
programmazione.
Le derivazioni ottenute da questo tipo di grammatiche possono essere rappresentate
tramite alberi etichettati, chiamati alberi di derivazione, aventi le seguenti caratteristiche:
1. la radice etichettata con il simbolo iniziale della grammatica,
2. ogni nodo interno dellalbero etichettato con un simbolo non terminale,

47

3.1 Grammatiche
S
A
a

S
A

B
b

B
b

Figura 3.1: Un albero di derivazione


3. se un nodo interno etichettato con A ed i suoi immediati discendenti sono etichettati con A1 , . . . , Ak , allora la grammatica possiede una produzione della forma
A ! A1 . . . Ak ,
4. ogni foglia dellalbero etichettata con un simbolo terminale oppure con ".
Leggendo le foglie di un albero di derivazione da sinistra a destra (e saltando le foglie
etichettate con ") si ottiene una stringa del linguaggio generato dalla grammatica.

La Figura 3.1 illustra lalbero di derivazione di S ! acbb per la grammatica


S ::= ASB | c
A ::= aA | "
B ::= bB | "
Si osservi come lo stesso albero possa rappresentare diverse derivazioni, che dieriscono luna
dallaltra per lordine di applicazione delle produzioni. Per esempio, le derivazioni
S ! ASB ! aASB ! aSB ! aSbB ! aSbbB ! aSbb ! acbb
S ! ASB ! AcB ! AcbB ! AcbbB ! Acbb ! aAcbb ! acbb

sono rappresentate dallo stesso albero.


La struttura di un albero di derivazione essenziale per assegnare un significato alle
stringhe di un linguaggio. Essa permette di individuare univocamente le componenti di una
stringa e quindi di determinare lordine in cui esse vanno interpretate. Linsieme degli alberi
di derivazione di tutte le stringhe prodotte da una grammatica si indica con T (G).
Le grammatiche che permettono di derivare una stringa tramite due alberi diversi sono
dette ambigue. La grammatica
S ::= aS | Sb | "

ambigua infatti gli alberi mostrati in Figura 3.2 sono due alberi distinti per la derivazione

S ! ab.
Si noti comunque che gi la grammatica
S ::= ASB | c
A ::= aA | "
B ::= bB | "

48

Capitolo 3 Sintassi e modelli semantici


S
a

S
S

S
S

b
S

Figura 3.2: Due alberi di derivazione per la derivazione S ! ab


ambigua. Ecco un altro albero di derivazione per la stringa acbb.
S
A

S
A

B
b

Si osservi che non esiste una relazione fra lambiguit di una grammatica ed il fatto che
un albero di derivazione possa essere il risultato di diverse sequenze di derivazioni.
I linguaggi generati dai simboli non terminali di una grammatica libera dal contesto possono essere visti come una famiglia di insiemi definiti in maniera mutuamente ricorsiva per
mezzo di regole, dove le regole sono date dalle produzioni della grammatica. Vale quindi per
le grammatiche il principio di induzione strutturale che nello specifico viene talvolta detto
principio di induzione sui termini . Vediamo un esempio.
Esempio 3.6. Data la grammatica
E ::= a | E1 + E2 | (E)
dove i pedici, come detto, servono a dare un nome alle diverse occorrenze del nonterminale
E, proviamo, per induzione sulla struttura2 di E, che tutti gli elementi di L(E) hanno un
numero uguale di parentesi sinistre e destre.
Caso a. Questo caso banale, non essendoci alcuna parentesi nel terminale a.
Caso E1 + E2 . Per ipotesi induttiva abbiamo che E1 ed E2 hanno un numero uguale di
parentesi destre e sinistre, diciamo n per E1 , ed m per E2 . Abbiamo che E1 + E2 ha
m + n parentesi sinistre ed m + n parentesi destre.
Caso (E). Per lipotesi induttiva E ha lo stesso numero di parentesi sinistre e destre, diciamo
n; chiaramente (E) ha n + 1 parentesi sinistre e destre.
2

Le produzioni della grammatica possono essere viste come costruttori. Per ogni simbolo terminale a
abbiamo il costruttore di ariet 0 che rende a, abbiamo poi il costruttore di ariet 2 che presi e1 ed e2 rende
la scrittura formale e1 + e2 ed infine il costruttore di ariet 1 che preso e rende la scrittura formale (e).

49

3.1 Grammatiche
Introduciamo ora lultima classe di grammatiche.
Una grammatica si dice regolare se le sue produzioni sono della forma
U ! aT

oppure

U !b

oppure

U ! ",

con a, b 2 A e U, T 2 V . Un linguaggio generato da una grammatica regolare detto anchesso


regolare.
Le grammatiche di questo tipo sono dette regolari poich possono essere analizzate da
automi con un numero finito di stati. Molte propriet interessanti, come ad esempio stabilire se
una grammatica genera un linguaggio non vuoto o se una data stringa appartiene al linguaggio
generato da una grammatica, sono decidibili nel caso delle grammatiche regolari. Pertanto
queste grammatiche sono spesso usate nei linguaggi di programmazione, in particolare per
modellare i token e le parole chiave del linguaggio.
Abbiamo cos definito 4 classi di grammatiche: quelle generali (nessuna restrizione sulla
forma delle produzioni), quelle dipendenti da contesto, quelle libere e quelle regolari. Le 4
classi vengono a volte indicate con una terminologia dierente: si parla di grammatiche di
tipo 0 per quelle generali, di tipo 1 per quelle dipendenti da contesto, di tipo 2 per quelle
libere e di tipo 3 per quelle regolari. La classe dei linguaggi generati dalle grammatiche di
tipo i viene detta anchessa di tipo i ed indicata con Li , per i = 0, 1, 2, 3.
La teoria dei linguaggi formali ci dice che le 4 classi di linguaggi sono contenute luna
nellaltra in questo ordine:
L 3 L2 L1 L0 .
Si noti che le inclusioni sono strette, infatti per ogni i = 0, 1, 2 esiste un linguaggio Li tale
che Li 2 Li e Li 62 Li+1 . Dunque le 4 classi di linguaggi formano una gerarchia, la cosiddetta
gerarchia di Chomsky. Il seguente diagramma riassume le relazioni di inclusione tra le varie
classi.
L0

L1

L2

L3

Ad esempio, il linguaggio
L1 , {an bn |n

1}

libero dal contesto. Infatti, abbiamo gi visto che L1 generato dalla grammatica libera G1
data da
S ::= ab aSb.
Tuttavia L1 non regolare: infatti L3 coincide con la classe dei linguaggi riconosciuti dagli
automi a stati finiti e un tale automa, se deve riconoscere an bn con n arbitrariamente grande,
allora non pu non riconoscere anche am bn con m 6= n. Quindi L3 L2 .
Consideriamo ora il linguaggio
L2 , {an bn cn |n

1} .

Si pu dimostrare che L2 2 L1 , ma tuttavia L2 62 L2 , quindi L2 L1 .

50

Capitolo 3 Sintassi e modelli semantici

3.2

Sintassi concreta e sintassi astratta

Un linguaggio di programmazione3 in prima approssimazione costituito da due parti: una


sintassi e una semantica. La sintassi4 ha lo scopo di definire quali sono le frasi (corrette)
del linguaggio. La semantica5 ha lo scopo di attribuire un significato esatto alle frasi del
linguaggio.
Il modo migliore per definire la semantica denotazionale di un linguaggio di programmazione quello di attribuire un significato a tutti i programmi partendo dalla grammatica che
li genera. Alcune volte per la definizione completa della sintassi del linguaggio in questione,
che chiameremo sintassi concreta, lunga e noiosa e contiene dettagli che rendono dicile
la definizione di funzioni di interpretazione semantica semplici e chiare. Esistono cio alcuni
aspetti dei linguaggi di programmazione che poco hanno a che fare con il significato intrinseco
dei programmi. Si pensi ad esempio alle precedenze tra i diversi operatori presenti nel linguaggio, oppure al diverso modo di associare o raggruppare sequenze di comandi, cosicch con
la sintassi concreta del linguaggio si costretti a considerare contemporaneamente (e quindi
a dierenziarne la generazione) frasi come le seguenti:
(3 + 4) 5
while p do (c1 ; c2 )

e
e

3 + (4 5),
(while p do c1 ); c2

La sintassi concreta deve tenere conto di questi aspetti e per far questo appesantita da
notazioni estranee al significato dei singoli costrutti.
Quando si interessati alle caratteristiche semantiche di un linguaggio risulta utile pertanto ricorrere a varianti sintattiche che sono note come sintassi astratta. Tali varianti permettono
di astrarre da molti dettagli di rappresentazione delle frasi del linguaggio e di concentrarsi
solo sulla struttura dei programmi, cio su come questi possono essere composti a partire da
frasi pi elementari. Il procedimento di determinazione della sintassi astratta di un linguaggio
consiste in una semplificazione delle produzioni che porta ad unaltra grammatica, generalmente ambigua, i cui alberi di generazione possono essere messi in corrispondenza con quelli
del linguaggio originario. La sintassi astratta pu essere ottenuta dalla sintassi concreta, ad
esempio, identificando alcune frasi, ignorando delle parentesi oppure ridenominando dei simboli. In questo modo viene stabilita una corrispondenza tra gli alberi ottenuti come risultato
dellanalizzatore sintattico (alberi di derivazione) ed i programmi ottenuti tramite la sintassi
astratta (programmi astratti). In pratica, in una sintassi astratta viene considerato solo ci
che rilevante ai fini della semantica, specificando quindi per ogni costrutto sintattico solo:
1. la categoria sintattica del costrutto,
2. la costruzione sintattica applicata.
Quindi, analizzando pi in dettaglio un linguaggio di programmazione, risulta utile
distinguere quattro componenti fondamentali:
3
Contrariamente a quanto normalmente si crede, le dizioni linguaggio e linguaggio di programmazione
denotano entit molto distinte.
4
(Diz.) Sintassi: studio dei procedimenti attraverso i quali le parole di una frase sono collegate le une alle
altre, dal greco syn (insieme) e taxis (ordine).
5
(Diz.) Semantica: Studio del significato delle parole e delle frasi, dal greco sema (segno). Si pensi anche
alla parola semaforo dal greco sema phoros (che porta il segnale).

51

3.2 Sintassi concreta e sintassi astratta


Sintassi
concreta

Frasi del linguaggio


concreto

def inisce

?
y P arser
Sintassi
astratta

def inisce

Alberi di sintassi
astratta
?
y Esecuzione

Semantica

def inisce

Significato degli
alberi

Frase (concreta):
2 (3 + 4)
#
Albero della
sintassi astratta:
*
+

2
3

Significato (valore):
14

Tabella 3.1: Sintassi concreta e sintassi astratta


Una grammatica Gc , che genera linsieme L(Gc ) delle stringhe (corrette) del linguaggio
di programmazione. Linsieme L(Gc ) costituito dalle stringhe di caratteri che i programmatori possono scrivere e pu pertanto essere chiamato linguaggio concreto. La
sintassi definita dalla grammatica Gc detta sintassi concreta.
Una grammatica Ga , che d luogo ad una sintassi, detta sintassi astratta, che definisce
linsieme T (Ga ) degli alberi del linguaggio di programmazione. La sintassi astratta
prescinde da qualunque problema di rappresentazione degli alberi tramite sequenze di
caratteri, e rende la struttura dei termini associati agli alberi assolutamente ovvia.
Un parser (o analizzatore sintattico), che ad ogni stringa del linguaggio concreto associa
(passando attraverso un albero di derivazione della sintassi concreta) un albero della
sintassi astratta. Durante il parsing, varie convenzioni quali precedenze degli operatori,
associativit ed uso delle parentesi, vengono tenute in conto per produrre lalbero della
sintassi astratta associato a una frase del linguaggio.
Una semantica, che ha lo scopo di attribuire un significato esatto ad ogni albero della
sintassi astratta. importante sottolineare il fatto che la semantica non attribuisce
significato alle frasi del linguaggio concreto ma agli alberi astratti che queste rappresentano. In altre parole, il nucleo del linguaggio di programmazione costituito dalla
sintassi per gli alberi astratti e dalla semantica a questi associata.
Il problema di rappresentare gli alberi della sintassi astratta con sequenze lineari di caratteri gestito dalla sintassi concreta e dal parser ed del tutto ininfluente ai fini della
semantica (si veda anche la Tabella 3.1). per questo che nel resto di queste note, essendo
noi interessati alla semantica dei linguaggi, quando introdurremo nuovi formalismi o nuovi
linguaggi, definiremo sempre la loro sintassi astratta, mai quella concreta; questultima potr
essere derivata, nel caso ce ne sia bisogno, imponendo ulteriore struttura alla sintassi astratta.

52

Capitolo 3 Sintassi e modelli semantici

E
T
P
N
D

::=
::=
::=
::=
::=

E+T | E T | T
T P | T /P | P
N | (E)
DN | D
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9

(espressioni)
(termini)
(espressioni primarie)
(numeri)
(cifre)

(Gc )

Tabella 3.2: Sintassi concreta delle espressioni aritmetiche


Gli approcci pi usati per definire la semantica di un linguaggio di programmazione saranno esemplificati nella Sezione 4.5 usando il linguaggio delle espressioni regolari come caso
di studio.

3.3

Espressioni aritmetiche

In questa sezione chiariremo meglio i concetti di grammatica, sintassi concreta e sintassi


astratta usando come esempio il linguaggio delle espressioni aritmetiche.
La sintassi concreta data dalla grammatica (Gc ) in Tabella 3.2. Le produzioni della
grammatica (Gc ) possono essere considerate una descrizione formale della struttura delle
espressioni aritmetiche. Daltra parte, le stesse possono essere viste come regole di riscrittura
che permettono di generare espressioni aritmetiche. In questo senso, esse stabiliscono le
possibili evoluzioni delle stringhe che contengono i simboli E, T , P , N e D. Per esempio,
lultima produzione stabilisce che se abbiamo una stringa (vale a dire una sequenza finita
di simboli) w che contiene unoccorrenza del simbolo D, possiamo trasformare (riscrivere)
w rimpiazzando tale occorrenza di D con uno qualunque dei caratteri 0, 1, . . . , 9. In realt
questo un modo compatto di indicare dieci regole diverse.
Si osservi anche che le regole considerate presentano due diversi tipi di simboli: i simboli E,
T , P , N e D sono coinvolti nelle riscritture, mentre gli altri simboli, cio 0, 1, . . . , 9, +, , , /,
una volta introdotti nella stringa durante un passo della derivazione, non possono mai essere
riscritti. Inoltre, la stringa finale non contiene alcuna occorrenza di E, T , P , N oppure D.
In tal senso i simboli E, T , P , N e D vengono detti simboli nonterminali oppure variabili;
i restanti sono detti simboli terminali. Questi ultimi compongono dunque le parole del linguaggio che le regole date intendono generare. I simboli nonterminali invece rappresentano le
diverse categorie sintattiche presenti nelle regole descritte, vale a dire le espressioni, i termini,
le espressioni primarie, i numeri e le cifre. Pi precisamente, ogni riscrittura che parta rispettivamente dal simbolo E, T , P , N oppure D genera, nel momento in cui tutti i nonterminali
siano stati riscritti, unespressione, un termine, unespressione primaria, un numero oppure
una cifra, rispettivamente.
La grammatica (Gc ) contiene un certo numero di informazioni, ad esempio sulle precedenze
tra gli operatori e sulluso delle parentesi, che sono certo importanti per far si che ogni frase
sia interpretata in modo univoco (abbia cio un unico albero sintattico) ma che non sono
rilevanti per definire la semantica una volta nota la struttura della frase. Se ora astraiamo da
tali informazioni, possiamo intuitivamente descrivere la struttura di unespressione aritmetica
nel modo seguente:
0, 1, . . . , 9 sono cifre;

53

3.3 Espressioni aritmetiche


E

::=

n | E+E | E

E | E E | E/E

(Ga )

Tabella 3.3: Sintassi astratta delle espressioni aritmetiche (n rappresenta un numero)


ogni cifra un numero;
se N un numero e D una cifra, allora N D un numero;
ogni numero unespressione aritmetica;
se E unespressione aritmetica e N un numero, allora anche
E + N, E

N, E N, E/N

sono espressioni aritmetiche.


Questa definizione fornisce immediatamente una nuova grammatica per generare le espressioni
aritmetiche sintatticamente corrette:
E ::= N | E + N | E N | E N | E/N
N ::= N D | D
D ::= 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
Consideriamo il seguente esempio di generazione, dove i simboli che vengono rimpiazzati
sono sottolineati ad ogni passo mentre quelli che vanno a sostituirli sono sopralineati al passo
successivo.
E!E + N !E N + N !E N + D
! E D + D!E D + 1!E 6 + 1!N 6 + 1
! N D 6 + 1 ! N 5 6 + 1 ! D5 6 + 1 ! 25 6 + 1
Possiamo dire allora che la stringa finale dellesempio precedente deriva (in pi passi) da E e
scrivere

E ! 25 6 + 1.
Facciamo ora un altro passo di astrazione da quella che la rappresentazione sequenziale delle espressioni. Per cogliere invece la natura gerarchica delle espressioni aritmetiche
suciente la grammatica mostrata in Tabella 3.3.
La grammatica (Ga ) definisce infatti la sintassi astratta delle espressioni aritmetiche.
importante sottolineare che questa grammatica viene usata per generare gli alberi del linguaggio e non le frasi del linguaggio. Se venisse usata per generare stringhe allora tale grammatica
risulterebbe ovviamente ambigua (per esempio 2 3 + 4 ammetterebbe due alberi di derivazione). Si osservi anche che la definizione di sintassi astratta non fornice informazioni sulla
struttura dei numeri: compito del parser riconoscere un numero ed assegnargli un valore
semantico.
Di fronte alla frase 2(3+4) generata dalla grammatica Gc compito del parser ricostruire
lalbero di derivazione

54

Capitolo 3 Sintassi e modelli semantici


E
T
T

ed associare a tale albero il giusto albero della sintassi astratta, che nello specifico risulta
essere
E
*

E
E

spesso disegnato anche come


*
2

+
3

La semantica provveder poi ad attribuire un significato a questultimo albero. Lo schema


della Tabella 3.1 riassume la situazione.

3.4

Automi

Ricordiamo brevemente la definizione ed il funzionamento degli automi6 a stati finiti.


Gli automi a stati finiti sono definiti nel modo seguente.
6
(Diz.) Automa: macchina che ha in s i principi del proprio movimento, dal greco autos (da solo)
composto con una radice che significa memoria.

55

3.4 Automi
on

spento

acceso
ba

o
ng

bang

rotto
Figura 3.3: Un automa a stati finiti
Definizione 3.7. Un automa a stati finiti M descritto da una quintupla
M = hQ, A, !, q0 , F i
dove:
Q un insieme finito detto insieme degli stati,
A un insieme finito detto alfabeto di input,
! Q(A[{"})Q una relazione ternaria detta relazione di transizione; scriveremo

q ! q 0 per indicare che (q, , q 0 ) 2!,


q0 2 Q uno stato speciale detto stato iniziale,

F Q un insieme di stati detti stati finali o stati di accettazione.


Gli automi a stati finiti hanno una semplice e chiara rappresentazione grafica (come
illustrato in Figura 3.3):
Uno stato viene rappresentato da un ovale che racchiude il nome dello stato stesso.

Una transizione q ! q 0 dellautoma viene rappresentata collegando lovale che rappresenta lo stato q con quello che rappresenta q 0 tramite un arco orientato dal primo stato
al secondo ed etichettato con il simbolo .
Lo stato iniziale viene indicato con una freccia entrante che non proviene da nessun
altro stato.
Ogni stato finale viene indicato con un ovale che ha un bordo doppio.
La semplice forma delle produzioni delle grammatiche regolari consente di metterle in
corrispondenza, in maniera naturale, con gli automi a stati finiti. Data una grammatica
regolare G = (A, V, S, P ), il corrispondente automa a stati finiti
MG = hQ, A, !, S, {qf }i
dove
Q = V [ {qf } linsieme degli stati (e coincide con linsieme dei simboli nonterminali
della grammatica unito con un nuovo stato qf ),
A lalfabeto (e coincide con quello della grammatica),
! Q (A [ {"}) Q la relazione di transizione ed definita da: A
b

(A ::= aB) 2 P e A ! qf se (A ::= b) 2 P (con b 2 A [ {"}).

S lo stato iniziale (e coincide con il simbolo iniziale della grammatica),

! B se

56

Capitolo 3 Sintassi e modelli semantici


qf uno stato extra che rappresenta lunico stato finale.

La grammatica associata allautoma della Figura 3.3 data da


S ::= on A | bang
A ::= o S | bang
(dove S rappresenta lo stato spento e A lo stato acceso).
Gli automi possono essere usati anche come strumenti per specificare sequenze lecite di azioni; ad esempio lautoma in Figura 3.3, riconosce come corretta la sequenza
on o on o bang.
In generale, il comportamento dellautoma M su una stringa w 2 A pu essere descritto
nel modo seguente: M parte nello stato iniziale e scandisce il simbolo pi a sinistra di w. Sulla
base dello stato corrente e del simbolo scandito, lautoma passa in un nuovo stato secondo
quanto descritto dalla relazione di transizione. Il passaggio ad un nuovo stato avviene solo se
c una transizione che lo prevede. Se non vi sono transizioni possibili lautoma si blocca e
rifiuta la stringa w. Dopo ogni transizione, viene esaminato il prossimo simbolo della stringa
di ingresso e viene valutata la possibilit di eseguire una nuova transizione. Questo processo
va avanti fino a quando la stringa w stata completamente scandita. A questo punto lautoma
si trover in uno stato q. Se lo stato q uno degli stati finali dellautoma, cio se q 2 F , allora
la stringa w viene accettata, altrimenti viene rifiutata.
Un automa si dice nondeterministico se esiste uno stato da cui escono due archi con
la stessa etichetta. Formalizziamo lidea di accettazione di una stringa in modo da gestire
correttamente anche il nondeterminismo e le transizioni etichettate con ".
Per far ci, a partire dalla relazione di transizione ! che fin troppo dettagliata, definiamo
la seguente relazione pi astratta:
"

=
) =
a

"
! ,
"

"

=
) = =
) !=
) per a 2 A,
s

1
n
=
) = =)
=)
dove s 2 A ed s = a1 an con ai 2 A,

dove la giustapposizione di frecce rappresenta la composizione delle relazioni e indica la


chiusura riflessiva e transitiva di una relazione (si veda la Definizione 2.5). In altre parole se s
s
una stringa, q =
) q 0 significa che possibile transire dallo stato q allo stato q 0 attraverso una
sequenza di stati intermedi, eseguendo le transizioni indicate da s eventualmente intercalate
da sequenze di ".
Definizione 3.8 (Linguaggio riconosciuto da un automa). Si dice linguaggio riconosciuto da
un automa M = hQ, A, !, q0 , F i linsieme
w

L(M ) = {w 2 A : esiste q 2 F tale che q0 =) q }


un risultato noto, e semplice da dimostrare, il fatto che lautoma associato ad una
grammatica regolare riconosce il linguaggio generato dalla grammatica stessa.

57

3.5 Sistemi di transizioni etichettate e strutture di Kripke

3.5

Sistemi di transizioni etichettate e strutture di Kripke

Introduciamo in questa sezione i sistemi di transizioni etichettate (abbreviato in LTS, Labelled


Transition Systems) che, come vedremo, giocheranno un ruolo fondamentale nel seguito di
queste note per descrivere la semantica operazionale dei linguaggi che via via prenderemo in
considerazione.7
I sistemi8 di transizioni etichettate possono essere considerati una generalizzazione degli
automi a stati finiti. Un sistema di transizioni infatti pu non avere uno stato iniziale, pu
non avere degli stati finali e pu essere costituito da un numero infinito di stati. Mentre gli
automi sono adatti a descrivere levoluzione di un sistema da uno stato iniziale a uno stato
finale, i sistemi di transizioni risulteranno utili a descrivere il comportamento e linterazione
di sistemi concorrenti (i quali possono evolvere nel tempo senza che vi sia un concetto di stato
finale).
Definizione 3.9. Un sistema di transizioni etichettate S una quadrupla
S = hQ, A, !, q0 i
dove:
Q un insieme i cui elementi sono detti configurazioni o stati,
A un insieme finito di simboli detti azioni,
! Q A Q una relazione ternaria detta relazione di transizione; scriveremo
a
q ! q 0 per indicare che (q, a, q 0 ) 2! e diremo che q pu fare lazione a ed andare in
q0,
q0 2 Q uno stato speciale detto stato iniziale.
Lo stato iniziale viene spesso omesso, per cui in tali casi il sistema di transizioni pu essere
considerato una terna.9
Introduciamo adesso alcune convenzioni e notazioni riguardanti i sistemi di transizioni.
Definizione 3.10. Sia S , hQ, A, !i un sistema di transizioni. Un cammino (o
computazione) a partire da q0 2 Q una sequenza (finita o infinita) della forma
(q0 , a0 , q1 ) (q1 , a1 , q2 ) (q2 , a2 , q3 ) . . .
tale che (qi , ai , qi+1 ) 2! per ogni i.
Per i
0, denoteremo con [i] il suo
i + 1-esimo stato e con i il cammino da [i] che susso di (cio il cammino (qi , a0 , qi+1 ) (qi+1 , a1 , qi+2 ) (qi+2 , a2 , qi+3 ) . . .). Indicheremo con P aths(q) linsieme dei
cammini che iniziano dallo stato q.
s

Per ogni sequenza di azioni s 2 A , definiamo la relazione ! nel modo seguente:


7

Storicamente i sistemi di transizioni etichettate furono introdotti da Keller (1976) come un modello formale per descrivere programmi paralleli. In seguito (Plotkin, 1979) sono stati usati per dare una semantica
operazionale ai linguaggi di programmazione.
8
(Diz.) Sistema: Aggregato di parti che dipendono le une dalle altre secondo leggi e regole fisse e che
tendono a un medesimo fine, dal greco syn (insieme) e stema (collocare).
9
In letteratura si trovano a volte definizioni leggermente dierenti. Alcuni autori definiscono gli LTS
includendo anche un insieme di stati finali.

58

Capitolo 3 Sintassi e modelli semantici


q2
rk
wo

q0

pla
y

q3

pla
y

q4

rk
wo

q1

Figura 3.4: Grafo delle transizioni di un LTS


"

"

! = IdQ , ossia poniamo q ! q per ogni q 2 Q;


s

! =

a1

an

! , se s = a1 an con ai 2 A.

Se q ! q 0 diremo che q 0 una s-derivata di q.


I sistemi di transizioni il cui insieme di stati e transizioni finito, possono essere presentati
esplicitamente con un grafo orientato etichettato (come nel caso degli automi), detto grafo
delle transizioni. Quando invece linsieme degli stati infinito i sistemi di transizioni sono
presentati per mezzo di sistemi di inferenza (si veda la Sezione 2.4).
Esempio 3.11. [Bill-Ben] A titolo desempio, vediamo adesso un LTS (con 5 stati, 3 azioni
e 5 transizioni):
S = hQ, A, !i

dove:

Q = { q0 , q1 , q2 , q3 , q4 },
A = { play, work, },

! = { (q0 , play, q1 ), (q0 , work, q2 ), (q1 , work, q3 ), (q2 , play, q3 ), (q3 , , q4 ) }


Il grafo delle transizioni in Figura 3.4 una possibile rappresentazione dellLTS.
Vi una classe di sistemi di transizioni a cui saremo particolarmente interessati, si tratta
dei sistemi di transizioni con azione invisibile.
Un sistema di transizioni con azione invisibile un sistema di transizioni hQ, Act , !i il
cui insieme di azioni Act contiene una speciale azione denotata con e detta azione invisibile
(o interna): quindi Act della forma Act [ { }.
A partire dalla relazione ! definiamo ora una nuova relazione di transizione ) che tratta
lazione invisibile in maniera speciale.

"

"
=
) = ! , se q =
) q 0 si scrive anche q ) q 0 ,

"

"

=
) = =
) !=
) , se 2 Act ,
s

=
) = =) =) , se s = 1 n con i 2 Act .
s

In altre parole se s una stringa, q =


) q 0 significa che possibile andare da q in q 0 attraverso
una sequenza di stati intermedi, eseguendo le azioni indicate da s, eventualmente intercalate
s
da sequenze di azioni . Se q =
) q 0 diremo che q 0 un s-discendente di q.

59

3.5 Sistemi di transizioni etichettate e strutture di Kripke

Nel seguito useremo , , . . . come generici elementi di Act, come generico elemento di
Act e s come generica sequenza finita di azioni.
In alcuni casi potremmo essere interessati soltanto alla capacit da parte di uno stato di
eettuare unazione od una sequenza di azioni, indipendentemente dallo stato raggiunto, ed
useremo le seguenti notazioni:

q ! , se esiste q 0 tale che q ! q 0 ;

q 6 ! , se non esiste q 0 tale che q ! q 0 .


s

Le notazioni q ! , q 6 ! , q =
) , q=
6),q=
) e q=
6 ) hanno significati simili. Uno stato q si

dice stabile se q 6 ! .
Useremo infine la seguente notazione

se 6= ,

=
"
se = .
Esempio 3.12. [Bill-Ben] Riprendiamo lEsempio 3.11, dove le azioni visibili sono play e
work, e lazione invisibile . Alcune derivazioni possibili sono le seguenti:
q0

play

work

! q3

q1

work

! ! q4

q2

play

! ! q4

Tre possibili discendenze sono:


play

q2 ==) q4

work

q1 ===) q4

q3 =
) q4

Strutture di Kripke. Le strutture di Kripke sono dei sistemi in cui vengono etichettati gli
stati invece degli archi. La definizione formale di una struttura di Kripke la seguente.
Definizione 3.13. Una struttura di Kripke (KS) una quadrupla hQ, !, AP, Ii, dove
Q linsieme delle stati (o configurazioni),

! Q Q una relazione binaria (non etichettata) che determina quando possibile


transire da uno stato a un altro,
AP linsieme delle etichette (ad esempio, le etichette sono proposizioni atomiche),
I : Q ! Pow(AP ) una funzione, detta funzione di interpretazione, che ad ogni stato
assegna un insieme di etichette, ossia un sottoinsieme di AP .
Da un punto di vista grafico una KS pu essere rappresentata da un grafo avente un
nodo per ogni stato del sistema e un arco per ogni elemento della relazione !, cosicch
a hq1 , q2 i 2! corrisponder un arco che parte dal nodo q1 e arriva in q2 . La funzione I
rappresenta unetichettatura che associa ad ogni nodo le proposizioni atomiche che sono valide
nello stato corrispondente.

60

Capitolo 3 Sintassi e modelli semantici

Definizione 3.14. Sia K , hQ, !, AP, I i una struttura di Kripke. Un cammino da uno
stato q0 2 Q una sequenza (finita o infinita) di stati della forma
q 0 , q 1 , q2 , q3 . . .
tale che qi ! qi+1 per ogni i 0. Per i 0, denoteremo con [i] il suo i + 1-esimo stato e con
i il cammino da [i] che susso di (cio il cammino qi qi+1 qi+2 qi+3 . . .). Indicheremo
con P aths(q) linsieme dei cammini che cominciano dallo stato q.
Nel seguito, le KS saranno principalmente utilizzate nel Capitolo 13 come modelli di interpretazione di alcune logiche temporali. In tale contesto, si assume solitamente che qualsiasi
KS hQ, !, AP, Ii soddisfa la seguente propriet
8q 2 Q, 9q 0 2 Q tale che q ! q 0 ,
cio ogni stato ha almeno un successore, quindi i cammini in una tale struttura sono infiniti.
Definizione 3.15. Per ogni KS K , hQ, !, AP, I i e per ogni stato q0 2 Q c un albero
delle computazioni infinito con radice q0 tale che hq, q 0 i un arco dellalbero se e soltanto se
q ! q 0 . Tale albero ottenuto dispiegando la KS a partire da q0 .
Si osservi che gli alberi delle computazioni sono alberi i cui nodi sono etichettati da insiemi
di proposizioni atomiche. Un albero definito nella maniera usuale. Ha ununica radice e
ogni nodo qn pu essere raggiunto dalla radice tramite un unico cammino. Se !+ indica la
chiusura transitiva di !, hq1 , q2 i 2!+ verificata se q1 un nodo che si trova nellunico
cammino che va dalla radice al nodo q2 .

3.6

Semantica operazionale delle espressioni aritmetiche

In questa sezione, usiamo i sistemi di transizioni per definire una semantica operazionale per
le espressioni aritmetiche la cui sintassi astratta data dalla grammatica (Ga ) mostrata in
Tabella 3.3.
Il significato intuitivo di unespressione un numero. Diamo le regole per calcolare questo
numero definendo un sistema di transizioni10 i cui stati sono le espressioni generate dalla
grammatica in Tabella 3.3. Si noti, tra laltro, che alcuni degli stati del sistema sono finali,
nel senso che non hanno transizioni uscenti; tali stati corrispondono ai numeri. La relazione
di transizione definita tramite un sistema di regole di inferenza come la pi piccola relazione
che soddisfa gli assiomi e le regole in Tabella 3.4, dove op varia sullinsieme degli operatori
aritmetici; il sistema di inferenza quindi composto da dodici regole, ottenute istanziando op.
Una transizione quindi possibile (pu essere dedotta) se e solo se essa provabile tramite
le regole di inferenza della Tabella 3.4. La regola (op) stabilisce che lespressione m op n si
trasforma in k allorquando lapplicazione delloperazione op agli argomenti m ed n produce
come risultato k. Questa lunica regola che coinvolge eettivamente gli operatori aritmetici.
Le altre due regole consentono di ridurre ad un numero gli argomenti di un operatore. In
particolare, (redl) permette di eettuare un passo della trasformazione delloperando sinistro,
10

Si noti che i sistemi di transizioni usati in questa sezione non fanno uso di etichette. Intuitivamente, ci si
spiega col fatto che le transizioni corrispondono in ogni caso ad azioni interne, per le quali non necessario
pubblicare alcuna informazione visibile (che il ruolo tipicamente ricoperto dalle etichette delle transizioni).

61

3.6 Semantica operazionale delle espressioni aritmetiche

m op n ! k

(m op n = k)

(op)

E1 ! E10
E1 op E2 ! E10 op E2

(redl)

E2 ! E20
E1 op E2 ! E1 op E20

(redr)

Tabella 3.4: Semantica di computazione delle espressioni aritmetiche


(redr) permette di trasformare loperando destro. Il sistema di inferenza non stabilisce alcun
ordine nellapplicazione delle regole (redl) e (redr). Questo non comunque rilevante, perch
la valutazione di una qualunque espressione aritmetica fornisce sempre lo stesso risultato
indipendentemente dalla sequenza di applicazione delle regole.
La valutazione di unespressione aritmetica, ad esempio 4 + 7 3/6 1 comporta una
sequenza di transizioni. importante notare che le regole della semantica operazionale della
Tabella 3.4 sono date a partire dalla sintassi astratta delle espressioni aritmetiche e perci
per applicarle abbiamo bisogno di vedere lespressione da valutare non come una sequenza di
simboli, ma come un albero di parsing, ad esempio
/
+

4
7

che, utilizzando le parentesi, possiamo rappresentare con la stringa (4 + (7 3))/(6


Lespressione fornisce un risultato in quattro passi:
(4 + (7 3))/(6

1) ! (4 + 21)/(6

1) ! 25/(6

1) ! 25/5 ! 5.

La prima transizione viene derivata come segue


(7 3 = 21) (op)
7 3 ! 21
(redr)
4 + (7 3) ! 4 + 21
(redl)
(4 + (7 3))/(6 1) ! (4 + 21)/(6 1)
La seconda transizione viene derivata come segue
(4 + 21 = 25) (op)
4 + 21 ! 25
(redl)
(4 + 21)/(6 1) ! 25/(6 1)
La terza transizione viene derivata come segue
6
25/(6

(6 1 = 5) (op)
1 !5
(redr)
1) ! 25/5

1).

62

Capitolo 3 Sintassi e modelli semantici


m

!
!m

E1

!
! m1 E2 !
! m2
(m1 op m2 = k)
E1 op E2 !
!k

Tabella 3.5: Semantica di valutazione delle espressioni aritmetiche


La quarta transizione una banale applicazione di unistanza della prima regola della
semantica operazionale.
La semantica appena descritta fin troppo dettagliata. Essa non solo fornisce il risultato
della valutazione di unespressione, ma descrive anche il procedimento seguito per ottenerlo.
Per questo motivo chiamata semantica di computazione. Talvolta pu non essere necessario
conoscere esattamente la sequenza dei passi che ha portato ad associare un valore ad unespressione. In questi casi viene utilizzato un approccio leggermente diverso, detto semantica
di valutazione, attraverso il quale si raggiunge tale valore con una sola transizione. Il nuovo sistema di transizioni ha gli stessi stati del precedente, cio le espressioni generate dalla
grammatica in Tabella 3.3, e per relazione di transizione la pi piccola relazione che soddisfa
gli assiomi e le regole in Tabella 3.5. Per esempio, la transizione
(4 + (7 3))/(6

1)

!
!5

viene derivata nel modo seguente:


4

7 !
!7 3 !
! 3 (7 3 = 21)
!
!4
73 !
! 21 (4 + 21 = 25)
6
4 + (7 3) !
! 25
(4 + (7 3))/(6 1) !
!5

!
!6
6 1

1 !
! 1 (6 1 = 5)
!
!5
(25/5 = 5)

Si potrebbe facilmente dimostrare lequivalenza tra la semantica di computazione e la


semantica di valutazione, cio che, per ogni espressione aritmetica E, vale

E ! n se e solo se E

3.7

!
! n.

Esercizi

3.1 Data la grammatica G con le seguenti produzioni


P ::= aD | "
D ::= aP
si provi che il linguaggio generato da G
L(G) = w | w 2 {a} tale che |w| pari .
3.2 Data la grammatica dellesercizio precedente si disegni lautoma associato a tale grammatica.
3.3 Si dimostri che la grammatica
S ::= SaS | SbS | "

ambigua ossia che esistono frasi del linguaggio da essa generato che ammettono due alberi di
derivazione.

63

3.7 Esercizi

3.4 Dimostrare che tutti gli elementi del linguaggio generato dalla grammatica dellesempio 2.4.4
hanno pi a che +.
3.5 Data la grammatica
S ::= aT | "
T ::= aSS
dimostrare che essa genera solo stringhe di lunghezza pari.
3.6 Data la grammatica
S
T

::= aB
::= aSS

"

dimostrare che essa genera solo stringhe di lunghezza pari.


3.7 Definire una grammatica che generi il seguente linguaggio
L , an bn |n

1} [ {an b2n |n

3.8 Dimostrare che linsieme di tutte le stringhe formate da x, y e z che contengono un numero
dispari di x, un numero dispari di y ed un numero pari di z un linguaggio regolare sullalfabeto
{x, y, z}.
3.9 Dimostrare che il linguaggio L , {xr y s z t |s = r + t} libero (Suggerimento: si consideri la
grammatica per il linguaggio {an bn |n 1}).
3.10 Scrivere una grammatica dipendente da contesto per il linguaggio L , {an ban can |n

1}.

3.11 Dimostrare per induzione strutturale che ogni stringa generata dalla grammatica
S ::= aSbS | bSaS | "
appartiene al linguaggio
L = {w | w 2 {a, b} e w contiene tante a quante b}.
Dimostrare, per induzione sulla lunghezza delle parole, che la grammatica data genera
esattamente il linguaggio L.
3.12 La grammatica
E ::= n | E + E | (E) (E)
genera le espressioni aritmetiche con gli operatori di somma e moltiplicazione, in cui la moltiplicazione ha precedenza sulla somma. Si determini la corrispondente sintassi astratta e si
discutano le ragioni per cui lambiguit di questultima non crea problemi nella valutazione
delle espressioni.
3.13 Data la grammatica dellesercizio precedente, scrivere gli alberi di derivazione, concreti ed
astratti, per le espressioni:
1. (4 + 14) (3);

2. ((7) (0)) (6);

3. ((7) (0)) (6 + 8).

64

Capitolo 3 Sintassi e modelli semantici

3.14 Fornire lespressione, derivante dalla sintassi concreta dellesercizio 5, che ha il seguente albero
di derivazione:
*
*
1

+
12

5.

3.15 Dimostrare che, per ogni espressione aritmetica E, vale

E ! n se e solo se E

!
! n.

3.16 Provare che, per ogni espressione aritmetica E descritta nella Sezione 3.3,
E ! E1 , E ! E2 implica E1

!
! n, E2

!
! n.

Capitolo 4

Sintassi e denotazioni

SOMMARIO
Questo capitolo introduce alcune nozioni e definizioni preliminari di semantica denotazionale
e le illustra tramite due esempi di descrizione semantica di semplici formalismi. Cominciamo
col chiarire la dierenza fra notazioni sintattiche e denotazioni semantiche. Quindi, come
primo esempio presentiamo la semantica denotazionale di una semplice calcolatrice tascabile
e come secondo quella delle espressioni regolari. Vedremo che il principio di induzione strutturale uno strumento fondamentale per definire la semantica denotazionale e dimostrare
propriet dei linguaggi generati tramite grammatiche. Nel caso delle espressioni regolari mostreremo anche come definire semantiche coerenti usando lapproccio operazionale e quello
assiomatico.

4.1

Notazioni sintattiche e denotazioni semantiche

Vogliamo ora chiarire come bisogna procedere per definire la semantica di un programma
scritto, ovviamente, in sintassi concreta utilizzando le funzioni di interpretazione semantica
che sono invece definite a partire dalla sintassi astratta del linguaggio stesso. Il procedimento
consiste di tre passi:
1. si usa la sintassi concreta per definire le frasi del linguaggio concreto e quindi lalbero
di parsing del programma;
2. si usa la corrispondenza tra sintassi concreta e sintassi astratta per ottenere lalbero
astratto;
3. si usano le funzioni di interpretazione semantica per definire il significato degli alberi
astratti.
Qualcosa di simile in realt stato gi fatto in Sezione 3.6 per definire la semantica
operazionale delle espressioni aritmetiche, dove per il punto 3. rimpiazzato come segue
30 . si usa un sistema di transizioni etichettato per definire il significato degli alberi astratti.
Per quanto riguarda il punto 3. necessario:
1. stabilire la natura degli oggetti matematici che si intendono usare come denotazioni,

66

Capitolo 4 Sintassi e denotazioni


2. stabilire la natura delle funzioni di interpretazione semantica, ricordando che
funzione di
DOMINIO SINTATTICO
DOMINIO SEMANTICO
interpretazione
e definire le funzioni di interpretazione semantica per induzione sulla sintassi astratta
dei termini.

Il primo problema sar discusso nel Capitolo 6. Il secondo problema si risolve definendo
funzioni di interpretazione tra i termini generati dalla sintassi astratta e gli opportuni domini semantici. Per fare un esempio concreto, se la sintassi del linguaggio prevede quattro
domini sintattici, e cio Programmi, Dichiarazioni, Espressioni e Comandi, avremo un modello semantico costituito da quattro domini semantici e quattro funzioni di interpretazione
semantica, ciascuna da un dominio sintattico al corrispondente dominio semantico. Queste
ultime sono definite per induzione strutturale sulla sintassi dei programmi. Quindi, ad ogni
produzione della grammatica che definisce il linguaggio corrisponder un caso della definizione della funzione di interpretazione semantica, che avr la stessa struttura ricorsiva della
corrispondente produzione. Per esempio, i linguaggi di programmazione hanno solitamente
una produzione che stabilisce che un comando pu essere ottenuto mettendo in sequenza due
comandi qualsiasi:
C ::= | C; C | . . . ;
una clausola della funzione di interpretazione semantica dei comandi avr allora la forma:
C[[C1 ; C2 ]] = C[[C1 ]] C[[C2 ]],
in modo che alloperatore sintattico ; corrisponda loperatore semantico . Questo esempio
mette in luce due propriet essenziali dellapproccio denotazionale:
1. in corrispondenza ad ogni operatore sintattico (nel nostro esempio ;) viene definito un
operatore semantico (nel nostro esempio );
2. la semantica di un comando composto definita ricorsivamente in termini della semantica dei comandi che la compongono, cos come la sintassi della sequenza di comandi
definita ricorsivamente in base alla sintassi dei comandi stessi.
La seconda propriet descritta sopra va anche sotto il nome di composizionalit con cui si
intende che il significato di un termine composto costruito in base al significato dei termini
che lo compongono.
A titolo esemplificativo, per evidenziare le caratteristiche fondamentali delle funzioni di
interpretazione semantica, definiamo qui di seguito una semantica denotazionale dei numeri
binari in termini di numeri decimali. Relativamente a tale esempio, la Tabella 4.1 mostra le
tre componenti fondamentali di una definizione denotazionale:
1. il dominio sintattico: il linguaggio dei numeri binari;
2. il dominio semantico: i naturali;
3. la funzione di interpretazione semantica, che ad ogni numero binario associa un naturale.

4.1 Notazioni sintattiche e denotazioni semantiche

Dominio Sintattico:
Grammatica:
Dominio Semantico:
Operazioni:
Funzione di Interpretazione
Semantica:

67

Sintassi
Bin
B ::= 0 | 1 | B 0 | B 1
Semantica
N = {zero, uno, due, . . . }
pi`
u, per : N N ! N
M[[0]]
= zero
M[[1]]
= uno
M[[B 0]] = (M[[B]] per due) pi`
u M[[0]]
M[[B 1]] = (M[[B]] per due) pi`
u M[[1]]

Tabella 4.1: Semantica denotazionale dei numeri binari

Nella funzione di interpretazione semantica descritta in Tabella 4.1 abbiamo utilizzato le


stringhe zero, uno, due per rappresentare i numeri, che usualmente vengono indicati con le
cifre 0, 1, 2, per meglio rimarcare la dierenza fra sintassi (101) e semantica (cinque).
Per evidenziare ulteriormente la dierenza fra notazioni sintattiche e denotazioni semantiche, arontiamo il problema di assegnare un significato a sequenze di cifre decimali. Consideriamo la grammatica (Ga ) per le espressioni aritmetiche mostrata in Tabella 3.3, a pagina 53.
Indichiamo con Num linsieme di tutte le stringhe generate da tale grammatica a partire
da N (in pratica, prendiamo N come simbolo iniziale). La funzione di interpretazione, che
chiamiamo N , associa ad una stringa di cifre un numero decimale, N : Num ! N. In modo
perfettamente analogo a quanto visto in Tabella 4.1, ma moltiplicando per dieci invece che
per due, otterremo linterpretazione di sequenze di cifre decimali. Ad esempio avremo che
N [[152]] = (((uno per dieci) pi`
u cinque) per dieci) pi`
u due.
Ovviamente, il mantenere esplicita la dierenza fra la sintassi e la semantica nel caso dei
numeri naturali comporterebbe un notevole appesantimento notazionale, che peraltro risulterebbe inutile. Nel seguito, con abuso di notazione, utilizzeremo gli elementi di Num anche
per rappresentare gli elementi di N. In eetti, senza dubbio il lettore portato ad interpretare la sequenza 152 come il numero naturale centocinquantadue. Considerazioni analoghe
porteranno spesso ad utilizzare lo stesso simbolo per indicare la sintassi e la semantica degli
operatori sui naturali.
Riprendiamo ora lesame dellinterpretazione dei numeri binari in termini dei naturali,
per capire come procedere in modo composizionale alla determinazione della semantica di
un termine costruito tramite una BNF, considerando il modo in cui viene determinato il
significato di un numero binario, per esempio 101, tramite la funzione di interpretazione
M[[]]. La rappresentazione lineare non evidenzia come dividere il numero, di cui si vuol dare
la semantica, in sottoparti. allora la sintassi che ci dice esattamente come fare.
Siccome un numero binario definito come la concatenazione di un numero binario e di
una cifra binaria, abbiamo:
M[[101]] = M[[10]] composto con M[[1]]
e quindi

M[[101]] = (M[[10]] per due) pi`


u M[[1]] (M[[10]] 2) + M[[1]];

68

Capitolo 4 Sintassi e denotazioni

continuando abbiamo
(((M[[1]] 2) + M[[0]]) 2) + M[[1]] = ((1 2) + 0) 2) + 1 = 5.
Lesempio riportato sopra segue un approccio top-down per cui lespressione ottenuta sulla
destra dell= pu essere semplificata solo quando, a seguito di successive riscritture, si arriva
a dover interpretare il solo simbolo iniziale del numero binario originario. Alternativamente,
possibile seguire un approccio bottom-up che, nel caso del numero 101, consiste nel determinare prima il valore di tutte le sue sottostringhe, cio 1 e 10, e quindi di utilizzarle per
definire il significato dellintera stringa. In questo caso la sequenza 101 sarebbe valutata nel
modo seguente:
M[[1]] = 1
M[[10]] = (M[[1]] 2) + M[[0]] = 2
M[[101]] = (M[[10]] 2) + M[[1]] = 5.
Chiaramente la scelta di un approccio o dellaltro dipende dai gusti di chi specifica; bisogna comunque dire che lapproccio bottom-up ha il vantaggio di garantire che la lunghezza
delle formule intermedie che si originano nel processo di valutazione semantica non cresca
proporzionalmente al termine che si sta specificando: in generale questo fatto garantisce una
maggiore leggibilit.

4.2

Una calcolatrice tascabile

Per introdurre il lettore alla metodologia propria dello studio dei linguaggi di programmazione,
consideriamo il linguaggio che deve essere usato per servirsi di una semplice calcolatrice tascabile, la cui interfaccia rappresentata in Figura 4.1. Si noti che il linguaggio delle espressioni
aritmetiche introdotto in Sezione 3.3 parte del linguaggio della calcolatrice tascabile.
Lunica dicolt nella descrizione del comportamento della calcolatrice data dalla disponibilit di tasti per la memorizzazione di risultati intermedi; daltra parte questa la
caratteristica che rende il suo linguaggio simile ad un linguaggio di programmazione reale (e
lo dierenzia da quello delle espressioni aritmetiche).
La calcolatrice permette di eettuare le quattro operazioni ed fornita di un visore e
di una cella di memoria, di quattro tasti-comandi tramite i quali possibile modificare il
contenuto della memoria (MC, MR, M-, M+) e di un altro tasto-comando che permette di
rimediare a situazioni di errore e di azzerare il contenuto della cella di memoria (CE/C).
Rispetto al modo standard di interagire con la calcolatrice, che consiste nel premere tasti
in una qualsiasi sequenza, noi porremo delle restrizioni e chiederemo che i suoi programmi
seguano un particolare protocollo.
Sebbene sia fisicamente possibile premere il tasto + subito dopo quello
, premere lo
stesso tasto operazione un numero qualsiasi di volte oppure premere un qualsiasi tasto prima
di aver acceso la calcolatrice, noi lo vieteremo imponendo alcune restrizioni nella definizione
dei programmi accettabili dalla calcolatrice. Potremo allora parlare di sequenze di comandi
ben formati (corretti) ed ignorare tutti i comandi non corretti sintatticamente.
La nostra sintassi richiede che tutti i programmi comincino con laccensione della macchina
(On) e prevede che essi consistano di una sequenza di espressioni aritmetiche separate dal
simbolo uguale (per determinare risultati intermedi), inframmezzate da comandi che servono

69

4.2 Una calcolatrice tascabile

On

Off

MC

MR

M-

CE
C

M+

Figura 4.1: Una calcolatrice tascabile


a modificare il contenuto dellunica cella di memoria. anche previsto che tutti i programmi
terminino con lo spegnimento della macchina stessa (O).
La definizione dei programmi corretti si basa su diverse categorie sintattiche che
utilizzeremo per costruire le sequenze ben formate di tasti che si possono premere:
Program, i programmi (a cui corrisponde la variabile P della grammatica);
Stat, le sequenze di istruzioni (S);
Expr, le espressioni (E);
Numeric, i numeri che possono essere digitati oppure richiamati dalla cella di memoria
(M );
Nat, i numeri digitati (N );
Digit, le cifre (D);
Com, i comandi (C).
Le regole che descrivono i programmi accettati dalla calcolatrice sono le seguenti:
P

::= On S
Tutti i programmi sono formati da una sequenza di istruzioni preceduta
dalla parola chiave On.

S ::= E = S | O | C S
Una sequenza di istruzioni pu essere costituita da:
unespressione seguita dal simbolo = e quindi ancora da una
sequenza di istruzioni;
la parola chiave O;
un comando seguito ancora da una sequenza di istruzioni.

70

Capitolo 4 Sintassi e denotazioni


E ::= M | E + M | E M | E M | E/M
Unespressione pu essere costituita semplicemente da un numero richiamato dalla memoria oppure composto dalla tastiera, oppure sar
composta concatenando unaltra espressione, il simbolo di un operatore aritmetico e un numero (sia questo richiamato dalla memoria oppure
digitato).
M

::= N | MR
I numeri richiamati dalla memoria vengono qui distinti da quelli composti
premendo i tasti numerici della calcolatrice.

::= D | N D
Queste e le seguenti sono le produzioni viste in precedenza per descrivere
il meccanismo di generazione di un numero.

D ::= 0 | 1 | | 9
C ::= M+ | M- | MC | CE/C
I comandi disponibili per la gestione della cella di memoria e del visore
della calcolatrice.
Esempio 4.1. I programmi
On 5 + 37 2 = M+ O,
On 5 + 37 2 = M+ 44 + MR = O
sono sintatticamente corretti secondo le regole date sopra, mentre il programma
On 5 + 4 MR = O
non corretto perch non consentito premere il tasto MR dopo aver composto un numero.

4.3

Il linguaggio della calcolatrice tascabile

Chiamiamo G la grammatica proposta per generare il linguaggio dei programmi accettati dalla
calcolatrice tascabile nella Sezione 4.2. L(G) il linguaggio dei programmi accettati dalla
calcolatrice. La grammatica G stata introdotta pensando alle diverse categorie sintattiche
che possono intervenire nel progetto del linguaggio, ed una grammatica libera dal contesto.
Ovviamente, G non lunica grammatica che genera L(G) ed il fatto che G sia libera dal
contesto non implica che L(G) sia un linguaggio strettamente libero dal contesto. Infatti,
L(G) pu essere generato anche a partire da unaltra grammatica G0 che risulta essere regolare,
e quindi un linguaggio regolare (si veda quanto detto in Sezione 3.1). La nuova grammatica
G0 la seguente:
P ::= On S
S ::= O | d T | MR U | c S
T ::= d T | o V | = S
(4.1)
U ::= o V | = S
V ::= MR U | d T,

71

4.3 Il linguaggio della calcolatrice tascabile

dove d indica una qualunque cifra fra 0 e 9, c indica un comando (manipolazione della memoria
e cancellazione del visore o dellerrore), ed o indica una qualunque operazione aritmetica.
Volendo scrivere la grammatica senza considerare queste abbreviazioni dovremmo scrivere le
dieci produzioni
0 T | 1 T | | 9 T

al posto di d T , e lo stesso per i comandi e gli operatori.


A dierenza dalla prima, questa grammatica punta a caratterizzare la calcolatrice come
una macchina che via via abilita gruppi di tasti, eventualmente disabilitandone altri, impedendo in questo modo la scrittura di programmi non legali. Operativamente, la grammatica
individua gli stati di un sistema di transizioni etichettate ed il modo in cui si passa da uno
stato allaltro in funzione del tasto premuto.
Questa visione operativa dellinterazione con la calcolatrice esemplificata nella Figura 4.2
dove ogni stato rappresentato da una figura della calcolatrice. In ciascuna di tali figure sono
evidenziati in grigio scuro i tasti che lo stato consente di premere, mentre sono disegnati in
grigio chiaro i tasti disabilitati. Le frecce che collegano uno stato con un altro sono etichettate
con un tasto, che eventualmente rappresenta un insieme di tasti: in questo caso come se
avessimo tante frecce quanti sono gli elementi di tale insieme. Questo sta a significare che il
sistema di transizioni pu passare dallo stato di partenza a quello di arrivo (individuati dal
verso della freccia) qualora il tasto-etichetta sia premuto. Le etichette sulle frecce uscenti da
uno stato compongono linsieme dei tasti attivi nello stato in questione. Per rendere pi chiara
la corrispondenza fra il sistema di transizioni etichettate cos definito e la grammatica regolare
(4.1), accanto ad ogni stato specificato il simbolo nonterminale di quella grammatica che ad
esso corrisponde.
Questo semplice esempio di linguaggio generato tramite grammatiche di diverso tipo ci
ore la possibilit di chiarire che grammatiche diverse possono servire a scopi diversi. In particolare, una grammatica libera dal contesto permette di evidenziare la struttura e le categorie
concettuali fondamentali del linguaggio della calcolatrice tascabile, mentre una grammatica
regolare permette di mimare il comportamento della calcolatrice nellinterazione con lutente.
Riscriviamo ora, usando le stesse convenzioni stabilite per la grammatica regolare G0 , la
grammatica originale G:
P
S
E
M
N

::=
::=
::=
::=
::=

On S
E = S | O | c S
M |EoM
N | MR
d|N d

(4.2)

Possiamo dimostrare che le grammatiche G e G0 generano lo stesso linguaggio; ne seguir


ovviamente che tale linguaggio regolare.
Proposizione 4.2. Sia G la grammatica in (4.2) e G0 la grammatica in (4.1). Si ha che
L(G) = L(G0 ).
Dimostrazione. (Schema) Dimostriamo innanzitutto che entrambe le grammatiche seguenti
E
T
U
V

::=
::=
::=
::=

d T | MR U
dT |oV |"
oV |"
MR U | d T,

E
M
N

::= M | E o M
::= N | MR
::= d | N d

72

Capitolo 4 Sintassi e denotazioni

On

Off

MC

MR

M-

CE
C

M+

d
o
c

On

= 0 ,..., 9
= + ,..., /
= MC , , M- , M+
CE
C

P
c
On

Off

MR

M-

CE
C

M+

MC

STOP

Off

S
d

MR

On

Off

On

Off

MC

MC

MR

MR

M-

M-

CE
C

M+

CE
C

M+

MR

On

Off

MC

MR

M-

CE
C

M+

Figura 4.2: La calcolatrice tascabile come sistema di transizioni etichettate

73

4.4 Semantica denotazionale della calcolatrice tascabile


generano il linguaggio
L = {m0 o1 m1 o2 . . . ok mk | k

0}

dove ciascun oi uno dei quattro simboli di operazione aritmetica e gli mi sono stringhe di
cifre numeriche oppure MR. Queste dimostrazioni possono essere realizzate per induzione
sulla struttura delle grammatiche date, e vengono lasciate al lettore.
Si osservi ora che ogni derivazione di una stringa del linguaggio tramite la prima grammatica termina con una riscrittura di uno dei nonterminali T oppure U in ", quindi, fissato
un simbolo ausiliario , le due grammatiche
E0
E
T
U
V

::=
::=
::=
::=
::=

E
d T | MR U
dT |oV |"
oV |"
MR U | d T,

E
T
U
V

::=
::=
::=
::=

d T | MR U
dT |oV |
oV |
MR U | d T,

generano banalmente lo stesso linguaggio. Ora la tesi segue immediatamente confrontando le


grammatiche G e G0 ed usando le propriet appena dimostrate.

4.4

Semantica denotazionale della calcolatrice tascabile

Ricordiamo innanzitutto la sintassi dei programmi accettati dalla calcolatrice tascabile descritta nella Sezione 4.2, evitando di trattare dettagliatamente la generazione delle stringhe
corrispondenti ai numeri (in maniera simile a quanto fatto nella grammatica (Ga ) per le
espressioni aritmetiche mostrata in Tabella 3.3):
P
S
E
M
C

::=
::=
::=
::=
::=

On S
E = S | O | C S
M | E + M | E M | E M | E/M
n | MR
M+ | M- | MC | CE/C

Ricordiamo che le categorie sintattiche presenti nel linguaggio sono


Program: per i programmi;
Stat: per le sequenze di istruzioni;
Expr : per le espressioni;
Numeric: per i numeri oppure il contenuto della cella di memoria;
Com: per i comandi.
Per ciascuna di tali categorie avremo delle funzioni di interpretazione semantica il cui
valore dipender:
1. dal particolare elemento della categoria sintattica in esame;
2. dal numero che risulter scritto sul visore;

74

Capitolo 4 Sintassi e denotazioni


3. dal contenuto della cella di memoria.

In generale avremo quindi che le funzioni di interpretazione semantica dipenderanno da


uno stato globale che verr passato loro come argomento. Nel nostro caso largomento sar
la coppia costituita da ci che appare sul visore e dal contenuto della cella di memoria. Gli
elementi delle coppie saranno quindi numeri interi oppure stringhe di errore. Queste ultime
entreranno in gioco quando si verificano situazioni anormali, che nel nostro caso sono costituite
dalla sola divisione per zero.
Di seguito riportiamo il tipo (la natura dei possibili input e dei possibili output) delle funzioni di interpretazione semantica per la calcolatrice tascabile; il simbolo INT denota linsieme
degli interi. Il tipo di ciascuna funzione dovrebbe gi dare unidea circa il comportamento
della funzione stessa.
P : Program ! (INT + {error})

S : Stat (INT + {error}) INT ! (INT + {error})


E

: Expr (INT + {error}) INT ! (INT + {error}) INT

: Numeric (INT + {error}) INT ! (INT + {error}) INT

C : Com (INT + {error}) INT ! (INT + {error}) INT

Questi domini chiariscono che le funzioni P ed S associano un numero intero oppure un


errore ad ogni programma. Comunque, mentre P non tiene conto di altro che del programma
stesso, la funzione S, oltre che dalla sequenza di comandi, dipende anche dal valore riportato
dal visore e dal contenuto della memoria. importante notare come possibili valori del visore
siano interi oppure la stringa error mentre la memoria pu contenere solo interi; niente infatti
verr mai memorizzato se si verifica una condizione di errore.
Al momento potr non essere immediatamente chiaro il significato di alcuni dei costrutti
usati per descrivere il comportamento della calcolatrice; tutta la notazione sar chiarita nelle
prossime sezioni. Solo allora descriveremo tutti i costrutti del nostro metalinguaggio, cio del
linguaggio che utilizzeremo per parlare dei vari linguaggi di programmazione che prenderemo
in esame. Per ora ci adiamo allintuizione ed alla fantasia del lettore, anticipando solamente
che i termini del metalinguaggio sono scritti in corsivo, che lespressione let x be v in f significa
che allinterno di f tutte le occorrenze della variabile x vengono rimpiazzate dal valore v, che
la funzione (di tre argomenti) ! , la funzione condizionale tale che v ! v1 , v2 uguale
a v1 se v vero ed a v2 se v falso, ed infine che la funzione isint(v) il predicato (cio, la
funzione booleana) che restituisce true se v un intero e false altrimenti (che nel nostro caso
vuol dire che v error).
Le funzioni di interpretazione semantica necessarie per specificare completamente il comportamento della calcolatrice tascabile, quando le vengono fornite sequenze ben formate di
comandi, sono riportate di seguito.
P : P rogram ! INT + {error}
P[[On S]] = S[[S]] < 0, 0 >
La semantica di un programma coincide con quella della sequenza di istruzioni che compongono il programma stesso quando queste vengono valutate a partire da una memoria ed

4.4 Semantica denotazionale della calcolatrice tascabile

75

un visore inizializzati a zero.


S : Stat (INT + {error}) INT ! (INT + {error})
S[[E = S]] < v, m > = (S[[S]] E[[E]]) < v, m > = S[[S]](E[[E]] < v, m >)
La semantica di una istruzione del tipo E = S prevede prima la valutazione dellespressione
E e successivamente quella della sequenza S utilizzando i valori del visore e della memoria
dopo la valutazione di E.
S[[C S]] < v, m > = (S[[S]] C[[C]]) < v, m >
La semantica di una istruzione della forma C S prevede prima la valutazione del comando
C e successivamente quella della sequenza S utilizzando i valori del visore e della memoria
dopo la valutazione di C.
S[[O]] < v, m > = v
Il risultato finale di un programma il valore riportato sul visore dopo la valutazione di
tutte le istruzioni; tale valore pu essere un intero oppure la segnalazione del fatto che si
verificato un errore durante uno dei calcoli precedenti.
E : Expr (INT + {error}) INT ! (INT + {error}) INT
E[[M ]] < v, m > = isint(v) ! N [[M ]] < v, m >, < v, m >
La digitazione di una combinazione di tasti corrispondente ad un numero oppure del tasto
di richiamo dal registro di memoria causa la valutazione della sequenza di tasti premuta
quando sul visore non stata segnalata una situazione di errore. Vale la pena notare che
essendo gli unici valori possibili interi ed error il test isint(v) equivale a testare che non si
siano verificati errori durante i calcoli precedenti.
E[[E + M ]] < v, m > = let < v1 , m1 > be E[[E]] < v, m > in
isint(v1 ) ! (let < v2 , m2 > be N [[M ]] < v1 , m1 > in
< v1 + v2 , m2 >),
< v1 , m1 >
Eettuare loperazione di somma fra una espressione ed un oggetto numerico consiste nel
valutare prima lespressione e verificare che il risultato della valutazione sia un numero intero,
quindi nelleettuare loperazione vera e propria. Se durante la valutazione dellespressione si
verificano condizioni di errore, il risultato finale sar comunque un errore.

76

Capitolo 4 Sintassi e denotazioni

E[[E

M ]] < v, m > = let < v1 , m1 > be E[[E]] < v, m > in


isint(v1 ) ! (let < v2 , m2 > be N [[M ]] < v1 , m1 > in
< v1 v2 , m2 >),
< v1 , m1 >

E[[E M ]] < v, m > = let < v1 , m1 > be E[[E]] < v, m > in


isint(v1 ) ! (let < v2 , m2 > be N [[M ]] < v1 , m1 > in
< v1 v2 , m2 >),
< v1 , m1 >
I casi della dierenza e del prodotto sono analoghi al precedente.
E[[E/M ]] < v, m > = let < v1 , m1 > be E[[E]] < v, m > in
isint(v1 ) ! (let < v2 , m2 > be N [[M ]] < v1 , m1 > in
(v2 = 0 !< error, m2 >, < v1 /v2 , m2 >)),
< v1 , m1 >
Nel caso della divisione, invece, dobbiamo controllare che il secondo operando sia diverso
da zero; la divisione per zero genera un errore.
N : Numeric (INT + {error}) INT ! (INT + {error}) INT
N [[n]] < v, m > = isint(v) !< n, m >, < v, m >
N [[MR]] < v, m > = isint(v) !< m, m >, < v, m >
La valutazione di un oggetto numerico causa laggiornamento del visore ed il mantenimento
della cella di memoria, se tale oggetto stato composto premendo i tasti numerici della
calcolatrice; altrimenti, il risultato della valutazione uno stato in cui sia il visore che la cella
di memoria hanno il valore che la cella stessa aveva prima di premere il tasto MR.
C : Com (INT + {error}) INT ! (INT + {error}) INT
C[[MC]] < v, m > = isint(v) !< v, 0 >, < v, m >
C[[M+]] < v, m > = isint(v) !< v, m + v >, < v, m >
C[[M-]] < v, m > = isint(v) !< v, m

v >, < v, m >

C[[CE/C]] < v, m > =< 0, m >


Se sul visore non appare una segnalazione di errore, il comando MC azzera la memoria;
il comando M+ (M-) somma (sottrae) il contenuto della memoria e il numero riportato sul
visore. Il comando CE/C azzera il visore cancellando eventualmente la segnalazione di errore
su di esso riportato cos ripristinando una situazione di normalit.

77

4.5 Espressioni regolari

4.5

Espressioni regolari

NellIntroduzione a queste note abbiamo descritto brevemente i tre approcci pi usati per
definire la semantica di un linguaggio di programmazione. Tali approcci vanno sotto il nome
di semantica denotazionale, semantica operazionale e semantica assiomatica. Chiudiamo
questo capitolo con un esempio in cui utilizziamo tutti e tre gli approcci definendo delle
semantiche consistenti.
Il linguaggio scelto come esempio quello delle espressioni regolari. Le espressioni regolari
sono usualmente utilizzate per rappresentare linguaggi regolari in forma sintetica oppure per
descrivere le sequenze di azioni che un sistema pu eseguire o le sequenze di caratteri che un
automa a stati finiti pu riconoscere.
Le espressioni regolari possono essere considerate anche come un piccolo linguaggio di
programmazione. I costrutti da esse usati (sequenzializzazione, scelta, iterazione, processo
nullo) saranno presenti anche nei formalismi e nei linguaggi che analizzeremo nei prossimi
capitoli, per cui usare le espressioni regolari come caso di studio risulter anche propedeutico.
La sintassi (astratta) delle espressioni regolari la seguente:
E ::= 0 | 1 | a | E + E | E; E | E

(Ge )

dove a appartiene ad un alfabeto finito A.1 Per semplicit, loperatore ; viene talvolta
indicato con la giustapposizione delle due espressioni regolari che ne costituiscono gli argometi.
Nellinterpretazione pi comune, un elemento di A inteso rappresentare unazione atomica o evento. Lelemento 1 rappresenta levento terminale e lelemento 0 rappresenta levento
vuoto. Se E ed F sono espressioni regolari E + F rappresenta lespressione che pu essere
in alternativa lespressione E o lespressione F , lespressione E; F rappresenta lespressione
ottenuta sequenzializzando le espressioni E ed F ed, infine, lespressione E rappresenta la ripetizione di un numero finito (eventualmente nullo) di volte dellespressione E, cio la ripetuta
sequenzializzazione di E con se stessa.
Osserviamo che le descrizioni precedenti costituiscono solo una semantica intuitiva per le
espressioni regolari: dicile stabilire quale possa essere linterpretazione di una espressione
composta, come ad esempio
(a + b)

oppure

(a + b ) .

Per il momento, lunica aermazione che possiamo fare riguardo a queste due espressioni
regolari che esse sono sintatticamente dierenti. Vediamo allora i vari modi di dare una
semantica formale ed esatta alle espressioni regolari.

4.5.1

Semantica denotazionale

La semantica denotazionale associa ad ogni espressione regolare il linguaggio (ossia, linsieme


di stringhe) che essa denota. Per definire la funzione di interpretazione semantica, abbiamo
bisogno di alcune semplici costruzioni sugli insiemi di stringhe.
Se L1 ed L2 sono insiemi non vuoti di stringhe definiamo concatenazione di L1 e di L2 e
la denotiamo con L1 L2 , linsieme
L1 L2 = {xy : x 2 L1 e y 2 L2 }

1
Nella sintassi concreta delle espressioni regolari, loperatore unario ha precedenza sugli operatori binari
+ e ; , mentre loperatore ; ha precedenza sulloperatore +. Quando necessario useremo le parentesi.

78

Capitolo 4 Sintassi e denotazioni

L[[0]] = ;
L[[1]] = {"}

L[[a]] = {a} (per a 2 A)


L[[E + F ]] = L[[E]] [ L[[F ]]
L[[E; F ]] = L[[E]] L[[F ]]
L[[E ]] = (L[[E]])

Tabella 4.2: Semantica denotazionale delle espressioni regolari


ossia linsieme di tutte le stringhe ottenibili concatenando una stringa di L1 con una stringa
di L2 . Inoltre, poniamo ; L = L ; = ;. Se L un insieme di stringhe poniamo anche
L0 = {"},

Ln+1 = L Ln ,
[
L =
Ln .
n 0

Si noti che linsieme Ln linsieme delle stringhe composte dalla concatenazione di n stringhe
di L, mentre linsieme L linsieme di tutte le stringhe composte dalla concatenazione di un
numero qualsiasi di stringhe di L (compresa la stringa vuota).
Ci detto siamo in grado di definire la funzione L di interpretazione semantica delle espressioni regolari. Linterpretazione di una espressione E sar scritta come L[[E]]. La funzione
L definita per induzione strutturale sui termini del linguaggio dalle regole mostrate nella
Tabella 4.2.2
Date due espressioni regolari E ed F diremo che esse sono semanticamente uguali e scriveremo E ' F se L[[E]] = L[[F ]]. Useremo invece la notazione E F per indicare luguaglianza
sintattica. Risulta per esempio
a+a'a
infatti
L[[a + a]] = L[[a]] [ L[[a]] = L[[a]].
Esempio 4.3. Vediamo un altro esempio di uguaglianza semantica. Vogliamo dimostrare
che
(a + b) ' (a + b ) .
Dimostriamo prima che
L[[(a + b) ]] L[[(a + b ) ]]
2

Si osservi che nellultima regola loperatore gioca due ruoli distinti: nella prima occorrenza si tratta
delloperatore sintattico delle espressioni regolari, nella seconda occorrenza si tratta delloperatore definito
in precedenza sugli insiemi di stringhe.

79

4.5 Espressioni regolari


Abbiamo
L[[(a + b) ]] =

L[[(a + b)]]

= L[[a]] [ L[[b]]

(L[[a]]) [ (L[[b]])

= L[[(a + b ) ]]

= L[[a ]] [ L[[b ]]

= L[[a + b ]]

Per dimostrare linclusione opposta, bisogna dimostrare che


(L[[a]]) [ (L[[b]])

L[[a]] [ L[[b]]

da cui la tesi segue ragionando come nel caso precedente. Sfruttando il fatto che loperatore
_ idempotente, quindi che
L[[a]] [ L[[b]]

L[[a]] [ L[[b]]

sar allora suciente dimostrare che


(L[[a]]) [ (L[[b]])

L[[a]] [ L[[b]]

A tale scopo, sia s 2 L[[a]] [ L[[b]] . Ci significa che o s = e quindi s 2 L[[a]] [ L[[b]]
per definizione, oppure per un qualche n
1, si ha s = s1 s2 sn e si 2 L[[a]] oppure

si 2 L[[b]] , per ogni 1 i n. Dato che L[[a]] (L[[a]] [ L[[b]]) e L[[b]] (L[[a]] [ L[[b]]) , da


ci segue che si 2 L[[a]] [ L[[b]] , per ogni 1 i n, e quindi s 2 L[[a]] [ L[[b]]
.
Si potrebbe dimostrare che la semantica denotazionale delle espressioni regolari soddisfa
le seguenti semplici propriet:
E + (F + G) ' (E + F ) + G
E+0'E
E (F G) ' (E F ) G
E (F + G) ' E F + E G
0E ' 0
E

'1+

0 '1

E E

E+F 'F +E
E+E 'E
(E + F ) G ' E G + F G
1E ' E

E ' (1 + E)

dove E, F, G sono generiche espressioni regolari e loperatore ; stato indicato con la


giustapposizione.

4.5.2

Semantica operazionale

Introduciamo adesso una semantica operazionale per le espressioni regolari, vale a dire un
meccanismo di esecuzione.
Diamo prima unidea intuitiva del meccanismo. Se a 2 A unespressione atomica, possiamo immaginare che lesecuzione di a corrisponda per esempio a stampare il simbolo a.
Lesecuzione dellespressione composta E + F dovr consistere di tutte le azioni di E o, in alternativa, di tutte le azioni di F . Lesecuzione dellespressione composta E; F dovr consistere
delle azioni di E seguite dalle azioni di F .

80

Capitolo 4 Sintassi e denotazioni

(Tic)

(Atom)

"

1 !1

(Sum1 )

E ! E0
a

(Seq1 )

(Star1 )

! E0

! F0

! F0

E+F
"

E ! E0

(Seq2 )

! E0; F

E; F

(Sum2 )

E+F

a2A

a !1

E !1
"

!F

E; F

(Star2 )

"

E ! 1

E ! E0

E ! E0; E

Tabella 4.3: Semantica operazionale delle espressioni regolari ( 2 A [ {"})

Formalmente, la definizione della semantica operazionale si basa sulla relazione E ! F ,


dove 2 A [ {"}, definita come la pi piccola relazione che soddisfa gli assiomi e le regole di
inferenza in Tabella 4.3.
Di seguito commentiamo brevemente il comportamento delle espressioni.
1 - Lespressione 1 pu essere interpretata come lo stato di arresto. La macchina ha finito di
eseguire le azioni ed adesso continua a ciclare eseguendo lazione vuota.
a - Lespressione a in grado di eseguire lazione a per poi arrestarsi.
E + F - Lespressione E + F si pu comportare come E o come F per cui se E evolve in E 0
con lazione allora E + F pu evolvere in E 0 con lazione ed analogamente per F .
E; F - Lespressione E; F deve eseguire le azioni di E e poi quelle di F . Per cui se E evolve
in E 0 con lazione a allora E; F evolve in E 0 ; F con lazione a. Se invece E ha finito il
suo lavoro per cui evolve in 1 con " allora F pu partire per cui E; F evolve in F .
E - Lespressione E pu evolvere direttamente in 1 oppure evolvere in E 0 ; E se E evolve
in E 0 .
0 - Per lespressione 0 non ci sono regole. Questo fa in modo che lespressione 0 non possa
eseguire nessuna azione. Lespressione 0 rappresenta quindi la macchina bloccata.
s

Definizione 4.4. Sia E unespressione regolare e sia s 2 A una stringa. Scriveremo E =


) E0
se esistono 1 , . . . , n 2 A [ {"} (n 0) tali che:
1. la stringa 1 . . . n coincide (a meno di occorrenze di ") con la stringa s,
2. risulta

E ! E1 ! E2 ! . . . ! En E 0 .

Definiamo linsieme delle tracce di E come linsieme di stringhe


s

Tracce(E) = {s 2 A : E =
) 1},

81

4.5 Espressioni regolari

ossia linsieme delle stringhe s che ammettono una computazione terminante di E.


Due espressioni regolari E ed F si dicono equivalenti a tacce, scritto E
= F , se Tracce(E) =
Tracce(F ).
Esempio 4.5. Vediamo, anche in questo caso, che E (a + b) e F (a + b ) risultano
equivalenti, ossia
Tracce((a + b) )
= Tracce((a + b ) ).
s

Proviamo che se s una traccia di E (ossia E =


) 1) allora s una traccia anche di F
(il viceversa lasciato per esercizio). Procediamo per induzione sulla lunghezza di s. Se
"
|s| = 0 (ossia, s = ") allora non c nulla da dimostrare perch vero che F ! 1 (si applica
lassioma Star1 ). Se |s| > 0 allora s = as0 oppure s = bs0 . Senza perdita di generalit possiamo
a
a
assumere s = as0 . Le uniche transizioni che E pu eseguire tramite a sono E =
) 1; E e E =
)E
giustificate da
a

a !1

(Atom)

a+b !1
(a + b)

"

1 !1

(Sum1 )

! 1; (a + b)

(T ic)

"

1; (a + b) ! (a + b)

(Star2 )

as0

s0

(Seq2 )

s0

Inoltre, per ipotesi, E ==) 1 per cui devessere o 1; E =


) 1 oppure E =
) 1. In ogni caso
s0

s0

segue E =
) 1. Quindi, per ipotesi induttiva, F =
) 1. Basta allora dimostrare che F =
)F
s
a
per ottenere F =
) 1. Ora, F =
) F giustificata da
a

a !1
a

(Atom)

a ! 1; a

(Star2 )

a + b ! 1; a

"

1 !1

(Sum1 )

(a + b ) ! 1; a ; (a + b )

"

1; a ; (a + b ) ! a ; (a + b )

(Star2 )

"

a ! 1
"

che dimostrano che F

"

(T ic)
(Seq2 )

(Star1 )

a ; (a + b ) ! (a + b )

(Seq2 )

"

! ! ! F.

Vediamo ora come associare ad ogni espressione regolare una macchina astratta che descrive lesecuzione dellespressione stessa. Pi precisamente, utilizzando la relazione di transizione
introdotta per le espressioni regolari, associamo ad ogni espressione regolare un automa a stati
finiti.
Definizione 4.6. Sia E unespressione regolare, definiamo lautoma a stati finiti associato
ad E come
ME = QE , A, !E , E, {1}
dove

82

Capitolo 4 Sintassi e denotazioni

Figura 4.3: Automi corrispondenti a (a + b) e (a + b )


s

QE = {F : 9s 2 A tale che E =
) F } linsieme degli stati dellautoma ed costituito
dalle espressioni raggiungibili a partire da E;
A lalfabeto dellautoma (e coincide con quello dellespressione regolare);
!E la relazione di transizione tra stati in QE ed definita da F
con 2 A [ {"};

!E F 0 se F

! F0

lo stato iniziale rappresentato dallespressione E;

lunico stato finale rappresentato dallespressione 1.


La Figura 4.3 riporta come esempio gli automi associati alle espressioni regolari (a + b)
e (a + b ) . Si osservi che la transizione
b

(a + b ) ! 1; b ; (a + b )
che serve a costruire lautoma di destra nella figura viene derivata nel modo seguente:
(Atom)

b !1
b

! 1; b

a +b
b

! 1; b

(Star2 )

(Sum2 )

(a + b ) ! 1; b ; (a + b )

(Star2 )

Vogliamo ora dimostrare che linsieme delle stringhe che unespressione E pu produrre
durante la sua esecuzione, secondo la semantica operazionale data, coincide con il linguaggio
riconosciuto dallautoma ME associato allespressione E.

83

4.5 Espressioni regolari

Teorema 4.7. Sia E unespressione regolare ed ME lautoma a stati finiti ad essa associato.
Allora
Tracce(E) = L(ME )
dove L(ME ) il linguaggio riconosciuto da ME .
a

Dimostrazione. Si ricordi (vedere Sezione 3.4) che la relazione !E dellautoma d luogo a


a
s
una relazione =)E e che L(ME ) = {s 2 A : E =)E 1}.
w
() Se w 2 Tracce(E), allora E =
) 1. Proviamo per induzione sulla lunghezza di w che
"
"
w 2 L(ME ). Se |w| = 0, cio E =
) 1, allora per definizione E =)E 1, e quindi " 2 L(ME ).
Sia allora w = aw0 , abbiamo
a

w0

E=
) E1 =) 1.
w0

Per ipotesi induttiva w0 2 L(ME1 ) ossia E1 =)E 1. La tesi segue allora osservando che,
sempre per definizione,
a
a
E=
) E1
implica
E =)E E1 .
() Procediamo di nuovo per induzione sulla lunghezza di w 2 L(ME ) e proviamo che w 2
Tracce(E). Il caso base banale. Se w = aw0 per un certo w0 , abbiamo per ipotesi
a

w0

E =)E E 0 =)E 1.
w0

Quindi E =) E 0 inoltre, per ipotesi induttiva, w0 2 Tracce(E 0 ), per cui E 0 =) 1. Ne segue


w
E =) 1.
Possiamo vedere la semantica operazionale come la specifica del comportamento desiderato
per ogni implementazione del linguaggio delle espressioni regolari e lassociazione con gli
automi come una eettiva implementazione del linguaggio.
Vogliamo ora determinare le relazioni esistenti tra la semantica operazionale e la semantica denotazionale data in precedenza per le espressioni regolari. In particolare vogliamo
dimostrare che esse sono in accordo. Pi precisamente, dimostreremo che il linguaggio che
la semantica denotazionale associa ad una espressione regolare coincide con linsieme delle
tracce della stessa espressione, e quindi, per il teorema precedente, con il linguaggio accettato
dallautoma ad essa associato.
Teorema 4.8. Sia E unespressione regolare. Allora
w 2 Tracce(E) () w 2 L[[E]].
Dimostrazione. (=)) Procediamo per induzione sulla struttura di E.
E 0 Banale, perch Tracce(0) = ; = L[[0]].
E 1 Banale, perch Tracce(1) = {"} = L[[1]].
E a Banale, perch Tracce(a) = {a} = L[[a]].
E E1 + E2 Se w 2 Tracce(E1 + E2 ), allora esistono 2 A [ {"} e w0 2 A con w = w0 e

w0

E1 + E2 ! F =) 1,

84

Capitolo 4 Sintassi e denotazioni


dove la prima transizione ottenuta applicando una delle due regole relative alloperatore
di somma. Quindi abbiamo che

w0

w0

E1 ! F =) 1

oppure

E2 ! F =) 1.

w 2 L[[E1 ]]

oppure

w 2 L[[E2 ]]

Per ipotesi induttiva allora

da cui w 2 L[[E1 ]] [ L[[E2 ]] = L[[E1 + E2 ]].

E E1 ; E2 Se w 2 Tracce(E1 ; E2 ), cio E1 ; E2 =) 1, allora si potrebbe dimostrare che


esistono due stringhe x e y tali che w = xy e
y

E1 =) 1 e E2 =) 1.
Quindi, per ipotesi induttiva abbiamo che
x 2 L[[E1 ]] e y 2 L[[E2 ]],

da cui w 2 L[[E1 ]] L[[E2 ]] = L[[E1 ; E2 ]].

E E1 Indichiamo con S(E1 , w) il numero di volte che la regola Star2 viene applicata nella
w
sequenza di transizioni E1 =) 1 e dimostriamo per induzione (locale) su n = S(E1 , w)
che
w 2 Ln [[E1 ]].
(Ln [[E1 ]] sta per (L[[E1 ]])n )

Se S(E1 , w) = 0, cio Star2 non viene mai usata, allora vuol dire che stata usata Star1 ,
quindi w = ". Infatti la semantica operazionale delloperatore modellata dalle due
regole Star1 e Star2 . La tesi segue dal fatto che, per definizione, si ha {"} = " 2 L0 [[E1 ]].
Se invece S(E1 , w) = n + 1, allora si ha che esistono due stringhe x, y tali che w = xy e
y

"

E1 =) E1 =) E1 ! 1,

con S(E1 , x) = n, per cui per ipotesi induttiva (locale) x 2 Ln [[E1 ]]. Dato che S(E1 , y) =
y
1, abbiamo che la regola Star2 deve essere applicata esattamente una volta in E1 =) E1

per cui devono esistere 2 A [ {"} ed y 0 2 A tali che y = y 0 , E1 ! E 0 e


y0

E1 ! E 0 ; E1 =) E1 .

y0

y0

Dato che E 0 ; E1 =) E1 non usa la regola Star2 abbiamo E 0 =) 1, da cui


y 0

E1 ==) 1

e quindi, per lipotesi induttiva strutturale, y 2 L[[E1 ]] che insieme a x 2 Ln [[E1 ]] d la


tesi.
((=) Procediamo per induzione sulla struttura di E. Per semplicit, trattiamo in dettaglio
solo il caso E = E1 . Se w 2 L[[E1 ]], allora esiste n tale che w 2 Ln [[E1 ]]. Quindi esistono
x1 , . . . , xn 2 L[[E1 ]] tali che w = x1 xn . Per ipotesi induttiva xi 2 Tracce(E1 ), ossia
xi
x1
E1 =)
1 da cui, applicando Star2 e (pi volte) Seq1 , si ricava E1 =)
1; E1 . Dato che
"
"
1; E1 ! E1 , per la Seq2 , e E1 ! 1, per la Star1 , abbiamo
x

"

1
2
n
E1 =)
1; E1 =)
1; E1 =)
1; E1 ! 1

per cui E1 =) 1, cio per definizione w 2 T racce(E1 ).

85

4.5 Espressioni regolari

4.5.3

Semantica assiomatica

Vediamo infine una semantica assiomatica per le espressioni regolari. Diamo cio un insieme
di assiomi e di regole di inferenza che definiscono una relazione di binaria sullinsieme delle
espressioni regolari. Denoteremo con luguaglianza E = F il fatto che le espressioni regolari
E e F sono uguagliate da tale sistema di inferenza (ossia il fatto che esiste una derivazione di
E = F ).
Prima di introdurre il sistema di inferenza abbiamo bisogno della seguente definizione.
Definizione 4.9. Una espressioni regolare E si dice possedere la propriet di produrre la
stringa vuota se una delle seguenti tre condizioni verificata:
E E1 per un certo E1 ,
E una somma di espressioni regolari ed una di queste possiede la propriet di produrre
la stringa vuota,
E una sequenzializzazione di espressioni regolari ciascuna delle quali possiede la
propriet di produrre la stringa vuota.
La Tabella 4.4 riporta gli assiomi e le regole del sistema di inferenza (gli assiomi sono stati
divisi in gruppi e agli assiomi ed ai gruppi stessi sono stati dati dei nomi; per semplificare le
notazioni, per denotare loperatore di sequenzializzazione stata usata la giustapposizione).
Facciamo alcune osservazioni sul sistema di inferenza presentato. Innanzitutto si pu
osservare che gli assiomi e le regole risultano sensati ossia coerenti con la nostra intuizione
sul significato delle espressioni regolari. Non dicile vedere (e lo abbiamo gi osservato
nella Sezione 4.5.3) che gli assiomi sono coerenti anche con la semantica denotazionale. Per
esempio, lassioma 0E = 0 in accordo con il fatto che
L[[0E]] = L[[0]] L[[E]] = ; L[[E]] = ; = L[[0]].
Tuttavia rispetto alle semantiche viste finora, mostrare che due espressioni regolari sono
uguali risulta pi dicile. Si osservi per esempio che anche il fatto che per ogni espressione
regolare E risulta E = E, cio che = una relazione riflessiva, richiede una dimostrazione
che basata sulla sola applicazione della regola di sostituzione:
E+E =E
E=E

E+E =E
E =E+E

(regola1)

Dimostriamo ora che E = F implica F = E, cio che = simmetrica. Lo facciamo applicando


ancora la regola di sostituzione:
E=F

E=F

F =F

F =E

(regola1)

Infine, dimostriamo che E = F e F = G implicano E = G, cio che = transitiva. Anche in


questo caso, la dimostrazione segue dalla applicazione della regola di sostituzione:
E=F

E=F

F =E

(regola1)
E=G

F =G

(regola1)

86

Capitolo 4 Sintassi e denotazioni

Assiomi:

E + (F + G) = (E + F ) + G
E+F =F +E
E+0=E

(assoc +)
(comm +)
(neutro +)

E (F G) = (E F ) G
1E = E

(assoc ;)
(neutro ;)

E (F + G) = E F + E G
(E + F ) G = E G + F G
0E = 0

9
=
;

E E

=1+
E = (1 + E)
0 = 1

(distribS)
(distribD)
(assorb 0)

(modulo +, ;)

(unfolding)
(assorb *)
(00 )

9
=

(regole *)

Regola 1 (Sostituzione):

E=F

G=H

G0 = H

G0 = G

(monoide ;)

9
=

E+E =E
E

(monoide+)

;
;

(idempotenza +)

dove G0 ottenuta da G rimpiazzando


una occorrenza di E con F

Regola 2 (Soluzione di equazioni):


E =EF +G
se F non possiede la propriet

di produrre la stringa vuota


E = GF

Tabella 4.4: Semantica assiomatica delle espressioni regolari


Da tutto ci segue che = una relazione equivalenza.
Come altro esempio, mostriamo ora che E0 = 0 (durante linferenza, faremo pi volte
implicitamente uso del fatto che = simmetrica)
0 = 00

(absorb0)

E0 = E0

E00 = E0
00 = 0

(regola1)

E00 + 0 = E0

(absorb0)

E0 = 00
E0 = 0

E0 + 0 = E0

(neutro+)
(regola1)

(regola2)

(regola1)

Come si vede, le dimostrazioni anche di semplici uguaglianze diventano laboriose. Ci si pu


allora chiedere quale sia il potere dimostrativo di questo sistema di inferenza e quale sia la
sua relazione con la semantica denotazionale. Si pu dimostrare che
E=F

derivabile dal sistema di inferenza

se e solo se
L[[E]] = L[[F ]].

Se diciamo che una uguaglianza E = F valida quando L[[E]] = L[[F ]], allora possiamo chiederci se il sistema di inferenza dimostra solo uguaglianze valide (correttezza) e se le dimostra

87

4.5 Espressioni regolari

tutte (completezza), cio se vero che se una uguaglianza valida allora essa dimostrabile dal sistema di inferenza. La dimostrazione della correttezza immediata ed gi stata
indirettamente osservata alla fine della Sezione 4.5.1. La dimostrazione della completezza
invece delicata e in queste note ci limitiamo a dimostrare la completezza per linsieme delle
espressioni regolari che non usano loperatore .
Cominciamo con lintrodurre il concetto di forma normale per espressioni regolari senza .
Definizione 4.10. Una espressione regolare senza si dice in forma normale se o 1 oppure
della forma
X
si
i2I

dove I un insieme (finito) di indici, si 2 A+ e si 6= sj per i 6= j.


P
Se I = ; allora sintende che i2I si = 0.

Proposizione 4.11. Se E unespressione regolare senza , allora esiste unespressione regolare E 0 in forma normale tale che E = E 0 derivabile con il sistema di inferenza della
Tabella 4.4 (senza luso delle regole- e della regola 2).
Dimostrazione. Procediamo per induzione strutturale su E.
- Se E 0, 1, a non c nulla da dimostrare.
-PSe E EP
1 + E2 allora per induzione, e grazie alla regola di sostituzione, abbiamo E =
s
+
i
i2I
j2J tj e quindi, a meno di raccogliere tutti gli addendi in ununica somma per
mezzo dellassociativit e di eliminare gli addendi ripetuti per mezzo dellidempotenza, E
in forma normale.
-PSe E PE1 E2 allora per induzione, e grazie alla regola di P
sostituzione,
abbiamo E =
P
j2J tj e quindi, per la propriet distributiva, E =
i2I
j2J si tj ossia E =
Pi2I si
u
dove
K
=
I

J
ed
u
=
s
t
per
k
=
(i,
j).
Per
cui,
a
meno
di eliminare gli
i
j
k
k
k2K
addendi ripetuti per mezzo dellidempotenza, E in forma normale.
Siamo ora in grado di dimostrare la completezza del sistema di inferenza per le espressioni
regolari che non usano loperatore .
Teorema 4.12. Se E ed F sono espressioni regolari senza ed
L[[E]] = L[[F ]]
allora
E=F

derivabile dal sistema di inferenza

della Tabella 4.4 (senza luso delle regole- e della regola 2).
Dimostrazione. Per la proposizione precedente esistono due forme normali E 0 ed F 0 tali che
le uguaglianze E = E 0 ed F = F 0 siano derivabili. Si noti che se E 0 1 allora, data
P lipotesi
L[[E]] P
= L[[F ]], segue che F 0 1 (e viceversa). Supponiamo quindi che E 0 i2I si ed
F 0 j2J tj . Basta quindi dimostrare che E 0 = F 0 , dopodiche la tesi segue applicando la
regola di sostituzione. Dalla correttezza degli assiomi segue L[[E]] = L[[E 0 ]] e L[[F ]] = L[[F 0 ]]
e quindi, data lipotesi L[[E]] = L[[F ]], segue che L[[E 0 ]] = L[[F 0 ]]. Usando la definizione di L
(Tabella 4.2) abbiamo
P
S
S
L[[E 0 ]] = L[[ i2I si ]] = i2I L[[si ]] = i2I {si } = {si : i 2 I}

88

Capitolo 4 Sintassi e denotazioni

ed analogamente

L[[F 0 ]] = {tj : j 2 J}.

Per
applicando lassioma di commutativit della somma, abbiamo che
P cui, eventualmente
P
s
=
t
,
ossia
E0 = F 0.
i
j
i2I
j2J

4.6

Esercizi

4.1 Fornire la semantica denotazionale dei numeri in base 5, usando come dominio semantico i
naturali.
4.2 Considerare una variante della calcolatrice tascabile in cui il tasto M- sottrae il contenuto della
memoria a quello del visore.
4.3 Considerare una calcolatrice tascabile che ha una memoria con tre registri (a, b, c) a cui si accede
premendo i tasti MC, M+, M-, MR e poi il tasto On 1, 2, 3 volte, rispettivamente.
4.4 Modificare la sintassi e la semantica della calcolatrice tascabile in modo da distinguere i tasti
CE (cancellazione dopo errore) e C (cancellazione senza errore).
4.5 Descrivere in modo informale i linguaggi specificati dalle seguenti espressioni regolari:
a) (a; a) ; (b; b) ,
a) (a ; b ; c ) ,
b) (a; a; a + a; a; a; a) .
4.6 Si provi che L[[(a + b) ]] = L[[(a + b ) ]].

4.7 Costruire gli automi associati alle espressioni regolari a; (b + c) e a; b + a; c.


4.8 Si provi che Tracce((a + b) ) = Tracce((a + b ) ).
s

4.9 Siano E ed F espressioni regolari e sia s una stringa, si provi che se E; F =) 1, allora esistono
y
x
delle stringhe x e y tali che s = xy e E =) 1, F =) 1.
4.10 Si dimostrino le seguenti uguaglianze usando il sistema di inferenza della semantica assiomatica:
a) E = F =) F = E
b) E1 = E
c) E = F =) E = F

d) E + 1 = E
e) E + E = E
F ) 0 = 0

Parte II

Sistemi Sequenziali

Capitolo 5

-calculus

SOMMARIO
Questo capitolo presenta il -calculus, un sistema formale che ha un ruolo importante nello
studio dei fondamenti dei linguaggi di programmazione. Il -calculus fornisce infatti sia una
notazione semplice per la rappresentazione di funzioni nonch di altri importanti concetti di
programmazione, sia un sistema di calcolo basato su un insieme di regole di riduzione che
consente di studiare le propriet semantiche di funzioni e programmi.
Le funzioni giocano un ruolo importante nella definizione della semantica dei linguaggi di
programmazione, poich il significato di un programma sequenziale pu essere considerato una
funzione dai valori in input a quelli in output. Inoltre, le funzioni hanno un ruolo essenziale
in matematica, e infatti gran parte della teoria delle funzioni, comprese le questioni che
riguardano la computabilit, furono sviluppate come parte della logica matematica prima
ancora della nascita dei calcolatori. Tant vero che negli anni 30 del secolo scorso, il logico
americano Alonzo Church ide il -calculus [Chu41, Bar84, Bar90] come sistema formale per
definire in modo non ambiguo funzioni e manipolarle in maniera puramente sintattica.
Originariamente, quindi, il -calculus fu sviluppato come un ramo della logica matematica per definire formalmente la nozione di funzione calcolabile, in alternativa alla teoria degli
insiemi. Infatti, un modo semplice per definire le funzioni quello di vederle come insiemi di
coppie ordinate. Una funzione f : A ! B stata definita (si veda la Definizione 2.12) come
un sottoinsieme del prodotto cartesiano A B: cos (a, b) 2 f se e solo se la f assume valore
b sullargomento a. Tale definizione tuttavia non considera in alcun modo laspetto computazionale delle funzioni, vale a dire il processo che dallargomento conduce al valore. Inoltre,
essa non consente di descrivere in modo chiaro e semplice i meccanismi che permettono di costruire nuove funzioni a partire da funzioni gi definite. Un tipico esempio che illustra queste
dicolt dato dai funzionali, vale a dire funzioni che hanno funzioni fra i loro argomenti o
che producono funzioni come risultato. Al contrario, il -calculus, come altri formalismi quali
le funzioni ricorsive o le macchine di Turing, descrive come, mediante regole di riscrittura,
determinare meccanicamente i valori associati ad ogni argomento e come comporre funzioni,
risolvendo cos i problemi summenzionati in modo naturale ed elegante. Inoltre, lestrema
semplicit del sistema di calcolo lo rende interessante come modello per lo studio di propriet.
Nella teoria della computabilit il -calculus ha permesso di formalizzare una risposta
(negativa) al problema della decisione di Hilbert. Il potere espressivo del formalismo infatti
equivalente a quello delle macchine di Turing, come appunto la tesi di Church-Turing sostiene:
il -calculus (non tipato) pu esprimere e calcolare tutte le funzioni eettivamente calcolabili.

92

Capitolo 5 -calculus

Il -calculus tuttavia enfatizza luso delle regole di riscrittura pi che loperato delle macchine
che implementano le regole. Il metodo di riscrittura il calcolo.
Il -calculus ha anche avuto un ruolo importante nella teoria dei linguaggi di programmazione e ha fornito contributi importanti anche alla definizione formale della semantica dei
linguaggi di programmazione:
tutti i linguaggi di programmazione funzionali (quali Lisp, ML, Scheme, Haskell) sono sostanzialmente derivati direttamente dal -calculus che a sua volta pu essere considerato
il pi semplice linguaggio di programmazione;
sebbene sia capace di rappresentare tutte le funzioni calcolabili, la semplicit della
sua sintassi e della sua semantica forniscono uno strumento eccellente per studiare il
significato dei concetti dei linguaggi di programmazione;
la semantica denotazionale, uno degli approcci pi utilizzati per specificare formalmente
la semantica dei linguaggi, ha avuto origine dalla ricerca nel campo del -calculus e fa
largamente uso della notazione fornita dal -calculus per esprimere funzioni di ordine
superiore.

5.1

La -convenzioni semplificative

Una funzione pu essere descritta da unespressione E che contiene simboli di funzioni gi


definite (o di cui assumiamo implicitamente di conoscere gi il significato) e variabili. Scriviamo E(x, y, . . . ) per indicare che lespressione E contiene le variabili x, y, . . . . In particolare,
se E(x) unespressione che contiene la sola variabile x ed a un valore in un opportuno
dominio D, indichiamo con E(a) il valore che la funzione descritta dallespressione E assume
quando il parametro formale x viene rimpiazzato con il valore attuale a. E(a) un elemento
di un altro dominio di valori D0 . Vista come insieme di coppie, la funzione descritta da E
{(a, E(a)) | a 2 D}.
Non tutte le espressioni possono essere considerate funzioni; esse infatti non sempre garantiscono la univocit del loro valore, quando le loro variabili vengono istanziate. Dicendo
ad esempio calcoliamo la funzione x y per gli argomenti 7 e 20, pu non essere chiaro
se x = 7 e y = 20 o viceversa. Inoltre considerando x y come una funzione di una sola
variabile, non sappiamo se essa una funzione f di x oppure una g di y.
Per evitare ambiguit ed imprecisioni necessario essere pi specifici. Ad esempio, per
definire la funzione successore per i numeri naturali in modo preciso, scriviamo:
f, dove f (x) = x + 1 per tutti gli interi non negativi x.
Questa definizione individua inequivocabilmente linsieme
{(x, x + 1) | x 2 N} .
Inoltre, considerando funzioni di due variabili, possiamo distinguere la funzione h, dove
h(x, y) = x

93

5.1 La -convenzioni semplificative


dalla k, dove
k(y, x) = x
cosicch h(5, 3) = 5 3 mentre k(5, 3) = 3 5.
Considerando ancora lespressione E(x, y) = x
g1 (x) = x

y,
y, possiamo quindi distinguere

y e g2 (y) = x

y,

in modo tale che ad esempio


g1 (0) = 0

y, g1 (5) = 5

y, g2 (3) = x

3.

Eettivamente, questa soluzione permette di evitare ambiguit e di caratterizzare univocamente quelle espressioni che rappresentano funzioni; essa, per, oltre a richiedere descrizioni
lunghe, ha lo svantaggio di richiedere che venga dato un nome ad ogni funzione definita. Inoltre, in alcune situazioni pu non essere chiaro come procedere nel definire una funzione: si
consideri ad esempio il caso in cui la funzione si ottenga come risultato dellapplicazione di
unaltra funzione ad un valore, oppure addirittura ad unulteriore funzione.
Per evitare questi problemi e per avere una notazione pi compatta, Alonzo Church ha
introdotto unoperazione che nota come -astrazione. Essa permette di specificare una
funzione ed i suoi argomenti nel modo seguente:
Sia E unespressione la cui variabile pu assumere valori in un dominio D. La
funzione
f : D ! D0
definita da

viene scritta

f x = E, 8x 2 D
x : D.E.

Quando il dominio D evidente dal contesto si scrive semplicemente x.E.


La costruzione che prevede la giustapposizione del prefisso x. ad una espressione E viene
chiamata -astrazione o semplicemente astrazione. Essa pu essere vista come un costruttore di funzioni; al contrario, lapplicazione di funzione un distruttore di funzioni. La
stringa x. stabilisce un legame per tutte le occorrenze della variabile x in E per le quali non
vi un legame pi interno. Intuitivamente, x il parametro formale della funzione.
Per associare ad una -espressione un nome, questo viene scritto a sinistra del simbolo
, mentre lespressione viene scritta alla sua destra. Ad esempio, per associare il nome
succ alla funzione x.x + 1, scriveremo: succ x.x + 1. In eetti con h T intendiamo
che h rappresenta integralmente T . Questo, oltre ad essere un modo per attribuire un nome
alla espressione T , stabilisce anche che ogni volta che si voglia considerare unespressione
contenente il simbolo h, questo una sorta di segnaposto per T .
La -astrazione, come descritta sopra, permette di legare una sola variabile, e quindi
di definire solo funzioni unarie. Le funzioni di pi variabili vengono descritte come definizioni successive di funzioni unarie. Spesso, per semplicit, rappresenteremo funzioni di pi
argomenti omettendo i ripetuti; ad esempio, xyz.E sar unabbreviazione di x. y. z.E.

94

Capitolo 5 -calculus
Se consideriamo le espressioni sopra menzionate, abbiamo allora
g1 x.x y
h x. y.x y

g2 y.x y
k y. x.x y

e conseguentemente
g1 (0) ( x.x y)(0) = 0 y,
g2 (3) ( y.x y)(3) = x 3,
h(5)(3) ( x. y.x y)(5)(3) = 5

3.

Altri esempi di -astrazione sono


x.x + 1
x.x x

x. y.x + 1
x.(x = 7) ! x

1, x + 1.

Si osservi che, mentre il termine x.x + 1 rappresenta la funzione successore, il termine


x. y.x + 1 rappresenta una funzione che applicata a due argomenti uguale alla funzione
successore sul primo dei due. La notazione p ! e1 , e2 indica la funzione condizionale, che
assume il valore di e1 se il predicato p vero, di e2 se p falso.
In tutti gli esempi appena visti, abbiamo evitato di scrivere il tipo dei parametri formali della funzione che stiamo definendo; quando potranno sorgere ambiguit scriveremo
esplicitamente i domini coinvolti nella definizione della funzione.
Nella -notazione, unespressione pu essere applicata ad un argomento di tipo opportuno;
loperazione di applicazione viene rappresentata come semplice giustapposizione; le parentesi
attorno allargomento non sono pi necessarie e, quando ritenute inutili, saranno omesse. Per
esempio
( x.x + 1) 2 = 2 + 1 = 3
e, se plus ( xy.x + y), allora

plus 2 3 = 5.

Per valutare lespressione ( x.E(x))d bisogna sostituire d a quelle occorrenze di x in E che


non sono legate da pi interni; tali x vengono dette libere. Gli esempi seguenti illustrano
questa gestione del meccanismo di sostituzione del parametro attuale a quello formale:
( x.( x.x))2 = x.x 6= x.2
( y.( x.y))3 = x.3.
Tuttavia questo processo di sostituzione non del tutto banale, perch bisogna assicurarsi
che esso non produca conflitti tra i nomi delle variabili. In unespressione x.E, il nome x della
variabile legata non rilevante per il significato della funzione; esso serve solo ad identificare
le occorrenze del parametro formale nel corpo E della funzione. Possiamo dunque considerare
sintatticamente uguali, in quanto intercambiabili, quelle espressioni che dieriscono solo per
il nome delle variabili legate. Abbiamo ad esempio che f y.yf rappresenta la stessa funzione
di f z.zf , al punto che potremo considerare questi due termini sintatticamente equivalenti. Se il nome di una variabile legata causa conflitti durante la sostituzione del parametro
formale con largomento della funzione, possiamo ridenominarla per poter eettuare una sostituzione corretta. Ad esempio, la valutazione di ( f y.f y)( x.x y) non y.( x.x y)y,
ma z.( x.x y)z. Senza la ridenominazione della y legata in z, la y libera della funzione
x.x y diventerebbe legata, cambiando il significato della valutazione.

95

5.2 Il principio di estensionalit

Una delle ragioni principali delluso della -notazione che essa permette di descrivere
naturalmente funzioni di ordine superiore, vale a dire funzioni che possono ricevere come
argomento, e produrre come risultato, altre funzioni.
Un esempio di funzione di ordine superiore il seguente:
plusc x.( y.x + y).
Abbiamo, ad esempio,
1. plusc 2 = ( x.( y.x + y)) 2 = y.2 + y
2. plusc 2 3 = ( x.( y.x + y)) 2 3 = ( y.2 + y) 3 = 2 + 3 = 5.
La funzione plusc applicata al valore 2 ha come risultato una funzione che associa naturali
a naturali, sommando 2 al suo argomento. La funzione plusc pu essere dunque applicata
anche ad un solo argomento. Il questo caso il suo valore sar una funzione, che a sua volta
potr accettare un altro argomento e produrre come risultato un intero.
Considerare le funzioni come se fossero tutte unarie e trattare funzioni di pi argomenti
come sequenze di funzioni unarie detto currificazione 1 . La currificazione fondamentale per
avere un formalismo che permetta di rappresentare in modo naturale i meccanismi con cui le
funzioni vengono combinate fra loro per ottenerne di nuove.
La -notazione risulter utile per definire funzioni e per riferirsi ad esse senza dover necessariamente dare loro un nome. Nel seguito di queste note, la notazione, arricchita con altri
costrutti derivati ad essa riconducibili, costituir il metalinguaggio (si veda Sezione 6.5) per
descrivere le funzioni di interpretazione semantica di diversi linguaggi di programmazione.

5.2

Il principio di estensionalit

Un classico esempio di funzione di ordine superiore sono gli iteratori. Consideriamo ad


esempio la funzione twice, che, data una funzione ed un naturale, applica la funzione prima
a questo argomento e poi al risultato dellapplicazione:
twice f x.f (f x)
Ad esempio,

twice succ ( f x.f (f x))( x.x + 1)


= x.( x.x + 1)(( x.x + 1)x)
= x.( x.x + 1)(x + 1)
= x.(x + 1) + 1.

Osserviamo adesso che lapplicazione di twice a succ ha fornito una nuova funzione x.(x+
1) + 1 che sommer 1 due volte consecutive al proprio argomento. Non possiamo dire tuttavia
che questa la funzione che prende un valore intero e gli somma 2, perch non vi nella
nostra notazione alcun modo di esprimere la propriet associativa della somma e trasformare
x.(x + 1) + 1
1

Loperazione di currificazione prende il nome dal logico americano Haskell Brooks Curry.

96

Capitolo 5 -calculus

in
x.x + (1 + 1)
e quindi in
x.x + 2.
Tuttavia, possiamo aermare che le due -espressioni
x.(x + 1) + 1 e

x.x + 2

sono equivalenti, perch esse forniscono evidentemente lo stesso risultato per ogni argomento.
In altre parole, gli insiemi di coppie
{(a, ( x.(x + 1) + 1) a) | a 2 N} e {(a, ( x.x + 2) a) | a 2 N}
coincidono, anche se la funzione che essi individuano viene rappresentata in due modi
dierenti.
Il principio che permette di considerare due -espressioni equivalenti se descrivono lo stesso
comportamento input-output viene detto principio di estensionalit. Esso viene espresso
formalmente come segue:
Siano e1 : D ! D0 e e2 : D ! D0 due -espressioni unarie, che rappresentano
due funzioni che associano elementi di D ad elementi di D0 . Allora diciamo che
e1 ed e2 sono estensionalmente equivalenti su D se e solo se individuano la stessa
funzione:
8d 2 D.e1 d = e2 d.

Scriveremo in questo caso e1 = e2 , ovviamente distinto da e1 e2 che indica


luguaglianza sintattica delle due espressioni.

5.3

Operatori di n-upla

La -notazione uno strumento conveniente per definire funzioni composte. In questa sezione
descriviamo alcuni operatori che saranno utili allo scopo.
I primi operatori che consideriamo sono gli operatori di n-upla. Questi possono essere
utilizzati quando si desiderano formare funzioni di pi argomenti raggruppando questi ultimi
in ununica struttura.
Il costruttore di una n-upla organizza una sequenza ordinata di n espressioni in unespressione unica, in modo analogo a quanto avviene in programmazione tramite la struttura di
record. Ad esempio, date le espressioni T1 , . . . , Tn , il costruttore di n-upla fornisce la singola
espressione
hT1 , . . . , Tn i.
Ad ogni costruttore di n-ple sono associati n distruttori, detti proiettori, che consentono di
estrarre le singole componenti dalln-upla.
I costruttori ed i proiettori possono essere definiti tramite la -notazione nel modo
seguente:
Costruttori di n-ple: Dn x1 . . . xn x.xx1 . . . xn ;

97

5.3 Operatori di n-upla


Proiettori di n-ple: ni x.x( t1 . . . tn .ti ).
Date n espressioni T1 , . . . , Tn , ln-upla di queste dunque definita come
Dn T1 . . . Tn = x.xT1 . . . Tn .
Si verifica facilmente che
ni ( x.xT1 . . . Tn ) = ( x.xT1 . . . Tn )( t1 . . . tn .ti )
= ( t1 . . . tn .ti )T1 . . . Tn
= Ti .

Ne segue che lespressione x.xT1 . . . Tn rappresenta eettivamente nella -notazione lnupla hT1 , . . . , Tn i. Nel seguito, per comodit di notazione, useremo direttamente hT1 , . . . , Tn i
per rappresentare unn-upla e ni per indicare il selettore del suo i-esimo elemento (i n).
Come abbiamo gi visto, la -notazione considera tutti gli operatori come se fossero unari.
In alcuni casi tuttavia pu essere pi naturale fornire tutti gli argomenti ad una funzione n-aria
simultaneamente. In altre parole, una funzione n-aria pu essere trasformata in una funzione
unaria il cui argomento sia una n-upla. Per fare questo, si raggruppano gli argomenti della
funzione in una n-upla e si usano i proiettori per recuperare volta per volta largomento
opportuno. A partire dalla -espressione
f x1 . . . xn .E(x1 , . . . , xn ),
nella quale E(x1 , . . . , xn ) indica unespressione in cui compaiono le variabili x1 , . . . , xn ,
possibile costruire lespressione
f 0 x.E(n1 x, . . . , nn x),
rimpiazzando in E ciascuna xi con ni x. Per ogni n-upla hT1 , . . . , Tn i, si ha allora che
f 0 hT1 , . . . , Tn i = E(n1 hT1 , . . . , Tn i, . . . , nn hT1 , . . . , Tn i)
= E(T1 , . . . , Tn ) = f T1 . . . Tn .
Tramite le n-ple ed i proiettori possibile dunque ottenere le versioni non currificate delle
funzioni. Ad esempio, lespressione
somma x.(21 x) + (22 x).
tale che
somma h3, 5i ( x.(21 x) + (22 x))h3, 5i = 3 + 5 = 8.
Notazione 5.1. Per semplificare la notazione scriveremo le funzioni non currificate
semplicemente usando
(x1 , . . . , xn ).E(x1 , . . . , xn )
invece di
x.E(n1 x, . . . , nn x).

98

Capitolo 5 -calculus

Esistono due famiglie di operatori, indicizzate sui naturali, CurT oU ncurn e


U ncurT oCurn , che consentono di trasformare la versione currificata di una funzione n-aria
nella corrispondente non currificata, e viceversa. Essi sono definiti come segue:
CurT oU ncurn x.( (x1 , . . . , xn ).x x1 . . . xn ),
U ncurT oCurn xy1 . . . yn .xhy1 , . . . , yn i.
Con questa scelta si ha allora:
CurT oU ncur2 ( xy.x + y) ( x.( (x1 , x2 ).x x1 x2 ))( xy.x + y)
= (x1 , x2 ).( xy.x + y) x1 x2
= (x1 , x2 ).x1 + x2
e

U ncurT oCur2 ( (x, y).x + y) ( xy1 y2 .xhy1 , y2 i)( (x, y).x + y)


= y1 y2 .( (x, y).x + y)hy1 , y2 i
= y1 y2 .y1 + y2 .

5.4

Operatori di composizione

Come abbiamo visto nel Capitolo 2, la funzione composta g f di due funzioni f e g la


funzione che richiede di applicare successivamente prima la f e poi la g al risultato della prima
applicazione. Ovviamente perch questo abbia senso le due funzioni devono essere tali che il
dominio della g coincida con il codominio della f . Possiamo definire due -espressioni
comp xyz.x(yz) e comp0 xyz.y(xz)
che, qualora applicate a due funzioni, forniscano la loro composizione, utilizzando gli argomenti (cio le funzioni da comporre) nellordine in cui sono presentati oppure nellordine invertito.
In tal modo avremo ad esempio
comp succ double

( xyz.x(yz))( x.x + 1)( y.2y)


= z.( x.x + 1)(( y.2y) z)
= z.(( y.2y) z) + 1 = z.2z + 1,
0
comp succ double ( xyz.y(xz))( x.x + 1)( y.2y)
= z.( y.2y)(( x.x + 1) z)
= z.2(( x.x + 1) z) = z.2(z + 1).
Gli operatori di composizione possono essere scritti in forma infissa: utilizzeremo i simboli
e in modo tale che
comp f g f

g e comp0 f g f g.

Quindi, per ogni x,


(f

g) x = f (g x) e (f g) x = g(f x).

Inoltre, gli operatori di composizione sono entrambi associativi, per cui scriveremo
f1 f2 fn al posto di f1 (f2 ( (fn

fn ) ))

99

5.5 Il sistema di calcolo

ed analogamente per loperatore .


Loperatore permette di esprimere in modo chiaro e semplice lapplicazione sequenziale
di funzioni. Infatti, la notazione
(f1 f2 fn ) x

rappresenta lapplicazione di f1 ad x, quindi di f2 al risultato della prima applicazione, e cos


via fino allapplicazione di fn .
Esempio 5.2. Siano

Allora

5.5

f (x, y).hx + y, yi,


g (x, y).h2x, 3yi,
h (x, y).hx y, xi.
(f g h) h3, 4i = h(g(f h3, 4i))
= h(g h7, 4i)
= h h14, 12i = h2, 14i.

Il sistema di calcolo

La -notazione stata introdotta come formalismo per la rappresentazione di funzioni. In


realt essa non solo una notazione ma pone le premesse per un vero e proprio sistema di
calcolo. Il meccanismo fondamentale usato per ottenere nuove -espressioni a partire da altre
gi definite costituito dal passaggio di un argomento ad una funzione e dalla sua sostituzione
al posto di uno dei parametri formali nella funzione stessa. Nelle sezioni precedenti abbiamo
utilizzato alcune nozioni ad un livello puramente intuitivo, quali il passaggio di parametri,
lapplicazione di funzione, nonch la sua valutazione per certi argomenti. Queste nozioni
possono essere formalizzate definendo un vero e proprio sistema di calcolo, detto -calculus,
basato su specifiche regole di riscrittura.
Il -calculus pu essere definito in diversi modi, che si dierenziano in base alla presenza
di tipi, di operatori aggiuntivi e delle regole di calcolo usate. In questo capitolo introdurremo
il sistema puro, che dal punto di vista sintattico il pi semplice.

5.5.1

Sintassi del -calculus

Definizione 5.3. Dato un insieme numerabile Var di simboli distinti detti variabili, i cui elementi sono denotati da x, y, z, . . ., linsieme dei termini del -calculus definito attraverso
la seguente grammatica:
M ::= x | ( x.M ) | (M N )
Ad esempio, le espressioni

( x.x),

( x.( y.(x(xy)))),

( x.(xx))

sono termini del -calculus.


Dati due termini M, N 2 , diciamo che il termine ( x.M ) ottenuto da M per astrazione
della variabile x, mentre il termine (M N ) ottenuto per applicazione di M ad N . Loperazione
di applicazione si indica dunque come semplice giustapposizione di un termine ad un altro.
Nel seguito, per semplificare la notazione, adotteremo alcune convenzioni semplificative.

100

Capitolo 5 -calculus

Notazione 5.4. In primo luogo, ometteremo le parentesi pi esterne di un termine scrivendo


ad esempio x.(xx) anzicch ( x.(xx)). Inoltre, assumeremo che lapplicazione associa a
sinistra e che lastrazione associa a destra. Cosicch, ad esempio, possiamo scrivere
M N P, x( u.u)(vz), x(( u.u)v)z
per indicare rispettivamente
(M N )P, (x( u.u))(vz), (x(( u.u)v))z
e
x.xx,

x. y.xy

per indicare rispettivamente


x.(xx),

x.( y.(xy)).

Inoltre, quando pi variabili sono astratte in successione, assumeremo di poterle scrivere tutte
dopo un unico ; ad esempio, i termini
xyz.xyz, x( uvz.uzv), x( uv.u( z.zv))
saranno considerati abbreviazioni, rispettivamente, di
x.( y.( z.xyz)), x( u.( v.( z.uzv))), x( u.( v.u( z.zv))).
La sintassi mostra che tutti i termini del -calculus sono unari. Prendiamo ad esempio il
termine T xy.yx. Esso rappresenta un operatore che, una volta applicato a due argomenti,
a e b, applica b ad a. Tuttavia i due argomenti non devono necessariamente essere passati
ambedue a T . Infatti lapplicazione T a fornisce un nuovo operatore, che potremmo chiamare
Ta , che rappresenta quella funzione che, preso ora un solo argomento, lo applica ad a. Questo
fenomeno risulta pi chiaro se si ricorda che il termine T sintatticamente equivalente a
x.( y.yx).
Osservazione 5.5. Nella sintassi non compaiono simboli di funzione di base (come gli operatori aritmetici) n costanti (come i naturali). In tal senso, essa potrebbe sembrare meno
espressiva della sintassi delle -espressioni sottintesa dalle sezioni precedenti. In eetti, possibile dimostrare che sia i naturali che linsieme di tutte le funzioni calcolabili sono codificabili
nella semplice sintassi presentata in questa sezione.
Ad esempio, il naturale n pu essere rappresentato dal termine
n xy. x(x(. . . (x y) . . .)),
| {z }
n volte

mentre i valori booleani true e false possono essere rappresentati dalle funzioni ( selettori)
true xy.x

false xy.y.

A questo punto il condizionale p ! q, r rappresentato semplicemente dallapplicazione pqr,


dove p un valore booleano.
Lo scopo di questa sezione tuttavia quello di studiare la struttura dei termini e di descrivere ed analizzare propriet del meccanismo di calcolo proprio di essi. Per far questo
suciente il sistema puro e ad esso ci limiteremo.

101

5.5 Il sistema di calcolo

5.5.2

Semantica del -calculus

Il significato di un -termine il -termine risultante dalla sua valutazione, cio il -termine


ottenuto dopo aver eettuato tutte le applicazioni di funzioni contenute nel termine originario. Quindi, valutare un -termine vuol dire ridurlo finch non sono possibili ulteriori
semplificazioni.
La regola di riduzione principale coinvolge la sostituzione di occorrenze libere di variabili
con termini in maniera simile a quanto accade per la sostituzione dei parametri formali con i
parametri attuali in uninvocazione di funzione allinterno di un programma. Consideriamo il
termine
ab.a
(5.1)
Seguendo linterpretazione informale dei termini data precedentemente, esso rappresenta una
funzione che restituisce il primo dei suoi due argomenti, indipendentemente dal valore del
secondo. Osserviamo quindi che, sebbene sintatticamente distinto da esso, il termine uv.u
ha la stessa interpretazione di ab.a. I due termini considerati sono legati fra loro da una
semplice relazione: luno ottenibile dallaltro attraverso unoperazione di ridenominazione
delle variabili legate dal , che nellesempio in questione mette in corrispondenza a con u e
b con v.
Formalizziamo ora il concetto di occorrenza legata e libera di una variabile. A tale scopo,
introduciamo una notazione che permette unanalisi della struttura dei -termini e, quindi,
di ragionare su di essi.
Definizione 5.6. La relazione P occorre in Q (anche, P un sottotermine di Q) definita
per induzione strutturale come segue:
1. P occorre in P ;
2. se P occorre in M oppure in N , allora P occorre in M N ;
3. se P occorre in M , allora P occorre in x.M .
Ad esempio in xy( xy.x(xy)) ci sono due occorrenze di (xy) (quelle sottolineate), e tre
occorrenze di x. Inoltre, il termine x(yz) occorre in u(x(yz)) ma non in ux(yz), che per le
convenzioni usate uguale a (ux)(yz).
Definizione 5.7. Per una particolare occorrenza di x.M in un termine P , il corpo del x
considerato M .
Ad esempio, se
P ( y.yx( x.y( y.z)x))vw,

allora il corpo del primo y da sinistra

yx( x.y( y.z)x),


quello del x
y( y.z)x,
mentre quello del secondo y la sola variabile z.
Le variabili in un termine possono essere classificate secondo la loro occorrenza nel corpo
di un .

102

Capitolo 5 -calculus

Definizione 5.8. Sia M un termine del -calculus.


1. Una occorrenza della variabile x in M legata se e solo se essa si trova nel corpo di un
x in M , altrimenti libera.
2. Se una variabile ha almeno una occorrenza libera in M viene detta variabile libera di
M ; linsieme delle variabili libere di un termine M viene denotato con F V (M ).
3. Un termine senza variabili libere viene detto chiuso (si dice anche che un combinatore).
Si noti che una variabile x pu essere sia libera che legata in un certo -termine M , per
esempio se M x( x.x), ma una particolare occorrenza di x in M non pu essere allo stesso
tempo libera e legata.
Linsieme F V (M ) pu essere definito per induzione sulla sintassi dei -termini come segue:
F V (x) = {x};
F V ( x.N ) = F V (N ) \ {x};
F V (N P ) = F V (N ) [ F V (P );
F V ( (N ) ) = F V (N ).
Nel seguito scriveremo M N per indicare che M e N sono lo stesso termine o possono
essere ottenuti luno dallaltro attraverso unoperazione di ridenominazione delle variabili legate dal , come ad esempio y.(xy) e z.(xz). chiaro che la relazione una equivalenza
sui -termini che raggruppa in una stessa classe di equivalenza termini che dieriscono soltanto per il nome delle loro variabili legate e che possono essere resi sintatticamente identici
ridenominando queste ultime. Nel seguito non faremo alcuna distinzione tra termini tra loro
equivalenti.
Inoltre adotteremo la seguente convenzione sulle variabili : se i -termini M1 , . . . , Mn
sono utilizzati in un certo contesto (per esempio, una definizione, un termine pi grande),
allora in tali termini tutte le variabili legate sono (diverse tra loro e) diverse dalle variabili
libere.
Queste due assunzioni ci permetteranno di semplificare la definizione delloperazione di
sostituzione, che il cuore del meccanismo di valutazione del -calculus in quanto permettono
di evitare che si verifichino collisioni tra le variabili, come illustrato nellesempio seguente.
Esempio 5.9. [Collisione tra variabili] La regola principale del sistema di valutazione
chiamata -riduzione e coinvolge loperazione di applicazione di funzione. Un termine della
forma
( x.M )N
(5.2)
rappresenta lapplicazione di una funzione ad un argomento. Intuitivamente, il valore di questa applicazione viene calcolato passando largomento N alla funzione x.M . In questultima,
lastrazione rispetto alla variabile x indica il parametro formale coinvolto. Durante la valutazione dellespressione (5.2), largomento viene sostituito al posto di ogni occorrenza libera
della variabile x in M , cio al posto di tutte le occorrenze del parametro formale nel corpo
della funzione.

103

5.5 Il sistema di calcolo


Consideriamo ad esempio le seguenti applicazioni e le sostituzioni relative:
( ab.a)(xv)z

( b.xv)z

(5.3)

xv.

necessario evitare che il passaggio dellargomento alla funzione comporti lintroduzione di legami per le variabili libere dellargomento stesso. In particolare, le variabili libere
nellargomento N devono essere dierenti da tutte le variabili legate dai in M .
Eseguendo le stesse operazioni che in (5.3) senza preoccuparsi che le variabili dellargomento restino libere dopo la sostituzione, otteniamo infatti, partendo dal termine ( uv.u)(xv)z,
che -equivalente a quello in (5.3),
( uv.u)(xv)z

( v.xv)z

xz 6= xv.

Ne segue che due termini che hanno apparentemente la stessa interpretazione vengono ad avere
due valori diversi: questo dovuto al fatto che la variabile v, libera prima della sostituzione,
viene a trovarsi nel corpo di un v: questo fenomeno si chiama collisione di variabili e deve
essere evitato durante la valutazione, ridenominando la variabile legata come di seguito
( uv.u)(xv)z ( ub.u)(xv)z

( b.xv)z

xv.

Possiamo finalmente definire formalmente loperazione di sostituzione.


Definizione 5.10 (Sostituzione). Il risultato della sostituzione di N al posto delle occorrenze
libere di x in M , scritto M [N/x], definito per induzione sulla sintassi dei termini tramite
le seguenti clausole:
x[N/x]
y[N/x]
(M1 M2 )[N/x]
( x.M )[N/x]
( y.M )[N/x]

= N
= y
se x 6= y
= (M1 [N/x])(M2 [N/x])
= x.M
= y.(M [N/x])
se x 6= y

Loperazione di sostituzione fornisce il meccanismo per implementare lapplicazione di


funzione e ci permette quindi di definire formalmente la -riduzione.
Introduciamo prima alcune propriet delle relazioni binarie tra -termini.
Definizione 5.11.
1. Una relazione binaria R sui -termini detta compatibile (con le operazioni) se
M
MZ

R
R

N
NZ

2. Una relazione di riduzione sui


transitiva.

M
ZM

R
R

N
ZN

M
x.M

R
R

N
x.N

-termini una relazione compatibile, riflessiva e

3. Una relazione di congruenza sui -termini una relazione di equivalenza compatibile.


Definizione 5.12. Siano le relazioni binarie
regole seguenti:

! , =) e = sui

-termini definite dalle

104

Capitolo 5 -calculus

1.
( x.M )N ! M [N/x]

M ! N

MZ ! NZ

2.

M ! N

M =) M
3.

M ! N

ZM ! ZN
M =) N

M =) N

M =) N

M= N

M= N

N= M

M ! N

x.M !

x.N

N =) L

M =) L
M= N

N= L

M= L

Tali relazioni sono denominate come segue:


M ! N : M si -riduce a N in un passo;
M =) N : M si -riduce a N ;
M = N : M -convertibile a N .
Si noti che per definizione abbiamo che ! una relazione compatibile, =) una
relazione di riduzione e = una relazione di congruenza.
La relazione di -riduzione in un passo ! descrive leetto dellapplicazione di funzione. Si noti che, grazie alle regole di compatibilit, la -riduzione pu avvenire in qualsiasi
contesto. La relazione di -riduzione =) descrive leetto dellapplicazione di una sequenza,
eventualmente nulla, di -riduzioni, mentre la relazione di -conversione = sostanzialmente
la sua chiusura simmetrica.
Osservazione 5.13 (-conversione). Per semplicit, nella nostra presentazione del -calculus
abbiamo scelto di identificare termini che dieriscono solo per il nome delle variabili legate. Una alternativa consiste nellintrodurre esplicitamente nel calcolo loperazione di
ridenominazione delle variabili legate, detta -conversione.
Se x e y sono variabili e M un -termine in cui y non occorre, allora diciamo
che x.M -convertibile in y.M 0 e scriviamo
x.M ! y.M [y/x]
In origine, questa era la prima regola di riscrittura del calcolo, da cui il suo nome e quello
della regola introdotta nella Definizione 5.12. L-conversione comunque necessaria per
implementare gli algoritmi di valutazione dei termini del -calculus.
Osservazione 5.14 (-conversione). Oltre ad -conversione e -riduzione, c unaltra regola
di riscrittura usata in letteratura, detta -conversione.
Se x una variabile e M un -termine in cui x non occorre, allora x.M x si
-converte a M e scriviamo
x.M x ! M

105

5.5 Il sistema di calcolo

Intuitivamente, questa regola consente di dichiarare identici due termini sulla base del principio che se essi si comportano allo stesso modo (una volta applicati ad un parametro) devono
quindi essere considerati identici. Quando diciamo che x.(M x) e M si comportano allo
stesso modo, intendiamo dire che per ogni N : ( x.(M x))N = (M x)[N/x] = M N . In pratica
la regola di -conversione giustifica una visione estensionale delle funzioni: cio due funzioni
sono uguali se producono gli stessi valori quando vengono passati loro gli stessi argomenti.
La regola di -conversione non strettamente necessaria per valutare -termini; noi la
menzioniamo per completezza.
Un termine della forma ( x.M )N chiamato -redesso, terminologia derivata da reduction expression che significa espressione che pu essere -ridotta. Il termine M [N/x]
risultante dalla -riduzione chiamato contratto. Lo scopo della valutazione di un -termine
quindi quello di ridurlo finch non contiene pi -redessi. Il termine cos ottenuto viene
detto forma normale e rappresenta la valutazione del -termine originario.
Definizione 5.15 (Forma normale). Diciamo che P una -forma normale se P non contiene
alcun -redesso. Un termine M si riduce a -forma normale (o ha -forma normale) se esiste
un termine N in -forma normale tale che M =) N .
Nel -calculus una funzione calcolabile (rappresentata da) una qualche -espressione in
grado di riscriversi fino a raggiungere una -forma normale. Esistono per anche termini che
generano una successione infinita di riscritture senza mai raggiungere una -forma normale,
che perci rappresentano funzioni non calcolabili. Un tipico esempio dato dallapplicazione
del duplicatore x.xx a se stesso
( x.xx)( x.xx).
Infatti, durante il processo di riduzione, il termine non fa altro che riprodurre se stesso:
( x.xx)( x.xx) =) ( x.xx)( x.xx) =) ( x.xx)( x.xx) =) . . .
La caratteristica di poter definire funzioni calcolabili e non calcolabili insieme alla ricorsione, rende il -calculus del tutto equivalente alle macchine di Turing ma con un approccio
completamente a-temporale.
Vale la pena notare che un termine potrebbe contenere pi di un redesso e potrebbe quindi
ridursi in diversi modi; ad esempio, i redessi presenti in
( x.x)(( u.uv)t)
sono stati sottolineati. Abbiamo allora
( x.x)(( u.uv)t) =) ( u.uv)t
ma anche
( x.x)(( u.uv)t) =) ( x.x)(tv).
Il criterio con cui viene scelto il redesso successivo da ridurre viene detto strategia di
riduzione. Ci sono varie strategie, come ad esempio quella detta normal order, che sceglie
sempre il redesso pi a sinistra tra quelli pi esterni, o quella detta applicative order che
invece sceglie il redesso pi a sinistra tra quelli pi interni.
Bench ci siano varie strategie di riduzione, vale tuttavia la seguente propriet di
confluenza o Church-Rosser :

106

Capitolo 5 -calculus
Se P =) Q e P =) R, allora esiste un termine S tale che Q =) S e R =) S.

Da questa propriet segue immediatamente che se un termine ha una -forma normale


allora questa unica (a meno di -conversione, ovviamente). Intuitivamente, la riduzione
pu essere pensata come un processo di calcolo e la propriet di confluenza assicura lunicit
del risultato per tutte le computazioni che terminano. Inoltre la -forma normale, se esiste,
pu essere raggiunta usando la strategia normal order, o qualsiasi altra, perch la -forma
normale indipendente dal criterio di riduzione utilizzato (anche questa propriet dovuta a
Church-Rosser). Quindi una riduzione in normal order pu avere uno dei seguenti due esiti:
1. raggiunge una -forma normale unica (a meno di ridenominazioni di variabili legate);
2. non termina mai.
Sfortunatamente non c un procedimento algoritmico per determinare per un
arbitrario quale di queste due situazioni si verificher.

5.6

-termine

Esercizi

5.1 Quali dei seguenti termini


(x(xx)x), (x((x)x)x), x(xx)x, y(yy)y, y(yyy), x(xxx);
(xy)(xy), xyxy, xy(xy), xz(xz);

y.(xy)(xy), y.xyxy, y.xy(xy), z.xz(xz), t.xz(xz);

zx.xz(xz), xz.xz(xz), x.( z.xz(xz)).

possono essere considerati sintatticamente equivalenti, sfruttando le convenzioni stabilite


precedentemente?
5.2 Determinare la forma normale dei termini
( z.z)( z.z), ( zy.yz)(zy), ( yz.y(yz))(+3)2.

5.3 I due termini (( yz.z(yz))( a.a) e ( yz.yzz)( ab.ba) possono essere considerati uguali?
Perch?
5.4 Si ponga

S xyz.xz(yz)
B xyz.x(yz)

K xy.x
C xyz.xzy

I x.x
W xy.xyy.

Definire S in termini di B, C, W, definire I in termini di S, K, definire C in termini di S, B, K.


5.5 Dimostrare che SK = KI.
5.6 Trovare un -termine Y tale che, per ogni variabile x, Y x = x(Y x).
5.7 Trovare la forma normale dei due termini ( y.yyy)(KI(SS)) e SSSSSSS.
5.8 Scrivere un termine che contiene almeno due redessi, ha una forma normale ma pu anche dar
luogo ad una sequenza di riduzioni infinita.
5.9 Usando il termine Y dellesercizio precedente, dimostrare che, per ogni termine M , esiste un
termine X tale che X = F X.

107

5.6 Esercizi
5.10 Esibire un termine

tale che, per ogni coppia di variabili distinte x, y,


S = x,

K = y.

5.11 Sia (vedi Sezione 5.5):


n xy. x(x(. . . (x y) . . .)).
| {z }
n volte

Esibire:

un termine s tale che, per ogni n, s n = n + 1,


un termine A tale che A m n = m + n,
un termine P tale che P m n = m n.
5.12 Un grafo orientato i cui nodi sono etichettati con -termini si dice grafo di riduzione se
non esistono in esso due nodi etichettati dallo stesso termine;
se un nodo etichettato con M e M ! N , allora esiste un nodo etichettato con N .
Mostrare i grafi di riduzione dei termini
K( x.Ixx)( x.Ixx)), II(III), KI(WI(WI)).

5.13 Si trovi un termine il cui grafo di riduzione ha la struttura seguente:


/
O
o

Capitolo 6

Domini per la semantica


denotazionale

SOMMARIO
Questo capitolo introduce le basi matematiche per la semantica denotazionale dei linguaggi
di programmazione. Introdurremo i concetti di insieme parzialmente ordinato completo,
funzione continua, minimo punto fisso e soluzione di un sistema di equazioni mutuamente
ricorsive. Presenteremo quindi i concetti di base della teoria dei domini ed alcuni operatori
che permettono di costruire domini a partire da domini pi semplici. Infine, definiremo un
metalinguaggio per esprimere le funzioni utilizzate per descrivere la semantica denotazionale di una vasta classe di linguaggi di programmazione e mostreremo che i costrutti del
metalinguaggio preservano la continuit.
Per studiare la semantica dei linguaggi di programmazione importante definire una teoria
matematica che permetta di parlare di significati. A tale scopo, la semantica denotazionale usa
la teoria dei domini e le funzioni sui domini. Dana Scott svilupp la teoria dei domini [Sco76]
per fornire un modello per il -calculus cos da gettare delle basi consistenti per la semantica
denotazionale. Senza un tale fondamento, non avremmo motivo di credere che le definizioni
denotazionali hanno realmente un significato matematico. Allo stesso tempo, la teoria dei
domini fornisce una valida interpretazione per funzioni e tipi definiti ricorsivamente.
La nozione centrale della teoria dei domini quella di dominio semantico, un insieme di
elementi, raggruppati perch condividono importanti propriet, strutturato da una relazione
di ordinamento parziale, v, basata sulla quantit di informazione associata ai singoli elementi.
Ogni dominio fornisce un insieme di operazioni che ben si comportano rispetto alla struttura
e che permettono di assemblare e disassemblare gli elementi del dominio stesso.
I domini permettono quindi di parlare di quantit di informazione contenuta in un elemento e, soprattutto, di elementi infiniti in termini delle loro approssimazioni finite. Infatti, i
domini garantiscono che tutte le sequenze, anche infinite, di elementi sempre pi definiti hanno un limite di cui gli elementi della sequenza sono approssimazioni via via migliori. Questa
propriet, che permette di rappresentare informazione infinita come limite di sequenze di elementi con informazione finita, essenziale per costruire una teoria delle funzioni, perch una
funzione ha un carattere intrinsecamente infinito, dovendo essere in generale definita per una
quantit infinita di argomenti. Analogo discorso vale per i programmi scritti in un linguaggio.
Quindi, il concetto di approssimazione connesso alla relazione di ordinamento parziale riveste
un ruolo fondamentale.

110

Capitolo 6 Domini per la semantica denotazionale

I domini sono anche dotati di un elemento minimo, ?, che rappresenta assenza di informazione. In pratica esso un elemento totalmente indefinito, che la peggiore approssimazione
di un qualsiasi elemento. La presenza di un elemento minimo nei domini permette di poter
considerare totali tutte le funzioni usate nella nostra indagine sulla semantica denotazionale.
Infatti, piuttosto che dire che una funzione f non definita su un elemento d del suo dominio,
scriveremo f (d) =?, dove ? lelemento minimo del codominio di f . Lelemento minimo
inoltre fondamentale per la semantica dei linguaggi di programmazione. Infatti, qualsiasi linguaggio che fornisce la possibilit di usare iterazione indefinita e funzioni ricorsive consente di
scrivere programmi che non terminano. Perci, per definire la semantica serve un meccanismo
per rappresentare la non terminazione e lelemento minimo pu essere visto come il risultato
di una computazione che non termina.
Definiremo vari operatori che permettono di costruire nuovi domini a partire da domini
pi semplici e mostreremo che le funzioni associate a tali costruzioni sono continue. Infatti,
quando si ha a che fare con insiemi strutturati, piuttosto che con insiemi senza alcuna struttura associata, di solito utile considerare funzioni che preservano la struttura, invece che
funzioni arbitrarie. Ci porta alla richiesta di monotonia, nel caso di insiemi parzialmente
ordinati (o poset), ed a quella di continuit, nel caso di insiemi parzialmente ordinati completi
(o cpo o domini). Le funzioni in questione costituiscono una sorta di -calculus esteso, un
metalinguaggio che nei capitoli successivi sar usato come formalismo matematico per definire la semantica denotazionale dei vari linguaggi considerati. Il fatto che il metalinguaggio
permetta di descrivere solo funzioni continue, ci consentir di assumere la continuit delle
funzioni che via via introdurremo, evitando di intercalare la loro presentazione con le relative
prove di continuit.

6.1

Esempi duso dei domini nella semantica denotazionale

Definizioni ricorsive vengono utilizzate sia nei linguaggi di programmazione, che solitamente
permettono per esempio la definizione di funzioni o strutture dati (es. liste, alberi) ricorsive,
che nelle specifiche dei linguaggi stessi (le grammatiche che generano i termini di un linguaggio
sono solitamente ricorsive). Costrutti familiari nella pratica della programmazione vengono
altrettanto spesso spiegati intuitivamente tramite equazioni ricorsive. Si pensi ad esempio
al costrutto while ed allequazione
while e do c = if e then begin c; while e do c end,
con la quale si indica che lesecuzione di un ciclo while consiste nella valutazione dellespressione booleana e seguita, nel caso in cui essa sia vera, dallesecuzione della sequenza di
comandi c e da una nuova esecuzione del ciclo while.
Normalmente lutente di un linguaggio di programmazione non si cura dei fondamenti logici
delle definizioni ricorsive, tuttavia necessario garantire la validit delle definizioni ricorsive. Lattribuzione di un significato ad unequazione ricorsiva non per sempre immediato.
Consideriamo ad esempio la seguente equazione ricorsiva:
f x.(x = 0) ! 1, f (x + 1).

(6.1)

In eetti, si potrebbe obiettare che questa non una vera e propria definizione di funzione,
in quanto f definito in termini di se stesso. La (6.1) deve essere vista piuttosto come una

6.1 Esempi duso dei domini nella semantica denotazionale

111

specifica di funzione, vale a dire la descrizione di vincoli che la funzione f deve soddisfare. Tale
specifica indica che una qualsiasi funzione che la rispetti deve dare risultato 1 quando riceve
0 come argomento. Tuttavia il suo comportamento sugli altri argomenti non univocamente
determinato. Infatti lunico altro vincolo che viene richiesto quello di dare sempre lo stesso
risultato per tutti gli argomenti maggiori di 0. Da un punto di vista computazionale il
significato intuitivo della specifica daltra parte ovvio:
per calcolare la f su un argomento x, si controlli innanzitutto se x = 0, nel qual
caso f (x) = 1; altrimenti si richiami la f sullargomento x + 1.
Seguendo questo procedimento di calcolo, ed indicando con ? la non definizione (lassenza
di informazione), chiaro che la specifica (6.1) individua la funzione
g x.(x = 0) ! 1, ?,
cio la funzione che d risultato 1 per argomento 0 e che non definita per gli altri argomenti
perch il procedimento di calcolo procede allinfinito per essi.
In generale, diciamo che una funzione soddisfa una specifica se e solo se essa una sua
soluzione. In eetti, una specifica come la (6.1) pu essere vista come unequazione nellincognita f . Una soluzione allora una qualunque funzione che, sostituita al posto di f , renda
lequazione unidentit.
Ci si pu facilmente rendere conto che la funzione g una soluzione dellequazione (6.1).
Sostituendo la definizione di g nella parte destra dellequazione (6.1) otteniamo:
x.(x = 0) ! 1, ( x.(x = 0) ! 1, ?)(x + 1)
|
{z
}
g

= x.(x = 0) ! 1, (x + 1 = 0) ! 1, ?
= x.(x = 0) ! 1, ?
(dato che non esiste un naturale x tale che x + 1 = 0)
g.

Daltra parte importante notare come la g non sia lunica soluzione possibile; infatti, per
ogni k 2 N, ogni funzione della forma
gk x.(x = 0) ! 1, k
soddisfa la specifica, vale a dire soluzione dellequazione.
Tra tutte le possibili soluzioni, la g ha comunque un ruolo particolare; essa corrisponde ai
risultati che si ottengono interpretando la specifica in modo meccanico, cos che, per valutare
la f per un generico x > 0, si espande il corpo della f per scoprire che necessario valutarla
per x + 1, quindi per x + 2, e cos via.
Si noti che la funzione g meno definita di ciascuna delle gk . Infatti, sullunico argomento
su cui g definita, le gk sono anchesse definite ed assumono lo stesso valore:
8k. g(0) = gk (0).
La discussione precedente evidenzia la necessit di individuare un metodo per risolvere
equazioni ricorsive, nonch per poter scegliere fra eventuali soluzioni multiple. Allo scopo di
caratterizzare le soluzioni di unequazione ricorsiva, diamo innanzitutto una definizione che
useremo spesso nel seguito.

112

Capitolo 6 Domini per la semantica denotazionale


Data una funzione f : D ! D, diciamo punto fisso di f un qualsiasi elemento
d 2 D tale che f d = d.

Per spiegare meglio limportanza di questo concetto, consideriamo unequazione, per


esempio sugli interi
x = 2x + 1.
Possiamo vedere la sua soluzione come il punto fisso della funzione dagli interi agli interi
f x.2x + 1,
cio 1. In modo analogo, una soluzione dellequazione (6.1) pu essere vista come un punto
fisso della funzione
f.( x.(x = 0) ! 1, f (x + 1))
che una funzione che prende come argomento una funzione e restituisce come risultato
unaltra funzione, vale a dire
: (N ! N) ! (N ! N).
Un altro esempio di funzionale il seguente

f act f. x.(x = 0) ! 1, x f (x

1)

che corrisponde evidentemente alla definizione della funzione fattoriale. Infatti, se poniamo
f act = x.(x = 0) ! 1, x f act(x

1)

allora evidentemente f act (f act) = f act.


Ogni soluzione di una specifica ricorsiva di funzione dunque un punto fisso del funzionale
associato alla specifica stessa. Tale funzionale ottenuto astraendo il membro destro della
specifica rispetto allincognita dellequazione.
Per poter scegliere tra diverse soluzioni di una specifica ricorsiva, risulta utile introdurre
un ordinamento fra funzioni che formalizzi lintuizione che una funzione unapprossimazione
di unaltra.
Siano f, g : D ! D0 . Diciamo che f approssima (o meno definita di) g, e
scriviamo f v g se
8x. se f (x) definita, allora f (x) = g(x).
Lesempio iniziale mostra che fra tutti i punti fissi del funzionale associato alla specifica
(6.1) ne esiste uno che meno definito di tutti gli altri e che corrisponde allintuizione operazionale della specifica stessa. Questa particolare soluzione viene chiamata minimo punto
fisso.
Vediamo ora come i concetti di approssimazione finita di una funzione e quello di minimo
punto fisso contribuiscano a fornire un modo eettivo per determinare una soluzione di una
specifica ricorsiva.
Si consideri innanzitutto la funzione x. ?, che ovunque non definita e che quindi
costituisce la peggior approssimazione di ogni funzione. Si applichi quindi il funzionale
associato alla specifica (6.1):
= x.(x = 0) ! 1, (x + 1) = g.

113

6.2 Insiemi parzialmente ordinati completi


La soluzione g stata ottenuta applicando il funzionale ad una sua approssimazione!
Si consideri ora il funzionale f act e si calcoli F act1 f act :
F act1 f act = x.(x = 0) ! 1, x (x

1) = x.(x = 0) ! 1, ? .

(6.2)

F act1 non ovviamente un punto fisso di f act , per una funzione pi definita di ,
ed assume sullargomento su cui definita lo stesso valore che su di esso assume la funzione
fattoriale. F act1 unapprossimazione della funzione fattoriale migliore di . Inoltre, F act1
ha, sullunico argomento per cui definita, un comportamento operazionalmente corrispondente alla specifica della funzione fattoriale, perch stata ottenuta interpretando la specifica
come un programma e sostituendo, al posto del richiamo ricorsivo della funzione, una sua
approssimazione. Il lettore potr ora verificare che, considerando la sequenza
F act2 f act F act1 , F act3 f act F act2 , . . .
si ottengono approssimazioni della funzione fattoriale via via migliori, e che il limite di questa
sequenza di funzioni la funzione fattoriale stessa. In altre parole, il minimo punto fisso della
specifica della funzione fattoriale pu essere ottenuto per approssimazioni successive. Inoltre,
ciascuna di queste approssimazioni pu essere rappresentata in modo finito e, ovviamente,
non ricorsivo.

6.2

Insiemi parzialmente ordinati completi

Cominciamo col definire le propriet strutturali degli insiemi che costituiscono i domini. A
questo proposito, si ricordi che una relazione binaria R su un insieme A una relazione di
ordine se riflessiva, antisimmetrica e transitiva (Definizione 2.7).
Definizione 6.1.
1. Un insieme parzialmente ordinato (poset) una coppia (D, v), dove D un insieme e
v una relazione di ordine parziale su D.
2. Un poset D totalmente ordinato se per ogni coppia d, d0 2 D abbiamo che d v d0 o
d0 v d.
3. Un insieme totalmente ordinato finito o numerabile viene chiamato catena.
Abbiamo gi detto, nellintroduzione di questo capitolo, che intuitivamente la relazione
di ordine parziale v basata sulla quantit di informazione associata ai singoli elementi
dellinsieme D. Qui facciamo notare che in un insieme totalmente ordinato la quantit di informazione di due elementi qualsiasi sempre confrontabile. In una catena, poi, ogni elemento
deve contenere informazione che consistente con quella contenuta dal suo predecessore; pu
essere uguale al suo predecessore o pu contenere informazione aggiuntiva.
Esempio 6.2.
1. Gli interi con la relazione di minore o uguale sono una catena.

114

Capitolo 6 Domini per la semantica denotazionale

2. Linsieme dei sottoinsiemi di un insieme con la relazione di contenuto o uguale un


poset.
Sia (D, v) un poset. Dati d, d0 2 D, diciamo che d precede immediatamente d0 se d v d0
e non c alcun d00 2 D tale che d v d00 v d0 . Si noti che la relazione di ordinamento v del
poset coincide con la chiusura riflessiva e transitiva della relazione precede immediatamente.
Un grafo (o diagramma) della relazione precede immediatamente chiamato diagramma di
Hasse del poset. Tali grafi sono spesso usati per rappresentare poset in maniera grafica. I nodi
del grafo rappresentano elementi di D, mentre gli archi rappresentano la relazione precede
immediatamente, con la convenzione che questi ultimi siano orientati verso lalto.
Ad esempio, i sottoinsiemi dellinsieme {a, b, c} con lordinamento di inclusione sono
rappresentati dal grafo seguente
{a, b, c}
{a, b}

{a, c}

{b, c}

{a}

{b}

{c}

{}
I naturali con il tradizionale ordinamento di minore o uguale possono essere rappresentati
come segue:

Si noti che se (D, v) un poset, allora per ogni A D si ha che (A, vA ), dove vA la
restrizione di v su A, un poset.
Le definizioni riportate di seguito servono come preparazione alla nozione di approssimazione di informazione e fissano le propriet di alcuni elementi di un ordinamento
parziale.
Definizione 6.3. Sia (D, v) un poset ed S un sottoinsieme di D; un elemento a 2 D
chiamato:
1. un maggiorante di S se d v a, 8d 2 S;
2. un minorante di S se a v d, 8d 2 S;
3. il massimo di S se a un maggiorante di S ed a 2 S;

115

6.2 Insiemi parzialmente ordinati completi


4. il minimo di S se a un minorante di S ed a 2 S.

Si noti che, dallantisimmetria della relazione v, segue immediatamente che il massimo


(minimo) di un poset, se esiste, unico.
Definizione 6.4. Sia (D, v) un poset ed S un sottoinsieme di D; un elemento di D
chiamato:
1. l estremo superiore (o least upper bound, o limite, o join) di SFse il minimo dei suoi
maggioranti. Nel seguito sar denotato da sup S (o anche da S).
2. l estremo inferiore (o greatest lower bound, o meet) di Sd se il massimo dei suoi
minoranti. Nel seguito sar denotato da inf S (o anche da S).

Per denotare lestremo superiore (inferiore) utilizzeremo soltanto sup (inf) omettendo in
D tutte le volte che il dominio in questione risulti evidente dal contesto. Alcune volte, per
far capire in quale dominio viene determinato lestremo superiore verr utilizzato un apice od
un indice che suggerisca il dominio (ad esempio scriveremo sup0 S invece di sup S in D0 ).
Naturalmente, lunicit del massimo (minimo) di un poset, implica quella dellestremo
inferiore (superiore).
Esempio 6.5.
1. Linsieme dei naturali ha minimo, ma non ha maggioranti; talvolta il maggiorante viene
aggiunto e viene denotato da !.
2. Linsieme dei sottoinsiemi di un insieme ordinato per inclusione ha per minimo linsieme
vuoto e per massimo linsieme originario.
3. Consideriamo il seguente poset D:
g
f
d

c
a

e siano S = {a, b, c}, S 0 = {a, b, c, d, e}. S ha quattro maggioranti in D: d, e, f, e g, ma


non ha alcun estremo superiore. Daltra parte S ha un estremo inferiore che anche il
minimo (a). S 0 ha due maggioranti di cui f il minimo ed quindi lestremo superiore
di S 0 , ma anche S 0 non ha massimo. Linsieme D ha invece sia massimo (g) che minimo
(a).
Associate alle definizioni precedenti abbiamo le seguenti proposizioni, di facile
dimostrazione:

116

Capitolo 6 Domini per la semantica denotazionale

Proposizione 6.6.
Dato un insieme parzialmente ordinato, abbiamo che:
1. Se un sottoinsieme ha massimo, questo anche lestremo superiore.
2. Ogni catena finita ha un massimo.
3. Ogni sottoinsieme di una catena una catena.

Proposizione 6.7.
Sia (D, v) un cpo, {xi | i 2 I} una catena su D e d 2 D un elemento qualsiasi. Se xi v d,
per ogni i 2 I, allora sup{xi | i 2 I} v d.
Dimostrazione. Per definizione di estremo superiore, se d un maggiorante della catena, il
minimo degli maggioranti sup{xi | i 2 I} devessere non pi grande di d.
Proposizione 6.8.
Sia (D, v) un cpo e {xi | i 2 I} e {yi | i 2 I} due catene su D. Se xi v yi , per ogni i 2 I,
allora sup{xi | i 2 I} v sup{yi | i 2 I}.
Dimostrazione. Dallipotesi, e per definizione di estremo superiore, segue che per ogni i 2 I,
xi v yi v sup{yi | i 2 I}. Perci, per la Proposizione 6.7 (prendendo d = sup{yi | i 2 I}), si
ha sup{xi | i 2 I} v sup{yi | i 2 I}.
I domini utilizzati per definire la semantica di linguaggi di programmazione sono insiemi
parzialmente ordinati (poset), che hanno sempre un elemento minimo e sono tali che lestremo
superiore delle loro catene esista sempre. Essi sono chiamati ordinamenti parziali completi,
abbreviati in cpo, dallinglese complete partially ordered set.
Definizione 6.9. Un poset (D, v) completo ( cpo set, cpo o dominio) se e solo se
1. D ha il minimo, indicato con ?;
2. ogni catena in (D, v) ha estremo superiore in D.
I poset descritti negli esempi precedenti sono tutti cpo tranne i naturali, che hanno minimo
ma non hanno estremo superiore della catena costituita da tutto linsieme, e gli interi, che
non hanno n massimo n minimo.
In un cpo dunque lestremo superiore di una catena riassume linformazione che stata
accumulata in maniera consistente lungo la catena stessa. Poich una catena pu avere un
numero infinito di elementi distinti, lestremo superiore agisce come elemento limite per la
sequenza infinita. Daltro canto, una catena pu avere elementi duplicati, poich v include
anche luguaglianza, e pu anche assumere un valore costante da un certo punto in poi. Nel
qual caso, lestremo superiore proprio quel valore.

6.3 Funzioni continue e minimo punto fisso

6.3

117

Funzioni continue e minimo punto fisso

Una funzione f : D ! D0 pu essere vista computazionalmente come un agente che trasforma


un elemento d di (D, v) in un elemento d0 di (D0 , v0 ). La teoria della computazione si
interessa a come questa trasformazione pu essere attuata, anche quando d infinito, tramite
procedimenti eettivi.
Linsieme D ! D0 delle funzioni totali da D a D0 contiene molte funzioni con un comportamento anormale che preclude la possibilit di calcolarle o anche solo approssimarle tramite
un computer. Per esempio, consideriamo la funzione H : (N ! N) ! (N ! N) definita da
H g. x.(g(x) =?) ! 0, 1.
Chiaramente, se accettiamo questa funzione nella teoria dei domini, che fornisce le basi fondazionali per la semantica denotazionale, allora ammettiamo una funzione che risolve il problema della fermata (cio, se una funzione g arbitraria termina regolarmente quando applicata
ad un argomento x arbitrario), che sappiamo essere non decidibile. Per escludere questa, ed
altre funzioni dal comportamento anormale, imponiamo alcune restrizioni sulle funzioni in
modo da assicurare che esse abbiano un comportamento accettabile.
Si pu pensare ad un argomento d di una funzione come ad una molecola di informazione
ed assumere che f trasformi d trasformando prima gli atomi di d e poi ricomponendoli per
ottenere d0 , una molecola di D0 . Questo suggerisce che se d1 e d2 sono due elementi di D tali
che d2 contiene gli stessi atomi di d1 ed eventualmente qualcosa di pi, cio d1 v d2 , allora
ragionevole aspettarsi che f d1 v0 f d2 . Una funzione che preserva la quantit di informazione
viene detta monotona.
Quando un oggetto infinito e viene usato come argomento di una funzione, pu non essere
possibile immagazzinarne la rappresentazione in un computer con memoria finita e quindi,
data una funzione f , il risultato di f e pu non essere determinabile nel modo convenzionale.
Comunque, se e lestremo superiore di una catena {ei | i 2 I} dove ciascun ei ha grandezza
finita, allora ciascun ei pu essere memorizzato separatamente ed f applicata ai vari ei in
successione. In questo caso il valore di f e pu essere determinato come lestremo superiore
della catena {f ei | i 2 I}. Una funzione che ore questo tipo di possibilit detta continua.
Le funzioni che vengono usate per definire la semantica denotazionale dei linguaggi di
programmazione sono monotone e continue. Di seguito riportiamo le definizioni formali di
queste due importanti nozioni, utilizzando la seguente notazione: se f una funzione che
mappa elementi di un cpo D in elementi di un cpo D0 ed S un sottoinsieme di D, allora con
f S indichiamo linsieme {f x | x 2 S}.
Definizione 6.10. Siano (D, v) e (D0 , v0 ) due cpo.
1. Una funzione f : D ! D0 si dice monotona se e solo se
8x, y 2 D, x v y implica f x v0 f y;
2. Una funzione f : D ! D0 si dice continua se e solo se per ogni catena K di D
(a) esiste sup0 (f K);
(b) f (sup K) = sup0 (f K).

118

Capitolo 6 Domini per la semantica denotazionale

In pratica, una funzione tra due cpo monotona quando preserva la relazione dordine
ed continua quando preserva e rispetta gli estremi superiori delle catene del dominio.
Si noti che la nozione di funzione continua introduce in matematica discreta il concetto di
limite, solitamente utilizzato in matematica del continuo.
Il teorema che segue chiarisce la relazione tra funzioni monotone e funzioni continue.
Teorema 6.11. Siano (D, v) e (D0 , v0 ) due cpo. Se f : D ! D0 una funzione continua
allora f anche monotona.
Dimostrazione. Se consideriamo x, y 2 D con x v y e la corrispondente catena {x, y}, abbiamo che sup{x, y} = y. Siccome f continua, abbiamo anche che f (sup{x, y}) = f y =
sup{f x, f y} e quindi che f x v0 f y per definizione di estremo superiore.
In generale il viceversa di questo teorema non vero; esistono funzioni che sono monotone
ma non continue. Come esempio consideriamo il cpo N! , costituito dai naturali con il tradizionale ordinamento di minore o uguale (0 1 2 . . . ), ed esteso con un nuovo elemento
! tale che ! ! e, per ogni naturale n, n !. facile dimostrare che N! = (N [ {!}, )
un cpo. Consideriamo ora la funzione f : N! ! N! definita come segue:
f x.(x = !) ! !, 1.
facile verificare che f monotona. Essa non per continua: infatti se consideriamo
la catena {i | i 2 N} ottenuta prendendo tutti i naturali senza ! abbiamo che f (sup{i | i 2
N}) = f ! = ! 6= sup{f i | i 2 N} = 1.
Monotonia e continuit si implicano a vicenda soltanto quando gli argomenti della funzione
appartengono a cpo che contengono solo catene finite.
Teorema 6.12. Sia f : D ! D0 una funzione monotona e D contenga solo catene finite.
Allora f continua.
Dimostrazione. Sia {x0 , . . . , xn }, n 2 N, una catena su D. Siccome la catena finita, abbiamo
che sup{x0 , . . . , xn } = xn e quindi che f (sup{x1 , . . . , xn }) = f xn . Daltra parte, siccome f
monotona abbiamo anche che {f x1 , . . . , f xn } una catena di D0 il cui estremo superiore
f xn . Questo basta per concludere che sup0 (f {x1 , . . . , xn }) = f (sup{x1 , . . . , xn }) e quindi
che f continua.
Dalla definizione di funzione continua su un cpo segue banalmente la continuit della
funzione identit.
Lemma 6.13. Se D un cpo, la funzione identit su D continua.
Nel seguito, faremo uso di questa propriet di base della composizione di funzioni continue.
Lemma 6.14. Se D1 , D2 e D3 sono cpo e f : D1 ! D2 e g : D2 ! D3 sono due funzioni
continue, allora
g f : D1 ! D3
continua.

119

6.3 Funzioni continue e minimo punto fisso


Dimostrazione.
g f (sup{xi | i 2 I}) =
=
=
=

g(f (sup{xi | i 2 I}))


g(sup{f xi | i 2 I})
sup{g(f xi ) | i 2 I}
sup{g f (xi ) | i 2 I}

per
per
per
per

definizione
la continuit di f
la continuit di g
definizione.

Una volta definite le nozioni di ordinamento e di continuit si possono dimostrare alcune


propriet fondamentali delle funzioni continue che ci permettono di assegnare un significato alle definizioni ricorsive di funzioni. Un concetto importante quello di punto fisso di
una funzione, che ora possiamo definire formalmente perch disponiamo di una relazione di
ordinamento fra le funzioni e fra i loro argomenti.
Definizione 6.15. Dato un cpo D, una funzione f : D ! D ed un elemento d 2 D
1. d un punto fisso di f se f d = d;

2. d il minimo punto fisso di f se il minimo dei punti fissi di f ;


3. d il massimo punto fisso di f se il massimo dei punti fissi di f .
Esempio 6.16. Consideriamo il dominio piatto (si veda Sezione 6.4.1) dei naturali,
denotato con NAT, che pu essere rappresentato graficamente nel modo seguente:
0

ed alcuni esempi di funzioni da NAT in NAT.

1. La funzione f x.(x =?) !?, x monotona e quindi continua (NAT ha solo catene
finite). Tutti gli elementi di NAT sono suoi punti fissi e il minimo punto fisso ?.
2. Invece la funzione g x.(x =?) ! 1, ? non monotona. Infatti per ogni numero
naturale n abbiamo che ? n ma g ?= 1 6 ?= g n e quindi la funzione g non ha punti
fissi.
3. Un altro esempio di funzione non monotona h x.(x =?) ! 1, x. La funzione h ha
infiniti punti fissi (tutti i naturali diversi da ?) ma non ha minimo punto fisso.
In Sezione 6.1 abbiamo visto come i concetti di approssimazione finita di una funzione e
quello di minimo punto fisso contribuiscano a fornire un modo eettivo per determinare una
soluzione di una specifica ricorsiva. Il prossimo teorema, dovuto al matematico americano
Stephen Cole Kleene, mostra che, nel caso di funzioni continue, il minimo punto fisso
ottenibile come estremo superiore di una catena ed quindi approssimabile in maniera finita
con gli stessi elementi della catena.
Nel seguito, se f : D ! D una funzione, useremo la seguente notazione
f 0x = x
f i+1 x = f (f i x)

120

Capitolo 6 Domini per la semantica denotazionale

Teorema 6.17 (Teorema di Kleene per il minimo punto fisso). Sia (D, v) un cpo. Ogni
funzione continua f : D ! D ha il minimo punto fisso (indicato con fix f ) che uguale a
sup f i ?| i 2 N .
Dimostrazione. La prova si svolge in tre passi. Prima (passo 1) proviamo che {f i ?| i 2 N}
una catena e che sup{f i ?| i 2 N} il suo estremo superiore, quindi (passo 2) che sup{f i ?|
i 2 N} un punto fisso di f , infine (passo 3) che esso il minimo tra tutti i punti fissi di f .
1. Per induzione su N dimostriamo prima che {f i ?| i 2 N} una catena, cio che 8i :
f i ?v f i+1 ?.
Base dellinduzione. f 0 ?=?v f ?= f 1 ?, perch ?v d, 8d 2 D.
Passo induttivo. f i ?= f (f i 1 ?) v f (f i ?) = f i+1 ?, per la monotonia di f e lipotesi
induttiva (f i 1 ?v f i ?).
Ora, siccome D un cpo, questa catena ha estremo superiore sup{f i ?} (per abbreviare,
anche nel seguito, scriviamo {f i ?} anzicch {f i ?| i 2 N}).
2. Dimostriamo ora che sup{f i ?| i 2 N} un punto fisso di f :
f (sup{f i ?}) =
=
=
=
=

sup{f (f i ?)}
sup{f i+1 ?}
sup({f i+1 ?} [ {?})
sup({f i+1 ?} [ {f 0 ?})
sup{f i ?}

per la continuit di f
per la definizione di f i
il sup non varia aggiungendo ?
perch ?= f 0 ?

3. Dimostriamo ora che ogni punto fisso della funzione f un maggiorante della catena
{f i ?} e quindi che ogni punto fisso maggiore o uguale dellestremo superiore della
catena. La dimostrazione procede per induzione su N. Sia x un punto fisso, cio tale
che f x = x.
Base dellinduzione. f 0 ? = ?v x, perch ?v x, 8x 2 D.
Passo induttivo. Supponiamo che f i ?v x; dobbiamo dimostrare che f i+1 ? v x.
Abbiamo
f i+1 ? = f (f i ?)
v fx
= x

per definizione
per ipotesi induttiva e per la monotonia di f
perch x un punto fisso di f .

Questo basta per concludere che per ogni i 2 N abbiamo f i ?v x. Poich lestremo superiore di una catena per definizione il minimo dei maggioranti, abbiamo che
sup{f i ?} v x, e quindi che sup{f i ?} il minimo punto fisso di f .
Come immediata applicazione del teorema del punto fisso abbiamo il seguente corollario.
Corollario 6.18. Siano (D, v) e (D0 , v0 ) due cpo. Ogni funzionale continuo F : (D !
D0 ) ! (D ! D0 ) ha minimo punto fisso fix F , che pu essere assunto come il significato della
definizione (ricorsiva) corrispondente a F .
Osservazione 6.19 (Cpo e funzioni continue). Soermiamoci ora brevemente sullidea intuitiva alla base dei cpo e delle funzioni continue. Gli ordinamenti parziali completi corrispondono ai tipi di dati, dati che possono essere utilizzati come input o come output di una

121

6.3 Funzioni continue e minimo punto fisso

computazione. Gli elementi di un cpo sono visti come punti di informazione e x v y pu


essere interpretato come x approssima y, oppure x contiene una quantit di informazione
minore o uguale a quella di y, di conseguenza ? lelemento con minima informazione. Le
funzioni stesse possono essere pensate come dati utilizzati oppure prodotti da una computazione. In particolare, le funzioni calcolabili sono rappresentate come funzioni continue tra tali
cpo. Ci deriva dallidea intuitiva che la presenza di una unti di informazione nelloutput di
una funzione calcolabile debba dipendere soltanto dalla presenza di un numero finito di unti di
informazioni nellinput. In caso contrario una computazione della funzione dovrebbe elaborare
un numero infinito di unti di informazione prima di produrre lunti di output in questione.
Alcuni cpo sono anche dei reticoli completi, cio sono tali che ogni sottoinsieme di elementi
abbia sia estremo superiore che estremo inferiore (un reticolo un insieme che soddisfa la
propriet che qualsiasi coppia di elementi ha estremo superiore ed estremo inferiore). In tali
strutture si pu dimostrare che ogni funzione monotona ha sempre minimo e massimo punto
fisso. Ci quanto aerma il teorema fondamentale della teoria del punto fisso, noto anche
come teorema di Tarski, dal nome del matematico che lo ha formulato. Unaltra dimostrazione
indipendente del teorema era stata trovata da Knster.
Definizione 6.20. Dato un cpo D, una funzione f : D ! D ed un elemento d 2 D
1. d un pre-punto fisso di f se f d v d;
2. d un post-punto fisso di f se d v f d.
Quindi un punto fisso sia un pre-punto fisso che un post-punto fisso.
Teorema 6.21 (Teorema di Knster-Tarski per i punti fissi). Sia (R, v) un reticolo completo
e sia f : R ! R una funzione monotona. Allora f ammette sia massimo punto fisso zmax che
minimo punto fisso zmin , i quali sono definiti nel modo seguente:
zmax = sup {x 2 R | x v f (x)}
zmin = inf {x 2 R | f (x) v x}
Dimostrazione. Dimostriamo che zmax il massimo punto fisso di f (la dimostrazione per
zmin pu essere fatta in maniera analoga). Anch ci valga devono essere valide le due
seguenti aermazioni:
1. zmax = f (zmax ), cio zmax un punto fisso, e
2. r v zmax , per ogni r 2 R punto fisso di f .
Nella dimostrazione proveremo separatamente le due aermazioni.
dellinsieme A definito nel modo seguente:
A = {x 2 R | x v f (x)}
1. Mostriamo dapprima che
zmax
f (zmax )

v
v

f (zmax ) e
zmax .

Ci serviremo inoltre

122

Capitolo 6 Domini per la semantica denotazionale


Dimostriamo la prima delle due relazioni. Per definizione
zmax = sup A.
Allora, per ogni x 2 A, verificata x v zmax . Dalla monotonia di f , la relazione
x v zmax implica f (x) v f (zmax ). Segue che, per ogni x 2 A, x v f (x) v f (zmax ),
perci f (zmax ) un maggiorante per linsieme A. Per definizione zmax il minimo
maggiorante di A, quindi zmax v f (zmax ).
Per dimostrare la seconda relazione, si osservi che, da zmax v f (zmax ) e dalla monotonia
di f , si ha che f (zmax ) v f (f (zmax )). Ma allora f (zmax ) 2 A e quindi f (zmax ) v zmax ,
dato che zmax lestremo superiore di A.

Componendo le due relazioni delle quali appena stata dimostrata la validit si ottiene
zmax v f (zmax ) v zmax
Per lantisimmetria di v deve valere zmax = f (zmax ), quindi zmax un punto fisso di f .
2. Vediamo ora che zmax il massimo punto fisso di f . Sia r un qualsiasi punto fisso di
f . Allora in particolare avremo che r v f (r). Questo implica che r 2 A e quindi che
r v sup A = zmax . Perci tutti i punti fissi di f appartengono ad A e quindi zmax ,
che lestremo superiore di A, il massimo punto fisso di f .

Il teorema di Knster-Tarski importante perch si applica a qualsiasi funzione monotona


su un reticolo completo. Nel seguito, tuttavia, lattenzione sar concentrata soprattutto sui
minimi punti fissi di funzioni continue costruiti, con la tecnica utilizzata nel teorema di Kleene,
come estremi superiori (cio minimi maggioranti) di catene.

6.4

Costruzioni di domini

Come i linguaggi di programmazione forniscono primitive per costruire nuovi dati a partire
da dati preesistenti, cos la teoria dei domini fornisce alcuni operatori che permettono di
costruire nuovi domini a partire da domini esistenti. Questa ricchezza importante in quanto
garantisce che i cpo possano essere utilizzati come domini per dare significato ai vari tipi di
costrutti dei linguaggi di programmazione. Di seguito illustriamo alcuni di questi operatori
insieme a particolari funzioni continue associate alle costruzioni.

6.4.1

Domini elementari

Il modo pi semplice di definire un cpo a partire da un insieme qualsiasi quello di definire


il dominio piatto o elementare basato su di esso. Dato un insieme D, loperazione di lifting
up(D) consente di ottenere il cpo D = (D [ {?} , v) tramite laggiunta di un nuovo elemento
? (?62 D) a D e la definizione dellordinamento parziale, detto discreto, v come segue:
1. ?v x per ogni x 2 D;
2. x v x per ogni x 2 D [ {?}.

123

6.4 Costruzioni di domini

banale verificare che ogni D definito come sopra soddisfa le condizioni richieste ai domini.
Il pi semplice esempio di dominio piatto quello dei booleani estesi con ?:
BOOL = (true, false, ?)

in cui i due valori di verit true e false sono incomparabili ed entrambi pi definiti di ?.
true

false
?

Un altro esempio di dominio piatto che sar frequentemente usato in queste note NAT,
il dominio piatto dei naturali (introdotto nellEsempio 6.16).

6.4.2

Prodotti finiti

Il prodotto tra domini, indicato dalloperatore , costruisce un dominio di n-uple a partire


da n domini. Per semplicit in questa sezione presenteremo i dettagli per il prodotto binario,
lestensione al prodotto di n domini ovvia.
Definizione 6.22. Siano D0 = (D0 , v0 ) e D1 = (D1 , v1 ) due domini. Chiamiamo dominio
prodotto, denotato con D0 D1 , la coppia (D0 D1 , v) dove
1. D0 D1 il prodotto cartesiano di D0 e D1 , cio {hx, yi | x 2 D0 , y 2 D1 };
2. la relazione v definita per componenti, cio hx, yi v hx0 , y 0 i se e solo se x v0 x0 e
y v1 y 0 .
Dimostriamo ora che il prodotto di cpo esso stesso un cpo.
Teorema 6.23. D0 D1 un cpo.
Dimostrazione. Si dimostra facilmente che la relazione v riflessiva, antisimmetrica e transitiva sfruttando le analoghe propriet di v0 e v1 . Quindi D0 D1 un poset. Il suo minimo
la coppia h?0 , ?1 i ( ovvio infatti che h?0 , ?1 i v hd0 , d1 i, 8d0 2 D0 , 8d1 2 D1 ). Resta da
dimostrare che ogni catena in D0 D1 ha estremo superiore. Sia {hxi , yi i | i 2 N} una catena.
Per definizione di v abbiamo che {xi | i 2 N} e {yi | i 2 N} sono catene rispettivamente in D0
e D1 e quindi hanno sup perch questi insiemi sono cpo. Siccome abbiamo:
8j 2 N : xj v0 sup {xi | i 2 N} e yj v1 sup {yi | i 2 N}
allora abbiamo anche che
8j 2 N : hxj , yj i v hsup {xi | i 2 N} , sup {yi | i 2 N}i
e quindi hsup {xi | i 2 N} , sup {yi | i 2 N}i un maggiorante della catena {hxj , yj i | j 2 N}.
Dimostriamo ora che il pi piccolo dei maggioranti. Sia hm, ni un altro maggiorante. Questo
vuol dire che
8i 2 N : hxi , yi i v hm, ni

124

Capitolo 6 Domini per la semantica denotazionale

e quindi, per come v stato definito,


8i 2 N : xi v0 m e yi v1 n.
Questo basta per concludere che m ed n sono maggioranti di {xi | i 2 N} e {yi | i 2 N}, rispettivamente. Dalla definizione di estremo superiore segue che sup {xi | i 2 N} v0 m e
sup {yi | i 2 N} v1 n. Pertanto, dalla definizione di v, abbiamo
hsup {xi | i 2 N} , sup {yi | i 2 N}i v hm, ni
e quindi la coppia hsup {xi | i 2 N} , sup {yi | i 2 N}i lestremo superiore della catena
{hxi , yi i | i 2 N} .
In particolare, generalizzando il teorema precedente al prodotto di n domini, abbiamo che
lestremo superiore di una catena di n-uple corrisponde alla n-upla degli estremi superiori
delle singole componenti.
Le funzioni associate al cpo prodotto rivestono una notevole importanza. Al costruttore
di n-uple h, . . . , i sono anche associati n distruttori, detti anche selettori o proiettori, che
| {z }
n

permettono di selezionare singole componenti di una n-upla in D0 D1 Dn


n = 2 abbiamo due selettori, cio due funzioni funzioni

1.

Nel caso

0 : ( D 0 D 1 ) ! D 0
1 : ( D 0 D 1 ) ! D 1
definite come segue:
i (x0 , x1 ) = xi

i = 0, 1.

Lemma 6.24. I selettori 0 e 1 sono continui.


Dimostrazione. (Schema) La prova semplice e si basa sul fatto che lestremo superiore di una
catena di n-uple corrisponde alla n-upla degli estremi superiori delle singole componenti.
Loperazione che dati gli elementi di singoli cpo crea la n-upla corrispondente pu essere
estesa alle funzioni. Siano f0 : D ! D0 e f1 : D ! D1 due funzioni continue. Si definisce la
funzione
hf0 , f1 i : D ! D0 D1
nel seguente modo:

hf0 , f1 i(d) = hf0 (d), f1 (d)i

La funzione hf0 , f1 i chiaramente soddisfa la propriet che


i hf0 , f1 i = fi

per i = 0, 1

e, in eetti, hf0 , f1 i lunica funzione in D ! D0 D1 che gode di tale propriet. Si pu


facilmente dimostrare che la funzione hf0 , f1 i monotona. Inoltre anche continua, come
aerma il seguente Lemma.

125

6.4 Costruzioni di domini


Lemma 6.25. La funzione hf0 , f1 i continua.
Dimostrazione. Sia {xi | i 2 N} una catena in D. Allora abbiamo
hf0 , f1 i(sup {xi | i 2 N})
= hf0 (sup {xi | i 2 N}), f1 (sup {xi | i 2 N})i definizione di hf0 , f1 i
= hsup {f0 (xi ) | i 2 N} , sup {f1 (xi ) | i 2 N}i continuit delle fi
= sup {hf0 (xi ), f1 (xi )i | i 2 N}
definizione di sup di un prodotto,
Teorema 6.23
= sup {hf0 , f1 i(xi ) | i 2 N}
definizione di hf0 , f1 i.

La costruzione di prodotto sui cpo pu essere estesa alle funzioni. Siano f0 : D0 ! D2 e


f1 : D1 ! D3 due funzioni continue. Si definisce la funzione
f 0 f 1 : D0 D 1 ! D2 D 3
nel modo seguente:
f0 f1 he0 , e1 i = hf0 (e0 ), f1 (e1 )i
Lemma 6.26. La funzione f0 f1 continua.
Dimostrazione. Si noti che f0 f1 = hf0 0 , f1 1 i. Ogni componente fi i continua
poich la composizione di funzioni continue (Lemma 6.14), e, per il Lemma 6.25, continua
anche la coppia hf0 0 , f1 1 i, cos la tesi dimostrata.
Vediamo un paio di importanti propriet dei prodotti, spesso usate in pratica.
Lemma 6.27. Siano D, D0 e D1 cpo e sia h : D ! D0 D1 una funzione. Allora h continua
se e solo se le funzioni 0 h : D ! D0 e 1 h : D ! D1 sono continue.
Dimostrazione. )) Segue direttamente dal fatto che la composizione di funzioni continue
una funzione continua (Lemma 6.14).
() Siano 0 h e 1 h continue. Allora, per qualsiasi x 2 D abbiamo
h(x) = h0 (h(x)), 1 (h(x))i = h0 h(x), 1 h(x)i = h0 h, 1 hi(x)
Dunque, poich 0 h e 1 h sono continue, per il Lemma 6.25, anche h = h0 h, 1 hi
continua.
Per dimostrare la propriet successiva, faremo uso del seguente risultato riguardante
lestremo superiore di una matrice di elementi di un cpo.
Proposizione 6.28. Siano ai,j elementi di un cpo D, con i 2 I e j 2 I, aventi la propriet
che ai,j v ai0 ,j 0 se i i0 e j j 0 . Allora linsieme {ai,j | i 2 I, j 2 I} ha estremo superiore e
sup{ai,j | i 2 I, j 2 I} = sup{sup{ai,j | i 2 I} | j 2 I}
= sup{sup{ai,j | j 2 I} | i 2 I}
= sup{ai,i | i 2 I}

126

Capitolo 6 Domini per la semantica denotazionale

Dimostrazione. La prova semplice e si basa sul fatto che gli insiemi A = {ai,j | i 2 I, j 2 I},
B = {sup{ai,j | i 2 I} | j 2 I}, C = {sup{ai,j | j 2 I} | i 2 I} e D = {ai,i | i 2 I} hanno
gli stessi maggioranti, e quindi lo stesso minimo dei maggioranti, cio estremo superiore. Per
esempio, facile vedere che A e D hanno gli stessi maggioranti perch qualsiasi elemento ai,j
minore o uguale di un elemento della forma ai,i , e viceversa. Certamente lestremo superiore
della catena D esiste e quindi lestremo superiore di A esiste e i due valori coincidono. Inoltre,
sfruttando la commutativit di quantificatori omogenei, in questo caso del quantificatore
universale, abbiamo
x un maggiorante per B

,
,
,
,
,

8j. sup{ai,j | i 2 I} v x
8j8i. ai,j v x
x un maggiorante per A
8i. sup{ai,j | j 2 I} v x
x un maggiorante per C.

Lemma 6.29. Una funzione f : D1 D2 ! D continua se e solo se f continua nei due


argomenti separatamente, cio se, per qualsiasi d1 2 D1 , la funzione f2 : D2 ! D definita da
f2 (d) = f (d1 , d) continua, cos come pure continua la funzione f1 : D1 ! D definita da
f1 (d) = f (d, d2 ), per qualsiasi d2 2 D2 .

Dimostrazione. ) Questa parte semplice. Basta fissare uno dei due argomenti e dimostrare che se soltanto uno degli argomenti contribuisce al crescere della catena, allora
lipotesi di continuit della funzione suciente per derivare la tesi. In pratica, bisogna
dimostrare che se {ai | ai 2 D1 , i 2 I} una catena e b 2 D2 allora
f (sup{ai | i 2 I}, b) = sup{f (ai , b) | i 2 I}.

da cui la tesi segue per simmetria. In eetti, abbiamo

sup{f (ai , b) | i 2 I} = f (sup{(ai , b) | i 2 I}) per la continuit di f


= f (sup{ai | i 2 I}, b)
per definizione di prodotto
( Bisogna dimostrare che se A = {(ai , bi ) | ai 2 D1 , bi 2 D2 , i 2 I} una catena allora
f (sup{(ai , bi ) | i 2 I}) = sup{f (ai , bi ) | i 2 I}.

Dallipotesi che A una catena segue che anche gli insiemi {(ai , bj ) | bj 2 D2 , j 2 I},
per ogni ai 2 D1 con i 2 I, sono catene. In particolare, lipotesi di continuit, seppure
sui singoli argomenti, implica la monotonia di f e quindi sono catene anche gli insiemi
{f (ai , bj ) | bj 2 D2 , j 2 I}, per ogni ai 2 D1 e i 2 I. Inoltre, sempre dallipotesi di
continuit, segue che tali insiemi hanno estremo superiore. Quindi abbiamo
f (sup{(ai , bi ) | i 2 I}) = f (sup{ai | i 2 I}, sup{bj | j 2 I})
per la definizione di sup di un prodotto,
= sup{f (ai , sup{bj | j 2 I}) | i 2 I}
per la continuit di f nel primo argomento
= sup{sup{f (ai , bj ) | j 2 I} | i 2 I}
per la continuit di f nel secondo argomento
= sup{f (ai , bi ) | i 2 I}
per la Proposizione 6.28.

127

6.4 Costruzioni di domini

Questultimo risultato molto utile perch in numerose occasioni la continuit di una


funzione definita su di un prodotto viene verificata dimostrando che continua separatamente
rispetto a ciascun argomento.

6.4.3

Somma disgiunta

spesso utile creare unioni di domini, per esempio per aggiungere valori di errore ai valori
normali delle computazioni. Un modo per unire due o pi domini ed ottenere un nuovo
dominio quello di fare lunione disgiunta dei loro elementi. Questa costruzione, indicata
dalloperatore +, simile alloperazione di unione disgiunta tra insiemi; essa strutturata in
modo tale che possibile esaminare un elemento del risultato e decidere a quale degli insiemi di
partenza esso appartiene. Dati due domini D0 e D1 , loperazione di somma disgiunta costruisce
un dominio i cui elementi sono copie degli elementi dei domini di origine contrassegnate con
il nome di tale dominio (o con qualcosa che permetta di identificarlo univocamente), pi un
nuovo elemento minimo. Anche in questo caso definiremo soltanto la somma disgiunta di due
domini, in quanto la sua estensione al caso generale di n domini ovvia.
Definizione 6.30. Siano D0 = (D0 , v0 ) e D1 = (D1 , v1 ) due domini. Chiamiamo somma
disgiunta, denotata da D0 + D1 , la coppia (D0 + D1 , v) con
1. D0 + D1 = {inD0 (x) | x 2 D0 } [ {inD1 (y) | y 2 D1 } [ {?},
2. v definita come segue:
(a) ?v d, per ogni d 2 D0 + D1 ,

(b) inDi (d) v inDi (d0 ) , d vi d0 , per ogni d, d0 2 Di (i = 0, 1),

dove le funzioni di immersione inD0 : D0 ! D0 + D1 e inD1 : D1 ! D0 + D1 sono iniettive


e tali che inD0 (d) e inD1 (d0 ) siano sempre inconfrontabili per qualsiasi d e d0 .
Analogamente a quanto dimostrato per il prodotto, si pu facilmente dimostrare che la
somma disgiunta di cpo essa stessa un cpo.
Teorema 6.31. D0 + D1 un cpo.
Associati al costruttore somma ci sono operatori che permettono di riottenere elementi dei
domini originari a partire da elementi del dominio composto o di testare il dominio di origine
di un certo elemento del dominio composto.
Nel caso n = 2, abbiamo i due selettori
outD0 : D0 + D1 ! D0
outD1 : D0 + D1 ! D1
definiti come segue:
outDi (x) =

?i se x =? o x = inDi+2 1 (y)
y
se x = inDi (y)

dove i = 0, 1 e +2 denota la somma modulo 2.

128

Capitolo 6 Domini per la semantica denotazionale


Abbiamo anche i due predicati di test
isD0 : D0 + D1 ! BOOL
isD1 : D0 + D1 ! BOOL

definiti come segue:

8
se x = inDi (y)
< true
false
se x = inDi+2 1 (y)
isDi (x) =
:
?BOOL se x =?D0 +D1

dove i = 0, 1.
Possiamo dimostrare la continuit delle operazioni associate alla somma disgiunta, come
enunciato dal seguente risultato.
Lemma 6.32. Le immersioni inDi , i selettori outDi e i predicati isDi sono continui.
La costruzione di somma disgiunta di cpo pu essere estesa alle funzioni. Siano f0 : D0 ! D
e f1 : D1 ! D due funzioni continue sui cpo D0 , D1 e D. Si definisce la funzione combinazione
[f0 , f1 ] : D0 + D1 ! D
nel modo seguente:
[f0 , f1 ](inDi (di )) = fi (di )
[f0 , f1 ](?)
= ?D

8di 2 Di e i = 0, 1

Si potrebbe dimostrare che la funzione cos definita continua.


Lemma 6.33. La funzione [f0 , f1 ] continua.
Inoltre, vale che [f0 , f1 ] inDi = fi per i = 0, 1 e tale propriet sulle funzioni in D0 +D1 ! D
caratterizza la funzione [f0 , f1 ] in modo univoco.

6.4.4

Spazio delle funzioni

Il prossimo costruttore di domini risulta essenziale per le definizioni semantiche dei linguaggi
di programmazione. Il costruttore di spazi di funzione, indicato con !, crea il dominio (D0 !
D1 , v) a partire dai domini D0 e D1 . Gli elementi di questo dominio sono tutte le funzioni
continue da D0 a D1 e lordinamento v richiede che una funzione pi definita di unaltra
fornisca, per uguale argomento, un risultato uguale o pi definito. Tale ordinamento, quando
i domini D0 e D1 sono piatti, coincide con quello presentato informalmente in Sezione 6.1.
Per esprimere gli elementi del dominio (D0 ! D1 , v) useremo la -notazione (introdotta nel
Capitolo 5); in pratica, la -astrazione funge da costruttore e lapplicazione di funzione da
distruttore.
Definizione 6.34. Siano D0 = (D0 , v0 ) e D1 = (D1 , v1 ) due domini. Chiamiamo spazio
delle funzioni continue da D0 a D1 , denotato da [D0 ! D1 ], la coppia (D0 ! D1 , v) dove
1. D0 ! D1 linsieme delle funzioni continue da D0 a D1 ,
2. v cos definito: f v g , 8x. f x v1 gx.

129

6.4 Costruzioni di domini

Di seguito dimostriamo che lo spazio delle funzioni continue tra due cpo ancora un cpo.
Teorema 6.35. [D0 ! D1 ] un cpo.

Dimostrazione. facile verificare che v riflessiva, antisimmetrica e transitiva: ci deriva


dalle corrispondenti propriet di v0 e v1 . Quindi (D0 ! D1 , v) un poset. Inoltre esiste il
minimo, che la funzione continua:
= x. ?1 .
Resta da dimostrare che ogni catena di funzioni in [D0 ! D1 ] ha sup in [D0 ! D1 ]. Data una
generica catena di funzioni continue {fi | i 2 I}, sia g la funzione cos definita:
g = x.sup{fi x | i 2 I}.
Per dimostrare la tesi, sar allora suciente dimostrare che la funzione g cos definita appartiene a [D0 ! D1 ], cio che g continua (punto 1) e che g = sup{fi | i 2 I} (punto
2).
1. facile convincersi che g monotona. Infatti, siano x1 , x2 2 D0 tali che x1 v x2 .
Allora, abbiamo fi x1 v fi x2 per ogni i 2 I, dato che fi monotona. Quindi, per la
definizione di g, abbiamo 8i 2 I, gx1 = sup{fi x1 | i 2 I} v sup{fi x2 | i 2 I} = gx2 .
Dimostriamo ora che g anche continua, cio che, data una catena {xj | j 2 J} di
elementi di D0 , abbiamo:
g sup{xj | j 2 J} = sup{g xj | j 2 J}.
Il fatto che g sia monotona garantisce lesistenza di sup{g xj | j 2 J}; infatti {g xj |
j 2 J} una catena in D1 e quindi ha estremo superiore dato che per ipotesi D1 un
cpo. Abbiamo:
g sup{xj | j 2 J} =
=
=
=

sup{fi sup{xj | j 2 J} | i 2 I}
sup{sup{fi xj | j 2 J} | i 2 I}
sup{sup{fi xj | i 2 I} | j 2 J}
sup{g xj | j 2 J}

definizione di g
continuit delle fi
Proposizione 6.28
definizione di g.

2. Per la definizione di sup e per quella di g abbiamo:


8i 2 I, 8x 2 D0 : fi x v1 sup{fi x | i 2 I} = g x.
Questo, per come stato definito lordinamento tra funzioni, implica
8i 2 I : fi v g
e quindi g un maggiorante della catena {fi | i 2 I}. Dimostriamo che esso anche il
minimo tra i maggioranti. Sia h un altro maggiorante per {fi | i 2 I}. Per la definizione
di v abbiamo che
8i 2 I, x 2 D0 , fi x v1 h x.

Questo basta per concludere che h x un maggiorante della catena {fi x | i 2 I}. Poich
g x per definizione il sup di tale catena, dalle definizioni di sup e di v abbiamo
8x 2 D0 . g x v1 h x, dunque g v h
e questo basta per concludere che g il sup di {fi | i 2 I}.

130

Capitolo 6 Domini per la semantica denotazionale

In particolare, dal teorema precedente segue che lestremo superiore di una catena di
funzioni continue definito in maniera puntuale, cio corrisponde alla funzione che su ogni
elemento del dominio restituisce lestremo superiore della catena di elementi formata dai valori
restituiti dalle singole funzioni della catena quando invocate su quellelemento.
Ci sono due operazioni chiave associate alla costruzione dello spazio delle funzioni,
lapplicazione e la currificazione (introdotta alla fine della Sezione 5.1). La prima corrisponde
alla funzione apply : [D1 ! D2 ] D1 ! D2 definita da
apply (f, x).f (x) .
La seconda ()c :: [(D1 D2 ) ! D3 ] ! [D1 ! D2 ! D3 ], data una funzione continua f :
(D1 D2 ) ! D3 , corrisponde alla versione currificata di f , cio f c : D1 ! D2 ! D3 , definita
da
()c f. x. y.f (x, y) .
Sotto ipotesi opportune, entrambe le funzioni risultano essere continue, come sostenuto dai
due lemmi seguenti.
Lemma 6.36. La funzione apply continua se il suo primo argomento una funzione
continua.
Dimostrazione. Sfruttando il Lemma 6.29 sar suciente dimostrare che apply continua nel
primo e secondo argomento separatamente.
1. Dimostriamo prima che apply(f, sup{xi | i 2 I}) = sup{apply(f, xi ) | i 2 I}.
apply(f, sup{xi | i 2 I}) = f (sup{xi | i 2 I})
per definizione di apply,
= sup{f xi | i 2 I}
per la continuit di f ,
= sup{apply(f, xi ) | i 2 I} per definizione di apply.
2. Dimostriamo ora che apply(sup{fi | i 2 I}, x) = sup{apply(fi , x) | i 2 I}.
per definizione di apply,
perch lestremo superiore di una catena di
funzioni continue definito in modo puntuale,
= sup{apply(fi , x) | i 2 I} per definizione di apply.

apply(sup{fi | i 2 I}, x) = (sup{fi | i 2 I})x


= sup{fi x | i 2 I}

Lemma 6.37. Se f : [(D1 D2 ) ! D3 ] una funzione continua allora anche f c continua.


Dimostrazione. Si osservi innanzitutto che, 8x 2 D1 , f c (x) = y.f (x, y) continua. Infatti,
dato che f continua, dal Lemma 6.29 segue che continua separatamente rispetto a ciascun
argomento, per cui f c (x) continua. Dimostriamo ora che f c continua, cio che per una

131

6.4 Costruzioni di domini

generica catena {xi | xi 2 Di , i 2 I} abbiamo f c (sup{xi | xi 2 Di , i 2 I}) = sup(f c {xi | xi 2


Di , i 2 I}). Sia d 2 D2 generico. Abbiamo
(f c (sup{xi | i 2 I}))d =
=
=
=

f (sup{xi | i 2 I}, d)
sup{f (xi , d) | i 2 I}
sup{(f c (xi ))d | i 2 I}
sup(f c {xi | i 2 I})d

per definizione di f c ,
perch f continua,
per definizione di f c ,
perch lestremo superiore di una catena di
funzioni continue definito in modo puntuale.

Si potrebbe anche dimostrare che, data f : [D1 D2 ! D3 ], f c lunica funzione continua


in [D1 ! D2 ! D3 ] tale che
apply(f c (d1 ), d2 ) = f (d1 , d2 )

8d1 2 D1 , d2 2 D2 .

Un operatore utile nel seguito () :: [D1 ! D2 ] ! [D1 ! D2 ], il quale data una funzione
continua f : [D1 ! D2 ] ne restituisce la sua versione stretta; questa coincide con la funzione
originale a parte che indefinita quando tale largomento. Sia f : [D1 ! D2 ] una funzione
continua tra due cpo. La funzione f : [D1 ! D2 ] definita nel modo seguente

f (d) se d 6=?D1

f (d) =
?D2 se d =?D1
Lemma 6.38. Loperatore () continuo.
Dimostrazione. Sia d un elemento qualsiasi di D1 e sia {fi | i 2 I} una generica catena di
funzioni continue in [D1 ! D2 ]. Nel caso in cui d =?D1 , dalla definizione delloperatore () , si
ottiene immediatamente che (sup{fi | i 2 I}) (d) =?D2 = (sup{fi | i 2 I})(d). Altrimenti,
cio se d 6=?D1 , abbiamo
per definizione di f ,
perch lestremo superiore di una catena di
funzioni continue definito in modo puntuale.

= sup{fi (d) | i 2 I}
per definizione di f ,

= (sup{fi | i 2 I})(d) perch lestremo superiore di una catena di


funzioni continue definito in modo puntuale.

(sup{fi | i 2 I}) (d) = (sup{fi | i 2 I})(d)


= sup{fi (d) | i 2 I}

Chiudiamo questa sezione introducendo la funzione condizionale


! , : BOOL D D ! D
dove D un qualche cpo (si ricordi che BOOL = {true, false, ?} il cpo piatto dei valori di
verit). Presi b 2 BOOL e d, d0 2 D, poniamo
8
se b = true
< d
0
0
d
se
b = false
b ! d, d =
:
?D se b =?BOOL
Il risultato successivo ne dimostra la continuit.

132

Capitolo 6 Domini per la semantica denotazionale

Lemma 6.39. La funzione condizionale ! , : BOOL D D ! D continua.


Dimostrazione. Sia hb1 , d1 , d01 i v hb2 , d2 , d02 i v hb3 , d3 , d03 i v . . . una catena in BOOL D D.
Abbiamo tre casi da considerare.
1. bi =? per tutti gli i 1: Poich lestremo superiore di una catena di n-uple corrisponde
alla n-upla degli estremi superiori delle singole componenti (si veda il Teorema 6.23),
abbiamo sup h?, di , d0i i = hsup ?, sup di , sup d0i i = h?, sup di , sup d0i i. Inoltre,
poich
! , (?, sup di , sup d0i ) =?! sup di , sup d0i =?D =
sup {?D } = sup {?! di , d0i } = sup { ! , (?, di , d0i )}
abbiamo che la condizione di continuit per la funzione ! , verificata.
2. bi = true per tutti gli i k per un qualche k: ragionando come nel caso precedente, abbiamo sup hbi , di , d0i i = hsup bi , sup di , sup d0i i = htrue, sup di , sup d0i i. La condizione
di continuit per la funzione ! , risulta verificata poich abbiamo:
! , (true, sup di , sup d0i ) = true ! sup di , sup d0i = sup di =
sup {di |i k} = sup {bi ! di , d0i } = sup { ! , (bi , di , d0i )}
3. bi = false per tutti gli i
del caso precedente.

6.5

k per un qualche k: la prova di questo caso simile a quella

Un metalinguaggio per la definizione di funzioni di


interpretazione

Nel Capitolo 4 abbiamo visto che la semantica denotazionale di un linguaggio di programmazione consiste nellassociare elementi di opportuni domini semantici a termini della sintassi
astratta del linguaggio. Nellintroduzione a questo capitolo abbiamo visto che, per le dicolt
matematiche che intervengono quando si vogliono catturare propriet e descrivere costrutti
dei linguaggi di programmazione, necessario utilizzare come domini speciali tipi di insiemi
con struttura conosciuti come ordinamenti parziali completi ed necessario richiedere che le
funzioni su tali oggetti matematici siano continue.
In questa sezione introdurremo un linguaggio per descrivere elementi dei domini semantici,
cio elementi dei cpo che utilizzeremo per denotare i costrutti dei linguaggi di programmazione
che studieremo nei capitoli successivi. Siccome il linguaggio che proporremo verr utilizzato
per descrivere altri linguaggi, esso verr chiamato metalinguaggio. Assumeremo che il significato dei suoi costrutti sia noto; se cos non fosse dovremmo utilizzare un meta-metalinguaggio
pi semplice per descrivere il metalinguaggio stesso ed assumere o che la semantica del metametalinguaggio sia nota oppure andare avanti fino ad un linguaggio (ad esempio quello dei
numeri naturali) che riterremo sucientemente semplice per poter essere utilizzato come base
delle nostre descrizioni semantiche.

6.5 Un metalinguaggio per la definizione di funzioni di interpretazione

6.5.1

133

Una classe di domini

Prima di procedere alla presentazione del metalinguaggio ricapitoliamo come, a partire da


insiemi di valori, che prendiamo come valori di base e noti, sia possibile definire una classe di
cpo sucientemente ricca per i nostri scopi.
Gli insiemi di base che utilizzeremo per le denotazioni dei vari linguaggi che saranno presi
in esame in queste note saranno:
Naturali, {0, 1, 2, . . .}, che chiameremo N;
Booleani, {true, false}, che chiameremo B;
Locazioni, {l, loc, . . .} che chiameremo LOC;
Identificatori, {in, out, res, plike, . . .}, un insieme di stringhe di lettere e numeri che
chiameremo I;
Insiemi finiti, {{error} , {unbound} , {unused} , {error, unbound, unused} , . . .}, insiemi costruiti elencando esplicitamente i loro elementi.
I domini che utilizzeremo saranno costruiti a partire da uno qualsiasi di questi insiemi di base, oppure componendo altri domini precedentemente definiti, tramite opportuni costruttori.
Questi costruttori di dominio sono stati, per la maggior parte, gi presentati nella Sezione 6.4;
li ripresentiamo qui per sommi capi per ricordare la struttura delle nostre denotazioni e per
introdurre alcune semplici generalizzazioni.
Lifting: up(D). I domini primitivi possono essere formati a partire da uno qualsiasi degli
insiemi base tramite loperazione di lifting. Se D un insieme di valori base allora up(D)
restituisce il dominio (piatto) D = (D [ {?} , v) che contiene lelemento minimo ? ed tale
che tutti gli elementi sono pi definiti di ? e sono tra di loro inconfrontabili. Per esempio,
nelle sezioni precedenti, abbiamo visto come i domini NAT e BOOL dei naturali e dei booleani
vengono costruiti tramite lifting a partire da N e B.
Prodotto di domini: (D1 , . . . , Dn ). Dati n domini D1 , . . . , Dn , loperazione di prodotto
(D1 , . . . , Dn ) costruisce un dominio di n-uple di elementi degli n domini. Spesso invece della
notazione prefissa, scriveremo (D1 Dn ). Questa operazione la generalizzazione del
prodotto binario visto in dettaglio nella Sezione 6.4.2. Le operazioni associate al prodotto di
domini sono il costruttore di n-uple h, . . . , i ed i proiettori i () (con 1 i n). Nel seguito,
| {z }
n

dato il dominio D, indicheremo con Dn il dominio prodotto D


. . D}.
| .{z
n

Somma disgiunta di domini: +(D1 , . . . , Dn ). Dati n domini D1 , . . . , Dn , loperazione di


somma disgiunta +(D1 , . . . , Dn ) costruisce un dominio i cui elementi sono etichettati dal nome
(o da qualcosa che permetta di identificare univocamente il nome) dei loro domini di origine.
Anche per questo operatore useremo spesso la notazione infissa: D1 + + Dn . Questa
operazione la generalizzazione della somma binaria vista in dettaglio nella Sezione 6.4.3.
Le operazioni associate alla somma disgiunta di domini sono i costruttori inDi (), i selettori
outDi () ed i predicati isDi () (con 1 i n).

134

Capitolo 6 Domini per la semantica denotazionale

Generalizzando, si pu definire una somma disgiunta infinita. Se D1 , D2 , D3 , . . . sono


domini allora D1 + D2 + D3 + . . . contiene elementi della forma inDi (d) con d 2 Di (per i > 0),
pi un nuovo elemento minimo.
Tra laltro, questa costruzione permette la definizione del dominio delle sequenze, denotato con D , comprendente tutte le sequenze finite (liste) formate da elementi di un dominio
D

D = {nil} + D + D2 + D3 + . . .

Se d 2 D , allora esso o la sequenza vuota (rappresentata da nil), oppure una sequenza di


elementi di D di lunghezza finita n, per qualche n 1, oppure ?. Al dominio sequenza D
sono associate specifiche operazioni: il costruttore :: , i selettori hd() e tl() ed il predicato
null(). Se s 2 D e d 2 D, informalmente le operazioni sono cos definite:
d :: s la sequenza il cui primo elemento d e il resto la sequenza s;
hd(s) il primo elemento della sequenza s;
tl(s) la sequenza ottenuta da s togliendo il primo elemento;
null(s) un predicato che vero se s la sequenza vuota.
Vogliamo ora definire formalmente le operazioni associate a D . Si tenga innanzitutto
presente che se uno dei loro argomenti un elemento minimo (di D o di D , a seconda del tipo
delloperazione) il risultato delloperazione lelemento minimo del codominio. Consideriamo
ora i casi restanti, cio s 2 D e d 2 D con s 6=?D e d 6=?D . Quindi s = inDn (d1 , d2 , . . . , dn ),
per qualche n 1 e di 2 D per ogni 1 i n, oppure s = inD0 (nil). Allora abbiamo:
:: : D D ! D con
d :: inD0 (nil) = inD1 (d)
d :: inDn (d1 , d2 , . . . , dn ) = inDn+1 (d, 1 (outDn (inDn (d1 , d2 , . . . , dn ))), . . . ,
n (outDn (inDn (d1 , d2 , . . . , dn ))))
hd() : D ! D con
hd(inD0 (nil)) =?
hd(inDn (d1 , d2 , . . . , dn )) = 1 (outDn (inDn (d1 , d2 , . . . , dn )))
tl() : D ! D con
tl(inD0 (nil)) =?
tl(inD1 (d)) = inD0 (nil)
tl(inDn (d1 , d2 , . . . , dn )) = inDn

1 (2 (outDn (inDn (d1 , d2 , . . . , dn ))), . . . ,

n (outDn (inDn (d1 , d2 , . . . , dn ))))

se n > 1

null() : D ! BOOL con


null(s) = isD0 (s)
Dalla loro definizione formale deriva direttamente che le operazioni associate al dominio
sequenza D sono continue poich definite in termini della composizione di funzioni continue
(si vedano i risultati delle Sezioni 6.3 e 6.4). Quindi vale il seguente risultato.
Lemma 6.40. Il costruttore :: 2 (D D ) ! D , i selettori hd() 2 D ! D e tl() 2 D !
D ed il predicato null 2 D ! BOOL sono continui.

6.5 Un metalinguaggio per la definizione di funzioni di interpretazione

135

Spazio delle funzioni continue: [D0 ! D1 ]. Il costruttore di spazi di funzioni rappresenta


linsieme di tutte le funzioni continue da un dominio D0 ad un dominio D1 ; esso crea il dominio
[D0 ! D1 ] a partire dai domini D0 e D1 . Per non appesantire la notazione, assumeremo che
loperatore ! associ a destra e rappresenteremo:
D0 ! (D1 ! (D2 ! ! Dn ) . . .)

con D0 ! D1 ! D2 ! ! Dn .

La -astrazione il modo pi comune per costruire elementi di [D0 ! D1 ], cos come lapplicazione di una funzione elemento di [D0 ! D1 ] ad un elemento di D0 permette di riottenere
un elemento di D1 .

6.5.2

Il metalinguaggio

Nella descrizione della semantica denotazionale di un linguaggio di programmazione necessario avere a disposizione strumenti che permettano di ottenere nuove funzioni a partire da
funzioni esistenti. Per quanto visto finora (si veda in particolare i risultati in Sezione 6.3),
importante che le funzioni utilizzate siano continue. Risulta essenziale quindi che le operazioni
per la manipolazione di funzioni preservino la continuit. Il principale scopo di questa sezione quello di rassicurare il lettore che le funzioni di interpretazione semantica che saranno
utilizzate nel seguito per descrivere i costrutti dei linguaggi di programmazione sono tutte
definite su cpo e sono tutte continue.
Il metalinguaggio proposto basato sulla -notazione introdotta nel Capitolo 5 e la sua
semantica operazionale quindi basata sulla -riduzione. Ricordiamo che invece di scrivere
x. y.f spesso scriveremo semplicemente xy.f . importante non confondere questa notazione con (x, y).f . Infatti, xy.f un funzionale di un solo argomento, mentre (x, y).f
una funzione di due argomenti raggruppati in una coppia. Approfittiamo di questa occasione
anche per ricordare che la -astrazione associa a destra, cio lega il pi possibile alla sua
destra: pertanto x.x + y va letto come x.(x + y) e non come ( x.x) + y.
Tuttavia, per denotare funzioni utilizzeremo non soltanto -espressioni, ma anche una
sintassi pi mnemonica. Questa pu comunque essere sempre vista come unabbreviazione
di una qualche -espressione, come sar chiaro alla fine della sezione. Si vorrebbe imporre il
minor numero possibile di vincoli sulla -notazione e tuttavia essere sicuri che, cos facendo,
si definiscono funzioni continue.
Le principali componenti delle funzioni di interpretazione che utilizzeremo nei capitoli
successivi saranno:
le variabili,
le costanti, tra cui loperatore di minimo punto fisso,
le n-uple,
lapplicazione di funzione,
la -astrazione,
i costrutti derivati Condizionale, Let e Case.

136

Capitolo 6 Domini per la semantica denotazionale

Queste, ed alcune altre costruzioni esprimibili utilizzando solo quelle elencate sopra, costituiscono le espressioni del metalinguaggio. Tipicamente, tali espressioni rappresentano elementi
di un qualche cpo D1 e dipendono da variabili ciascuna delle quali assume valori in qualche
altro cpo. quindi necessario stabilire la continuit di queste espressioni. Unespressione e
detta continua nella variabile x 2 D0 se e solo se la funzione x.e (con tipo D0 ! D1 )
continua. Si dice che e continua nelle sue variabili se e solo se e continua in ciascuna
delle sue variabili. In particolare, se la variabile x non occorre in e, allora la funzione x.e
costante e quindi continua.
I risultati di questa sezione, insieme a quelli della sezione precedente, ci permettono di
dimostrare che i costrutti fondamentali del metalinguaggio usato per descrivere le funzioni di
interpretazione semantica preservano la continuit e quindi garantiscono che le espressioni del
metalinguaggio sono continue nelle loro variabili.
Variabili. Unespressione e, che assume valori in un cpo D1 , costituita da una singola variabile x continua nelle sue variabili perch, presa y 2 D0 , la funzione y.e risulta infatti
essere o lidentit x.x (quando y = x) oppure la funzione costante y.x.
Costanti. Oltre ai valori base (interi, booleani, ?, . . . ), abbiamo gi introdotto altri
elementi particolari dei cpo, quali
le proiezioni i 2 (D0 . . . Dn ) ! Di , le operazioni su funzioni hf0 , . . . , fn i : D !
D0 . . . Dn e f0 . . . fn : D0 . . . Dn ! D00 . . . D0n associate al prodotto di
cpo;
le immersioni inDi 2 Di ! (D0 + . . . + Dn ), i selettori outDi 2 (D0 + . . . + Dn ) ! Di ,
i predicati isDi 2 (D0 + . . . + Dn ) ! BOOL e loperazione di combinazione di funzioni
[f0 , . . . , fn ] 2 D0 + . . . + Dn ! D, tutti associati alla somma disgiunta;
il costruttore :: 2 (D D ) ! D , i selettori hd() 2 D ! D e tl() 2 D ! D ed il
predicato null 2 D ! BOOL, tutti associati al dominio delle sequenze;
gli operatori apply 2 (D1 ! D2 ) D1 ! D2 , ()c 2 [(D1 D2 ) ! D3 ] ! [D1 ! D2 ! D3 ]
e () :: [D1 ! D2 ] ! [D1 ! D2 ] associate allo spazio delle funzioni;
il condizionale ! , : BOOL D D ! D.
Queste espressioni costanti (non dipendenti da variabili), di cui abbiamo provato la continuit
nelle Sezioni 6.3, 6.4 e 6.5.1, costituiscono pertanto elementi prestabiliti di un cpo di funzioni
continue perci sono continue nelle loro variabili.
Introduciamo ora un importante operatore che riguarda le funzioni continue da un cpo a
se stesso. Ad ogni cpo D infatti associato un operatore di punto fisso fix : [D ! D] ! D che
mappa una qualsiasi funzione continua f : [D ! D] nel suo minimo punto fisso, ed definito
da
fix f.sup f i ?| i 2 I .
Il Lemma 6.41, la cui dimostrazione rimandata a dopo aver trattato lapplicazione di funzione
e la -astrazione, ci dice che loperatore fix continuo.

6.5 Un metalinguaggio per la definizione di funzioni di interpretazione

137

n-uple. Date le espressioni e1 2 D1 , . . . , en 2 Dn , nei cpo D1 , . . . , Dn , si pu definire la


n-pla he1 , . . . , en i nel cpo prodotto (D1 . . . Dn ). La continuit di unespressione ottenuta
in questo modo una conseguenza del fatto che la continuit di una n-pla e quella delle sue
componenti si implicano vicendevolmente.
Infatti, per definizione, una n-upla he1 , . . . , en i continua nella variabile x se e solo se la
funzione x.he1 , . . . , en i continua, cio, per il Lemma 6.27, se e solo se i ( x.he1 , . . . , en i)
continua per 1 i n, cio se e solo se x.ei continua per 1 i n, cio se e solo se ei
continua su x per 1 i n.
Quindi se le componenti sono continue nelle loro variabili, lo sono anche le n-ple.
Applicazione di funzione. Consideriamo innanzitutto unapplicazione c(e), dove c una
funzione continua del tipo discusso precedentemente in Costanti. Per definizione, c(e)
continua in una variabile x se e solo se x.c(e) continua. Mostriamo ora che se e continua
in x allora x.c(e) continua. Infatti, se supponiamo che e continua in x, per definizione
ci vuol dire che x.e continua e, per il Lemma 6.14, anche c ( x.e) continua. Poich c
costante, cio non ha variabili libere, abbiamo c ( x.e) = x.c(e), quindi x.c(e) continua.
Le applicazioni generali della forma e1 (e2 ) sono continue nelle loro variabili se tali sono e1
ed e2 . Questo segue osservando che
e1 (e2 ) = apply(e1 , e2 ),
cio e1 (e2 ) si ottiene applicando la costante apply alla n-upla he1 , e2 i.
-astrazione. Sia e unespressione continua nelle sue variabili. Allora scegliendo una variabile particolare x che assuma valori in un cpo D si pu costruire la funzione x.e, che
risulta quindi essere continua per costruzione. Per dimostrare che anche x.e continua nelle
sue variabili, necessario dimostrare la continuit di y. x.e, per una generica variabile y.
Certamente ci vero se x = y, essendo il risultato una funzione che fornisce costantemente
x.e (che continua per costruzione). Altrimenti, essendo e continua sia in x che in y per
ipotesi, allora per il Lemma 6.29 (y, x).e continua. Se ora applichiamo loperatore di currificazione ()c otteniamo proprio y. x.e che quindi continua perch tale operatore preserva
la continuit (come aerma anche il Lemma 6.37). Quindi unastrazione continua nelle sue
variabili a condizione che lo sia il suo corpo.
Come caso particolare, si ottiene che la composizione di espressioni preserva la propriet
di continuit nelle variabili perch e1 e2 = x.e1 (e2 (x)). Si noti che anche -astrazioni pi
generali, quali ad esempio (x, y).e 2 (D1 D2 ) ! D3 , sono continue perch ad esempio
possibile esprimerle nella forma z.e[1 (z)/x, 2 (z)/y] con z 2 D1 D2 .
Lemma 6.41. Loperatore fix continuo.
Dimostrazione. Per dimostrare la tesi mostriamo dapprima che, per ogni i, la funzione fixi
f.f i ? continua. La prova procede per induzione su i. fix0 f.f 0 ? il funzionale
costante f. ? che sappiamo essere continuo. Assumiamo che fixi sia una funzione continua
e proviamo che anche fixi+1 una funzione continua. Poich fixi+1 f.f (f i ?) pu
essere vista come f.apply(f, (f i ?)), cio pu essere espressa in termini di applicazione di
funzione e -astrazione a partire da funzioni continue, fixi+1 continua. Per induzione su i
non dicile dimostrare che {fixi | i 2 I} una catena nello spazio delle funzioni continue

138

Capitolo 6 Domini per la semantica denotazionale

[D ! D]. A questo punto, per il Teorema 6.35, segue che sup{fixi | i 2 I} esiste ed una
funzione continua. Infine, poich lestremo superiore di una catena di funzioni definito in
modo puntuale, abbiamo che sup{fixi | i 2 I} = f.sup{f i ?| i 2 I} che appunto fix.
Costrutti derivati. Riassumendo, unespressione costruita a partire da elementi prestabiliti e funzioni continue tramite i metodi descritti nei paragrafi precedenti continua nelle sue
variabili. Vediamo ora come esprimere alcuni costrutti utili in termini di quelli gi esaminati
in modo da ottenere una sintassi pi mnemonica.
Condizionale. Useremo
p ! e 1 , e2

dove p 2 BOOL e e1 , e2 2 D, al posto di apply(( ! , ), (p, e1 , e2 )). Il costrutto in


questione restituisce ?D se p =?BOOL , e1 se p = true ed e2 se p = false. Se p,
e1 e e2 sono continue nelle loro variabili, allora anche p ! e1 , e2 continuo nelle sue
variabili perch esprimibile usando unicamente le costruzioni descritte in precedenza, in
particolare apply e ! , , di cui abbiamo gi mostrato la continuit (Lemmi 6.36 e
6.39).
Osservazione 6.42. In alternativa, il costrutto condizionale pu essere espresso in
termini di altri costrutti, senza bisogno di introdurre la funzione ! , (si veda anche
il Lemma 6.39). In particolare, lidea di esprimere le costanti booleane tramite i
proiettori del dominio prodotto D D: cio
true 0 : (D D) ! D

false 1 : (D D) ! D

definite da:
true (x, y).x

false (x, y).y

Difatti queste definizioni corrispondono a quelle introdotte nellOsservazione 5.5 riguardo (le modalit per esprimere) le costanti nel -calculus. A questo punto, indicando
genericamente con p una qualsiasi delle funzioni true, false o 2 (x, y). ?, e con e1
ed e2 espressioni a valori in D, abbiamo che il condizionale esprimibile con lespressione apply(p, (e1 , e2 )). Quindi, se e1 e e2 sono continue nelle loro variabili, allora anche
anche il condizionale lo , perch esprimibile usando unicamente le costruzioni descritte in precedenza, in particolare apply e i , di cui abbiamo gi mostrato la continuit
(Lemmi 6.36 e 6.24).
Let. Useremo
let x be e1 in e2
al posto di ( x.e2 ) e1 . In pratica, il costrutto let vuole evidenziare che soltanto se
e1 2 D1 un valore diverso da ?D1 allora la funzione x.e2 utilizza tale valore per
determinare il risultato tramite lespressione e2 , altrimenti il risultato ?D2 . Dalla sua
definizione segue immediatamente che il costrutto let continuo nelle sue variabili se
e1 2 D1 e e2 2 D2 lo sono, perch in tal caso continua lespressione ( x.e2 ) e1 , la
quale infatti si pu ottenere da e1 e e2 usando unicamente le costruzioni descritte in
precedenza.

6.6 Esempi di funzioni sul dominio dei naturali

139

T ::= D | hT1 , . . . , Tn i | i (T )
| inD(T ) | outD(T ) | isD(T )
| T1 :: T2 | hd(T ) | tl(T ) | null(T )
| x | x.T | T1 T2

| fix(T ) | T ! T1 , T2 | let x be T1 in T2

| cases T of inD(T1 ) : T10 ; . . . ; inD(Tn ) : Tn0 endcases


Tabella 6.1: Sintassi del metalinguaggio
Cases. La combinazione mostrata in Sezione 6.4.3 permette di definire un costrutto generale,
detto cases, che produce risultati dierenti a seconda del componente della somma a
cui appartiene largomento. Sia D un cpo. Sia D1 + . . . + Dn una somma disgiunta di n
cpo e sia e unespressione a valori nella somma disgiunta, continua nelle sue variabili.
Useremo
cases e of inD1 (x1 ) : e1 ;
...
inDn (xn ) : en
endcases
al posto della seguente combinazione [ x1 .e1 , . . . , xn .en ](e). In pratica, il costrutto
cases seleziona ei nel caso in cui e = inDi (di ) per qualche di 2 Di e restituire ?D se
e =?. Se supponiamo che, per 1 i n, xi .ei : Di ! D sono funzioni continue nelle
loro variabili, allora il costrutto cases continuo nelle sue variabili perch rappresenta
unespressione costruita in termini di espressioni e costrutti che preservano la continuit.
In definitiva, i termini del metalinguaggio sono quelli descritti dalla grammatica in
Tabella 6.1.
Considerazioni conclusive. Sebbene presentato in modo informale, il linguaggio riassunto
in questa sezione pu essere formalizzato definendo precisamente quali siano i tipi e le operazioni costanti, ottenendo cos un particolare -calcolo tipato i cui termini, nellinterpretazione
standard, denotano elementi di cpo. In pratica le regole di costruzione del linguaggio assicurano che funzioni non continue non possono insinuarsi in esso. Un approccio di questo tipo
ha consentito a Dana Scott di sviluppare LCF (logica delle funzioni calcolabili) che consiste
in un -calcolo tipato simile a quello brevemente introdotto qui, con predicati ed una regola
di prova (induzione di punto fisso) per ragionare sui minimi punti fissi.

6.6

Esempi di funzioni sul dominio dei naturali

In questa sezione applichiamo la teoria vista in precedenza al dominio piatto dei naturali NAT
e alle funzioni continue che coinvolgono i naturali.
Cominciamo col dare una struttura di dominio alle funzioni dai naturali ai naturali. Consideriamo il dominio NAT ed il dominio prodotto NAT NAT = NATn . Il dominio

140

Capitolo 6 Domini per la semantica denotazionale

FUNn = ({f : NATn ! NAT | f continua} , v) delle funzioni continue di n argomenti definito

come segue:

8f, g 2 FUNn . f v g se e solo se, 8hx1 , . . . , xn i 2 NATn : f (x1 , . . . , xn ) v g(x1 , . . . , xn ) .


Per quanto visto in precedenza, questo insieme un cpo. Vale la pena notare che in questo
caso i domini su cui sono definite le funzioni in esame sono tutti domini con solo catene finite.
Pi precisamente, vero che NATn ha catene lunghe al pi n + 1. Infatti, una n-upla a meno
definita o uguale di unaltra n-upla b se e solo se o le due n-uple sono uguali o a contiene
almeno un elemento uguale a ? mentre gli altri elementi di a e b sono uguali.
Inoltre, il fatto che NAT sia un dominio piatto ha come conseguenza che, se f v g, allora
8hx1 , . . . , xn i 2 NATn : f (x1 , . . . , xn ) 6=? ) f (x1 , . . . , xn ) = g(x1 , . . . , xn ),
cio che g una estensione di f .
Consideriamo di nuovo la funzione fattoriale
f = x.(x = 0) ! 1, x f (x

1)

e le sue approssimazioni iniziali ottenute a partire dal funzionale


= f. x.(x = 0) ! 1, x f (x

1).

Essendo il funzionale continuo, per il Teorema 6.17, esso ha minimo punto fisso, che dato
da
sup{ i }
dove x. ? il minimo di FUN1 .
0 = =
x. ?
1 = ( f. x.(x = 0) ! 1, x f (x 1))()
= x.(x = 0) ! 1, x (x 1)
= x.(x = 0) ! 1, x ?
= x.(x = 0) ! 1, ? (perch come vedremo pi avanti x ?=?)
2 = ( f. x.(x = 0) ! 1, x f (x 1))( x.(x = 0) ! 1, ?)
= x.(x = 0) ! 1, x (( x.(x = 0) ! 1, ?)(x 1))
= x.(x = 0) ! 1, x ((x 1 = 0) ! 1, x 1 ?)
= x.(x = 0) ! 1, (x 1 = 0) ! x, ?
= x.(x = 0) ! 1, ((x = 1) ! x, ?).
In generale si pu dimostrare che per ogni i 2 N
i = x.(x < i) ! x!, ?
e quindi lestremo superiore della catena la funzione fattoriale x.x!.
Lesempio appena visto ci permette di capire come la continuit permetta di ragionare su
oggetti infiniti non considerandoli globalmente (cosa peraltro impossibile), ma considerando le
loro approssimazioni finite. Infatti per conoscere, ad esempio, il risultato della funzione che
la semantica del funzionale succitato sullargomento 5 non necessario sapere che tale funzione

141

6.6 Esempi di funzioni sul dominio dei naturali

la funzione fattoriale, basta considerare la sesta funzione nella catena che la approssima e
valutarla con argomento 5.
Se un funzionale non continuo, il comportamento dellestremo superiore della catena
pu non avere nulla a che vedere col comportamento degli elementi della catena. Di seguito
riportiamo due esempi di funzionali non continui. Ricordiamo che su domini piatti continuit
e monotonia si equivalgono (vedi 6.11).
Esempio 6.43. Il funzionale
1 = f. x.(f x =?) ! 0, ?
non monotono. Infatti, se consideriamo le funzioni
= x. ? e Z = x.0;
abbiamo che v Z secondo il normale ordinamento di funzioni, ma
1 Z v 1 e 1 Z 6= 1
essendo 1 = Z e 1 Z = .
Esempio 6.44. Consideriamo la funzione Id x.x ed il funzionale
2 = f. x.(f = Id) ! x, ? .
Il risultato di 2 per qualsiasi argomento diverso dalla funzione identit vale sempre , mentre
2 ( x.x) = x.x. Sia f v g. Se nessuna delle due funzioni la funzione identit, abbiamo
che 2 f = 2 g = . Nel caso g x.x allora possiamo avere due sottocasi: 2 f = oppure
2 f = x.x; in entrambi i casi abbiamo sempre che 2 f v 2 g. Per esaurire i casi e concludere
che 2 monotono ci basta ora notare che se f lidentit allora f = g, perch non esistono
funzioni monotone pi definite dellidentit, che una funzione totale.
Mostriamo ora che il funzionale 2 non continuo. Si consideri la catena di funzioni
continue
{ x.(x < i) ! x, ?| i 2 N}
il cui estremo superiore la funzione identit. Abbiamo
2 (sup{ x.(x < i) ! x, ?| i
mentre

0}) = 2 ( x.x) = x.x

sup {2 ( x.(x < i) ! x, ?) | i 2 N} = {} = .

Si noti che la non continuit di 2 dovuta sostanzialmente al fatto che in esso viene eettuato
un test di uguaglianza fra funzioni, che ovviamente non pu essere determinato confrontando
un numero finito di approssimanti.
Per concludere questa sezione, analizziamo un problema posto dal fatto che, per garantire
la continuit, i domini delle funzioni sono stati ottenuti estendendo linsieme dei numeri
naturali con ?. La presenza di ? pone la necessit di associare un significato allapplicazione di
funzione ad argomenti indefiniti. Questo permetter daltra parte di trattare la composizione
di funzioni f g anche quando g non sia definita su qualche argomento.

142

Capitolo 6 Domini per la semantica denotazionale

Definizione 6.45. Data una funzione f : Nn ! NAT diciamo che la funzione fext la sua
estensione naturale su NATn se e solo se definita come segue:

f (x1 , . . . , xn ) se xi 6=?, 8i 2 {1 . . . n};


fext (x1 , . . . , xn ) =
?
altrimenti.
Si dimostra facilmente che ogni funzione ottenuta in questo modo monotona, e dunque
continua, dato che NATn ha solo catene finite (lunghe al pi n + 1, come abbiamo gi visto).
Infatti, una n-upla a meno definita o uguale di unaltra n-upla b se e solo se o le due n-uple
sono uguali o a contiene almeno un elemento uguale a ? mentre gli altri elementi di a e b
sono uguali. Se in questultimo caso la funzione ha valore ?, tale valore sar senzaltro per
definizione meno definito del (o uguale al) valore della funzione su b e quindi la funzione f
monotona.
Le funzioni che nel caso di argomenti indefiniti valgono ? sono anche note come funzioni strette ed infatti lestensione naturale detta anche estensione stretta. Questo tipo di
estensione non comunque lunica estensione monotona possibile. Ad esempio, una funzione
costante K = x.k pu essere estesa anche ponendo K ?= k.
Se consideriamo le funzioni con un solo argomento, una estensione monotona diversa dalla
stretta possibile solo se la funzione costante. Altrimenti avremmo ?v d ma f ?6v f d,
poich f ?, f d 6=? e in NAT abbiamo che d1 6v d2 se d1 , d2 6=?. Il discorso dierente per
funzioni con pi argomenti. Consideriamo ad esempio la moltiplicazione. Essa ha quattro
estensioni monotone:
8
< x y se x 6=? e y 6=?
mul1 (x, y) =
:
altrimenti
8 ?
< x y se x 6=? e y 6=?
0
se x = 0
mul2 (x, y) =
:
?
altrimenti
8
< x y se x 6=? e y 6=?
0
se y = 0
mul3 (x, y) =
:
altrimenti
8 ?
< x y se x 6=? e y 6=?
0
se x = 0 o y = 0
mul4 (x, y) =
:
?
altrimenti
Si pu vedere che mul1 , che lestensione stretta, la meno definita tra le quattro funzioni, mentre mul4 la pi definita; abbiamo inoltre che mul2 non confrontabile con mul3 .
Le quattro funzioni definite sopra corrispondono a modi diversi di valutare lespressione di
moltiplicazione: mul1 corrisponde ad una valutazione che prima di dare un risultato calcola
entrambi gli argomenti, mul2 corrisponde ad una valutazione da sinistra a destra, mul3 da
destra a sinistra, mentre in mul4 i due argomenti sono valutati parallelamente; le ultime tre
funzioni forniscono zero come risultato non appena uno dei loro argomenti viene valutato a
zero.
Una funzione di cui non utilizzeremo lestensione stretta il condizionale, il quale, nel
caso in cui il dominio dei sui tre argomenti sia quello dei naturali N, potrebbe essere scritto
come
if thenelse = xyz.x ! y, z

6.7 Sistemi di equazioni mutuamente ricorsive

143

indicando in questo modo la funzione che vale y se x = 0 e z altrimenti. Se questa funzione


fosse estesa a NAT in modo stretto il significato di qualsiasi definizione intrinsecamente ricorsiva sarebbe indefinito. Per esempio, se consideriamo la prima approssimazione F act1 definita
nellequazione (6.2), avremmo
F act1 f act = x.x ! 1, ?= x.if thenelse(x, 1, ?) = x. ?= F act0
da cui non sarebbe dicile dimostrare che F acti per ogni i 2 N !
La funzione condizionale viene di solito estesa in modo tale che risulti stretta soltanto
rispetto al suo primo argomento:
8
< y se x = 0
z se x 6= 0 e x 6=?
if thenelse(x, y, z) =
:
? altrimenti

Con questa estensione, che permette di avere unespressione indefinita o erronea in


uno dei rami del condizionale purch quel ramo non sia scelto, abbiamo, ad esempio,
if thenelse(0, 5, ?) = 5.

6.7

Sistemi di equazioni mutuamente ricorsive

La teoria del punto fisso per le definizioni ricorsive di funzione pu essere estesa senza dicolt
a sistemi di equazioni mutuamente ricorsive.
Consideriamo un insieme di n equazioni:
8
>
< f1 = x1 . . . xm1 .e1
..
.
>
:
fn = x1 . . . xmn .en
Ognuna di esse individua un funzionale di mi argomenti

i : (FUNm1 FUNmn ) ! FUNmi


definito da
i = (f1 , . . . , fn )x1 . . . xmi .ei
e lintero sistema individua un unico funzionale
: (FUNm1 FUNmn ) ! (FUNm1 FUNmn )
cos definito:
= (g1 , . . . , gn ).h1 (g1 , . . . , gn ), . . . , n (g1 , . . . , gn )i
Una n-upla di funzioni hg1 , . . . , gn i un punto fisso per se e solo se
(g1 , . . . , gn ) = hg1 , . . . , gn i,
cio
8i : i (g1 , . . . , gn ) = gi .

144

Capitolo 6 Domini per la semantica denotazionale

Se continuo (e i risultati presentati in Sezione 6.4 ci dicono quando questo pu


succedere), il suo minimo punto fisso
n
o
sup h1j (m1 , . . . , mn ), . . . , nj (m1 , . . . , mn )i | j 2 N

dove, per ogni i = 1, . . . , n, mi il minimo di FUNmi , cio la funzione da mi -ple di naturali


a naturali che fornisce come risultato sempre ?, e per ogni j 2 N, ij definito iterativamente
come segue
i0 (m1 , . . . , mn ) = mi
ij+1 (m1 , . . . , mn ) = i (1j (m1 , . . . , mn ), . . . , nj (m1 , . . . , mn )).
Lestremo superiore di questa catena una n-upla di funzioni. Per estrarre le singole
funzioni suciente utilizzare i selettori gi definiti per i domini ottenuti come prodotti di
altri domini.
Consideriamo ad esempio il funzionale
: (FUN1 FUN2 ) ! (FUN1 FUN2 )
associato al sistema di equazioni

f1 = x.(x = 0) ! 1, f2 (x, f1 (x 1))


f2 = (x, y).(x = 0) ! 0, y + f2 (x 1, y)
cio

1 = (f1 , f2 ) x.(x = 0) ! 1, f2 (x, f1 (x 1))


2 = (f1 , f2 ) (x, y).(x = 0) ! 0, y + f2 (x 1, y)

e calcoliamo le prime approssimazioni della catena (abbreviando ij (1 , 2 ) in ij ).


10 = x. ?
20 = (x, y). ?
11 = 1 (10 , 20 ) = x.(x = 0) ! 1, ?
21 = 2 h10 , 20 i = (x, y).(x = 0) ! 0, ?
12 = 1 h11 , 21 i = x.(x = 0) ! 1, ?
22 = 2 h11 , 21 i = (x, y).(x = 0) ! 0, (x = 1) ! y, ? .
13 = 1 h12 , 22 i = x.(x = 0) ! 1, (x = 1) ! 1, ?
23 = 2 h12 , 22 i = (x, y).(x = 0) ! 0, (x = 1) ! y, (x = 2) ! y + y, ? .
In generale si pu dimostrare che, per ogni i 2 N
1i = x.(x < i 1) ! x!, ?
2i = (x, y).(x < i) ! x y, ?
per cui lestremo superiore della catena la coppia di funzioni
h x.x!, (x, y).x yi.

145

6.8 Esercizi

6.8

Esercizi

6.1 Si dimostri che se un cpo ha un numero finito di elementi, allora ogni funzione monotona su di
esso anche continua.
6.2 Un ordinamento parziale su un insieme finito sempre completo? E quello su un insieme
infinito?
6.3 Si considerino due cpo (D1 , v1 ) e (D2 , v2 ) tali che D1 D e D2 D, per qualche D.
1. La struttura (D1 [D2 , v), dove x v y se e solo se x v1 y _x v2 y sempre un ordinamento
parziale?
2. La struttura (D1 \ D2 , v), dove x v y se e solo se x v1 y ^ x v2 y
(a) sempre un ordinamento parziale?
(b) sempre un ordinamento parziale completo?

6.4 Si consideri linsieme T di tutti i termini costruiti con un simbolo f di funzione binaria e con
due simboli di costante c e ?. Si consideri la relazione v ( T T ) definita informalmente da
t v t0 se il termine t0 ottenuto da t sostituendo alcune occorrenze di ? con generici termini in
T.
1. Si definisca formalmente la relazione v.

2. Si provi che (T , v) un ordinamento parziale con elemento minimo.


3. Si dimostri che (T , v) non completo.

6.5 Si studino gli insiemi V e V [ V 1 delle stringhe finite e delle stringhe finite ed infinite
sullalfabeto V = {a, b, c}, con lordinamento v , dove indica la concatenazione delle
stringhe e e inoltre = se infinita.
1. La struttura (V [ V 1 , v) un ordinamento parziale?
2. Esiste lelemento minimo?
3. completo?
6.6 Si considerino le stesse domande dellesercizio precedente per la struttura (V , v).
6.7 Risolvere le equazioni fra linguaggi:
X = {a} X,

X = {a} [ ({b} X),


dopo aver scelto gli opportuni domini e verificato che e [ sono operazioni continue.

6.8 Si dimostri che, per ogni f, g, funzioni continue tra gli opportuni cpo, vale
fix(f

g) = f (fix(g f )).

6.9 Dimostrare se, per ogni cpo, esiste sempre il minimo dei maggioranti di ogni suo sottoinsieme.
6.10 Sia D un cpo. Una funzione r : D ! D si dice idempotente se r(r(x)) = r(x), per ogni x 2 D.
Dimostrare che linsieme di tutte le funzioni continue idempotenti da D in D un cpo.

Capitolo 7

Un semplice linguaggio funzionale

SOMMARIO
In questo capitolo definiamo la semantica denotazionale di un semplice linguaggio funzionale. La semantica ottenuta viene paragonata ad una semantica operazionale, basata su
regole di riscrittura semplici ed intuitive. La prova che semantica operazionale e semantica
denotazionale coincidono fornisce unulteriore giustificazione dellapproccio alla semantica
basato su di una teoria che garantisce lesistenza di punti fissi e, in molti casi, di un minimo
punto fisso per le funzioni definite ricorsivamente.
In questo capitolo analizziamo sintassi e semantica di un semplice linguaggio funzionale,
che chiameremo SLF. Il linguaggio detto funzionale in quanto i costrutti principali che lo
caratterizzano sono la definizione e lapplicazione di funzioni (per questo motivo tali linguaggi
sono anche detti applicativi ). Esso ha un costrutto letrec D in T , che permette di definire
insiemi di funzioni, anche mutuamente ricorsive, a partire da funzioni base, numeri naturali,
e variabili. Il calcolo avviene solo attraverso applicazioni di funzioni. Lassociazione variabilevalore non modellata attraverso una nozione esplicita di stato, ma semplicemente tramite la
sostituzione dei parametri formali con quelli attuali. Il linguaggio sucientemente espressivo
per permettere di definire tutte le funzioni calcolabili.
Per definire la semantica di SLF utilizzeremo due tecniche diverse, una basata sullapproccio operazionale ed unaltra su quello denotazionale, quindi studieremo le relazioni tra questi
due approcci. Inoltre, delle due semantiche forniremo versioni che permettono di descrivere il
passaggio degli argomenti alle funzioni con meccanismi per nome e per valore.

7.1

Sintassi di un semplice linguaggio funzionale

La sintassi di SLF basata sui seguenti insiemi di simboli terminali:


Valori di base: N = {0, 1, 2, . . . }; la lettera n (n1 , n2 , . . . ) sar utilizzata per denotare elementi
di N;
Variabili su valori di base: Var = {x1 , x2 , . . . , xm , . . . };
Simboli di funzioni base: B = {b1 , . . . , bk };
Variabili di funzione: FVar = {f1 , . . . , fr }.

148

Capitolo 7 Un semplice linguaggio funzionale

P ::= letrec D in T
T ::= xi | n | bj (T1 , . . . , Tm ) | fr (T1 , . . . , T(r) ) | if T then T1 else T2
D ::= f1 (x1 , . . . , x(1) ) ( T1 , . . . , fn (x1 , . . . , x(n) ) ( Tn
dove (j) uguale allarit di fj , 1 j n.
Tabella 7.1: Sintassi di SLF
Esempi tipici di funzioni di base sono +, , succ, pred. Per semplicit, tra i valori di base
sono assenti i booleani; codificheremo true con 0, false con tutti gli altri naturali. Cambiando
gli insiemi delle funzioni e dei valori di base possibile ottenere linguaggi leggermente diversi.
Per descrivere linsieme delle funzioni di base si presenta un problema analogo a quello
incontrato studiando la semantica dei numeri naturali. necessario distinguere oggetti appartenenti ad un dominio sintattico dalle loro denotazioni, anche quando la loro corrispondenza
diretta. In questo capitolo utilizzeremo le stesse lettere per rappresentare i nomi delle funzioni
di base e le funzioni di base stesse, evidenziando la dierenza fra sintassi e semantica tramite
caratteri tipografici leggermente diversi. Il nome della funzione di base b sar scritto b.
I termini del linguaggio sono definiti tramite la grammatica descritta in Tabella 7.1. Indichiamo con Prog, Term, Decl i linguaggi generati da tale grammatica con simboli iniziali
rispettivamente P, T, D.
Nelle varie clausole si utilizzano per comodit degli indici per denotare elementi della stessa
categoria sintattica: ad esempio, nel caso della categoria sintattica Term, i vari Ti denotano
un qualsiasi termine di SLF. Un programma P 2 Prog scritto nel linguaggio SLF consiste di
un termine T 2 Term e di un insieme di dichiarazioni D 2 Decl; queste ultime determinano
il contesto in cui T dovr essere valutato. Nella definizione di programma il termine T deve
essere un termine chiuso, cio un termine in cui non compaiono variabili di dati.
Le dichiarazioni sono semplicemente una n-upla di associazioni di termini a nomi di
funzioni e possono essere mutuamente ricorsive.
Gli esempi che seguono sono programmi, scritti nel linguaggio SLF, che calcolano il fattoriale di 2. Mentre nel primo esempio moltiplicazione e sottrazione sono considerate funzioni
base (ed espresse in notazione infissa), nel secondo esempio la moltiplicazione viene definita
in base alla somma e alla sottrazione.
Esempio 7.1.
1. letrec
in

f(x) ( if x then 1 else x f(x


f(2)

2. letrec

f1 (x) ( if x then 1 else f2 (x, f1 (x 1))


f2 (x1 , x2 ) ( if x1 then 0 else x2 + f2 (x1
f1 (2)

in

7.2

1)

1, x2 )

Semantica operazionale

Lapproccio operazionale alla semantica dei linguaggi di programmazione stato il primo


ad essere proposto per descrivere precisamente il significato dei vari costrutti dei linguaggi

149

7.2 Semantica operazionale

bj (n1 , . . . , nm ) = n
bj (n1 , . . . , nm ) !D n
Ti
bj (. . . , Ti , . . . )

(Bas1 )

!D Ti0

!D bj (. . . , Ti0 , . . . )

if 0 then T1 else T2

!D T1

if n + 1 then T1 else T2
T
if T then T1 else T2

!D T2

!D T 0

!D if T 0 then T1 else T2

D contiene fr (x1 , . . . , x(r) ) ( T

fr (T1 , . . . , T(r) )

!D T [T1 /x1 , . . . , T(r) /x(r) ]

(Bas2 )
(Cond1 )
(Cond2 )
(Cond3 )
(Fun)

Tabella 7.2: Semantica operazionale per nome di SLF


stessi. Essenzialmente, esso permette di descrivere il significato dei costrutti di un linguaggio
specificando una opportuna macchina astratta e descrivendo leetto dellesecuzione di ogni
costrutto su questa macchina. Inizialmente questo approccio non stato accettato da molti
perch spesso le macchine astratte erano troppo concrete e troppo simili alle macchine vere
e le specifiche richiedevano troppi dettagli implementativi.
Pi di recente c stato un rinnovato interesse per lapproccio operazionale. Vari ricercatori, utilizzando concetti, come quello di composizionalit e sintassi astratta, propri dellapproccio denotazionale, hanno proposto una nuova tecnica operazionale che sucientemente
astratta e formale. La semantica di un linguaggio descritta in termini di un sistema di transizioni che indica quali sono i possibili stati in cui un programma pu transire quando si trova
in uno stato noto. Questo metodo combina la vecchia idea di usare i sistemi di transizioni
etichettate per specificare il comportamento dei programmi con il rinnovato interesse per la
modularit: le transizioni associate ad una istruzione dipendono dalle transizioni associate ai
suoi componenti pi elementari.
Nel caso del linguaggio SLF la relazione di transizione definita tramite un insieme di
assiomi e regole dinferenza applicando le quali possibile dedurre tutte e sole le transizioni
possibili di un programma scritto nel linguaggio stesso. Gli assiomi e le regole di inferenza
per SLF sono riportati in Tabella 7.2. La tabella contiene almeno un assioma o una regola di
inferenza per ogni costrutto del linguaggio. Il principio di induzione strutturale garantisce che
il sistema proposto permette di assegnare un significato ad un qualunque programma SLF.
Dato un insieme di dichiarazioni D, la relazione !D la pi piccola relazione fra elementi chiusi (senza variabili libere) di Prog, basata su D, derivabile dalle regole di inferenza
riportate in Tabella 7.2. Le regole di riscrittura descrivono tutte e sole le transizioni a cui
i vari programmi di SLF possono dar luogo e gli stati raggiungibili dopo ogni transizione.
Essendo SLF un linguaggio applicativo, ogni stato sar rappresentato soltanto da un termine.
importante notare che tutte le derivazioni sono relative ad un insieme di dichiarazioni D
e per questo riportiamo D accanto alla freccia. Commentiamo ora brevemente le regole di

150

Capitolo 7 Un semplice linguaggio funzionale

inferenza.
(Bas1 ) se, valutando la funzione base bj con m naturali come argomenti, si ottiene come
risultato un naturale n, allora il termine ottenuto applicando il simbolo di funzione
bj (che corrisponde a bj ) ai simboli che rappresentano gli argomenti stessi, pu essere
riscritto nella rappresentazione di n.
(Bas2 ) quando il termine attuale un simbolo di funzione base applicato a termini che non
sono ancora riscritti come rappresentazioni di naturali, necessario trasformare tutti gli
argomenti in rappresentazioni di naturali, per poter essere nella condizione di applicare
la regola (Bas1 ).
(Cond1 ) e (Cond2 ) questi due assiomi definiscono le possibili trasformazioni di un termine
condizionale in cui il predicato gi il rappresentante di un naturale. Le riscritture sono
dovute alla scelta di considerare 0 come il valore booleano true e tutti gli altri numeri
come il valore false.
(Cond3 ) nel caso in cui il termine di controllo non rappresenti un naturale, necessario
trasformarlo, per poter essere nella condizione di applicare la regola (Cond1 ) oppure la
(Cond2 ).
(Fun) descrive il comportamento di una chiamata di funzione quando a questa vengono passati
altri termini come argomenti: si deve sostituire al nome della funzione il suo corpo
come specificato nelle dichiarazioni in D e sostituire i parametri attuali ai parametri
formali. importante notare che, siccome nella regola non si fa alcun riferimento alla
valutazione dei parametri prima di legarli allinterno del corpo della funzione, questa
semantica realizza la cosiddetta chiamata per nome o call-by-name. In seguito vedremo
i cambiamenti necessari per modellare un diverso meccanismo di passaggio di parametri
noto come call-by-value.

A partire dalle regole di riscrittura per !D possibile definire una nuova relazione
!D
che semplicemente la chiusura riflessiva e transitiva di !D e che necessaria per definire
il valore prodotto dalla valutazione operazionale di un programma. Si noti che !D una
relazione e non una funzione, nel senso che un programma pu evolvere in modi dierenti.
Ad esempio abbiamo che

ma anche

+(succ(0), succ(0))

!D +(1, succ(0))

+(succ(0), succ(0))

!D +(succ(0), 1)

Si pu tuttavia dimostrare che la semantica operazionale originata dalle regole di riscrittura


in Tabella 7.2 confluente. Infatti, abbiamo che, dato un generico termine chiuso T , esiste al

pi un naturale n tale che T


!D n.
Intuitivamente non dicile capire la ragione della univocit della nostra semantica.
Infatti, il sistema di transizioni considerato permette di scegliere di riscrivere indierentemente
due termini solo nel caso in cui il termine in esame preveda la valutazione dellapplicazione
di una funzione base ai suoi argomenti, e cio quando
T = bj (T1 , . . . , Tm ).

151

7.2 Semantica operazionale

In questo caso, esiste la possibilit di scegliere quale dei termini Ti riscrivere. Tuttavia,

per determinare il valore finale di T (e cio il naturale n tale che T


!D n) dobbiamo
necessariamente applicare la regola (Bas1 ), e questo possibile solo se abbiamo riscritto in

un naturale tutti gli argomenti della funzione base (Tj


!D nj , 8j tale che 1 j m).
Dovendo pertanto ridurre tutti gli argomenti, lordine di riduzione non risulta rilevante.
Possiamo ora definire formalmente la valutazione dei programmi di SLF:
Definizione 7.2. Il significato operazionale di un programma chiuso letrec D in T il

naturale n tale che T


!D n, se esiste; altrimenti, il significato del programma indefinito.
Proposizione 7.3.
Dato un programma chiuso letrec D in T , esiste al pi un naturale n tale che T

! n.
D

Dimostrazione. Per induzione sulla struttura di T .


Come abbiamo visto in precedenza, gli assiomi e le regole di inferenza della Tabella 7.2
portano ad una semantica operazionale in cui la chiamata di funzione utilizza come meccanismo di passaggio dei parametri attuali la cosiddetta chiamata per nome (call-by-name).
Infatti, la valutazione dellapplicazione di una qualsiasi funzione dichiarata in D non richiede
alcuna valutazione dei suoi argomenti al momento della chiamata.
possibile, con semplici modifiche alle regole precedenti, definire una semantica basata
sulla chiamata per valore (call-by-value), che richiede di valutare gli argomenti prima di sostituirli allinterno del corpo di una funzione. Lunica modifica da apportare alle regole della
semantica sostituire la (Fun) con le due regole (Fun0 ) e (Fun00 ) in Tabella 7.3, lasciando
tutte le altre immutate.
La regola (Fun0 ) simile alla regola (Fun) vista in precedenza, nel senso che permette
di sostituire il corpo della funzione al suo nome e di istanziare i parametri formali; essa
pu comunque essere applicata soltanto quando tutti gli argomenti sono stati trasformati in
rappresentazioni di interi. La regola (Fun00 ) rende possibile la trasformazione degli argomenti
in rappresentazioni di interi.
Si pu facilmente verificare che le regole che descrivono la chiamata per nome e quelle che
descrivono la chiamata per valore possono dare origine a sequenze di transizioni diverse. Se,
ad esempio, consideriamo il seguente programma SLF
P = letrec f(x) ( 0 in f(f(1))
(nome)
(nome)
e con
!D ,
!D indichiamo la transizione ottenuta applicando la regola (nome)
di una delle due semantiche operazionali viste sopra, abbiamo che con la call-by-name in un
solo passo possibile determinare che il valore di P la rappresentazione del naturale 0;

f(f(1))

(Fun)

!D 0.

Daltra parte, per determinare il valore di P tramite la call-by-value, abbiamo bisogno di due
passi:
f(f(1))

(Fun00 )

!D f(0)

(Fun0 )

!D 0.

152

Capitolo 7 Un semplice linguaggio funzionale

bj (n1 , . . . , nm ) = n
bj (n1 , . . . , nm ) !D n

(Bas1 )

Ti !D Ti0

(Bas2 )

bj (. . . , Ti , . . . ) !D bj (. . . , Ti0 , . . . )
if 0 then T1 else T2 !D T1

(Cond1 )

if n + 1 then T1 else T2 !D T2

(Cond2 )

T !D T 0

(Cond3 )

if T then T1 else T2 !D if T 0 then T1 else T2


D contiene fr (x1 , . . . , x(r) ) ( T

(Fun0 )

fr (n1 , . . . , n(r) ) !D T [n1 /x1 , . . . , n(r) /x(r) ]


Ti !D Ti0

fr (T1 , . . . , Ti , . . . , T(r) ) !D fr (T1 , . . . , Ti0 , . . . , T(r) )

(Fun00 )

Tabella 7.3: Semantica operazionale per valore di SLF


(Fun00 )

(Fun0 )

Si osservi che f(f(1))


!D f(0) perch f(1)
!D 0.
I due insiemi di regole possono dare addirittura origine a valutazioni diverse. Se ad esempio
consideriamo il programma
letrec f(x1 , x2 ) ( if x1 then 0 else f(x1

1, f(x1 , x2 )) in f(1, 2)

abbiamo che, mentre il suo valore operazionale basato sulla call-by-name 0, quello basato
sulla call-by-value non d alcun risultato, nel senso che le regole richiedono sempre nuove
riscritture. Infatti, nel caso della call-by-value necessario valutare tutti gli argomenti della
funzione f prima di cercare di determinarne il valore e questo fa s che dopo ogni riscrittura
sia sempre necessario valutare il termine f(x1 , x2 ):
f(1, 2)

(Fun0 )

!D

(Cond2 )

!D

if 1 then 0 else f(1


f(1

1, f(1, 2))

()

1, f(1, 2))

!D .

Un programma che d luogo a sequenze infinite di riscritture viene detto divergente.


In eetti, non dicile dimostrare, ragionando per induzione sulla lunghezza delle
derivazioni, il lemma seguente.
Lemma 7.4. Se T

7.3

!D n, allora T

!D n.

Semantica denotazionale

Come abbiamo gi visto, lapproccio denotazionale descrive in termini matematici il significato di ogni costrutto del linguaggio, in generale associando ad esso una funzione che permette

7.3 Semantica denotazionale

153

di determinare la relazione di input-output calcolata da ogni programma. La semantica viene


definita in maniera composizionale per induzione sulla sintassi astratta del linguaggio. Nel
caso di SLF per, non essendo presenti nel linguaggio costrutti di input, ad ogni programma
verr associato un naturale; si osservi tuttavia che, nel fornire linterpretazione dei termini
del linguaggio, dovremo comunque associare ad essi delle funzioni.
Per definire la semantica denotazionale di SLF utilizzeremo tre funzioni di interpretazione
semantica, una per ogni categoria sintattica (T per i termini, D per le dichiarazioni e P per
i programmi), che associano ad ogni termine del linguaggio il suo significato.
Dato un programma SLF, faremo le seguenti assunzioni, senza perdere in generalit:
il numero delle definizioni di funzioni (mutuamente ricorsive) presenti in una qualunque
dichiarazione D sar indicato con n;
il numero degli argomenti di ciascuna funzione costante e sar indicato con m (cio
supponiamo per semplicit (1) = = (n) = m).
Ricordiamo che con NAT viene indicato il dominio piatto dei naturali e con FUNm quello
delle funzioni continue con m argomenti naturali. Indichiamo con (FUNm )n il dominio delle nuple di funzioni appartenenti a FUNm . Per indicare n-uple e m-uple utilizzeremo la notazione
vettoriale, (~ ). Quindi
F~ sta per hf1 , . . . , fn i;

F~ sta per (f1 , . . . , fn );

~ sta per hx1 , . . . , xm i;


X

~ sta per (x1 , . . . , xm ).


X

I tipi delle funzioni semantiche sono:


T : Term ! (FUNm )n ! NATm ! NAT
D : Decl ! (FUNm )n
P : Prog ! NAT
La denotazione di un termine un funzionale che prende come argomento una n-upla di
funzioni e restituisce una funzione da m-uple di naturali a naturali; la denotazione di una
dichiarazione restituisce una n-upla di funzioni ed infine quella di un programma restituisce
un naturale.
Le clausole che definiscono la semantica sono riportate in Tabella 7.4 e brevemente
commentate qui sotto.
(Var) stabilisce che la denotazione di una variabile di dato xi il funzionale costante che
data una qualsiasi n-upla di funzioni restituisce una funzione che modella la i-esima
proiezione di una m-pla.
(Nat) stabilisce che la denotazione di un naturale il funzionale costante che data una
~
qualsiasi n-upla di funzioni restituisce la funzione costante X.n.

154

Capitolo 7 Un semplice linguaggio funzionale

~ i X
~
T [[xi ]] = F~ . X.

(Var)

~ n
T [[n]] = F~ . X.

(Nat)

~ bj (T [[T1 ]] F~ X,
~ . . . , T [[Tm ]] F~ X)
~
T [[bj (T1 , . . . , Tm )]] = F~ . X.

(Bas)

~ [[T ]] F~ X
~ ! T [[T1 ]] F~ X,
~ T [[T2 ]] F~ X
~ (Cond)
T [[if T then T1 else T2 ]] = F~ . X.T
~ r (F~ )(T [[T1 ]] F~ X,
~ . . . , T [[Tm ]] F~ X)
~
T [[fr (T1 , . . . , Tm )]] = F~ . X.

(Fun)

D[[f1 (x1 , . . . , xm ) ( T1 , . . . , fn (x1 , . . . , xm ) ( Tn ]] =


(Dec)
~
~
fix( F .hT [[T1 ]] F , . . . , T [[Tn ]] F~ i)
P[[letrec D in T ]] = T [[T ]] D[[D]] h0, . . . , 0i

(Prg)

Tabella 7.4: Semantica denotazionale di SLF


(Bas) definisce la denotazione del termine bj (T1 , . . . , Tm ) a partire dalla denotazione dei suoi
sottotermini, vale a dire T1 , . . . , Tm . La denotazione il funzionale che, data una n-upla
~
di funzioni F~ , restituisce la funzione che, data a sua volta una m-pla di naturali X
come argomento, applica la funzione base bj ai naturali ottenuti valutando i vari Ti con
~
i legami determinati da F~ e X.
(Cond) ha un significato analogo alla precedente. Difatti anche il condizionale una funzione
di base; essa viene considerata separatamente solo per la sua particolare struttura.
(Fun) associa al termine fr (T1 , . . . , Tm ) il funzionale che proietta lr-esimo argomento di una
n-pla e lo applica alla valutazione degli argomenti di fr .
(Dec) Il significato di una dichiarazione D una n-upla di funzioni ottenuta come minimo
punto fisso di un funzionale (FUNm )n ! (FUNm )n ; D pu infatti contenere definizioni
mutuamente ricorsive. Questo funzionale, data una n-upla di funzioni F~ , restituisce la
n-upla di funzioni ottenuta valutando ricorsivamente i termini associati ai simboli di
funzione nella dichiarazione D, con argomento F~ (si veda la Sezione 6.7).
(Prg) il significato di un programma letrec D in T ottenuto valutando il significato del
termine chiuso T con la n-upla di funzioni ottenuta dalla valutazione della dichiarazione
D e con la m-upla di argomenti h0, . . . , 0i. La scelta di usare questultima m-upla
irrilevante; essendo T chiuso rispetto alle variabili di dato, la sua interpretazione sar
una funzione che non dipende dalla m-pla di dati.
Anch la clausola per la valutazione delle dichiarazioni abbia senso, si deve dimostrare
che, per ogni n-upla di termini hT1 , . . . , Tn i, il minimo punto fisso di
F~ .hT [[T1 ]] F~ , . . . , T [[Tn ]] F~ i
esiste sempre. Per provare questo, necessario mostrare che, per ogni T , T [[T ]] continuo.
La continuit di F~ .hT [[T1 ]] F~ , . . . , T [[Tn ]] F~ i, e quindi lesistenza del suo minimo punto fisso, segue dalla continuit dellastrazione, dellapplicazione e delloperazione di formazione di

155

7.3 Semantica denotazionale

n-ple. Per provare la continuit di T suciente seguire il percorso tracciato nella Sezione 6.5. Osserviamo che nelle clausole relative a T in Tabella 7.4 compaiono solo variabili,
naturali oppure operazioni che abbiamo gi dimostrato preservare la continuit. Siccome anche la composizione di funzioni preserva la continuit, abbiamo che la propriet desiderata
garantita.
Teorema 7.5 (Continuit). Per ogni termine T del linguaggio SLF, il funzionale T [[T ]]
continuo.
Dimostrazione. Per induzione sulla struttura di T. Per la base dellinduzione suciente
notare che
~ i
T [[xi ]] = F~ . X.x
e

~
T [[n]] = F~ . X.n

sono banalmente funzionali continui; ad esempio, data una catena di n-uple di funzioni
{F~i | i 2 I},
si ha che
e

~
T [[n]]( sup {F~i | i 2 I}) = X.n
~
8i T [[n]]F~i = X.n.

Per il passo induttivo consideriamo innanzitutto il caso delle funzioni base e, supponendo che
T [[T1 ]], . . . , T [[Tm ]]
siano continui, dimostriamo che
T [[bj (T1 , . . . , Tm )]]

continuo. Sia {F~i | i 2 I} una catena di n-uple di funzioni. Per ogni m-upla d~ di naturali
abbiamo
sup {(T [[bj (T1 , . . . , Tm )]]F~i }d~
~ . . . , T [[Tm ]]F~i d)}
~
= sup {bj (T [[T1 ]]F~i d,
~ . . . , sup {T [[Tm ]]F~i d})
~
= bj ( sup 0 {T [[T1 ]]F~i d},
~ . . . , sup {T [[Tm ]]F~i }d)
~
= bj ( sup {T [[T1 ]]F~i }d,
~ . . . , T [[Tm ]] sup {F~i }d)
~
= bj (T [[T1 ]] sup {F~i }d,
~
~
= T [[bj (T1 , . . . , Tm )]] sup {Fi }d

perch lestremo superiore di una catena di


funzioni continue definito in modo puntuale,
per la continuit di bj
perch lestremo superiore di una catena di
funzioni continue definito in modo puntuale,
per ipotesi induttiva

~ data lequivalenza estensionale delle funzioni, abbiamo che


Poich questo vale per ogni d,
sup {T [[bj (. . . )]]F~i } = T [[bj (. . . )]] sup {F~i }.
La dimostrazione che i funzionali T [[if T then T1 else T2 ]] e T [[fr (T1 , . . . , Tm )]] sono continui
segue uno schema analogo.

156

Capitolo 7 Un semplice linguaggio funzionale

7.4

Relazioni tra semantica operazionale e denotazionale

Gli approcci operazionali e denotazionali alla semantica dei linguaggi di programmazione


giocano un ruolo complementare. Una semantica operazionale serve da guida per limplementazione del linguaggio in quanto essa permette di tenere conto anche delle caratteristiche
delle macchine su cui questo sar implementato. Daltra parte lapproccio denotazionale permette di definire un linguaggio in modo indipendente dalla macchina, di evitare ridondanze
e costrutti ad hoc. Inoltre, lesistenza di una semantica matematica di un linguaggio di
programmazione permette di provare propriet dei suoi programmi.
Se si dispone di due diverse metodologie di specifica della semantica di un linguaggio,
diventa importante provare che, per ogni programma, esse danno luogo alla stessa valutazione.
Di seguito caratterizzeremo precisamente il concetto di equivalenza fra diverse semantiche di
un linguaggio.
Definizione 7.6. Data una semantica operazionale Op ed una semantica denotazionale Den
per un linguaggio di programmazione L, abbiamo:
1. Den consistente rispetto ad Op se Den[p] = v implica Op[p] = v per tutti i programmi
p che possibile scrivere nel linguaggio L;
2. Den completa rispetto a Op se Op[p] = v implica Den[p] = v per tutti i programmi p
che possibile scrivere nel linguaggio L;
3. Den equivalente ad Op se consistente e completa rispetto ad essa.
Per provare le relazioni fra le semantiche introdotte per SLF, abbiamo bisogno di alcuni
risultati preliminari.
Osserviamo innanzitutto che, per la definizione di punto fisso, abbiamo:
Osservazione 7.7. Per ogni dichiarazione D che contiene fr (x1 , . . . , xm ) ( Tr , abbiamo che
r (D[[D]]) = T [[Tr ]] (D[[D]]).
Valgono inoltre i due lemmi che seguono:
Lemma 7.8. (Lemma di sostituzione) Per ogni termine T e per ogni dichiarazione D si ha
~ =
T [[T [T1 /x1 , . . . , Tm /xm ]]] (D[[D]])X

~ . . . , T [[Tm ]] (D[[D]])Xi.
~
T [[T ]] (D[[D]])hT [[T1 ]] (D[[D]])X,

Dimostrazione. Per induzione sulla struttura di T .


Lemma 7.9. Per ogni dichiarazione D = {f1 (x1 , . . . , xm ) ( T1 , . . . , fn (x1 , . . . , xm ) ( Tn }
si ha
P[[letrec D in Tr [T1 /x1 , . . . , Tm /xm ]]] = P[[letrec D in fr (T1 , . . . , Tm )]].

157

7.4 Relazioni tra semantica operazionale e denotazionale


Dimostrazione. Utilizziamo ~0 per rappresentare la m-pla h0, . . . , 0i.
P[[letrec D in Tr [T1 /x1 , . . . , Tm /xm ]]]
= T [[Tr [T1 /x1 , . . . , Tm /xm ]]](D[[D]])~0
= T [[Tr ]] (D[[D]])hT [[T1 ]] (D[[D]])~0, . . . , T [[Tm ]] (D[[D]])~0i
= r (D[[D]])hT [[T1 ]] (D[[D]])~0, . . . , T [[Tm ]] (D[[D]])~0i
= T [[fr (T1 , . . . , Tm )]] (D[[D]])~0
= P[[letrec D in fr (T1 , . . . , Tm )]]

per
per
per
per
per

la regola (Dec),
il Lemma 7.8,
lOsservazione 7.7,
la regola (Fun),
la regola (Prg).

Possiamo ora dimostrare il seguente risultato di completezza:


Teorema 7.10 (Completezza rispetto alla semantica operazionale con call-by-name). P

completa rispetto a
!D , cio per tutti i programmi del linguaggio SLF abbiamo

!D n implica P[[letrec D in T ]] = n.

Dimostrazione. La tesi viene provata per induzione sulla lunghezza k della derivazione

k
T
!D n (che indichiamo T
!D n).
Base dellinduzione. Se T va in zero passi in n allora lunica possibilit che sia T n.
Esaminando la denotazione che abbiamo associato alle costanti, otteniamo che questa coincide
con n:
P[[letrec D in n]] = T [[n]] (D[[D]])h0, . . . , 0i
~
= ( F~ X.n)(D[[D]])h0,
. . . , 0i
= n.
Passo induttivo. Supponiamo che, se T

!D n, allora, per tutti i k i,

P[[letrec D in T ]] = n.
Dobbiamo provare che T
cui T

i+1

i+1

!D n possibile.

!D n implica P[[letrec D in T ]] = n. Consideriamo i casi in

T bj (T1 , . . . , Tm ) : Se bj (T1 , . . . , Tm )
m, e quindi abbiamo

i+1

!D n, allora Th

!D nh con k i e 1 h

P[[letrec D in bj (T1 , . . . , Tm )]]


= T [[bj (T1 , . . . , Tm )]] (D[[D]])h0, . . . , 0i
~
~ j (T [[T1 ]] F~ X,
~ . . . , T [[Tm ]] F~ X))(D[[D]])h0,
= ( F~ X.b
. . . , 0i
= bj (P[[letrec D in T1 ]], . . . , P[[letrec D in Tm ]])
= bj (n1 , . . . , nm )
= n

per
per
per
per
per

def. di P,
def. di T ,
def. di P,
lipotesi induttiva,
la definizione delle funzioni base.

T if T then T1 else T2 : La prova simile a quella per il caso precedente.

158

Capitolo 7 Un semplice linguaggio funzionale

T fr (T1 , . . . , Tm ) : Abbiamo che


fr (T1 , . . . , Tm )

!D Tr [T1 /x1 , . . . , Tm /xm ]

!D n.

Per ipotesi induttiva, questo implica


P[[letrec D in Tr [T1 /x1 , . . . , Tm /xm ]]] = n,
pertanto per provare la tesi resta da provare che
P[[letrec D in Tr [T1 /X1 , . . . , Tm /xm ]]] = P[[letrec D in fr (T1 , . . . , Tm )]],
ma questo esattamente quanto aermato dal Lemma 7.9.

Come abbiamo dimostrato che P completa rispetto alla semantica operazionale con callby-name, cos possiamo dimostrare che lo anche rispetto alla semantica operazionale con
call-by-value. In eetti, questo risultato una immediata conseguenza di alcuni risultati gi
dimostrati.
Teorema 7.11 (Completezza rispetto alla semantica operazionale con call-by-value). P

completa rispetto a !D , cio per tutti i programmi del linguaggio SLF abbiamo
T

!D n implica P[[letrec D in T ]] = n.

Dimostrazione. Questo risultato una diretta conseguenza del Lemma 7.4 e del Teorema 7.10.
Per la semantica operazionale basata sulla chiamata per nome, dimostriamo anche il
seguente teorema, che risulter non valido per la semantica basata su call-by-value.
Teorema 7.12 (Consistenza rispetto alla semantica operazionale con call-by-name). P

consistente rispetto a
!D , cio per tutti i programmi del linguaggio SLF abbiamo
P[[letrec D in T ]] = n implica T

!D n.

Dimostrazione. Dalla definizione di P e dalla continuit di T (Teorema 7.5), segue che


P[[letrec D in T ]] = T [[T ]] D[[D]]h0, . . . , 0i = T [[T ]] f ix F~ (r) h0, . . . , 0i = f ix T [[T ]] F~ (r) h0, . . . , 0i
dove, per ogni r 0, F~ (r) indica lr-mo approssimante del minimo punto fisso del funzionale
associato alle dichiarazioni D. Quindi, P[[letrec D in T ]] = n implica che, per qualche naturale r, si ha T [[T ]] F~ (r) h0, . . . , 0i = n. Sar allora suciente dimostrare che, per ogni naturale
r,

T [[T ]] F~ (r) h0, . . . , 0i = n implica T


!D n.
(7.1)
Si noti che essendo T chiuso, la scelta della m-pla di argomenti (in questo caso h0, . . . , 0i)
del tutto irrilevante, cio non influenza il valore assunto dalla funzione T [[T ]] F~ (r) .

159

7.4 Relazioni tra semantica operazionale e denotazionale

Dimostriamo ora un risultato pi generale, da cui la tesi seguir come corollario. Sia T un
termine non necessariamente chiuso; assumiamo solo che le sue variabili libere appartengano
allinsieme {y1 , . . . , ym }. Presi m termini chiusi {V1 , . . . , Vm } qualsiasi, dimostriamo che:
T [[T ]]F~ (r) (res(V1 ), . . . , res(Vm )) = n implica T [V1 /y1 , . . . , Vm /ym ]
dove, per ogni termine chiuso V , poniamo
(
res(V ) =

!D n,

(7.2)

n se V
!D n
? altrimenti.

In pratica, res(V ) indica il risultato della valutazione operazionale del termine chiuso V .
Si noti che la propriet (7.2) pu essere equivalentemente espressa come:
T [[T ]]F~ (r) (res(V1 ), . . . , res(Vm )) v res(T [V1 /y1 , . . . , Vm /ym ]).

(7.3)

Infatti, se vale la propriet (7.2) allora abbiamo o che T [[T ]]F~ (r) (res(V1 ), . . . , res(Vm )) =?,
quindi la propriet (7.3) banalmente vera, oppure che T [[T ]]F~ (r) (res(V1 ), . . . , res(Vm )) =
n; in questultimo caso, dalla definizione di res(), segue res(T [V1 /y1 , . . . , Vm /ym ]) = n
per cui si ha nuovamente che la propriet (7.3) vale. Al contrario, cio se vale la propriet (7.3), e se T [[T ]]F~ (r) (res(V1 ), . . . , res(Vm )) = n, allora, dalla definizione di v,
segue che res(T [V1 /y1 , . . . , Vm /ym ]) = n; quindi, dalla definizione di res(), abbiamo

T [V1 /y1 , . . . , Vm /ym ]


!D n, che vuol dire che la propriet (7.2) vale.
Procediamo ora a dimostrare la propriet (7.1) ragionando per induzione su r. Se
r = 0, quindi F~ (0) = hm , . . . , m i (dove m (x1 , . . . xm ). ?), la tesi segue per in~ =
duzione sulla struttura di T . Consideriamo solo i casi pi interessanti. Poniamo V
hres(V1 ), . . . , res(Vm )i. Osserviamo che, se T fh (T1 , . . . , Tm ), allora:
~ =
T [[fh (T1 , . . . , Tm )]]hm , . . . , m iV
~ , . . . , T [[Tm ]] hm , . . . , m iV
~)=
h hm , . . . , m i(T [[T1 ]] hm , . . . , m iV
~ , . . . , T [[Tm ]] hm , . . . , m iV
~ ) =?
m (T [[T1 ]] hm , . . . , m iV
e quindi la tesi segue banalmente. Invece, se T una variabile, necessariamente una delle yj ,
con 1 j m, si ha
~ = j V
~ = res(Vj ).
T [[yj ]]hm , . . . , m iV

~ = n, cio res(Vj ) = n, allora, dalla definizione di res(Vj ), segue


Ora, se T [[yj ]]hm , . . . , m iV

che Vj
!D n. La tesi deriva allora dal fatto che yj [V1 /y1 , . . . , Vm /ym ] Vj . Gli altri casi
della base dellinduzione sono altrettanto semplici e lasciati al lettore.
Consideriamo ora il caso r > 0. Procediamo ancora per induzione sulla struttura di T .
Lunico caso interessante quando T fh (T1 , . . . , Tm ), poich gli altri casi procedono in
modo simile al caso r = 0. In tal caso, abbiamo
~
T [[fh (T1 , . . . , Tm )]]F~ (r) V

~ , . . . , T [[Tm ]]F~ (r) V


~i
= h (F~ (r) )hT [[T1 ]]F~ (r) V
~ , . . . , T [[Tm ]]F~ (r) V
~ i,
= T [[Th ]]F~ (r 1) hT [[T1 ]]F~ (r) V

dove la prima uguaglianza ottenuta applicando la regola (Fun) della semantica


denotazionale, mentre la seconda segue dalla definizione di approssimante (vista in 6.7).

160

Capitolo 7 Un semplice linguaggio funzionale

Le variabili di Ti , per 1 < i < m, appartengono certamente allinsieme {y1 , . . . , ym }


cosicch, per ipotesi induttiva interna (induzione strutturale), abbiamo che, per ogni 1 i
m,
~ = ni implica Ti [V1 /y1 , . . . , Vm /ym ] ! ni .
T [[Ti ]]F~ (r) V
D
cio, equivalentemente, che

~ v res(Ti [V1 /y1 , . . . , Vm /ym ]).


T [[Ti ]]F~ (r) V
Allora, per la monotonia di T (si ricordi che la continuit di T , argomentata alla fine della
sezione precedente e dimostrata dal Teorema 7.5, ne implica la monotonia) si ha
T [[Th ]]F~ (r

1)

~ , . . . , T [[Tm ]]F~ (r) V


~iv
hT [[T1 ]]F~ (r) V
T [[Th ]]F~ (r 1) hres(T1 [V1 /y1 , . . . , Vm /ym ]), . . . , res(Tm [V1 /y1 , . . . , Vm /ym ])i

Per ipotesi induttiva esterna (induzione matematica) abbiamo che


T [[Th ]]F~ (r

1)

hres(T1 [V1 /y1 , . . . , Vm /ym ]), . . . , res(Tm [V1 /y1 , . . . , Vm /ym ])i = n

implica Th [T1 [V1 /y1 , . . . , Vm /ym ]/y1 , . . . , Tm [V1 /y1 , . . . , Vm /ym ]/ym ]

!D n.

cio, equivalentemente, che


T [[Th ]]F~ (r

1)

hres(T1 [V1 /y1 , . . . , Vm /ym ]), . . . , res(Tm [V1 /y1 , . . . , Vm /ym ])i

v res(Th [T1 [V1 /y1 , . . . , Vm /ym ]/y1 , . . . , Tm [V1 /y1 , . . . , Vm /ym ]/ym ]).

Poich dalla semantica operazionale abbiamo che


fh (T1 [V1 /y1 , . . . , Vm /ym ], . . . , Tm [V1 /y1 , . . . , Vm /ym ])

!D

Th [T1 [V1 /y1 , . . . , Vm /ym ]/y1 , . . . , Tm [V1 /y1 , . . . , Vm /ym ]/ym ]


ne segue, per definizione di res(), che
res(fh (T1 [V1 /y1 , . . . , Vm /ym ], . . . , Tm [V1 /y1 , . . . , Vm /ym ]))
= res(Th [T1 [V1 /y1 , . . . , Vm /ym ]/y1 , . . . , Tm [V1 /y1 , . . . , Vm /ym ]/ym ]).
Perci

~ v res(fh (T1 , . . . , Tm )[V1 /y1 , . . . , Vm /ym ])


T [[fh (T1 , . . . , Tm )]]F~ (r) V

Quindi, lipotesi induttiva provata nel caso T fh (T1 , . . . , Tm ).


Per induzione matematica possiamo allora concludere che per ogni naturale r e per ogni
termine chiuso T vale che
T [[T ]]F~ (r) h0, . . . , 0i = n implica

!D n.

che quanto volevamo dimostrare.


facile vedere che P non consistente rispetto alla semantica operazionale con call-byvalue.

161

7.5 Esercizi
Esempio 7.13. Sia P il programma
letrec

f1 (x) ( if x then 1 else f1 (x)


f2 (x) ( 1
f2 (f1 (1))

in

Ora, non dicile dimostrare che


D[[f1 (x) ( if x then 1 else f1 (x), f2 (x) ( 1]] =
fix( (g1 , g2 ).hT [[if x then 1 else f1 (x)]] hg1 , g2 i, T [[1]] hg1 , g2 ii) =
h x.x ! 1,?, x.1i,
e quindi che
P[[P ]] =
T [[f2 (f1 (1))]] h x.x ! 1,?, x.1i 0 =
( x.1)(T [[f1 (1)]]h x.x ! 1,?, x.1i 0) =
= 1
Invece, la semantica operazionale basata su call-by-value d luogo alla computazione
divergente:
(Fun00 )

f2 (f1 (1))
perch si ha

f1 (1)

!D f2 (f1 (1))
(Cond2 )

(Fun00 )

!D . . .

!D f1 (1)

Per concludere, osserviamo che certamente possibile definire una semantica denotazionale
per il linguaggio SLF che sia equivalente (consistente e completa rispetto) alla semantica
operazionale definita dalle regole per la chiamata per valore. Per far ci suciente modificare
leggermente la semantica denotazionale descritta in Tabella 7.4. Lapplicazione di funzione
va modificata, per richiedere che anche tutte le funzioni non di base siano strette, cio che
siano indefinite se alcuni dei loro argomenti non sono definiti.

7.5

Esercizi

1. Scrivere i programmi SLF per calcolare


la funzione M CD(x, y), che determina il massimo comun divisore fra x ed y;
la funzione di Fibonacci F IB(x).
2. Definire in SLF la funzione predecessore senza usare loperazione di sottrazione.
3. Introdurre in SLF un tipo di dato lista di naturali e scrivere una funzione che, data una
lista, ne calcola la lunghezza.
4. Modificare la semantica operazionale di SLF in modo tale che gli argomenti delle funzioni
base siano valutati
da sinistra verso destra;
in parallelo.

162

Capitolo 7 Un semplice linguaggio funzionale

5. Definire i predicati di uguaglianza, di minore e di minore o uguale in SLF.


6. Fornire semantica operazionale e denotazionale del programma
letrec f(x) ( f(x) in f(5).
7. Fornire un programma SLF la cui valutazione usando il passaggio di parametri per valore
pi rapida di quella che si ottiene usando il passaggio di parametri per nome, nel
senso che il valore si ottiene con una minore quantit di transizioni.
8. Definire una semantica denotazionale per SLF che sia equivalente alla semantica
operazionale con la chiamata per valore.
9. Proporre restrizioni sintattiche per il linguaggio SLF in modo tale che nell linguaggio
risultante le chiamate per nome e per valore coincidano.
10. Discutere, dal punto di vista operazionale, la validit della seguente equivalenza:
f(if T then T1 else T2 ) = if T then f(T1 ) else f(T2 ).
11. Usare la semantica denotazionale per provare che
letrec f(x) ( x in T

= letrec f(x) ( x in f(T ).

12. possibile specificare la sintassi di SLF senza usare i puntini (. . .)? Motivare la risposta.

Capitolo 8

Un semplice linguaggio imperativo

SOMMARIO
Questo capitolo presenta alcuni concetti comuni a vari linguaggi di programmazione e le
tecniche utilizzate per la loro descrizione formale. Considereremo TINY, un semplice linguaggio di programmazione imperativo, di cui presenteremo una semantica operazionale ed
una semantica denotazionale e ne dimostreremo lequivalenza.

8.1

Il linguaggio TINY

TINY, gi introdotto in [Gor79], un frammento, privo di dichiarazioni, del linguaggio Pascal.


Esso rientra allinterno di quella categoria di linguaggi noti come imperativi, cio basati sui
comandi (quali assegnamento e sequenzializzazione); in contrasto con i cosiddetti linguaggi
funzionali (o applicativi ), che sono invece essenzialmente basati sullapplicazione di funzione.
Un programma TINY consiste di una sequenza di comandi, che possono contenere al loro
interno delle espressioni da valutare. Il linguaggio quindi basato su due principali categorie
sintattiche: Com, la categoria dei comandi, ed Exp, la categoria delle espressioni. Entrambe
queste categorie sono basate sulla categoria sintattica degli identificatori, che assumeremo gi
nota ed il cui corrispettivo semantico non sar analizzato in dettaglio. Essi si assumeranno
costituiti da una qualsiasi stringa di numeri o lettere.
Le clausole che specificano la sintassi astratta del linguaggio TINY sono riportate in
Tabella 8.1; le parole chiave del linguaggio sono scritte in grassetto.
e ::= true | false | not e | n | e1 nop e2 | e1 bop e2 | read | x
c ::= noaction | x := e | c1 ; c2 | if e then c1 else c2 | while e do c | output e
Tabella 8.1: Sintassi di TINY
Il significato intuitivo dei vari costrutti quello suggerito dalla pratica della programmazione. Per quanto riguarda le espressioni, le stringhe true e false rappresentano i valori
booleani vero e falso, cos come n rappresenta un qualunque numero naturale. La stringa not
rappresenta loperazione di negazione sui booleani, mentre nop e bop stanno ad indicare
operatori binari rispettivamente sui naturali e sui booleani, come le operazioni aritmetiche
o il predicato di uguaglianza. La stringa read rappresenta invece loperazione di lettura da

164

Capitolo 8 Un semplice linguaggio imperativo

un file di input. Per quanto riguarda i comandi, i costrutti sintattici rappresentano, nellordine, il comando nullo, lassegnamento, la sequenzializzazione, il condizionale, literazione e
loperazione di scrittura su un file di output. Infine, un programma TINY una sequenza di
comandi.

8.2

Semantica operazionale di TINY

Per definire la semantica operazionale delle espressioni di TINY, consideriamo innanzitutto il


sistema di transizioni
(, F , !
!)
in cui linsieme delle configurazioni definito come segue:
= {he, i | e 2 Exp,

: Id ! Val} [ { : Id ! Val},

dove e unespressione e , lo stato, una funzione che associa valori ad identificatori.


Linsieme delle configurazioni finali F
F = { : Id ! Val}.
Dato uno stato , un valore v 2 Val ed un identificatore id 2 Id, la notazione [v/id]
indica lo stato cos definito: [v/id](id0 ) = (id0 ) se id0 6= id, [v/id](id0 ) = v altrimenti (cio
se id0 = id).
La definizione della relazione di transizione !
! riportata in Tabella 8.2.
Assumeremo lesistenza di tre identificatori riservati, che chiameremo rispettivamente
res, a cui sar associato un valore di base, ovvero un intero o un booleano;
in, a cui sar associata una sequenza di valori di base, gli input del programma;
out, a cui sar associata una sequenza di valori di base, gli output del programma.
Il risultato v della valutazione di unespressione sar memorizzato tramite lassociazione di v
allidentificatore res. La lettura di un valore dalla sequenza di input, tramite lespressione
read, modificher questa sequenza estraendone la testa (e memorizzandola in res) ed associando ad in la coda della sequenza iniziale. Per realizzare queste operazioni vengono usate
le due funzioni hd e tl.
Si osservi che quella descritta nella Tabella 8.2 una semantica di valutazione; questo
vuol dire che la relazione di transizione permette di ottenere in un solo passo il valore di
unespressione.
(True), (False), (Nat): La valutazione dellespressione true nello stato comporta laggiornamento di in modo tale che, nel nuovo stato, allidentificatore res venga associato il
valore true. La valutazione dellespressione false o dellespressione n avviene in modo
analogo.
(Ide): La valutazione di un identificatore x in uno stato
il valore che in viene associato ad x.

viene realizzata associando a res

165

8.2 Semantica operazionale di TINY

htrue, i

!
! [true/res]

(True)

hfalse, i

!
! [false/res]

(False)

hn, i

!
! [n/res]

(Nat)

hx, i

!
! [ (x)/res]

(Ide)

he, i !
!
hnot e, i

0 (res)

!
!

0 [v/res]

=v

he1 , i !
! 0
he2 , 0 i !
! 00
he1 bop e2 , i !
!

= v1
= v2
00 [v bop v /res]
1
2

he1 , i !
! 0
0
he2 , i !
! 00
he1 nop e2 , i !
!

= v1
= v2
00 [v nop v /res]
1
2

hread, i

(Not)

0 (res)

00 (res)

(Bop)

0 (res)

00 (res)

(Nop)

!
! [hd( (in))/res, tl( (in))/in] (Read)

Tabella 8.2: Semantica operazionale delle espressioni di TINY


(Not): Data unespressione e, la valutazione dellespressione not e in uno stato viene ottenuta considerando lo stato 0 risultato della valutazione di e e negando il valore che
0 associa a res. Non ci occupiamo, in questa descrizione, delleventualit che il valore
dellespressione e non sia un booleano; ignoriamo quindi situazioni di errore.
(Bop): Per valutare unespressione della forma e1 bop e2 in uno stato , si considera lo stato 0
ottenuto dalla valutazione di e1 in ; successivamente si considera lo stato 00 ottenuto
dalla valutazione di e2 in 0 . Il risultato finale uno stato ottenuto da 00 associando a
res il valore v1 bop v2 che si ha applicando loperatore booleano ai valori ottenuti dalla
valutazione di e1 ed e2 .
(Nop): La valutazione di unespressione della forma e1 nop e2 procede in modo perfettamente
analogo al caso precedente.
(Read): La valutazione dellespressione read in uno stato comporta lassociazione a res
della testa della sequenza di input, ed il conseguente aggiornamento di questultima.
Per definire la semantica operazionale dei comandi di TINY, consideriamo il sistema di
transizioni
(K, KF , !)

166

Capitolo 8 Un semplice linguaggio imperativo

0 (res) = v
he, i !
! 0
(Ass)
hx := e, i ! hnoaction, 0 [v/x]i

hnoaction; c2 , i ! hc2 , i

(Seq1 )

hc1 , i ! hc01 , 0 i
(Seq2 )
hc1 ; c2 , i ! hc01 ; c2 , 0 i
0 (res) = true
he, i !
! 0
(Cond1 )
hif e then c1 else c2 , i ! hc1 , 0 i
0 (res) = false
he, i !
! 0
(Cond2 )
hif e then c1 else c2 , i ! hc2 , 0 i
0 (res) = true
he, i !
! 0
hwhile e do c, i ! hc; while e do c,

0i

(While1 )

0 (res) = false
he, i !
! 0
(While2 )
hwhile e do c, i ! hnoaction, 0 i
0 (res) = v
he, i !
! 0
(Out)
houtput e, i ! hnoaction, 0 [v :: ( (out))/out]i

Tabella 8.3: Semantica operazionale dei comandi di TINY


in cui linsieme delle configurazioni K definito come segue:
K = {hc, i | c 2 Com,
dove c un comando e

: Id ! Val},

uno stato. Linsieme delle configurazioni finali KF


KF = {hnoaction, i |

: Id ! Val}.

La semantica operazionale dei comandi di TINY descritta dalla relazione di transizione


!, definita in Tabella 8.3 (dove ricordiamo che loperatore :: indica laggiunta di un elemento
in testa ad una lista).
Lesecuzione di un comando procede nel modo seguente:
(Ass): La valutazione di unassegnazione x := e nello stato
dellespressione e allidentificatore x.

causa lassociazione del valore

(Seq): Nella valutazione di una sequenza di comandi c1 ; c2 , si procede valutando c1 tramite la


regola (Seq)2 , finch c1 non si rriduce a noaction. A questo punto lesecuzione prosegue
valutando c2 nello stato ottenuto dallesecuzione di c1 .

167

8.3 Semantica denotazionale di TINY

(Cond): Per eseguire il condizionale if e then c1 else c2 , si valuta prima lespressione e,


quindi, a seconda che questa sia vera o falsa, si esegue il comando c1 oppure il comando
c2 , a partire dallo stato ottenuto dalla valutazione di e.
(While): Per eseguire il ciclo while e do c, si valuta prima lespressione e, quindi, a seconda
che questa sia vera o falsa, si esegue, a partire dallo stato ottenuto dalla valutazione di
e, il comando c seguito da una nuova chiamata di ciclo oppure il comando noaction.
(Out): La valutazione del comando output e in uno stato
seguita dallaggiornamento della sequenza di output.

comporta la valutazione di e

Osserviamo che la Tabella 8.3 non contiene alcuna regola per la riscrittura di noaction.
Questo basta per concludere che noaction viene interpretato come il comando nullo. Un
esempio dellesecuzione di un semplice programma TINY, ottenuta utilizzando il sistema di
transizioni appena descritto, riportato in Tabella 8.4.
Analizziamo ora alcune propriet della semantica operazionale di TINY. Per fare questo,
abbiamo bisogno di introdurre alcuni concetti.
Definizione 8.1. Una computazione di un comando c a partire da uno stato
hc, i hc0 ,

0i

! hc1 ,

1i

! ! hcn ,

ni

una sequenza

che infinita, oppure tale che lultima configurazione della forma hnoaction,

0 i.

Informalmente, diremo che uno stato appropriato per un comando c se tutte le variabili
di c sono definite in . Il fatto che una variabile x sia definita in uno stato indica o che
associa esplicitamente un valore a x o che la sequenza dei valori di input associati a in
sucientemente lunga da permettere di leggere, tramite espressioni read, i valori di base
necessari per poi inizializzare x.
Vale il seguente teorema, che pu essere dimostrato per induzione utilizzando la semantica
operazionale ed eettuando unanalisi della struttura di tutti i possibili programmi TINY.
Teorema 8.2. Siano c un programma TINY e

uno stato appropriato per c.

1. Progresso: esiste sempre una computazione da hc, i.


2. Determinismo: se c 6 noaction, allora esiste una sola configurazione hc0 ,
hc, i ! hc0 , 0 i.

8.3

0i

tale che

Semantica denotazionale di TINY

Di seguito studieremo le funzioni di interpretazione semantica per Exp, che chiameremo E,


e per Com, che chiameremo C. Queste funzioni associano ai relativi costrutti sintattici gli
elementi di opportuni domini semantici. Per far questo, dopo aver definito tramite la sintassi
astratta i possibili programmi, necessario specificare i domini semantici D1 e D2 tali che:
E : Exp ! D1
C : Com ! D2 .
A questo scopo bisogna individuare linsieme dei possibili valori delle espressioni, dei possibili input e dei possibili output del programma. anche necessario individuare delle strutture

168

Capitolo 8 Un semplice linguaggio imperativo


* x := 2 read; y := read;
while x < y do
output (y x); x := x + 1
#
* y := read;
while x < y do
output (y

while x < y do
output (y

x); x := x + 1
#

x); x := x + 1

in 7! [2, 5]
out 7! [ ]

8
res 7! 4
>
>
<
in 7! [5]
,
out 7! [ ]
>
>
:
x 7! 4

9
>
+
>
=
>
>
;

8
9 +
< res 7! 5
=
in 7! [ ] x 7! 4
,
:
;
out 7! [ ] y !
7
5

#
8
9 +
* output (y x); x := x + 1;
< res 7! true
=
while x < y do
in 7! [ ]
x 7! 4
,
:
;
output (y x); x := x + 1
out 7! [ ]
y 7! 5
#
8
9 +
* x := x + 1;
7
1
< res !
=
while x < y do
in 7! [ ]
x 7! 4
,
:
;
output (y x); x := x + 1
out 7! [1] y 7! 5
#
8
9 +
*
< res 7! 5
=
while x < y do
in 7! [ ]
x 7! 5
,
output (y x); x := x + 1
:
;
out 7! [1] y 7! 5
#
8
9 +
*
< res 7! false
=
noaction ,
in 7! [ ]
x 7! 5
:
;
out 7! [1]
y 7! 5
Tabella 8.4: Un esempio di computazione in TINY
dati che permettano di descrivere passo passo il comportamento dei vari programmi scritti
in TINY e che siano comunque sucientemente astratte da evitare la descrizione di inutili
dettagli implementativi. Tali strutture dati, analogamente a quanto gi visto nel caso della
calcolatrice tascabile, dipenderanno dallinput, dalloutput e dalla memoria. La memoria non
sar, come nel caso della calcolatrice tascabile, semplicemente un intero, ma una funzione
che associa valori booleani o naturali ad identificatori. Questa scelta ci permetter di determinare i valori delle variabili usate allinterno dei programmi e di modificare lassociazione
variabili-valori per tener conto di eventuali comandi di assegnamento.
La struttura dati, che utilizzeremo per descrivere il comportamento dei vari programmi,
non esplicitamente menzionata allinterno della sintassi del linguaggio, ma gioca un ruolo
fondamentale per la descrizione della semantica; come per la semantica operazionale, questa
struttura viene chiamata stato. Tutte le possibili frasi del linguaggio verranno descritte in
termini delle modifiche che esse inducono sullo stato. Oltre a definire lassociazione variabili-

8.3 Semantica denotazionale di TINY

169

valori, esso servir a modellare la comunicazione tra parti separate di uno stesso programma:
i valori calcolati da una frase sono depositati nello stato ed altre frasi useranno il nuovo stato
aggiornato. Essenzialmente lo stato rappresenta un argomento implicito durante lesecuzione
di tutti i programmi e non altro che un modello della memoria del calcolatore.
In generale leetto dellesecuzione di un comando di un linguaggio imperativo quello di cambiare il contenuto delle celle di memoria, dellinput o delloutput. La descrizione
denotazionale rende esplicito questo fatto modellando lo stato come una tripla che contiene
informazioni su input, output e memoria e la semantica dei vari comandi come funzioni che
trasformano uno stato in un altro, in generale diverso dal precedente.
I domini semantici che utilizzeremo per descrivere le funzioni di interpretazione del
linguaggio TINY sono riportati di seguito.
VAL
MEM
STATO

= NAT + BOOL
= ID ! (VAL + {unbound})
= VAL VAL MEM.

VAL indica linsieme dei possibili valori che le diverse espressioni possono assumere.
MEM invece una funzione che viene utilizzata per rappresentare la corrispondenza tra

identificatori e valori dei domini semantici. Ad un identificatore al quale non corrisponde


alcun valore viene associata la stringa unbound.
STATO una tripla che rappresenta lo stato di un particolare programma ed il parametro
che deve essere passato alla funzione di interpretazione semantica per valutare i vari termini
del linguaggio. Lo stato di un programma contiene informazioni sulle sequenze di valori che
saranno date come input e prodotte come output e sullassociazione identificatori-valori del
programma stesso. Difatti la coppia VAL VAL sta proprio ad indicare le possibili sequenze
di valori di input e di output dei programmi.
Noi assumeremo che linput venga fornito dallutente prima dellesecuzione di un programma e che loutput del programma venga descritto aggiungendo ad una sequenza inizialmente vuota i valori che si vogliono comunicare allesterno. Il risultato finale di un qualsiasi
programma sar lintera lista degli output, leggibile solo dopo la terminazione del programma.
I domini semantici appena visti ci permettono di specificare i domini semantici di E e di
C, cio D1 e D2 ; importante notare che entrambi questi ultimi, e anche le loro componenti
pi elementari (STATO, VAL, {error}) sono degli ordinamenti parziali completi, o cpo.
Leetto di valutare unespressione a partire da uno stato qualsiasi quello di produrre
un risultato ed allo stesso tempo un nuovo stato, oppure di generare un errore. Questo viene
espresso dalla seguente funzionalit di E:
E : Exp ! STATO ! ((VAL STATO) + {error}).
La funzione di valutazione di unespressione prende lespressione stessa come argomento e
fornisce come risultato una funzione che, dato uno stato, produce errore oppure una coppia
formata da un valore e da un altro stato. Questultimo risulta dalle modifiche apportate
allo stato originario durante la valutazione dellespressione. Il valore error viene restituito
se, durante la valutazione dellespressione, insorgono situazioni di errore, quali ad esempio la
divisione per zero oppure luso di identificatori a cui non corrisponde alcun valore allinterno
della memoria.

170

Capitolo 8 Un semplice linguaggio imperativo

Osservazione 8.3. Poich le espressioni producono valori, si potrebbe pensare di prendere come denotazione delle espressioni gli elementi del dominio VAL, e quindi di porre semplicemente
E : Exp ! VAL.
Questo potrebbe andar bene per i valori (costanti) di base, ma non permetterebbe di modellare la semantica di espressioni che causano errori, quali ad esempio 1 + true. Per trattare
adeguatamente tali situazioni dovremmo definire E : Exp ! (VAL + {error}).
Ci per non sarebbe ancora suciente per esprimere la dipendenza dei valori di alcune
espressioni dallo stato, come per esempio nel caso di x+1, il cui valore dipende dal valore legato
ad x nella memoria, o di 1+read, il cui valore dipende dallinput. Per trattare adeguatamente
anche tali situazioni dovremmo definire E : Exp ! STATO ! (VAL + {error}).
Infine, dobbiamo tener conto anche del fatto che la valutazione di unespressione potrebbe
modificare lo stato, come capita per esempio per lespressione read, la cui valutazione comporta la rimozione del primo valore dalla sequenza dei valori in input. Per trattare adeguatamente
anche tali situazioni dobbiamo definire E : Exp ! STATO ! ((VAL STATO) + {error}).
Leetto di eseguire un comando a partire da uno stato qualsiasi quello di produrre un
nuovo stato o di generare un errore; questo viene espresso nella seguente funzionalit di C:
C : Com ! STATO ! (STATO + {error}).
La funzione di valutazione di un comando prende il comando stesso come argomento e fornisce
come risultato una funzione che, dato uno stato, produce errore oppure un nuovo stato.
Nelle due sezioni successive riportiamo tutte le clausole di interpretazione semantica per
TINY. Il valore delle funzioni di interpretazione E e C sar definito in termini del metalinguaggio visto in precedenza in Sezione 6.5; avremo unequazione per ciascuna delle opzioni
delle categorie sintattiche Exp e Com. Ogni equazione sar seguita da brevi commenti sul suo
significato.
importante notare che le clausole di interpretazione semantica che riportiamo sono
sucienti per definire completamente la semantica di TINY e cio di tutti i programmi e di
tutte le espressioni che si possono costruire a partire dalla grammatica del linguaggio. Daremo
una clausola per ogni costrutto di TINY e definiremo E e C sui termini composti in funzione dei
risultati della loro applicazione ai sottotermini. Il principio di induzione strutturale garantisce
che questo suciente per specificare la semantica di qualsiasi programma TINY. Come
vedremo, le definizioni di E e di C sono mutuamente ricorsive nel senso che si richiamano a
vicenda. Esse vanno viste come un unico sistema ricorsivo la cui soluzione garantita dal
fatto che tutte le funzioni sono continue (vedi Capitolo 6) e quindi dallesistenza del minimo
punto fisso.

8.4

Semantica delle espressioni

In questa sezione riportiamo le equazioni semantiche relative alla categoria sintattica Exp.
Sostanzialmente esse associano ad ogni espressione una funzione che preso uno stato produce un valore (il valore dellespressione) ed uno stato eventualmente modificato durante la
valutazione dellespressione.

171

8.4 Semantica delle espressioni

E[[true]] =
E[[false]] =

. < true,
. < false,

>
>

La denotazione dellespressione true (risp. false) una funzione che riceve come input
uno stato e costruisce la coppia < true, > (risp. < false, >) dove true (false) il valore
di verit costante che fa parte del dominio semantico dei booleani assunto noto; lo stato
esattamente lo stesso stato ricevuto in ingresso dal momento che la valutazione di una costante
non comporta alcuna modifica alla memoria. Vale la pena notare che la denotazione scelta
per true e false non completamente appropriata. Per tener conto esattamente del tipo delle
funzioni di interpretazione semantica avremmo dovuto scrivere
E[[true]] =

.in0 (< true,

>)

E[[false]] =

.in0 (< false,

>).

Comunque, nel resto delle note ometteremo questi dettagli per non appesantire
ulteriormente la notazione.
E[[not e]] =

. cases (E[[e]] ) of
< v, 0 >: isbool(v) !< (v),
error : error
endcases

>, error;

La denotazione dellespressione not e una funzione che ricevuto uno stato lo usa per
valutare lespressione e, quindi produce come risultato intermedio una coppia <valore, nuovo
stato>. Successivamente la funzione controlla che la prima componente del risultato sia un
valore di verit e costruisce la coppia formata dal negato del valore risultato e dal nuovo stato
( rappresenta il simbolo di negazione del metalinguaggio). Nel caso in cui la valutazione
dellespressione e dia luogo ad errore oppure il valore risultato non sia un booleano, il risultato
della funzione error. A voler essere pi precisi si potrebbe distinguere anche fra i due tipi
di errore, ma, per semplicit, preferiamo ignorare anche questo tipo di problematica.
E[[n]] =

. < n,

>

La denotazione dellespressione n una funzione che quando riceve come input uno stato
costruisce la coppia < n, > dove ora n un elemento del dominio degli interi e lo stato
ricevuto in ingresso.
E[[read]] = (in, out, mem). cases in of
nil : error;
v :: in0 :< v, < in0 , out, mem >>
endcases
La funzione associata a read riceve in input uno stato, che viene visto in questo caso
come una tripla ottenuta dal prodotto di elementi di tre domini1 . Questo modo esplicito di
1
Ricordiamo che, in base alla notazione descritta nel Capitolo 5, (in, out, mem).E(in, out, mem) sta per
.E(21 , 22 , 23 ).

172

Capitolo 8 Un semplice linguaggio imperativo

vedere lo stato ci permette di selezionare la sue componenti ed assegnare loro un nome; grazie
a questa possibilit, la funzione associata a read pu verificare se la componente dello stato
corrispondente allinput una lista (diciamo l) non vuota ed in caso aermativo produrre
come risultato il primo elemento di l insieme ad un nuovo stato del tutto simile al precedente
a parte la lista di input che viene modificata rimuovendo da essa il primo elemento. Se la lista
di input risulta vuota la funzione corrispondente a read vale error.
E[[e1 nop e2 ]] =

. cases (E[[e1 ]] ) of
< v1 , 1 >: isnat(v1 ) !
cases (E[[e2 ]] 1 ) of
< v2 , 2 >: isnat(v2 ) !
< v1 nop v2 ,
error;
error : error
endcases,
error;
error : error
endcases

>,

La funzione associata ad e1 nop e2 valuta la prima espressione ottenendo come risultato


un valore ed un nuovo stato; questultimo viene usato per valutare la seconda espressione. Il
risultato finale della valutazione di e1 nop e2 quindi la coppia formata dal risultato delloperazione fra i valori ottenuti dalla valutazione delle due espressioni e dallo stato risultante
dalla valutazione della seconda espressione. Tutto questo si verifica se le valutazioni non danno luogo ad errori e se i valori ottenuti come risultato sono elementi del dominio dei naturali;
in caso contrario il risultato della valutazione di e1 nop e2
. error. A volte sar necessario inserire nella clausola precedente ulteriori controlli sulla correttezza di una particolare
operazione. Nel caso della divisione ad esempio scriveremo, al posto di < v1 nop v2 , 2 >:
iszero(v2 ) ! error, < v1 nop v2 ,
E[[e1 bop e2 ]] =

>.

. cases (E[[e1 ]] ) of
< v1 , 1 >: isbool(v1 ) !
cases (E[[e2 ]] 1 ) of
< v2 , 2 >: isbool(v2 ) !
< v1 bop v2 ,
error;
error : error
endcases,
error;
error : error
endcases

>,

La funzione associata ad e1 bop e2 simile a quella associata ad e1 nop e2 . Il risultato


finale quindi una coppia < v1 bop v2 , 2 > dove 2 lo stato ottenuto dopo la valutazione
di e2 .

173

8.5 Semantica dei comandi


E[[x]] = (in, out, mem). mem(x) = unbound ! error,
< mem(x), < in, out, mem >>

La semantica di un identificatore una funzione dello stato che restituisce il vecchio stato
ed il valore associato ad x allinterno di esso, se x non unbound; in caso contrario restituisce
semplicemente error.

8.5

Semantica dei comandi

La funzione di interpretazione dei comandi una funzione che dato uno stato lo trasforma
in un nuovo stato che il risultato delle modifiche apportate allo stato originario durante
lesecuzione del comando. Se si verificano situazioni di errore allora invece che uno stato il
risultato della valutazione la stringa error.
C[[noaction]] =

Il significato del comando noaction la funzione identit sullo stato, cio la funzione che
non modifica il suo argomento.
C[[x := e]] =

. cases (E[[e]] ) of
< v, < in, out, mem >>:< in, out, mem[v/x] >;
error : error
endcases

La semantica di un comando di assegnamento prevede la valutazione dellespressione coinvolta nel comando, la verifica che questa valutazione non dia luogo ad errori e quindi la
creazione di un nuovo legame allinterno della memoria (tramite [v/x]) tra lidentificatore a
sinistra dellassegnamento ed il risultato della valutazione. Chiaramente, se x in precedenza
era legato ad un altro valore, il vecchio legame viene perso.
C[[c1 ; c2 ]] =

. cases (C[[c1 ]] ) of
0 : C[[c ]] 0 ;
2
error : error
endcases

La semantica delloperatore di sequenzializzazione prevede la valutazione del primo comando usando lo stato che viene passato come argomento alla funzione di valutazione. Il secondo
comando viene quindi interpretato utilizzando lo stato risultante della prima valutazione.
Questo succede solo quando non si verificano situazioni di errore.
C[[if e then c1 else c2 ]] =

. cases (E[[e]] ) of
< v, 0 >: isbool(v) !
v ! C[[c1 ]] 0 , C[[c2 ]]
error;
error : error
endcases

0,

174

Capitolo 8 Un semplice linguaggio imperativo

La semantica del condizionale basata sul condizionale del metalinguaggio. Essa prevede
di valutare prima la condizione e, poi il comando c1 o il comando c2 a seconda che il valore
dellespressione e sia vero o falso. Quando la valutazione di e non un valore booleano, il
risultato della valutazione del condizionale error.
C[[output e]] =

. cases (E[[e]] ) of
< v, < in, out, mem >>:< in, v :: out, mem >;
error : error
endcases

La funzione associata ad output e riceve in input uno stato che essa usa per valutare
lespressione e; il risultato della valutazione, se diverso da error, viene inserito in testa alla
lista degli output del programma di cui il comando fa parte. Come risultato complessivo la
funzione produce un nuovo stato che contiene la stessa lista di input, la nuova lista di output
e la memoria risultante dalla valutazione di e.
La funzione di interpretazione semantica del comando while la pi complicata tra quelle
prese in considerazione finora. Il suo significato intuitivo ed i motivi dellintroduzione delloperatore di punto fisso possono essere spiegati utilizzando la semantica di tre dei comandi gi
descritti. Infatti, abbiamo che
while e do c
ha lo stesso significato di
if e then ( c; while e do c ) else noaction.
Pertanto, se si ignorano alcune verifiche di assenza di errore, che in questo caso avrebbero il
solo risultato di appesantire la notazione, si ha che la funzione di interpretazione semantica
del while pu essere descritta in termini della semantica delloperatore condizionale come:
C[[while e do c]] =

. cases (E[[e]] ) of < v,


endcases.

>: v ! C[[c; while e do c]]


C[[noaction]] 0

0,

Quindi, espandendo la funzione sopra definita utilizzando la semantica delloperatore di


sequenzializzazione, depurata dai controlli di errore,
C[[c; while e do c]] =

. C[[while e do c]] (C[[c]] ),

e la semantica di noaction, abbiamo:


C[[while e do c]] =
. cases (E[[e]] ) of < v,

>: v ! C[[while e do c]](C[[c]]


0

endcases.

0 ),

Se ora ridenominiamo C[[while e do c]] con w , otteniamo la specifica ricorsiva


w =

. cases (E[[e]] ) of < v,

>: v ! w (C[[c]]

),

endcases.

175

8.6 Equivalenza fra le semantiche


da cui, astraendo rispetto a w , ricaviamo il funzionale:
w .

. cases (E[[e]] ) of < v,

>: v ! w (C[[c]]

),

endcases.

Possiamo quindi concludere che la funzione di interpretazione del while il punto fisso del
funzionale suddetto (ove si siano considerate le tre possibili sorgenti di errore: E[[e]] , isbool(v)
e C[[c]] 0 ).
C[[while e do c]] = fix( w .

. cases (E[[e]] ) of
< v, 0 >: isbool(v) !
v!
cases C[[c]]

of
: w 00 ;
error : error
endcases,
0,
error;
error : error
endcases)
00

8.6

Equivalenza fra le semantiche

Mostriamo ora lequivalenza tra semantica operazionale e semantica denotazionale proposte


per TINY. Per non appesantire le dimostrazioni, adotteremo alcune semplificazioni. Innanzitutto, non considereremo la verifica delle situazioni di errore, che stata invece ampiamente
trattata nella semantica denotazionale. Infatti, eventuali errori, siano questi causati dalla
presenza di espressioni mal tipate o dalla richiesta di eseguire operazioni non definite, non
hanno un corrispettivo operazionale. In altre parole, nessuna transizione possibile partendo
da un errore. Nel confrontare le semantiche proposte siamo invece interessati solo al caso in
cui un programma produca un risultato.
Prima di enunciare i teoremi che permetteranno di stabilire le relazioni fra le semantiche
proposte, osserviamo che le strutture dati utilizzate nel caso operazionale sono leggermente
diverse da quelle usate nella semantica denotazionale. In particolare, lo stato nella semantica
operazionale una funzione che associa valori, eventualmente sequenze di valori, ad identificatori. Lo stato nella semantica denotazionale invece una tripla, formata da due sequenze
di valori e da una funzione che associa valori ad identificatori. Nel seguito di questo capitolo
supporremo di poter uniformare queste diverse strutture. Assumeremo allora che lo stato
utilizzato nella semantica denotazionale contenga anche le associazioni per gli identificatori
riservati in e out, ma non per laltro identificatore riservato res. Quindi, se < i, o, m >,
lo useremo anche per indicare la funzione m[i/in, o/out]. Dato un che non contiene alcuna
associazione per res, la notazione [ {res 7! v} indicher [v/res]. Scriveremo inoltre res
per indicare uno stato che identico a a parte per il fatto che pu contenere lassociazione
di un valore per la variabile riservata res. Spesso, quando il contesto non renda necessario distinguerli, confonderemo lo stato con res . da notare che nel linguaggio TINY, il
comportamento di un programma determinato dalla sequenza di output ottenibile a partire
da una sequenza di input. Quindi il vero oggetto del nostro interesse sta nelle evoluzioni di

176

Capitolo 8 Un semplice linguaggio imperativo

queste due sequenze di valori. La variabile riservata res sar utile nellanalisi della semantica
delle espressioni, ma avr scarsa rilevanza nello studio della semantica dei comandi.
Innanzitutto, consideriamo lequivalenza tra le semantiche delle espressioni.
Lemma 8.4. La semantica operazionale e la semantica denotazionale definite per le
espressioni del linguaggio TINY sono equivalenti:
E[[e]]

=< v,

> , he,

res i

!
!

[ {res 7! v}.

Dimostrazione. Per induzione sulla struttura di e.


true : Si ha E[[true]] =< true, > e inoltre htrue, res i !
!
allora per il fatto che res [true/res] = [ {res 7! true}.

res [true/res].

La tesi segue

false : Simile al caso precedente.


n : Simile ai casi true e false.
x : Si ha E[[x]] =< (x), > e inoltre hx, res i !
!
per il fatto che res [ res (x)/res] = [ {res 7!
read : Si ha E[[read]]

res [ res (x)/res].

La tesi segue allora

res (x)}.

=< hd( (in)), [tl( (in))/in] > e inoltre

hread,

res i

!
!

res [hd( res (in))/res, tl( res (in))/in].

La tesi segue allora per il fatto che


[tl( res (in))/in] [ {res 7! hd( res (in))}.

res [hd( res (in))/res, tl( res (in))/in]

not e : Si ha
E[[not e]] =< v, 0 >
, E[[e]] =< v, 0 >
per la definizione di E[[]]
0
, he, res i !
! [ {res 7! v}
per ipotesi induttiva
, hnot e, res i !
! 0 [ {res 7! v}. per la regola operazionale (Not)
e1 nop e2 : Per ipotesi induttiva abbiamo che
E[[e1 ]] =< v1 ,
E[[e2 ]] 0 =< v2 ,

00

> , he1 ,
> , he2 ,

res i
0
res i

!
!
!
!

00

[ {res 7! v1 },
[ {res 7! v2 }.

Per la definizione di E[[]] e per la regola operazionale (Nop), segue che


E[[e1 nop e2 ]] =< v1 nop v2 , 00 >
, he1 nop e2 , res i !
! 00 [ {res 7! v1 nop v2 }.
e1 bop e2 : Simile al caso precedente.

Utilizziamo ora il risultato precedente per stabilire lequivalenza fra le semantiche dei
comandi.

177

8.6 Equivalenza fra le semantiche

Teorema 8.5. La semantica operazionale e la semantica denotazionale definite per i comandi


del linguaggio TINY sono equivalenti:
C[[c]]

, hc,

res i

! hnoaction,

0
res i.

Dimostrazione. Consideriamo innanzitutto limplicazione ) (cio la consistenza della semantica denotazionale rispetto alla semantica operazionale). La dimostrazione procede per
induzione sulla struttura di c. Il caso pi interessante quando si considera il comando while.
In questo caso, abbiamo
C[[while e do c]] = fix F
dove F il funzionale descritto nella sezione precedente, cio
F =

w .

. let < v,

> be E[[e]]

in v ! w (C[[c]]

),

le cui approssimazioni sono definite come segue:


F 0 = =
.?
=
. let < v,

F n+1

> be E[[e]]

in v ! (F n )(C[[c]]

0 ),

Considerando che fix F una funzione da stati in stati, conviene in questo contesto rappresentarla come un insieme di coppie di stati. Analogamente, tutte le sue approssimazioni finite
possono essere descritte come insiemi di coppie di stati. Infatti, applicando la funzione F n+1
and uno stato , si ottiene
0
E[[e]] =< false, 0 >
n+1
(F
) =
0 E[[e]] =< true, 00 > e (F n )(C[[c]] 00 ) = 0
Per cui abbiamo
F 0 = ;
= {( ,
{( ,

F n+1

0)

0)

| E[[e]]
| E[[e]]

=< false,
=< true,

00

>} [
> e (C[[c]]

00 ,

0)

2 F n }.

Quindi, ad esempio, abbiamo


F 1 = {(
F 2 = {(
{(
= {(
{(
3
F = {(
{(
= {(
{(
{(

,
,
,
,
,
,
,
,
,
,

| E[[e]] =< false, 0 >}


| E[[e]] =< false, 0 >} [
0 ) | E[[e]] =< true, 00 > e (C[[c]] 00 , 0 ) 2 F 1 }
0 ) | E[[e]] =< false, 0 >} [
0 ) | E[[e]] =< true, 00 > e E[[e]] (C[[c]] 00 ) =< false,
0 ) | E[[e]] =< false, 0 >} [
0 ) | E[[e]] =< true, 00 > e (C[[c]] 00 , 0 ) 2 F 2 }
0 ) | E[[e]] =< false, 0 >} [
0 ) | E[[e]] =< true, 00 > e E[[e]] (C[[c]] 00 ) =< false,
0 ) | E[[e]] =< true, 00 > e E[[e]] (C[[c]] 00 ) =< true,
e E[[e]] (C[[c]] 000 ) =< false, 0 >}
0)
0)

>}

>} [
>

000

Dimostriamo ora, per induzione matematica (interna), che per ogni n, abbiamo
8( ,

) 2 F n ) hwhile e do c,

res i

! hnoaction,

0
res i.

178

Capitolo 8 Un semplice linguaggio imperativo

Da ci, poich F continuo e C[[while e do c]] = fix F , segue che


8( ,

) 2 C[[while e do c]] ) hwhile e do c,

res i

! hnoaction,

0
res i.

Cos, nel caso del comando while, la tesi risulta dimostrata.


Base dellinduzione. Se n = 0, allora F 0 = ; e quindi laermazione banalmente vera.

Passo induttivo. Siano e 0 tali che ( , 0 ) 2 F n+1 . Data la definizione di F n+1 ci sono
due possibilit. Se E[[e]] =< false, 0 >, allora la tesi segue dal Lemma 8.4 e dalla regola
(While2 ) della semantica operazionale dei comandi. Altrimenti, sia E[[e]] =< true, 00 >.
Per il Lemma 8.4, segue che he, res i !
! 00 [ {res 7! true}. Allora, applicando la regola
operazionale (While1 ), otteniamo
hwhile e do c,

res i

! hc; while e do c,

00
dove res
indica lo stato 00 [ {res 7! true}. Se ora poniamo
strutturale (esterna), abbiamo che

hc,

00
res i

! hnoaction,

00
res i
000

= C[[c]]

00 ,

per induzione

000
res i.

Quindi, usando le regole (Seq1 ) e (Seq2 ), ricaviamo che


hc; while e do c,

00
res i

! hwhile e do c,

000
res i.

Ora, dalla definizione di F n+1 , da E[[e]] =< true, 00 > e 000 = C[[c]]
F n e quindi, per induzione matematica (interna), segue che
hwhile e do c,

000
res i

! hnoaction,

0
res i,

res i

! hnoaction,

0
res i.

00 ,

segue che (

000 ,

0)

per cui possiamo concludere che


hwhile e do c,

Dimostriamo ora limplicazione ( (cio la completezza della semantica denotazionale rispetto alla semantica operazionale). La dimostrazione procede, come nel caso precedente,
per induzione sulla struttura dei comandi, considerando i diversi modi in cui possono essere
applicate le regole della semantica operazionale. Per semplicit, considereremo solo il caso pi interessante, relativo al comando while e do c. Consideriamo allora la transizione,
eventualmente in pi passi,
hwhile e do c,

res i

! hnoaction,

0
res i.

In questo caso, la dimostrazione procede per induzione sul numero n di volte che nella
transizione viene applicata la regola (While1 ).
Se n = 0, allora la transizione in esame ottenuta in un solo passo attraverso la re0
0 (res) = f alse.
gola (While2 ), quindi he, res i !
! res
con res
Dal Lemma 8.4 si ha
0
0
E[[e]] =< false, >. Quindi, la tesi, cio C[[while e do c]] = , segue immediatamente
dalla definizione di C[[while e do c]].
Altrimenti, cio n > 0, esistono 00 e 000 tali che

179

8.7 Esercizi

00
00 (res) = true, quindi, per la regola operazionale (While ),
1. he, res i !! res
e res
1
00 i,
ricaviamo che hwhile e do c, res i ! hc; while e do c, res

2. hc,

00
res i

! hnoaction,

3. hwhile e do c,
volte.

000
res i

000
res i,

! hnoaction,

Quindi abbiamo
E[[e]]

per il Lemma 8.4, e

0
res i,

dove la regola (While1 ) utilizzata n

00

=< true,

C[[c ]]

00

000

>,

per ipotesi induttiva esterna (induzione strutturale), e


C[[while e do c]]

000

per ipotesi induttiva interna (numero di applicazioni della regola (While1 )). La tesi, cio
C[[while e do c]] = 0 , allora segue dalla definizione di C[[while e do c]], dato che si ha
E[[e]] =< true, 00 > e C[[while e do c]] (C[[c ]] 00 ) = 0 .
Come detto allinizio di questa dimostrazione, gli unici casi interessante nellinduzione
strutturale su cui si basano la due prove sono quelli appena completati. Inoltre il caso del
comando while richiede due prove sostanzialmente dierenti per le due implicazioni, mentre
i casi degli altri comandi possono essere arontati seguendo uno stesso schema. Vediamo
infatti come si dimostra uno degli altri casi, relativo al comando di assegnamento, lasciando
il resto della dimostrazione per esercizio al lettore. Abbiamo
C[[x := e]] = {( ,

) | E[[e]] =< v,

00

> e

00

[v/x]}.

Quindi, per il Lemma 8.4, he, i !


! 00 [ {res 7! v}. La tesi segue immediatamente dalla
regola operazionale (Ass).
Viceversa, se hx := e, i ! hnoaction, 0 [v/x]i, allora, dalla regola operazionale (Ass),
abbiamo he, i !! 0 , con 0 (res) = v. Applicando il Lemma 8.4 e la definizione di
C[[x := e]] si ottiene la tesi.

8.7

Esercizi

8.1 Si dimostri che i comandi


while e do c

(while e do c); while e do c

hanno la stessa semantica operazionale e la stessa semantica denotazionale.


8.2 Si dimostri che
C[[while x = 1 do noaction]] =
C[[if x = 1 then (while true do noaction) else noaction]].
8.3 Dimostrare che

C[[while x 6= 0 do x := 0]] = C[[x := 0]].

180

Capitolo 8 Un semplice linguaggio imperativo

8.4 Si fornisca la semantica operazionale e denotazionale del costrutto


cases e of
n1 :c1
n2 :c2
otherwise:c3 ,
dove n1 6= n2 . Questo comando prevede lesecuzione di c1 , c2 o c3 a seconda che la valutazione
di e fornisca n1 , n2 oppure un altro intero.
8.5 Si consideri il comando

c1 then when e do c2 ,

con la seguente semantica informale: nello stato ottenuto eseguendo c1 viene valutata la condizione e; se questa risulta vera, il comando c2 viene valutato nello stato precedente lesecuzione
di c1 , altrimenti lintero comando non ha eetto sullo stato. Fornire la semantica operazionale
e denotazionale del comando sopra descritto.
8.6 Si calcoli formalmente, usando la semantica denotazionale di TINY, linsieme degli stati a partire
dai quali eseguendo il comando seguente si ha divergenza:
while x > 0 do
if x < 3 then x := x

1 else noaction.

8.7 La semantica C[[c1 ; c2 ]], con C[[c2 ]] =? pu non essere ??

8.8 Fornire una semantica non standard di TINY, che ad ogni programma associa linsieme degli
identificatori utilizzati.
8.9 Fornire una semantica non standard di TINY, che associa ad ogni programma il valore corretto,
se tutti gli identificatori, prima di comparire a sinistra di un assegnamento, compaiono a destra,
ed il valore sbagliato altrimenti.
8.10 La semantica operazionale presentata per il linguaggio TINY una semantica di valutazione
oppure di computazione? Specificare laltra alternativa.
8.11 Si aggiunga al linguaggio TINY un comando stop con la semantica informale di far terminare il
programma. Se ne dia la semantica e si dimostri che c1 ; stop e c1 ; stop; c2 sono semanticamente
equivalenti.

Capitolo 9

Linguaggi con contesti

SOMMARIO
Questo capitolo introduce un altro linguaggio di programmazione, SMALL, che una semplice estensione del linguaggio TINY considerato nel capitolo precedente. Rispetto a TINY, il
linguaggio SMALL prevede la dichiarazione esplicita di variabili e costanti usate allinterno di
un programma e la strutturazione in blocchi dei programmi stessi; inoltre SMALL permette
la dichiarazione e luso di funzioni e procedure. Pertanto, SMALL si avvicina notevolmente
al linguaggio Pascal.

9.1

Il linguaggio SMALL

SMALL, anchesso ripreso da [Gor79], ha quattro categorie sintattiche. Una categoria Dec per
le dichiarazioni, una categoria, Prog per i programmi e le categorie Exp e Com, come il TINY,
per le espressioni ed i comandi. Qui e nel resto della sezione utilizzeremo
prog
d, d1 , d2 , . . .
e, e1 , e2 , . . .
c, c1 , c2 , . . .

per
per
per
per

indicare
indicare
indicare
indicare

elementi
elementi
elementi
elementi

di
di
di
di

Prog,
Dec,
Exp, ed infine
Com.

prog ::= program c


d
::= const x = e | var x = e | proc p(x); c | fun f (x); e | d1 ; d2
e
::= b | n | not e | e1 nop e2 | e1 bop e2
| if e then e1 else e2 | x | e(e1 ) | read
c
::= e := e1 | c1 ; c2 | if e then c1 else c2 | while e do c | output e |
begin d; c end | e(e1 )
Tabella 9.1: Sintassi di SMALL
Nella sintassi riportata in Tabella 9.1 non abbiamo descritto gli elementi del dominio dei
booleani e dei naturali e le relative operazioni; li abbiamo indicati con b e con n e con nop
e bop rispettivamente. La nuova sintassi richiede di dichiarare variabili e costanti prima di
usarle ed ore la possibilit di strutturare i programmi in blocchi (begin d; c end).

182

Capitolo 9 Linguaggi con contesti

Il linguaggio inoltre prevede la definizione e luso di funzioni e procedure. Per semplicit


sia procedure che funzioni avranno sempre uno ed un solo parametro. Il meccanismo di passaggio dei parametri previsto la cosiddetta call-by-undereferenced value, un compromesso tra
il passaggio di parametri per valore e quello per nome: se viene passato come parametro un
indirizzo, questo non viene dereferenziato, cio non viene utilizzato per determinare il valore
che si trova nella relativa cella di memoria al momento della chiamata. Procedure e funzioni
possono essere dichiarate allinterno di blocchi ed il meccanismo utilizzato per assegnare un
valore alle loro variabili globali quello noto come scoping statico: le sequenze di istruzioni
che costituiscono il corpo delle procedure e delle funzioni usano i valori che le loro variabili
globali hanno al momento della dichiarazione e non quelli attivi al momento delle chiamate
(scoping dinamico). La valutazione di unespressione pu produrre come risultato anche una
funzione od una procedura; per questo, la sintassi prevede anche espressioni e comandi del tipo: e(e1 ), e := e1 , invece di prevedere semplicemente qualcosa del tipo f (e1 ), p(e1 ) ed x := e1 .
Sono previste inoltre dichiarazioni di costanti, variabili, procedure e funzioni; possibile eettuare sequenze di dichiarazioni con begin d1 ; d2 ; c end. In questultimo caso le dichiarazioni
eettuate con d2 hanno precedenza su quelle eettuate con d1 ed entrambi, insieme ai legami
attivi prima dellesecuzione del blocco, determinano il contesto (scope) in cui il comando c
deve essere valutato.

9.2

Ambienti e locazioni

Lintroduzione dei blocchi porta con s la nozione di contesto allinterno del quale valutare le
espressioni ed i comandi e quindi il problema di decidere quale significato assegnare alle loro
variabili. Si pu infatti verificare il caso in cui un unico identificatore abbia due significati
diversi che dipendono dal contesto in cui esso viene usato. Ci accade ad esempio quando in
un programma ci sono due blocchi che usano lo stesso identificatore; ovvio che in questo
caso, in un qualsiasi punto di un programma, si pone il problema di determinare lassociazione
attiva.
Esempio 9.1. Consideriamo il programma
program
begin
var x = 100;
var y = 0;
y := x;
begin
var x = 1;
y := x
end;
y := x
end
In esso appaiono due diverse dichiarazioni per x e di conseguenza due diversi valori per y.
Infatti, nel blocco pi esterno, x vale 100, mentre nel blocco pi interno x una variabile
inizializzata ad 1. Conseguentemente nel blocco pi esterno y vale 100 sia prima che dopo la
valutazione del blocco pi interno; dentro questultimo y vale 1.

183

9.2 Ambienti e locazioni

Oltre al problema di utilizzare lo stesso nome per indicare valori diversi, evidenziato dal
frammento di programma SMALL riportato nellEsempio 9.1, pu anche succedere che vengano utilizzati due identificatori per far riferimento allo stesso valore; ci si verifica ad esempio
quando i corpi di due diverse procedure usano una stessa variabile globale. In tal caso il problema che si pone quello di mantenere la consistenza tra i valori associati ai due identificatori:
in un qualsiasi istante la valutazione di entrambi deve dar luogo allo stesso valore.
importante notare come sia sempre possibile determinare, in ogni punto di un programma, il contesto attivo e quindi lesatta associazione tra variabili e valori. Nel nostro caso,
avendo scelto per SMALL uno scoping statico, lassociazione potr essere determinata anche
senza eseguire i programmi. Altri linguaggi, che qui non prenderemo in considerazione, sono
basati sullo scoping dinamico: in questi casi la determinazione esatta dei contesti attivi
possibile solo durante lesecuzione.
La descrizione della semantica di un qualsiasi linguaggio a blocchi richiede una gestione
appropriata dei contesti. Con lapproccio denotazionale questi vengono modellati tramite
funzioni chiamate ambienti . Gli ambienti stabiliscono una corrispondenza tra identificatori
e locazioni della memoria, le quali contengono invece dei valori. Lassociazione completa
identificatore-valore viene quindi ottenuta applicando in sequenza due funzioni: lambiente e
la memoria. Questultima una funzione simile alla funzione mem vista per TINY e che in
questo caso mappa locazioni (invece che identificatori) in valori. Abbiamo quindi la doppia
corrispondenza rappresentata in Figura 9.1.
xO

identificatore

/l
O
O

locazione
ambiente

/v
O

valore
memoria

Figura 9.1: Associazione identificatore-valore in SMALL


Le locazioni possono essere viste come indirizzi astratti ma anche, forse meglio, come
oggetti che hanno una vita che generalmente ha inizio al momento della dichiarazione di un
identificatore e ha fine quando si esce dal blocco in cui la dichiarazione avvenuta. Alle
locazioni viene fatto riferimento tramite gli identificatori e ad esse viene associato un valore
(che pu cambiare nel tempo) tramite la memoria. Quindi, se sono stati dati due nomi diversi
ad una stessa locazione (vedi Figura 9.2), situazione nota col nome di aliasing, non ci sono
dicolt a mantenere la consistenza tra i valori associati ai due nomi: ogni aggiornamento di
una variabile implementata tramite una modifica dellassociazione della sua locazione con il
suo valore e, quindi, comporter un automatico aggiornamento anche della seconda variabile.
Nel caso del TINY non abbiamo avuto bisogno di introdurre lambiente perch ogni programma dava luogo ad un solo contesto globale. Lunico ambiente corrispondente a questo
contesto era inglobato nello stato per ottenere unassociazione diretta tra identificatori e valori
rappresentata in Figura 9.3.
Nel seguito vedremo come, in generale, gli ambienti possono essere modificati solo dalle dichiarazioni mentre le memorie possono essere modificate sia dai comandi che dalle dichiarazioni. Le dichiarazioni possono modificare lambiente, introducendo nuovi legami identificatore-

184

Capitolo 9 Linguaggi con contesti

/v

Cl

y
Figura 9.2: Nomi diversi per una stessa locazione

xO
O

identificatore

/v
O

valore
memoria

Figura 9.3: Associazione identificatore-valore in TINY


locazione, e possono modificare la memoria associando un valore ad una locazione. I comandi
possono soltanto modificare il contenuto delle locazioni, ma non il legame tra identificatori e
locazioni.
Allinterno di un blocco un identificatore denota sempre la stessa locazione, quello che pu
cambiare (a causa di unoperazione di assegnamento) solo il contenuto di questa locazione.
In generale, un identificatore visibile in tutto il blocco in cui stato dichiarato, a meno
che esso non venga ridichiarato in un blocco pi interno. In questo caso la locazione ad esso
associata originariamente scompare momentaneamente per ricomparire quando si esce dal
blocco pi interno.
Nel caso dellEsempio 9.1 i due identificatori x denotano due dierenti locazioni mentre
lidentificatore y, non essendo stato dichiarato nel blocco pi interno, denota la stessa locazione
sia in questo che nel blocco che lo contiene. SInoltre, abbiamo che il valore finale di y 100
in quanto lultimo x visibile quello associato alla locazione che contiene 100.

9.3

Domini semantici per SMALL

Di seguito studieremo le funzioni di interpretazione semantica per Prog, Dec, Exp e Com,
che chiameremo rispettivamente P, D, E e C. Queste funzioni associano elementi dei domini
semantici ai relativi costrutti sintattici. Per definirle essenziale quindi specificare i domini
semantici che abbiamo intenzione di utilizzare. Come nel caso di TINY, questi domini saranno
dei cpo. Tutti saranno costruiti a partire da domini elementari quali NAT, BOOL, LOC (il
dominio piatto delle locazioni), ID (il dominio piatto degli identificatori) e dai singoletti
error, unused e unbound. I domini pi complicati saranno costruiti utilizzando operatori tra
domini quali +, , !.
Per descrivere i domini delle varie funzioni che vengono associate ai frammenti di
programmi SMALL, risulta conveniente individuare dierenti classi di valori. Avremo pertanto:

185

9.3 Domini semantici per SMALL

BVAL il dominio che contiene i valori che possono essere dati in input ai programmi e ottenuti

come output (valori di base); un esempio sono i naturali ed i booleani.

NVAL il dominio dei valori che possono essere denotati da identificatori (valori nominabili),

come per esempio le locazioni.

EVAL il dominio dei valori che le espressioni possono assumere (valori esprimibili); un esempio

sono le funzioni od i valori di base.

MVAL il dominio dei valori che possono essere associati alle locazioni nella memoria (valori

memorizzabili ), come ad esempio i valori di base o le sequenze di input o di output.

Non pu essere deciso una volta per tutte, a prescindere dal linguaggio che si intende
descrivere, quali debbano essere gli elementi dei domini di interpretazione. Ad esempio, pu
essere o meno necessario avere le procedure tra i valori esprimibili, avere i reali tra i valori di
base, avere le locazioni tra i valori memorizzabili, e cos via.
Nel caso di SMALL i domini precedentemente menzionati sono quelli specificati dalle
seguenti equazioni:
BVAL =
NVAL

= BVAL + LOC + FUN + PROC

EVAL =
MVAL

NAT + BOOL
NVAL

= BVAL + BVAL

Dalle formule riportate sopra possiamo vedere che i valori di base necessari per descrivere la
semantica di SMALL sono i naturali ed i booleani, mentre i valori nominabili sono quelli di base
pi le locazioni, le funzioni e le procedure. Ancora, per SMALL abbiamo che i valori esprimibili
coincidono con quelli nominabili; anche questo fatto pu non essere vero per tutti i linguaggi:
ad esempio, in alcuni linguaggi le procedure sono valori nominabili ma non esprimibili. I
valori memorizzabili necessari per SMALL sono i valori di base oppure loro sequenze; queste
ultime verranno essenzialmente utilizzate per rappresentare possibili input ed output.
Insieme ai domini semantici visti sopra, per descrivere la semantica di SMALL utilizzeremo
un ambiente ed una memori il cui scopo stato gi discusso in precedenza. Ambiente e
memoria sono funzioni che associano valori nominabili e valori memorizzabili ad identificatori
e locazioni, rispettivamente. Pi formalmente abbiamo:
AMB
MEM

= ID ! (NVAL + {unbound})

= LOC ! (MVAL + {unused})

Come suggerito dai loro tipi, le equazioni sopra riportate prevedono anche la possibilit
che lambiente definisca unbound un identificatore e che la memoria definisca unused una
locazione.
Un ambiente fornisce il risultato unbound quando il suo argomento non stato dichiarato
prima del suo uso. Gli elementi di AMB saranno nel seguito indicati con , 0 , 00 , etc. e
saranno funzioni inizialmente uguali a x.unbound, che verranno successivamente aggiornate
in base alle dichiarazioni presenti allinterno dei programmi.
Per descrivere la modifica di un ambiente utilizzeremo due diverse notazioni:

186

Capitolo 9 Linguaggi con contesti

1. [loc/id] che sta per x. (x = id) ! loc, (x);


2. [0 ] che sta per x. (0 (x) = unbound) ! (x), 0 (x).

La prima notazione verr utilizzata per descrivere laggiornamento dellambiente relativamente ad un solo identificatore, mentre la seconda indicher che tutte le associazioni
dellambiente 0 in cui il valore diverso da unbound vengono utilizzate per aggiornare .
Come detto in precedenza, anche per la memoria abbiamo la possibilit di segnalare situazioni anomale che si verificano durante la valutazione di un frammento di programma.
La memoria infatti rappresentata da una funzione che pu produrre il valore associato alla
locazione che gli viene passata come argomento, oppure la stringa unused quando alla locazione argomento non stato ancora associato alcun valore. Gli elementi di MEM, che saranno
indicati con , 0 , 00 , etc., saranno funzioni inizialmente uguali a x.unused, che verranno
poi aggiornate dalla valutazione delle dichiarazioni o degli assegnamenti presenti allinterno
dei programmi.
In modo simile alle funzioni ambiente, possibile aggiornare i valori associati ad una
locazione. Nel seguito useremo la seguente notazione:
[val/loc] che sta per x. (x = loc) ! val, (x).

Prima di concludere questa discussione, necessario stabilire quali sono gli elementi del
dominio base LOC; infatti la memoria definita in termini di questi. Una possibile soluzione
quella di assumere LOC uguale al dominio dei naturali NAT; per modellare le locazioni serve
soltanto un insieme sucientemente grande ed un meccanismo per verificare se ci sono o meno
valori associati ai suoi elementi. Tutte le volte che avremo bisogno di far riferimento ad una
locazione per la prima volta allinterno di una memoria, utilizzeremo la funzione:
new : MEM ! LOC

che, quando applicata ad una memoria , restituisce il minimo intero n a cui non si mai
fatto riferimento precedentemente, e cio un n tale che (n) = unused e (m) 6= unused, per
ogni m < n.
Va detto che questa soluzione non tiene conto n dei problemi indotti dalle limitazioni
della memoria, n del comportamento del programma in caso di overflow. In caso contrario
bisognerebbe assumere che la memoria sia una funzione che mappa gli interi fino a k (opportunamente scelto) in unused e gli interi maggiori di k in error. Se facessimo questa scelta la
funzione new dovrebbe essere del tipo
new : MEM ! (LOC + {error})

e restituire il minimo intero m a cui non si mai fatto riferimento precedentemente, cio un
m tale che (m) = unused, se m minore od uguale a k, ed error altrimenti.
In tutto questo capitolo, per evitare ulteriori controlli ed appesantimenti notazionali, assumeremo memoria illimitata. Inoltre, assumeremo come date due locazioni che chiameremo
lin e lout; ad esse saranno associate le stringhe di valori di input e di output dei programmi.
Una volta definiti ambiente e memoria, siamo in grado di definire i domini delle funzioni e delle procedure che ci permettono di completare la definizione dellinsieme dei valori
nominabili NVAL:
FUN = NVAL ! MEM ! ((EVAL MEM) + {error})
PROC = NVAL ! MEM ! (MEM + {error})

187

9.4 Semantica di SMALL

Queste equazioni prevedono che le funzioni programmabili in SMALL prendano come argomento un valore nominabile (il parametro attuale) e diano come risultato una funzione che
prende come argomento la memoria e produce un valore esprimibile (il risultato della funzione) ed una nuova memoria; questo ovviamente se non si verificano situazioni di errore. Una
procedura SMALL si comporta in modo analogo alle funzioni, ma ha come risultato semplicemente una nuova memoria; il risultato della procedura potr essere fornito al programma
chiamante tramite assegnamenti a variabili globali e quindi tramite il nuovo stato.
Osservazione 9.2. Poich non immediatamente evidente, vale la pena notare che le definizioni di questi domini semantici sono ricorsive. Per esempio, abbiamo che PROC un valore
nominabile (cio appartenente a NVAL), ma anche che NVAL viene usato nella definizione del
dominio PROC. Questa caratteristica dei domini semantici aumenta notevolmente il potere
espressivo dei linguaggi di programmazione. Grazie ad essa, siamo ad esempio in grado di
scrivere il seguente programma SMALL che calcola la funzione fattoriale senza utilizzare alcun
costrutto per la ricorsione, o per literazione.
program
begin
fun f (< g, x >);
if x = 0 then 1 else g(< g, x
output f (< f, read >)
end

1 >) x;

Infine, i domini semantici introdotti permettono di definire i domini delle funzioni di


interpretazione semantica per le espressioni, le dichiarazioni, i comandi ed i programmi.
E : Exp
C : Com
D : Dec
P : Prog

9.4

! AMB ! MEM ! ((EVAL MEM) + {error})


! AMB ! MEM ! (MEM + {error})
! AMB ! MEM ! ((AMB MEM) + {error})
! BVAL ! (BVAL + {error})

Semantica di SMALL

Prima di descrivere le funzioni semantiche di SMALL introdurremo delle funzioni ausiliarie


che permetteranno di semplificare la notazione e di abbreviare significativamente la lunghezza
delle equazioni semantiche.
Uno dei fattori principali, tra quelli che contribuiscono alla lunghezza delle equazioni per
TINY, il fatto che quasi in ogni espressione si deve considerare la propagazione delle situazioni
di errore; spesso infatti le alternative del cases sono solo due, una delle quali gestisce soltanto
eventuali errori. Di seguito presentiamo un nuovo operatore di composizione di funzioni che
permette di tener conto in modo omogeneo del problema degli errori. Questo nuovo operatore,
chiamato ? e gi definito in [Gor79], permette di comporre due funzioni facendo galleggiare
gli errori che si verificano al momento dellapplicazione della prima funzione, evitando di
valutare la seconda funzione. La valutazione di questultima viene fatta solo se la prima
valutazione non d luogo ad errori. Loperatore ?, inoltre, permette di trattare in modo
opportuno anche quei casi di composizione in cui il risultato dellapplicazione della prima
funzione una coppia mentre la seconda funzione si aspetta gli argomenti uno dopo laltro.

188

Capitolo 9 Linguaggi con contesti

Definizione 9.3. Loperatore ? definito nel modo seguente:


1. Se f : D1 ! (D2 + {error}) e g : D2 ! (D3 + {error}), allora
f ? g : D1 ! (D3 + {error})
definita come segue:
f ? g = x. (f x = error) ! error, g(f x).
2. Se f : D1 ! ((D2 D3 ) + {error}) e g : D2 ! D3 ! (D4 + {error}) allora
f ? g : D1 ! (D4 + {error})
definita come segue:

f ? g = x. cases f x of
< d2 , d3 >: (g d2 ) d3 ;
error : error
endcases

Se f e g sono due funzioni di dominio appropriato, allora f ? g la funzione che prevede


lapplicazione di f ed un comportamento futuro che dipende dal risultato di questa applicazione. In particolare, se essa d luogo ad errori il risultato di f ? g, la costante error; se
invece lapplicazione di f produce un qualsiasi altro valore v, questo viene passato a g ed il
risultato finale di f ? g quello che si ottiene applicando g al valore v.
Per avere unidea dellimpatto di queste scelte notazionali, consideriamo la funzione di
interpretazione semantica delloperatore di sequenzializzazione di TINY, che prima era:
C[[c1 ; c2 ]] =

. cases C[[c1 ]] of
0 : C[[c ]] 0 ;
2
error : error
endcases

e che ora diventa:


C[[c1 ; c2 ]] = C[[c1 ]] ? C[[c2 ]].
Questultima funzione richiede di valutare prima c1 , quindi di passare lo stato risultante ad
unaltra funzione che lo utilizza per valutare c2 .
Si noti che ? associativo, cio f ? (g ? h) = (f ? g) ? h, quindi espressioni del tipo f ? g ? h
non sono ambigue e che espressioni quali f ? g ? x.h ? k significano f ? g ? ( x.(h ? k)) (poich
loperatore ! associa a destra, come evidenziato in Sezione 6.5.1).
Unaltra funzione che risulta utile nella descrizione della semantica di SMALL una funzione simile a isD gi discussa nella Sezione 6.5; lunica dierenza che la nuova funzione,
invece di produrre il valore booleano che dipende dal dominio di appartenenza delloggetto a
che le viene passato come argomento, d come risultato error quando isD(a) = false e largomento stesso quando isD(a) = true. La nuova funzione, che chiameremo checkD, permette
di trattare in termini di composizioni di funzioni sia la verifica del tipo degli argomenti che
leettiva applicazione di una funzione ai suoi argomenti. La funzione checkD sar definita

189

9.4 Semantica di SMALL

per un generico dominio D, ma non c alcuna dicolt ad istanziarla sui domini di nostro
interesse; la sua definizione la seguente:
checkD : D ! MEM ! ((D MEM) + {error})
checkD = v . isD(v) !< v,

>, error.

Essenzialmente checkD si comporta come un filtro tra una funzione e laltra, che lascia
passare soltanto quei risultati dellapplicazione della prima funzione che risultano essere di
tipo D. Utilizzando sia ? che checkD abbiamo che la semantica delloperatore not di TINY,
che prima era
E[[not e]] =

. cases E[[e]] of
< v, 0 >: isbool(v) !< v,
error : error
endcases

>, error;

diventa semplicemente:
E[[not e]] = E[[e]] ? checkBOOL ? v . < v,

>

In alcuni casi per descrivere le funzioni di interpretazione semantica troveremo pi conveniente mostrare il loro comportamento quando sono applicate ad alcuni dei loro parametri;
questo giustificato dal principio di estensionalit, che permette di identificare due funzioni
quando i loro valori sono gli stessi per tutti i possibili argomenti (si veda a tale proposito la
Sezione 5.2). Nel seguito pertanto, invece di scrivere
C[[c1 ; c2 ]] = . (

. C[[c1 ]] ) ?

. C[[c2 ]]

scriveremo
C[[c1 ; c2 ]] =

. C[[c1 ]] ?

. C[[c2 ]]

applicando largomento , inoltre, utilizzando il principio di estensionalit a sinistra


delloperatore ?, abbiamo
C[[c1 ; c2 ]] = C[[c1 ]] ?

. C[[c2 ]]

ed infine, utilizzando il principio di estensionalit anche a destra delloperatore ?, possiamo


scrivere
C[[c1 ; c2 ]] = C[[c1 ]] ? C[[c2 ]] .
Di seguito riportiamo tutte le clausole semantiche di SMALL, scritte utilizzando sia gli
operatori del metalinguaggio presentati nella Sezione 6.5 che i nuovi operatori checkD e ?. Per
utilizzare al meglio questi operatori cambieremo leggermente anche lo stile di descrizione delle
funzioni di interpretazione semantica ed utilizzeremo pi pesantemente la composizione di
funzioni. Inoltre le funzioni verranno spesso specificate utilizzando direttamente -espressioni
invece degli operatori derivati let e cases. Come per le clausole semantiche del linguaggio
TINY, faremo seguire ogni definizione da un breve commento.

190

9.5

Capitolo 9 Linguaggi con contesti

Semantica dei programmi


P[[program c]]in = cases (C[[c]]0 ( x.unused)[in/lin][nil/lout]) of
: (lout);
error : error
endcases

Un programma SMALL una funzione della sequenza di input (in); il suo valore dipende
dalla semantica del corpo del programma, valutato in un ambiente vuoto 0 (indica lambiente
x.unbound) ed utilizzando una memoria in cui le uniche locazioni inizialmente definite sono
la locazione lin inizializzata con la sequenza di input e la locazione lout inizializzata con la
sequenza vuota. Il risultato del programma il contenuto della locazione lout allinterno della
memoria che risultata dalla valutazione del programma stesso.

9.6

Semantica delle dichiarazioni

Nel seguito, lambiente vuoto 0 sar utilizzato come base per costruire il piccolo ambiente
che viene fornito come risultato della valutazione di una o pi dichiarazioni. Nel piccolo
ambiente tutte le locazioni, a parte quelle appena dichiarate, sono legate ad unbound.
D[[const x = e]] = R[[e]] ? v . < 0 [v/x],

>

La valutazione di una dichiarazione di costante prevede la determinazione del valore da


associare allidentificatore x e quindi la creazione di un piccolo ambiente in cui lunica associazione quella tra il valore dellespressione ed x stesso. La garanzia che x non sar mai
modificato allinterno del programma data dal fatto che ad x viene associato direttamente un
valore memorizzabile e non una locazione, e dal fatto che, come sar evidente dalla descrizione
della semantica dei comandi, il comando di assegnamento permette di modificare soltanto le
locazioni. R una nuova funzione di valutazione, che verr definita in seguito, simile ad E,
che produce error quando il risultato di E[[e]] una funzione od una procedura, e produce un
valore di base quando il risultato di E[[e]] gi un valore di base oppure una locazione.
D[[var x = e]] = R[[e]] ? v . < 0 [new /x], [v/new ] >
Come per la clausola precedente, la valutazione di una dichiarazione di variabile prevede,
innanzitutto, la determinazione del valore da associare allidentificatore che si intende dichiarare. In questo caso comunque il piccolo ambiente non associa ad x il valore dellespressione a
destra del simbolo =, ma gli associa una nuova locazione new . Il risultato della valutazione
di e viene poi associato ad new allinterno della memoria che, insieme al piccolo ambiente
che contiene solo lassociazione tra x ed new , rappresenta il risultato della valutazione della
dichiarazione.
D[[proc p(x); c]] =
D[[fun f (x); e]] =

. < 0 [( d. C[[c]] [d/x])/p],


. < 0 [( d.E[[e]] [d/x])/f ],

>
>

191

9.7 Semantica delle espressioni

Le valutazioni delle dichiarazioni di funzione e di procedura danno come risultato la memoria ricevuta come argomento ed un piccolo ambiente in cui lunica associazione quella tra
il nome della funzione, o della procedura, e la semantica del loro corpo. Questultima una
funzione che, ricevuti come argomento il parametro attuale ed una memoria, valuta i costrutti
che costituiscono il corpo utilizzando la memoria passatale come argomento e lambiente in
cui ha avuto luogo la dichiarazione, aggiornato per dallassociazione tra il parametro formale
ed il parametro attuale.
D[[d1 ; d2 ]] = D[[d1 ]] ? 1 . D[[d2 ]] [1 ] ? 2 . < 1 [2 ],

>

La valutazione di una sequenza d1 ; d2 di due dichiarazioni ha come risultato il piccolo


ambiente risultante dalla valutazione di d1 modificato dal piccolo ambiente risultante dalla
valutazione di d2 . Per la valutazione di d1 vengono utilizzati lambiente e la memoria passati
come argomento alla funzione di valutazione. Per la valutazione di d2 vengono utilizzati
la memoria risultante dalla valutazione di d1 , e lambiente ottenuto aggiornando lambiente
originario con il piccolo ambiente risultante questa stessa valutazione.

9.7

Semantica delle espressioni

Prima di descrivere la funzione di interpretazione semantica per le espressioni necessario


chiarire un problema che viene introdotto dal fatto che la loro valutazione pu dar luogo ad
un qualsiasi valore esprimibile e non semplicemente a valori memorizzabili. Infatti, nel caso
di SMALL abbiamo visto che sono esprimibili tutti quei valori a cui possibile associare un
nome; quindi, possiamo avere come risultato della valutazione di unespressione non solo un
valore memorizzabile ma anche una locazione, una funzione o una procedura. In alcuni casi
(quali ad esempio loperazione di somma ed il comando di assegnamento) necessario avere
un valore memorizzabile come risultato della valutazione di unespressione. In questi casi, se
il risultato un valore allora non resta che passarlo alla funzione di valutazione successiva.
Se invece il risultato una locazione, allora bisogna fornire alla funzione successiva non la
locazione, ma il valore ad essa associato allinterno della memoria. Infine, se come risultato
della valutazione viene ottenuta una procedura od una funzione, allora alla funzione successiva
non viene passato alcun valore, ma viene solo segnalata una situazione di errore.
Per tenere conto di questo tipo di problemi necessario introdurre unoperazione, comunemente chiamata di dereferenziazione, che permette di determinare il valore associato a
ciascuna locazione allinterno della memoria. Per evitare di dover far riferimento in continuazione alloperazione di dereferenziazione e quindi di scrivere tutte le volte qualcosa come
deref (E[[e]]), definiamo una nuova funzione di valutazione R che simile ad E, ma produce error quando il risultato di E[[e]] una funzione od una procedura, e produce un valore
di base quando il risultato di E[[e]] gi un valore di base o una locazione. Ricordiamo
che isbval(), isloc(), isf un(), isproc() sono le ovvie istanziazioni del costrutto isD() del
metalinguaggio.
R : Exp ! AMB ! MEM ! (BVAL MEM) + {error}

192

Capitolo 9 Linguaggi con contesti


R[[e]] = E[[e]] ? v . cases v of
isbval(v) :< v, >;
isloc(v) : (v) = unused ! error, < (v),
isf un(v) : error;
isproc(v) : error
endcases

>;

Ora possiamo considerare le funzioni di interpretazione semantica per le espressioni:


E[[true]] =
E[[false]] =
E[[n]] =

. < true,
. < false,

. < n,

>
>

>

La semantica delle costanti di base di SMALL una funzione costante che lascia inalterati
ambiente e memoria e d come risultato la vecchia memoria ed il valore semantico associato
ai simboli di costante.
E[[not e]] = R[[e]] ? checkBOOL ? b . < b,

>

E[[e1 nop e2 ]] = R[[e1 ]] ? checkN AT


? n1 . R[[e2 ]] ? checkN AT ? n2 . < n1 nop n2 ,
E[[e1 bop e2 ]] = R[[e1 ]] ? checkBOOL
? b1 . R[[e2 ]] ? checkBOOL ? b2 . < b1 bop b2 ,

>
>

Le valutazioni delle varie operazioni tra espressioni sono funzioni che, dopo aver ricevuto
come argomenti un ambiente ed una memoria, valutano il primo operando, quindi verificano
che il risultato della valutazione del tipo appropriato rispetto alloperazione che si deve
eseguire. Successivamente, se il tipo del primo operando appropriato e se loperazione
ha un altro argomento, valutano anche questo utilizzando il vecchio ambiente e la memoria
risultante dalla prima valutazione. Infine, se anche il risultato della seconda valutazione
del tipo appropriato, applicano loperazione, corrispondente alloperatore sintattico, ai valori
ottenuti dalla valutazione degli operandi. Per valutare gli operandi viene utilizzata la funzione
R e non la E, in quanto le operazioni not, nop e bop sono definite soltanto su valori di
base.
E[[if e then e1 else e2 ]] = R[[e]] ? checkBOOL
? b. b ! E[[e1 ]] , E[[e2 ]]
Linterpretazione del condizionale valuta la condizione e, verifica che il valore risultante
sia un booleano, quindi a seconda che esso sia il booleano true o false, valuta il secondo o
il terzo argomento utilizzando il vecchio ambiente e la memoria risultante dalla valutazione
dellespressione e.

193

9.8 Semantica dei comandi


E[[read]] =

. cases (lin) of
v :: in :< v, [in/lin] >;
nil : error
endcases

Se la lista associata alla locazione lin non vuota, lespressione read produce come risultato il suo primo elemento insieme ad una nuova memoria che dierisce da quella originaria
solo per la locazione lin. A questa verr associata una nuova sequenza ottenuta rimuovendo
lelemento di testa dalla vecchia.
E[[x]] =

. (x) = unbound ! error, < (x),

>

La valutazione di un identificatore ha come risultato il valore nominabile (cio un valore di base intero o booleano, una locazione, una procedura o una funzione) associato
allidentificatore allinterno dellambiente ed insieme ad esso la vecchia memoria.
E[[e(e0 )]] = E[[e]] ? checkF U N ? f. E[[e0 ]] ? v . f v
La valutazione di unapplicazione di funzione ha come risultato, se non si verificano situazioni di errore, lapplicazione del risultato della valutazione della prima espressione al risultato
della valutazione della seconda espressione. I punti importantiche caratterizzano il tipo di passaggio di parametri ed il tipo di scoping modellati con la chiamata di funzione qui descritta
sono due:
1. Per valutare largomento viene utilizzata la funzione E e non la funzione R, quindi si
pu passare come parametro un qualunque valore esprimibile; e cio non solo valori di
base ma anche locazioni, procedure od altre funzioni.
2. Lambiente in cui viene eettuata la chiamata non viene utilizzato al momento della
valutazione dellapplicazione della funzione. Vengono utilizzati a questo punto soltanto
largomento e la memoria come definita al momento della chiamata; lambiente in cui la
valutazione dellapplicazione ha luogo quello che era attivo quando la funzione era stata
dichiarata e che stato associato al corpo della funzione al momento della valutazione
della dichiarazione della funzione stessa.

9.8

Semantica dei comandi


C[[e := e0 ]] = E[[e]] ? checkLOC ? l. R[[e0 ]] ? v . [v/l]

Si controlla se la valutazione della prima espressione e produce una locazione; in questo


caso si determina il valore memorizzabile associato alla seconda espressione e0 . Il risultato
una nuova memoria in cui alla locazione ottenuta dalla valutazione di e viene associato il
valore di e0 .

194

Capitolo 9 Linguaggi con contesti

C[[c1 ; c2 ]] = C[[c1 ]] ? C[[c2 ]]


Il comando c2 viene valutato utilizzando lambiente passato come argomento alla funzione
di valutazione della sequenzializzazione e la memoria modificata dalla valutazione del comando
c1 .
C[[if e then c1 else c2 ]] = R[[e]] ? checkBOOL
? b. b ! C[[c1 ]] , C[[c2 ]]
C[[while e do c]] = fix( . R[[e]] ? checkBOOL
? b. b ! C[[c]] ? ,

Le funzioni di interpretazione semantica di if e then c1 else c2 e di while e do c sono


simili a quelle di TINY commentate nel capitolo precedente.
C[[output e]] = R[[e]] ? b . [b :: (lout)/lout]
Siccome i possibili output sono sequenze di valori memorizzabili, la funzione di valutazione
di output e valuta lespressione tramite la R, quindi modifica la memoria aggiungendo il
risultato della R in testa alla sequenza associata alla locazione lout.
C[[begin d; c end]] = D[[d]] ? 0 . C[[c]] [0 ]
Per valutare un blocco, vengono prima valutate le dichiarazioni che si trovano in esso. Il
risultato di tale valutazione, come visto sopra, una coppia < 0 , >. Dopo la valutazione
delle dichiarazioni, viene valutato il corpo del blocco utilizzando la nuova memoria e lambiente
passato originariamente come argomento, aggiornato dal piccolo ambiente 0 , in cui gli unici
legami sono quelli dichiarati con d.
C[[e(e0 )]] = E[[e]] ? checkP ROC ? p. E[[e0 ]] ? v . p v
La funzione di valutazione della chiamata di procedura, a parte il controllo che il risultato
della valutazione della prima espressione sia una procedura, analoga a quella relativa alla
chiamata di funzione vista prima.

9.9

Considerazioni conclusive

La semantica di SMALL descritta in precedenza tale che la denotazione di un termine


qualsiasi ottenuta componendo sequenzialmente, tramite la funzione ?, le denotazioni delle
sue componenti. Tale tipo di semantica nota come semantica diretta per il fatto che ad ogni
termine del linguaggio viene direttamente associata la sua denotazione. Come abbiamo visto,
la semantica diretta permette descrivere adeguatamente ed in modo compatto un linguaggio
relativamente complicato.

9.9 Considerazioni conclusive

195

La semantica diretta ha purtroppo linconveniente di non permettere di descrivere in


modo naturale costrutti che prevedono anche una esecuzione non sequenziale delle istruzioni
di un programma, quali per esempio escape, exit e goto. La causa principale di questo
inconveniente proprio il fatto che con la semantica diretta tutte le istruzioni di un programma
vengono valutate nello stesso ordine in cui esse appaiono allinterno del corpo del programma
stesso. Inoltre, ogni funzione di valutazione passa sempre il suo risultato intermedio alla
funzione di valutazione del resto del programma. Chiaramente, nel caso di salti ed in generale
di comandi che modificano il flusso del controllo, lapproccio diretto risulta non del tutto
adeguato. Infatti, non immediato capire come, semplicemente componendo funzioni del
tipo di quelle viste in precedenza, sia possibile modellare linguaggi che prevedano ordini di
esecuzione modificabili.
Per far fronte a questo tipo di problemi, bisogna essere in grado di esprimere anche il
controllo dellesecuzione in termini di composizione di funzioni e definire la semantica di un
linguaggio in modo tale che anche il controllo sia un argomento esplicito delle funzioni di
interpretazione. Largomento utilizzato per descrivere il controllo di un linguaggio chiamato
continuazione. Esso viene associato ad ogni clausola di interpretazione semantica e serve per
indicare quale parte di un programma deve essere interpretata dopo la valutazione di ciascun
costrutto. Linterpretazione di ogni costrutto fornisce sempre informazioni sulla parte di
programma che deve ricevere il suo risultato. Usualmente, questo viene passato alle funzioni
di interpretazione delle istruzioni che seguono testualmente listruzione in esame. In alcuni
casi (per esempio in presenza di errori o di salti), invece, le continuazioni normali vengono
ignorate ed il risultato viene passato ad altre continuazioni. Nel caso di salti, il risultato viene
pasato a quelle funzioni di interpretazione che valutano la parte di programma che segue
letichetta a cui viene richiesto di saltare.
Le continuazioni sono state originariamente sviluppate come uno strumento per trattare in
modo semplice i salti incondizionati presenti in vari linguaggi [SW74]; successivamente, esse
si sono imposte anche come strumento per descrivere tutti i linguaggi di programmazione,
anche quelli senza goto. Infatti, le continuazioni permettono di alleggerire notevolmente la
notazione e di trattare con eleganza ed in modo matematicamente pulito anche situazioni
di errore e comandi di fermata (stop, exit) senza dover ricorrere a varianti di funzioni di
composizione, quali la funzione ?.
Parecchi autori fanno ora riferimento alla semantica denotazionale con continuazioni come
alla semantica standard, anche per spingere nella direzione di fissare una metodologia unificante per la definizione della semantica denotazionale del maggior numero di linguaggi di
programmazione possibile. Infatti, lutilizzo di un metodo standard per la descrizione di linguaggi dierenti renderebbe pi facile confrontarli; ovviamente il prezzo da pagare quello di
non poter usare tecniche ad hoc per ogni linguaggio, che in alcuni casi potrebbero semplificare
la presentazione della sua semantica.
Lapproccio basato sulle continuazioni noto anche come semantica inversa, in quanto la
funzione di interpretazione semantica di una sequenza di costrutti prevede che il risultato della
valutazione dellultimo costrutto della sequenza sia passato come argomento alla funzione di
interpretazione dei costrutti che lo precedono. Il ruolo di questo argomento sar essenzialmente
quello di ricevere la memoria e lambiente risultanti dalla valutazione delle istruzioni precedenti
e di continuare la valutazione del programma.

196

Capitolo 9 Linguaggi con contesti

9.10

Esercizi

9.1 Informalmente, un programma genera aliasing se durante una sua esecuzione due identificatori
vengono legati alla stessa locazione. Definire formalmente tale concetto e dire quali costrutti
SMALL possono dar luogo ad aliasing.
9.2 Si modifichi la semantica di SMALL in modo che le locazioni liberate alluscita dei blocchi
possano essere riutilizzate.
9.3 Mostrare, usando le clausole semantiche, che in SMALL possibile lautoapplicazione, vale a
dire il passaggio di una procedura come parametro a se stessa.
9.4 Utilizzando la propriet vista nellesercizio precedente, scrivere un programma che, ricevendo
in input una stringa u appartenente al linguaggio descritto dallespressione
(a + b) c(a + b)
decide se u appartiene al linguaggio delle stringhe palindrome sullalfabeto {a, b}.

9.5 Il linguaggio SMALL valuta le espressioni da sinistra a destra o viceversa? Modificare la semantica in modo tale che venga scelta laltra alternativa e mostrare un semplice programma che ha
una semantica diversa nei due casi, calcolando la semantica in entrambi i casi.
9.6 Si aggiunga al linguaggio SMALL un comando stop con la semantica informale di far terminare il
programma. Se ne dia la semantica e si dimostri che c1 ; stop e c1 ; stop; c2 sono semanticamente
equivalenti.
9.7 Estendere il linguaggio SMALL introducendo i comandi restart ed exit, il cui significato di
saltare rispettivamente allinizio ed alla fine del blocco pi interno.
9.8 Fornire una semantica non standard di SMALL, che ad ogni programma associa il numero
corrispondente alle volte che un assegnamento appare nel programma.
9.9 Fornire una semantica non standard di SMALL, che ad ogni programma associa il numero
corrispondente alle volte che un assegnamento viene eettuato dal programma.
9.10 Ridefinire la semantica di SMALL in modo che si abbia error se una variabile viene usata senza
essere dichiarata.
9.11 Ridefinire la semantica di SMALL in modo che si abbia warning se una variabile viene dichiarata,
ma mai usata.

Parte III

Sistemi Concorrenti

Capitolo 10

Operatori per concorrenza e


nondeterminismo

SOMMARIO
Questo capitolo introduce alcuni degli operatori utilizzati dai calcoli di processo pi conosciuti. Vedremo come tali operatori possono essere impiegati per costruire processi complessi
a partire da azioni elementari e processi pi semplici. Grazie alla semantica definita in stile SOS, il comportamento di un processo composto verr quindi definito per mezzo della
semantica dei processi che lo compongono.

10.1

Azioni esterne ed interne

Unazione elementare di un sistema rappresenta astrattamente un passo atomico (cio non


interrompibile) di computazione che viene eettuato da un sistema per transire da uno stato
ad un altro. Unoperazione atomica non permette di osservare stati intermedi attraverso i
quali il sistema transisce dallinizio della sua esecuzione alla sua conclusione. Quando ci si
trova di fronte ad un sistema concorrente da modellare, la prima questione che si pone
quella di identificare le azioni atomiche. Per rispondere a questa domanda occorre essere
chiari riguardo al livello di astrazione che si vuole usare per modellare il sistema, poich ci
che atomico ad un determinato livello pu non esserlo ad un livello di astrazione pi basso.
Prendiamo come esempio un conto bancario. Ad un appropriato livello di astrazione, le
operazioni di prelievo e deposito possono essere considerate entrambe atomiche, ma loperazione di trasferimento di denaro da un conto pu non esserlo; essa pu essere vista come due
separate operazioni atomiche: un prelievo da un conto, seguito da un deposito in un altro. Ad
un livello di astrazione pi basso il conto bancario potrebbe essere rappresentato come un file
del database centrale della banca. Eseguire unoperazione, come ad esempio un prelievo, pu
tradursi in varie operazioni di accesso e modifica al file. Ad un simile livello ragionevole assumere che le operazioni di accesso e modifica siano entrambe atomiche. Abbassando il livello
di astrazione, potremmo immaginare che il file risieda in un disco fisico, e che quindi siano
le operazioni di lettura e scrittura del disco ad essere atomiche. Ancora, il file probabilmente
sar diviso su diversi blocchi del disco fisico, per cui la lettura e scrittura del disco in realt
composta da varie letture e scritture atomiche dei suoi blocchi. Infine, potremmo considerare
atomiche le letture e scritture dei singoli byte da parte della testina del disco.

200

Capitolo 10 Operatori per concorrenza e nondeterminismo

Per ogni livello di astrazione, ci che determina se unoperazione o meno atomica la


possibilit di dividerla in sotto-operazioni: se la divisione risulta impossibile, loperazione
deve essere considerata atomica. Tornando allesempio dei conti bancari, se loperazione di
trasferimento da un conto ad un altro non fosse atomica, sarebbe possibile osservare lo stato
in cui la somma dei due conti bancari minore della somma dei loro valori iniziali e finali
(valori che invece, nel caso di trasferimenti, devono coincidere).
Le azioni di un sistema possono essere di due tipi. Unazione che rappresenta uninterazione
del sistema con lambiente esterno attraverso una porta (o canale) di comunicazione si dice
azione esterna o visibile. Unazione che invece il risultato di una qualche computazione
interna al sistema si dice azione interna o invisibile.
In alcuni calcoli di processo, come ad esempio CCS, le azioni esterne sono convenzionalmente suddivise in azioni di input ed azioni di output. Le azioni di input vengono indicate
con lo stesso nome della porta su cui avvengono mentre le azioni di output vengono indicate
con il nome della porta su cui avvengono con sopra una barra orizzontale. Perci, se denota
linsieme delle porte, linsieme delle azioni visibili sar Act , [ {a|a 2 }. Le azioni a e a
sono dette complementari. In CCS linterazione pu avvenire solo tra due processi in parallelo
che eseguono simultaneamente azioni complementari (per convenzione si pone anche a = a).
Intuitivamente, quando un processo esegue unazione di input a come se esso ricevesse un
segnale sulla porta a, mentre quando il processo esegue unazione di output a come se il
processo stesso emettesse un segnale attraverso la porta a. La distinzione tra input ed output
del tutto fittizia quando non c scambio di valori, come nel caso di CCS, mentre ha un
ruolo importante e d un verso alla comunicazione quando associata allinterazione vi uno
scambio di valori, come avviene ad esempio nella variante di CCS con value-passing.
In altri calcoli, come ad esempio in ACP, non si distingue tra azioni di input ed azioni di
output, per cui le azioni sono sempre indicate con lo stesso nome della porta su cui avvengono.
In questo caso linsieme delle porte e quello delle azioni esterne Act coincidono, cio si
pone Act , . Inoltre, linterazione pu avvenire tra un qualunque numero di processi in
parallelo che eseguono simultaneamente azioni correlate tra loro da una opportuna funzione
di comunicazione. La funzione di comunicazione definisce lazione risultante dallinterazione
di due azioni.
Dato che i passi di computazione interna non sono osservabili dallesterno essi risultano
indistinguibili uno dallaltro per cui per descriverli suciente utilizzare ununica azione
interna, solitamente denotata col simbolo (o a volte, come in LOTOS, con i). Le azioni
invisibili hanno grande importanza nello studio delle astrazioni e giocano un ruolo essenziale
nel definire equivalenze o preordini tra sistemi concorrenti. Infatti una computazione interna
pu essere ignorata ad un certo livello di astrazione mentre ad un livello di astrazione pi
basso pu essere vista come il risultato di una interazione tra componenti del sistema.

10.2

Operatori sui processi

In questo capitolo esamineremo gli operatori pi frequentemente utilizzati dai calcoli di processo. Non considereremo operatori che modellano caratteristiche sofisticate dei sistemi concorrenti quali priorit, tempo, probabilit, ecc. Ci limiteremo invece a considerare gli operatori
di base e ad alcuni operatori che manipolano valori.

201

10.3 Processi di base

Nellapproccio che presentiamo i sistemi complessi saranno ottenuti utilizzando operatori


che permettono di comporre sistemi pi semplici. Raggrupperemo gli operatori in sei gruppi
principali che corrispondono alle tipiche operazioni di composizione:
Processi di Base. Gli operatori di base costruiscono i processi elementari che sono i mattoni
per la costruzione di sistemi complessi.
Sequenzializzazione. Gli operatori di sequenzializzazione permettono di stabilire la
sequenza temporale che le componenti di un sistema debbono rispettare.
Scelta. Gli operatori di scelta permettono di descrivere i comportamenti alternativi che un
processo pu avere.
Parallelizzazione. Gli operatori di parallelizzazione permettono di comporre sistemi in
parallelo. Ve ne sono di vari tipi e si dierenziano per il tipo di comunicazione e
sincronizzazione che permettono tra le componenti.
Astrazione. Gli operatori di astrazione permettono di astrarre da aspetti ritenuti non
rilevanti o di presentare viste particolari dei sistemi.
Ricorsione. Gli operatori di ricorsione permettono di introdurre sistemi con comportamenti
infiniti a partire da presentazioni finite.
Una ulteriore classificazione degli operatori dei calcoli di processi quella che li suddivide
in operatori statici ed operatori dinamici. Un operatore si dice statico se le regole che ne
definiscono la semantica non permettono che loperatore sparisca, ossia se in tutte le regole
loperatore presente sia a destra che a sinistra della conclusione. In altre parole, per un
operatore statico op, le regole saranno della forma

1
Ei 1 !
Ei01 Eim

! Ei0m

op(E1 , , En ) ! op(E10 , , En0 )


dove {i1 , , im } {1, , n}.
Un operatore si dice dinamico se non statico, ossia se nella conclusione di almeno una regola che lo definisce, avviene che loperatore presente prima dellesecuzione della transizione
ed assente dopo.
Infine gli operatori possono essere deterministici o non deterministici. Un operatore n-ario op si dice non deterministico se, per certi processi E1 , . . . , En , pu avvenire che

op(E1 , . . . , En ) ! F e op(E1 , . . . , En ) ! F 0 con F e F 0 diversi.


Nel presentare gli operatori ricorreremo frequentemente allesempio di un distributore
automatico di bevande. Di volta in volta il comportamento del distributore sar arricchito o
modificato per mezzo di nuovi operatori.

10.3

Processi di base

I processi di base sono costanti (cio, operatori senza argomenti) e rappresentano i processi
elementari.

202

Capitolo 10 Operatori per concorrenza e nondeterminismo

Processo inattivo. Il processo pi elementare di tutti quello inattivo ossia quel processo
che non esegue alcuna attivit. Esso viene solitamente indicato con i simboli nil, 0, o stop.
La sua semantica definita dal fatto di non avere regole di transizione. Per semplificare la
notazione si omette spesso il processo inattivo quando preceduto da almeno unazione.
Il processo
nil
pu quindi rappresentare un distributore automatico rotto: esso non accetta monete e non
ore bevande.
Terminazione. La terminazione a volte esplicitamente denotata dalla costante di procesp
so exit (o, skip) che pu solo eseguire lazione speciale (pronunciato tick) per indicare la
terminazione e trasformarsi in un processo inattivo, come formalizzato dal seguente assioma
p

exit ! stop

Riconoscere la terminazione di un processo importante quando da essa dipende linizio


dellesecuzione di un altro processo, come, per esempio, nella concatenazione di processi.
Nei calcoli di processo che prevedono la terminazione esplicita, tipicamente si usa exit per
rappresentare terminazione con successo e stop, o , per rappresentare terminazione senza
successo.
Processo azione. Alcuni calcoli di processo, invece di usare come strumento elementare
loperazione di prefixing, prevedono che le azioni siano esse stesse considerate come delle
costanti di processo (cio, come operatori di processo senza argomenti). Il comportamento di
un tale processo elementare consiste semplicemente nellesecuzione dellazione corrispondente
p
per poi trasformarsi nel processo speciale che indica terminazione con successo. Lassioma
utilizzato in questo caso il seguente:
p
!
Sfruttando questo operatore un distributore automatico disonesto che riceve una moneta e
si ferma verrebbe descritto semplicemente da
coin
Chaos. Il processo chaos rappresenta un processo completamente sottospecificato che pu
comportarsi come qualsiasi processo. In pratica, chaos pu eseguire una qualsiasi sequenza di
azioni e fermarsi in qualsiasi momento. Le regole dinferenza che definiscono la sua semantica
operazionale sono:
a

chaos ! chaos

10.4

chaos ! stop

Operatori di sequenzializzazione

Gli operatori di sequenzializzazione sono operatori dinamici che permettono di mettere in


sequenza pi processi: un processo inizier la sua esecuzione quando il processo precedente
sar terminato. La sequenzializzazione ha quindi senso se i processi da sequenzializzare hanno
termine.

203

10.4 Operatori di sequenzializzazione

Azione prefissa (prefixing). Si tratta di unoperazione molto comune. Ad ogni azione


dellinsieme delle azioni si associa un operatore unario, denotato con . oppure con ! ,
che ad ogni processo E associa un nuovo processo .E che pu eseguire lazione per poi
comportarsi come E. La semantica definita dallassioma

.E ! E

Si tratta quindi di un operatore dinamico e deterministico.


Ad esempio lespressione . ..0 indica un processo che esegue in sequenza le azioni visibili
e , poi eettua unazione interna ed infine si comporta come 0, il processo che non svolge
nessuna azione.
Un esempio pi concreto dato dal seguente termine
coin ! choc ! stop

che descrive un distributore automatico (un po limitato) che in cambio di una moneta fornisce
una barretta di cioccolato e poi si ferma.
Composizione sequenziale o enabling. Loperatore binario composizione sequenziale
tra processi si indica con ; . A volte, con la la stessa semantica, si usa il simbolo
che
chiamato enabling o il simbolo che chiamato prodotto. Intuitivamente, se E ed F
sono processi, la semantica del processo E; F prevede che inizialmente venga eseguito E e che,
p
quando E segnala la sua terminazione (indicata dallazione ), cominci lesecuzione di F . Le
regole di inferenza che definiscono la semantica delloperatore composizione sequenziale sono
le seguenti
p

p
E ! E0
E ! E0
( 6= )

E; F ! E 0 ; F
E; F ! F
Con loperatore di sequenzializzazione un distributore automatico limitato ma onesto pu
essere descritto, considerando le azioni come processi, da
coin; choc
esso prende una moneta e, dopo che il processo di acquisizione della moneta terminato, ore
una barretta di cioccolato.
Disabling. Loperatore binario disabling, indicato con [>, viene di solito usato in congiunzione con lenabling. Intuitivamente, se E ed F sono processi, il processo E [> F inizialmente
si comporta come E ma pu essere interrotto in qualsiasi momento da F , anche prima della
sua terminazione. Se invece E segnala la sua terminazione, F viene eliminato perch venuto
meno il suo ruolo.

E ! E0

E [> F ! E 0 [> F

( 6=

E ! E0

E [> F ! E 0

Un possibile esempio di uso di questo operatore il seguente

F ! F0

E [> F ! F 0

(coin ! choc ! exit) [> (bang ! choc ! exit)

che descrive un distributore automatico che in cambio di un colpo ben assestato fornisce la
barretta di cioccolato anche quando non stata inserita alcuna moneta.

204

10.5

Capitolo 10 Operatori per concorrenza e nondeterminismo

Operatori di scelta

Gli operatori di scelta permettono di esprimere scelte tra comportamenti alternativi. Si tratta
di operatori dinamici (perch scompaiono quando la scelta viene eettuata) e, naturalmente,
non deterministici. Con essi, e con gli operatori visti in precedenza, possiamo gi modellare
LTS ed automi a stati finiti.
Scelta (mista) o somma. Loperatore binario scelta, scritto +, permette di esprimere
una scelta tra due possibili comportamenti. Cominciamo col vedere le semplici regole che
definiscono loperatore

E ! E0
F ! F0

E + F ! E0
E + F ! F0
Osserviamo che loperatore non-deterministico, infatti il processo

coin ! choc ! stop + coin ! water ! stop


pu evolvere con lazione coin nel processo choc ! nil o nel processo water ! nil. Tale
processo rappresenta quindi un distributore automatico che, a sua scelta, dopo lintroduzione
di una moneta decide se lutente aamato o assetato ed ore una barretta di cioccolato o
un bicchiere dacqua.
Loperatore pu anche modellare scelte che vengono guidate dallesterno. Un possibile
esempio il seguente
coin ! (choc ! stop + water ! stop)
che descrive un distributore automatico che in cambio di una moneta fornisce, a scelta
dellutente, una barretta di cioccolato o un bicchiere dacqua.
Riassumendo, se E ed F hanno delle azioni iniziali in comune allora il processo E + F
risulta non-deterministico, e in tal caso si parla di scelta interna, se invece le azioni iniziali di
E sono diverse dalle azioni iniziali di F , allora il processo E + F risulta deterministico, e in
tal caso si parla scelta esterna.
Dato che loperatore + risulta essere commutativo e associativo, possibile definire una
somma
generale con pi di due operandi . La sintassi di solito usata per tale operatore
P
E
i2I i e la semantica data dalla seguente regola

Ej ! Ej0
X

Ei ! Ej

(j 2 I)

i2I

Esempio 10.1. [Bill-Ben] Utilizzando gli operatori visti fino a qui possiamo scrivere un
processo che ha come grafo delle transizioni quello della Figura 10.1. Infatti, se allo stato q0
associamo il processo
play. work. . nil + work. play. . nil
abbiamo che, grazie alla semantica degli operatori, dallo stato q0 escono due archi distinti
(transizioni (q0 , play, q1 ) e (q0 , work, q2 ) ) che raggiungono due stati dierenti q1 e q2 , associati rispettivamente ai processi work. . nil e play. . nil. Da questi, tramite altri due archi

205

10.5 Operatori di scelta


q2
rk
wo

q0

pla
y

q3

pla
y

q4

rk
wo

q1

Figura 10.1: Grafo delle transizioni di un LTS


(transizioni (q1 , work, q3 ) e (q2 , play, q3 ) ), si raggiunge sempre lo stesso stato q3 , associato
al processo . nil. Lo stato q3 ha un solo arco uscente (transizione (q3 , , q4 ) ) con il quale si
raggiunge lo stato q4 , associato al processo nil.
In pratica otteniamo un LTS formato da 5 stati, 3 azioni (o etichette) e 5 transizioni:
h{q0 , q1 , q2 , q3 , q4 } , {play, work, } ,
{(q0 , play, q1 ), (q0 , work, q2 ), (q1 , work, q3 ), (q2 , play, q3 ), (q3 , , q4 )}i.
di cui una una possibile rappresentazione data dal grafo delle transizioni in Figura 10.1.
Loperatore + loperatore di scelta pi comunemente usato nelle algebre di processi.
Come abbiamo visto esso pu rappresentare, a seconda dei casi, una scelta interna o una
scelta esterna. In alternativa a tale operatore possibile usare due operatori che rendono la
scelta esclusivamente interna, ossia a carico del processo, o esclusivamente esterna, ossia a
carico dellambiente.
Scelta interna. Loperatore binario scelta interna pura ada il compito di scegliere uno
tra due comportamenti al processo stesso. La semantica definita dai due seguenti assiomi
E

F !E

F !F

Come si vede la scelta eettuata esibendo unazione interna ed quindi completamente


incontrollabile dallambiente.
Con questo operatore tramite il termine
coin ! (choc ! stop

water ! stop)

possibile descrive il distributore automatico che decide se lutente aamato o assetato e


fornisce a sua scelta una barretta di cioccolato o un bicchiere dacqua.
Scelta esterna. Loperatore binario scelta esterna prevede invece che la scelta sia eettuata solo tramite lesecuzione di unazione visibile e quindi sotto il controllo dellambiente
esterno. Anche in questo caso comunque, come nel caso delloperatore scelta mista, se i due
processi a cui la scelta applicata possono eseguire azioni visibili comuni, la scelta sfugge al
controllo dellambiente e diventa non deterministica. Le regole di inferenza che definiscono la

206

Capitolo 10 Operatori per concorrenza e nondeterminismo

semantica delloperatore sono le seguenti

E ! E0

E F ! E0

( 6= )

F ! F0

E F ! F0

( 6= )

E ! E0

F ! F0

E F ! E0 F

E F ! E F0

Con questo operatore possibile limitare larbitrio del nostro distributore automatico. Ad
esempio, il termine
water ! stop) water ! stop

coin ! (choc ! stop

descrive un distributore automatico che non pu rifiutarsi di orire lacqua. Infatti, se dopo
aver ricevuto la moneta la componente a sinistra di decidesse di orire solo una barretta
di cioccolato, allora la componente a destra di continuerebbe a garantire la possibilit di
scegliere lacqua. Levoluzione sarebbe la seguente:
coin ! (choc ! stop
water ! stop) water ! stop
(choc ! stop
water ! stop) water ! stop
(choc ! stop water ! stop)

coin

!
!

opportuno notare che, invece, il termine


coin ! (choc ! stop

water ! stop )

water ! stop

non fornisce garanzie; infatti una sua possibile evoluzione


coin ! (choc ! stop
water ! stop)
water ! stop
(choc ! stop
water ! stop)
water ! stop
choc ! stop
water ! stop
choc ! stop
stop

10.6

coin

!
!

choc

Operatori di parallelismo

Gli operatori di parallelismo permettono di ottenere processi complessi tramite la composizione parallela di processi pi semplici. Si tratta in generale di operatori statici che modellizzano
la strutturazione di processi in sottoprocessi.
Composizione parallela ( la Milner). Loperatore binario | permette sia linterleaving
delle azioni eseguibili dalle componenti parallele sia linterazione tra due processi che eseguono
azioni complementari. Informalmente, nel processo E|F le azioni di E e di F sono considerate
indipendenti le une dalle altre e qualsiasi interleaving tra loro possibile; inoltre, azioni visibili
complementari e possono dare origine a sincronizzazioni. Quando vi una sincronizzazione

207

10.6 Operatori di parallelismo

essa viene percepita dallesterno come unazione . Le regole di inferenza che definiscono la
semantica delloperatore sono

E ! E0

F ! F0

E|F ! E 0 |F

E|F ! E|F 0

E ! E0

F ! F0

E|F ! E 0 |F 0

( 6= )

Per mezzo delloperatore composizione parallela possiamo modellare non solo il nostro
distributore automatico ma anche le sue interazioni con un utente ipotetico. Il termine
coin ! (choc ! stop

water ! stop)

| (coin ! choc ! stop)

rappresenta il sistema costituito dalla composizione parallela del distributore automatico e


dellutente. Una possibile computazione prevede che lutente inserisca la moneta con lazione
coin e ottenga il cioccolato con lazione choc:
coin ! (choc ! stop
water ! stop) | (coin ! choc ! stop)
(choc ! stop
water ! stop) | (choc ! stop)
(choc ! stop) | (choc ! stop)
stop | stop

Va detto che questo sistema prevede anche altre computazioni in cui le sincronizzazioni non
avvengono, come in
coin ! (choc ! stop

(choc ! stop
(choc ! stop

water ! stop)

| (coin ! choc ! stop)

water ! stop) | (coin ! choc ! stop)


water ! stop) | (choc ! stop)

coin

coin

che sostanzialmente cattura il fatto che il distributore ore la possibilit di inserire la moneta
anche ad altri utenti e che lutente pu inserire la sua moneta anche in altri distributori.
Nel seguito, vedremo come forzare le sincronizzazioni quando discuteremo gli operatori di
astrazione.
Merge. Alcuni calcoli, quali ad esempio ACP, utilizzano, per la composizione parallela tra
due processi, loperatore k . Anche questo operatore permette sia linterleaving che linterazione tra i due processi. La dierenza rispetto alloperatore | sta nel modo in cui viene espressa
linterazione. Come abbiamo visto, nel caso delloperatore | , si usa la nozione di complementarit tra azioni. Nel caso delloperatore k , si usa invece un meccanismo pi generale e si
modella il fatto che lesecuzione simultanea di due azioni qualunque pu originare una sincronizzazione. A questo scopo viene introdotta una funzione di comunicazione : !
(dove linsieme delle azioni) avente la propriet di essere commutativa (cio tale che
(a, b) = (b, a)) e associativa (cio tale che ( (a, b), c) = (a, (b, c))). Dati due elementi
a, b 2 , lelemento (a, b) viene interpretato come lazione risultante dalla sincronizzazione di
un processo che esegue lazione a con uno che esegue lazione b. In generale si ammette che la
funzione sia una funzione parziale e talvolta, come ad esempio nei calcoli di processi TCSP
e LOTOS, si impone (a, a) = a. Inoltre, poich (a, b) visibile, essa pu essere usata per
ulteriori sincronizzazioni con altre azioni. Quindi, mentre | permette solo la sincronizzazione

208

Capitolo 10 Operatori per concorrenza e nondeterminismo

di due processi, k permette la sincronizzazione di pi processi. Le regole di inferenza che


definiscono la semantica delloperatore sono

F ! F0

E k F ! E0 k F

E ! E0

E ! E0

E k F ! E k F0

EkF

F ! F0
(a,b)

! E0 k F 0

dove 2 [ { }.
Il sistema costituito da un distributore automatico e da un utente potrebbe essere cos
descritto (dove usiamo loperatore . per le azioni prefisse):
getCoin.(giveChoc.nil + giveW ater.nil) k putCoin.getChoc.nil
dove si pone (getCoin, putCoin) = ok e (giveChoc, getChoc) = ok. Anche in questo caso,
come per loperatore | , le sincronizzazioni non sono obbligatorie; vedremo in seguito come
forzare le sincronizzazioni a cui siamo interessati.
Loperatore k pu essere espresso in termini di operatori di parallelismo pi basilari come
specificato dallequazione E k F = ETF +F TE+E|c F , dove T e |c sono gli operatori left-merge
e communication-merge che illustriamo adesso.
Left-merge e communication-merge. Loperatore T noto come left-merge e la sua
semantica dice che lazione iniziale deve essere eseguita dal processo di sinistra dopodich il
comportamento del sistema regolato da k. Lunica regola semantica

E ! E0

ETF ! E 0 k F
Loperatore |c noto come communication-merge e la sua semantica dice che lazione
iniziale deve essere uninterazione tra i due processi dopodich il comportamento del sistema
regolato da k. Lunica regola semantica
a

E ! E0
E|c F

F ! F0

(a,b)

! E0 k F 0

Interleaving Gli operatori di parallelismo che abbiamo visto finora permettono ai processi
in parallelo di sincronizzarsi nellesecuzione di certe azioni. Al contrario, loperatore binario
interleaving ||| permette esclusivamente lesecuzione indipendente dei due processi argomento.
Le regole semantiche sono

E ! E0

E ||| F ! E 0 ||| F

F ! F0

E ||| F ! E ||| F 0

Consideriamo il processo
a.b.nil ||| c.d.nil

esso ammette le seguenti computazioni che lo fanno evolvere in nil ||| nil
abcd,

acdb,

cdba,

acbd,

cadb,

cabd

209

10.6 Operatori di parallelismo

Composizione parallela con interfaccia ( la Hoare) Loperatore binario |[L]|, dove


L , permette sia linterleaving che linterazione tra due processi; questultima si ha per
tutte le azioni che appartengono allinsieme L. Loperatore utilizzato nelle algebre di processi, come ad esempio CSP, in cui non si fa distinzione tra azioni di input ed azioni di output
e la sincronizzazione tra processi ottenuta richiedendo che essi eseguano le stesse azioni
simultaneamente. Le regole di inferenza che definiscono la semantica delloperatore sono

E ! E0

E |[L]| F ! E 0 |[L]| F

F ! F0

( 62 L)

E |[L]| F ! E |[L]| F 0

E ! E0

( 62 L)

F ! F0

E |[L]| F ! E 0 |[L]| F 0

(a 2 L)

Loperatore |[L]| in relazione con alcuni degli operatori visti in precedenza. In particolare,
se si definisce (a, a) = a per ogni a 2 L, gli operatori |[L]| e k hanno semantiche equivalenti.
Se invece si prende L = ;, gli operatori |[L]| e ||| risultano equivalenti.
Prodotto (o parallelo con esecuzione sincrona). Se E ed F sono processi, loperatore
binario permette di formare il processo E F in grado di eseguire unazione solo se questa
il risultato del prodotto di unazione iniziale di E ed una azione iniziale di F . In pratica, le
componenti E e F di E F devono procedere in maniera sincrona; cio, non possibile che
una componente resti ferma mentre laltra eettua unazione.
Perch la definizione abbia senso richiesto che sullinsieme delle azioni sia definita unoperazione di prodotto, denotata anchessa con , che rende tale insieme un gruppo abeliano.
Ricordiamo che un gruppo abeliano costituito da un insieme A e da unoperazione binaria
su A tale che
associativa e commutativa,
esiste un elemento speciale 1 2 A, detto elemento neutro, tale che 1 = 1 = ,
per ogni 2 A,
per ogni 2 A esiste un elemento, detto opposto di e denotato con
, tale che

=
= 1.
La semantica operazionale delloperatore sui processi definita dalla seguente regola
dinferenza

E ! E0
EF

F ! F0

! E0 F 0

Come si vede, si tratta di unoperatore statico.


Consideriamo come esempio il processo (a.b.0 + c.(d.0 + e.0)) a
.1.0. Il grafo delle
transizioni associato il seguente

210

Capitolo 10 Operatori per concorrenza e nondeterminismo


00
d

(d.0 + e.0) 1.0

(a.b.0 + c.(d.0 + e.0)) a


.1.0

00
1

b.0 1.0

10.7

00

Operatori di astrazione

Spesso utile vedere un processo come una black-box e modificarne il comportamento restringendo o ridenominando le azioni che pu eettuare. Gli operatori di astrazione permettono
questo tipo di modifiche sui processi e si rendono quindi utili per modificare il livello di
astrazione a cui un sistema descritto facilitando cos la composizionalit dei processi stessi.
Restrizione. Loperatore unario \L , dove L , permette di restringere le azioni visibili
del processo a cui applicato. Il processo E\L potr eseguire solo le azioni non incluse in
L ed il cui complementare non incluso in L. Ovviamente non ha senso impedire che un
processo esegua unazione interna e perci non permesso che appartenga ad L. Quando
L contiene una sola azione, cio L = {a}, scriveremo, per semplicit, E\a invece di E\{a}.
La semantica operazionale definita dalla regola dinferenza

E ! E0

E \L ! E 0 \L

( , 62 L)

Come si vede loperatore deterministico e statico.


Vediamo un esempio. Modelliamo il nostro distributore automatico come la composizione
parallela di due processi, uno che controlla linserimento della moneta e laltro che ore la
barretta di cioccolato o lacqua. Per fare in modo che le due componenti comunichino senza
interferenze con lambiente esterno usiamo la restrizione nel modo seguente
(coin.ok.nil) | ok.(choc.nil + water.nil) \ ok
Messo in parallelo con un utente coin.choc.nil, una computazione possibile la seguente
(coin.ok.nil) | ok.(choc.nil + water.nil) \ ok | coin.choc.nil

!
(ok.nil) | ok.(choc.nil + water.nil) \ ok | choc.nil

!
nil | (choc.nil + water.nil) \ ok | choc.nil

!
nil | nil \ ok | nil
Si osservi che un utente malizioso che tentasse di eseguire la sequenza di azioni ok.choc.nil
per ottenere il cioccolato senza inserire una moneta non riuscirebbe ad interagire con il
distributore.

211

10.7 Operatori di astrazione

Questo modo di combinare la restrizione con la composizione parallela usato spesso


per costringere i processi concorrenti a sincronizzarsi sulluso di alcuni canali. Potremmo
per esempio costringere il distributore e lutente a sincronizzarsi sullazione coin nel modo
seguente

(coin.ok.nil) | ok.(choc.nil + water.nil) \ ok | coin.choc.nil \ coin

Osserviamo infine che c una certa corrispondenza tra i processi (E|F )\L e E |[L]| F : in
entrambi i casi i processi E ed F devono necessariamente sincronizzarsi se vogliono eseguire
azioni di L, nel secondo caso per lazione risultante dalla sincronizzazione visibile anche
allesterno.
Esempio 10.2. [Bill-Ben] Abbiamo visto che il grafo delle transizioni associato al processo
play.work..nil + work.play..nil
quello della Figura 10.1. Vediamo adesso che vi sono altri processi che hanno lo stesso grafo
delle transizioni. Si consideri il processo
(play.meet.nil | work.meet.nil) \ meet
Non dicile rendersi conto che il grafo delle transizioni ad esso associato ancora quello di
Figura 10.1.

Abilitazione. Loperatore unario L consente a un processo di eseguire solo le azioni


contenute in L (e le loro complementari). Si tratta quindi di un operatore che si comporta
in maniera complementare alla restrizione. La semantica operazionale definita dalla regola
dinferenza

E ! E0
( 2 L _ 2 L _ = )

E L ! E0 L
Encapsulation. Loperatore unario H , dove H , ha leetto di rinominare le azioni
appartenenti ad H in bloccandone cos lesecuzione. In pratica, il processo H (E) si
comporta come E eccettuato il fatto che esso non pu eseguire le azioni che compaiono in H
e le loro complementari (e, di conseguenza, ci che li segue sintatticamente). La semantica
operazionale definita dalla regola di inferenza (ove si assume che lazione invisibile non
appartenga a H)

E ! E0
H (E)

H (E

( 62 H)

Si noti la stretta corrispondenza con (la regola che definisce) la semantica operazionale
delloperatore di restrizione (in pratica, E \H e H (E) si comportano allo stesso modo).

212

Capitolo 10 Operatori per concorrenza e nondeterminismo

Hiding. Loperatore unario /L, con L , nasconde le azioni appartenenti allinsieme L


e fa in modo che vengano percepite al di fuori del sistema come azioni invisibili. Tuttavia, diversamente dalla restrizione, lascia inalterata la capacit dei processi di eettuare transizioni.
La semantica operazionale definita dalle seguenti regole di inferenza

E ! E0

E/L ! E 0 /L

E ! E0

( 62 L)

E/L ! E 0 /L

( 2 L)

Come si vede, si tratta di un operatore statico.


Possiamo modellare il nostro distributore automatico per mezzo della composizione
parallela con interfaccia e delloperatore hiding
(coin.ok.nil) |[ok]| ok.(choc.nil + water.nil) / ok
Questo modo di abbinare composizione parallela con interfaccia e operatore hiding molto
comune.
Osservazione 10.3. Si noti che (E |[L]| F )/L e (E | F )\L non si comportano, in generale,
allo stesso modo. Infatti, a dierenza del secondo, il primo non consente sincronizzazioni su
canali non appartenenti ad L.
Esempio 10.4. [Bill-Ben] Il processo
(play.meet.nil |[meet]| work.meet.nil)/meet
ha anchesso come grafo delle transizioni quello di Figura 10.1.
Si pu infine osservare che, mentre la restrizione preserva il determinismo, non accade
altrettanto per loperatore hiding. Si consideri per esempio il processo ..nil + .nil. Esso
deterministico, mentre se nascondiamo lazione , ossia consideriamo il processo (..nil +
.nil)/ , esso non pi deterministico perch per mezzo dellazione pu andare in .nil o
in nil.
Rietichettatura (o relabelling). Loperatore unario [f ], dove f : ! una funzione
dallinsieme delle etichette in se stesso, usato per ridenominare le azioni di un processo. La
semantica operazionale definita dalla regola di inferenza

E ! E0
E[f ]

f ()

! E 0 [f ]

dove sintende f ( ) = e f (a) = f (a). Come si vede si tratta di un operatore statico. Esso
usato per gestire meglio la sincronizzazione e per facilitare il compito di costruire processi
complessi a partire da altri pi semplici.
Se la funzione f non si comporta come lidentit solo su un insieme finito di punti a1 , , an
allora essa viene scritta per semplicit come [b1 /a1 , , bn /an ] dove b1 = f (a1 ), , bn =
f (an ). Per esempio [c/a, d/b] la funzione che rinomina a con c e b con d.

213

10.8 Operatori per definire comportamenti infiniti


Consideriamo come esempio il solito distributore automatico
coin. (choc. nil + water. nil)

e un utente italiano che voglia usufruire del distributore per prendere un bicchiere di acqua
soldo. acqua. nil
Lutente pu interagire col distributore se gli applichiamo un operatore di rietichettatura
coin. (choc. nil + water. nil) | ( soldo. acqua. nil ) [coin/soldo, water/acqua]

10.8

Operatori per definire comportamenti infiniti

Gli operatori che abbiamo visto finora permettono di definire solo processi il cui comportamento finito, cio processi che possono eettuare solo computazioni di lunghezza finita.
Introduciamo adesso i meccanismi che possono essere utilizzati per definire processi in grado
di eettuare sequenze infinite di transizioni.
Costanti di processo. Una costante di processo un processo il cui significato dato da
unequazione di definizione. Se A una costante di processo si assume quindi che vi sia anche
una definizione della forma A , E che definisce A per mezzo del processo E. La semantica
operazionale per le costanti di processo ovvia

E ! E0

A ! E0

(A , E)

Il potere espressivo di quella che sembra essere una definizione banale sta nel fatto che nulla impedisce che la costante di processo A venga usata anche nel processo che la definisce
permettendo cos definizioni ricorsive o mutuamente ricorsive.
Per convenzione, le costanti di processo sono solitamente indicate con stringhe che
cominciamo con una lettera maiuscola.
Finalmente siamo in grado di migliorare il nostro distributore automatico e fare in modo
che esso sia sempre pronto a servire un nuovo cliente dopo aver finito di servirne un altro. A
questo scopo definiamo la costante di processo D (distributore) come
D , coin. (choc. D + water. D)
Una possibile computazione del distributore in parallelo con un utente la seguente
D | coin. choc. nil
(choc. D + water. D) | choc. nil
D | nil

che mostra che, dopo aver interagito con lutente, il distributore tornato nel suo stato iniziale
ed attende il prossimo cliente.

214

Capitolo 10 Operatori per concorrenza e nondeterminismo

Esempio 10.5. Vediamo un altro semplice esempio. Consideriamo la costante di processo


Coin , toss.tail.Coin + toss.head.Coin
Esso descrive il lancio reiterato di una moneta che di volta in volta pu dare come esito testa
o croce. Una possibile computazione
Coin

toss

! tail.Coin

tail

! Coin

toss

! head.Coin

head

! Coin

toss

! ...

Ricorsione. Processi ricorsivi possono essere ottenuti anche per mezzo delloperatore unario rec X. . Se E un processo (o, pi precisamente, unespressione di processo) in cui
compare la variabile X allora, intuitivamente, il processo rec X.E (talvolta scritto anche come f ix(X = E)) definito come il processo che si comporta come E in cui le occorrenze
di X sono sostituite con rec X.E stesso. Informalmente possiamo anche dire che rec X.E
equivalente a una definizione della forma X , E. Per definire formalmente la semantica
delloperatore di ricorsione bisogna definire il concetto di occorrenza libera di una variabile.
Se E unespressione di processo, ossia un processo in cui compaiono delle variabili, allora
diremo che una certa occorrenza di X in E libera se essa non appartiene al corpo di un operatore della forma rec X. Con E{F/X} si denota il processo ottenuto sostituendo (a livello
sintattico) le occorrenze libere di X in E con il processo F .
La semantica data dalla seguente regola dinferenza

E{rec X.E/X} ! E 0

rec X.E ! E 0

La regola dice che il processo rec X.E pu fare qualsiasi azione che pu fare il processo
E{rec X.E/X} e proseguire nello stesso modo.
Per mezzo di questo operatore il distributore automatico pu essere definito come il
processo
rec D. coin. (choc. D + water. D)
Una possibile computazione di questo processo la seguente
coin

rec D. coin. (choc. D + water. D)


choc. rec D. coin. (choc. D + water. D)
+
water. rec D. coin. (choc. D + water. D)
rec D. coin. (choc. D + water. D)

9
=
;

Mentre il lancio reiterato della moneta pu essere descritto da


rec C. (toss. tail. C + toss. head. C)

choc

coin

...

215

10.8 Operatori per definire comportamenti infiniti


ed una possibile computazione la seguente
rec C. (toss. tail. C + toss. head. C)

toss

tail. rec C. (toss. tail. C + toss. head. C)


rec C. (toss. tail. C + toss. head. C)

tail

!
!

toss

...

Loperatore rec X. costituisce un modo alternativo di trattare la ricorsione rispetto alle


costanti di processo. Facendo uso delloperatore di ricorsione, lequazione ricorsiva A , E
potrebbe essere trasformata nellequazione non ricorsiva A , rec X.E{X/A}, separando cos
i costrutti usati per esprimere la ricorsione da quelli usati per definire processi. In generale,
trattare la ricorsione usando il rec X. pi conveniente dal punto di vista dello sviluppo della
teoria, ma meno comodo da utilizzare in pratica per specificare sistemi.
Loperatore di ricorsione pu essere generalizzato per gestire anche la ricorsione mutua.
Siano Xi variabili, per i appartenente a un certo insieme di indici I, e siano Ei , per i 2 I,
espressioni di processo in cui possono comparire una o pi delle variabili Xi . Indichiamo con
=E
linsieme di equazioni {Xi = Ei | i 2 I}. La j-esima componente delloperatore di
X
ricorsione generalizzato indicata con
= E)

f ixj (X
ed ha la seguente semantica
Ej

= E)/X

f ixi (X
i | i2I

= E)
!
f ixj (X
E0

! E0

= E)/X

dove Ej f ixi (X
rappresenta il processo ottenuto sostituendo, per ogni i,
i | i2I
= E).

le occorrenze libere di Xi in Ej con la scrittura formale f ixi (X


Replicazione. Un altro operatore usato per descrivere comportamenti infiniti loperatore
unario ! (letto bang). Intuitivamente, !E rappresenta un numero illimitato di copie del
processo E, tutte composte in parallelo. La sua semantica operazionale pu essere definita
da una delle seguenti regole di transizione equivalenti:

E ! E0

! E ! E0| ! E

oppure

E| ! E ! E 0

! E ! E0

Come si vede, si tratta di un operatore statico. Il suo potere espressivo equivalente a quello
delle definizioni di processo ed a quello delloperatore di ricorsione. Infatti, ! E pu essere
definito dalla seguente equazione
A , E|A
oppure pu essere espresso in termini delloperatore rec dal processo
recX.(E|X)
Al contrario, ! pu essere utilizzato per codificare equazioni di processo ricorsive e processi
ricorsivi in modo tale che, se si ignorano le azioni invisibili, i processi risultanti dalle codifiche si
comportino come quelli originali. Per esempio, supponiamo che il processo E usi la costante di

216

Capitolo 10 Operatori per concorrenza e nondeterminismo

processo A definita dallequazione A , F . Se vogliamo tradurre E in un calcolo che utilizza la


replicazione al posto delle equazioni di definizione, dobbiamo scegliere un a 2 non utilizzato
b | ! a.Fb )\{a}, dove E
b ed Fb denotano i processi
in E ed F e quindi considerare il processo (E
ottenuti rimpiazzando in E ed F , rispettivamente, le occorrenze di A con a. nil. Similmente,
b
recX.E codificato da (a. nil | ! a.E)\{a}.
Sistemi di equazioni di processo mutuamente
ricorsive e processi mutuamente ricorsivi potrebbero essere espressi tramite ! usando lo stesso
metodo.
Esempio 10.6. Come esempio delloperatore ! vediamo la seguente definizione di un
distributore automatico
! coin. choc. nil
Esso accetta una moneta ed ore una barretta di cioccolato, un numero qualunque di volte.
Una sua possibile computazione la seguente
! coin. choc. nil

coin

choc. nil | ! coin. choc. nil

coin

nil | choc. nil | ! coin. choc. nil


nil | nil | ! coin. choc. nil

choc

choc. nil | choc. nil | ! coin. choc. nil

!
!

choc

!
!

Si pu quindi osservare che, una volta ricevuta una moneta, il distributore non obbligato a
dare la barretta di cioccolato prima di ricevere una seconda moneta. Se invece si vuole fare in
modo che le azioni di ricezione della moneta e di erogazione della barretta siano strettamente
sequenziali, si potrebbe utilizzare il seguente processo ricorsivo
recX. coin. choc.X
Tale processo, codificato usando loperatore ! , diventa
(a. nil | ! a. coin. choc. a. nil) \ a
Le sue possibili computazioni sono della forma
(a. nil | ! a. coin. choc. a. nil) \ a

(nil | coin. choc. a. nil | ! a. coin. choc. a. nil) \ a

(nil | choc. a. nil | ! a. coin. choc. a. nil) \ a


(nil | a. nil | ! a. coin. choc. a. nil) \ a

coin

choc

!
...

e quindi il processo ottenuto si comporta sostanzialmente (cio, come sar formalizzato nel
Capitolo 11, a meno di azioni interne) come volevamo.

10.9 Sincronia ed asincronia

10.9

217

Sincronia ed asincronia

I termini sincronia ed asincronia sono usati per specificare la modalit di interazione o la


modalit di esecuzione di due o pi processi.
Nel caso dellinterazione, si dice che essa sincrona quando i processi interagenti devono
eettuare le azioni di interazione simultaneamente anch linterazione abbia luogo. In CCS,
per esempio, mittente e destinatario di una interazione su un canale devono eettuare le azioni
di output e di input nello stesso istante. Nei calcoli in cui linterazione sincrona, le azioni di
interazione sono quindi bloccanti nel senso che, se non possibile eseguirle, il processo che le
invoca si blocca in attesa che ci sia un altro processo pronto per linterazione. Linterazione
invece asincrona quando i processi coinvolti non sono obbligati ad eseguire simultaneamente le
azioni che portano allinterazione. Nella variante di CCS con interazione asincrona, il processo
mittente non si blocca mai sullesecuzione di un output su un canale (la sintassi tale che
loutput non pi un prefisso, ma un processo autonomo), mentre il destinatario si blocca
nellesecuzione di un input se loutput corrispondente non stato precedentemente eseguito.
Nel caso dellesecuzione, si dice che essa sincrona quando, ad ogni passo di riduzione di un
sistema di processi in parallelo (che in maniera astratta corrisponde ad un istante di tempo),
tutti i processi componenti sono obbligati ad eettuare unazione. Tale tipo di comportamento si presta a descrivere soprattutto componenti hardware ed utilizzato da vari calcoli di
processo (quali ad esempio SCCS, Mejie ed Esterel) che si prefiggono lobiettivo di descrivere
le componenti hardware di sistemi concorrenti. Lesecuzione dei processi asincrona quando
i processi in parallelo non sono obbligati ad eettuare azioni simultaneamente; in questo caso
quindi la semantica delloperatore composizione parallela permette anche linterleaving, cio
lesecuzione interallacciata delle azioni delle varie componenti. Questa la scelta fatta da
CCS, CSP, ACP e da molte altre algebre di processo.
Molti degli operatori di composizione parallela che abbiamo visto, sia con esecuzione asincrona che sincrona, possono essere espressi con un unico operatore a patto di dotare linsieme
delle azioni di unopportuna struttura algebrica, cio di trasformarlo in una algebra di sincronizzazione. Unalgebra di sincronizzazione determina i possibili interleaving e le possibili
sincronizzazioni di due processi composti in parallelo. In particolare unalgebra di sincronizzazione specifica lazione risultante dallinterazione di due azioni. Le algebre di sincronizzazione
sono cos definite.
Definizione 10.7. Un algebra di sincronizzazione una quadrupla h, , 0, i dove
1. un insieme, detto insieme delle etichette, contenente le etichette speciali e 0,
2. unoperazione binaria su (cio : ! ), che associativa, commutativa e
soddisfa le seguenti propriet
(a) a 0 = 0 per ogni a 2 ,
(b) = ,

(c) a b = implica a = b = , per ogni a, b 2 .


Date due azioni a e b, a b rappresenta lazione risultante dallinterazione sincrona di a e
b. Se a b = 0 sintende che linterazione non ammessa. Letichetta rappresenta unazione
fittizia, che pu essere eseguita da qualsiasi processo in qualsiasi momento, ed usata per

218

Capitolo 10 Operatori per concorrenza e nondeterminismo

trattare lasincronia dellesecuzione. Nessuna azione vera etichettata da . Quando due


processi sono messi in parallelo, un processo pu eettuare lazione a senza sincronizzarsi con
unazione dellaltro processo se a 6= 0, ossia se si pu sincronizzare con lazione .
Ad esempio, lalgebra di sincronizzazione per CCS data dalla seguente tabella, che mostra come in CCS sia permessa solo la sincronizzazione di azioni complementari e come tale
sincronizzazione produca unazione invisibile
b
b
0
0
0

0
.. . .
.
.

0
0
0
0
0
0
0
..
.

0 0 0 0 0 0 0

a
a

b
b
..
.

a
a

b
b
..
.

0
0
0
0
0
..
.

a
a
0
0

0
0
..
.

0
0
0
..
.

b
b
0
0
0
0

..
.

Come altro esempio consideriamo unalgebra di sincronizzazione che costringe a


sincronizzarsi solo per eseguire una certa azione a. Essa pu essere ottenuta imponendo
= 0 per ogni

a a = a, a = 0, a

= 0,

ossia

per ogni ,

=



a 0

0
0
0
0 0

a
0
0
a
0
0

0
0
0
0

6= a

6= a

0
0
0
0
0
0

Come ultimo esempio consideriamo unalgebra di sincronizzazione che assicura che tutte
le azioni dei processi composti in parallelo occorrono in maniera asincrona.

0
0

0
0
0
0

Al contrario, quando per ogni a 6= risulta a = 0, lalgebra di sincronizzazione


sincrona, poich in tal caso la composizione parallela tra processi puramente sincrona in
quanto non possibile eseguire nessuna azione senza sincronizzarsi con unaltra.
Ad ogni algebra di sincronizzazione associato in maniera naturale un operatore composizione parallela, denotato anchesso con , la cui semantica definita dalla seguente
regola

E ! E0
EF

F ! F0

! E F

6= 0)

219

10.10 Operatori che manipolano valori

dove si assume che E ! E valga per ogni processo.


Concludendo, possiamo dire che le algebre di sincronizzazione generalizzano i vari operatori
di composizione parallela e sono simili ai gruppi abeliani usati in connessione con loperatore
. La dierenza tra una algebra di sincronizzazione ed un gruppo abeliano, che nellalgebra
non esistono necessariamente lelemento neutro e lopposto di ogni elemento, mentre esistono
le due etichette speciali e 0.

10.10

Operatori che manipolano valori

Finora abbiamo introdotto azioni ed operatori che non manipolano valori. Consideriamo ora
un sistema in cui vi scambio di informazioni tra le varie componenti e in cui il comportamento
delle varie componenti dipende dalle informazioni ricevute. Si potrebbe pensare che un tale
sistema non possa essere espresso con gli operatori visti. Le cose non stanno cos. Si pu infatti
mostrare, e lo faremo in seguito per CCS, che sotto opportune ipotesi possibile tradurre un
sistema in cui c scambio di valori in uno in cui tale scambio non c.
I calcoli di processo che supportano il passaggio di valori tra le varie componenti sono
detti calcoli con value-passing. Tali calcoli risultano pi espressivi e comodi da usare ma, dal
punto di vista teorico, equivalenti a quelli senza value-passing. Quando si tratta di studiare
le propriet di un calcolo di processi conviene quindi riferirsi alla versione senza value-passing
che risulta sicuramente pi facile da trattare avendo meno costrutti.
In questa sezione presentiamo gli operatori standard per la manipolazione di valori. Le
operazioni pi comuni per trattare valori sono:
Output di valori. Per inviare il valore dellespressione e sul canale a si usa la sintassi
a e. Tale sintassi viene vista come una sorta di azione e la si usa perci come prefisso: se
E un processo, a e.E il processo che spedisce il valore dellespressione e sul canale a
per poi comportarsi come E. Per esempio: a 1.nil spedisce 1 sul canale a e poi termina.
Input di valori. Per ricevere un valore su un canale a si usa la sintassi a(x). Se E un
processo in cui compare la variabile x, allora a(x).E rappresenta il processo che riceve
un valore v sul canale a e poi si comporta come E in cui le occorrenze libere di x sono
sostituite dal valore v. Vedremo tra breve linterazione tra un processo che spedisce un
valore ed uno che lo riceve.
Comportamento condizionale. Se un processo riceve un valore si potrebbe volere
che il suo comportamento dipenda dal valore ricevuto. A questo scopo si usa loperatore
if . Se E ed F sono processi, il processo if e then E else F si comporta come E se
la valutazione (che supponiamo gestita da qualche altro meccanismo) dellespressione e
restituisce true e si comporta come F se la valutazione di e f alse.
Costanti di processo parametriche. Se i processi sono in grado di gestire valori
pu risultare utile permettere che le costanti di processo abbiano dei parametri. Una
costante di processo parametrica A un processo definito da una equazione della forma
A(x1 , . . . , xn ) , E
dove E un processo che pu contenere le variabili x1 , . . . , xn (oltre che A o altre
costanti di processo). Per esempio: il processo a(x).A(x), dove
A(x) , if x = 0 then nil else b x.nil

220

Capitolo 10 Operatori per concorrenza e nondeterminismo


riceve un valore x sul canale a ed invoca il processo A(x), il quale si blocca se x = 0 e
spedisce invece il valore x sul canale b se x 6= 0.

Le regole dinferenza per linput e loutput sono


a(x).E

(v valore)

a(v)

! E{v/x}

a val(e)

!E

a e.E

dove val(e) rappresenta il valore dellespressione e ed E{v/x} rappresenta il processo ottenuto


sostituendo le occorrenze libere di x in E con il valore v 1 . Si noti che lassioma per linput
permette un numero di possibili derivazioni per il processo a(x).E pari al numero di elementi dellinsieme dei valori. In particolare, se linsieme dei valori ha infiniti elementi, linput
introduce un infinite branching, cio una scelta tra infinite possibilit.
Le regole per la sincronizzazione e per il costrutto if sono
E

a v

! E0

a(v)

! F0

a(v)

! E0

E|F ! E 0 |F 0

a v

! F0

E|F ! E 0 |F 0

val(e) = true E ! E 0

val(e) = f alse

F ! F0

if e then E else F ! E 0

if e then E else F ! F 0

Come esempio descriviamo un distributore automatico che accetta una moneta da 20 centesimi
(o pi) ed ore una barretta di cioccolato
coin(x). if x

20 then choc.nil else nil

Vediamo come il distributore interagisce con un utente


coin(x). if x
if 50

20 then choc.nil else nil | coin 50.choc.nil

!
20 then choc.nil else nil | choc.nil

!
nil | nil

Ovviamente, cos com descritto, il distributore non d il resto e non restituisce la moneta
se questa inferiore a 20 centesimi (oltre al problema di funzionare per una volta sola). Si
osservi anche che ci siamo permessi di usare in modo promiscuo gli operatori per il passaggio
di valori e quelli senza passaggio di valori.
Diamo infine la semantica per le costanti di processo parametriche

E{val(e1 )/x1 , . . . , val(en )/xn } ! E 0

A(e1 , . . . , en ) ! E 0

(A(x1 , . . . , xn ) , E)

Vediamo ora un altro semplice esempio di processo che utilizza il passaggio di valori con
lo scopo di mostrare come esso possa essere simulato senza luso del passaggio di valori.
1

Si noti che il prefisso di input a(x). legante nel senso che nel processo a(x).E le occorrenze libere della
variabile x in E sono legate allinput a(x). Le definizioni di costanti di processo parametriche si comportano
in maniera simile, cio in A(x1 , . . . , xn ) , E le occorrenze libere delle variabili xi in E sono legate dalla
definizione.

221

10.10 Operatori che manipolano valori

Consideriamo il seguente processo forwarder che riceve un valore sul canale in e quindi lo
spedisce sul canale out
F , in(x). out(x). F
Le computazioni del processo risultano quindi essere della forma
F

in(v)

! out(v). F

out(v)

! F

Indichiamo con V linsieme dei valori che possono essere trasmessi. Per esprimere nel calcolo
senza passaggio di valori un processo che si comporta come F associamo a ogni canale a
del calcolo con value-passing tanti canali del calcolo senza value-passing quanti sono i valori
di V . In altre parole, ad ogni canale a del calcolo con value-passing associamo un insieme
{av | v 2 V } i cui elementi sono canali indicizzati dagli elementi di V . In questo modo, per
esempio, un processo della forma in(x). E corrisponde al processo
X
inv . E {v/x}.
v2V

Lazione P
in(v) corrisponde allazione inv e lazione out(v) corrisponde allazione outv . Loperatore
esprime la possibilit da parte del processo tradotto di scegliere uno qualunque
degli elementi di V . Ovviamente, se linsieme V dei valori infinito la scelta espressa da
una somma con infiniti termini per cui la traduzione che abbiamo eettuato ha senso se V
finito o se si ammettono le somme di infiniti termini.
Il processo risultante dalla traduzione di F il seguente
X
Fb ,
inv . outv . Fb
v2V

Vediamo ora come pu essere tradotto il costrutto if e then E else F in un calcolo senza
value-passing. Nella definizione della traduzione, non c un costrutto corrispondente a questo
operatore, piuttosto, la guardia e utilizzata per scomporre linsieme degli indici di ciascuna
delle somme risultanti dalla traduzione delle azioni di input in due insiemi: quello degli indici
che rendono vera e, e quello degli indici che la rendono falsa. Per esempio, se V linsieme
dei numeri naturali, il processo
in(x). if x > 0 then out(x
tradotto nel processo
(

inv .outv

1 .nil)

1).nil else out(0).nil


+ in0 .out0 .nil

v>0

Vediamo infine come tradurre le costanti di processo parametriche. A ciascuna costante


di processo sono associate tante costanti di processo del calcolo senza value-passing quante
sono le possibili combinazioni dei valori dei suoi parametri e, quindi, a ciascuna equazione
di definizione sar associato un insieme di equazioni di definizione, una per ogni costante.
Consideriamo per esempio la definizione A(x1 , . . . , xn ) , E. Alla costante A corrisponder
linsieme di costanti {Av1 ,...,vn | 1 i n : vi 2 V } e lequazione di definizione precedente
sar tradotta nel seguente insieme, eventualmente infinito, di equazioni
{Av1 ,...,vn , E{v1 /x1 , . . . , vn /xn } | 1 i n : vi 2 V }

222

Capitolo 10 Operatori per concorrenza e nondeterminismo

Altri operatori che subiscono modifiche nella traduzione sono la restrizione e il relabelling.
Nel primo caso, \L diventa \{v | 2 L, v 2 V } mentre [f ] diventa [f] dove, per definizione,
si pone f(v ) = f ()v .
Esempio 10.8. Facendo uso delle costanti di processo parametriche si pu definire un
processo Countdown(x) che esegue un conto alla rovescia a partire dal valore x:
Countdown(x) , if x > 0 then tick. Countdown(x

1) else beep. nil

Se applichiamo lo schema di traduzione che abbiamo delineato, al processo Countdown(3)


corrisponder il processo Countdown3 ed allequazione di definizione per la costante Countdown(x) corrisponder un insieme infinito contenente le seguenti equazioni di
definizione:
...
... ...
Countdown10 , tick.Countdown9
...
... ...
Countdown3
, tick.Countdown2
Countdown2
, tick.Countdown1
Countdown1
, tick.Countdown0
Countdown0
, beep. nil

Osservazione 10.9. Sono stati definiti in letteratura calcoli in cui i processi possono scambiarsi altri tipi di informazioni, quali ad esempio record di dati, processi (comunicazione
higher-order) o canali di comunicazione ( link mobility). Le teorie matematiche sviluppate
per questi calcoli sono basate su idee simili a quelle utilizzate per i calcoli di base ma sono
sensibilmente pi complicate. Per questo motivo tali calcoli di processo non saranno presi in
considerazione in queste note.

10.11

Esercizi

10.1 Si disegnino i grafi di transizione associati ai seguenti termini (i nil finali sono stati omessi):
a)
b)
c)
e)
f)
g)

a+a

a|a

(a.b | a
.c) \ a
a.b + a.c
a.b a.c
.a.b + .a.c

h)
i)
l)
m)
n)
o)

.a.b .a.c
a.b | a
.b
a.b ||| a
.b
rec x.a.b.x
rec x.(a + b).x
A|a
, dove A , a.b.A

10.2 Si scriva un termine che descriva un distributore automatico in grado di orire acqua o cioccolato
un numero illimitato di volte senza accettare monete fino a che non stato servito lutente
precedente. Si risolva lesercizio in tre modi: con loperatore di ricorsione, con la definizione di
costanti di processo e con loperatore di replicazione.
10.3 Si descriva il comportamento del termine D(0) dove D una costante di processo parametrica
definita nel modo seguente

223

10.11 Esercizi

D(q)

change (q).D(0)
+ if(q < 40) then coin(x). D(x + q) else nil
+ if(q 40)
then chock. change (q 40). D(0)
else if(q 20) then water. change (q 20). D(0) else nil

dove change lazione di dare il resto.

Capitolo 11

Equivalenze comportamentali e
preordini di ranamento

SOMMARIO
Questo capitolo presenta diversi criteri per confrontare sistemi di transizioni etichettate.
Alcuni di questi criteri costituiscono delle relazioni di equivalenza sullinsieme dei sistemi di
transizioni, altri invece costituiscono dei preordini su tale insieme. In particolare introdurremo lequivalenza a tracce, la bisimilarit e lequivalenza testing. Di ciascuna di esse daremo
una versione forte che considera le azioni invisibili alla stessa stregua delle altre azioni ed
una versione debole che tratta le azioni invisibili in maniera speciale. Presenteremo inoltre
alcune varianti, quali lequivalenza a tracce complete, la doppia simulazione e la bisimilarit
di branching. Concluderemo esaminando il comportamento delle relazioni introdotte nei
confronti della divergenza e la gerarchie a cui danno origine.

11.1

Osservatori, equivalenze e preordini

Come detto nellintroduzione, stabilire se due processi sono equivalenti interessante ed utile
sia al fine di assegnare una semantica formale ai processi sia al fine di dimostrare che limplementazione di un sistema (come realizzato) corretta rispetto ad una data specifica (cosa
gli si chiede di fare), quando implementazione e specifica sono entrambe espresse utilizzando
lo stesso formalismo.
La nozione di equivalenza da utilizzare dipende fondamentalmente dalluso previsto per
i sistemi in considerazione. In eetti, il tipo di uso di un sistema determina gli aspetti
comportamentali che devono essere presi in considerazione e quelli che possono essere ignorati.
Perci, per ciascuna equivalenza, importante conoscere le propriet dei sistemi che essa
preserva. Non quindi sorprendente che in letteratura siano state proposte molte teorie di
equivalenza per via dei molti aspetti di un sistema concorrente che potrebbe valere la pena di
considerare.
Le equivalenze che vedremo sono tutte basate sullidea che due processi sono equivalenti
se nessun osservatore (utente) esterno li pu distinguere, cio se i due processi hanno lo stesso
insieme di osservazioni. Le semantiche indotte da questo tipo di equivalenze sono anche dette
osservazionali. Ci che interessa, infatti, non la struttura interna di un processo, ma il
suo comportamento in relazione allambiente esterno. Pertanto, unequivalenza ragionevole
tra processi non pu essere basata sulluguaglianza delle loro semantiche operazionali, cio

226

Capitolo 11 Equivalenze comportamentali e preordini di ranamento

dei corrispondenti LTS, perch risulterebbe eccessivamente discriminante in quanto considererebbe dettagli dei processi, quali la struttura, non osservabili dallesterno. Perci, bisogna
definire dei meccanismi di astrazione che, a partire dalla semantica operazionale, cio dagli
LTS, permettano di ignorare dettagli ritenuti irrilevanti.
Non c per ancora completo accordo su quale sia la nozione corretta di osservazione e
su come gli esiti di unosservazione debbano essere usati per distinguere o identificare sistemi.
Per questo, in letteratura sono state definite molte equivalenze osservazionali, ciascuna basata
su una specifica e ragionevole nozione di osservabile. Difatti, esiste unintera gamma di equivalenze che possono essere organizzate in una gerarchia che va dallequivalenza pi restrittiva,
che lisomorfismo tra i grafi di transizione degli LTS, a quella pi debole, che lequivalenza
a tracce. Va tenuto conto che ci che dierenzia le equivalenze osservazionali il modo in cui
esse trattano il nondeterminismo. Infatti, se si considerano solo LTS deterministici, tutte le
equivalenze coincidono.
Le equivalenze che considereremo possono essere raggruppate in due grandi categorie: le
equivalenze forti che considerano lazione interna alla stessa stregua delle altre azioni e le
equivalenze deboli che invece trattano lazione interna in maniera speciale, nel senso che la
considerano non osservabile e, ad esempio, astraggono dal fatto che un processo la possa
eettuare o no.
Quanto detto relativamente alle equivalenze comportamentali, si applica anche ai preordini
di ranamento. Questi sono relazioni di (pre)ordinamento e quindi si prestano in maniera
naturale a descrivere le relazioni tra descrizioni di uno stesso sistema a vari livelli di astrazione.
Infatti, le equivalenze talvolta impongono restrizioni troppo severe ed in particolare richiedono
che i comportamenti di un sistema a vari livelli di astrazione siano identici. I preordini di
ranamento costituiscono quindi unalternativa ragionevole alle relazioni di equivalenza.
I calcoli di processo utilizzano spesso le nozioni di congruenza e precongruenza (introdotte
in Sezione 2.5) comportamentale sia per lanalisi dei sistemi che per sviluppare una metodologia di stepwise-development che permette di passare dalla specifica allimplementazione
di un sistema complesso eettuando una serie di sostituzioni di componenti con altre componenti equivalenti o pi ranate. Per, mentre equivalenze comportamentali e preordini
di ranamento possono essere definiti direttamente sugli LTS in maniera indipendente dagli
operatori di uno specifico calcolo di processi, non altrettanto possiamo fare per congruenze e
precongruenze. Come abbiamo visto, infatti, una congruenza una relazione di equivalenza
che soddisfa anche la propriet di sostituzione: sistemi equivalenti possono essere usati in
modo intercambiabile allinterno di sistemi pi grandi. Pi formalmente, un contesto c[ ] lo
si pu definire come una descrizione di un processo con un buco, [ ], eettuata usando gli
operatori di un determinato linguaggio. Dato un processo E scritto nello stesso linguaggio,
c[E] rappresenta il processo ottenuto riempiendo il buco con E. Unequivalenza t una congruenza per il linguaggio in considerazione se da E t F , deriva c[E] t c[F ] per ogni contesto
c[ ] costruito usando gli operatori del linguaggio. Il problema di determinare se le equivalenze
ed i preordini introdotti in questo capitolo sono rispettivamente congruenze e precongruenze
sar arontato nel Capitolo 12 relativamente allo specifico calcolo di processi CCS.
In questo capitolo introdurremo alcune semantiche osservazionali che permettono di confrontare stati di un LTS. Le definizioni delle semantiche quindi saranno date senza fare riferimento ad un insieme specifico di operatori. Nel capitolo successivo vedremo che tali definizioni
si possono riportare senza alcuna modifica in un calcolo di processi specifico come CCS. Ci
reso possibile dal fatto che lo stesso calcolo pu essere visto come un unico LTS, dove gli

227

11.2 Relazioni forti


q

r
a

a
q1

p1
b
p2
c

p3

p4

q2

q3

c
q5

r2

r1

b
r4

d
q4

r3

d
r6

r5

Figura 11.1: Tre LTS con cui evidenziare le dierenze tra equivalenza a tracce, equivalenza
testing e bisimilarit forte
stati corrispondono ai processi CCS.
Definiremo le semantiche osservazionali come relazioni tra stati di uno stesso LTS, piuttosto che tra stati di due LTS diversi, questo perch a volte ci servir confrontare stati di uno
stesso LTS. Ovviamente, le definizioni si applicano facilmente a stati di due LTS in quanto
lunione disgiunta di due LTS ancora un LTS.

11.2

Relazioni forti

In questa sezione introdurremo alcune relazioni tra stati di LTS che trattano le azioni degli
LTS tutte allo stesso modo, senza distinguere tra azioni esterne, ossia visibili, ed azioni interne.
Pertanto, tali relazioni saranno definite su un LTS hQ, A, ! i generico il cui insieme di azioni
A non contiene azioni trattate in modo speciale.
Cominceremo con lintrodurre le seguenti tre equivalenze: a tracce, bisimilarit e testing.
Esse ci forniranno dei criteri che ci permetteranno di eguagliare e/o distinguere, ad esempio,
gli stati p, q ed r degli LTS della Figura 11.1. Vedremo infatti che i tre stati sono indistinguibili per lequivalenza a tracce, in quanto tutti in grado di eseguire le stesse sequenze di
azioni, mentre sono distinti per la bisimilarit che basata su un gioco di sfide reciproche
in cui i sistemi procedono sfidandosi a vicenda sulla capacit di eseguire una determinata
azione; lequivalenza testing, invece, che considera le capacit di interazione e le potenzialit
di deadlock dei sistemi, eguaglia q ed r e li dierenzia da p.
Concluderemo con la definizione di alcuni preordini di ranamento e con lintroduzione di altre equivalenze (tracce complete e doppia simulazione) ottenute come varianti delle
equivalenze viste.

11.2.1

Equivalenza basata sulle tracce

Nella teoria dei linguaggi formali, esiste una ben precisa nozione di equivalenza per gli automi
a stati finiti. Si tratta dellequivalenza dei linguaggi accettati che stabilisce che due automi
sono in relazione tra loro se accettano le stesse sequenze di simboli (si veda Sezione 3.4). Nel
Capitolo 3 abbiamo visto che, dierentemente dagli automi, gli LTS non contengono stati

228

Capitolo 11 Equivalenze comportamentali e preordini di ranamento

di accettazione, quindi lequivalenza dei linguaggi accettati non pu essere applicata direttamente. Tuttavia, se supponiamo che ogni stato di un LTS uno stato di accettazione,
allora il linguaggio accettato da un LTS formato dalle sequenze di etichette, dette tracce,
di tutte le sequenze di transizioni che pu eseguire. Quindi, nel caso dellequivalenza a tracce, unosservazione di un processo una sequenza finita di azioni eseguita dal processo in
successione.
Definizione 11.1 (Traccia). Siano hQ, A, ! i un LTS, q 2 Q e s 2 A . La sequenza s
s
una traccia di q se esiste q 0 2 Q tale che q ! q 0 . Denoteremo con T (q) linsieme di tutte le
tracce di q.
Definizione 11.2 (Equivalenza a tracce). Siano hQ, A, ! i un LTS, p 2 Q e q 2 Q. Gli
stati p e q sono detti equivalenti a tracce, scritto p =T q, se T (p) = T (q).
Si pu notare che nelle definizioni precedenti non c distinzione tra azioni interne ed esterne;
tutte possono apparire in una traccia e sono trattate allo stesso modo.
Sebbene semplice da definire, lequivalenza a tracce =T risulta essere inadeguata per LTS
non deterministici, in cui cio esiste perlomeno uno stato che ha due transizioni etichettate
con la stessa etichetta verso stati dierenti tra loro, com illustrato dal seguente esempio.
Esempio 11.3. [Macchina distributrice di t e ca] Consideriamo una macchina
distributrice di t e ca il cui grafo delle transizioni sia il seguente:

20
20

tea

p0
cof f ee

A partire dallo stato p0 , dopo aver inserito 20, si pu ottenere un t oppure si possono inserire
altri 20 e quindi ottenere un ca; e cos via. Consideriamo ora una variante della macchina
il cui grafo delle transizioni sia il seguente:

20

tea

q0
cof f ee
20

20

Linsieme delle tracce a partire dagli stati p0 e q0 lo stesso; precisamente linsieme di


sequenze generate dalla seguente espressione regolare

229

11.2 Relazioni forti

(20 (tea + 20 cof f ee))

o equivalentemente, per via della distributivit, dallespressione regolare


(20 tea + 20 20 cof f ee) .

Malgrado il fatto che i due stati p0 e q0 siano equivalenti a tracce, chiaro che essi, e quindi
le macchine corrispondenti, non sono equivalenti per un utente esterno. Questo perch la
seconda macchina non deterministica: dopo che ha ricevuto 20, si pu trovare in uno stato
in cui solo possibile emettere tea (e non pu pi ricevere 20), oppure pu essere in uno
stato in cui pu solo accettare 20 (e non pu emettere tea) per emettere cof f ee. chiaro
che un utente non sar contento di avere a che fare con una macchina che si comporta in
questo modo dal momento che lutente non avrebbe alcuna garanzia di ottenere la bevanda
eettivamente desiderata.
Il problema sta quindi nel considerare equivalenti una macchina deterministica e una non
deterministica e, quindi, meno adabile.
In conclusione, se siamo interessati al comportamento interattivo degli LTS, allora un LTS
non deterministico non pu essere considerato equivalente ad uno deterministico. Il problema
con lequivalenza a tracce e gli LTS non deterministici che, anche quando due stati hanno
le stesse tracce, durante lesecuzione delle stesse si possono incontrare stati non equivalenti,
ossia stati con tracce diverse (come si vede nel caso degli LTS dellesempio precedente). Ci
non succede per gli LTS deterministici.
Considerando sistemi che interagiscono con lambiente esterno, diventa importante sapere, ad esempio, se certe interazioni avranno sempre luogo, oppure se esiste la possibilit di
raggiungere uno stato di deadlock , cio uno stato da cui non possibile eettuare azioni.
Il comportamento riguardo al deadlock in eetti unaltra propriet dei sistemi concorrenti
che non catturabile soddisfacentemente dallequivalenza a tracce, come mostra il seguente
esempio.
Esempio 11.4. Si vede facilmente che gli stati p0 e q0 dei due LTS
q3
a

p0

p1

p2

q0
a

q1

q2

sono in relazione =T , per p0 pu sempre eseguire lazione visibile b dopo aver eettuato
lazione a, mentre q0 dopo aver eettuato lazione a pu raggiungere uno stato in cui non
possibile eettuare alcuna azione.
Esempio 11.5. Consideriamo lesempio dei tre LTS della Figura 11.1 di pagina 227. facile
vedere che tutti e tre gli LTS hanno il seguente insieme di tracce a partire, rispettivamente,
dagli stati p, q ed r:
{, a, ab, abc, abd}
Pertanto, si ha p =T q =T r, come gi anticipato.

230

11.2.2

Capitolo 11 Equivalenze comportamentali e preordini di ranamento

Bisimilarit forte

Le considerazioni della sezione precedente ci suggeriscono un modo per arricchire le osservazioni fatte sul comportamento degli LTS non deterministici: le sequenze di esecuzione dovrebbero
attraversare stati equivalenti. Il forte potere discriminante delle relazioni ottenute in questo
modo dovuto proprio a questo loro carattere ricorsivo. In pratica, rispetto alla semantica
a tracce, nel caso della bisimilarit forte losservatore esterno, in qualsiasi momento durante
una computazione del sistema osservato, pu eettuare quante copie1 vuole del sistema nel
suo stato corrente ed osservarle indipendentemente in modo da osservare tutte le possibili
computazioni a partire da quello stato. Quindi, il risultato di unosservazione ora un albero
anzicch una traccia.
Definizione 11.6 (Bisimulazione forte). Sia hQ, A, ! i un LTS. Una relazione R QQ
una bisimulazione forte se, dati p e q tali che hp, qi 2 R, le seguenti condizioni sono soddisfatte:
a

1. per ogni a 2 A e p0 2 Q, se p ! p0 allora q ! q 0 per qualche q 0 2 Q tale che hp0 , q 0 i 2 R;


2. per ogni a 2 A e q 0 2 Q, se q ! q 0 allora p ! p0 per qualche p0 2 Q tale che hp0 , q 0 i 2 R.

Intuitivamente, se due stati sono in relazione di bisimulazione forte, possibile per ognuno
dei due simulare il comportamento dellaltro: da qui il termine bisimulazione. Pi specificamente, perch una relazione sia una bisimulazione forte, gli stati in relazione fra loro devono
essere in grado di eseguire le stesse transizioni, muovendosi verso stati che sono ancora in
relazione fra loro. In pratica, ci significa che una bisimulazione forte una relazione chiusa
per transizioni. Diremo che due stati sono equivalenti secondo la bisimulazione forte, o che
sono bisimili, se esiste una bisimulazione forte fra di loro.
Definizione 11.7 (Bisimilarit). Sia hQ, A, ! i un LTS. Due stati p, q 2 Q sono fortemente
bisimili, scritto p q, se esiste una bisimulazione forte R che contiene hp, qi.

In pratica, la relazione , detta anche bisimilarit forte, lunione di tutte le possibili


bisimulazioni. Cio, formalmente, abbiamo
[
,
{R | R una bisimulazione forte }
Esempio 11.8. Consideriamo i due LTS seguenti.
q1

q3

p2

q0

p0
a

p1
c

q2

q4

p3

Gli stati p0 e q0 non sono fortemente bisimili. Se lo fossero anche gli stati p1 e q1 , in cui p0 e
q0 si trasformano dopo aver eettuato una transizione etichettata con a, dovrebbero esserlo,
ma non c alcuna bisimulazione forte R che contiene la coppia hp1 , q1 i. Infatti, la transizione
di p1 etichettata c non pu essere simulata da q1 che non in grado di eettuare transizioni
etichettate c.
1
In realt questa solo unapprossimazione del reale potere di osservazione richiesto, che va sotto il nome
di global testing e che non esploreremo oltre.

231

11.2 Relazioni forti

Un ragionamento simile a quello dellesempio precedente ci permette di distinguere i due


LTS dellEsempio 11.3 (macchina distributrice di t e ca).
Esempio 11.9. Consideriamo di nuovo lesempio dei tre LTS della Figura 11.1 di pagina
227. facile vedere che gli stati q e r non sono fortemente bisimili. Infatti, se fossero bisimili,
altrettanto dovrebbero essere q1 ed r1 , dal momento che la transizione da r in r1 etichettata
a non pu essere simulata da q che con la transizione in q1 . Per, la transizione di q1 in q2
etichettata b non pu essere simulata dallunica transizione di r1 in r3 dal momento che gli
stati q2 ed r3 non possono essere bisimili in quanto hanno transizioni etichettate diversamente.
Con ragionamenti simili, si pu dimostrare che gli stati p e q non sono fortemente bisimili.
Infatti, se lo fossero, anche p1 e q1 dovrebbero esserlo e quindi anche q2 e p2 , dal momento
che la transizione da q1 a q2 etichettata b non pu che essere simulata dalla transizione da p1
a p2 . chiaro per che gli stati p2 e q2 non sono bisimili perch q2 non in grado di simulare
la transizione di p2 etichetta d.
In maniera analoga si prova che p ed r non sono fortemente bisimili.

Esempio 11.10. Si noti che abbiamo


b
a
a

a
b

mentre i due LTS hanno ovviamente grafi di transizione non isomorfi.

Esempio 11.11. Vediamo ora un esempio pi articolato. Consideriamo i due LTS seguenti.
p1

q1

a
b

p0

q0

a
b

p2

q2

Si ha p0 q0 . Per dimostrarlo, suciente dimostrare che la relazione


R , {hp0 , q0 i, hp0 , q2 i, hp1 , q1 i, hp2 , q1 i}
una bisimulazione forte. Possiamo anche rappresentare graficamente la relazione R direttamente sugli LTS mettendo in corrispondenza tra loro gli stati fortemente bisimili. Nella figura
sottostante, tale corrispondenza evidenziata tramite le linee tratteggiate

232

Capitolo 11 Equivalenze comportamentali e preordini di ranamento


p1

q1

a
b

p0

q0

a
b

p2

q2

Le bisimulazioni e la bisimilarit hanno diverse propriet interessanti. Dimostriamo dapprima che la propriet di essere una bisimulazione forte preservata da alcune operazioni sulle
relazioni (si rivedano eventualmente le definizioni di inversa e di composizione di relazioni
binarie viste nella Sezione 2.2).
Proposizione 11.12. Si assuma che ogni Si , con i 2 I, sia una bisimulazione forte e che Id
sia la funzione identit su Q. Allora le seguenti relazioni sono bisimulazioni forti.
1. Id
2. Si

3. S1 S2
4. [i2I Si
Dimostrazione. Dimostreremo solo la 3, le altre sono altrettanto semplici. Supponiamo duna
que che hp, ri 2 S1 S2 . Supponiamo inoltre che p ! p0 e facciamo vedere che ci implica che,
a
per qualche r0 , r ! r0 e hp0 , r0 i 2 S1 S2 .
Per definizione di composizione tra relazioni binarie, per qualche q, si ha che
hp, qi 2 S1

hq, ri 2 S2

Allora, dal momento che hp, qi 2 S1 che una bisimulazione, per qualche q 0 abbiamo che
a

q ! q0

hp0 , q 0 i 2 S1

Inoltre, poich hq, ri 2 S2 che una bisimulazione, per qualche r0 si ha che


a

r ! r0

hq 0 , r0 i 2 S2

Da ci segue anche che (p0 , r0 ) 2 S1 S2 . In modo del tutto simile si dimostra che se supponiamo
a
a
che r ! r0 , allora possiamo trovare un p0 tale che p ! p0 e hp0 , r0 i 2 S1 S2 .
Dimostriamo ora che la bisimilarit la pi grande tra le bisimulazioni e che una
equivalenza.
Proposizione 11.13.
1. la pi grande bisimulazione forte;
2. una relazione di equivalenza.
Dimostrazione. Dimostriamo i due asserti separatamente.

233

11.2 Relazioni forti

1. Dalla Proposizione 11.12(4) si vede che lunione di bisimulazioni forti ancora una
bisimulazione forte: dunque, anche lo e include tutte le altre bisimulazioni.
2. Per dimostrare che una relazione di equivalenza, cio che riflessiva, simmetrica e
transitiva, ragioniamo come segue.
Riflessivit. Dalla Proposizione 11.12(1) segue che 8p 2 Q p p.
Simmetria. Se p q allora hp, qi 2 S per qualche bisimulazione forte S. Allora
hq, pi 2 S 1 e, per la Proposizione 11.12(2), S 1 una bisimulazione forte; quindi
q p.
Transitivit. Se p q e q r allora hp, qi 2 S1 e hq, ri 2 S2 per qualche bisimulazione
forte S1 ed S2 . Dunque hp, ri 2 S1 S2 e quindi p r per la Proposizione 11.12(3).
Infine, dimostriamo una propriet di che nel seguito sar talvolta usata al posto della
sua definizione per dimostrare che due stati sono fortemente bisimili.
Proposizione 11.14. Siano hQ, A, ! i un LTS, p, q 2 Q. Si ha p q se e solo se 8a 2 A
a

allora

9q 0 2 Q : q ! q 0

allora

9p0 2 Q : p ! p0

i) 8p0 2 Q : p ! p0
ii) 8q 0 2 Q : q ! q 0

p0 q 0 ;

p0 q 0 .

Dimostrazione. Definiamo dapprima una nuova relazione, 0 in termini di nel modo


seguente
p 0 q se per ogni a 2 A risulta:
a

1. 8p 2 Q : p ! p0
a

2. 8q 2 Q : q ! q 0

allora 9q 0 2 Q : q ! q 0
a

allora 9p0 2 Q : p ! p0

^
^

p0 q 0 ;
p0 q 0 .

Dalla Proposizione 11.13(1), sappiamo che una bisimulazione forte; dalle definizioni di
bisimulazione forte e di 0 , possiamo allora dedurre che
p q

implica p 0 q

(11.1)

Rimane da dimostrare il viceversa, cio che p 0 q implica p q. Per questo, suciente


dimostrare che la relazione 0 una bisimulazione forte. Procediamo come segue. Sia p 0 q
a
a
e p ! p0 . Dobbiamo trovare un q 0 tale che q ! q 0 e p0 0 q 0 . Per la definizione di 0 possiamo
a
trovare un q 0 tale che q ! q 0 e p0 q 0 . Da (11.2) segue allora che p0 0 q 0 , e con questo si
conclude la prova.
Come abbiamo visto negli esempi, la bisimulazione forte provvista di una tecnica di
prova piuttosto ecace: per dimostrare che due stati sono bisimili suciente trovare una
bisimulazione forte che contiene la coppia formata dai due stati. Tuttavia, ci non sempre
agevole poich tale relazione pu avere un numero elevato di elementi.
Esempio 11.15. Definiamo un semplice semaforo binario come segue:
Sem , get.put.Sem

234

Capitolo 11 Equivalenze comportamentali e preordini di ranamento

dove get e put corrispondono alle tipiche operazioni P e V sui semafori originariamente usate
da Dijkstra. Un tale semaforo quindi una risorsa che pu essere alternativamente acquisita
e rilasciata.
Definiamo ora un semaforo pi generale, cio un semaforo n-ario (con n 1), che ammette
una qualsiasi sequenza di get e put purch il numero di get meno il numero di put rimanga
nellintervallo tra 0 e n, estremi inclusi.
Semn (0) , get.Semn (1)
Semn (k) , get.Semn (k + 1) + put.Semn (k
Semn (n) , put.Semn (n 1)

1)

(0 < k < n)

Indichiamo ora con Sem(n) la composizione parallela di n semafori binari, cio


Sem(n) , Sem | Sem | . . . | Sem
Intuitivamente, ogni get su Sem(n) acquisisce uno qualsiasi dei semafori binari liberi che
compongono Sem(n) . Ci aspettiamo cos di poter dimostrare che
Semn (0) Sem(n)
Per esempio, consideriamo il caso n = 2, e dimostriamo che Sem2 (0) Sem(2) . A tale scopo, suciente trovare una bisimulazione forte R che contenga la coppia hSem2 (0), Sem(2) i.
In eetti, consideriamo la seguente relazione
R , {hSem2 (0), Sem | Semi, hSem2 (1), Sem0 | Semi,
hSem2 (1), Sem | Sem0 i, hSem2 (2), Sem0 | Sem0 i}
dove Sem0 , put.Sem. Si noti che la seconda e la terza coppia hanno la stessa prima componente, mentre le seconde componenti sono chiaramente fortemente bisimili, dal momento che
la composizione parallela commutativa. Perci, una delle due coppie ridondante. Lidea
quindi che potremmo cercare un modo di evitare di dover eplicitamente considerare tutti gli
elementi di una bisimulazione che sono identici up to (a meno di) bisimilarit forte. Nellesempio precedente il risparmio minimo (una sola coppia), ma se consideriamo per esempio
il caso n = 3 abbiamo che nella bisimulazione
R , {hSem3 (0), Sem | Sem | Semi,
hSem3 (1), Sem0 | Sem | Semi, hSem3 (1), Sem | Sem0 | Semi, hSem3 (1), Sem | Sem | Sem0 i,
hSem3 (2), Sem0 | Sem0 | Semi, hSem3 (2), Sem | Sem0 | Sem0 i, hSem3 (2), Sem0 | Sem | Sem0 i,
hSem3 (3), Sem0 | Sem0 | Sem0 i}

ci sono ben quattro coppie su otto che sono ridondanti! Le definizioni e le proposizioni che
seguono formalizzano tale idea.
Introduciamo allora la nozione di bisimulazione forte up to che ci permetter di rendere
pi eciente la tecnica di prova della bisimulazione forte. Ricordiamo che se R una relazione
binaria tra stati, la notazione R indica la composizione delle relazioni binarie e R e
poi di nuovo ; pi specificamente, p R q significa che per qualche p0 e q 0 abbiamo che
p p0 , p0 Rq 0 , q 0 q.

235

11.2 Relazioni forti

Definizione 11.16 (Bisimulazione forte up to ). Sia hQ, A, ! i un LTS. Una relazione


R Q Q una bisimulazione forte up to se, dati p e q tali che hp, qi 2 R, le seguenti
condizioni sono soddisfatte
a

1. per ogni a 2 A e p0 2 Q, se p ! p0 allora q ! q 0 per qualche q 0 2 Q tale che hp0 , q 0 i 2


R ;
2. per ogni a 2 A e q 0 2 Q, se q ! q 0 allora p ! p0 per qualche p0 2 Q tale che hp0 , q 0 i 2
R .
Lutilit della nozione di bisimulazione forte up to deriva dal fatto che per stabilire se
p q suciente trovare una qualche bisimulazione forte up to che contenga la coppia
hp, qi; ci quanto asserito dalle seguenti proposizioni.
Proposizione 11.17. Se R una bisimulazione forte up to allora R una
bisimulazione forte.
Dimostrazione. Supponiamo che p R q. Per simmetria, sar suciente dimostrare che
a
a
se p ! p0 allora q ! q 0 e p0 R q 0 . Poich per ipotesi p R q, dalla definizione di
bisimulazione forte up to segue che per qualche p1 e q1 abbiamo che p p1 Rq1 q. Ora,
a
a
da p p1 e p ! p0 segue che, per qualche p01 , p1 ! p01 con p0 p01 . Dallipotesi che R una
a
a
bisimulazione forte up to , da p1 Rq1 e p1 ! p01 , segue che q1 ! q10 e p01 R q10 . Infine,
a
a
da q1 q e q1 ! q10 segue che, per qualche q 0 , q ! q 0 e q10 q 0 . Concludendo, abbiamo che
a
q ! q 0 e p0 p01 R q10 q 0 , e, quindi, la tesi.
Proposizione 11.18. Se R una bisimulazione forte up to allora R .
Dimostrazione. Per la Proposizione 11.12(1), Id ; dunque Id R Id = R R .
Per la proposizione precedente, R una bisimulazione forte, quindi, per la
Proposizione 11.13(1), abbiamo R , e la tesi segue per transitivit.
Concludiamo largomento con alcune osservazioni. Si pu dimostrare che sistemi fortemente bisimili hanno lo stesso comportamento da un punto di vista del deadlock, cio lo
stesso potenziale di deadlock; nella Sezione 13.4, definiremo una particolare logica modale,
chiamata Hennessy-Milner Logic (HML), che permette la formulazione di semplici propriet
dei sistemi, e la useremo per rendere precisa questa aermazione. Inoltre, ha algoritmi di
verifica molto ecienti che lavorano in tempo polinomiale rispetto alle dimensioni del LTS da
verificare. Nel prossimo capitolo, dimostreremo che una congruenza per il CCS.

11.2.3

Equivalenze basate su testing

Sebbene sistemi fortemente bisimili abbiano lo stesso potenziale di deadlock, il contrario non
vero, cio, in generale, sistemi aventi lo stesso comportamento riguardo al deadlock possono
non essere bisimili. Si pu quindi dire che la bisimilarit forte eccessivamente sensibile alle
dierenze non osservabili della struttura ramificata (branching) dei sistemi. Ci testimoniato
dal fatto che gli stati q e r dellesempio di Figura 11.1 non sono bisimili. Sostanzialmente
ci succede perch r non sempre in grado, dopo aver fatto a, di eettuare la sequenza b c,
mentre q lo . Tuttavia, non sarebbe necessario doverli distinguere, perch per entrambi la
scelta tra le azioni c e d nondeterministica, cio non controllabile, mentre il potenziale di

236

Capitolo 11 Equivalenze comportamentali e preordini di ranamento

deadlock lo stesso. La dierenza tra i due LTS risiede nel momento in cui la scelta viene
fatta. Ci si riflette sulla diversa struttura branching dei due LTS ma non di interesse
da parte di un osservatore esterno che pu solo interagire con gli LTS (quindi, controllare il
comportamento riguardo il deadlock) e non pu invece osservarne la struttura interna.
In questa sezione, definiremo una equivalenza che tiene conto di queste considerazioni (e
quindi eguaglia gli stati q ed r). A questo scopo utilizzeremo lapproccio testing che basato
su una nozione esplicita di osservatore che esegue dei test sui sistemi sotto osservazione e ne
esamina lesito. In questo scenario, risulta importante non soltanto sapere se, dato un particolare test, un processo risponde positivamente oppure no, ma anche se il processo risponde
in maniera consistente ogni volta che il test viene eseguito. Pi specificamente, possiamo
pensare ad un insieme di sistemi e ad un insieme di test; due sistemi saranno equivalenti
(rispetto a questo insieme di test) se superano esattamente gli stessi test. Questa naturale
equivalenza pu essere espressa tramite altre due equivalenze tra sistemi: la prima formulata
in termini dellabilit di rispondere positivamente ad un particolare test, la seconda in termini
dellincapacit di non rispondere positivamente ad un particolare test; nellultimo caso vedremo come un processo p sia equivalente ad un processo q se, per ogni test a cui p risponde
positivamente, anche q risponde positivamente, e viceversa. Attraverso la congiunzione di
queste due equivalenze se ne otterr una terza.
Supponiamo di dover confrontare LTS le cui azioni appartengono ad uno stesso insieme A
(dati degli LTS qualsiasi, semplice ricondursi a questa situazione, basta prendere lunione
degli insiemi di azioni degli LTS in considerazione). Un osservatore un LTS il cui insieme
di azioni Aw , A [ {w}, con w 62 A; in pratica, un osservatore esegue dei test su un LTS ed
eettua lazione visibile w quando il LTS sotto esame passa con successo un test. Nel seguito,
indichiamo con O linsieme degli osservatori. Per determinare se uno stato q soddisfa o no un
osservatore o si considera linsieme Comp(q, o) delle computazioni dalla configurazione iniziale
hq, oi e si determina lesito di ogni computazione c.
Definizione 11.19 (Computazione). Dati due LTS hQ, A, ! i e hO, Aw , ! i e presi due
stati q 2 Q e o 2 O, una computazione c dalla configurazione iniziale hq, oi una sequenza
di configurazioni hqi , oi i, con i 0, cio di coppie di stati, tale che
1. hq0 , o0 i coincide con hq, oi;

2. tra due configurazioni consecutive, diciamo hqi , oi i e hqi+1 , oi+1 i, si pu derivare una
a
transizione hqi , oi i ! hqi+1 , oi+1 i usando la seguente regola dinferenza
a

E ! E0

F ! F0

hE, F i ! hE 0 , F 0 i

a2A

3. se la sequenza finita allora lultimo elemento, diciamo hqk , ok i, tale che per nessun
a 2 A e per nessuna configurazione hq 0 , o0 i, con q 0 2 Q e o0 2 O, sia possibile derivare
a
una transizione hqk , ok i ! hq 0 , o0 i usando la regola precedente.

Indichiamo con Comp(q, o) linsieme di tutte le computazioni dalla configurazione iniziale


hq, oi.

Definizione 11.20 (Esito di una computazione).


Una computazione c 2 Comp(q, o) ha successo se esiste una configurazione hqn , on i 2 c, con
w
n 0, tale che on ! .

11.2 Relazioni forti

237

Definizione 11.21 (Soddisfacimento di un osservatore).


i) q may satisfy o se esiste una computazione c 2 Comp(q, o) che ha successo;
ii) q must satisfy o se ogni computazione c 2 Comp(q, o) ha successo.
A questo punto possiamo introdurre lequivalenza may e lequivalenza must.
Definizione 11.22 (Equivalenze may e must).
may: Dati p, q 2 Q diremo che p equivalente may a q, scritto p 'm q, se per ogni o 2 O si
ha p may satisfy o se e solo se q may satisfy o;
must: Dati p, q 2 Q diremo che p equivalente must a q, scritto p 'M q se per ogni o 2 O
si ha p must satisfy o se e solo se q must satisfy o.
Possiamo ora definire lequivalenza di testing in termini delle due appena introdotte.
Definizione 11.23 (Equivalenza testing). Dati p, q 2 Q diremo che p equivalente testing
a q, scritto p 'test q, se p 'm q e p 'M q.
Esempio 11.24. Consideriamo lesempio della Figura 11.1. facile dimostrare che gli stati
p e q non sono must equivalenti (e quindi neanche test equivalenti). A tale scopo suciente
trovare un osservatore che li distingue. Un tale osservatore il processo o , a.b.c.w. Infatti
si ha p must satisfy o, ma q must satisfy o non vale dato che esiste una computazione da
q | o che porta nello stato d | c.w.
Dicile invece risulta dimostrare la must equivalenza di q e r dato che linsieme degli
osservatori da considerare infinito. Stesso discorso vale per la dimostrazione che tutti e tre
gli stati sono may equivalenti. Nella sezione successiva definiremo delle tecniche di prova alternative per le varianti deboli delle equivalenze testing; tecniche simili possono essere definite
per le equivalenze introdotte in questa sezione.
Concludendo, le equivalenze definite seguendo lapproccio basato sul testing sono dicili
da verificare. Infatti, risulta relativamente semplice dimostrare che due LTS non sono in
una certa relazione (basta trovare un controesempio), mentre diventa assai pi complicato, o
comunque lungo e tedioso, verificare che due LTS sono in relazione (bisogna infatti prendere
in considerazione tutti i possibili osservatori e le risultanti osservazioni).

11.2.4

Preordini di ranamento

In questa sezione introdurremo alcuni preordini di ranamento e studieremo le relazioni tra


i loro nuclei e le equivalenze viste finora.
Preordine basato sulle tracce
Il primo preordine definito in termini della relazione di contenimento tra insiemi di tracce.
Definizione 11.25 (Preordine basato sulle tracce). Siano hQ, A, ! i un LTS, p, q 2 Q. Si
dice che p minore rispetto alle tracce di q, scritto p vT q, se T (p) T (q).

238

Capitolo 11 Equivalenze comportamentali e preordini di ranamento

Chiaramente, bisogna dimostrare che la relazione vT un preordine.


Proposizione 11.26. vT un preordine.
Dimostrazione. Bisogna far vedere che vT riflessiva e transitiva. Per la riflessivit si tratta
di dimostrare che T (q) vT T (q) per ogni q 2 Q, e ci segue dal fatto che T (q) T (q) (cio dal
fatto che la relazione tra insiemi riflessiva). Per la transitivit si tratta di dimostrare che
T (p) vT T (q) e T (q) vT T (r) implicano T (p) vT T (r), e ci segue dal fatto che la relazione
transitiva.
immediato verificare che il nucleo (si veda la Definizione 2.5) del preordine appena definito
coincide con lequivalenza a tracce.
Proposizione 11.27. Siano hQ, A, ! i un LTS, p, q 2 Q. Si ha p =T q se e solo se p vT q
e q vT p.
Preordine di simulazione
Informalmente, dire che q simula p, o che p simulato da q, significa che il modello di
comportamento di q almeno altrettanto ricco quanto quello di p. La definizione formale di
tale relazione la seguente.
Definizione 11.28. Sia hQ, A, ! i un LTS. Una relazione R Q Q una simulazione
se, dati p, q 2 Q tali che hp, qi 2 R, vale la seguente condizione:
a

per ogni a 2 A e p0 2 Q, se p ! p0 allora q ! q 0 per qualche q 0 2 Q tale che


hp0 , q 0 i 2 R.
Diremo che q simula p, scritto p v q, se esiste una simulazione R tale che hp, qi 2 R.
Non dicile dimostrare il seguente risultato.
Proposizione 11.29. v un preordine.
Esempio 11.30. Riprendiamo lEsempio 11.8 di pagina 230. facile dimostrare che p0
simula q0 . Infatti, a tale scopo, suciente definire una relazione binaria tra gli stati dei due
LTS che contenga la coppia hq0 , p0 i e che sia una simulazione. Per esempio, una tale relazione
la seguente:
R , {hq0 , p0 i, hq1 , p1 i, hq2 , p1 i, hq3 , p2 i, hq4 , p3 i}
La seguente proposizione evidenzia il legame esistente tra il concetto di bisimulazione e
quello di simulazione.
Proposizione 11.31 (Definizione alternativa di bisimulazione).
Sia hQ, A, ! i un LTS. Una relazione R Q Q una bisimulazione se e solo se R e R
sono simulazioni.
La dimostrazione lasciata come esercizio.

11.2 Relazioni forti

239

Preordini basati su testing


Basandoci sul concetto di soddisfacimento di un osservatore, possiamo introdurre i seguenti
tre preordini: preordine may, preordine must e preordine test.
Definizione 11.32 (Preordini di testing). Siano hQ, A, ! i e hO, Aw , ! i due LTS, p, q 2 Q
e o 2 O. Scriveremo
p vm q se, per ogni o 2 O, p may satisfy o implica q may satisfy o;
p vM q se, per ogni o 2 O, p must satisfy o implica q must satisfy o.
p vtest q se p vm q e p vM q;
evidente dalla definizione che le relazioni equivalenza may, equivalenza must ed
equivalenza test sono in eetti i nuclei dei preordini appena definiti.
Proposizione 11.33. Siano hQ, A, ! i un LTS, p, q 2 Q. Si ha
p 'm q se, e solo se, p vm q e q vm p;
p 'M q se, e solo se, p vM q e q vM p;
p 'test q se, e solo se, p 'm q e p 'M q.
Esempio 11.34. Riprendiamo lEsempio 11.8 di pagina 230. facile dimostrare che p0 6vM
q0 ; infatti, preso losservatore o , a.b.w si ha p0 must satisfy o, ma q0 must satisfy o non
vale dato che esiste una computazione che parte da q0 | o e porta nello stato c | b.w.
Con tecniche simili a quelle che introdurremo nella sezione successiva a proposito delle
varianti deboli dei preordini testing, si pu dimostrare che q0 vM p0 , q0 'm p0 e, quindi,
q0 vtest p0 .

11.2.5

Altre equivalenze forti

Equivalenza a tracce complete


Un modo per ranare le osservazioni su cui si basa lequivalenza a tracce consiste nel tener
conto separatamente delle tracce finite di uno stato che portano lo stato in uno stato terminale.
In pratica, oltre che una sequenza di azioni, si tratta di osservare se questa porta in uno stato
di deadlock.
Definizione 11.35 (Traccia completa). Siano hQ, A, ! i un LTS, q 2 Q e s 2 A . La
s
a
sequenza s una traccia completa di q se esiste q 0 tale che q ! q 0 e q 0 6 ! per qualsiasi
a 2 A. Denoteremo con CT (q) linsieme di tutte le tracce complete di q.
Definizione 11.36 (Equivalenza a tracce complete). Siano hQ, A, ! i un LTS, q 2 Q e
s 2 A . Gli stati p e q si dicono essere equivalenti a tracce complete, scritto p =CT q, se
T (p) = T (q) e CT (p) = CT (q).

240

Capitolo 11 Equivalenze comportamentali e preordini di ranamento

Si noti che se non si richiedesse anche T (p) = T (q) nella definizione di p =CT q, cio se si
definisse p =CT q se CT (p) = CT (q), =CT non sarebbe un ranamento di =T . Infatti, ad
esempio, gli LTS seguenti hanno le stesse tracce complete ma non hanno le stesse tracce.
b
b
a
a

Dalla definizione di =CT si ottiene banalmente che se due stati sono in relazione =CT
allora essi sono sicuramente equivalenti a tracce. Per il contrario non sempre vero, come
testimonia lEsempio 11.4 di pagina 229: si ha infatti p0 =T q0 e p0 6=CT q0 poich gli stati
p0 e q0 hanno le tracce ", a e ab, ma q0 ha la traccia completa a che non appartiene a p0 (il
quale dopo a pu sempre fare b).
Tuttavia, anche questa equivalenza non del tutto soddisfacente da un punto di vista
dellinterazione con lambiente esterno. Difatti, si ha p0 =CT q0 dove p0 e q0 sono gli stati iniziali delle due descrizioni della macchina distributrice di t e ca dellEsempio 11.3 di pagina
228 (infatti abbiamo CT (p0 ) = CT (q0 ) = ;). Questo perch, come nel caso dellequivalenza
basata sulle tracce, vale ancora il fatto che stati di un LTS non deterministico che hanno
le stesse tracce complete possono passare, durante lesecuzione delle stesse, attraverso stati
aventi tracce dierenti (come lo stesso esempio testimonia).
Doppia simulazione
Introduciamo ora il nucleo della relazione di simulazione.
Definizione 11.37 (Doppia simulazione). La doppia simulazione, denotata con ', il nucleo
del preordine di simulazione (quindi, ' , v \ v 1 ).

Dato che la bisimilarit lunione di tutte le bisimulazioni e che una relazione una bisimulazione se essa stessa e la sua inversa sono simulazioni (vedere Proposizione 11.31), risulta
naturale chiedersi quale sia la relazione tra e '. In eetti si ha che implica ', cio p
bisimile a q implica p simula q e q simula p (perch ovviamente ogni bisimulazione
una simulazione ed inoltre simmetrica). Il contrario per non vale! Per esempio, consideriamo gli LTS dellEsempio 11.4 di pagina 229. Non dicile dimostrare che la relazione
R1 = {hp0 , q0 i, hp1 , q1 i, hp2 , q2 i} una simulazione, e quindi q0 simula p0 , e che la relazione
R2 = {hq0 , p0 i, hq1 , p1 i, hq2 , p2 i, hq3 , p1 i} una simulazione, e quindi p0 simula q0 . Perci,
p0 ' q0 . Daltro canto, q0 meno adabile di p0 perch ha pi possibilit di andare in
deadlock, quindi, per quanto detto sulla bisimulazione, ci aspettiamo che p0 6 q0 . In eetti,
una ipotetica relazione di bisimulazione R che contenga la coppia hp0 , q0 i, dovrebbe anche
a
contenere la coppia hp1 , q3 i, dato che alla transizione q0 ! q3 , p0 pu solo replicare con la
a

transizione p0 ! p1 . Per, q3 incapace di rispondere alla transizione p1 ! p2 che p1 pu


eettuare; quindi R non potrebbe soddisfare la definizione di bisimulazione.

11.3

Relazioni deboli

In questa sezione introdurremo le seguenti equivalenze di tipo debole: a tracce deboli, bisimulazione debole, bisimulazione di branching, testing ed equivalenza basata sui fallimenti.

241

11.3 Relazioni deboli

Ricordiamo che tali equivalenze trattano in maniera speciale lazione interna degli LTS e
saranno quindi definite su un LTS del tipo hQ, A , ! i con A , A [ { }. La sezione conclusiva esaminer, in particolare, il trattamento dei processi con comportamento divergente
(cio capaci di eseguire sequenze infinite di azioni interne) da parte delle equivalenze deboli
ed introdurr alcune semplici varianti delle relazioni viste (quali, ad esempio, fair testing).
Esempio 11.38. Consideriamo la seguente specifica di una macchina distributrice di ca,
la quale, dopo linserimento di una moneta, e prima della produzione del ca, si occupa di
macinarne i grani.
p0

cof f ee

grinding

coin

Le azioni interne necessarie alla macchina per produrre il ca non dovrebbero tuttavia essere
osservabili da un utente esterno. Quindi, il comportamento della macchina da un punto di
vista delle interazioni con lambiente esterno dovrebbe essere quello specificato dal seguente
LTS.
q0

cof f ee

coin

In eetti, un tale comportamento pu essere approssimato modificando il LTS iniziale, ad


esempio tramite lapplicazione delloperatore di hiding visto nel capitolo precedente, per
astrarre dallazione di macinatura del ca. Si ottiene cos il seguente LTS.
p0

coin

cof f ee

Per, gli stati p0 e q0 dei due LTS non sono equivalenti rispetto a nessuna delle nozioni
esaminate nella sezione precedente, anche se, osservandone il comportamento dallesterno, e
mettendosi nellottica che non osservabile, non possibile individuare delle dierenze. Il
problema che nessuna delle equivalenze forti viste nella sezione precedente tiene conto della
particolare natura delle azioni interne.

11.3.1

Equivalenza basata sulle tracce deboli

Definiamo ora la variante debole dellequivalenza a tracce. Si ricordi, dal Capitolo 10, che
s
q=
) q 0 indica che lo stato q pu trasformarsi nello stato q 0 tramite lesecuzione di una sequenza
s di azioni visibili ciascuna delle quali pu essere preceduta e seguita da un qualsiasi numero
di azioni interne .
Definizione 11.39 (Traccia debole). Siano hQ, A , ! i un LTS, q 2 Q e s 2 A . La
s
sequenza s una traccia debole di q se esiste q 0 tale che q =
) q 0 . Denoteremo con L(q)
linsieme di tutte le tracce deboli di q.
Definizione 11.40 (Equivalenza a tracce deboli). Siano hQ, A , ! i un LTS, p 2 Q e q 2 Q.
Gli stati p e q si dicono equivalenti a tracce deboli, scritto p tL q, se L(p) = L(q).

242

Capitolo 11 Equivalenze comportamentali e preordini di ranamento

11.3.2

Bisimulazione debole

Per diminuire la sensibilit alle azioni interne rispetto alla bisimulazione forte, la bisimulazione
debole considera lazione interna in modo speciale per cui, quando un sistema eettua unazione interna, laltro sistema pu rispondere eettuando un numero qualsiasi (anche nullo) di
azioni interne. Introduciamo prima una notazione tecnica.
Definizione 11.41. Sia hQ, A , ! i un LTS. Se s 2 (A ) allora con s 2 A indichiamo la
sequenza (eventualmente vuota) di azioni visibili ottenuta cancellando tutte le occorrenze di
da s.
Intuitivamente, s rappresenta il contenuto visibile (cio gli elementi diversi da ) della
sequenza s e pu essere definita induttivamente sulla lunghezza di s. In particolare, data
2 A , abbiamo

se =

=
se 6=
Adesso possibile definire la bisimulazione debole come segue.

Definizione 11.42 (Bisimulazione debole). Sia hQ, A , ! i un LTS. Una relazione R


Q Q una bisimulazione debole se, dati p e q tali che hp, qi 2 R, le seguenti condizioni
sono soddisfatte:

1. per ogni 2 A e p0 2 Q, se p ! p0 allora q =


) q 0 per qualche q 0 2 Q tale che
0
0
hp , q i 2 R;
2. per ogni 2 A e q 0 2 Q, se q ! q 0 allora p =
) p0 per qualche p0 2 Q tale che
0
0
hq , p i 2 R.
Due stati p e q sono debolmente bisimili, o osservazionalmente equivalenti, scritto p q, se
esiste una bisimulazione debole R che contiene hp, qi. La bisimilarit debole o equivalenza
osservazionale, , lunione di tutte le bisimulazioni deboli. In modo equivalente, possiamo
scrivere:
[
,
{R | R una bisimulazione debole}
Esempio 11.43. Consideriamo di nuovo lEsempio 11.38. Non dicile rendersi conto che
gli stati p0 e q0 dei due LTS sono osservazionalmente equivalenti.
Dimostriamo ora propriet analoghe a quelle dimostrate per le bisimulazioni a la
bisimilarit forti anche per le corrispondenti relazioni deboli.
Proposizione 11.44. Si assuma che ogni Si , con i 2 I, sia una bisimulazione debole e che
Id sia la funzione identit su Q. Allora le seguenti relazioni sono bisimulazioni deboli.
1. Id
2. Si

3. S1 S2

243

11.3 Relazioni deboli


4. [i2I Si

Dimostrazione. La dimostrazione si svolge in modo simile a quanto fatto in precedenza per la


bisimulazione forte (Proposizione 11.12). Nel punto 3 abbiamo bisogno del seguente semplice

risultato: se hq, ri 2 S2 e q =
) q 0 allora, per qualche r0 , r =
) r0 e (q 0 , r0 ) 2 S2 .
Proposizione 11.45.
1. la pi grande bisimulazione debole;
2. una relazione di equivalenza.
Dimostrazione. La dimostrazione segue le argomentazioni usate nella Proposizione 11.13,
utilizzando per la Proposizione 11.44 anzicch la Proposizione 11.12.
Proposizione 11.46. Siano hQ, A , ! i un LTS, p, q 2 Q. Si ha p q se, e solo se,
8 2 A

allora

9q 0 2 Q : q =
) q0

allora

9p0 2 Q : p =
) p0

i) 8p0 2 Q : p ! p0
ii) 8q 0 2 Q : q ! q 0

p0 q 0 ;

p0 q 0 .

Dimostrazione. Cominciamo col definire una nuova relazione, 0 , in termini di nel modo
seguente
p 0 q se per ogni 2 A risulta:
1. 8p0 2 Q : p ! p0

allora

9q 0 2 Q : q =
) q0

p0 q 0 ;

2. 8q 0 2 Q : q ! q 0

allora

9p0 2 Q : p =
) p0

p0 q 0 .

Dalla Proposizione 11.45(1) sappiamo che una bisimulazione debole. Dalle definizioni di
bisimulazione debole e di 0 , possiamo allora dedurre che
p q

implica p 0 q

(11.2)

Rimane da dimostrare il viceversa, cio che p 0 q implica p q. Per questo, suciente


dimostrare che la relazione 0 una bisimulazione debole. Procediamo come segue. Sia

p 0 q e p ! p0 . Dobbiamo trovare un q 0 tale che q =


) q 0 e p0 0 q 0 . Per la definizione di 0

possiamo trovare un q 0 tale che q =


) q 0 e p0 q 0 . Da (11.2) segue allora che p0 0 q 0 , e con
questo si conclude la prova.
Presentiamo ancora ulteriori propriet di e cominciamo proprio dal caso emblematico
che la distingue da , cio il trattamento dellazione .
Proposizione 11.47. Sia hQ, A , ! i un LTS e sia p 2 Q. Si ha
p .p

244

Capitolo 11 Equivalenze comportamentali e preordini di ranamento

Dimostrazione. Dal momento che abbiamo mostrato luguaglianza di e 0 (introdotta nella


dimostrazione della Proposizione 11.46), la tesi risulta dimostrata se proviamo che p 0 .p.

Dapprima consideriamo una transizione p ! p0 di p: chiaramente .p ! p ! p0 , quindi

.p =
) p0 , e ovviamente p0 p0 . Consideriamo ora la sola transizione che .p pu fare, ossia

"
.p ! p: questa chiaramente corrisposta dalla transizione nulla p =
) p di p (dato che = ").
Abbiamo dunque che p 0 .p e di conseguenza p .p.

Dimostriamo ora una propriet che fornisce un criterio alternativo per poter stabilire che
una data relazione una bisimulazione debole.
Proposizione 11.48. Sia hQ, A , ! i un LTS. Una relazione R QQ una bisimulazione
debole se, e solo se, dati p, q 2 Q tali che hp, qi 2 R ed s 2 A , le seguenti condizioni sono
soddisfatte:
s

1. per ogni p0 2 Q, se p =
) p0 allora q =
) q 0 per qualche q 0 2 Q tale che hp0 , q 0 i 2 R;
2. per ogni q 0 2 Q, se q =
) q 0 allora p =
) p0 per qualche p0 2 Q tale che hq 0 , p0 i 2 R.
s

Dimostrazione. ()) Supponiamo che R sia una bisimulazione debole. Sia p =


) p0 , cos che

t
n
1
2
p ! p0 dove t = (1 . . . n ) 2 A e t = s. Allora p ! p1 ! ! p0 e dal momento che

R una bisimulazione debole abbiamo che esiste q 0 2 Q tale che q =) q1 =) =) q 0 e


t

p0 R q 0 . Da ci segue che q =
) q 0 , e quindi q =
) q 0 . La tesi segue allora per simmetria.

"
"
0
(() Supponiamo che p ! p . Se = allora p =
) p0 e cos dal punto 1 si ha q =
) q 0 con

p0 Rq 0 ; ma
= ", quindi q =
) q 0 come richiesto. Se 6= allora p =
) p0 , e grazie al punto 1

q =
) q 0 con p0 Rq 0 ; ma
= e quindi q =
) q 0 come richiesto. Anche in questo caso, la tesi
segue allora per simmetria.

Lo sviluppo di tecniche di prova che permettano di ridurre la cardinalit delle bisimulazioni


deboli con cui si lavora almeno altrettanto importante quanto nel caso delle bisimulazioni
forti. Nei sistemi reali infatti ci sono in generale molti stati che sono debolmente bisimili ma
non identici a causa della presenza di alcuni ; sarebbe tedioso trattarli come stati dierenti
quando si esibiscono delle bisimulazioni deboli. La nozione di bisimulazione debole up to
quindi anche pi importante di quella di bisimulazione forte up to . Tuttavia, nel caso della
bisimulazione debole, non altrettanto semplice definire tecniche di prova up to tipo quelle
introdotte per la bisimulazione forte. Si potrebbe infatti pensare di riadattare in maniera
ingenua la Definizione 11.16 come di seguito:
Sia hQ, A , ! i un LTS. Una relazione R Q Q una bisimulazione debole up
to se, dati p, q 2 Q tali che hp, qi 2 R, le seguenti condizioni sono soddisfatte:

1. per ogni 2 A e p0 2 Q, se p ! p0 allora q =


) q 0 per qualche q 0 2 Q tale
che hp0 , q 0 i 2 R ;
2. per ogni 2 A e q 0 2 Q, se q ! q 0 allora p =
) p0 per qualche p0 2 Q tale
che hq 0 , p0 i 2 R .

245

11.3 Relazioni deboli

Il problema per che R non una bisimulazione debole, cio R 6. Quindi,


per dimostrare che p q, non basterebbe trovare una bisimulazione debole up to R che
contenga la coppia hp, qi.
Vediamo infatti un controesempio. Consideriamo gli stati p0 e q0 dei seguenti due LTS
p0

q0

q1

q2

e definiamo la relazione R , {hp0 , q0 i}. In base alla definizione precedente, R una bisimulazione debole up to . Infatti, p0 non ha transizioni, quindi non c bisogno che q0
faccia alcuna transizione. Invece, q0 ha una transizione etichettata nello stato q1 a cui p0
risponde senza muoversi; per cui otteniamo la coppia hp0 , q1 i. Ora, poich stiamo ragionando
up to , e poich q1 q0 , possiamo richiedere che hp0 , q0 i sia in R (che, per definizione,
vero), anzicch chiedere che lo sia hp0 , q1 i. Quindi, R una bisimulazione debole up to , ma
chiaramente p0 e q0 non sono bisimili.
Il problema in eetti dovuto al fatto che le transizioni possono essere ignorate, come nellesempio precedente. La definizione naturale presentata in precedenza pu essere modificata
imponendo condizioni pi restrittive che considerino -discendenti anzicch -derivate.
Definizione 11.49 (Bisimulazione debole up to ). Sia hQ, A , ! i un LTS. Una relazione
R Q Q una bisimulazione debole up to se, dati p e q tali che hp, qi 2 R, le seguenti
condizioni sono soddisfatte

1. per ogni 2 A e p0 2 Q, se p =
) p0 allora q =
) q 0 per qualche q 0 2 Q tale che
0
0
hp , q i 2 R ;
2. per ogni 2 A e q 0 2 Q, se q =
) q 0 allora p =
) p0 per qualche p0 2 Q tale che
0
0
hp , q i 2 R .
Analogamente a quanto fatto per la bisimulazione forte up to si possono dimostrare
(con tecniche simili) le seguenti propriet, che ci autorizzano, dovendo dimostrare che p q,
a dimostrare pi semplicemente lesistenza di una bisimulazione debole up to R tale che
hp, qi 2 R.
Proposizione 11.50. Se R una bisimulazione debole up to allora R una
bisimulazione debole.
Proposizione 11.51. Se R una bisimulazione debole up to allora R .

Un inconveniente nella definizione di bisimulazione debole up to luso di =


) al

posto di ! . Questo comporta la necessit di considerare non solo -derivate ma anche discendenti: i -discendenti potrebbero essere molto pi numerosi delle -derivate e, talvolta,
potrebbero addirittura essere infiniti. La seguente proposizione fornisce un criterio alternativo
per stabilire se una relazione R una bisimulazione debole up to che permette di considerare
solo -derivate a patto di raorzare alcuni vincoli (richiedendo al posto di , sebbene questa
richiesta pu a volte essere eccessiva [SM92]).
Proposizione 11.52. Sia hQ, A , ! i un LTS ed R Q Q. Se hp, qi 2 R implica che per
ogni 2 A le seguenti condizioni sono soddisfatte

246

Capitolo 11 Equivalenze comportamentali e preordini di ranamento

1. se p ! p0 allora, per qualche q 0 2 Q, q =


) q 0 e hp0 , q 0 i 2 R
2. se q ! q 0 allora, per qualche p0 2 Q, p =
) p0 e hp0 , q 0 i 2 R
allora R una bisimulazione debole up to .
Nel Capitolo 13, facendo uso della logica HML, vedremo che lequivalenza osservazionale,
anche se ignora le azioni interne, gode di un grado di sensibilit al deadlock simile a quello
della bisimulazione forte.

11.3.3

Bisimulazione di branching

Questa equivalenza si pone tra la bisimulazione forte e quella debole, in quanto da una parte
tratta le azioni interne in modo speciale (come fa la bisimulazione debole), dallaltra cerca
di preservare la struttura di branching dei sistemi (come fa la bisimulazione forte) non ignorando del tutto gli stati intermedi attraversati eettuando azioni interne. Lidea quindi di
indebolire le richieste fatte dalla bisimulazione forte, considerando il ruolo speciale rivestito
dalle azioni interne, in modo da uguagliare LTS quali
a

che sono invece dierenziati da , ed al contempo esaminare gli stati attraversati durante
lesecuzione di una sequenza di azioni interne, per dierenziare LTS quali i seguenti
p2
c
a

p0

p1

q0

p4

q6

q2

q5

q1
p3

q3

q4

che invece non sono dierenziati da .


Esercizio 11.53. Si considerino gli LTS precedenti e si dimostri che p0 e q0 sono
osservazionalmente equivalenti. Suggerimento: si verifichi che la relazione
R , {hp0 , q0 i, hp1 , q1 i, hp2 , q2 i, hp3 , q3 i, hp4 , q4 i, hp3 , q5 i, hp4 , q6 i}
una bisimulazione debole.
Definizione 11.54 (Bisimulazione di branching). Sia hQ, A , ! i un LTS. Una relazione
simmetrica R Q Q una bisimulazione di branching se, dati p, q 2 Q tali che hp, qi 2 R

e p ! p0 , con 2 A e p0 2 Q, almeno una delle seguenti condizioni soddisfatta:


1. = e hp0 , qi 2 R

2. q =
) q 00 ! q 0 per qualche q 0 , q 00 2 Q tali che hp, q 00 i 2 R e hp0 , q 0 i 2 R.

247

11.3 Relazioni deboli

Gli stati p e q sono branching bisimili, scritto p b q, se esiste una bisimulazione di branching
R contenente hp, qi. La bisimilarit di branching, b , lunione di tutte le bisimulazioni di
branching. In modo equivalente, possiamo scrivere:
[
b ,
{R | R una bisimulazione di branching}

Si noti che nel caso 2 della definizione, pu anche essere . Quindi, se = , suciente
che una delle due condizioni sia soddisfatta, mentre se 6= , deve necessariamente essere
soddisfatta la seconda condizione.
Esempio 11.55. Consideriamo gli LTS precedenti e dimostriamo che p0 e q0 non sono
branching bisimili. Il problema dovuto alla transizione etichettata a da q0 in q5 . Infatti, p0
pu rispondere soltanto eettuando a e andando in p1 (e non in p3 come invece permette la
), ma p1 e q5 non sono chiaramente branching bisimili poich p1 ha una transizione c che q5
non ha.
La condizione 2 della Definizione 11.54, pu essere espressa in vari modi alternativi tutti
equivalenti tra loro. In particolare, avremmo ottenuto la stessa relazione raorzando (apparentemente) la condizione 2 richiedendo che tutti gli stati intermedi in q =
) q 00 siano in
a
00
0
0
000
relazione con p e permettendo che dopo q ! q si possa avere q =
) q con q 000 , e tutti gli
0
stati intermedi, in relazione con p . Formalmente, la condizione la seguente

0 = q 000 per certi


2. q = q1 ! q2 ! . . . ! qn = q 00 ! q 0 = q10 ! q20 ! . . . ! qm
stati qi , qj0 2 Q tali che hp, qi i 2 R e hp0 , qj0 i 2 R, per 1 i n e 1 j m (con
1 n, 1 m).

che graficamente cos rappresentabile

q1

q2

...

qn

q1

q2

...

qm

Quindi, riassumendo possiamo dire che la bisimulazione di branching considera due stati
equivalenti soltanto se hanno la stessa capacit di eseguire azioni e se gli stati intermedi,
anche quelli raggiunti attraverso azioni interne, hanno comportamento equivalente.
Si pu dimostrare che lunione di tutte le bisimulazioni di branching la pi grande
bisimulazione di branching e che essa una equivalenza.
Proposizione 11.56.
1. b la pi grande bisimulazione di branching;
2. b una relazione di equivalenza.
La dimostrazione lasciata come esercizio.

248

11.3.4

Capitolo 11 Equivalenze comportamentali e preordini di ranamento

Relazioni basate su testing

Per definire le varianti deboli delle relazioni basate sul testing, dobbiamo modificare la nozione di computazione per permettere che una configurazione possa evolvere anche quando,
in maniera asincrona, losservatore od il processo osservato eseguono una azione interna. Al
solito, supponiamo che w 62 A sia unazione speciale usata per indicare il successo di un
esperimento. Indicheremo con A w linsieme A [ {w}.
Definizione 11.57 (Computazione). Siano hQ, A , ! i e hO, A w , ! i due LTS e siano
q 2 Q e o 2 O. Una computazione c dalla configurazione iniziale hq, oi una sequenza di
configurazioni hqi , oi i (con i 0), cio una sequenza di coppie di stati, tale che
1. hq0 , o0 i coincide con hq, oi;
2. tra due configurazioni consecutive, diciamo hqi , oi i e hqi+1 , oi+1 i, si pu derivare una

transizione hqi , oi i ! hqi+1 , oi+1 i usando una delle seguenti regole dinferenza

E ! E0

hE, F i ! hE 0 , F i

F ! F0

E ! E0

hE, F i ! hE, F 0 i

F ! F0

hE, F i ! hE 0 , F 0 i

a2A

3. se la sequenza finita allora lultimo elemento, diciamo hqk , ok i, tale che per nessuna configurazione hq 0 , o0 i, con q 0 2 Q e o0 2 O, sia possibile derivare una transizione

hqk , ok i ! hq 0 , o0 i usando una qualsiasi delle tre regole precedenti.


Indichiamo con Comp(q, o) linsieme di tutte le computazioni dalla configurazione iniziale
hq, oi.
Le nozioni di esito di una computazione (Definizione 11.20) e soddisfacimento (Definizione 11.21) di un osservatore restano invariate, cos come pure le definizioni dei preordini
(Definizione 11.32) e delle equivalenze (Definizioni 11.22 e 11.23), per i quali useremo gli stessi
simboli. Quindi, lunica dierenza, che le relazioni deboli sono basate sulla nuova nozione
di computazione.
Vediamo ora un paio di esempi che illustrano il tipo di relazioni indotte dalle definizioni
precedenti e i ragionamenti necessari per dimostrarle.
Esempio 11.58. Consideriamo i seguenti due LTS e dimostriamo che p1 'test q1 .
p3
a

q3

test

p1

q1

q2
p2

p4

q6
q5

q4

Possiamo ragionare cos. Dobbiamo dimostrare che p1 'm q1 e p1 'M q1 .


Cominciamo a dimostrare che p1 'm q1 . Supponiamo che, per un qualche osservatore o
w
si abbia p1 may satisfy o. Se o =
) allora abbiamo anche q1 may satisfy o; altrimenti, p1
a
w
b
w
may satisfy o implica che o o =
) o0 =
) oo=
) o00 =
) , in entrambi i casi abbiamo q1 may

249

11.3 Relazioni deboli

satisfy o. Ragionando in maniera simile possiamo convincerci che q1 may satisfy o implica
p1 may satisfy o, per ogni osservatore o.
Dimostriamo ora che p1 'M q1 . Supponiamo che per un qualche osservatore o si abbia
w
p1 must satisfy o. Se o ! allora abbiamo anche q1 must satisfy o. Altrimenti, cio se
w
o 6 ! , p1 must satisfy o implica che per ogni o1 tale che o =
) o1 dobbiamo avere che o
w
b
0
0
esiste uno stato intermedio o tale che o ! , oppure o1 =
) o2 ed esiste uno stato intermedio
w
a
w
o0 tale che o0 ! , oppure o1 ! o2 ed esiste uno stato intermedio o0 tale che o0 ! . facile
vedere che in tutti i casi q1 si comporta come p1 relativamente allosservatore o. Ragionando
in maniera simile possiamo dimostrare limplicazione inversa.
Quindi la tesi dimostrata.

Esempio 11.59. Consideriamo i seguenti due LTS e dimostriamo che q2 vtest p2 .


test
p2

q2

test

...

Possiamo ragionare cos. Dimostriamo dapprima che q2 vm p2 . Supponiamo che, per un


w
a
w
qualche osservatore o, si abbia q2 may satisfy o. Ci implica che o =
) oppure o =
) o0 =
);
in entrambi i casi abbiamo che p2 may satisfy o.
Dimostriamo ora che q2 vM p2 . Supponiamo che q2 must satisfy o. Poich q2 pu
eseguire una sequenza infinita di azioni interne, lipotesi q2 must satisfy o implica che
w
o ! (altrimenti ci sarebbe una computazione, quella formata dalla sequenza infinita di
azioni interne, lungo la quale losservatore non ha lopportunit di eettuare azioni e, quindi,
w
neanche lopportunit di eettuare ! ); perci, si ha pure p2 must satisfy o. In eetti,
q2 vM p2 vale anche se in q2 sostituiamo a con una qualsiasi altra azione; cos facendo per,
q2 vm p2 , e quindi q2 vtest p2 , non vale pi.
Dimostrare invece che p2 6vtest q2 pi semplice perch basta esibire un controesempio.
Per esempio, se consideriamo il seguente osservatore
o

abbiamo che p2 must satisfy o ma non vero che q2 must satisfy o (per via della computazione formata dalla sequenza infinita di azioni interne che q2 pu eettuare), quindi la tesi
dimostrata.
Abbiamo gi detto, nel caso delle varianti forti delle relazioni testing, che esse sono dicili
da verificare, ci anche testimoniato dai due esempi precedenti. Possiamo per definire una
caratterizzazione alternativa delle relazioni in modo da ovviare a questo inconveniente. Tale
caratterizzazione indipendente dalla nozione di osservatore ed definita in termini delle
sequenze di azioni che un LTS pu eseguire e dellinsieme di azioni che un LTS deve accettare.
Per esempio, per lequivalenza testing, si tratter di controllare che due LTS possano eseguire
le stesse sequenze di azioni e che, dopo ogni sequenza lungo la quale non c divergenza (cio
possibilit di eseguire sequenze infinite di azioni interne), possano scegliere la loro prossima

250

Capitolo 11 Equivalenze comportamentali e preordini di ranamento

azione dallo stesso insieme di azioni. Un ulteriore vantaggio della caratterizzazione alternativa
che essa permette un confronto pi agevole con le altre equivalenze studiate.
In eetti, la caratterizzazione alternativa del preordine may data dal preordine vL
definito in termini di inclusione dei linguaggi.
Definizione 11.60. Siano hQ, A , ! i un LTS, p, q 2 Q. Si dice che p minore rispetto
alle tracce deboli di q, scritto p vL q, se L(p) L(q).
Teorema 11.61 (Caratterizzazione alternativa di vm ). Sia hQ, A , ! i un LTS e siano
p, q 2 Q. Si ha p vm q se e solo se p vL q.
Dimostrazione. Caso se. Supponiamo che p vL q e che p may satisfy o, dove o un
s
osservatore generico. Lipotesi p may satisfy o significa che esiste s 2 A tale che p =
) e
sw
o ==) ; in particolare ci significa che s 2 L(p). Pertanto, se per assurdo q may satisfy o
sw
s
non valesse, dato che comunque o ==) , avremmo che q =
6 ) , cio s 62 L(q), che contradirebbe
lipotesi p vL q. Quindi devessere q may satisfy o, da cui segue che p vm q.
Caso solo se. Cominciamo col definire, per ogni sequenza s 2 A , diciamo s = a1 an
(n 0), il seguente osservatore canonico o(s):

o(s) ,
{oi | 0 i n + 1},
{ai | 1 i n} [ {w},
{oi

ai+1

! oi+1 | 0 i n

1} [ {on ! on+1 }

che possiamo visualizzare graficamente nel modo seguente:


o(s)

a1

o1

a2

o2

on1

an

on

on+1

Non dicile dimostrare che vale la seguente propriet:


p may satisfy o0 se e solo se s 2 L(p).

(11.3)

Supponiamo ora che p vm q e s 2 L(p). Dallipotesi che s 2 L(p) e dalla propriet precedente
segue che p may satisfy o0 . Dallaltra ipotesi, segue allora che q may satisfy o0 . Applicando
nuovamente la Propriet (11.3) si ha che s 2 L(q) e, quindi, la tesi.
Una banale conseguenza del teorema precedente che lequivalenza may 'm coincide con
quella a tracce deboli, cio tL (se veda Definizione 11.40).
La caratterizzazione alternativa del preordine must non cos diretta come la precedente
e fa uso delle seguenti definizioni ausiliarie.
Definizione 11.62. Siano hQ, A , ! i un LTS, q 2 Q, s 2 A , Q0 Q e L f A (cio L
sottoinsieme finito di azioni visibili).
q diverge, scritto q *, se esiste una sequenza infinita di stati q0 , q1 , . . . tale che q = q0 e

qi ! qi+1 per ogni i 0.


q diverge su s, scritto q * s, se esiste un prefisso s0 (eventualmente vuoto) di s ed un
s0

q 0 2 Q tale che q =) q 0 e q 0 *. Scriviamo q + s se q * s non vera e in questo caso


diciamo che q converge su s.

251

11.3 Relazioni deboli


q totalmente convergente se q + s0 vera per ogni s0 2 A .
s

(q after s) , {q 0 2 Q | q =
) q 0 } linsieme degli stati che q pu raggiungere dopo aver

eettuato s 2 A ed un numero qualsiasi di azioni invisibili.


a

(q must L) se per ogni stato q 0 2 Q tale che q =


) q 0 esiste a 2 L tale che q 0 =
).
(Q0 must L) se per ogni stato q 0 2 Q0 si ha q 0 must L.
Quindi, uno stato divergente se pu eseguire una sequenza infinita di azioni interne,
ignorando in tal modo il suo ambiente; uno stato diverge su s se, durante lesecuzione di s,
pu raggiungere uno stato divergente.
A questo punto possiamo introdurre la caratterizzazione alternativa del preordine must.
Definizione 11.63. Siano hQ, A , ! i un LTS, p, q 2 Q. Si pone p 4M q se per ogni s 2 A
e per ogni L f A si ha che p + s implica:
1. q + s;
2. ((p after s) must L) implica ((q after s) must L).
Il vantaggio di questa caratterizzazione alternativa che la complessit di dimostrare che
due stati sono equivalenti si riduce drasticamente in quanto si riducono le sequenze di azioni
da considerare. Intanto, dalla definizione del preordine, evidente che per dimostrare che
p 4M q, vanno considerate solo le sequenze s lungo le quali p non diverge. In tal caso, la
seguente propriet ci dice che se p vM q allora anche q non diverge lungo s e se s una traccia
di q lo anche di p.
Lemma 11.64. Siano hQ, A , ! i un LTS, p, q 2 Q. Se p vM q allora, per ogni s 2 A ,
p + s implica
1. q + s e
2. s 2 L(q) implica s 2 L(p).
Dimostrazione.
1. Ragioniamo per assurdo. Supponiamo che esista una sequenza s 2 A ,
diciamo s = a1 an , tale p + s e q * s. Allora, se prendiamo losservatore

o , {oi | 0 i n} [ {of , ow },
{ai | 1 i n} [ {, w},

ai+1

w
{oi ! ow , oi
! oi+1 | 0 i n 1} [ {on ! ow , ow ! of }
che possiamo visualizzare graficamente nel modo seguente
w

ow

of

o0

a1

o1

a2

o2

on1

an

on

252

Capitolo 11 Equivalenze comportamentali e preordini di ranamento


abbiamo p must satisfy o0 mentre q must satisfy o0 falso, cio p 6vM q. Ci
contraddice lipotesi p vM q, quindi devessere q + s.

2. Ragioniamo per assurdo. Supponiamo che esista una sequenza s 2 A , diciamo s =


a1 an , tale p + s, s 2 L(q) e s 62 L(p). Allora, se prendiamo losservatore

o0 ,
{oi | 0 i n} [ {of , ow },
{ai | 1 i n} [ {, w},

{oi ! ow , oi

ai+1

! oi+1 | 0 i n

1} [ {ow ! of }

che possiamo visualizzare graficamente nel modo seguente


w

ow

of

o0

a1

o1

a2

o2

on1

an

on

abbiamo p must satisfy o0 mentre q must satisfy o0 falso, cio p 6vM q. Ci


contraddice lipotesi p vM q, quindi devessere s 2 L(p), da cui segue la tesi.

Si pu anche dimostrare che per ogni sequenza s che non una traccia per uno stato q si
ha che (q after s) = ; e viceversa; da ci segue banalmente che se s 62 L(q) allora (q after
s) must L vero, per ogni insieme di azioni L. Quindi, per verificare se p vM q, suciente
limitarsi a considerare le sequenze s lungo le quali p non diverge e che sono anche tracce di p.
Lemma 11.65. (q after s) must ; se e solo se s 62 L(q).
Dimostrazione. (() banale, in quanto se s 62 L(q) questo implica che (q after s) = ;.
s
()) Ragioniamo per assurdo e supponiamo che s 2 L(q). Allora esiste un q 0 tale che q =
) q0
quindi linsieme (q after s) non vuoto (contiene almeno q 0 ). Evidentemente, non c un
a
a 2 ; tale che q 0 =
) e quindi dovremmo concludere che (q after s) must ; falso, che
sarebbe in contraddizione con lipotesi.
Sfruttando la propriet precedente, si pu dimostrare che se p 4M q e se p non diverge
lungo s, allora se s una traccia di q lo anche di p.
Lemma 11.66. Se p 4M q e p + s allora s 2 L(q) implica s 2 L(p).
Dimostrazione. Ragioniamo per assurdo, supponiamo cio che essendo vere le ipotesi vale
anche che s 62 L(p). Allora, per il Lemma 11.65 abbiamo che (p after s) must ;. Per via
delle ipotesi, ci implica che (q after s) must ;. Quindi, ancora per il Lemma 11.65, si ha
che s 62 L(q), che contraddice lipotesi. Quindi, devessere s 2 L(p).
Nel seguito, per qualsiasi stato r 2 Q di un LTS hQ, A , ! i, indicheremo con Init(r)
a
linsieme {a 2 A | r =
) }, cio linsieme delle azioni visibili che r pu immediatamente eseguire
(eventualmente precedute da una sequenza di azioni invisibili).

253

11.3 Relazioni deboli


Teorema 11.67 (Caratterizzazione alternativa di vM ).
p, q 2 Q. Si ha p vM q se e solo se p 4M q.

Sia hQ, A , ! i un LTS e siano

Dimostrazione. Dimostriamo prima che p vM q implica p 4M q. Dal Lemma 11.64 segue


che, per ogni s 2 A , se p + s allora q + s. Resta da dimostrare che, per ogni s 2 A tale che
p + s e per ogni L f A, si ha che (p after s) must L implica (q after s) must L. Siano
s = a1 an e L = {b1 , . . . , bm }; consideriamo il seguente osservatore

o,
{oi | 0 i n} [ {of , ow },
{ai | 1 i n} [ {, w},

bj
ai+1

w
{oi ! ow , oi
! oi+1 | 0 i n 1} [ {on ! ow | bj 2 L} [ {ow ! of }
che possiamo visualizzare graficamente nel modo seguente
w

ow

of

o0

a1

o1

a2

b1 bm

o2

on1

an

on

facile verificare che (p after s) must L implica p must satisfy o che a sua volta, per via
dellipotesi, implica che q must satisfy o. Questo implica che (q after s) must L; infatti,
per come fatto losservatore o, abbiamo o che s 62 L(q) o che per tutti gli stati q 0 tali che
s

bj

q=
) q 0 , vero che q 0 =) per qualche bj 2 L.
Ora, dimostriamo che p 4M q implica p vM q. Dimostreremo una aermazione equivalente cio che preso un osservatore o qualsiasi abbiamo che se q must satisfy o falso
allora anche p must satisfy o falso. In altri termini, dimostreremo che se esiste una
computazione senza successo c1 2 Comp(q, o) allora esiste una computazione senza successo
c2 2 Comp(p, o). Se una tale c1 esiste allora il fatto che c1 non ha successo pu dipendere da
una delle seguenti ragioni:

1. c1 = hq0 , o0 ihq1 , o1 i hqn , on i, q = q0 e o = o0 , hqn , on i 6 ! , oi 6 ! e qi + e oi + per


ogni i : 0 i n.
2. c1 = hq0 , o0 ihq1 , o1 i hqn , on i , q = q0 e o = o0 , qm * oppure om * per qualche
w
m : 0 m n, e oi 6 ! per ogni i : 0 i < m.
w

3. c1 = hq0 , o0 ihq1 , o1 i hqi , oi i , q = q0 e o = o0 , qi + e oi + e oi 6 ! e hqi , oi i ! per


ogni 0 i.
Per dimostrare la tesi allora suciente determinare in ciascuno di questi casi una
computazione c2 2 Comp(p, o) senza successo.
s

1. In questo caso esiste un s 2 A tale che q =


) qn , o =
) on , q + s, o + s, e (q after
s
w
s) must Init(on ) falso. Ora, se p * s, allora il fatto che o =
) on e che oi 6 ! per
ogni i : 0 i n implica che c2 esiste. Daltro canto, se p + s, il Lemma 11.66
s
implica che s 2 L(p), cio p =
) p0 per qualche stato p0 . quindi possibile costruire una
computazione c2 = hp, oi hp0 , on i in cui gli stati dellosservatore sono esattamente gli

254

Capitolo 11 Equivalenze comportamentali e preordini di ranamento


stessi di quelli della computazione c1 . Inoltre, dallipotesi p 4M q, abbiamo che il fatto
che (q after s) must Init(on ) falso implica che (p after s) must Init(on ) pure
falso, perci anche c2 non ha successo.
s

2. In questo caso esiste un s 2 A tale che q =


) qn , o =
) on , e q * s oppure o * s. Da ci, per
via dellipotesi p 4M q, segue che p * s oppure o * s. Quindi possiamo costruire una
computazione c2 2 Comp(p, o) in cui gli stati dellosservatore lungo la computazione
sono gli stessi che nella computazione c1 , e quindi abbiamo che c2 deve essere senza
successo.
3. Poich, per ogni stato qk della computazione c1 , qk + allora abbiamo che per s 2 A
s
s
s
w
tale che q =
) qk e o =
) ok si ha q + s. Ora, se p * s, allora, poich o =
) ok e oi 6 ! per
ogni 0 i, possibile costruire una computazione c2 2 Comp(p, o) che non ha successo.
Altrimenti, se p + s, per il Lemma 11.66, abbiamo che s 2 L(p) cio esiste uno stato
s
stato p0 tale che p =
) p0 . Il ragionamento pu essere ripetuto per ogni k 0, in questo
modo possiamo costruire una computazione c2 2 Comp(p, o), eventualmente infinita,
che non ha successo.

Esempio 11.68. Riconsideriamo i due LTS presentati nellEsempio 11.58 di pagina 248.
Vogliamo vedere il tipo di ragionamento che bisogna seguire per dimostrare che p1 'test q1
utilizzando le caratterizzazioni alternative; quindi vogliamo dimostrare che p1 tL q1 , che
p1 4M q1 e che q1 4M p1 . La validit della relazione p1 tL q1 ovvia dato che p1 e q1
hanno le stesse tracce deboli. Per dimostrare che p1 4M q1 consideriamo solo le sequenze
di azioni visibili s 2 L(p) perch altrimenti avremmo p after s = q after s = ; (dato
che L(p) = L(q)) e quindi, per qualsiasi L, (p after s) must L e (q after s) must L
valgono. Se prendiamo s = allora p after = {p1 , p2 }; quindi, anch (p after ) must
L devessere b 2 L. Dato che q after = {q1 , q2 , q3 }, segue allora che (q after ) must L.
Se s = a allora p after a = {p3 }. Quindi, (p after a) must L falso per qualsiasi insieme

L: se L = ;, ci segue dal Lemma 11.65; altrimenti, cio se L 6= ;, segue dal fatto che p3 6 !
per qualsiasi 2 A. Quindi, non c bisogno di fare alcuna verifica su (q after s) must L.
Analogo ragionamento pu essere ripetuto nel caso s = b. Con un ragionamento simile si pu
dimostrare che q1 4M p1 , e quindi la tesi.

11.3.5

Relazioni basate sui fallimenti

Introduciamo ora un preordine basato sulle nozioni di rifiuto e fallimento.


Definizione 11.69. Siano hQ, A , ! i un LTS, q 2 Q, s 2 A ed un insieme finito di azioni
B f A.
b

1. q rifiuta B se per tutti i b 2 B, non esiste q 0 tale che q =


) q0.
s

2. hs, Bi un fallimento per q se q * s oppure se esiste q 0 tale che q =


) q 0 e q 0 rifiuta B.
Indichiamo con F (q) linsieme di tutti i fallimenti di q.

255

11.3 Relazioni deboli

Quindi, un rifiuto consiste in un insieme finito di azioni visibili che uno stato incapace di
eseguire, non tenendo conto del numero di azioni interne eseguite. Un fallimento una coppia
data da una sequenza di azioni e da un insieme di azioni oerte dallambiente; uno stato pu
fallire divergendo durante lesecuzione della sequenza oppure completandola ma arrivando in
uno stato incapace di rispondere alle azioni oerte. Quindi, un fallimento pu anche essere il
risultato di non determinismo o divergenza; pi un sistema non deterministico o divergente,
pi fallimenti ha.
Consideriamo un paio di esempi.
Esempio 11.70. Consideriamo i seguenti tre LTS.
b

p1

p2

p3

a
c

a
c

La coppia ha, {b}i un fallimento per p1 e per p2 ma non per p3 . Infatti, i primi due stati
a
hanno transizioni =
) che portano in uno stato che non pu eseguire b, cio che rifiuta {b};
lo stato p3 non ha una tale transizione. In eetti, si potrebbe dimostrare che p1 e p2 hanno
gli stessi fallimenti, i quali sono un sovrainsieme di quelli di p3 .

Esempio 11.71. Si consideri il seguente LTS.

Poich q *, si ha che q * s per ogni sequenza s di azioni visibili, e di conseguenza hs, Bi un


fallimento per q per ogni sequenza s e per ogni insieme finito di azioni B.
Possiamo ora definire il seguente ordinamento che basato sullidentificazione del fallimento come evento non desiderabile; quindi, un processo pi piccolo di un altro ha pi
possibilit di fallimento di uno pi grande.
Definizione 11.72. Siano hQ, A , ! i un LTS, p, q 2 Q. Si pone p vF q se F (p) F (q).
immediato dimostrare che lordinamento vF una relazione riflessiva e transitiva.
Quindi vale la seguente propriet.
Proposizione 11.73. La relazione vF un preordine.
Indicheremo con 'F lequivalenza nucleo del preordine vF . Nella sezione conclusiva di
questo capitolo, vedremo che lordinamento indotto dal preordine basato sui fallimenti molto
simile a quello indotto dal preordine must introdotto in precedenza; lo stesso vale per le
equivalenze.

256

11.4

Capitolo 11 Equivalenze comportamentali e preordini di ranamento

Trattamento della divergenza

Le equivalenze viste hanno comportamenti piuttosto dierenti riguardo le computazioni divergenti , cio le computazioni formate da sequenze infinite di transizioni interne senza alcuna
interazione con lambiente esterno. Per esempio, lequivalenza a tracce deboli tL incapace
di distinguere il deadlock dalla divergenza, come mostra il fatto che

p0

q0

Da questo punto di vista, lequivalenza a tracce (forti) =T ha un comportamento migliore


perch tiene conto delle azioni interne ed quindi in grado di distinguere i due precedenti
LTS.
Gli stati p0 e q0 sono anche osservazionalmente equivalenti e ci quindi rivela un trattamento non sempre adeguato della divergenza anche da parte della bisimilarit debole . In
qualche modo, la bisimulazione incorpora nella sua definizione un concetto di fairness per cui
se possibile scegliere infinitamente spesso di eettuare una determinata azione allora prima
o poi quellazione verr eettuata. Cos, se un processo ha la possibilit di evitare lesecuzione
di una sequenza infinita di azioni interne, assume che prima o poi lo far. Per esempio, i
due stati p1 e q1 dei seguenti LTS

p1

q1

sono bisimili debolmente. Questa propriet cruciale per poter usare come criterio di
correttezza per la verifica di sistemi quali i protocolli di comunicazione. Daltro canto, come
si visto, essa comporta che sistemi alcuni dei quali divergono ed altri no possano essere
considerati equivalenti.
Al contrario, lequivalenza must (e, quindi, anche lequivalenza test) pi sensibile al
problema della divergenza, come si pu anche intuire dalla definizione alternativa del preordine
must (Definizione 11.63). Se infatti prendiamo come osservatore lo stato o del seguente LTS
o

abbiamo che p0 must satisfy o mentre non vero che q0 must satisfy o; quindi, p0 6vM q0
e p0 6vtest q0 , e di conseguenza i due stati non sono n must n test equivalenti.
Esercizio 11.74. Dimostrare che q0 vM p0 e q0 vtest p0 .

Tra le varianti dei preordini testing che sono state studiate in letteratura, ne sono state
introdotte anche alcune che trattano la divergenza in maniera simile a quanto appena detto
per la bisimulazione debole. Di seguito ne presentiamo una. A tale scopo, modifichiamo la
nozione di successo di una computazione (Definizione 11.20) in modo da ignorare lesistenza
di eventuali computazioni divergenti.
Definizione 11.75 (Esito di una computazione).
Siano hQ, A, ! i e hO, Aw , ! i due LTS, q 2 Q e o 2 O. Una computazione c 2 Comp(q, o)
della forma hq0 , o0 i, hq1 , o1 i, hq2 , o2 i, . . . ha successo se per ogni configurazione hqi , oi i 2 c, con
w
i 0, si ha hqi , oi i =) .

257

11.5 Gerarchie tra le relazioni


b

=CT

F M
=T

L m

Figura 11.2: Gerarchie tra le equivalenze presentate in questo capitolo nel caso di processi
totalmente convergenti: R1 ! R2 significa R2 R1 . I simboli hanno il seguente significato: =T equivalenza a tracce forti, =CT equivalenza a tracce (forti) complete, ' doppia
simulazione, bisimilarit forte, tL equivalenza a tracce deboli, 'm equivalenza may, 'F
equivalenza basata sui fallimenti, 'M equivalenza must, bisimilarit debole, b bisimilarit
di branching.
Si noti che di fatto la definizione appena data indebolisce la richiesta posta dalla Definizione 11.20 anch una computazione abbia successo cosicch anche una computazione
divergente pu avere successo.
Definizione 11.76 (Soddisfacimento di un osservatore).
Siano hQ, A, ! i e hO, Aw , ! i due LTS, q 2 Q e o 2 O. Si dice che q fair-must satisfy
o se ogni computazione c 2 Comp(q, o) ha successo.

Se riconsideriamo lesempio precedente, abbiamo ora che q0 fair-must satisfy o.


Abbiamo anche che p fair-must satisfy o0 , dove p e o0 sono gli stati dei seguenti LTS

Basandoci su questa nuova definizione di soddisfacimento di un osservatore, possiamo


definire il seguente ordinamento.
Definizione 11.77 (Preordine fair-must). Siano hQ, A, ! i e hO, Aw , ! i due LTS, p, q 2 Q
e o 2 O. Si dice che p vF M q se per ogni o 2 O si ha che p fair-must satisfy o implica q
fair-must satisfy o.
Non dicile dimostrare che vF M un preordine.

11.5

Gerarchie tra le relazioni

Innanzitutto, va ricordato che nel caso di LTS deterministici tutte le equivalenze coincidono.
Consideriamo allora il caso pi generale dgli LTS non deterministici.
Se ci limitiamo al caso di LTS totalmente convergenti, le relazioni che abbiamo definito
in questo capitolo possono essere raggruppate, a seconda che si tratti di equivalenze forti
o deboli, nelle due gerarchie mostrate in Figura 11.2 (gerarchie simili valgono anche per i
corrispondenti preordini). Di seguito, commentiamo alcuni dei risultati riassunti nella figura.
Nel caso che tutti gli LTS considerati siano totalmente convergenti si ha:

258

Capitolo 11 Equivalenze comportamentali e preordini di ranamento


p vM q implica q vm p: ci unimmediata conseguenza del Lemma 11.66 e delle
caratterizzazioni alternative dei preordini vM e vm ;
p vF q implica q vL p : infatti, per ogni fallimento hs, Bi di p, si ha s 2 L(p).

Si pu anche dimostrare che vF e vM coincidono.


Inoltre, sempre nel caso dgli LTS totalmente convergenti, lequivalenza osservazionale un ranamento anche dellequivalenza must. Per dimostrarlo, facciamo uso della
caratterizzazione alternativa di questultima.
Proposizione 11.78. Siano p, q 2 Q totalmente convergenti. Si ha che p q implica
p vM q.

Dimostrazione. Dimostrare la tesi equivale a dimostrare che p 6vM q ) p 6 q. Utilizzando la


caratterizzazione alternativa di vM (Definizione 11.63), dallipotesi che p e q sono totalmente
convergenti e dal fatto che p 6vM q segue che esistono s 2 A ed L f A tali che p + s, q + s e
s

se p =
) p0 si ha che Init(p0 ) \ L 6= ;, 9q 0 : q =
) q 0 ^ Init(q 0 ) \ L = ;
s

Ne segue che q 0 6 p0 per ogni p0 : p =


) p0 da cui, per la Proposizione 11.48, segue che q 6 p e,
quindi, la tesi.
Quindi, dalla definizione del preordine vtest , dalla proposizione precedente e per la Proposizione 11.80 (che vale a maggior ragione anche nel caso particolare di sistemi totalmente
convergenti), otteniamo il risultato seguente.
Teorema 11.79. Siano p, q 2 Q totalmente convergenti. Si ha che p q implica p vtest q.

In generale invece, cio nel caso di LTS non convergenti, le equivalenze 'm e 'M non
sono confrontabili. Per convincerci di ci, suciente individuare coppie di stati che sono in
una relazione ma non nellaltra, e viceversa. Per esempio, abbiamo che p1 'm q1 e p1 6'M q1
dove p1 e q1 sono cos definiti:
b
a

p1

q1

a
c

Infatti, usando le caratterizzazioni alternative, sappiamo che p1 tL q1 e che (q1 after a)


must {b} mentre non vero che (p1 after a) must {b} (in eetti, si potrebbe dimostrare
che p1 vtest q1 ).
Se invece consideriamo

p2

q2

abbiamo p2 'M q2 (poich in generale vale che se q * e q must satisfy o allora o ! ) e


p2 6'm q2 (poich i due stati non hanno le stesse tracce).
Inoltre, sappiamo gi che 'M 6. In eetti, per LTS generici, le due relazioni non sono
confrontabili. Consideriamo infatti gli LTS seguenti

259

11.6 Esercizi

Si pu vedere facilmente che p q e p 6'M q, quindi 6'M .


Invece, c una relazione ben precisa tra equivalenza osservazionale ed equivalenza a tracce
deboli come mostra la seguente propriet (enunciata per il preordine may ma facilmente
adattabile al caso dellequivalenza).
Proposizione 11.80. Siano p, q 2 Q. Si ha che p q implica p vm q.
Dimostrazione. Dimostrare la tesi equivale a dimostrare che p 6vm q ) p 6 q. In base alla
s
s
definizione alternativa di vm si ha: p 6vm q implica che 9s : p =
) ^ q=
6 ) . La tesi segue
allora direttamente dalla Proposizione 11.48 di pagina 244.

11.6

Esercizi

11.1 Sia hQ, A, ! i un LTS. Dimostrare che una relazione R Q Q una simulazione forte se e
solo se
a
a
R 1 ! !R 1
per ogni a 2 A.

11.2 Sia hQ, A, ! i un LTS. Dimostrare che una relazione R Q Q una bisimulazione forte se
e solo se
a
a
a
a
R 1 ! !R 1
e
R ! !R
per ogni a 2 A.

11.3 Utilizzando la caratterizzazione delle simulazioni forti vista nellEsercizio 11.1, si provi che Id
una simulazione e che se R ed S sono simulazioni allora R [ S ed RS sono simulazioni.

11.4 Sia hQ, A, ! i un LTS e sia v lunione di tutte le simulazioni forti. Si provi che v un
preordine, ossia che Id v e vv v.
11.5 Si provi con un esempio che lintersezione di bisimulazioni forti non necessariamente una
bisimulazione forte.
11.6 Si considerino le seguenti costanti di processo:
Impl
Spec

,
,

(coin. grind. cof f ee. nil) / grind


coin. cof f ee. nil

Si provi che Impl e Spec sono equivalenti a tracce deboli ma non sono equivalenti a tracce (si
ricordi che / loperatore di hiding).
11.7 Si considerino le seguenti costanti di processo:
R
W
S

,
,
,

p. beginRead. endRead. v. R
p. beginW rite. endW rite. v. W
p. v. S

Si disegnino i due LTS corrispondenti a


Spec
Impl

,
,

. beginRead. endRead. Spec + . beginW rite. endW rite. Spec


(R | S | W ) \ {p, v}

Si provi che Impl e Spec sono debolmente bisimili e che non sono fortemente bisimili.

260

Capitolo 11 Equivalenze comportamentali e preordini di ranamento

11.8 Dimostrare che lunione di tutte le bisimulazioni di branching una bisimulazione di branching
e che essa una equivalenza.
11.9 Si dimostri che se la coppia hs, Bi un fallimento per q e B 0 B allora anche la coppia hs, B 0 i
un fallimento per q.

Capitolo 12

Calculus of Communicating
Systems (CCS)

SOMMARIO
Questo capitolo presenta CCS (Calculus of Communicating Systems, Milner 1980), uno dei
calcoli di processo pi conosciuti ed utilizzati, ed alcune teorie della concorrenza sviluppate
specificamente per esso. Cominceremo con la sintassi e la semantica operazionale di CCS.
Quindi vedremo una variante di CCS con passaggio di valori e la sua traduzione nel calcolo
con pura sincronizzazione. Successivamente presenteremo specificamente per CCS alcune
delle equivalenze e dei preordini comportamentali visti nel capitolo precedente. Studieremo
anche quali relazioni sono preservate da tutti gli operatori del linguaggio. Infine, introdurremo un altro approccio alla definizione della semantica dei sistemi concorrenti, quello
algebrico (o assiomatico), tramite caratterizzazioni (dis)equazionali alternative di alcune
delle relazioni osservazionali introdotte.
In questo capitolo rivedremo in maniera omogenea alcuni concetti gi introdotti, ma il
fatto di aver fissato la sintassi per il linguaggio ci permetter di concentrarci su due aspetti
importanti che finora erano stati volutamente tralasciati: (pre)congruenze e assiomatizzazioni.

12.1

Sintassi di CCS

CCS [Mil80, Mil89] basato su un insieme minimale di operatori che possono essere usati
per costruire descrizioni di sistemi a partire da descrizioni di sottosistemi. Gli elementi fondamentali su cui si basano queste descrizioni, come in ogni altro calcolo di processo, sono le
azioni.
Azioni in CCS. Le azioni rappresentano operazioni elementari eseguite in maniera atomica
e non interrompibile. In pratica le azioni corrispondono sia ad operazioni di input/output sulle
porte di comunicazione, sia a passi computazionali interni di un sistema. Le prime vengono
dette esterne, o visibili, dato che permettono linterazione di un sistema con lambiente.
Per formalizzare queste intuizioni, sia un insieme infinito numerabile di etichette, o
porte, non contenente il simbolo . Unazione in CCS ha una delle seguenti tre forme:
a 2 , rappresenta lazione di ricevere un segnale sulla porta a;

262

Capitolo 12 Calculus of Communicating Systems (CCS)


a, con a 2 , rappresenta lazione di emettere un segnale sulla porta a;
rappresenta un passo di computazione interna.

La capacit di un sistema di interagire con lesterno dipende dalle porte che il sistema
utilizza e dalle operazioni di input/output che eettua. Quindi, importante distinguere le
diverse porte di comunicazione, mentre non c alcuna necessit di distinguere tra loro i passi
computazionali interni, dal momento che essi corrispondono ad operazioni che non possono
influenzare lambiente di esecuzione o essere da questo influenzate. Perci, ununica azione
suciente per modellare le operazioni interne dei sistemi in questione.
Linsieme ACCS di tutte le azioni CCS quindi:
ACCS , [ {a | a 2 } [ { }
Poniamo inoltre , , dove 2 [ {a | a 2 }. Si noti che non unazione valida.
Le azioni e sono dette complementari, ovvero rappresentano azioni di input e di output
su uno stesso canale. Essendo lunica azione interna, linsieme di tutte le azioni esterne
ACCS \ { }. Nel seguito, quando non diversamente specificato, utilizzeremo come elemento
generico di ACCS \ { } e come elemento generico di ACCS .
Operatori di CCS. Dopo aver definito linsieme ACCS delle azioni CCS introduciamo gli
operatori che il calcolo mette a disposizione per la descrizione di sistemi interattivi.
Sia C un insieme infinito numerabile di costanti di processo, i cui generici elementi sono
denotati con A, B, C, . . . . Di seguito utilizzeremo p, p1 , q, q 0 per denotare processi CCS.
CCS fornisce i seguenti operatori per costruire processi.
Processo inattivo: nil rappresenta il processo che non esegue alcuna attivit.
Azione prefissa: ., con 2 ACCS , permette di preporre lazione ad un processo. Intuitivamente, .p capace di eseguire prima lazione e poi di comportarsi come il
processo p.
Scelta o somma: + rappresenta una scelta tra due comportamenti possibili. Il processo
p1 + p2 ha la possibilit di comportarsi come p1 o come p2 , a seconda dellinterazione
oerta dallambiente.
Composizione parallela: | permette lesecuzione concorrente dei due processi argomento.
Il processo p1 | p2 esegue p1 e p2 simultaneamente permettendo anche azioni complementari per la loro sincronizzazione; in questo caso lazione composta risultante unazione
interna .
Restrizione: \L, dove L , permette di localizzare delle azioni allinterno di un processo.
Intuitivamente, p\L si comporta come p eccettuato il fatto che esso non pu interagire
con lambiente usando azioni, o complementari di azioni, che compaiono in L.
Relabelling: [f ], dove f : ! , permette di ridenominare le azioni di un processo in
modo da facilitare la costruzione di processi complessi a partire da altri pi semplici.
Il processo p[f ] si comporta come p, eccetto che ogni azione che p pu eseguire viene
ridenominata applicandole f .

263

12.1 Sintassi di CCS

::=

nil

.p

p1 |p2

p1 + p 2

p\L

p[f ]

Tabella 12.1: Sintassi di CCS


Costanti di processo: se C una costante di processo la cui equazione di definizione
C , p, allora C rappresenta linvocazione del processo p, analogamente allinvocazione di
funzioni o procedure nei linguaggi imperativi. Questo costrutto permette la definizione
di processi ricorsivi.
Nel seguito, indicheremo con PCCS linsieme di tutti i processi CCS generati dalla sintassi in
Backus Naur Form illustrata in Tabella 12.1.
Vediamo ora alcuni esempi di processi CCS.
Esempio 12.1. [Bill-Ben] In CCS, il sistema concorrente Bill Ben di Figura 10.1 pu essere
definito nel modo seguente:
Bill
Ben
Bill_Ben

, play. meet. nil


, work. meet. nil
, (Bill | Ben)\{meet}

Nellesempio precedente abbiamo assunto che , lalfabeto delle azioni atomiche, contenga
play, work e meet. Nei tre esempi che seguono assumeremo che contenga send, recv, msg,
ack, get, put, get_ack e put_ack.
Esempio 12.2. Il termine
send.recv.nil
rappresenta un sistema che esegue una sequenza di due azioni: un input sul canale send,
seguito da un output sul canale recv.

Esempio 12.3. La definizione


M , put.get.M + put_ack.get_ack.M
aggiunge allambiente una costante di processo M il cui comportamento pu essere visto come
un buer di comunicazione ad una posizione: quando riceve un messaggio sul canale put, lo
spedisce sul canale get, e si comporta in maniera simile per gli acknowledgment.

Esempio 12.4. [Un semplice protocollo di comunicazione] Consideriamo le seguenti


definizioni, dove M il processo definito nellesempio precedente.
S , send.msg.ack.S
R , msg.recv.ack.R

264

Capitolo 12 Calculus of Communicating Systems (CCS)

Figura 12.1: Architettura di un semplice protocollo di comunicazione


P , (S[put/msg, get_ack/ack]|M |R[get/msg, put_ack/ack])
\ {get, put, get_ack, put_ack}
P rappresenta un processo CCS corrispondente ad un semplice protocollo di comunicazione
consistente in un mittente S, un ricevente R e un mezzo di comunicazione M . Il mittente
accetta ripetutamente messaggi sul suo canale send e li spedisce sul suo canale msg, quindi
attende un ack sul suo canale ack. Il ricevente si comporta in modo simile: aspetta un
messaggio sul suo canale msg, lo spedisce su recv e spedisce un ack attraverso il canale ack.
Gli operatori di relabelling sono dati nella forma a/b, c/d, . . . ; intuitivamente ci significa
che il relabelling sostituisce b con a, d con c, etc; le azioni non menzionate restano immutate
(cio, f su queste azioni si comporta come la funzione identit). Loperatore di restrizione
assicura che solo il mittente e il ricevente possono interagire direttamente con il mezzo di
comunicazione.
Larchitettura del protocollo rappresentata in Figura 12.1 per mezzo di un cosiddetto
grafo di flusso. Tale grafo fornisce una descrizione statica del sistema evidenziando le componenti in parallelo (nodi del grafo) e la loro struttura di interconnessione (archi del grafo che
congiungono porte), mentre la descrizione dinamica del comportamento del sistema data
dal grafo delle transizioni in Figura 12.2.
Alcuni degli esempi visti sopra, illustrano come, nonostante la versione di CCS fin qui considerata non supporti esplicitamente il passaggio di valori, sia possibile implementare una limitata forma di scambio di dati, associando una porta ad ogni possibile valore. Nellesempio 12.3,
M in grado di gestire due valori: messaggi e acknowledgment.
Tramite gli operatori CCS si possono implementare molti altri operatori presenti in altre
algebre di processi. Vediamo qui come sia possibile simulare il comportamento di due semplici
operatori.
Hiding p / L , (p | Ever1 | | Evern ) \ L, dove L = {a1 , ..., an }, ed Everi , ai .Everi +
ai .Everi , per 1 i n. In pratica, Everi mette continuamente a disposizione le azioni
ai e ai e quindi, quando il processo p esegue ai o ai , avviene necessariamente (per via
della restrizione \ L) la sincronizzazione che d come risultato . In pratica, ai e ai
non sono pi visibili, che proprio lobiettivo dellhiding.

265

12.2 Semantica operazionale di CCS

Link pa q , (p[mid/out] | q[mid/in]) \mid, dove supponiamo che p e q interagiscano con


lesterno tramite le porte out ed in, rispettivamente, e che mid sia una porta che non
usata n da p n da q. Per come definito, loperatore a mette in comunicazione tra
loro i due processi argomento obbligandoli a sincronizzarsi sulla porta mid.

12.2

Semantica operazionale di CCS

Vediamo adesso le regole dinferenza che definiscono la semantica operazionale in stile SOS di
ogni singolo operatore CCS. Va detto che tutti sono stati gi definiti nel Capitolo 10, riteniamo
tuttavia opportuno riportare qui la loro semantica per facilit di consultazione.
Processo inattivo. Il processo nil non ha regole; di conseguenza, non capace di eettuare
alcuna transizione.
Azione prefissa. Loperatore di azione prefissa ha una sola regola. Per questo operatore
la regola di inferenza non ha premesse e viene anche detta assioma.

.p ! p
La regola aerma che un processo della forma .p pu eseguire e poi comportarsi come p.
Scelta o somma. Loperatore di scelta ha due regole simmetriche.

p ! p0

q ! q0

p + q ! p0

p + q ! q0

Tali regole ci dicono che un processo della forma p + q pu comportarsi come uno dei due
(sotto)processi p e q, a seconda dellinterazione oerta dallambiente. Va detto che se uno
dei due sottoprocessi eettua unazione interna, lambiente pu non riuscire a controllare la
scelta.
Composizione parallela. La semantica delloperatore di composizione parallela definita
da tre regole, le prime due sono simmetriche ed indicano che | intercala le azioni dei due
processi argomento.

p ! p0

q ! q0

p|q ! p0 |q

p|q ! p|q 0

La terza regola permette ai processi argomento di sincronizzarsi fra di loro eettuando azioni
complementari (cio input ed output sulla stessa porta); in questo caso lazione risultante
unazione interna .

p ! p0 , q ! q 0

p|q ! p0 |q 0

266

Capitolo 12 Calculus of Communicating Systems (CCS)

(pref)

.p ! p

p ! p0

(sum1)

p + q ! p0

(par1)

p ! p0

p|q ! p0 |q

(sum2)

q ! q0

(par2)

p|q ! p|q 0

q ! q0

p + q ! q0

(sincr)

p|q ! p0 |q 0

p ! p0

(res)

p ! p0

p\L ! p0 \L

p ! p0 q ! q 0

(rel)

(, 2
/ L)

p[f ]

f()

! p0 [f ]

(def)

p ! p0

C ! p0

(C , p)

Tabella 12.2: Semantica operazionale di CCS

Restrizione. Loperatore di restrizione ha una sola regola.

p ! p0

p\L ! p0 \L

(, 2
/ L)

La regola dice che il processo p\L pu eseguire solo azioni tali che n loro n le loro complementari appartengono allinsieme L . La restrizione in eetti localizza le azioni
dellinsieme L, dato che loperatore proibisce allambiente di interagire con il processo usando
quelle azioni. Si noti che lazione interna non pu mai essere ristretta.
Relabelling. Anche loperazione di relabelling ha una sola regola.

p ! p0
p[f ]

f()

! p0 [f ]

dove la funzione f : ACCS ! ACCS unestensione della funzione f cos definita: f( ) = ,


f(a) = f (a) e f(a) = f (a), 8a 2 . Intuitivamente, p[f ] pu eseguire le stesse transizioni di
p, ma le sue azioni visibili sono ridenominate tramite f .
Costanti di processo. La semantica delle costanti di processo definita da una sola regola
che sostanzialmente dice che il comportamento della costante C dato dal processo p che
rappresenta il corpo della definizione C , p.

p ! p0

C ! p0

(C , p)

Le regole dinferenza che definiscono la semantica operazionale di CCS sono raggruppate


nella Tabella 12.2. Nel seguito, gli operatori composizione parallela, restrizione e relabelling

267

12.2 Semantica operazionale di CCS

saranno talvolta detti operatori statici in quanto, esaminando le conclusioni delle corrispondenti regole operazionali, si pu notare che essi sono presenti sia a sinistra che a destra del
simbolo di transizione. Ci dierente dal caso dei restanti operatori che invece saranno detti
dinamici.
Esempio 12.5. Consideriamo il processo M dellesempio 12.3 e vediamo le sue possibili
transizioni. Usando la regola per il prefisso (pref), si deriva la seguente transizione:
put.get.M

put

! get.M

Usando questo fatto e la regola per la scelta (sum1), si ha anche che:


put.get.M + put_ack.get_ack.M

put

! get.M

Quindi, usando la regola (def) per le costanti di processo, possibile determinare che:
M

put

! get.M

Utilizzando lo stesso tipo di ragionamento e le regole (rel), (par1) e (res), si pu dedurre


che il processo P dellesempio 12.4 pu eettuare la seguente transizione:
P

send

(msg.ack.S)[put/msg, get_ack/ack]| M | R[get/msg, put_ack/ack]


\ {get, get_ack, put, put_ack}

Si noti che questa lunica azione inizialmente possibile per P , dato che le azioni iniziali di
M e R[] sono tutte ristrette.
La definizione della semantica operazionale mostra che in realt lo stesso calcolo di processo
CCS pu essere visto come un unico LTS. Infatti, abbiamo che la tripla
hPCCS , ACCS , ! i
costituisce un LTS, dove:
PCCS linsieme di tutti i processi CCS sintatticamente corretti,
ACCS linsieme di tutte le azioni CCS,
! indica la relazione di transizione definita dalle regole in Tabella 12.2.
Questa osservazione vale anche per altri calcoli di processo ed ha due conseguenze importanti.
La prima che alcune definizioni, come quelle di equivalenze comportamentali e ordinamenti per ranamento, possono essere date in modo indipendente dal linguaggio, definendole
direttamente su LTS generici.
La seconda conseguenza che ad ogni descrizione in CCS di un sistema, pu essere associato un LTS con uno stato iniziale che rappresenta il sistema. In pratica ci vuol dire che ad
ogni termine sintattico corrisponde semanticamente un LTS con stato iniziale. Formalmente,
ad ogni processo p associata la quadrupla
hPCCS , ACCS , ! , pi

268

Capitolo 12 Calculus of Communicating Systems (CCS)

Figura 12.2: Grafo delle transizioni associato a P


che costituisce un LTS con stato iniziale p. Dato che gli insiemi PCCS e ACCS sono infiniti,
questa osservazione ha solo una valenza teorica. Abbiamo per che non tutti gli stati in PCCS
sono raggiungibili da p attraverso ! e non tutte le azioni di ACCS sono eettuabili da p
e dalle sue derivate. Quindi possibile definire un altro LTS contenente solo i termini CCS
raggiungibili da p tramite sequenze di transizioni ed azioni eettuabili da p e dalle sue derivate.
Se tale LTS contiene un numero finito di stati e di azioni, allora pu essere analizzato usando
algoritmi per la manipolazione di macchine a stati finiti.
Ad esempio, la Figura 12.2 illustra il grafo delle transizioni del LTS a stati finiti
corrispondente al protocollo di comunicazione P descritto nellesempio 12.4.

12.3

CCS con passaggio di valori

Consideriamo un sistema che riceve sul canale in un valore v 2 V, dove V , {v1 , v2 , . . . , vn }, e


successivamente lo inoltra sul canale out. Una possibile implementazione del sistema in CCS

269

12.3 CCS con passaggio di valori


Processo inattivo
Azione prefissa (a 2 )
Somma (I insieme di indici)
Composizione parallela
Restrizione (L )
Relabelling (f : ! )
Operatore condizionale
Costanti di processo

nil
a(x)., a
e., .
P
i2I
|
\L
[f ]
if be then
A(e1 , . . . , en )

Tabella 12.3: Sintassi di CCS con passaggio di valori


la seguente:
C

inv1 .outv1 .C+


inv2 .outv2 .C+
..
.
invn .outvn .C

In pratica si codificano i valori tramite canali di comunicazione, e si introduce un canale per


ogni valore.
Ovviamente in un calcolo che permette di trasmettere valori sui canali, lo stesso sistema
sarebbe descrivibile in maniera pi sintetica nel modo seguente:
C , in(x). out x. C
In questa sezione presentiamo prima CCS con passaggio di valori e quindi la sua traduzione
in CCS puro (che quello visto finora) che ci permetter di riutilizzare per il calcolo con
passaggio esplicito di valori tutti gli strumenti semantici introdotti per la versione pura. Si
rimanda il lettore interessato alla Sezione 10.10 per considerazioni generali e motivazioni.
La sintassi di CCS con passaggio di valori, riportata nella Tabella 12.3, del tutto simile
a quella di CCS puro vista allinizio di questo capitolo. Ci limitiamo a far notare la presenza
delle espressioni sui valori negli operatori di prefisso e nelle costanti di processo ed anche come
guardia delloperatore condizionale. Nella tabella, non definiamo la sintassi e la semantica
delle espressioni sui valori, indicate genericamente con e, e di quelle condizionali, indicate
genericamente con be; la loro struttura ininfluente ai fini della definizione della semantica
dei processi. Nel resto della sezione, semplicemente assumeremo che esista un meccanismo di
valutazione delle espressioni, anche di quelle condizionali, chiuse (cioe, che non contengono
variabili) ed useremo val(e) 2 V e val(be) 2 {true, f alse} per denotare il valore risultante
dalla valutazione delle espressioni e o be, rispettivamente.
Per dare una semantica a CCS con passaggio di valori possiamo seguire pi strade. Per
esempio, possiamo definire una semantica operazionale in stile SOS simile a quella data per
CCS puro oppure possiamo definire una semantica per traduzione in espressioni di cui conosciamo la semantica, per esempio traducendo ogni processo CCS con passaggio di valori in
CCS puro. Il primo approccio stato accennato nella Sezione 10.10; qui invece seguiremo il
secondo approccio.
Per definire la traduzione useremo la funzione b che prende come argomento un termine in
CCS con passaggio di valori e restituisce il corrispondente termine in CCS puro. La definizione

270

Capitolo 12 Calculus of Communicating Systems (CCS)


F
nil
a(x).p
a
e.p
.p
P
i2I pi
p1 | p 2
p\L
p[f ]
if b then p
A(e1 , . . . , en )

Fb
nil
P

\
av .p{v/x}
aval(e) .b
p
.b
p
P
bi
i2I p
pb1 | pb2
pb\{av : a 2 L, v 2 V}
pb[fb], dove fb(av ) = f (a)v

pb
se val(be) = true
nil altrimenti
Aval(e1 ),...,val(en )
v2V

Tabella 12.4: Semantica di CCS con passaggio di valori per traduzione in CCS puro
P
di b riportata in Tabella 12.4. Si noti che, per semplicit, usiamo loperatore
al posto
delloperatore + anche in CCS puro. A questo proposito, per evitare di dover introdurre
somme infinite essenziale far uso dellipotesi che linsieme dei valori V sia finito. Cos, il
P
\ dove le azioni av rappresentano tutti i
termine a(x).p tradotto nel termine v2V av .p{v/x},
valori che x pu assumere. Similmente, il termine A(e1 , . . . , en ) tradotto in Aval(e1 ),...,val(en )
dove al contempo si definiscono tante costanti Av1 ,...,vn per ogni possibile n-upla di valori
v1 , . . . , vn .

12.4

Equivalenze e preordini osservazionali per CCS

In questa sezione approfondiremo le propriet delle relazioni di bisimulazione e bisimilarit, e


dei preordini di testing per processi CCS. In particolare, vedremo che mentre la bisimilarit
forte una congruenza per CCS, nel senso che preservata da tutti gli operatori del calcolo,
altrettanto non si pu dire per quella debole e per il preordine di testing. Per questi ultimi
comunque presenteremo una utile caratterizzazione della pi grande (pre)congruenza in esse
contenuta.
Nel resto del capitolo faremo riferimento al sistema di transizioni etichettate che definisce la
semantica operazionale di CCS, cio hPCCS , ACCS , ! i. Per cui, anche se non eplicitamente
specificato, i processi e le azioni con cui lavoreremo saranno elementi di PCCS ed ACCS ,
rispettivamente. Inoltre, useremo per indicare identit sintattica di due termini.

12.4.1

Bisimulazioni e bisimilarit forte

Per comodit, riformuliamo la definizione di bisimulazione forte data nel Capitolo 11


direttamente per termini CCS.
Definizione 12.6 (Bisimulazione forte per CCS).
Una relazione R PCCS PCCS una bisimulazione forte se, dati due processi p e q tali
che hp, qi 2 R, allora le seguenti condizioni sono soddisfatte:

271

12.4 Equivalenze e preordini osservazionali per CCS

1. per ogni 2 ACCS e p0 2 PCCS , se p ! p0 allora q ! q 0 per qualche q 0 2 PCCS tale


che hp0 , q 0 i 2 R;
2. per ogni 2 ACCS e q 0 2 PCCS , se q ! q 0 allora p ! p0 per qualche p0 2 PCCS tale
che hp0 , q 0 i 2 R.
Definizione 12.7 (Bisimilarit forte per CCS).
Due processi p, q 2 PCCS sono fortemente bisimili, scritto p q, se esiste una bisimulazione
forte che contiene la coppia hp, qi. In pratica, la relazione , detta anche bisimilarit forte,
lunione di tutte le possibili bisimulazioni forti. Cio, formalmente, abbiamo:
[
,
{R | R una bisimulazione forte }

Nel capitolo precedente abbiamo enunciato e dimostrato alcune propriet generali della
relazione di bisimulazione forte su LTS generici. Dimostriamo ora che la bisimilarit ()
una relazione di congruenza per CCS, cio sostituitiva per tutti gli operatori sui processi
ed anche per le definizioni ricorsive di costanti di processo. Quindi, se due processi CCS
sono fortemente bisimili, allora possono essere inter-scambiati in un qualunque contesto CCS.
Dimostriamo prima la propriet per tutti gli operatori CCS.
Proposizione 12.8. Siano p, q, r 2 PCCS , L ed f : ! . Allora p q implica
1. .p .q
2. p + r q + r
3. p|r q|r
4. p \ L q \ L
5. p[f ] q[f ]
Dimostrazione. Per dimostrare il punto 1. suciente esibire una bisimulazione forte R0 che
contiene la coppia h.p, .qi. Definiamo R0 a partire da una (qualsiasi) bisimulazione forte R
che contiene la coppia hp, qi, la quale esiste per ipotesi. La definizione la seguente:
R0 , {h.p, .qi} [ R
R0 una bisimulazione forte. Infatti, essa ovviamente chiusa per transizioni perch R lo
e perch le uniche transizioni di .p e .q portano in p e q, rispettivamente.
Per il punto 2., si pu procedere in maniera simile. Cos, se R una bisimulazione forte
che contiene la coppia hp, qi, allora la bisimulazione forte cercata R0 la seguente:
R0 , {hp + r, q + ri} [ R [ Id
Mostriamo che R0 chiusa rispetto alle transizioni (gi sappiamo che R e Id lo sono). Sia

p + r ! t; questo pu essere dovuto a due situazioni:

Caso 1 p ! p0 e t p0 .

Allora, poich R una bisimulazione forte e hp, qi 2 R, esiste q 0 2 PCCS tale che q ! q 0
e hp0 , q 0 i 2 R. Dato che R R0 , abbiamo hp0 , q 0 i 2 R0 .

272

Capitolo 12 Calculus of Communicating Systems (CCS)

Caso 2 r ! r0 e t r0 .

In questo caso abbiamo ovviamente q + r ! r0 e hr0 , r0 i 2 R0 , dato che hr0 , r0 i 2 Id ed


Id R0 .
La tesi segue grazie ad un argomento simmetrico.
Per il punto 3., data una bisimulazione forte R che contiene la coppia hp, qi, suciente
dimostrare che la relazione
R0 , {hr1 | t, r2 | ti : t 2 PCCS ^ hr1 , r2 i 2 R}
una bisimulazione forte. A quel punto, infatti, la tesi discende dal fatto che, per costruzione,

hp| r, q| ri 2 R0 . Vediamo allora che R0 chiusa per transizioni. Sia r1 | t ! t0 ; questo pu


essere dovuto a tre situazioni distinte:

Caso 1 r1 ! r10 e t0 r10 | t.

Allora, poich hr1 , r2 i 2 R, abbiamo che r2 ! r20 con hr10 , r20 i 2 R; da questo si ha

r2 | t ! r20 | t e, per definizione di R0 , hr10 | t, r20 | ti 2 R0 .

Caso 2 t ! t00 e t0 r1 | t00 .

Allora, con un ragionamento analogo, abbiamo anche r2 | t ! r2 | t00 e, per definizione di


R0 , hr1 | t00 , r2 | t00 i 2 R0 .

Caso 3 = , r1 ! r10 ^ t ! t00 e t0 r10 | t00 .

Allora, poich hr1 , r2 i 2 R, abbiamo che r2 ! r20 con hr10 , r20 i 2 R; da questo si ha

r2 | t ! r20 | t00 e, per definizione di R0 , hr10 | t00 , r20 | t00 i 2 R0 .


Da quanto detto sopra, tramite un argomento simmetrico, segue che R0 una bisimulazione.
La dimostrazione per 4. simile e, data una bisimulazione forte R che contiene la coppia
hp, qi, utilizza la bisimulazione forte
R0 , {hr1 \ L, r2 \ Li : hr1 , r2 i 2 R}
La dimostrazione per 5. simile e, data una bisimulazione forte R che contiene la coppia
hp, qi, utilizza la bisimulazione forte
R0 , {hr1 [f ], r2 [f ]i : hr1 , r2 i 2 R}
Per dimostrare che le definizioni di costanti di processo preservano , estendiamo prima
la definizione di al caso dei contesti CCS.
Definizione 12.9. Due contesti CCS C[] e D[] sono fortemente bisimili, scritto C[] D[],
se per ogni processo p 2 PCCS si ha C[p] D[p].
Siamo ora pronti a dimostrare, facendo uso della definizione di bisimulazione forte up to
introdotta nella Definizione 11.16, la propriet desiderata1 .
1

Tale propriet una semplificazione di una propriet pi generale in cui si ha a che fare con singole
definizioni di costanti piuttosto che con sistemi di equazioni di definizione per pi costanti (rimandiamo il
lettore interessato a Milner [Mil89], pag. 99).

273

12.4 Equivalenze e preordini osservazionali per CCS


Proposizione 12.10. Se A , C[A], B , D[B] e C[] D[] allora A B.
Dimostrazione. suciente dimostrare che la seguente relazione
S = {hE[A], E[B]i : E[] contesto CCS}

una bisimulazione forte up to . Infatti, prendendo E[] [] ne deriva che hA, Bi 2 S e


quindi A B. Per dimostrare che S una bisimulazione forte up to suciente dimostrare
che

se E[A] ! p0 allora per qualche q 0 , q 00 2 PCCS , E[B] ! q 00 q 0 con hp0 , q 0 i 2 S.


La dimostrazione procede per induzione sulla profondit della derivazione con la quale la

transizione E[A] ! p0 inferita. Ragioniamo esaminando i vari casi.


Caso 1 E[] [].

Quindi E[A] A e E[B] B. Perci A ! p0 , e poich A , C[A] abbiamo che,

con uninferenza pi breve, C[A] ! p0 . Allora, per induzione, possiamo assumere che
00

C[B] ! q q 0 con hp0 , q 0 i 2 S. Poich C[] D[], abbiamo allora che D[B] ! q 000 q 0

e visto che B , D[B] ne segue che E[B] B ! q 000 q 0 con hp0 , q 0 i 2 S.


Caso 2 E[] .F []
Quindi E[A] .F [A], questo fa si che p0 F [A]. Abbiamo anche che E[B]

.F [B] ! F [B]. Per costruzione hF [A], F [B]i 2 S, come richiesto.


Caso 3 E[] E1 [] + E2 []

E[A] E1 [A] + E2 [A]; ci sono quindi due casi per cui E[A] ! p0 :

E1 [A] ! p0 ;

E2 [A] ! p0 .
Esaminiamo il primo caso in quanto il secondo analogo. Poich la derivazione di

E1 [A] ! p0 pi corta di quella di E[A] ! p0 , per induzione possiamo assumere che

E1 [B] ! q 00 q 0 con hp0 , q 0 i 2 S. quindi possibile dedurre che E[B] E1 [B] +

E2 [B] ! q 00 q 0 come richiesto (dato che gi sappiamo che hp0 , q 0 i 2 S).


Caso 4 E[] E1 []|E2 []

Quindi E[A] E1 [A]|E2 [A]. Consideriamo la transizione E[A] ! p0 ; abbiamo tre casi
possibili
E1 [A] compie lazione e E2 [A] sta fermo;
E2 [A] compie lazione e E1 [A] sta fermo;
E1 [A] compie unazione e E2 [A] compie lazione complementare .
Esaminiamo il terzo caso che il pi complesso; gli altri due procedono in maniera

simile. In questo caso, abbiamo = , E1 [A] ! p01 , E2 [A] ! p02 e p0 p01 |p02 . Poich
le transizioni da E1 [A] e E2 [A] hanno uninferenza pi corta, per induzione possiamo

assumere che E1 [B] ! q100 q10 con hp01 , q10 i 2 S e E1 [B] ! q200 q20 con hp02 , q20 i 2 S.

274

Capitolo 12 Calculus of Communicating Systems (CCS)

Quindi, prendendo q 0 q10 |q20 e q 00 q100 |q200 abbiamo che E[B] E1 [B]|E1 [B] ! q 00
q 0 . Rimane da stabilire se hp0 , q 0 i 2 S. Ora, poich hp0i , qi0 i 2 S con i = 1, 2, per
definizione di S, per qualche contesto Hi [] si ha p0i Hi [A] e qi0 Hi [B], sempre per
i = 1, 2. Prendiamo allora il contesto H[] H1 []|H2 []. Abbiamo H[A] H1 [A]|H2 [A]
e H[B] H1 [B]|H2 [B] e, quindi, hp0 , q 0 i hH[A], H[B]i 2 S come richiesto.
Caso 5 E[] E1 []\L oppure E1 [][R]
Questo caso pi semplice del caso precedente e la prova lasciata per esercizio al
lettore.
Caso 6 E[] C con C , r
Quindi, E un contesto costante (cio senza buchi). Ne deriva che E[A] C e
E[B] C ed entrambi hanno la stessa -derivata p0 ; essendo il processo p0 un contesto
senza buchi si ha hp0 , p0 i hp0 [A], p0 [B]i e, quindi, hp0 , p0 i 2 S come richiesto.

12.4.2

Bisimulazioni, bisimilarit e congruenza debole

Per comodit, riportiamo su CCS la definizione di bisimulazione debole data nel Capitolo 11.
Definizione 12.11 (Bisimulazione debole per CCS).
Una relazione R PCCS PCCS una bisimulazione debole se, dati p e q tali che hp, qi 2 R,
allora le seguenti condizioni sono soddisfatte:

1. per ogni 2 ACCS e p0 2 PCCS , se p ! p0 allora q =


) q 0 per qualche q 0 2 PCCS tale
0
0
che hp , q i 2 R;
2. per ogni 2 ACCS e q 0 2 PCCS , se q ! q 0 allora p =
) p0 per qualche p0 2 PCCS tale
0
0
che hp , q i 2 R.
Definizione 12.12 (Bisimilarit debole per CCS).
Due processi p, q 2 PCCS sono debolmente bisimili, o osservazionalmente equivalenti, scritto
p q, se esiste una bisimulazione debole contenente hp, qi. La bisimilarit debole o equivalenza osservazionale, , lunione di tutte le bisimulazioni deboli. In modo equivalente,
possiamo scrivere:
[
,
{R | R una bisimulazione debole }
Nel capitolo precedente abbiamo enunciato e dimostrato alcune propriet generali della
relazione di bisimulazione debole su LTS generici. Dimostriamo adesso che la bisimilarit
debole preservata da tutti gli operatori CCS ad eccezione della scelta (ci a causa della
prelazione esercitata dellazione in connessione con loperatore di scelta). Cominciamo con
loperatore di azione prefissa per il quale la propriet una immediata applicazione della
Proposizione 11.46.
Proposizione 12.13. Se p q allora .p .q, 8 2 ACCS .
Dimostriamo ora che gli operatori statici preservano la bisimilarit debole.
Proposizione 12.14. Siano p, q, r 2 PCCS , L ed f : ! . Allora p q implica
1. p | r q| r

275

12.4 Equivalenze e preordini osservazionali per CCS


2. p \ L q \ L
3. p[f ] q[f ]

Dimostrazione. La dimostrazione in tutti e tre i casi simile alla corrispondente per la bisimilarit forte. Cominciamo a considerare il caso 1. Supponiamo che R una bisimulazione
debole che contiene la coppia hp, qi. suciente allora dimostrare che la relazione
R0 = {hr1 | t, r2 | ti : t 2 PCCS ^ hr1 , r2 i 2 R}
una bisimulazione debole. A quel punto, infatti, la tesi segue dal fatto che per costruzione
la coppia hp | r, q| ri 2 R0 . Per dimostrare che R0 una bisimulazione debole, prendiamo una

generica transizione r1 | t ! t0 e consideriamo i tre casi possibili:

Caso 1: r1 ! r10 e t0 r10 |t.

Allora, poich hr1 , r2 i 2 R, abbiamo che, per qualche r20 2 PCCS , r2 =


) r20 e hr10 , r20 i 2

R. Quindi r2 | t =
) r20 | t e, per definizione di R0 , hr10 | t, r20 | ti 2 R0 come richiesto.

Caso 2: t ! t00 e t0 r1 |t00 .

Allora, con un ragionamento analogo, r2 | t ! r2 | t00 , e per definizione di R0 abbiamo


hr1 | t00 , r2 | t00 i 2 R0 come richiesto.

Caso 3: = , r1 ! r10 e t ! t00 .

Allora, poich hr1 , r2 i 2 R, abbiamo che, per qualche r20 2 PCCS , r2 =


) r20 e hr10 , r20 i 2

R. Quindi r2 | t =
) r20 | t00 e, per definizione di R0 , hr10 | t00 , r20 | t00 i 2 R0 come richiesto.
Da questo, tramite un argomento simmetrico, segue che R0 una bisimulazione debole.
La dimostrazione per 2. simile e, data una bisimulazione debole R che contiene la coppia
hp, qi, utilizza la bisimulazione debole
R0 , {hr1 \ L, r2 \ Li : hr1 , r2 i 2 R}
La dimostrazione per 3. simile e, data una bisimulazione debole R che contiene la coppia
hp, qi, utilizza la bisimulazione debole
R0 , {hr1 [f ], r2 [f ]i : hr1 , r2 i 2 R}
Abbiamo quindi dimostrato che la bisimilarit debole preservata da tutti gli operatori ad
eccezione della scelta. Purtroppo, come gi accennato in precedenza, la bisimulazione debole
non completamente sostitutiva perch non preservata dalloperatore di scelta. Abbiamo
infatti che p q non implica p + r q + r, per qualsiasi processo r.
Per mostrare che non una congruenza, suciente esibire due processi p e q e un
contesto C[] tali che p q e C[p] 6 C[q]. Prendiamo i processi a.nil e .a.nil ed il contesto []+
b.nil. Ora, dalla Proposizione 11.47, segue che .a.nil a.nil. Tuttavia, abbiamo C[.a.nil] 6

C[a.nil]. Infatti, la transizione C[.a.nil] ! a.nil deve essere messa in corrispondenza con
una discendenza etichettata con del processo C[a.nil]; lunica discendenza possibile quindi
quella che lascia il processo C[a.nil] invariato. Daltra parte, si ha a.nil 6 C[a.nil], dato che

276

Capitolo 12 Calculus of Communicating Systems (CCS)

C[a.nil] pu eseguire una transizione b che non pu essere eseguita da a.nil; ci quindi mostra
che C[.a.nil] 6 C[a.nil]. Concludendo, non una congruenza, e la causa linterazione
delloperatore di scelta con le azioni interne iniziali di un processo.
Data limportanza che riveste la possibilit di sostituire un termine con uno equivalente in
qualsiasi contesto, si pone quindi il problema di determinare quale sia la pi grande congruenza
contenuta in . Indichiamo tale relazione con il simbolo c . Formalmente la si pu definire
come una relazione di congruenza tale che c e per ogni altra congruenza R tale che
R si ha R c . Per definizione, tale congruenza esiste (Id una congruenza ed inoltre
Id ); per la precedente definizione di c poco utile in pratica, per cui sarebbe meglio
trovare una caratterizzazione alternativa. A tale scopo introduciamo la relazione congruenza
osservazionale, denotata col simbolo
=.
Definizione 12.15. Due processi p, q 2 PCCS sono osservazionalmente congruenti, scritto
p
= q, se per ogni 2 ACCS

1. per ogni p0 2 PCCS , se p ! p0 allora esiste q 0 2 PCCS tale che q =


) q 0 e p0 q 0 ;
2. per ogni q 0 2 PCCS , se q ! q 0 allora esiste p0 2 PCCS tale che p =
) p0 e p 0 q 0 .

Si noti la somiglianza con la propriet di data dalla Proposizione 11.46 di pagina 243.

In eetti,le due relazioni dieriscono soltanto in due aspetti: nella definizione di


)
= si usa =

al posto di =
) , che si usa invece nella definizione di , e la definizione di
= non ricorsiva.

Il primo punto implica che ogni azione di p o q deve essere corrisposta da almeno unazione
dellaltro processo. Questo comunque vale solo per lazione iniziale, in quanto successivamente
si richiede p0 q 0 e non p0
= q 0 (infatti, come si detto, la definizione di
= non ricorsiva).

Vogliamo innanzitutto dare una caratterizzazione di = che mostri quanto questa sia vicina
alla bisimilarit debole . Introduciamo allora la nozione di sorta di un processo p per indicare
linsieme delle porte usate da p. Formalmente possiamo dare la seguente definizione.
Definizione 12.16. Sia L ACCS \ { }. Se le azioni di un processo p e di tutte le sue
derivate sono elementi di L [ { } allora diremo che L una sorta di p, o anche che p ha
sorta L, e scriveremo p : L.
Chiaramente ogni processo ha una sorta minima, data dallintersezione di tutte le sue
sorte, ma non sempre facile determinarla (data una porta che compare nella sintassi del
processo, bisogna fare unanalisi semantica per capire se il processo pu eettivamente eettuare unazione su quella porta). Un modo piuttosto naturale per assegnare una sorta ad
ogni processo p per induzione sulla sintassi; questa viene chiamata sorta sintattica di p ed
indicata con L(p).
Definizione 12.17. La sorta (sintattica) L(p) di un processo p definita come segue (per
induzione sulla sintassi di p):
L(nil)
L(.p)
L(.p)
L(p + q)
L(p|q)
L(p\L)
L(p[f ])

,
,
,
,
,
,
,

;
{} [ L(p)
L(p)
L(p) [ L(q)
L(p) [ L(q)
L(p) \ (L [ L)
{f ()| 2 L(p)}

277

12.4 Equivalenze e preordini osservazionali per CCS

dove si suppongono assegnate le sorte L(A) alle costanti di processo A 2 C in modo tale che
per ogni equazione di definizione A , p si abbia L(p) L(A).
La nozione di sorta sintattica ci sar utile in seguito quando sar necessario poter scegliere
porte nuove rispetto a quelle utilizzate dai processi presi in considerazione. Sar infatti
suciente supporre che sia sempre possibile scegliere una porta che non appartiene alle sorte
(sintattiche) di tali processi. Una prima applicazione nella dimostrazione della proposizione
successiva.
Proposizione 12.18. Siano p, q 2 PCCS tali che L(p) [ L(q) ACCS . Allora p
= q se, e
solo se, per ogni r 2 PCCS , p + r q + r.

Dimostrazione. ()) Dallipotesi p


= q e dalla Proposizione 12.19, segue che hp, qi 2 R per
qualche bisimulazione debole R. A partire da R, definiamo allora la seguente relazione:
R0 , {(p + r, q + r) : r 2 PCCS } [ R [ Id

e dimostriamo che una bisimulazione debole. Sia p + r ! t; questo pu essere dovuto a due
situazioni:

Caso 1 p ! p0 e t p0 .
Allora, poich hp, qi 2 R ed R una bisimulazione debole, abbiamo che, per qualche q 0 ,

q=
) q 0 e hp0 , q 0 i 2 R. Quindi, dato che R R0 , abbiamo che hp0 , q 0 i 2 R0 .

Caso 2 r ! r0 e t r0 .

In questo caso abbiamo ovviamente q + r ! r0 , quindi q + r =


) r0 . Ora, dato che
hr0 , r0 i 2 Id ed Id R0 abbiamo anche hr0 , r0 i 2 R0 .
La tesi segue da un argomento simmetrico.
(() Ragioniamo per assurdo, quindi supponiamo che p
6 q. Allora, senza perdita di
=

generalit, possiamo supporre che per qualche 2 ACCS e p0 2 PCCS si ha p ! p0 e o (i)

non esiste q 0 2 PCCS tale che q =


) q 0 , oppure (ii) per ogni q 0 2 PCCS tale che q =
) q 0 si
ha p0 6 q 0 . Sia r .nil dove 62 L(p) [ L(q). Vogliamo arrivare a contraddire lipotesi

p + r q + r. Nel caso (i), abbiamo che p + r ! p0 e q + r =


6 ) . Ora, se 6= , ci vuol dire

che q + r =
6 ) ; se invece = , abbiamo p0 6 q + r dato che q + r ! e p0 6 ! . Perci in ogni

caso non esiste t tale che q + r =


) t e p0 t. Nel caso (ii), poich 6= , tutte le -derivate t

di q + r sono dovute a q, cio q =


) t; quindi, date le assunzioni del caso (ii), p0
6 t. Quindi,

in entrambi i casi si ha p + a.nil ! p0 ma non esiste t 2 PCCS tale che q + a.nil =


) t e p0 t.
Per via della propriet di data dalla Proposizione 11.46, ci contraddice lipotesi che, per
ogni r 2 PCCS , p + r q + r.
Possiamo ora facilmente mostrare che
= si posiziona tra e .

Proposizione 12.19. Valgono le seguenti inclusioni:


=e
= .
Dimostrazione. Come prima cosa notiamo che dal fatto, facilmente verificabile dalle definizioni, che ogni bisimulazione forte anche una bisimulazione debole discende che . Questo
fatto, la Proposizione 11.14 di pagina 233 e la definizione di
= implicano che
=. Dimostriamo ora linclusione
= . Per la Proposizione 12.18, p
= q implica p + nil q + nil.

278

Capitolo 12 Calculus of Communicating Systems (CCS)

Ora, poich p+nil p, q +nil q e , abbiamo p+nil p e q +nil q. Per transitivit


possiamo quindi concludere che p q.
Vogliamo analizzare quanto le nozioni di congruenza osservazionale e bisimilarit debole sono vicine. Cos, dalla definizione di
=, si ricava immediatamente che prefissando con
unazione processi debolmente bisimili si ottengono processi osservazionalmente congruenti.
Proposizione 12.20. Se p q allora .p
= .q.

Anche la nozione di stabilit gioca un ruolo importante per passare da a


=. Si ricordi
che un sistema si dice stabile se non ha derivazioni (Sezione 3.5); analogamente, un processo

p 2 PCCS stabile se p 6 ! .
Proposizione 12.21. Se p e q sono stabili, allora p q implica p
= q.

Dimostrazione. Sia p ! p0 . Per ipotesi, e per la Proposizione 11.46 di pagina 243, esiste q 0

tale che q =
) q 0 e p0 q 0 . Per via dellipotesi di stabilit, 6= e, quindi, =
) e =
)

coincidono. Ne segue allora che q =


) q 0 e, quindi, p
= q segue per definizione.
Dimostriamo ora un risultato tanto inatteso quanto importante e che mostra ancora una
volta come le nozioni di bisimilarit debole e di congruenza osservazionale siano vicine. Questo
risultato stato dimostrato per la prima volta da Matthew Hennessy e verr sfruttato in
seguito per provare la completezza dellinsieme di assiomi che introdurremo.
Proposizione 12.22 (Lemma di Hennessy). p q se e solo se p
= q o .p
=q op
= .q

Dimostrazione. (() Tutte le implicazioni seguono dal fatto che p0


= q 0 implica p0 q 0
(Proposizione 12.19), eventualmente usando il fatto che r .r (Proposizione 11.47) ed il
fatto che transitiva.
()) Assumiamo che p q, e consideriamo tre casi esaustivi. Primo, se per qualche

0
p 2 PCCS si ha che p ! p0 e p0 q allora, dalla definizione di
=, segue che p
= .q.

0
0
0
Secondo, se per qualche q 2 PCCS si ha che q ! q e p q allora, ragionando come prima,
segue che .p
= q. Se nessuno dei due casi precedenti si verifica, allora si pu mostrare che

p = q nel modo seguente. Supponiamo dapprima che p ! p0 con 6= ; dal momento che

p q abbiamo che esiste q 0 tale che q =


) q 0 e q 0 p0 . Da ci segue che q =
) q 0 e p0 q 0

come richiesto dalla definizione di


=. Nellaltro caso, cio se p ! p0 , allora, dal momento che
p q, abbiamo q =) q 0 e p0 q 0 . Ora, non pu essere che q 0 q, altrimenti ricadremmo

nel primo caso considerato, quindi q =


) q 0 come richiesto dalla definizione di
= (assieme al
fatto gi noto che p0 q 0 ). La tesi segue allora da un argomento simmetrico.
Concludiamo con una importante propriet di
=: quella di essere una congruenza.
Proposizione 12.23.
= una relazione di equivalenza.
Dimostrazione. Discende direttamente dalla definizione di
= e dal fatto che
unequivalenza.
Facciamo ora vedere che
= preservata da tutti gli operatori CCS.
Proposizione 12.24. Se p
= q allora .p
= .q, p + r
= q + r, p|r
= q|r, p \ L
= q\L e
p[f ]
= q[f ].

12.4 Equivalenze e preordini osservazionali per CCS

279

Dimostrazione. .p
= .q discende direttamente dalla proposizione precedente e dalla Proposizione 12.20. Le rimanenti uguaglianze si possono dimostrare applicando direttamente la
definizione di
=.
Per dimostrare che
= preservata dalloperatore di scelta, supponiamo che p
= q e che

r 2 PCCS e facciamo vedere che p + r = q + r. Supponiamo allora che p + r ! t. Ci sono

due casi possibili. Se p ! t allora, dallipotesi p


= q, segue che esiste q 0 2 PCCS tale che

q=
) q 0 e t q 0 . La tesi per questo caso segue allora dal fatto che q + r =
) q 0 . Se r ! t allora,

ovviamente, q + r =
) t. La tesi segue tramite un argomento simmetrico.
Per dimostrare che
= preservata dalloperatore di composizione parallela, supponiamo

che p = q e che r 2 PCCS e facciamo vedere che p|r


= q|r. Supponiamo allora che p|r ! t. Ci

sono tre casi possibili. Se p ! p0 e t p0 |r allora, dallipotesi p


= q, segue che esiste q 0 2 PCCS

tale che q =
) q 0 e p0 q 0 . Poich preservata dalloperatore di composizione parallela,

abbiamo p0 |r q 0 |r e quindi la tesi per questo caso dimostrata. Se r ! r0 e t p|r0 allora,

ovviamente, abbiamo anche q|r =


) q|r0 . Inoltre, dallipotesi p
= q, dalla Proposizione 12.19 e
dal fatto che preservata dalla composizione parallela segue che p|r0 q|r0 , che dimostra

la tesi per questo caso. Se = , p ! p0 , r ! r0 e t p0 |r0 allora, dallipotesi p


= q, segue

che esiste q 0 2 PCCS tale che q =


) q 0 e p0 q 0 . Quindi q|r =
) q 0 |r0 e poich preservata
dalloperatore di composizione parallela, abbiamo p0 |r0 q 0 |r0 e quindi la tesi anche in questo
caso dimostrata. Possiamo allora concludere tramite un argomento simmetrico.
Per dimostrare che
= preservata dalloperatore di restrizione, supponiamo che p
=q e

che L e facciamo vedere che p \ L = q \ L. Supponiamo che p \ L ! t. Ci vuol dire


che, per qualche p0 2 PCCS , , 62 L e t p0 \ L (ci pu essere dimostrato per induzione

sulle regole di Tabella 12.2). Dallipotesi p


) q0 e
= q, segue che esiste q 0 2 PCCS tale che q =

p0 q 0 . Poich , 62 L, abbiamo anche che q \ L =


) q 0 \ L. Inoltre, poich preservata
dalla restrizione, abbiamo p0 \ L q 0 \ L. La tesi segue da un argomento simmetrico.
Per dimostrare che
= preservata dalloperatore di relabelling, supponiamo che p
=q e

che f : ! e facciamo vedere che p[f ] = q[f ]. Supponiamo che p[f ] ! t. Ci vuol dire che,
0

per qualche 0 2 ACCS e p0 2 PCCS , f (0 ) = , p ! p0 e t p0 [f ] (ci pu essere dimostrato


per induzione sulle regole di Tabella 12.2). Dallipotesi p
= q, segue che esiste q 0 2 PCCS
0

tale che q =) q 0 e p0 q 0 . Segue allora che q[f ] =


) q 0 [f ]. Inoltre, poich preservata dal
0
0
relabelling, abbiamo p [f ] q [f ]. La tesi segue da un argomento simmetrico.
Per completare la dimostrazione che
= una congruenza, ci resta da far vedere che
preservata2 anche dalle definizioni delle costanti di processo. Estendiamo prima la definizione
di
= al caso dei contesti CCS, quindi enunciamo la propriet desiderata.
Definizione 12.25. Due contesti CCS C[] e D[] sono osservazionalmente congruenti, scritto
C[]
= D[], se per ogni processo p 2 PCCS si ha C[p]
= D[p].
Proposizione 12.26. Se A , C[A], B , D[B] e C[]
= D[] allora A
= B.
Dimostrazione. Si comincia col dimostrare che la relazione

S = {hE[A], E[B]i : E[] contesto CCS}

Anche nel caso di


=, come gi fatto per , ci limiteremo a considerare una semplificazione di una propriet
generale in cui si ha a che fare con singole definizioni di costanti piuttosto che con sistemi di equazioni di
definizione per pi costanti (rimandiamo il lettore interessato a Milner [Mil89], pag. 155).

280

Capitolo 12 Calculus of Communicating Systems (CCS)

gode della seguente propriet

se E[A] ! p0 allora per qualche q 0 2 PCCS , E[B] =


) q 0 con p0 S q 0

(12.1)

se E[B] ! q 0 allora per qualche p0 2 PCCS , E[A] =


) p0 con p0 Sq 0 .

La dimostrazione procede per induzione sulla profondit della derivazione con la quale la

transizione E[A] ! p0 inferita (il caso della transizione E[B] ! q 0 analogo). I dettagli sono
simili a quelli della dimostrazione della Proposizione 12.10. Ora, per la Proposizione 11.52 di
pagina 245, il fatto che S soddisfa la propriet precedente implica che S una bisimulazione

debole up to . Infatti, luso di =


) al posto di =
) rende la propriet (12.1) pi forte di
quella su cui si basa la Proposizione 11.52. Quindi p0 S q 0 e p0 Sq 0 implicano p0 q 0 .
Perci, prendendo E[] [], per cui abbiamo E[A] A e E[B] B, otteniamo A
= B per
via della definizione di
=.
In questa sezione abbiamo introdotto una semantica osservazionale completamente sostitutiva e molto vicina alla bisimilarit debole. Si potrebbe allora pensare che la bisimilarit
debole sia ridondante. Invece, le dimostrazioni basate sulla costruzione di bisimulazioni deboli
sono molto convenienti, ed inoltre, stabilire la bisimilarit debole molto naturale e spesso
meccanizzabile. Una volta stabilito che p q, proposizioni quali la 12.21 e 12.22 possono
essere utilizzate per stabilire che p
= q. Concludiamo la sezione mostrando alcuni esempi.
Esempio 12.27.
1. a..b.nil a.b.nil e a..b.nil
= a.b.nil.
2. .a.nil a.nil ma .a.nil
6 a.nil, dato che la transizione
=

corrispondere ad una transizione =


) di a.nil.

! di .a.nil non pu

3. Svc
= P , dove Svc , send.recv.Svc e P il processo (corrispondente ad un semplice
protocollo di comunicazione) definito in Sezione 12.2.

12.4.3

Equivalenze basate su testing

In questa sezione studiamo il comportamento dellequivalenza test 'test relativamente agli


operatori CCS. Purtroppo risulta che neanche 'test una congruenza. Per dimostrarlo basta
individuare un contesto che non preserva la relazione 'test . Ragioniamo allora come segue.
Sappiamo che a 'test .a; infatti, a 'm .a vale perch i due processi hanno le stesse tracce
deboli e a 'M .a vale perch gli unici osservatori interessanti sono w e a
.w che non possono
distinguere i due processi. Se ora consideriamo il contesto b + [ ], otteniamo che b + a 6'test
b + .a. Infatti, abbiamo che b + a must satisfy b.w mentre non vero che b + .a must

satisfy b.w perch la computazione (b + .a)|b.w ! a|b.w non ha successo.


In maniera simile a quanto fatto per la bisimilarit debole, possibile modificare leggermente la definizione dei preordini must e test in modo che i preordini e le equivalenze risultanti
siano preservati da tutti gli operatori CCS.

Definizione 12.28 (Precongruenza must). p vcM q se e solo se p vM q ^ (q ! ) p ! ).


Definizione 12.29 (Precongruenza test). p vctest q se e solo se p vtest q ^ (q ! ) p ! ).

281

12.5 Ragionamento equazionale in CCS

(riflessivit)

t1 = t 1

(sostitutivit)

(simmetria)

t1 = t2
t2 = t1

(transitivit)

t1 = t01 . . . tk = t0k
C(t1 , . . . , tk ) = C(t01 , . . . , t0k )

t 1 = t2

t2 = t 3

t1 = t3

C operatore di arit k

Tabella 12.5: Regole dinferenza

La dierenza minima ma fondamentale: si richiede infatti che se q pu inizialmente


fare unazione interna, allora anche p deve poter fare inizialmente unazione interna. Si pu
in eetti dimostrare che vcM una precongruenza per CCS ed anche che la pi grande
precongruenza contenuta in vM (ci giustifica la notazione usata). Un risultato analogo vale
per vctest e per le equivalenze che costituiscono i nuclei dei preordini.

12.5

Ragionamento equazionale in CCS

Come abbiamo detto nellIntroduzione esistono vari approcci per definire semantiche formali
per calcoli di processo. Finora abbiamo esaminato lapproccio operazionale; in questa sezione
esamineremo lapproccio equazionale. Tale approccio permette di stabilire la validit o meno
di una relazione tra processi attraverso semplici manipolazioni sintattiche dei processi stessi,
quindi senza utilizzare la semantica operazionale.
Lapproccio equazionale consiste nellindividuare un certo numero di regole dinferenza che
costituiscono quello che si chiama sistema di prova. Ci che distingue un sistema di prova da
un altro linsieme degli assiomi, che pu essere visto come unalgebra di processi. Linguaggi
di processi dierenti ed equivalenze dierenti conducono ad algebre di processi dierenti.
Come vedremo infatti, gli assiomi sono specifici della relazione che si intende catturare (per
esempio, bisimilarit o testing).
Oltre agli assiomi, un sistema di prova contiene di solito le regole dinferenza presentate
nella Tabella 12.5. Esse riflettono il fatto che ogni termine uguale a se stesso (riflessivit),
che se un termine uguale ad un altro allora vero anche il contrario (simmetria), che
termini uguali ad uno stesso termine sono uguali tra loro (transitivit), e che allinterno di
certi contesti termini uguali possono essere sostituiti gli uni agli altri (sostitutivit). In pratica
ci vuol dire che la relazione risultante dal sistema di inferenza una equivalenza e, talvolta,
una congruenza (quando la sostituzione si pu applicare a tutti i contesti del linguaggio). Le
regole nella Tabella 12.5 vengono di solito usate implicitamente per la costruzione di prove
per cui nel seguito menzioneremo solo gli assiomi dei vari sistemi. Quando esiste una prova
per i termini t1 e t2 usando le regole suddette e gli assiomi di un certo insieme E, scriveremo
E ` t1 = t2 .
Data una certa assiomatizzazione, cio un certo insieme di assiomi, ed una relazione di
equivalenza, ad esempio, comportamentale importante stabilire la relazione esistente tra le
uguaglianze che lassiomatizzazione ci permette di dimostrare e la relazione in questione. In
particolare, importante garantire che:
1. lassiomatizzazione corretta: ovvero, tutte le uguaglianze che riusciamo a dimostrare nel sistema di prova valgono per lequivalenza comportamentale che stiamo

282

Capitolo 12 Calculus of Communicating Systems (CCS)


(A1)
(A2)
(A3)
(A4)

p+q
p + (q + r)
p + nil
p+p

=
=
=
=

q+p
(p + q) + r
p
p

Tabella 12.6: Assiomatizzazione di per CCS di base: insieme E1


considerando;
2. lassiomatizzazione completa: ovvero, tramite il sistema di prova riusciamo a dimostrare tutte le uguaglianze che valgono per lequivalenza comportamentale che stiamo
considerando.
La correttezza ovviamente unassoluta necessit; un sistema di prova non corretto non
utilizzabile, dato che permette la derivazione di uguaglianze che non hanno un corrispettivo
nellequivalenza comportamentale scelta. La completezza desiderabile, dato che un sistema
completo garantisce che possibile derivare tutte le uguaglianze determinate dallequivalenza
comportamentale.
In questa sezione, presenteremo alcune assiomatizzazioni corrette e complete, per certe
classi di processi, della bisimilarit forte, della congruenza osservazionale e dei preordini basati
su testing.

12.5.1

Assiomatizzazione di

Presentiamo lassiomatizzazione di per CCS in modo incrementale, partendo da CCS di


base e considerando successivamente sottolinguaggi di CCS sempre pi ampi.
Assiomatizzazione per CCS di base. CCS di base contiene solo il processo costante nil,
loperatore di azione prefissa e quello di scelta; di conseguenza permette solo la definizione
di sistemi sequenziali (senza parallelismo) e finiti (che eseguono sequenze finite di transizioni). Lassiomatizzazione di per CCS di base consiste di soli quattro assiomi, elencati in
Tabella 12.6, detti anche leggi monoidali.
Indichiamo con E1 linsieme che contiene i quattro assiomi di Tabella 12.6. Per convenienza
associamo un nome ad ogni assioma; in questo caso gli assiomi si chiamano (A1)-(A4). Ogni
assioma dato in termini processi arbitrari del linguaggio in considerazione, in questo caso
CCS di base. In (A2), per esempio, p, q e r sono processi generici, e lassioma asserisce
che, sostituendo ad ogni processi generico qualunque processo CCS di base, luguaglianza
verificata.
Commentiamo brevemente gli assiomi dellinsieme E1 . Gli assiomi (A1) e (A2) indicano
rispettivamente che + commutativo e associativo. Questo significa che espressioni della
forma p1 + . . . + pn , anche se non contengono parentesi nelle giuste posizioni, sono legittime
ed hanno un significato preciso, dato che tutte le giustapposizioni di parentesi sono equivalenti.
Lassioma (A3) indica che nil lelemento neutro per +. Questi primi tre assiomi fanno s
che CCS di base sia un monoide. Lultimo assioma detto anche legge di assorbimento, dato
che permette di assorbire copie multiple della stesso processo in una sola.

283

12.5 Ragionamento equazionale in CCS


(A1)-(A4) dalla Tabella 12.6
(Exp)

i2I

i .pi |

j2J

0j .qj

P
P
P

i2I

j2J

i . pi |
0j . (

j2J

i2I

0j .qj +

i .pi ) | qj

{(i,j) | i =0j } .(pi | qj )

Tabella 12.7: Assiomatizzazione di per CCS di base con parallelo: insieme E2


Esempio 12.30. Mostriamo come usare assiomi per costruire prove equazionali.
a.(b.nil + nil) + (a.nil + a.b.nil) = a.b.nil + (a.nil + a.b.nil)

da (A3)

= a.b.nil + (a.b.nil + a.nil)

da (A1)

= (a.b.nil + a.b.nil) + a.nil

da (A2)

= a.b.nil + a.nil

da (A4)

Questa prova stabilisce che a.(b.nil + nil) + (a.nil + a.b.nil) = a.b.nil + a.nil in quattro passi,
dove ogni passo rappresenta una applicazione di un assioma ad un sottotermine, in modo
da produrne un altro, facendo uso delle regole dinferenza di Tabella 12.5 di cui si detto
allinizio di questa sezione. Quindi, possiamo scrivere
E1 ` a.(b.nil + nil) + (a.nil + a.b.nil) = a.b.nil + a.nil
possibile dimostrare che E1 unassiomatizzazione corretta e completa di per CCS
di base.
Assiomatizzazione per CCS di base con parallelo. Analizziamo adesso il sottolinguaggio ottenuto aggiungendo a CCS di base loperatore di composizione parallela. Per questo
motivo, lo chiameremo CCS di base con parallelo. Come si pu intuire, gli assiomi (A1)-(A4)
rimangono corretti per CCS di base con parallelo, ma non sono ovviamente completi, dato
che nessun assioma menziona il parallelo; quindi, per esempio, non possiamo uguagliare p|q
e q|p. Per definire unassiomatizzazione completa per questo nuovo sottoinsieme di CCS, occorre aggiungere degli assiomi per il parallelo. La nuova assiomatizzazione presentata in
Tabella 12.7.
Lunico nuovo assioma, (Exp), conosciuto come legge di espansione, dato che mostra come
un termine costruito usando il parallelo come operatore principale (cio, al livello pi alto),
pu essere espanso in un altro che invece utilizza la somma come operatore al livello pi alto.
In questo modo, tramite applicazioni ripetute di (Exp), possibile eliminare completamente
loperatore di composizione parallela da un termine.
In eetti, (Exp) il pi complicato assioma
Pdi CCS, e merita ulteriori commenti. In primo
luogo, si ricordi la definizione delloperatore i2I data nella SezioneP10.5: dato un indice I
e un insieme di termini della forma pi , indicizzato da I, si definisce i2I pi come nil se I
vuoto e come la somma di tutti i pi altrimenti. Si noti allora che (Exp) pu essere applicato
a un termine p1 |p2 solo se p1 e p2 hanno una certa forma: ognuno deve essere una somma

284

Capitolo 12 Calculus of Communicating Systems (CCS)

di termini il cui operatore pi esterno quello di azione prefissa. Ancora, bisogna dire che
(Exp) uno schema di assiomi; al variare di I e J si ottengono assiomi diversi. Infine, la parte
destra di (Exp) consiste di tre sommandi, ognuno dei quali corrisponde ad una diversa regola
SOS per loperatore di composizione parallela: il primo sommando permette al sottotermine
a sinistra del parallelo di muoversi in modo autonomo; il secondo fa la stessa cosa con quello
di destra; il terzo sommando gestisce le possibili sincronizzazioni.
Per vedere come (Exp) pu essere usato nelle prove, presentiamo un paio di esempi.
Esempio 12.31. Vediamo un semplice esempio di applicazione della legge di espansione.
p , . p0 + . p00

def

q = . q 0 + . q 00

def

r = p|q

Applicando la legge si ottiene:


def

r = (. (p0 | q) + . (p00 | q)) + (. (p | q 0 ) + . (p | q 00 )) + . (p0 | q 0 )


Se conosciamo la sintassi dei processi p0 , p00 , q 0 , q 00 possiamo iterare il procedimento fino ad
avere un processo con solo prefissi e somme.

Esempio
12.32. Mostriamo che E2 ` nil|b.nil = b.nil; ricordiamo che nil sta per il termine
P
i2; pi , con pi qualsiasi.
nil|b.nil = nil + b.(nil|nil) + nil

da (Exp)

= b.(nil|nil)

da (A3) due volte

= b.(nil + nil + nil)

da (Exp)

= b.nil

da (A3) due volte

Pi in generale, per ogni processo CCS di base con parallelo p si pu dimostrare che
E2 ` nil|p = p; quindi, | ha nil come elemento neutro. possibile inoltre dimostrare che per
ogni p1 , p2 e p3 , E2 ` p1 |p2 = p2 |p1 e E2 ` p1 |(p2 |p3 ) = (p1 |p2 )|p3 ; conseguentemente, |
commutativo e associativo.
possibile dimostrare che E2 unassiomatizzazione corretta e completa di per CCS
di base con parallelo.
Assiomatizzazione per CCS finito. Consideriamo ora il sottolinguaggio di CCS che comprende tutti gli operatori a parte le costanti di processo; in letteratura questo sottolinguaggio
noto col nome di CCS finito. In altre parole, CCS finito estende CCS di base con parallelo
con gli operatori di restrizione e relabelling; gli assiomi per questo linguaggio sono presentati
in Tabella 12.8.
Gli assiomi per \L e [f ] esprimono solo come questi operatori interagiscono con nil, azione
prefissa e somma. Il fatto che non ci siano regole che descrivono linterazione tra | e \L oppure
tra \L e [f ], una conseguenza del fatto che le occorrenze pi interne di ciascun operatore
statico possono essere eliminate con luso ripetuto degli assiomi per loperatore in questione
in aggiunta agli assiomi (A1)-(A4).

285

12.5 Ragionamento equazionale in CCS


(A1)-(A4) da Tabella 12.6; (Exp) da Tabella 12.7
(Res1)

nil\L

(Res2)

(.p)\L

(Res3)
(Rel1)
(Rel2)
(Rel3)

(p + q)\L
nil[f ]
(.p)[f ]
(p + q)[f ]

=
=
=
=

nil

nil
se , 2 L
.(p\L) altrimenti
p\L + q\L
nil
f ().(p[f ])
p[f ] + q[f ]

Tabella 12.8: Assiomatizzazione di per CCS finito: insieme E3


Largomento precedente pu essere formalizzato e usato per di mostrare che linsieme di
regole E3 costituisce unassiomatizzazione corretta e completa di per CCS finito. Ci
proprio quello che faremo nel resto di questa sezione.
Cominciamo col dimostrare che le leggi introdotte nelle Tabelle 12.6, 12.7 e 12.8 sono
corrette rispetto a . Per ciascuna legge, la dimostrazione pu procedere esibendo una bisimulazione forte che contiene i due termini coinvolti nella legge. Una tale bisimulazione la si
pu costruire eettuando lunione della relazione identit con quella che contiene coppie di
termini di CCS finito della forma di quelli coinvolti nella legge in questione. Alternativamente,
la prova pu consistere nel dimostrare che i termini CCS coinvolti nella legge hanno le stesse
-derivate per ogni 2 ACCS ; a questo punto la tesi deriva sfruttando la propriet di data
dalla Proposizione 11.14 di pagina 233. Per illustrare entrambi i metodi, useremo il primo
nella dimostrazione di correttezza delle leggi monoidali ed il secondo in quella della legge di
espansione. La dimostrazione della correttezza delle leggi per restrizione e relabelling invece
lasciata per esercizio al lettore.
Proposizione 12.33 (Leggi monoidali). Le leggi nella Tabella 12.6, cio
1. p + q = q + p
2. p + (q + r) = (p + q) + r
3. p + p = p
4. p + nil = p
sono corrette rispetto a .
Dimostrazione. Per ciascuna legge t1 = t2 bisogna esibire una bisimulazione forte R tale che
ht1 , t2 i 2 R. Dimostreremo solo la correttezza della legge 2.; le altre dimostrazioni seguono
procedimenti simili ma sono pi semplici. Definiamo la relazione seguente:
R , {hp + (q + r), (p + q) + ri : p, q, r 2 PCCS } [ Id
e mostriamo che R chiusa rispetto alle transizioni (si ricordi che Id lo ). Supponiamo che

p + (q + r) ! t. Allora, dalle regole della semantica operazionale per la somma, si ha che

p ! t oppure q ! t oppure r ! t. In ognuno dei casi, usando ancora le regole della semantica

operazionale per la somma, possiamo facilmente inferire che (p + q) + r ! t. La tesi segue


da un argomento simmetrico.

286

Capitolo 12 Calculus of Communicating Systems (CCS)

Proposizione 12.34 (Legge di espansione). La legge (Tabella 12.7)


P
P
P
P
0
0
=
i2I i .pi |
j2J j .qj
i2I i . pi |
j2J j .qj +
P
P

corretta rispetto a .

j2J

0j . (

i2I

i .pi ) | qj

{(i,j) | i =0j } .(pi | qj )

Dimostrazione. suciente dimostrare che i termini CCS coinvolti nella legge di espansione
hanno le stesse -derivate per ogni 2 ACCS ; a questo puntoP
la tesi deriva P
dalla propriet di

0
espressa dalla Proposizione 11.14. Supponiamo allora che

.p
|
i2I i i
j2J j .qj ! t.
Dalle regole della semantica operazionale per la composizione parallela, otteniamo che si deve
presentare una delle seguenti tre situazioni:
P
P
k
Caso 1 = k per qualche k 2 I, i2I i .pi !
pk e t pk |( j2J 0j .qj );
Caso 2 = 0l per qualche l 2 J,

j2J

l
j .pj !
ql e t (

Caso 3 = , k = 0l per qualche k 2 I ed l 2 J,


t pk |ql .

i2I

i .pi )|ql ;

k
i2I i .pi ! pk ,

l
0
j2J j .qj ! ql e

In ognuno dei casi, usando le regole della semantica operazionale per la somma, possiamo
facilmente inferire che il termine a destra del simbolo di = nella legge di espansione ha t come derivata. Infatti, per ciascuna delle tre situazioni precedenti, abbiamo un caso corrispondente
P
P
P
k
0
Caso 1
! pk |( j2J 0j .qj ) per qualche k 2 I;
i2I i . pi |
j2J j .qj
P

0l

i .pi )|ql per qualche l 2 J;


n
o
P

0 .
Caso 3
.(p
|
q
)
!
p
|q
per
qualche
(k,
l)
2
(i,
j)
|

0
i
j
k
l
i
j
{(i,j) | = }
Caso 2

0
j2J j . (

i2I i .pi ) | qj

!(

i2I

In maniera simile si pu dimostrare il contrario, cio che ogni -derivata del termine a destra
del simbolo di = anche una -derivata del termine a sinistra. Per quanto detto prima, ci
suciente per ricavare la tesi.
Proposizione 12.35 (Leggi per restrizione e relabelling). Le leggi della Tabella 12.8, cio
1. nil\L = nil

nil
se , 2 L
2. (.p)\L =
.(p\L) altrimenti
3. (p + q)\L = p\L + q\L
4. nil[f ] = nil
5. (.p)[f ] = f ().(p[f ])

287

12.5 Ragionamento equazionale in CCS


6. (p + q)[f ] = p[f ] + q[f ]
sono corrette rispetto a .
Proposizione 12.36 (Correttezza). E3 ` p = q implica p q.

Dimostrazione. Le precedenti tre proposizioni dimostrano la correttezza degli assiomi; quindi


la tesi si riduce a dimostrare la correttezza delle regole di inferenza di Tabella 12.5. Ora,
dimostrare la correttezza delle prime tre regole equivale a dimostrare che una relazione
di equivalenza, cosa che abbiamo fatto con la Proposizione 11.13(2), mentre dimostrare la
correttezza della quarta regola equivale a dimostrare che preservata da tutti gli operatori
di CCS finito, cosa che abbiamo fatto con la Proposizione 12.8. Ne segue quindi che il sistema
di prova illustrato corretto per su processi di CCS finito.
Occupiamoci ora di dimostrare la completezza del sistema di prova per su CCS finito.
A questo scopo introduciamo una forma sintattica particolare per i processi a cui comunque
tutti i processi di CCS finito sono riconducibili.
Definizione 12.37 (Standard form). Un processo p 2 PCCS in standard form (s.f.) se
p

m
X

i .pi

i=1

dove ogni pi anchesso in standard form.


In pratica, un processo in s.f. un processo CCS di base. In particolare, nil in s.f. ( il
caso limite per m = 0). Inoltre, si ricordi che lordine degli addendi pu essere ignorato grazie
agli assiomi (A1) ed (A2) in Tabella 12.6.
Nel seguito indicheremo con prof (p) la profondit di una s.f. p definita come il massimo
numero di azioni prefisse innestate presenti in p. Si noti che prof (nil) = 0. La profondit di
una s.f. ci fornir in alcune dimostrazioni un parametro su cui applicare induzione. Dimostriamo ora che usando gli assiomi delle Tabelle 12.7 e 12.8 possiamo trasformare ogni processo
finito in un processo finito che non contiene composizione parallela, restrizione o relabelling.
Lemma 12.38. Per ogni processo p di CCS finito, esiste un processo p0 in s.f. tale che
E3 ` p = p0 .
Dimostrazione. Si procede eliminando dapprima le occorrenze pi interne di ciascun operatore
statico ed iterando il procedimento fino a che tutti gli operatori statici non sono stati eliminati.
Non dicile infatti dimostrare, ragionando per induzione su prof (p) nei primi due casi e su
prof (p) + prof (q) nellultimo, i seguenti tre fatti:
1. Se p una s.f. ed f : ! allora E3 \ {(Exp)} ` p[f ] = p0 per qualche s.f. p0 ;
2. Se p una s.f. ed L allora E3 \ {(Exp)} ` p \ L = p0 per qualche s.f. p0 ;
3. Se p e q sono s.f. allora E2 ` p|q = p0 per qualche s.f. p0 .
A questo punto il processo ottenuto un processo CCS di base e si possono usare le leggi
dellinsieme E1 per eliminare nil da ogni scelta. Il risultato un processo in s.f..

288

Capitolo 12 Calculus of Communicating Systems (CCS)

Facendo uso delle s.f. possiamo dimostrare la completezza dellinsieme di leggi E3 rispetto
a per CCS finito.
Proposizione 12.39 (Completezza). p q implica E3 ` p = q.
Dimostrazione. Assumiamo cheP
p q ed inoltre,Pper via del lemma precedente, che p e q
n
sono entrambi in s.f., cio p m
i=1 i .pi e q
j=1 j .qj . La dimostrazione procede per
induzione sulla massima tra le profondit di p e di q, che indichiamo con k.
Se k = 0, allora entrambi i processi (essendo in s.f.) sono il processo nil e la regola
dinferenza (riflessivit) in Tabella 12.5 ci permette di inferire che E1 ` nil = nil.
Se k > 0, allora almeno uno tra p e q diverso dal processo nil; supponiamo sia p. Sia

.p0 un sommando di p. Allora p ! p0 ; inoltre, dal fatto che p q, sappiamo che esiste

un qualche q 0 tale che q ! q 0 e p0 q 0 . Poich q in s.f., .q 0 un sommando di q. Ora,


p0 e q 0 sono in s.f. e la massima tra le loro profondit minore di k, quindi, per induzione,
E3 ` p0 = q 0 . Perci, il sommando .p0 di p pu essere provato uguale ad un sommando di q.
Similmente, ogni sommando 0 .q 0 di q pu essere provato uguale tramite il sistema di prova ad
un sommando di p. Applicando un ragionamento simmetrico si pu dimostrare il contrario.
La tesi, cio E3 ` p = q, segue usando lassioma (A4) per eliminare eventuali sommandi
duplicati.
Assiomatizzazione per tutto CCS. Allo scopo di assiomatizzare lintero linguaggio, occorrono regole per termini che includono le costanti di processo. Sfortunatamente, risultati
derivanti dalla teoria della computabilit ci dicono che non esiste unassiomatizzazione completa di per tutto CCS. Sono comunque state sviluppate due utili euristiche per ragionare
anche in presenza di costanti di processo e definizioni ricorsive.
Entrambe le tecniche hanno la forma di regole di inferenza. La prima regola chiamata regola di unrolling, stabilisce che linvocazione di un processo equivalente al corpo
dellinvocazione.
C,p
(Unr)
C=p
La seconda regola di inferenza chiamata principio di unique fixpoint induction (UFI) e si
basa sulle nozioni di equazione e soluzione. Data una variabile di processo X e un termine
CCS t che potenzialmente contiene la variabile X (in forma libera), lespressione X = t
detta equazione. Un processo CCS p soluzione di X = t se e solo se p t[p/X], dove
t[p/X] il termine ottenuto rimpiazzando tutte le occorrenze della variabile X in t con p.
Unequazione ha soluzione unica a meno di se, per ogni coppia di soluzioni p e q, si ha
p q. Possiamo ora formulare la regola (UFI) come segue:
(UFI)

p = t[p/X]
q = t[q/X]
(X = t ha soluzione unica)
p=q

Questa regola ci permette di concludere che due termini sono uguali se possibile dimostrare (i) che sono entrambi soluzioni della stessa equazione e (ii) che lequazione ha una sola
soluzione (a meno di ).
Si possono fare alcune osservazioni su questa ultima regola. In primo luogo, ogni equazione
X = t ha una soluzione: posto infatti X , t, facile vedere che il processo X soluzione
di X = t. In eetti, (UFI) utile solo nel caso in cui siamo in grado di capire quando

289

12.5 Ragionamento equazionale in CCS

unequazione ha soluzione unica. Fortunatamente, possibile definire una classe di equazioni


che ha le caratteristiche richieste.
Nel resto di questa sezione3 , supporremo per semplicit che tutti i termini considerati
contengano al pi la stessa variabile di processo X.
Definizione 12.40. Sia X una variabile e t un termine CCS che contiene X. Allora X si
dice guardata in t se ogni occorrenza di X in t compare nello scopo di un operatore di azione
prefissa.
Per esempio, X guardata in a.X e .X|(b.(X + c.nil)) ma non guardata in X + b.X.
Dimostriamo ora che se X guardata in t, allora la prima mossa di t indipendente dal
processo sostituito al posto di X.

Proposizione 12.41. Se X guardata in t e t[p/X] ! p0 , allora, per qualche termine CCS

t0 , abbiamo p0 t0 [p/X] e t[q/X] ! t0 [q/X] per ogni q 2 PCCS .

Dimostrazione. La dimostrazione procede per induzione sulla profondit della derivazione con

la quale la transizione t[p/X] ! p0 inferita. Ragioniamo esaminando i vari casi per t.


Caso 1 t Y , cio t una variabile di processo.
Quindi X 6= Y poich X, se occorre in t, guardata in t. Ma Y [p/X] Y non ha
derivate quindi questo caso non si pu presentare.
Caso 2 t 0 .t1 .
Quindi dobbiamo avere 0 e p0 t1 [p/X]. Ovviamente abbiamo anche t[q/X]

.t1 [q/X] ! t1 [q/X]. La tesi segue allora prendendo t0 t1 .


Caso 3 t t1 + t2 .

Quindi, con uninferenza pi breve, abbiamo che o t1 [p/X] ! p0 o t2 [p/X] ! p0 . Nel


primo caso, per induzione, possiamo assumere che per qualche termine CCS t01 si ha

p0 t01 [p/X] e t[q/X] ! t01 [q/X] per ogni q 2 PCCS . Nel secondo caso, sempre per
induzione, possiamo assumere che per qualche termine CCS t02 si ha p0 t02 [p/X] e

t[q/X] ! t02 [q/X] per ogni q 2 PCCS .


Caso 4 t t1 |t2 .

Consideriamo la transizione t[p/X] ! p0 ; data la forma di t abbiamo tre casi possibili


t1 [p/X] compie lazione e t2 [p/X] sta fermo;
t2 [p/X] compie lazione e t1 [p/X] sta fermo;
t1 [p/X] compie unazione e t2 [p/X] compie lazione complementare .
Esaminiamo il terzo caso che il pi complesso; gli altri due procedono in maniera simile.

In questo caso, abbiamo = , t1 [p/X] ! p01 , t2 [p/X] ! p02 e p0 p01 |p02 . Poich le
transizioni da t1 [p/X] e t2 [p/X] hanno uninferenza pi breve, per induzione, possiamo
assumere che esistono due termini CCS t01 e t02 tali che p01 t01 [p/X], p02 t02 [p/X],

t1 [q/X] ! t01 [q/X] e t2 [q/X] ! t02 [q/X] per ogni q 2 PCCS . La tesi segue allora
prendendo t0 t01 |t02 .

3
La propriet che dimostreremo si potrebbero generalizzare a sistemi di equazioni di definizione con pi
variabili, ma rimandiamo il lettore interessato a Milner [Mil89], pag. 103.

290

Capitolo 12 Calculus of Communicating Systems (CCS)

Caso 5 t t1 \L oppure t1 [f ].
Questi casi sono pi semplici del caso precedente e la loro prova lasciata per esercizio
al lettore.
Caso 6 t C con C , r.

Quindi, non ci sono occorrenze di X in t, perci abbiamo C ! p0 . La tesi segue allora


facilmente prendendo t0 p0 .
Possiamo finalmente dimostrare lunicit delle soluzioni di unequazione a meno di .
Teorema 12.42. Sia X guardata in t. Allora lequazione X = t ha soluzione unica a meno
di .
Dimostrazione. Per definizione, dobbiamo dimostrare che se p t[p/X] e q t[q/X] allora
p q. Cominciamo a dimostrare che la seguente relazione
S = {ht0 [p/X], t0 [q/X]i : var(t0 ) {X}} [ Id
una bisimulazione forte up to dove la condizione var(t0 ) {X} indica che t0 un termine
CCS che o non contiene variabili di processo o contiene la variabile X. Per simmetria,
suciente dimostrare che

se t0 [p/X] ! p0 allora, per qualche q 0 2 PCCS , t0 [q/X] ! q 0 con hp0 , q 0 i 2 S .


Come per la proposizione precedente, la dimostrazione procede per induzione sulla profondit

della derivazione con la quale la transizione t0 [p/X] ! p0 inferita. Ragioniamo esaminando


i vari casi.
Caso 1 t0 X, cio t0 proprio la variabile di processo X.

Quindi X[p/X] p ! p0 , perci, dato che p t[p/X], abbiamo che t[p/X] ! p00 p0 .

Poich X guardata in t, per la Proposizione 12.41, p00 t00 [p/X] e t[q/X] ! t00 [q/X].

Dato che t0 [q/X] X[q/X] q t[q/X], allora abbiamo t0 [q/X] ! q 0 t00 [q/X].
Riassumendo abbiamo p0 t00 [p/X] S t00 [q/X] q 0 come richiesto.
Caso 2 t0 0 .t1 .
Quindi dobbiamo avere 0 e p0 t1 [p/X]. Ovviamente abbiamo anche t0 [q/X]

.t1 [q/X] ! t1 [q/X]. La tesi segue dal fatto che per costruzione ht1 [p/X], t1 [q/X]i 2 S.
Caso 3 t0 t1 + t2 .

Quindi, con uninferenza pi breve, abbiamo che o t1 [p/X] ! p0 o t2 [p/X] ! p0 . Nel

primo caso, per induzione, abbiamo che, per qualche q10 2 PCCS , t0 [q/X] ! q10 con
hp0 , q10 i 2 S . Nel secondo caso, sempre per induzione, abbiamo che, per qualche

q20 2 PCCS , t0 [q/X] ! q20 con hp0 , q20 i 2 S .


Caso 4 t0 t1 |t2 .

Consideriamo la transizione t0 [p/X] ! p0 ; data la forma di t0 abbiamo tre casi possibili


t1 [p/X] compie lazione e t2 [p/X] sta fermo;
t2 [p/X] compie lazione e t1 [p/X] sta fermo;

291

12.5 Ragionamento equazionale in CCS


t1 [p/X] compie unazione e t2 [p/X] compie lazione complementare .

Esaminiamo il terzo caso che il pi complesso; gli altri due procedono in maniera simile.

In questo caso, abbiamo = , t1 [p/X] ! p01 , t2 [p/X] ! p02 e p0 p01 |p02 . Poich le
transizioni da t1 [p/X] e t2 [p/X] hanno uninferenza pi breve, per induzione, possiamo

assumere che esistono q10 , q20 2 PCCS , tali che t1 [q/X] ! q10 , t2 [q/X] ! q20 , hp01 , q10 i 2
S e hp02 , q20 i 2 S . Rimane da stabilire se hp01 |p02 , q10 |q20 i 2 S . Ora, poich
hp0i , qi0 i 2 S con i = 1, 2, per definizione di S, per qualche termine t0i si ha p0i t0i [p/X]
e qi0 t0i [q/X], sempre per i = 1, 2. Prendiamo allora il termine t00 t01 |t02 . Abbiamo
t00 [p/X] t01 [p/X]|t02 [p/X] e t00 [q/X] t01 [q/X]|t02 [q/X] e, quindi, poich preservata
dalloperatore di composizione parallela, abbiamo p01 |p02 t00 [p/X] S t00 [q/X] q10 |q20
come richiesto.
Caso 5 t0 t1 \L oppure t0 t1 [f ] oppure t C con C , r.
Questi casi sono pi semplici del caso precedente e la loro prova lasciata per esercizio
al lettore.
Ora, prendiamo t0 X. Ne deriva che hX[p/X], X[q/X]i hp, qi 2 S e, quindi, che p q,
che ci che volevamo dimostrare.
Esempio 12.43. Come esempio di applicazione di (Unr) e (UFI), supponiamo di voler
dimostrare che A e B sono bisimili, dove A , a.A e B , a.a.B. Consideriamo lequazione
X = a.a.X. Dimostriamo dapprima che sia A che B sono soluzione di questa equazione:
A = a.A

da (Unr)

= a.a.A

da (Unr)

B = a.a.B

da (Unr)

Dato che X guardata in a.a.X, X = a.a.X ha soluzione unica e di conseguenza, usando


(UFI) si pu concludere che A = B.
Per una classe particolare di processi CCS comunque possibile fornire unassiomatizzazione completa, pur potendo tali processi non essere finiti. Si tratta dei cosiddetti processi
sequenziali, cio quei processi che non fanno uso dei tre operatori statici: composizione parallela, restrizione e relabelling. In questo caso serve anche la regola seguente che permette di
trasformare un processo sequenziale qualsiasi in uno guardato:
(Seq1)

C ,C +p
D , p[D/C]
C=D

dove p[D/C] indica il processo p in cui le occorrenze della costante di processo C sono
rimpiazzate con D. Si pu allora enunciare il seguente risultato (che non dimostreremo).
Proposizione 12.44 (Correttezza e completezza). Siano p, q 2 PCCS processi sequenziali.
p q se e solo se E1 [ {(Unr), (UFI), (Seq1)} ` p = q.

292

Capitolo 12 Calculus of Communicating Systems (CCS)


(A1)-(A4) da Tabella 12.6; (Exp) da Tabella 12.7;
(Res1)-(Res3),(Rel1)-(Rel3) da Tabella 12.8
( 1)
( 2)
( 3)

..p
p + .p
.(p + .q)

=
=
=

.p
.p
.(p + .q) + .q

Tabella 12.9: Assiomatizzazione di


= per CCS finito: insieme E4

12.5.2

Assiomatizzazione di
=

Occupiamoci ora dellassiomatizzazione di


= per CCS. Seguendo il procedimento usato per
, consideriamo dapprima CCS finito e quindi CCS completo.
Assiomatizzazione per CCS finito. Cominciamo facendo notare che le leggi nellinsieme
E3 di Tabella 12.8 sono corrette anche per
=, dato che p q implica p
= q. Per, per ottenere

unassiomatizzazione completa per =, occorre aggiungere degli assiomi che riflettano la natura
speciale dellazione interna . Tali assiomi, noti come leggi , sono illustrati in Tabella 12.9.
La legge ( 1) serve per lassorbimento delle azioni che seguono immediatamente operatori
di azione prefissa. La legge ( 2) pu essere spiegata come segue. Primo, ogni transizione forte
di .p anche una transizione forte di p+.p. Secondo, ogni transizione forte di p+.p, incluse
le transizioni , pu essere messa in corrispondenza con una appropriata transizione debole
di .p. La legge finale, ( 3) forse la pi dicile da interpretare; si noti che la derivazione

.(p + .q) + .q ! q
della parte destra della regola, pu essere messa in corrispondenza con la discendenza

.(p + .q) =
)q
della parte sinistra. Lutilit di queste leggi la si apprezzer nella dimostrazione di completezza
ed in particolare in quella del Lemma 12.47.
Dimostriamo adesso la correttezza delle leggi .
Proposizione 12.45 (Leggi ). Le leggi della Tabella 12.9, cio
1. ..p = .p
2. p + .p = .p
3. .(p + .q) + .q = .(p + .q)
sono corrette rispetto a
=.
Dimostrazione. La correttezza delle leggi segue direttamente dalla definizione di congruenza
osservazionale. Nel punto 1. si usa anche la Proposizione 11.47.
Si osservi anche che tutte le leggi corrette per e
= lo sono anche per , mentre non vale
il viceversa: infatti, abbiamo che p .p mentre in generale p
6 .p.
=
Possiamo infine dimostrare che linsieme di leggi E4 definito in Tabella 12.9 completo per

= su CCS finito. Anche in questo caso faremo uso di alcune forme particolari per i processi.

293

12.5 Ragionamento equazionale in CCS

Definizione 12.46 (Full standard form). Un processo p 2 PCCS in full standard form
(f.s.f.) se
P
1. p m
i=1 i .pi , dove ogni pi anchesso in full standard form;

2. se p =
) p0 allora p ! p0 .

Possiamo pensare alla f.s.f. come ad una s.f. saturata nel seguente senso: per ogni p =
) p0
allora .p0 appare come sommando di p. Vediamo ora come ogni s.f. pu essere saturata
utilizzando le leggi (Tabella 12.9).

Lemma 12.47 (Saturazione). Se p una s.f. e p =


) p0 , allora E4 ` p = p + .p0 .

Dimostrazione. La prova procede per induzione su prof (p). Dato che p una s.f., se p =
) p0
allora si deve presentare uno dei seguenti tre casi.
Caso 1 .p0 un sommando di p. La tesi segue dallassioma (A4).

Caso 2 .q un sommando di p e q =
) p0 . Allora per induzione E4 ` q = q + .p0 , quindi
E4 ` p =
=
=
=
=

p + .q
p + .(q + .p0 )
p + .(q + .p0 ) + .p0
p + .q + .p0
p + .p0

Caso 3 .q un sommando di p
quindi
E4 ` p =
=
=
=
=

da
da
da
da
da

(A4)
E4 ` q = q + .p0
( 3)
E4 ` q = q + .p0
(A4)

e q =
) p0 . Allora per induzione si ha E4 ` q = q + .p0 ,
p + .q
p + .q + q
p + .q + q + .p0
p + .q + .p0
p + .p0

da
da
da
da
da

(A4)
( 2)
E4 ` q = q + .p0
( 2)
(A4)

Questo completa la prova.


Con lausilio di questo lemma, possiamo trasformare ogni s.f. in una f.s.f. equivalente.
Lemma 12.48. Per ogni processo p in s.f. esiste un processo p0 in f.s.f. di uguale profondit,
tale che E4 ` p = p0 .
Dimostrazione. La dimostrazione procede per induzione su prof (p). Se prof (p) = 0 allora
p nil, e quindi p gi in f.s.f.. In caso contrario, per ogni sommando .q di p possiamo
assumere per induzione che q sia gi stato convertito, grazie allinsieme E4 , in f.s.f. senza
incremento di profondit. Ora, consideriamo tutte le coppie (i , pi ), 1 i k, tali che
i
i
p =) pi e p 6 ! pi . Ogni pi deve essere una f.s.f. in quanto una sottoespressione di qualche
sommando .q di p. Dunque
p0 p + 1 .p1 + + k .pk
una f.s.f. di uguale profondit di p, e grazie al lemma di saturazione, E4 ` p = p0 .

294

Capitolo 12 Calculus of Communicating Systems (CCS)


Siamo adesso in grado di dimostrare che E4 completo per
= su processi di CCS finito.

Proposizione 12.49 (Completezza). p


= q implica E4 ` p = q.
Dimostrazione. Per via del lemma precedente, possiamo assumere che p e q sono in f.s.f.; la
prova procede per induzione sulla somma delle profondit di p e q.
Se la somma pari a zero, allora si ha p nil q, e la tesi segue banalmente. In caso
contrario, almeno uno tra p e q diverso da nil; supponiamo sia p. Assumiamo ora che
p
= q e che .p0 un sommando di p. Il nostro obiettivo dimostrare che q ha un sommando

provabilmente uguale a .p0 . Dato che p ! p0 e per ipotesi p


) q0
= q, esiste un q 0 tale che q =

e p0 q 0 . Inoltre, poich q in f.s.f. si ha anche che q ! q 0 , e quindi .q 0 un sommando di


q.
Non possiamo applicare immediatamente linduzione, in quanto sappiamo soltanto che
p0 q 0 e non che p0
= q 0 . Ma dalla Proposizione 12.22 sappiamo che p0 q 0 implica che uno
dei seguenti tre casi si deve verificare: p0
= q 0 o p0
= .q 0 o .p0
= q0.
0
0
Nel primo caso, dal momento che p e q sono in f.s.f. e di profondit minore di p e q, per
induzione segue che E4 ` p0 = q 0 , quindi che E4 ` .p0 = .q 0 . Nel secondo caso dobbiamo
convertire .q 0 in f.s.f. prima di poter applicare linduzione. Dal Lemma 12.48 sappiamo che
esiste un q 00 in f.s.f. di uguale profondit di .q 0 , e quindi di q, tale che E4 ` .q 0 = q 00 . Ora, la
somma delle profondit di p0 e q 00 minore della somma delle profondit di p e q, e quindi per
induzione possiamo inferire che E4 ` p0 = q 00 e quindi che E4 ` p0 = .q 0 . Grazie allassioma
( 1) possiamo concludere che E4 ` .p0 = .q 0 . Il terzo caso simile a questo.
Dunque, in ognuno dei tre casi, abbiamo mostrato che tramite E4 ogni sommando .p0
di p pu essere provato uguale ad un sommando di q. In modo simile, ogni sommando 0 .q 0
di q pu essere provato uguale ad un sommando di p. Infine, utilizzando lassioma (A4) per
eliminare eventuali sommandi duplicati, possiamo concludere che E4 ` p = q.
Assiomatizzazione di
= per tutto CCS. Le stesse osservazioni fatte per valgono per
=,
quindi non esiste una assiomatizzazione corretta e completa per
su
tutto
CCS.
Nonostante
=
ci le regole (Unr) e (UFI) valgono ancora, anche se la caratterizzazione delle equazioni che
hanno soluzione unica diventa pi complessa; non pi suciente richiedere solo che la
variabile sia guardata. Infatti, si consideri lequazione X = .X. X guardata in .X, ma
qualunque processo capace di unazione iniziale soluzione di questa equazione a meno di

=. In particolare, .a.nil
= ..a.nil e .b.nil
= ..b.nil, ma ovviamente .a.nil 6
= .b.nil.
Comunque, possibile individuare una classe di equazioni che hanno soluzione unica rispetto
a
=.
Nel resto di questa sezione4 , supporremo per semplicit che tutti i termini considerati
contengano al pi la stessa variabile di processo X.
Definizione 12.50. Sia X una variabile e t un termine CCS. X fortemente guardata in t
se ogni sottotermine di t che contiene X, a parte X stesso, della forma .t0 , con 6= .
Ci significa che X fortemente guardata in t se almeno un operatore di azione prefissa
che coinvolge unazione visibile precede ogni occorrenza di X in t. Ovviamente X non
4
La propriet che dimostreremo si potrebbero generalizzare a sistemi di equazioni di definizione con pi
variabili, ma rimandiamo il lettore interessato a Milner [Mil89], pag. 158.

295

12.5 Ragionamento equazionale in CCS

fortemente guardata in .X. Comunque, il fatto che X sia fortemente guardata in t non
implica che X = t abbia soluzione unica a meno di
=. Infatti, consideriamo lequazione
X = (a.X|a.nil)\ {a} .
X fortemente guardata nella parte destra dellequazione, tuttavia si pu vedere che, per
esempio, .b.nil e .c.nil sono entrambe soluzioni. possibile risolvere questo problema
richiedendo quanto segue.
Definizione 12.51. Sia X una variabile e t un termine CCS. X sequenziale in t se ogni
sottotermine di t che contiene X, a parte X stesso, della forma .t0 oppure t1 + t2 .
Per esempio, X sequenziale in a.X e .X +(b.nil|c.nil) ma non sequenziale in a.X|b.nil
(bench il termine sia fortemente guardato). In pratica, se X sequenziale in t allora nessuna
occorrenza di X in t ricade nello scopo di un operatore statico.
Analogamente al caso della bisimilarit forte, dimostriamo prima che se un termine t contiene solo occorrenze fortemente guardate e sequenziali di una variabile di processo X, allora il
comportamento di t, fino ed incluso lesecuzione della prima azione visibile, completamente
indipendente dal processo sostituito al posto di X.

Proposizione 12.52. Se X fortemente guardata e sequenziale in t e t[p/X] ! p0 allora,

per qualche termine CCS t0 , abbiamo p0 t0 [p/X] e t[q/X] ! t0 [q/X] per ogni q 2 PCCS .
Inoltre, X sequenziale in t0 e, se = , allora anche fortemente guardata.
Dimostrazione. La dimostrazione procede per induzione sulla struttura di t. Innanzitutto si
noti che t X non pu verificarsi, poich per ipotesi X fortemente guardata in t. Ora, se
t C (C costante di processo), oppure t t1 |t2 , oppure t t1 \ L (L ), oppure t t1 [f ]
(f : ! ), allora, poich per ipotesi X sequenziale in t, la variabile X non occorre in t

e quindi t ! p0 . La tesi allora segue immediatamente ponendo t0 p0 . Se t 0 .t00 , allora


0 e chiaramente p0 t00 [p/X] e la tesi segue immediatamente ponendo t0 t00 ; si noti
che se = allora X fortemente guardata anche in t0 . Infine, se t t1 + t2 , la tesi segue
facilmente per induzione.
Possiamo finalmente dimostrare lunicit delle soluzioni di unequazione a meno di
=.
Teorema 12.53. Sia X = t unequazione con X fortemente guardata e sequenziale in t.
Allora X = t ha ununica soluzione a meno di
=.
Dimostrazione. Per definizione, dobbiamo dimostrare che se p
= t[p/X] e q
= t[q/X] allora

p = q. suciente dimostrare che la relazione


S = ht0 [p/X], t0 [q/X]i : X sequenziale in t0
gode della seguente propriet

se t0 [p/X] =
) p0 allora, per qualche q 0 2 PCCS , t0 [q/X] =
) q 0 e hp0 , q 0 i 2 S .

se t0 [q/X] =
) q 0 allora, per qualche p0 2 PCCS , t0 [p/X] =
) p0 e hp0 , q 0 i 2 S .

(12.2)

Vediamo prima perch ci ci permette di arrivare alla tesi. Ora, per ogni processo CCS r

ed azione , abbiamo che r =


) r0 implica r =
) r0 . Quindi, la validit della propriet (12.2)

296

Capitolo 12 Calculus of Communicating Systems (CCS)

implica che S una bisimulazione debole up to (Definizione 11.49). Perci, per la Proposizione 11.50, abbiamo che hp0 , q 0 i 2 S implica p0 q 0 . Inoltre, poich per ogni processo

CCS r ed azione , r ! r0 implica r =


) r0 , abbiamo che t0 [p/X] ! p0 implica t0 [p/X] =
) p0 e

t0 [q/X] ! q 0 implica t0 [q/X] =


) q 0 . Quindi, dalla propriet (12.2), prendendo t0 X per cui
abbiamo hp, qi hX[p/X], X[q/X]i 2 S, segue che:

se p t0 [p/X] ! p0 allora, per qualche q 0 2 PCCS , q t0 [q/X] =


) q 0 e hp0 , q 0 i 2

se q t0 [q/X] ! q 0 allora, per qualche p0 2 PCCS , p t0 [p/X] =


) p0 e hp0 , q 0 i 2
che, per definizione di congruenza osservazionale (Definizione 12.15), significa proprio che
p
= q.
Ci resta allora da dimostrare la propriet (12.2). La dimostrazione dipende in maniera
cruciale dalla possibilit di sostituire p con t[p/X] convertendo cos un termine t0 [p/X] nel
termine fortemente guardato t0 [t[p/X]/X] e rendendo applicabile la Proposizione 12.52.
Converr prima dimostrare una propriet simile alla (12.2) ma che coinvolge solo azioni
interne e cio:
se t0 [p/X] =
) p0 allora, per qualche q 0 2 PCCS , t0 [q/X] =
) q 0 e hp0 , q 0 i 2 S .
0
0
0
0
se t [q/X] =
) q allora, per qualche p 2 PCCS , t [p/X] =
) p0 e hp0 , q 0 i 2 S .

(12.3)

Supponiamo allora che t0 [p/X] =


) p0 . Ora, poich p
= t[p/X] e
= una congruenza, t0 [p/X]
=
0
00
0
t [t[p/X]/X], quindi per qualche p 2 PCCS , abbiamo t [t[p/X]/X] =
) p00 p0 . Poich X
fortemente guardata e sequenziale in t0 [t/X], per la Proposizione 12.52, esiste un termine
t00 con X sequenziale in esso tale che p00 t00 [p/X] e t0 [t[q/X]/X] =
) t00 [q/X]. Poich per
ipotesi t0 [q/X]
) q 0 t00 [q/X].
= t0 [t[q/X]/X], per qualche q 0 2 PCCS , abbiamo t0 [q/X] =
0
00
00
00
0
Riassumendo, abbiamo p p t [p/X] S t [q/X] q . Ci, per simmetria, suciente a
dimostrare la propriet (12.3).

Infine, dimostriamo la propriet (12.2). Supponiamo innanzitutto che t0 [p/X] =


) p0 . Al
lora, poich t0 [p/X]
) ! =
) p00 p0 . Ora, ap= t0 [t[p/X]/X], abbiamo t0 [t[p/X]/X] =

plicando ripetutamente la Proposizione 12.52 per le transizioni =


) ! , otteniamo che

esiste un termine t00 tale che X sequenziale in t00 , t0 [t[p/X]/X] =


) ! t00 [p/X] =
) p00 p0 e

t0 [t[q/X]/X] =
) ! t00 [q/X]. A questo punto, per la propriet (12.3), otteniamo t00 [q/X] =
) q 00
00
00
00
0
0

e p S q , per qualche q 2 PCCS . Infine, poich t [q/X] = t [t[q/X]/X], abbiamo

t0 [q/X] =
) q 0 q 00 . Perci p0 p00 S q 00 q 0 , da cui, per transitivit di , abbiamo
p0 S q 0 . Ci, per simmetria, suciente a concludere che la propriet (12.2) vale.
Esempio 12.54. Per concludere, presentiamo un esempio per esteso, riguardo lutilizzo
degli assiomi introdotti. Riprendiamo il semplice protocollo di comunicazione P definito in
Sezione 12.1 di pagina 261 e la sua specifica Svc definita nellEsempio 12.27 di pagina 280.
possibile stabilire che E4 [ {(Unr), (UFI)} ` P = Svc nel modo seguente. Si noti prima
di tutto che X fortemente guardata e sequenziale in send.recv.X e quindi lequazione X =
send.recv.X ha soluzione unica a meno di
=. Quello che resta da fare mostrare che sia P
che Svc sono soluzioni di questa equazione, dopodich, utilizzando la regola (UFI), si ha che
P = Svc. Per fare ci vediamo subito che
Svc = send.recv.Svc

da (Unr)

297

12.5 Ragionamento equazionale in CCS


quindi Svc una soluzione. Come per Svc, possiamo derivare che
P

= (S[put/msg, get_ack/ack] | M | R[get/msg, put_ack/ack])


\ {get, put, get_ack, put_ack}

usando (Unr), quindi suciente dimostrare che la parte destra una soluzione dellequazione
data, cio che
(S[put/msg, get_ack/ack] | M | R[get/msg, put_ack/ack])
\ {get, put, get_ack, put_ack} =

send.recv.(S[put/msg, get_ack/ack] | M | R[get/msg, put_ack/ack])


\ {get, put, get_ack, put_ack}
A tale scopo procediamo come segue. Abbiamo
(S[put/msg, get_ack/ack] | M | R[get/msg, put_ack/ack])
\ {get, put, get_ack, put_ack} =
per (Exp), (Rel1)-(Rel3), (Res1)-(Res3)
send.((msg.ack.S)[put/msg, get_ack/ack] | M | R[get/msg, put_ack/ack])
\ {. . .} =
per (Exp), (Rel1)-(Rel3), (Res1)-(Res3)
send..((ack.S)[put/msg, get_ack/ack] | (get.M )
| R[get/msg, put_ack/ack]) \ {. . .} =

per ( 1)

send.((ack.S)[put/msg, get_ack/ack] | (get.M ) | R[get/msg, put_ack/ack])


\ {. . .} =
per (Exp), (Rel1)-(Rel3), (Res1)-(Res3)
send..((ack.S)[put/msg, get_ack/ack] | M
| (recv.ack.R)[get/msg, put_ack/ack]) \ {. . .} =
send.((ack.S)[put/msg, get_ack/ack] | M
| (recv.ack.R)[get/msg, put_ack/ack]) \ {. . .} =
send.recv.((ack.S)[put/msg, get_ack/ack] | M
| (ack.R)[get/msg, put_ack/ack])\ {. . .} =

per ( 1)

per (Exp), (Rel1)-(Rel3), (Res1)-(Res3)

per (Exp), (Rel1)-(Rel3), (Res1)-(Res3)

send.recv..((ack.S)[put/msg, get_ack/ack] | get_ack.M


| R[get/msg, put_ack/ack]) \ {. . .} =

per ( 1)

send.recv.((ack.S)[put/msg, get_ack/ack] | get_ack.M


| R[get/msg, put_ack/ack])\ {. . .} =
per (Exp), (Rel1)-(Rel3), (Res1)-(Res3)
send.recv..(S[put/msg, get_ack/ack] | M | R[get/msg, put_ack/ack]) \ {. . .} =

298

Capitolo 12 Calculus of Communicating Systems (CCS)


(A1)-(A4) da Tabella 12.6; (Exp) da Tabella 12.7
(Res1)-(Res3),(Rel1)-(Rel3) da Tabella 12.8
(F1)
(F2)
(F3)
(F4)

.p + .q
p + .q
.p + .(.q + r)
.p

=
v
=
v

.(.p + .q)
.(p + q)
.(.p + .q + r)
p

Tabella 12.10: Assiomatizzazione di vctest per CCS finito: insieme E5


per ( 1)
send.recv.(S[put/msg, get_ack/ack] | M | R[get/msg, put_ack/ack]) \ {. . .}
Anche per
= possibile dare unassiomatizzazione completa per processi CCS sequenziali
(cio che non fanno uso dei tre operatori statici) e, quindi, non necessariamente finiti. Allo
scopo di trasformare un processo sequenziale qualsiasi in uno fortemente guardato servono
anche le regole:
(Seq2)

C , .C + p

D , .p[D/C]

C=D
(Seq3)

C , .(C + p) + q

D , .D + p[D/C] + q[D/C]
C=D

(si ricordi che r[D/C] indica il processo r in cui le occorrenze di C sono rimpiazzate con D).
Si pu allora enunciare il seguente risultato (che non dimostreremo).
Proposizione 12.55 (Correttezza e completezza). Siano p, q 2 PCCS processi sequenziali.
p
= q se e solo se E1 [ {( 1), ( 2), ( 3), (Unr), (UFI), (Seq1), (Seq2), (Seq3)} ` p = q.

12.5.3

Assiomatizzazione di vctest , vcM e vm

Come per e
=, cominciamo con lintrodurre le assiomatizzazioni corrette e complete dei
preordini per CCS finito e quindi presentiamo brevemente alcune euristiche per gestire le
definizioni di processo ricorsive.
Assiomatizzazione per CCS finito. Lassiomatizzazione di vctest per CCS finito data dallinsieme E5 ed presentata in Tabella 12.10. A dierenza di quanto abbiamo visto
finora, questa unassiomatizzazione disequazionale: essa usata per dimostrare asserzioni
della forma p v q invece che p = q. Come si pu vedere, gli assiomi includono disuguaglianze; le uguaglianze come nella regola (F1) vanno interpretate come abbreviazioni per due
disuguaglianze, nelle due direzioni.
Lassiomatizzazione per vcM si ottiene aggiungendo allinsieme E5 il seguente assioma
(F5)

.p + .q v p

mentre quella per vm si ottiene aggiungendo a E5 lassioma

299

12.5 Ragionamento equazionale in CCS


(F6)

p v .p + .q

Per vedere come queste regole possono essere usate per derivare dei risultati, mostriamo
che E5 [ {(F5)} ` a.b.nil + a.c.nil v a.b.nil.
a.b.nil + a.c.nil = a.(.b.nil + .c.nil)
v a.b.nil

da (F1)
da (F5)

Occupiamoci ora della correttezza delle assiomatizzazioni in questione. Il Teorema 11.79


ci assicura che gli assiomi dellinsieme E3 (cio quelli per la bisimilarit forte) sono corretti
anche per i preordini basati su testing; per lo stesso motivo, anche le leggi sono corrette. La
correttezza delle leggi (F1)-(F6), invece, si pu dimostrare come abbiamo fatto in precedenza.
Per quanto riguarda la completezza delle assiomatizzazioni, questa si dimostra con procedimenti simili a quelli visti per bisimilarit facendo uso di forme speciali per i processi.
In particolare, nel caso di vctest si utilizzano le seguenti forme speciali per i processi di CCS
finito (le forme speciali per gli altri due preordini sono simili).
Definizione 12.56 (Insieme saturato). Sia L un insieme non vuoto di insiemi finiti di azioni
visibili, cio L P(ACCS ). Sia Act(L) = { | 2 L, L 2 L} linsieme di tutte le azioni di L.
Si dice che L saturato se 8K ACCS
L 2 L ^ L K Act(L) implica K 2 L
Definizione 12.57 (Forma normale). Un processo in forma normale se in una delle due
forme seguenti:
P
P
a)
L2L .
2L .p con p in forma normale
P
b)
2L .p con p in forma normale
dove L un insieme saturato.

Sostanzialmente, la forma normale prevede che un processo sia strutturato in strati


alternati dove si fanno solo azioni invisibili o solo azioni visibili. Vale il seguente risultato:
Lemma 12.58. Ogni processo di CCS finito pu essere trasformato in forma normale usando
le leggi E5 .
Teorema 12.59 (Completezza per vctest ). p vctest q implica E5 ` p v q.
Dimostrazione. (Traccia) Per il lemma precedente, possiamo supporre che p e q siano in forma
normale. Allora avremo p vctest q se ogni sommando in p presente anche in q. Supponiamo,
per assurdo, che p abbia un sommando che q non ha, allora, sfruttando la saturazione delle
forme normali, avremmo che possibile determinare un insieme L tale che p must L vero
mentre q must L falso; ci porta allassurdo p 6vctest q.
Usando tecniche simili si pu dimostrare che
Teorema 12.60 (Completezza per vcM ). p vM q implica E5 [ {(F5)} ` p v q.
Teorema 12.61 (Completezza per vm ). p vm q implica E5 [ {(F6)} ` p v q.

300

Capitolo 12 Calculus of Communicating Systems (CCS)

Assiomatizzazione dei preordini per tutto CCS. Per trattare i processi ricorsivi, si
possono usare le regole (Unr) e (UFI) viste nella Sezione 12.5.1. Una condizione suciente
anch unequazione X = t abbia soluzione unica rispetto a 'ctest che X sia fortemente
guardata e sequenziale in t e che t sia totalmente convergente (si veda la Definizione 11.62).

12.6

Esercizi

12.1 Dimostrare la proposizione seguente che introduce alcune leggi per gli operatori statici derivabili
a partire da quelle nelle Tabelle 12.7, 12.8 e 12.9.
Proposizione 12.62 (Leggi derivabili). Le seguenti leggi
1. p|q q|p

2. p|(q|r) (p|q)|r
3. p|nil p

4. p \ L p

se L(p) \ (L [ L) = ;

5. p \ K \ L p \ (K [ L)
6. p[f ] \ L p \ f

(L)[f ]

7. (p|q) \ L p \ L|q \ L
8. p[Id] p

9. p[f ] p[f 0 ]

10. p[f ][f ] p[f


0

se f
0

f]

se L(p) \ L(q) \ (L [ L) = ;

L(p) = f 0

11. (p|q)[f ] p[f ]|q[f ]

se f

L(p)

(L [ L)

biunivova, dove L = L(p) [ L(q)

sono corrette rispetto a .


12.2 Mostrare che la legge seguente
( 4)

p + .(p + q) = .(p + q)

derivabile dallinsieme E4 definito in Tabella 12.9.


12.3 Relativamente alla definizione di insieme saturato (Definizione 12.56), si dimostri che se L
saturato, allora valgono le seguenti propriet:
1. se L1 , L2 2 L allora (i) L1 [ L2 2 L e (ii) se L1 K L2 allora K 2 L;
2. Act(L) 2 L.

Capitolo 13

Logiche per i sistemi concorrenti

SOMMARIO
Questo capitolo presenta alcune logiche modali e temporali e mostra come utilizzarle per
specificare propriet dei sistemi concorrenti. Dopo aver introdotto in generale le caratteristiche delle logiche modali e temporali, descriveremo in dettaglio la logica HML, la logica
ACTL ed il -calculus modale. Infine, esamineremo la corrispondenza tra le equivalenze
indotte dalle logiche e le equivalenze comportamentali presentate nel Capitolo 11.

13.1

Logiche e propriet di sistemi

I linguaggi per la specifica di processi, come il CCS, consentono di definire sia un sistema
concorrente che la sua specifica. Inoltre, forniscono tecniche di equivalence checking che
studiano la relazione che lega le due definizioni formali del sistema e permettono di verificare
se il sistema rispetta i requisiti richiesti della sua specifica.
Questo tipo di tecniche non sono per utilizzabili nel caso in cui si intenda verificare se
un dato sistema verifica una propriet del tipo in ogni momento il sistema pu eettuare
lazione a. I formalismi che vedremo in questo capitolo, chiamati logiche modali e temporali,
permettono di esprimere propriet di sistemi concorrenti e reattivi, quali deadlock e livelock.
Certamente sarebbe desiderabile disporre di una logica che consenta di formalizzare propriet allo stesso modo in cui queste vengono formulate dal pensiero umano. Purtroppo non
facile catturare in ununica logica tutti gli aspetti che possono descrivere le caratteristiche di
un sistema, per questo esistono logiche diverse che dieriscono tra loro proprio per il genere
di propriet che sono in grado di descrivere. La maggior parte delle propriet dei sistemi
concorrenti si possono suddividere in due categorie di base: propriet di safety e propriet di
liveness.
Safety. In questa categoria rientrano tutte quelle propriet del tipo niente di indesiderato
accadr nel prosieguo dellesecuzione del sistema. Per soddisfare una tale propriet il
sistema non dovr mai eettuare lattivit proibita. Per esempio, una propriet di
safety per una macchina distributrice di te e ca vista nellEsempio 11.3, che la macchina non distribuir un te se stato richiesto un ca. Normalmente, le propriet di
safety intendono esprimere invarianze, cio se una condizione vale nello stato iniziale,
allora essa resta vera per tutta lesecuzione del programma. Una di queste propriet
lassenza di stati di deadlock che assicura che il sistema non pu raggiungere una situazione in cui tutte le componenti sono bloccate. Oltre ai deadlock, possono esistere anche

302

Capitolo 13 Logiche per i sistemi concorrenti


altri stati di errore in cui il sistema non deve mai arrivare per non avere comportamenti
indesiderati.

Liveness. In questa categoria rientrano tutte quelle propriet del tipo qualcosa di positivo
accadr prima o poi nel prosieguo dellesecuzione del sistema. Per soddisfare una tale
propriet il sistema dovr eettuare una qualche attivit desiderata. Per esempio, una
propriet di liveness per una macchina distributrice di te e ca vista nellEsempio 11.3,
che la macchina distribuir un ca una volta che lutente ha inserito la giusta quantit
di denaro. Le propriet di liveness esprimono il fatto che, nel futuro, una data condizione
debba essere soddisfatta almeno una volta, infinite volte o continuamente da un certo
punto in poi. Le propriet che esprimono il progresso di un sistema sono una classe
di propriet di liveness. Dato un insieme di azioni L = {1 , , n }, un sistema ha
la propriet di progresso rispetto a L se, in qualunque stato si trovi, esso prima o poi
esegue una azione i 2 L.
Molte altre propriet possono essere descritte come combinazione delle due categorie di base.
Tra queste abbiamo alcune propriet di tipo infinitario quali quelle di fairness che esprimono
il fatto che qualcosa di buono accadr infinite volte. Ad esempio, desiderabile che se un
sistema operativo serve due utenti, il controllo passi dalluno allaltro infinite volte. In altri
termini, non succede mai che uno dei due utenti monopolizzi il sistema indefinitamente, poich
questo non sarebbe equo (fair ).
Una caratteristica importante di una logica per sistemi concorrenti il tipo di modello di
sistema su cui una formula interpretata. Sostanzialmente questo o un LTS o una Struttura
di Kripke (KS). Come abbiamo visto nel Capitolo 3, LTS e KS si dierenziano per quelle che
sono le informazioni associate ai nodi e agli archi dei grafi sui quali entrambi sono basati.
Lapproccio logico introdotto in questo capitolo costituisce un approccio alternativo a
quelli operazionale (comportamentale) ed assiomatico introdotti nei capitoli precedenti, per
lo studio del comportamento dei sistemi concorrenti e distribuiti e delle loro propriet. Infatti,
dati un modello a stati finiti di un sistema ed una formula che descrive una propriet in un
qualche formalismo logico appropriato (quale ad esempio una logica modale o temporale),
tramite una tecnica automatica chiamata model checking possibile verificare (tramite una
esplorazione dello spazio degli stati) se il sistema soddisfa la propriet. Il model checking
una tecnica alquanto generale che applicata in varie aree, quali la verifica di sistemi hardware
e lingegneria del software.
Uno dei vantaggi del model checking, che lo distingue dalle altre tecniche di verifica,
consiste nel fatto che gli algoritmi, attraverso i quali questa tecnica viene realizzata, sono
completamente automatici e raggiungono un esito senza richiedere nessun tipo di intervento
da parte dellutente che sta svolgendo la verifica. Questo aspetto rende possibile anche ad
utenti meno esperti lutilizzo di queste tecniche di verifica; le uniche conoscenze richieste sono
quelle minime relative ai formalismi di specifica del sistema e delle propriet da verificare.
Lapproccio logico pu comunque essere messo in relazione con gli approcci operazionale e
assiomatico. Una logica induce una naturale relazione di equivalenza sui sistemi: due sistemi
sono equivalenti se (e solo se) essi soddisfano le stesse formule. Supponiamo che L sia una
logica, allora possiamo definire la seguente equivalenza tra due sistemi p e q:
p L q

()

8' 2 L :

p |= ' sse q |= '

13.2 Logiche proposizionali, loro interpretazioni e modelli

303

Il fatto che due sistemi equivalenti soddisfano esattamente le stesse formule della logica L non
vuol dire che le soddisfano tutte (ovviamente, se L = ; allora qualunque coppia di sistemi
in relazione ; ). Spesso risulta che la nozione di equivalenza indotta da una logica coincide
con una nozione di equivalenza tra sistemi definita usando la semantica operazionale od un
insieme di assiomi. Difatti, naturale che due processi che si comportano allo stesso modo
soddisfino le stesse classi di propriet. In quel caso, si pu aermare che la logica espressiva
rispetto allequivalenza considerata. Per le logiche presentate in questo capitolo esamineremo
le relazioni con le semantiche basate sul concetto di bisimulazione.
Le logiche pi utilizzate per esprimere propriet di sistemi concorrenti sono quelle modali
e temporali. Le formule di una logica modale, come la Hennessy-Milner Logic, esprimono
capacit e necessit locali di (uno stato di) un sistema, ma non hanno la capacit di esprimere
propriet riguardanti levoluzione nel tempo del sistema. Ad esempio, non possono dire che
una certa propriet sempre vera (in ogni stato di una computazione) o inizier a valere in
uno stato futuro (non conosciuto). Tali propriet sono invece esprimibili tramite le logiche
temporali.
Le logiche temporali si possono raggruppare in due categorie sulla base del modello del
tempo sottostante. Le logiche temporali linear time (o lineari) hanno un modello del tempo
lineare per cui in ogni istante di tempo esiste un unico futuro che si potr concretizzare. Tali
logiche considerano un sistema come linsieme di tutte le sue possibili computazioni (sequenze
di esecuzione) distinte e permettono di esprimere propriet delle singole computazioni di un
sistema. Le logiche temporali branching time hanno un modello del tempo ad albero (cio
ramificato) per cui il futuro non univocamente determinato; esistono pi futuri possibili
ciascuno dei quali potrebbe essere quello che eettivamente si realizzer. Sono dotate di operatori che permettono di esprimere propriet che si riferiscono al futuro e di quantificare sulle
possibili computazioni dierenti. Tali logiche considerano un sistema come lalbero delle sue
computazioni. Infatti, lesecuzione di un sistema concorrente non un qualcosa di lineare,
di preconfezionato, ma caratterizzata da diverse scelte che vengono compiute in base al
valore assunto a runtime da particolari fattori, che possono essere i dati in input o le variabili
dambiente, o da eventi indesiderati che possono causare eccezioni. Lalbero delle computazioni rappresenta in maniera compatta lesecuzione di un sistema. I nodi interni dellalbero,
da cui partono rami diversi, rappresentano stati in cui viene eettuata una scelta. Ogni cammino nellalbero rappresenta una singola computazione possibile o, a seconda di come lo si
interpreta, un diverso futuro nel quale il sistema pu evolvere. Perci le logiche temporali
branching time permettono di esprimere propriet che riguardano le scelte che un sistema pu
fare durante la sua evoluzione e le possibili computazioni da un certo stato. Questi due tipi
di logiche, tuttavia, non sono in generale confrontabili in termini di espressivit.

13.2

Logiche proposizionali, loro interpretazioni e modelli

Il nostro interesse per le logiche motivato dallintento di utilizzarle per esprimere propriet
dei sistemi concorrenti. A questo scopo, di fondamentale importanza la relazione di soddisfazione per stabilire se un sistema un modello di una formula. In questa sezione, per illustrare
le tecniche di interpretazione di formule basate su modelli, introduciamo una presentazione
delle logiche proposizionali diversa da quella classica.

304

Capitolo 13 Logiche per i sistemi concorrenti

Nel panorama che introdurremo, le logiche proposizionali si collocano alla base di quelle
modali e temporali, in quanto definiscono un insieme di operatori comuni a queste diverse
categorie. Il loro nome deriva dal fatto che sono definite a partire da un insieme di proposizioni
atomiche ciascuna delle quali pu assumere valore true o f alse. Sia AP = {p0 , p1 , . . . , }
linsieme delle proposizioni atomiche. I suoi elementi esprimono propriet di base che il
sistema in esame garantisce nello stato in cui si trova, come ad esempio file_eliminato, che
indica il fatto che un certo file stato eliminato, o ca_pronto, che indica il fatto che il
ca pronto (si consideri il distributore automatico di bevande dei capitoli precedenti).
La sintassi delle formule della logica proposizionale definita dalla grammatica seguente:
' ::= AP

'

'1 _ '2

Ossia:
ogni proposizione atomica di AP una formula proposizionale;
la negazione di una formula proposizionale ancora una formula proposizionale;
la disgiunzione (_) di due formule proposizionali ancora una formula proposizionale.
Usando gli operatori della sintassi di base della logica proposizionale possiamo derivare
molti altri operatori, tra i quali i principali sono i seguenti:
le costanti booleane: true , p _ p e f alse , true, con p 2 AP ;
loperatore ^ (congiunzione): '1 ^ '2 , ('1 _ '2 );
loperatore ! (implica): '1 ! '2 , '1 _ '2 ;
loperatore $ (se e soltanto se): '1 $ '2 , ('1 ! '2 ) ^ ('2 ! '1 ).
Per definire la semantica della logica proposizionale dobbiamo introdurre il concetto di modello. A questo scopo, indichiamo con U il dominio dei valori booleani, cio U , {true, f alse}.
Una interpretazione I una funzione che associa ad ogni proposizione atomica p 2 AP un
valore booleano, cio:
I : AP ! U.

Il concetto di interpretazione importante in quanto ci consente di valutare le stesse proposizioni atomiche in situazioni dierenti a ciascuna delle quali associata una diversa interpretazione. Un modello per la logica proposizionale costituito allora da una coppia
M , hU , Ii.
La semantica della logica proposizionale formalizzata mediante una relazione binaria di
soddisfazione, indicata con il simbolo |=, tra un modello M , hU , Ii e una formula proposizionale '. Tale relazione definita per induzione sulla sintassi delle formule dalle regole
seguenti:
M |= p sse I(p) = true;
M |= ' sse non vero che M |= ';
M |= '1 _ '2 sse M |= '1 oppure M |= '2 .

305

13.3 Logiche modali proposizionali

Nel seguito, talvolta scriveremo M 6|= ' se non vero che M |= '.
Diremo che una formula ' soddisfacibile se esiste un modello M tale che M |= '. In tal
caso, diremo anche che M un modello per '. Diremo che una formula ' valida, scritto
|= ', se ogni modello M tale che M |= '. Si noti che se ' valida, allora ' non
soddisfacibile. Ad esempio abbiamo che true valida mentre f alse non soddisfacibile.
Le formule della logica proposizionale, se da un lato consentono di specificare diverse
propriet che lo stato di un sistema pu soddisfare, dallaltro non sono particolarmente adatte
per descrivere il cambiamento di queste propriet nel tempo quando il sistema transisce da
uno stato ad un altro. Non per esempio possibile esprimere, attraverso formule delle logiche
proposizionali, propriet del tipo dopo aver eettuato una certa azione lo stato del sistema
verifica la propriet '.
Per trattare propriet di questo tipo si possono usare le logiche modali.

13.3

Logiche modali proposizionali

Nelle logiche proposizionali ogni evento si intende riferito allistante presente del tempo. Proposizioni come file_eliminato vengono interpretate secondo il significato il file stato eliminato
adesso. Per poter introdurre il concetto di tempo e disporre degli strumenti per definire un
ordinamento tra gli istanti di tempo considerati, nelle logiche modali1 si introduce un insieme
R di relazioni binarie i cui elementi R 2 R sono relazioni di transizione tra stati. Ogni relazione R pu essere etichettata associando ad ogni suo elemento lazione che causa il passaggio da
uno stato allaltro. Nel caso in cui R sia etichettata, linsieme AP delle proposizioni atomiche
pu non esserci; questo il caso della logica HML che vedremo nella sezione successiva.
Loperatore principale delle logiche modali che consente di riferirsi ad istanti successivi
del tempo diamond, scritto hRi'. Il significato di hRi' che esiste un qualche stato in
relazione R con quello attuale nel quale la propriet ' verificata. Loperatore duale di
diamond, che prende il nome di box, scritto [R]', significa che in qualunque stato in relazione
R con quello attuale la propriet ' verificata. In pratica, loperatore diamond consente
di definire propriet di possibilit ( possibile arrivare in uno stato nel quale verificata la
propriet espressa dalla formula '), mentre loperatore box consente di definire propriet di
necessit (tutti gli stati in relazione R con quello attuale soddisfano la propriet ').
Se aggiungiamo alla logica proposizionale le due modalit di cui sopra, otteniamo la logica
modale proposizionale la cui sintassi delle formule definita dalla grammatica seguente:
' ::= true

AP

'

' 1 _ '2

'1 ^ '2

hRi'

[R]'

Per formalizzare la semantica della logica modale nel corso del tempo sono stati proposti
molti modelli dierenti. A noi qui interessa la semantica basata su strutture di Kripke. La
relazione di soddisfazione, indicata con il simbolo |=, in questo caso una relazione ternaria
tra una struttura di Kripke K , hQ, R, AP, I i, uno stato q 2 Q e una formula modale '. Per
convenienza notazionale, ometteremo K quando chiaro dal contesto. Quindi, la relazione |=
definita per induzione sulla sintassi delle formule dalle regole seguenti:
q |= true;
1

q |= p sse q 2 I(p);
La logica modale risale ad Aristotele, che la utilizz per studiare i concetti di possibilit e necessit.

306

Capitolo 13 Logiche per i sistemi concorrenti


q |= ' sse non vero che q |= ';
q |= '1 _ '2 sse q |= '1 oppure q |= '2 ;
q |= '1 ^ '2 sse q |= '1 e q |= '2 ;
q |= hRi' sse 9q 0 2 Q tale che hq, q 0 i 2 R e q 0 |= ';
q |= [R]' sse 8q 0 2 Q tale che hq, q 0 i 2 R vale q 0 |= '.

Alcuni degli operatori sono derivati nel senso che potrebbero essere eliminati senza che
ci influisca sul potere espressivo della logica (li abbiamo posti nella sintassi di base per
comodit). Potremmo porre per definizione
'1 ^ '2 , ('1 _ '2 )

[R]' , hRi'

e derivare la semantica delle formule '1 ^ '2 e [R]' da quella degli altri operatori della logica.
Nel caso del secondo operatore, possiamo procedere come mostrato di seguito:
q |= [R]'
, q |= hRi'
per definizione di [R]
, (9q 0 2 Q tale che hq, q 0 i 2 R e q 0 |= ') per la semantica di hRi
, 8q 0 2 Q tale che hq, q 0 i 2 R vale q 0 |= '
per la semantica di
Le logiche modali hanno una espressivit limitata, puramente locale. Infatti, la verit
di una formula modale di lunghezza n in un modello dipende solo dagli stati a distanza
al pi n dallo stato inizialmente considerato per interpretare la formula. Pertanto, la logica
modale troppo debole per esprimere molte delle propriet desiderabili dei sistemi informatici
che abbiamo accennato nellintroduzione di questo capitolo. Per ottenere la possibilit di
esprimere propriet globali, sono necessarie logiche pi potenti, quali quelle temporali.

13.4

La logica HML

HML (Hennessy-Milner Logic [HM85]) una logica modale e quindi permette di descrivere
capacit locali dei sistemi. La principale caratteristica che distingue HML dalle logiche modali
proposizionali presentate nella sezione precedente risiede nel fatto che le relazioni di transizione
R 2 R sono etichettate con le azioni, appartenenti ad un certo insieme A, che causano il
passaggio da uno stato allaltro. Questo comporta che possiamo fare a meno di AP e di
conseguenza il dominio di interpretazione delle formule della logica passa da KS a LTS. Nel
seguito, supporremo che i LTS hQ, A, !i usati per interpretare le formule HML (ma anche
quelle di ACTL in Sezione 13.6) soddisfano la seguente propriet
a

8q 2 Q, 9q 0 2 Q, 9a 2 A tali che q ! q 0 ,
cio ogni stato ha almeno un successore, quindi i cammini in una tale struttura sono infiniti.
Dato un insieme A di azioni (con , 2 A), la sintassi delle formule HML definita dalla
grammatica seguente:
' ::= true

'

'1 _ '2

' 1 ^ '2

<> '

[]'

307

13.4 La logica HML

Nel seguito useremo per indicare linsieme di tutte le formule HML.


I costrutti della logica possono essere informalmente spiegati come segue (si tenga presente
che le formule della logica vanno interpretate rispetto agli stati di un LTS). true una formula
costante vera per tutti gli stati (f alse derivata come al solito). e _ rappresentano i due
operatori logici standard negazione e disgiunzione (quello di congiunzione derivato come al
solito). Gli operatori modali permettono di formulare propriet di un sistema in termini delle
relazioni definite dalle transizioni che si originano a partire da uno stato. Quindi, uno stato
soddisfa <> ' se una delle sue -derivate soddisfa ', mentre soddisfa []' se tutte le sue
-derivate soddisfano '.
Per formalizzare la semantica della logica HML, definiamo la relazione di soddisfazione,
indicata con il simbolo |=, come una relazione ternaria tra un LTS S = hQ, A, !i avente lo
stesso insieme di azioni A assunto per HML, uno stato q 2 Q e una formula '. Per convenienza
notazionale, ometteremo S quando chiaro dal contesto. Quindi, la relazione |= definita
per induzione sulla sintassi delle formule HML dalle regole seguenti:
q |= true;
q |= ' sse non vero che q |= ';
q |= '1 _ '2 sse q |= '1 oppure q |= '2 ;
q |= '1 ^ '2 sse q |= '1 e q |= '2 ;

q |=<> ' sse 9q 0 2 Q tale che q ! q 0 e q 0 |= ';

q |= []' sse 8q 0 2 Q tale che q ! q 0 si ha q 0 |= '.


La definizione della semantica di HML include alcune sottigliezze che meritano di essere
commentate. La formula []f alse soddisfatta da q se e solo se q non ha -derivate. In
eetti, uno stato senza alcuna -derivata soddisfa []' per ogni '. Ci implica anche che uno
stato incapace di qualunque azione nellinsieme {1 , . . . , n } soddisfa la formula [1 ]f alse ^
. . . ^ [n ]f alse e, viceversa, la formula [1 ]f alse ^ . . . ^ [n ]f alse soddisfatta solo da quegli
stati che non hanno -derivate, con 2 {1 , . . . , n }. Analogamente, uno stato soddisfa
< > true se e solo se ha almeno una -derivata. In generale, data una sequenza non vuota
di azioni 1 . . . m , uno stato in grado di eettuare la sequenza di azioni 1 . . . m (cio,
la sequenza una traccia forte per quello stato) se e solo se lo stato soddisfa la formula
< 1> . . . < m> true. Consideriamo ora la formula
< 1> . . . <

m>

([1 ]f alse ^ . . . ^ [n ]f alse)

Uno stato soddisfa questa formula se pu eseguire la sequenza 1 . . . m e arrivare in uno stato
che rifiuta le oerte di interazione che coinvolgono le azioni 1 . . . n . Quindi, in un ambiente
capace prima di eseguire la sequenza 1 . . . m e poi di richiedere uninterazione che coinvolge
unazione tra le 1 . . . n , lo stato considerato potrebbe andare in deadlock.
Come abbiamo gi detto nella sezione precedente, alcuni degli operatori sono derivati
nel senso che potrebbero essere eliminati senza che ci influisca sul potere espressivo della
logica (li abbiamo posti nella sintassi di base per comodit). Potremmo porre per definizione
'1 ^ '2 , ('1 _ '2 )

[]' , <> '

308

Capitolo 13 Logiche per i sistemi concorrenti

infatti le due coppie di formule hanno lo stesso significato. Inoltre, se K , {1 , . . . , n } A


e s , 1 n , allora possono essere utilizzate le seguenti abbreviazioni:
<K> ' per denotare la formula <1> ' _ _ <n> ';
<s> ' per denotare la formula <1> <n> ';
[K]' per denotare la formula [1 ]' ^ ^ [n ]';
[s]' per denotare la formula [1 ] [n ]'.
A volte useremo K per indicare linsieme complementare di K rispetto ad A (cio linsieme
A \ K) ed il simbolo per indicare linsieme di tutte le azioni (cio A).
Vediamo ora alcuni esempi di formule HML.
[ ]f alse rappresenta la propriet di deadlock forte perch soddisfatta solo da quegli
stati che non sono in grado di eseguire alcuna azione (infatti, nessuno stato potrebbe
soddisfare f alse).
[ {}]f alse (a volte scritta come [ ]f alse) vera in quegli stati che non possono
eettuare transizioni con etichette diverse da .
< > true ^ [ ](< > true ^ [ {, }]f alse) vera in quegli stati che possono inizialmente fare unazione qualsiasi e immediatamente dopo possono solo fare unazione o
.
Esempio 13.1. Consideriamo il grafo delle transizioni di Figura 10.1 relativo allEsempio 10.2
(Bill-Ben) descritto dal termine CCS
Bill_Ben , (play.meet.nil | work.meet.nil)\meet.
Esaminiamo alcune semplici propriet del sistema descrivibili con HML.
Bill_Ben |= (<play><work><> true) _ (<work><play><> true) cio il sistema
pu fare la sequenza di azioni play work o la sequenza play work .
Bill_Ben |= [ {play, work}]f alse cio non si possono fare azioni iniziali diverse da
play e work.
Bill_Ben |= [play][play]f alse cio subito dopo unazione play non si pu eseguirne
unaltra uguale.
A questo punto occupiamoci della relazione tra lequivalenza indotta dalla logica, denotata
con HM L , e la bisimilarit forte . Indichiamo con q 6|= ' il fatto che q |= ' non vera.
Definizione 13.2. Siano hQ, A, !i un LTS e p, q 2 Q. Allora scriveremo p HM L q se per
ogni formula HML ', o p |= ' e q |= ' oppure p 6|= ' e q 6|= '.
Definiamo ora una classe speciale di LTS.

309

13.4 La logica HML

Definizione 13.3. Diremo che un LTS hQ, A, !i image-finite se 8q 2 Q, 8s 2 A linsieme


s
{q 0 2 Q | q ! q 0 } finito.
0
n Si noti che un
o LTS image-finite se, e solo se, 8q 2 Q e 8 2 A linsieme

q 00 2 Q | q 0 ! q 00 finito. Quindi nessun processo derivabile da p ha un numero infinito di


comportamenti. In pratica, la classe dei LTS image-finite
n piuttosto grande. Pero esempio,

sistemi finite-branching (cio tali che 8q 2 Q linsieme (, q 0 ) 2 A Q | q ! q 0 finito)


sono image-finite. In particolare, i LTS che corrispondono ai processi CCS sono image-finite
se le definizioni delle costanti di processo coinvolte sono guardate (si tenga comunque presente
che questa condizione solo suciente ma non necessaria). Ora, per LTS image-finite, vale il
seguente importante risultato (che non dimostreremo).

Teorema 13.4. Sia hQ, A, !i un LTS image-finite. Allora, per ogni p, q 2 Q, p HM L q se


e solo se p q.
Dimostrazione.
Questo risultato, e le osservazioni precedenti riguardo le formule HTML, confermano che
la bisimilarit richiede che stati bisimili abbiano lo stesso potenziale di deadlock. Inoltre,
il teorema fornisce un utile meccanismo per dimostrare che due stati non sono bisimili:
suciente trovare una formula HML soddisfatta da uno e non dallaltro. Vediamo un paio di
esempi nel contesto di CCS.
Consideriamo i processi CCS cos definiti: A , a.b.nil + a.c.nil e B , a.(b.nil + c.nil).
Dato che A 6 B ci deve essere (almeno) una formula soddisfatta da uno e non dallaltro.
Una formula di questo tipo [a] <b> true, che soddisfatta da B ma non da A.
Consideriamo ora i processi CCS cos definiti: C , a.C e D , a.D + a.nil. Evidentemente, D pu raggiungere uno stato di deadlock dopo una transizione a, mentre C non
andr mai in deadlock. La formula <a> [a]f alse li distingue, dato che D la soddisfa a
dierenza di C.
Infine, il Teorema 13.4 si pu generalizzare ad LTS generici
imageW (cio non necessariamente
V
finite) a patto di estendere HML con il connettivo logico i2I (ed il derivato i2I ) quantificato
rispetto ad insiemi di indici eventualmente infiniti.

I due operatori modali diamond e box possono essere indeboliti in modo da poter analizzare solo le azioni osservabili, ignorando le azioni interne. Si ottiene cos la variante weak
di HML. Quindi, prendendo un insieme di azioni qualsiasi ma contenente lazione interna ,
cio A [ { }, la sintassi delle formule di weak HML definita dalla grammatica seguente:
' ::= true

'

'1 _ '2

'1 ^ '2

'

'

[[]]'

[[ ]]'

dove 2 A (cio 6= ).
Intuitivamente, il significato dei nuovi operatori modali il seguente.
' (weak-diamond -): esiste un -discendente dello stato corrente che soddisfa '.
' (weak-diamond ): esiste una computazione dallo stato corrente formata da sole
azioni interne che porta in uno stato che soddisfa '.

310

Capitolo 13 Logiche per i sistemi concorrenti


[[]]' (weak-box -): ogni -discendente dello stato corrente soddisfa '. Ovviamente, la
formula vale anche se lo stato corrente non ha -discendenti.
[[ ]]' (weak-box ): tutte le computazioni dallo stato corrente formate da sole azioni
interne portano in stati che soddisfano '.

Formalmente, poich weak HML astrae dalle azioni interne che un sistema pu eettuare,
la sua interpretazione va definita su un LTS il cui insieme di azioni contiene lazione interna ,
cio un LTS della forma hQ, A[{ } , !i. Quindi, la relazione di soddisfazione |= che determina
la semantica delle formule definita per induzione sulla loro sintassi dalle regole seguenti
(mostriamo solo la semantica dei nuovi operatori, poich quella degli altri non cambia):
q |=

' sse 9q 0 2 Q tale che q =


) q 0 e q 0 |= ';

q |= ' sse 9q 0 2 Q tale che q =


) q 0 e q 0 |= ';
q |= [[ ]]' sse 8q 0 2 Q tale che q =
) q 0 si ha che q 0 |= ';

q |= [[]]' sse 8q 0 2 Q tale che q =


) q 0 si ha che q 0 |= '.
Vediamo ora alcuni esempi di formule weak HML.

true significa che c la possibilit di fare una sequenza di zero o pi inizialmente.

[[]]

true significa che ogni -discendente ha almeno un -discendente.

Anche per weak HML valgono le considerazioni gi espresse in precedenza a proposito


degli operatori derivati. Per esempio, loperatore di necessit debole esprimibile nel modo
seguente:
[[]]' , '.

Si possono anche utilizzare abbreviazioni simili a quelle definite per HML. A dierenza del
caso di HML, K denota il complemento di K rispetto allinsieme A (che non contiene lazione
).
Weak HML pi debole di HML poich, ad esempio, non in alcun modo capace di
esprimere loperatore <> , cosicch una formula non pu in alcun modo far riferimento alle
azioni interne (al contrario, tutti gli operatori di weak HML possono essere espressi in HML).
Per quanto riguarda i rapporti con le equivalenze comportamentali, possibile dimostrare che
lequivalenza indotta da weak HML coincide con la bisimilarit debole (sempre a condizione
che i LTS considerati siano image-finite), cio vale un teorema di corrispondenza simile a
quello tra HML e bisimilarit forte (anche questo non lo dimostreremo).
Teorema 13.5. Sia hQ, A, !i un LTS image-finite. Allora, per ogni p, q 2 Q, p W HM L q
se e solo se p q.
Dimostrazione.
Ci quindi implica che anche se ignora le computazioni interne, la bisimilarit debole (e
quindi anche lequivalenza osservazionale) gode ancora di un grado di sensibilit al deadlock
simile a quello della bisimilarit forte. A questo proposito consideriamo i due processi CCS
A , a.b.c.nil + a.b.d.nil e B , a.(b.c.nil + b.d.nil). Sappiamo gi che questi due processi non
sono in relazione tra loro; infatti, la formula [[a]]b c true soddisfatta da B e non
da A.

311

13.5 Logiche temporali

13.5

Logiche temporali

Le logiche temporali sono pi espressive delle logiche modali ma non richiedono il background
matematico necessario per capire ed apprezzare le definizioni ricorsive che sono alla base
dellespressivit del -calculus modale (che vedremo nella Sezione 13.8). Le logiche temporali
si occupano di concetti come sempre, mai, qualche volta, . . . . Costituiscono una branca
della logica di origine antica, ma solo negli anni 50 sono state studiate matematicamente,
a cominciare dal lavoro di Prior [Pri57]. Negli anni 70 sono state applicate alla verifica di
correttezza dei sistemi informatici, a cominciare dal lavoro di Pnueli [Pnu77].
Esistono vari aspetti da considerare per definire un modello matematico del tempo: lineare o ramificato, discreto o continuo, finito o infinito, unidirezionale o bidirezionale, . . . .
Come abbiamo visto nella prima sezione di questo capitolo, lalternativa tra tempo lineare e
ramificato genera due possibilit egualmente interessanti. Il tempo si dice lineare se in ogni
istante il sistema pu evolvere in un solo modo nellistante successivo; levoluzione si ragura
quindi su una linea retta. Invece, il tempo si dice ramificato se in ogni istante, il sistema
pu evolvere in molti modi, in questo caso levoluzione si rappresenta con un albero. Per
quanto riguarda gli altri aspetti, le scelte sono dettate dal fatto che lo scopo fare previsioni
sul comportamento futuro di un sistema. Pertanto, le logiche temporali specializzate per la
verifica di sistemi che presenteremo fanno tutte le seguenti assunzioni:
il tempo discreto: tra un istante e laltro, si hanno solo un numero finito di istanti
intermedi;
il tempo infinito nel futuro e finito nel passato: c un primo istante ma non un ultimo;
il tempo fluisce dal passato al futuro: siamo interessati a cosa accadr nel futuro.
Infine, si tenga presente che lespressivit di molte logiche temporali linear e branching
time non confrontabile. Ci significa che ci sono propriet esprimibili in una logica lineare
che non possono essere espresse in una branching, e viceversa. Inoltre, anche le tecniche per
il model checking di queste due classi di logiche sono solitamente piuttosto dierenti.

Linear Time Logic2 (LTL)


Un notevole incremento del potere espressivo di una logica pu derivare dalla capacit di
formulare propriet valide in intervalli di tempo. Per essere in grado di esprimere questo tipo
di propriet, in LTL viene introdotto un nuovo operatore U+ , chiamato Until 3 . Con questo
nuovo operatore possibile esprimere formule del tipo:
, '1 U+ '2
La formula va interpretata su un cammino di una struttura di Kripke (intuitivamente una
sequenza di stati in cui ogni coppia di stati consecutivi appartiene alla relazione di transizione
della struttura) ed verificata se la formula '1 valida negli stati intermedi di tale cammino
fino a che non si raggiunge uno stato in cui verificata la formula '2 . Graficamente la
propriet pu essere rappresentata dallo schema riportato in Figura 13.1.
2

Viene anche detta Propositional Linear Time Logic (PLTL).


In letteratura sono state proposte e studiate molte varianti delloperatore Until. La variante su cui qui ci
basiamo ha il pregio di permetterci di derivare tutti i principali operatori temporali.
3

312

Capitolo 13 Logiche per i sistemi concorrenti

...

Figura 13.1: Propriet '1 U+ '2


La logica temporale lineare, LTL, si pu ottenere aggiungendo alla logica proposizionale
loperatore Until. La sintassi delle formule di LTL definita dalla grammatica seguente:
' ::= true

AP

'

'1 _ '2

'1 ^ '2

'1 U+ '2

La relazione di soddisfazione, indicata con il simbolo |=, in questo caso una relazione
ternaria tra una struttura di Kripke K , hQ, R, AP, I i, un cammino in K (si veda la
Definizione 3.14) e una formula LTL '. Per convenienza notazionale, ometteremo K quando
chiaro dal contesto. Quindi, la relazione |= definita per induzione sulla sintassi delle formule
di LTL dalle regole seguenti:
|= true;
|= p sse q0 0 e q0 2 I(p);
|= ' sse non vero che |= ';
|= '1 _ '2 sse |= '1 oppure |= '2 ;
|= '1 ^ '2 sse |= '1 e |= '2 ;
|= '1 U+ '2 sse 9i > 0 tale che i |= '2 e per ogni 0 < j < i vale j |= '1 .
In LTL, alcuni importanti operatori temporali, quali neXt X, Future F e Global G, possono
essere derivati utilizzando loperatore U+ come mostrato di seguito. possibile innanzitutto
definire un operatore, detto Until riflessivo, che tenga anche conto dello stato attuale. Tale
operatore, indicato con U , definito come segue:
'1 U '2 , '2 _ ('1 ^ ('1 U+ '2 )).
La dierenza sostanziale con la formula '1 U+ '2 , che anch '1 U '2 sia vera, '1 deve
valere anche nello stato attuale oppure '2 devessere subito vera. Graficamente loperatore
illustrato in Figura 13.2. Utilizzando gli operatori Until possiamo porre:
X ' , f alse U+ ';
F+ ' , true U+ ';
F ' , true U ';
G' , (true U ').
X detto neXt in quanto, anch la formula X ' sia verificata, ' deve valere in uno stato
immediatamente successivo a quello attuale, cio raggiunto con un solo passo di transizione.
F invece viene chiamato Future in quanto ci consente di esprimere il fatto che la formula
' varr prima o poi in qualcuno degli stati successivi, cio raggiunti nel futuro: un futuro

313

13.5 Logiche temporali

...

Figura 13.2: Propriet '1 U '2


proprio, nel caso di F+ ', ed un futuro che contiene anche listante presente, nel caso di F '.
Infine, G viene chiamato Global poich consente di specificare che una data formula ' valida
in tutti gli stati di una computazione a partire dallo stato attuale.
Chiudiamo questa sezione con alcuni esempi di formule LTL che mostrano che, a dierenza della logica modale, la logica temporale sucientemente potente da esprimere molte
propriet globali desiderabili dei sistemi. Se ' una propriet che si vuole evitare, allora
G' dice che ' non accadr mai; questo un esempio di propriet di safety. Se '1 e '2
sono propriet, '1 ! F+ '2 dice che, se in un qualche stato vale '1 , allora in qualche stato
successivo varr '2 . Per esempio, se un utente chiede laccesso a una stampante, prima o poi
lo otterr; questo un esempio di propriet di liveness. Una propriet di liveness pi forte
'1 ! X '2 ; nel caso della stampante, dice che una richiesta di accesso alla stampante
soddisfatta immediatamente. Combinando gli operatori temporali possiamo esprimere anche
propriet di fairness. Per esempio, la formula GF ' significa che ' vera infinite volte,
mentre la formula F G ' significa che ' vera in tutti gli stati salvo un numero finito.

Computation Tree Logic (CTL)


Mentre nel caso delle logiche temporali linear time la logica LTL che abbiamo appena presentato quella pi usata, nel caso delle logiche branching time c pi variet. In particolare qui
presentiamo la Computation Tree Logic (CTL [CE81]). Questa logica deve il suo nome al fatto
che viene interpretata su modelli ad albero che rappresentano lalbero delle computazioni del
sistema in analisi.
Lidea alla base di CTL di estendere la logica temporale lineare con due nuovi operatori:
i quantificatori esistenziale (E) e universale (A) sui cammini. Cos, intuitivamente, se '
una formula, E' significa che ' vera in qualche cammino, e A' significa che ' vera in ogni
cammino. Con lintroduzione dei quantificatori, la logica acquisisce la capacit di distinguere
tra propriet vere in specifici rami di esecuzione, nei quali pu evolvere il sistema eettuando
scelte precise, e propriet vere indistintamente dal ramo seguito nellalbero di evoluzione. In
CTL, tuttavia, luso dei quantificatori permesso solo se questi sono immediatamente seguiti
da un operatore temporale (diversamente dallestensione CTL [CE81] in cui non c alcuna
restrizione). La sintassi delle formule di CTL quindi definita dalla grammatica seguente:
' ::= true

AP

'

'1 _ ' 2

'1 ^ '2

E ('1 U+ '2 )

A ('1 U+ '2 )

Come si pu notare, i quantificatori possono solo essere seguiti da formule che utilizzano
loperatore Until.
La relazione di soddisfazione, indicata con il simbolo |=, in questo caso una relazione
ternaria tra una struttura di Kripke K , hQ, R, AP, I i, un albero delle computazioni in
K (si veda la Definizione 3.15) e una formula CTL '. Se per semplicit omettiamo K ed
identifichiamo un albero con la sua radice, le clausole che definiscono la semantica delle formule
con i quantificatori la seguente:

314

Capitolo 13 Logiche per i sistemi concorrenti

Figura 13.3: Rappresentazione schematica del significato delle formule


q0 |= E ('1 U+ '2 ) sse 9 2 P aths(q0 ), 9i > 0 tale che [i] |= '2 e [j] |= '1 per ogni
0 < j < i;
q0 |= A ('1 U+ '2 ) sse 8 2 P aths(q0 ), 9i > 0 tale che [i] |= '2 e [j] |= '1 per ogni
0 < j < i.
La semantica delle altre formule facilmente adattabile al nuovo modello di interpretazione.
Intuitivamente, E ('1 U+ '2 ) significa che, in qualche cammino, '1 vale fino alla prima
volta in cui vale '2 ; analogamente, A ('1 U+ '2 ) dice che ci vale in ogni cammino.
Ovviamente gli operatori derivabili da U+ , quali ad esempio X e U , sono anchessi soggetti allutilizzo dei quantificatori. In Figura 13.3 riportata una rappresentazione grafica
schematica del significato dei costrutti derivati. Sono rappresentati in maniera semplificata quattro alberi di derivazione e ciascuno associato ad una formula verificata dallalbero
stesso. Le linee spezzate allinterno dellalbero rappresentano rami di un cammino mentre i
cerchietti rappresentano i nodi dellalbero. I nodi nei quali soddisfatta la propriet ' sono
rappresentati con un cerchietto nero mentre i nodi che verificano sono quelli vuoti. Larea
riempita di grigio indica che tutti i nodi al suo interno verificano la formula '.
Chiudiamo con alcuni esempi di formule CTL. La formula EX' equivale a dire che esiste
un successore dello stato attuale in cui vale ', proprio come la formula hRi' in logica modale.
Analogamente, la formula AX' equivale a dire che in ogni successore vale ', perci corrisponde alla formula [R]' in logica modale. Quindi CTL include la logica modale. Un altro
esempio la formula AG', che significa che ' varr sempre, nel senso che sar vera in ogni
stato di ogni cammino che parte dal punto in cui la formula valutata. Questa una propriet
di safety. Notiamo che non detto che tutti gli stati del modello siano raggiungibili dallo
stato in cui si valuta la formula; perci la formula non dice nulla sugli stati irraggiungibili.
Analogamente, la formula EF ' significa che ' vale in qualche stato di qualche cammino che
parte dallo stato in cui la formula valutata. Questa una propriet di liveness. Unaltra
propriet di liveness pi complicata esprimibile in CTL AF ' che significa che in ogni
cammino esiste uno stato in cui ' vera. Tale propriet si chiama talvolta inevitabilit.
Combinando gli operatori lineari abbiamo in CTL formule come A G E F ' che significa che
in ogni futuro c un futuro successivo in cui vale '.
Per fare un esempio di formule CTL che non sono (sintatticamente) in CTL, possiamo
considerare la formula di fairness E G F ' che significa che esiste un cammino in cui ' vale
infinite volte. In realt tale formula non neanche equivalente ad alcuna formula di CTL.
Infatti, alcuni risultati teorici dimostrano che CTL strettamente pi espressiva di CTL.
In generale CTL non pu esprimere propriet di fairness poich non possibile annidare gli
operatori G e F senza inserire tra loro un quantificatore di cammino. Lunica propriet di
fairness rilevante che pu essere espressa A G A F '. Bench CTL sia molto espressiva, ci
sono propriet che anche CTL non pu esprimere, quali le propriet cicliche. Ad esempio,

315

13.6 La logica ACTL

non possibile esprimere il fatto che in qualche cammino una certa propriet ' vale in tutti
gli stati in posizione pari. I limiti del potere espressivo di CTL motivano lintroduzione di
logiche pi potenti quali il -calculus modale, che sar presentato nella Sezione 13.8.

13.6

La logica ACTL

ACTL (Action-based Computation Tree Logic [DV90]) una logica temporale di tipo branching time derivata da CTL. Il nome della logica dovuto al fatto che le formule fanno
specifico riferimento alle azioni che il sistema in esame pu compiere. Grazie a questa sua
caratteristica ACTL consente di descrivere in maniera semplice ed intuitiva le propriet di un
sistema. Le formule di ACTL sono costruite usando i quantificatori di cammino 8 ed 9 (per
descrivere la struttura ramificata dellalbero delle computazioni) e gli operatori temporali X
ed U (per descrivere le propriet di un cammino nellalbero).
8 corrisponde allespressione per tutti i cammini di computazione, quindi la propriet
che segue questo quantificatore deve valere in ogni sequenza di azioni a partire dallo
stato corrente.
9 corrisponde allespressione per qualche cammino di computazione, quindi la propriet
che segue questo quantificatore deve valere almeno in una sequenza di azioni a partire
dallo stato corrente.
X loperatore neXt: corrisponde allespressione next time, quindi la formula che
segue questo operatore deve valere nello stato successivo del cammino che si sta
analizzando.
U loperatore Until : prende in input due formule e indica che esiste uno stato q nel
cammino che si sta analizzando in cui vale la seconda formula, ma in tutti gli stati che
precedono q vale la prima formula.
Formalizziamo ora la struttura della logica ACTL. Per rendere pi comprensibile la sintassi delle formule ACTL scomponiamo la sua definizione distinguendo tre categorie sintattiche:
formule di stato, formule di cammino e formule di azione. Come si detto la logica parametrizzata rispetto ad un insieme di azioni A [ { }; nel seguito, supporremo che 2 A. La
sintassi delle formule di ACTL quindi definita dalla grammatica seguente:
formule di stato ' ::= true
formule di cammino
formule di azione

::= X '
::=

'

X '

' _ '0

' U

0
0'

' U '0

Si noti che nelle formule di stato ogni operatore temporale preceduto da un quantificatore
di cammino.
Una formula di azione individua un insieme di azioni visibili, che sono appunto quelle che
la soddisfano. A volte useremo le formule derivate true, che sta per _ , per indicare
linsieme di tutte le azioni visibili, e f alse, che sta per true, per indicare linsieme vuoto di
azioni visibili.
Una novit importante che distingue la logica ACTL dalla logica CTL che, sebbene
anche questultima avesse delle formule di cammino, in ACTL ad ognuna di queste viene

316

Capitolo 13 Logiche per i sistemi concorrenti


U

b1

b2

...

bn

...

b1

b2

...

bn

...

dove b1 |= , . . . , bn |= e a |=

Figura 13.4: Significato delle formule dazione nelloperatore Until di ACTL


associata una formula di azione. Cos, alloperatore neXt viene associata una formula di
azione o lazione interna ; la formula X ' (rispettivamente X ') verificata dallo stato
corrente se la formula ' vale in tutti gli stati raggiungibili mediante unazione che rispetta
(rispettivamente, unazione interna). In maniera analoga, una formula di cammino con
loperatore Until verificata dallo stato corrente se eettuando zero o pi azioni che rispettano
si raggiungono sempre stati che verificano ' fino a raggiungere, compiendo unazione che
verifica 0 (o unazione qualsiasi, qualora questa non venga specificata) uno stato che verifica
'0 . Una rappresentazione grafica del significato delloperatore Until in ACTL riportata in
Figura 13.4.
Alcuni utili operatori derivati sono i seguenti:
' ^ '0 , (' _ '0 )

' ! '0 , ' _ '0

' $ '0 , (' ! '0 ) ^ ('0 ! ')

Per formalizzare la semantica della logica ACTL, definiamo tre relazioni di soddisfazione,
indicate con il simbolo |=, una per ogni diversa tipologia di formule. Infatti, dato un LTS
S = hQ, A [ { } , !i avente lo stesso insieme di azioni visibili A assunto per ACTL, le formule
di stato vanno interpretate rispetto ad uno stato q 2 Q, quelle di cammino rispetto ad un
cammino 2 P ath(q) (si veda anche la Definizione 3.10), e quelle di azione rispetto ad
unazione 2 A. Le relazioni |= sono definite come al solito per induzione sulla sintassi delle
formule ACTL dalle regole seguenti:
q |= true;
q |= ' sse non vero che q |= ';
q |= ' _ '0 sse q |= ' oppure q |= '0 ;
q |= 9 sse 9 2 P ath(q) tale che |= ;
q |= 8 sse 8 2 P ath(q) si ha |= ;
|= X ' sse = (q, , q 0 ), q 0 |= ' e |= ;
|= X ' sse = (q, , q 0 ) e q 0 |= ';

317

13.6 La logica ACTL

|= ' U 0 '0 sse 9i > 0 tale che [i + 1] |= '0 , [i] |= ' e i |= 0 , dove i
([i], i , [i + 1])i+1 , e 8j : 0 j < i abbiamo [j] |= ' e j |= oppure j , dove
j ([j], j , [j + 1])j+1 ;
|= ' U '0 sse 9i > 0 tale che [i] |= '0 e 8j : 0 j < i abbiamo [j] |= ' e j |=
oppure j , dove j ([j], j , [j + 1])j+1 ;
|=

sse ;

|= sse non vero che |= ;


|=

sse |=

_ |=

0.

I due operatori temporali standard Future e Global in ACTL possono essere derivati come
mostrato di seguito.
F ' , truetrue U ' (prima o poi nel futuro) asserisce che ' varr in qualche stato
successivo del cammino considerato. Infatti, qualsiasi stato soddisfa true e qualsiasi
azione visibile soddisfa true.
G' , F ' (sempre) asserisce che ' vale in ogni stato del cammino considerato
(infatti, letteralmente la formula asserisce che non possibile che prima o poi lungo il
cammino analizzato si arrivi in uno stato che non soddisfa ').
Vediamo ora alcuni esempi di formule ACTL.
9X true: esiste un cammino la cui prima azione silente.
8X true: tutti i cammini dallo stato corrente iniziano con lazione .
9(true U f alse): esiste un cammino infinito di sole azioni e .

Saf ety(') , 8G': non si arriva mai in uno stato in cui vale la condizione '.

Liveness(') , 8F ': in ogni cammino, prima o poi si arriva in uno stato in cui vale '.

Per quanto riguarda i rapporti con le equivalenze comportamentali, possibile dimostrare


che lequivalenza indotta da ACTL coincide con la bisimilarit di branching (sempre a condizione che i LTS considerati siano image-finite), cio vale il seguente teorema di corrispondenza
(anche questo non lo dimostreremo).
Teorema 13.6. Sia hQ, A, !i un LTS image-finite. Allora, per ogni p, q 2 Q, p ACT L q se
e solo se p b q.

Concludiamo la sezione introducendo il concetto di formula caratteristica di un sistema.


Si tratta della formula pi generale associabile ad un sistema che indica il comportamento del
sistema stesso. A partire da essa possibile dimostrare, per implicazione, tutte le formule che
il sistema soddisfa.
Spieghiamo il concetto tramite un esempio. A questo proposito, consideriamo nuovamente
il grafo delle transizioni di Figura 10.1 relativo allEsempio 10.2 (Bill_Ben). Si potrebbe
dimostrare che il sistema ha la seguente formula caratteristica:
(9Xplay 8Xwork 8X (9Xtrue true)) _ (9Xwork 8Xplay 8X (9Xtrue true))
Descriviamo ora alcune propriet di Bill_Ben usando la logica ACTL.

318

Capitolo 13 Logiche per i sistemi concorrenti


8X{play_work} true: tutti i cammini del sistema, cominciano con play o con work.
8(true{play_work} U (8X (9Xtrue true))): in tutti i cammini, dopo una certa sequenza
di azioni play e work, si va in uno stato in cui si pu fare soltanto unazione interna che
porta in deadlock.
8F (9X true): in ogni cammino, prima o poi, possibile eettuare unazione interna.
Ci corrisponde alla propriet Liveness(9X true).

Si potrebbe dimostrare che la formula caratteristica del sistema implica ciascuna delle
propriet suddette.

13.7

Propriet infinitarie: HML con ricorsione

Come abbiamo accennato alla fine della Sezione 13.3, lespressivit delle formule modali
assai limitata. Queste infatti consentono di esprimere propriet che descrivono comportamenti
finiti di un sistema sistema, mentre si visto che una delle caratteristiche principali dei sistemi
reattivi quella di avere comportamenti infiniti. Tale limitazione deriva del fatto che ogni
operatore delle logiche modali consente di studiare le evoluzioni del sistema limitatamente ad
un passo di esecuzione, per questo, e per il fatto che si possono prendere in considerazione
solamente formule di lunghezza finita, gli unici comportamenti analizzabili sono quelli con
un numero finito di azioni. Una misura per esprimere quanto a fondo il comportamento di
un sistema pu essere studiato utilizzando delle formule modali costituita dalla cos detta
profondit modale (modal depth) della formula. Questa definita come il massimo livello di
annidamento degli operatori modali allinterno di una formula. Ad esempio, se si considera
la formula hai[b]true _ hcitrue la profondit modale pari a due; verificare se un processo
soddisfa o meno la formula comporta dunque lanalisi di comportamenti del sistema costituiti
da sequenze di azioni che possono avere una lunghezza massima pari a due.
Per poter esprimere propriet legate al tempo, quali il sistema pu sempre eettuare una
certa azione, abbiamo introdotto le logiche temporali. Una prima alternativa per rendere le
logiche modali capaci di esprimere propriet infinitarie potrebbe essere quella di introdurre
la possibilit di definire congiunzioni e disgiunzioni infinite. Per esempio, consideriamo il
processo CCS C , a.C. C pu sempre (in ogni punto della computazione) eseguire unazione
a, cio la formula <a> true uninvariante. Chiamiamo questa propriet Inv(<a> true);
potremmo esprimerla in HML nel modo seguente:
Inv(<a> true) , <a> true ^ [a] <a> true ^ [a][a] <a> true ^ . . .
1
^
=
[a]i <a> true
i=0

La formula pu essere interpretata cos: anch un processo sia sempre capace di eseguire
unazione a, tale azione devessere possibile subito (come espresso dalla sottoformula <a>
true) e, per ogni i 0, in ogni stato che il processo pu raggiungere eseguendo una sequenza
di i azioni (come espresso dalla sottoformula [a]i <a> true, dal momento che a lunica
azione del nostro sistema).
Come altro esempio, consideriamo il processo CCS D , a.D + a.nil. D pu terminare
in qualsiasi momento o, equivalentemente, sempre possibile transire in uno stato in cui la

319

13.7 Propriet infinitarie: HML con ricorsione

formula [a]f alse vera. Chiamiamo questa propriet P os([a]f alse); potremmo esprimerla in
HML nel modo seguente:
P os([a]f alse) , [a]f alse _ <a> [a]f alse _ <a><a> [a]f alse _ . . .
1
_
=
<a>i [a]f alse
i=0

La formula pu essere interpretata cos: anch un processo abbia la capacit di rifiutare


unazione a in un qualche momento della sua esecuzione, tale azione devessere rifiutata subito
(come espresso dalla sottoformula [a]f alse) oppure devessere possibile eseguire una sequenza
di i azioni, per qualche i
0, e raggiungere uno stato in cui a possa essere rifiutata (come
espresso dalla sottoformula <a>i [a]true, dal momento che a lunica azione del nostro
sistema).
Il principale inconveniente delle formule infinitarie che non sono semplici da trattare.
Per esempio, esse sono infinitamente lunghe. In alternativa, potremmo estendere la logica modale introducendo la ricorsione. Cos facendo, le propriet temporali possono essere espresse
come soluzioni di certe formule ricorsive. Per dare significato alle formule ricorsive per di
fondamentale importanza il concetto di punto fisso che arriveremo a definire.
Con la ricorsione siamo ad esempio in grado di esprimere Inv(< a > true) tramite la
seguente equazione ricorsiva:
X <a> true ^ [a]X
(13.1)
dove la notazione ' '0 indica che gli insiemi di stati in cui ' e '0 sono vere coincidono.
In pratica, la relazione di soddisfazione |= permette di associare a ogni formula di HML
' e a ogni LTS S = hQ, A, !i linsieme di stati in Q in cui la formula vera, cio
[[']] , {q 2 Q | S, q |= '} .
Tale equazione introduce una caratterizzazione alternativa, di tipo denotazionale, della semantica di una formula HML (mentre finora il significato degli operatori delle logiche
stato descritto specificando quale devessere la struttura del modello anch soddisfi una
data formula). Essa definita sfruttando la relazione |=, ma possiamo definirla in maniera
indipendente, per induzione sulla sintassi delle formule HML, come mostrato di seguito.
[[true]] = Q
[['1 _ '2 ]] = [['1 ]] [ [['2 ]]
[[<> ']] =<> [[']]

[[']] = Q \ [[']]
[['1 ^ '2 ]] = [['1 ]] \ [['2 ]]
[[[]']] = [][[']]

dove abbiamo usato gli operatori <>, [] : 2Q ! 2Q definiti come


n
o

<> E = q 2 Q | 9q 0 2 Q : q ! q 0 e q 0 2 E

n
o

[]E = q 2 Q | 8q 0 2 Q : q ! q 0 si ha q 0 2 E

Quindi, formalmente, la notazione ' '0 indica che [[']] = [['0 ]].
naturale allora aspettarsi che un insieme E di stati che soddisfa la formula (13.1)
dovrebbe essere tale che
E <> Q \ []E

320

Capitolo 13 Logiche per i sistemi concorrenti

chiaro che E = ; una soluzione dellequazione; infatti, nessuno stato pu soddisfare


sia < a > true che [a]f alse. Cos facendo per lo stato corrispondente al processo C non
apparterrebbe a E, quindi questa non la soluzione che stiamo cercando. In eetti risulta
che in questo caso siamo interessati alla massima soluzione dellequazione, cio quella in cui
[[']] = {C} (mentre [[E]] = ; la minima).
In altri casi siamo invece interessati alla minima soluzione. Per esempio, possiamo
esprimere P os([a]f alse) con la seguente equazione ricorsiva:
Y [a]f alse _ <a> Y

(13.2)

In questo caso, sempre relativamente ai processi C e D, la massima soluzione [[Y ]]


{C, D, nil}; per tale soluzione non ci va bene perch C non pu terminare. La minima
soluzione invece [[Y ]] {D, nil} ed intuitivamente linsieme dei processi che soddisfano
P os([a]f alse). In eetti, abbiamo visto che la propriet P os([a]f alse) si pu esprimere come
una disgiunzione infinita; ci ricorda le costruzioni basate sui minimi estremi superiori delle
catene che vengono utilizzate per caratterizzare i minimi punti fissi delle funzioni continue.
Intuitivamente, prendiamo la massima soluzione per tutte quelle propriet di un processo
che valgono a meno che esso non abbia una computazione finita che falsifica la propriet. Ad
esempio, D non soddisfa la propriet Inv(<a> true) poich pu raggiungere uno stato che
non ha transizioni etichettate a. Al contrario, prendiamo la minima soluzione per tutte quelle
propriet di un processo che valgono se esso ha una computazione finita che prova la propriet.
Per esempio, un processo soddisfa la propriet P os(<a> true) se ha una computazione che
porta in uno stato che ha una transizione etichettata a; tale computazione prova il fatto
che il processo pu eseguire una transizione etichettata a in un qualche momento della sua
esecuzione.
Quindi quando scriviamo una propriet definita ricorsivamente vogliamo anche indicare
se siamo interessati alla minima o alla massima soluzione dellequazione. Per questo motivo
useremo una notazione dierente da quella vista finora; anzicch equazioni ricorsive useremo
formule parametriche e di volta in volta indicheremo se siamo interessati al minimo o al
massimo punto fisso della funzione corrispondente alla formula. Cosicch, relativamente agli
esempi visti, per esprimere la propriet Inv(<a> true) scriveremo la formula:
X.(<a> true ^ [a]X)
dove X. loperatore di massimo punto fisso, mentre per esprimere P os([a]f alse) useremo
la formula:
X.([a]f alse _ <a> X)

dove X. loperatore di minimo punto fisso.


Laggiunta di tali operatori ricorsivi (ciascuno esprimibile in termini dellaltro usando la
negazione logica) rende HML molto espressiva e capace di esprimere varie propriet di safety
e di liveness. Per esempio, anche possibile dire che una certa propriet '1 vale in ogni
computazione finch una certa propriet '2 diventa vera. Ci quanto un operatore di Until
permetterebbe di dire. In eetti possiamo esprimere due diverse interpretazioni:
Until forte: prima o poi durante una computazione dallo stato corrente si raggiunge uno
stato q in cui '2 vale ed in tutti gli stati che precedono q vale '1 :
X.('2 _ ('1 ^ < > true ^ [ ]X))

321

13.8 Il -calculus modale

Until debole: '1 vale in tutti gli stati di una computazione finch non si raggiunge uno
stato in cui vale '2 (ma ci potrebbe non succedere mai):
X.('2 _ ('1 ^ [ ]X))
Questi sono esempi di propriet temporali; quindi la logica che si ottiene in questo modo
temporale. Difatti HML con ricorsione ha un potere espressivo simile al -calculus modale (si
consulti [AILS07] per approfondimenti), il quale in grado di descrivere qualsiasi operatore
standard delle logiche temporali.

13.8

Il -calculus modale

Il -calculus modale [Koz83] si ottiene aggiungendo alla logica modale gli operatori di massimo
e minimo punto fisso, ovviamente insieme a variabili di punto fisso. Nella nostra presentazione
la logica modale di base ottenuta prendendo alcuni operatori di HML e di weak HML su un
insieme A [ { } di azioni. Lutilit degli operatori di minimo e massimo punto fisso deriva
dal fatto che molti concetti della logica temporale possono essere descritti come punti fissi
di certe funzioni su insiemi di stati dei modelli usati per le formule. Perci, nel -calculus
modale si possono esprimere anche propriet temporali. Ad esempio, stato dimostrato che
ogni formula di CTL , e quindi di CTL, ha una formula corrispondente nel -calculus.
La sintassi delle formule del -calculus modale definita dalla grammatica seguente:
' ::= true

'

' _ '0

<> '

'

Z.'

Una formula si dice ben-formata se ogni sottoformula della forma Z.' tale che la variabile
Z positiva (cio ogni occorrenza di Z compare sotto un numero pari di simboli di negazione)
in '. Tale restrizione garantisce la monotonia ed necessaria perch le formule non positive
possono dare luogo a funzioni insiemistiche senza punti fissi (ad esempio, la funzione negazione
F definita da F (X) = X non ha punti fissi nellinsieme potenza di un qualunque insieme
non vuoto). Una formula si dice chiusa se non contiene variabili libere, dove lunico operatore
legante Z..
Altri operatori ed abbreviazioni possono essere definiti come abbiamo gi fatto per HML
e weak HML.
Per definire la semantica delle formule chiuse e ben-formate conviene usare un approccio
basato sulla semantica denotazionale ed associare ad ogni formula ben-formata ' il sottoinsieme [[']] degli stati che soddisfano '. Le formule del -calculus sono interpretate sugli stati di
un generico LTS S = hQ, A [ { } , !i. Questa semantica, che pu essere definita al solito per
induzione sulla sintassi delle formule, in eetti non molto diversa da quella presentata per
HML con ricorsione nella sezione precedente. Tutti i casi sono semplici; lunica dicolt sta
nel definire la semantica di una formula ricorsiva del tipo Z.'. Nello specifico, una formula '
(che pu contenere una variabile Z) interpretata come una funzione [[']] : 2Q ! 2Q che, dato
un insieme E Q che si suppone soddisfi Z, restituisce linsieme degli stati che soddisfano '.
[[true]](E) = Q
[['1 _ '2 ]](E) = [['1 ]](E) [ [['2 ]](E)
[[<> ']](E) =<> [[']](E)
[[Z]](E) = E

[[']](E) = Q \ [[']](E)
[['1 ^ '2 ]](E) = [['1 ]](E) \ [['2 ]](E)
[[ ']](E)
T = [[']](E)
[[Z.']] = {E Q | [[']](E) E}

322

Capitolo 13 Logiche per i sistemi concorrenti

dove abbiamo usato gli operatori <>, : 2Q ! 2Q definiti come


n
o

<> E 0 = q 2 Q | 9q 0 2 Q : q ! q 0 e q 0 2 E 0
n
o

E 0 = q 2 Q | 9q 0 2 Q : q =
) q0 e q0 2 E 0

Vediamo ora se la definizione della semantica denotazionale ben posta. Innanzitutto,


osserviamo che si pu dimostrare che, per ogni formula ben-formata ', la funzione corrispondente [[']] : 2Q ! 2Q monotona nel cpo h2Q , i. Come detto prima, lidea sottostante la
definizione della funzione [[']] che se Z Q linsieme degli stati che soddisfano Z allora
linsieme degli stati che soddisfano '. Cos allora Z?
Sintatticamente assumeremo
[[']](Z)

che Z implicitamente dato da una equazione ricorsiva in Z della forma Z = '. Come
abbiamo visto nella sezione precedente, una tale equazione pu essere interpretata come une Ora, poich [[']] una funzione monotona su un cpo,
quazione su insiemi di stati Z = [[']](Z).
ha soluzione, cio ammette punti fissi. In particolare,
sappiamo che lequazione Z = [[']](Z)
il teorema del punto fisso ci dice che
1. [[']]
T ha minimo punto fisso dato dallintersezione dei punti pre-fissi:
{E Q | [[']](E) E};
2. [[']]
S ha massimo punto fisso dato dallunione dei punti post-fissi:
{E Q | E [[']](E)}.

La semantica di Z.', che per definizione il minimo punto fisso della funzione [[']], pertanto
ben definita.
La teoria del punto fisso dice inoltre che se la funzione associata a ' monotna, la
seguente una catena di approssimanti del minimo punto fisso:
'0 = f alse

'i+1 = '['i /Z].

Inoltre, in generale
lestremo superiore della catena strettamente minore del minimo
S1
S1 punto
fisso (cio, i=0 'i Z.'); ma se la funzione associata a ' continua si ha che i=0 'i =
Z.'. In pratica, ci vuol dire che la formula Z.' pu essere interpretata nel modo seguente
Z.' '0 _ '1 _ '2 _
Per dualit possiamo porre Z.' , Z.'[Z/Z]. Come conseguenza di questa definizione, si pu dimostrare che la semantica della formula Z.' il massimo punto fisso della
funzione corrispondente a ', cio
[
{E Q | E [[']](E)} .
La teoria del punto fisso dice inoltre che se la funzione associata a ' monotna, la seguente
una catena di approssimanti del massimo punto fisso:
'0 = true

'i+1 = '['i /Z].

Inoltre, in generale lestremo


inferiore della catena strettamente maggiore del massimo punto
T
i ); ma se la funzione associata a ' continua si ha che Z.' =
fisso (cio, Z.' 1
'
i=0

323

13.8 Il -calculus modale


T1

i=0 '

i.

seguente

In pratica, ci vuol dire che la formula Z.' pu essere interpretata nel modo
Z.' '0 ^ '1 ^ '2 ^

Si osservi infine che se Q finito, diciamo che formato da k elementi, ogni funzione
monotna continua ed inoltre ogni catena dopo al pi k elementi si stabilizza, cio diventa
costante. Di conseguenza, il k-esimo elemento di una catena di approssimanti coincide con il
punto fisso corrispondente.
Con gli operatori di minimo e massimo punto fisso si pu esprimere la capacit di svolgere
un comportamento nel futuro o di ripeterlo continuamente. In particolare, il costruttore di
minimo punto fisso utile per esprimere propriet di eventualit forte (prima o poi avviene
una data condizione), mentre quello di massimo punto fisso utile per esprimere propriet di
invarianza nel tempo (un certo comportamento si verifica in ogni stato indicato). Le formule
del -calculus possono diventare dicili da comprendere al crescere della loro lunghezza;
una euristica che pu aiutare a comprenderne il significato consiste nel vedere le formule
dinamicamente, come ricerche di stati con certe propriet svolte muovendosi lungo gli archi
del grafo delle transizioni che rappresenta il modello. Loperatore dice che la ricerca deve
terminare, mentre loperatore dice che la ricerca non deve necessariamente terminare.
Esempi di questa euristica sono i seguenti.
Z.(' _ < > Z) indica che la propriet ' vale inizialmente oppure dopo aver fatto
qualunque altra sequenza di azioni. In altri termini la formula dice che deve esistere uno
stato accessibile da quello iniziale che gode della propriet '. In pratica corrisponde
alla formula temporale EF'. Infatti, partendo dallo stato in cui la formula valutata,
iteriamo la seguente verifica: se il punto corrente verifica ', abbiamo finito; altrimenti,
selezioniamo una direzione (infatti, il diamond modale significa che si sceglie una direzione) e continuiamo la ricerca in quella direzione. Il allinizio della formula dice che
la ricerca deve terminare, e lunico modo per terminare la ricerca trovare uno stato
in cui ' vale. Notiamo che la formula esprime una propriet di liveness: qualcosa di
buono, prima o poi, accadr.
Z.(' ^ [ ]Z) indica che la propriet ' vale inizialmente e dopo aver fatto qualunque
altra sequenza di azioni. In altri termini la formula dice che tutti gli stati accessibili
godono della propriet '. In pratica corrisponde alla formula temporale AG'. Infatti,
partendo dallo stato in cui la formula valutata, iteriamo la seguente verifica: se lo
stato corrente verifica ', abbiamo un fallimento; altrimenti, continuiamo la ricerca in
tutte le direzioni (infatti il box modale significa prendere tutte le direzioni). Notiamo
che la formula precedente esprime una propriet di safety: se la negazione ' di '
una propriet indesiderata, abbiamo che qualcosa di indesiderato non accadr mai.
Vediamo alcuni altri esempi di formule del -calculus.
[[ ]] <> true significa che ogni volta che si esegue una sequenza di azioni si va in uno
stato dove possibile eseguire .
[[]] < > ( true ^ [, ]f alse) significa che in ogni cammino che comincia con un
-discendente, c poi la possibilit di eseguire unazione per arrivare in uno stato in
cui esiste un -discendente e non si possono eseguire le azioni e .

324

Capitolo 13 Logiche per i sistemi concorrenti


Z. <> Z esprime la capacit di eseguire lazione per sempre; quindi, se = ,
esprime la capacit di divergere.
Z.(<
> true ^ [ ]f alse ^ [ ]Z) significa che non possibile fare lazione
fintantoch si fanno azioni diverse da .
Saf ety(') = Z.(' ^ [ ]Z) significa che qualunque azione si faccia, si sempre in uno
stato nel quale non vale la condizione '.
Liveness(') = Z.(' _ (< > true ^ [ ]Z)) significa che c sempre la possibilit di
fare unazione e prima o poi arrivare in uno stato in cui vale '.

Combinando i minimi e i massimi punti fissi riusciamo anche a ottenere propriet di


fairness: ad esempio, la formula
Y.Z.('^ < > Y )_ < > Z
significa che esiste un cammino infinito ove ' occorre infinite volte, quindi corrisponde alla
formula temporale EGF'.
Si pu dimostrare che ogni formula della logica temporale CTL equivalente a una
formula del -calculus, mentre il contrario non vero. Ad esempio, la formula
Z.'^ < >< > Z
esprime il fatto che in qualche cammino una certa propriet ' vale in tutti gli stati in posizione
pari, propriet che, come abbiamo gi visto, non esprimibile nella logica temporale. Quindi
il -calculus modale strettamente pi espressivo di CTL .

Bibliografia

[AB84]

Didier Austry and Grard Boudol. Algbre de processus et synchronisation.


Theor. Comput. Sci., 30:91131, 1984.

[AILS07]

Luca Aceto, Anna Ingolfsdottir, Kim G. Larsen, and Jiri Srba. Reactive Systems:
Modelling, Specification and Verification. Cambridge University Press, 2007.

[Bar84]

Henk P. Barendregt. The Lambda Calculus: Its Syntax and Semantics. Studies
in Logic 103, second, revised edition, North-Holland, Amsterdam, 1984.

[Bar90]

Hendrik Pieter Barendregt. Functional programming and lambda calculus.


In Handbook of Theoretical Computer Science, Volume B: Formal Models and
Sematics (B), pages 321363. Elsevier and MIT Press, 1990.

[BB87]

Tommaso Bolognesi and Ed Brinksma. Introduction to the ISO Specification


Language LOTOS. Computer Networks, 14:2559, 1987.

[BHH+ 06] Bernhard Beckert, Tony Hoare, Reiner Hhnle, Douglas R. Smith, Cordell Green,
Silvio Ranise, Cesare Tinelli, Thomas Ball, and Sriram K. Rajamani. Intelligent
systems and formal methods in software engineering. IEEE Intelligent Systems,
21(6):7181, 2006.
[BHR84]

S. D. Brookes, C. A. R. Hoare, and A. W. Roscoe. A Theory of Communicating


Sequential Processes. J. ACM, 31(3):560599, June 1984.

[BK84a]

Jan A. Bergstra and Jan Willem Klop. The algebra of recursively defined processes
and the algebra of regular processes. In Jan Paredaens, editor, ICALP, volume
172 of Lecture Notes in Computer Science, pages 8294. Springer, 1984.

[BK84b]

Jan A. Bergstra and Jan Willem Klop. Process algebra for synchronous
communication. Information and Control, 60(1-3):109137, 1984.

[CE81]

Edmund M. Clarke and E. Allen Emerson. Design and synthesis of synchronization skeletons using branching-time temporal logic. In Dexter Kozen, editor,
Logic of Programs, volume 131 of Lecture Notes in Computer Science, pages 5271.
Springer, 1981.

[CGP99]

E. M. Clarke, O. Grumberg, and D. A. Peled. Model Checking. MIT Press, 1999.

326

Bibliografia

[Chu41]

Aalonso Church. The Theory of Lambda Conversion. Princeton University Press,


1941.

[DV90]

Rocco De Nicola and Frits Vaandrager. Action versus state based logics for transition systems. In Irene Guessarian, editor, Semantics of Systems of Concurrent
Processes, volume 469 of Lecture Notes in Computer Science, pages 407419.
Springer Berlin Heidelberg, 1990.

[Fok00]

W. Fokkink. Introduction to Process Algebra. Texts in Theoretical Computer


Science. An EATCS Series. Springer, 2000.

[Gor79]

Michael J.C. Gordon. The Denotational Description of Programming Languages.


Springer-Verlag, 1979.

[Hen88]

Matthew Hennessy. Algebraic theory of processes.


foundations of computing. MIT Press, 1988.

[HM85]

Matthew Hennessy and Robin Milner. Algebraic laws for nondeterminism and
concurrency. J. ACM, 32(1):137161, January 1985.

[Hoa78]

C. A. R. Hoare. Communicating sequential processes. Commun. ACM, 21(8):666


677, 1978.

[Hoa85]

C. A. R. Hoare. Communicating Sequential Processes.


Available at http://www.usingcsp.com/cspbook.pdf.

[HP85]

D. Harel and A. Pnueli. On the development of reactive systems. In K. R. Apt,


editor, Logics and Models of Concurrent Systems, NATO ASI Series, Vol. F-13,
pages 477498. Springer-Verlag, 1985.

[Koz83]

Dexter Kozen. Results on the propositional -calculus. Theoretical Computer


Science, 27(3):333 354, 1983.

[Mil80]

Robin Milner. A Calculus of Communicating Systems, volume 92 of Lecture Notes


in Computer Science. Springer, 1980.

[Mil89]

Robin Milner. Communication and Concurrency. PHI Series in computer science.


Prentice Hall, 1989.

[Pnu77]

Amir Pnueli. The temporal logic of programs. In FOCS, pages 4657. IEEE
Computer Society, 1977.

[Pri57]

Arthur Norman Prior. The Logic of Time and Modality. Oxford University Press,
1957.

[Sch86]

D.A. Schmidt. Denotational semantics: a methodology for language development.


Allyn and Bacon, 1986.

[Sch99]

Steve Schneider. Concurrent and Real Time Systems: the CSP approach. John
Wiley & Sons, Ltd., 1999. Available at http://www.computing.surrey.ac.uk/
personal/st/S.Schneider/books/CRTS.pdf.

MIT Press series in the

Prentice-Hall, 1985.

327
[Sco76]

Dana S. Scott. Data types as lattices. SIAM J. Comput., 5(3):522587, 1976.

[SM92]

Davide Sangiorgi and Robin Milner. The Problem of Weak Bisimulation up to.
In Rance Cleaveland, editor, CONCUR, volume 630 of Lecture Notes in Computer
Science, pages 3246. Springer, 1992.

[SW74]

Christopher Strachey and Christopher W. Wadsworth. Continuations: A Mathematical Semantics for Handling Full Jumps. Technical report, Tech.Monoghraph,
PRG-11, Oxford University, 1974.

[Win99]

Glynn Winskel. La Semantica Formale dei Linguaggi di Programmazione. MIT


Press, 1999.

[Win09]

Glynn Winskel. Topics in concurrency. Lecture Notes, 2009.

Appendice A

Tabelle

A.1
Op

Elenco degli operatori per la concorrenza


Uso

Significato

Regole

processo inattivo (nessuna regola)


(sinonimi: nil, o stop)

exit

exit

terminazione

Di base

(sinonimo: skip)

processo azione

chaos

chaos

chaos

exit ! stop

oppure

exit !

p
a

chaos ! stop

chaos ! chaos

Di sequenzializzazione
.

.E

azione prefissa

.E ! E

E; F

E ! E0
comp. sequenziale

o enabling
E; F ! E 0 ; F

( 6=

E ! E0

E; F ! F

[>

E [> F

disabling

E ! E0

E [> F ! E 0 [> F

( 6=

330

Appendice A Tabelle

F ! F0

E ! E0

E [> F ! F 0

E [> F ! E 0
Di scelta
+

E+F

scelta mista
o somma

scelta interna

E F

scelta esterna

E ! E0

F ! F0

E + F ! F0

E + F ! E0
F !E

F !F

E ! E0

E F ! E0

( 6= )

F ! F0

E F ! F0

( 6= )

E ! E0

F ! F0

E F ! E0 F

E F ! E F0

Di composizione parallela

E |F

comp. parallela

E ! E0

F ! F0

E | F ! E0 | F

E ! E0

E |F ! E |F0

F ! F0

E | F ! E0 | F 0

( 6= )

EkF

merge

E ! E0

E k F ! E0 k F

E ! E0

F ! F0

E k F ! E k F0

F ! F0

(, )

! E0 k F 0

EkF

ETF

|c

E |c F

|||

E ||| F

left merge

communication
merge

E ! E0

ETF ! E 0 k F

E ! E0 F ! F 0
E |c F

(, )

! E0 k F 0

interleaving

E ! E0

E ||| F ! E 0 ||| F

F ! F0

E ||| F ! E ||| F 0

331

A.1 Elenco degli operatori per la concorrenza

|[L]|

E |[L]| F

comp. parallela
con interfaccia

E ! E0

E |[L]| F ! E 0 |[L]| F

( 2
/ L)

F ! F0

E |[L]| F ! E |[L]| F 0

E ! E0

( 2
/ L)

F ! F0

E |[L]| F ! E 0 |[L]| F 0

( 2 L)

EF

prodotto

E ! E0 F ! F 0

! E0 F 0

EF

Di astrazione

E\L

restrizione

abilitazione

E ! E0

(,
2
/ L)

E\L ! E 0 \L

E ! E0
E

L ! E0

( 2 L _
2 L _ = )

H (E)

encapsulation

E ! E0

H (E)

H (E

( 62 H)

E/L

hiding

E ! E0

E/L ! E 0 /L

( 62 L)

E ! E0

E/L ! E 0 /L
[f ]

E[f ]

Rietichettatura
o relabelling

( 2 L)

E ! E0
E[f ]

f ()

! E 0 [f ]

Per comportamenti infiniti


A

A,P

costanti
di processo

E ! E0

A ! E0

(A , E)

rec x

rec x.E

ricorsione

E{rec x.E/x} ! E 0

rec x.E ! E 0

332

Appendice A Tabelle

replicazione

!E

E ! E0

E| ! E ! E 0

oppure

!E ! E 0 | !E

! E ! E0

Per manipolare valori


(x)

input

e.E

output

! E{v/x}

comunicazione
di valori

!E

(v)

! E0

(e espressione)

val(e)

e.E
E |F

! F0

E | F ! E0 | F 0

E ! E0

if e then E else F

(v valore)

(v)

(x).E

(v valore)

val(e) = true

if e then E else F ! E 0

F ! F0

val(e) = f alse

if e then E else F ! F 0

A.2

(e espressione)

(e espressione)

Alcuni calcoli di processi

CCS: Calculus of Communicating Processes (Milner 1980). Linsieme delle azioni


Act e costituito da un insieme di etichette , dallinsieme delle etichette soprasegnate e
dallazione speciale , la sintassi
E ::= nil

.E

E\L

E[f ]

E1 + E2

E1 |E2

recX.E

dove 2 Act , L , f : Act ! Act con la propriet che f (


) = f () e f ( ) = .
SCCS: Synchronous Calculus of Communicating Processes (Milner 1983). Linsieme delle azioni Act un gruppo abeliano costituito da un insieme di etichette , dallinsieme
delle etichette soprasegnate e dallelemento neutro 1, la sintassi
E ::= nil

:E

E1 + E2

E1 E2

recX.E

dove 2 Act, L , loperatore : denota laction prefixing. loperatore di rietichettatura


assente perch pu essere espresso per mezzo degli altri operatori.
TCSP: Theoretical Communicating Sequential Processes (Brookes-Hoare-Roscoe
1984). Linsieme delle azioni un insieme , la sintassi
E ::= stop

skip

E1 E2

a!E

E1 k E2

E\L

E[f ]

E1 ||| E2

E1 ; E2

E1 |[L]| E2

E1 u E2

333

A.2 Alcuni calcoli di processi

dove a 2 , L , f : ! , loperatore u denota la scelta interna, loperatore ! denota


laction prefixing e A una costante di processo.
ACP: Algebra of Communicating Processes (Bergstra-Klop 1984). Linsieme delle
azioni e costituito da un insieme finito di etichette e dallazione speciale , la sintassi
p
E ::=
a E\L E/L E[f ] E1 E2
E1 + E2
E1 k E2

E1 TE2

E1 | c E2

dove a 2 , L , f : ! , loperatore denota la composizione sequenziale e A una


costante di processo. Le notazioni originali degli operatori \L, /L e [f ] sono rispettivamente
L (), L () e f ().
LOTOS: Language of Temporal Order Specification (standard ISO 1988). Linsieme delle azioni i e costituito da un insieme finito di etichette e dallazione speciale i,
la sintassi
E ::= stop

exit

E1 + E2

; E
E1 k E2

E/L

E[f ]

E1 ||| E2

E1

E2

E1 |[L]| E2

E1 [> E2
A

dove 2 i , L , f : ! , loperatore ; denota laction prefixing, loperatore


la composizione sequenziale e A una costante di processo.

denota

You might also like