semantica di linguaggi di programmazione ne esistono differenti stili a seconda di paradigma di...

20
Semantica di linguaggi di programmazione istono differenti stili a seconda di paradigma di programmazione alidazione, prototyping, verifica di complessità... gusto personale dell’inventore vedremo due, già introdotti a LP Denotazionale Ogni termine del linguaggio denota un valore in un opportuno dominio Operazionale Ogni termine del linguaggio si semplifica fino ad un termine che rappresenta un valore Servono informazioni aggiuntive (contestuali) razione di una macchina Le informazioni contestuali sono rappresentate nel dominio, usando valori funzionali Buon supporto per interpretazioni di

Upload: grazia-quarta

Post on 01-May-2015

212 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Semantica di linguaggi di programmazione Ne esistono differenti stili a seconda di paradigma di programmazione uso (validazione, prototyping, verifica

Semantica di linguaggi di programmazioneNe esistono differenti stili a seconda di

paradigma di programmazioneuso (validazione, prototyping, verifica di complessità...)gusto personale dell’inventore

Ne vedremo due, già introdotti a LP

Denotazionale

Ogni termine del linguaggio denota un valore in un opportuno dominio

Operazionale

Ogni termine del linguaggio si semplifica fino ad un termine che rappresenta un valore

Servono informazioni aggiuntive (contestuali)

Astrazione di una macchina

Le informazioni contestuali sono rappresentate nel dominio, usando valori funzionaliBuon supporto per interpretazioni di logiche

Page 2: Semantica di linguaggi di programmazione Ne esistono differenti stili a seconda di paradigma di programmazione uso (validazione, prototyping, verifica

È logicamente sbagliato, cioè non fa quello che dovrebbe. Questo sarà l’argomento della parte di specifiche (Reggio + Zucca)

Dominio della semantica =?

Programma = termine su una qualche grammatica CF

(materiale propedeutico: dispense di LP, sezione 1 e appendici A, B,C)

Vogliamo eliminare i termini sbagliati non appena possibile• Per semplificare la definizione di semantica, fattorizzando i problemi

che si possono incontrare (=le motivazioni per cui un programma è sbagliato) ed affrontandoli separatamente

• Per facilitare la comprensione da parte dell’utente degli errori commessi, presentando le nozioni minime alla comprensione

Un programma può essere sbagliato a 3 livelliNon corrisponde alla sintassi descritta dalla grammatica (formalmente: non appartiene a L(G))

Non soddisfa i vincoli contestuali (formalmente la semantica statica dà errore)

La sua semantica non è definita (eg non terminazione) (formalmente la semantica dinamica non produce risultato accettabile)

4

Page 3: Semantica di linguaggi di programmazione Ne esistono differenti stili a seconda di paradigma di programmazione uso (validazione, prototyping, verifica

Percorso

Parser

Stringhe

Alberi(termini dell’algebra della sintassi astratta)

Semantica statica

Termini contestualmente corretti

Semantica

Valori

I problemi di ambiguità vengono risolti a questo livello

I problemi di nomi sconosciuti e tipaggio vengono risolti a questo livello

Page 4: Semantica di linguaggi di programmazione Ne esistono differenti stili a seconda di paradigma di programmazione uso (validazione, prototyping, verifica

Semantica staticaControlla sostanzialmente due cose: uso di identificatori (costanti, funzioni, metodi..) e tipaggio

Tipaggio

Con un insiemi di tipi finito e in assenza di identificatori (o con identificatori lessicalmente divisi per tipi) può essere catturato dalla grammatica. Ma non sono casi interessanti.

Identificatori

Presenti in tutti i linguaggi di alto livello, perché permettono di astrarre, semplificando anche l’esecuzione (su questo punto ci torneremo).Devono essere usati coerentemente dal punto di vista del tipo e della natura (con la loro dichiarazione/definizione, se c’è)

Impossibile in particolare catturarlo a livello della grammatica se il linguaggio permette la definizione di tipi da parte dell’utente

Page 5: Semantica di linguaggi di programmazione Ne esistono differenti stili a seconda di paradigma di programmazione uso (validazione, prototyping, verifica

ExpNum ::= …..ExpNum ::= Num | ExpNum + ExpNum | ExpNum ExpNum

Tutte le stringhe sono contestualmente corrette

Id ::= ….Dec ::= Id = ExpNum;Prog ::= Dec* eval ExpNum

| Id

Vincolo contestuale: una costante deve essere dichiarata prima di poter essere usata

Idea intuitiva: introduco la nozione di ambiente che mi memorizza le costanti dichiarate. All’inizio del programma l’ambiente è vuoto (non ho ancora esaminato nessuna dichiarazione)Ogni dichiarazione (corretta) amplia l’ambiente. Un’espressione è corretta se usa solo costanti già nell’ambiente.

Page 6: Semantica di linguaggi di programmazione Ne esistono differenti stili a seconda di paradigma di programmazione uso (validazione, prototyping, verifica

FormalizzazioneVoglio definire una funzione a valori booleani (che interpreterò come corretto/scorretto) sul linguaggio di tipo Prog [_]s

P:LProg(Exp)B

Per poterlo fare ho bisogno di funzioni ausiliarie che verificano la correttezza dei sottoprogrammi. Queste hanno bisogno di e/o costruiscono l’ambiente

[_]sE:LExpNum(Exp) EnvsB

[_]sD:LDec(Exp) Envs Envs

(Ci sarebbero anche funzioni per Num e Id ma sono sempre vere)

La informazioni da memorizzare nell’ambiente in questo caso così facile sono solo i nomi delle costanti già introdotte

Envs = Fin(LId(Exp) )

Page 7: Semantica di linguaggi di programmazione Ne esistono differenti stili a seconda di paradigma di programmazione uso (validazione, prototyping, verifica

Definizione delle funzioniLe funzioni di semantica statica si definiscono per (mutua) induzione.Le presentiamo in stile top-down (solo presentazione, perché stiamo dando un insieme di metaregole).

Un programma è corretto se la sua parte dichiarazioni costruisce un ambiente in cui è corretta l’espressione da valutare:

[dl eval e]sP = [e]s

E ( [dl]sD ) ()

Per valutare le dichiarazioni ho bisogno di un ambiente, all’inizio sarà quello vuoto

Per esattezza qui ci andrebbe la funzione sulle sequenze di dichiarazioni

Notazione equivalente:[dl]s

D() = [e]sE () = b

[dl eval e]sP = b

Page 8: Semantica di linguaggi di programmazione Ne esistono differenti stili a seconda di paradigma di programmazione uso (validazione, prototyping, verifica

DichiarazioniUna dichiarazione incrementa l’ambiente

[id = e]sD () = {id}

Questo va bene solo se l’espressione è corretta

Se [e]sE () = true, allora altrimenti

Non abbiamo previsto la possibilità che la valutazione delle dichiarazioni generasse un errore.Per tenerne conto aggiungiamo un elemento speciale agli ambienti statici.

Envs = Fin(LId(Exp) ) {err}

L’errore andrà, naturalmente propagato

[d]sD (err ) = err [e]s

E (err) = false

Esercizio proposto (facile) che cosa va modificato per impedire doppie dichiarazioni della stessa costante?

err

Page 9: Semantica di linguaggi di programmazione Ne esistono differenti stili a seconda di paradigma di programmazione uso (validazione, prototyping, verifica

EspressioniPer le espressioni abbiamo vari casi, seguiremo la struttura induttiva del linguaggio nel definire la semantica statica

I numeri sono sempre corretti[n]s

E () = true, se err e nLNum(Exp)

Somma e prodotto propagano correttezza ed errori[e + e’]s

E () = [e]sE () [e’]s

E () [e e’]s

E () = [e]sE () [e’]s

E ()

Una costante è corretta se e solo se è nota nell’ambiente[id]s

E () = id

Page 10: Semantica di linguaggi di programmazione Ne esistono differenti stili a seconda di paradigma di programmazione uso (validazione, prototyping, verifica

EsercizioVerificare che il seguente programma è staticamente corretto

X =7; Y=X+8; eval X+YCalcolo l’ambiente statico creato dalle dichiarazioni

[X =7; Y=X+8;]sD () = Per le regole sulle sequenze (che non abbiamo mai dato)

[Y=X+8;]sD ([X =7; ]s

D () ) =

[Y=X+8;]sD ({X})=

{X,Y}

Perché ([7]sE ()=true, essendo err

e 7 LNum(Exp)

Perché ([X+8]sE ({X})=

([X]sE ({X}) ([8]s

E ({X})= true trueEssendo X {X}

essendo {X}err e 8 LNum(Exp)

{X}

Valuto l’espressione nell’ambiente statico creato dalle dichiarazioni[X + Y]s

E ({X,Y})= ([X]sE ({X,Y}) ([Y]s

E ({X,Y}) = true true = true

Page 11: Semantica di linguaggi di programmazione Ne esistono differenti stili a seconda di paradigma di programmazione uso (validazione, prototyping, verifica

Esercizi PropostiVerificare che il seguente programma è staticamente correttoX =7 2; Z=X+X; X = 2; eval Z+X

Verificare che il seguente programma non è staticamente correttoX =2; Z=Y+X; eval Z

Page 12: Semantica di linguaggi di programmazione Ne esistono differenti stili a seconda di paradigma di programmazione uso (validazione, prototyping, verifica

Espressioni tipateChe cosa dobbiamo cambiare per gestire espressioni di vari tipi?

Idea intuitiva: dovremo tener conto del tipo delle espressioni per sapere quali operazioni sono lecite su di esse.

Vogliamo quindi che • Un ambiente statico corretto associ agli identificatori noti (che sono

un insieme finito) il loro tipo.• La semantica delle espressioni dia come risultato il tipo (o un errore)Formalmente

Envs = [LId(Exp) PTypes]Fin {err}

Funzioni parziali a dominio finito

Num ::= …..Bool ::= tt | ffExp ::= Id | Num | Bool | Exp + Exp | Exp Exp| Exp &Exp ….Non vale la pena di distinguere l’applicazione degli operatori a livello di grammatica, perché gli stessi problemi ci sono in ogni caso per via degli identificatori che possono avere il tipo che vogliono

[_]sE:LExp(Exp) Envs Types {err}

Types = {int, bool}

Page 13: Semantica di linguaggi di programmazione Ne esistono differenti stili a seconda di paradigma di programmazione uso (validazione, prototyping, verifica

Se [e]sE ()=t Types, allora [id = e]s

D () = [t/id], altrimenti err

Notazione per le funzioni parziali a dominio finito:[] funzione con dominio vuoto[a1/x1,…, an/xn] con tutte le xi distinte funzione f con dominio {x1,…,xn }

definita da f(xi)=(ai )[t/id] funzione con dominio dom() id} definita da [t/id](x)= (x)

se x id e [t/id](id)=t

I numeri sono sempre corretti[n]s

E () = int, se err e nLNum(Exp), altrimenti errIdem per le costanti booleane

[b]sE () = bool, se err e bLBool(Exp), altrimenti err

Somma e prodotto producono interi se applicati ad interi, errori altrimenti[e + e’]s

E () = int, se [e]sE () = int [e’]s

E () = int, err altrimenti Analogamente per gli operatori boleani

Una costante ha il tipo che risulta nell’ambiente oppure è ignota (err)[id]s

E () = (id) se id Dom(), err altrimenti

Page 14: Semantica di linguaggi di programmazione Ne esistono differenti stili a seconda di paradigma di programmazione uso (validazione, prototyping, verifica

Notazione equivalente

e : t________________________ t Types id = e [t/id]

___ Envs LDec(Exp) Envs {err} __:_ Envs LExp(Exp) Types {err}

e : err________________________

id = e err___________ err,nLNum(Exp) n:int

e:int e’:int__________________________

e + e’:int

_________________ id Dom(), id : (id)

______________

err e: err

e: err_________________

e + e’: err

e’: err_________________

e + e’: err

Spesso le regole per trattare gli errori si omettono, e analogamente nell’altro stile si definiscono funzioni parziali senza err nel codominio

__:_ Envs LExp(Exp) Types {err}[_]s

E: LExp(Exp) Envs Types {err}

Page 15: Semantica di linguaggi di programmazione Ne esistono differenti stili a seconda di paradigma di programmazione uso (validazione, prototyping, verifica

Ambienti localiChe cosa dobbiamo cambiare per gestire costrutti con ambienti locali?Exp ::= ….let dec* in Exp

Vogliamo che le costanti dichiarate localmente non siano più visibili dopo la fine del costrutto

ds ‘ ‘ e: t ______________________________

let ds in e: t

Questo si ottiene automaticamente, perché l’ambiente ‘ non compare nella conseguenza

Complicazione ulteriore: vogliamo permettere di ridichiarare nell’ambiente locale le costanti globali, ma non doppie dichiarazioni allo stesso livello.Idea intuitiva: in tutte le regole avremo un ambiente locale ed uno globale, da usare per tenere traccia degli identificatori globali ma non modificare.Problema: e nei casi tipo let d in let d’ in let d” in e ci basteranno due ambienti? Sì, perché analizzeremo i costrutti uno alla volta

Page 16: Semantica di linguaggi di programmazione Ne esistono differenti stili a seconda di paradigma di programmazione uso (validazione, prototyping, verifica

Due livelli di ambienteDove serve distinguere fra ambiente locale e globale?Solo al momento di decidere se una dichiarazione è lecita.Basta quindi cambiare[_]s

D:LDec(Exp) Envs Envs Envs

Ambiente globale usato ma non modificato

Se [e]sE (gl)=t Types, e id Dom(l), allora [id = e]s

D (g,l) = l[t/id], altrimenti err

Notazione ulteriore per le funzioni parziali a dominio finito:[l] funzione con dominio dom() dom(l) definita da

[l](x)= l(x) se xdom(l), e [l](x)= (x) altrimenti

[ds]sD () = l [e]s

E (l)=t __________________________________________

[let ds in e ]sE () = t

La dichiarazione locale copre (temporaneamente) quella globale, perché l’identificatore viene cercato prima nell’ambiente locale e solo se non lo si trova in quello globale

Page 17: Semantica di linguaggi di programmazione Ne esistono differenti stili a seconda di paradigma di programmazione uso (validazione, prototyping, verifica

Riassunto delle regole di dichiarazione[id = e;]s

D (l) = loc [ds]sD (loc) = 0

________________________________________________________________

[id = e;ds]sD (l) = 0

[e]sE (l)=t

_________________________________ id Dom(l) t Types[id = e;]s

D (l) = l[t/id]

[e]sE (l) = err

_________________________________

[id = e;]sD (l) = err

___________________________ id Dom(l)[id = e;]s

D (l) = err

Page 18: Semantica di linguaggi di programmazione Ne esistono differenti stili a seconda di paradigma di programmazione uso (validazione, prototyping, verifica

EsercizioIn quali ambienti statici è corretta la seguente espressione?let x=2; y=z+1; in let x=x+y; in x*y Partiamo con un generico ambiente 0 e vediamo quali restrizioni si deducono per avere la correttezza (intuitivamente: 0(z) = int).

[let x=2; y=z+1; in let x=x+y; in x*y ]sE (0) = t

__________________________________________________________________________________________________________

[x=2; y=z+1; ]sD (0) = l [let x=x+y; in x*y ]s

E (0l) = t _____________________________________________ ______________________________________________

T1T2

0err0(z) = int

l = [int/x,int/y ]

Page 19: Semantica di linguaggi di programmazione Ne esistono differenti stili a seconda di paradigma di programmazione uso (validazione, prototyping, verifica

[x=2; y=z+1; ]sD (0) = l

______________________________________________________________________________________________

[x=2;]sD (0) = [int/x] [y=z+1; ]s

D (0,[int/x]) = [int/x,t/y ]= l __________________________________ x =Dom([])___________________________________ y {x} =Dom([int/x]) [2]s

E (0) = int [z+1]sE (0int/x) = t

_______________________________ 0err ______________________________________________________ t=int [z]s

E (0int/x) = int [1]sE (0int/x) = int

____________________________ ____________________________

0int/x]](z) = int 0(z) = int ____________________________Perché 0int/x]](z) = 0(z),

essendo z x

Regole di correttezza dei numeri

Page 20: Semantica di linguaggi di programmazione Ne esistono differenti stili a seconda di paradigma di programmazione uso (validazione, prototyping, verifica

[let x=x+y; in x*y ]sE (0[int/x,int/y]) = t

_____________________________________________________________________________________________

[x=x+y;]sD (0[int/x,int/y])= t1/x] [x*y ]s

E (0[int/x,int/y]t1/x)=t ________________________________________________ x =Dom([]) ____________________________________________

[x+y]sE (0int/x,int/y) = t1 stesso albero di sinistra

___________________________________________ t1=int nello stesso ambiente, perché [x]s

E (0int/x,int/y) = int [y]sE (0int/x,int/y) = int 0[int/x,int/y]t1/x)=

__________________________________ ____________________________ 0[t1/x,int/y]0int/x,int/y(x)=int 0int/x,int/y(y)= int 0[int/x,int/y]__________________________________ ______________________________