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

Slides:



Advertisements
Presentazioni simili
Introduzione al linguaggio C++
Advertisements

Traduzione ed Interpretazione
Definitezza Vogliamo poter richiedere la “definitezza” delle funzioni
23/11/06Dino Puller1 Analisi statica in tempo reale con domini numerici Facoltà di scienze MM.FF.NN. Università degli studi di Verona.
PHP.
Linguaggi di programmazione
Algebra parziale con predicati
Esercitazione guidata 1
Type Checking (1° parte)
SOS a piccoli passi Invece di semplificare sempre in configurazioni finali, fattorizziamo in passi più piccoli (da cui il nome). In questo modo la non.
Paradigma Funzionale Paradigma Imperativo: Programma = transizione di stato Paradigma Funzionale: Programma = valutazione di un’espressione La maggior.
Linguaggi a memoria condivisa Lidea è di aggiungere ad un linguaggio imperativo dei costrutti per rappresentare lesecuzione parallela di statements. Supponiamo.
Paradigma Funzionale Paradigma Imperativo: Programma = transizione di stato Paradigma Funzionale: Programma = valutazione di unespressione La maggior parte.
Algoritmi e Programmazione
1 Semantica Operazionale di un frammento di Java: lo stato.
Classi ed Oggetti in Java (Cenni). Richiami Ruolo delle Classi in Java Oggetti.
Liste di Interi Esercitazione. Liste Concatenate Tipo di dato utile per memorizzare sequenze di elementi di dimensioni variabile Definizione tipicamente.
Esercitazione Frame. Argomento Realizzazione di un tipo di dato astratto Usare le eccezioni per segnalare situazioni particolari Invariante e funzione.
Semantica Operazionale di un frammento di Java: lo stato
1 Astrazioni sui dati : Ragionare sui Tipi di Dato Astratti.
Lez. 41 Universita' di Ferrara Facolta' di Scienze Matematiche, Fisiche e Naturali Laurea Specialistica in Informatica Algoritmi Avanzati Programmazione.
1 Istruzioni, algoritmi, linguaggi. 2 Algoritmo per il calcolo delle radici reali di unequazione di 2 o grado Data lequazione ax 2 +bx+c=0, quali sono.
Il ragionamento classico
Semantica Denotazionale
Semantiche dei linguaggi di programmazione
Sistemi basati su conoscenza Conoscenza e ragionamento Prof. M.T. PAZIENZA a.a
Introduzione alla programmazione lll
Lezione 4: Costrutti Condizionali Prof. Raffaele Montella.
-calcolo Vogliamo studiare le problematiche relative al meccanismo di chiamata di funzione (eg differenze fra binding statico e dinamico) in isolamento.
Semantica denotazionale algebrica di LW Idea intuitiva: i valori che vogliamo denotare sono: gli statements sono funzioni di trasformazioni di stato (interno)
Semantica Operazionale Strutturata
nome: sequenza di caratteri usata per denotare un oggetto
mosaic manipola oggetti primitivi (ruota e unisci) regole:
INSIEMI NUMERABILI L’analisi matematica introduce il concetto di insieme numerabile come insieme i cui elementi possono essere “contati” ossia che possiede.
LINGUAGGI DI PROGRAMMAZIONE
Da Problema a Programmazione
4 Tipi di dati & variabili
1 Programmazione = decomposizione basata su astrazioni (con riferimento a Java)
Lo sviluppo del software e i linguaggi di programmazione
1 Astrazioni sui dati : Ragionare sui Tipi di Dato Astratti dispense prof. G. Levi.
BIOINFO3 - Lezione 211 INPUT La lettura di un input dallo standard input (tastiera) si effettua utilizzando lespressione. Quando il programma incontra.
Sintassi: Programma e classi Program::=prog {ClassDeclList {StatList}} ClassDeclList::=ClassDecl ClassDeclList |  ClassDecl::=class Ide c [StaticMetDefList]
1 Tecniche per il passaggio dei parametri. 2 Contenuti ¥la tecnica base (nei vari paradigmi) ¥ passaggio per costante, per riferimento, di funzioni, procedure.
Un interprete astratto per l’inferenza dei tipi
Algebra di Boole.
Introduzione a Javascript
La ricorsione.
Ereditarieta’. Contenuti Introduciamo un meccanismo fondamentale di Java: l’ereditarieta’ Permette di estendere classi gia’ definite (ovvero di definire.
Esercitazione su Vector. Permette di definire collezioni di dati generiche, che sono in grado di memorizzare elementi di ogni sottotipo di Object Definito.
Parte 3 Lo stato: variabili, espressioni ed assegnazioni
Il Linguaggio SQL. Le interrogazioni in SQL (continua…) La parte di SQL dedicata alla formulazione di interrogazioni fa parte del DML. SQL esprime le.
Didattica e Fondamenti degli Algoritmi e della Calcolabilità Terza giornata: principali classi di complessità computazionale dei problemi Guido Proietti.
1 Tipi di Dato §descrittori, tipi, controllo e inferenza dei tipi §specifica (semantica) e implementazione di tipi di dato l implementazioni “sequenziali”
13 ottobre Decisioni F. Bombi 13 ottobre 2002.
1 Interpretazione astratta: un approccio sistematico all’analisi statica.
Nucleo di Java: Struttura e Semantica Espressioni Assegnamento Controllo di sequenza Dichiarazioni.
Semantica dinamica Vogliamo definire una funzione che associ ad ogni termine corretto del mio linguaggio di programmazione un valore. Questa associazione.
Grammatiche Grammatiche libere da contesto Grammatiche regolari
public class volume { public static void main (String[] args) { final double bott_vol =2.0; final double latt_vol = 0.355; int bott_num = 4; int latt_num.
Elementi di semantica denotazionale ed operazionale
Sommario Oggetti immutabili e non Tipi Primitivi: String, Arrays.
1 Metodologie di Programmazione = decomposizione basata su astrazioni.
La codifica dei numeri.
Corso di Laurea Ingegneria Informatica Fondamenti di Informatica
Analisi matematica Introduzione ai limiti
Introduzione alla LOGICA MATEMATICA Corso di Matematica Discreta. Corso di laurea in Informatica. Prof. Luigi Borzacchini III. La logica delle proposizioni.
Parsing ricorsivo discendente Il parsing ricorsivo discendente (recursive descent parsing) è un metodo di tipo top-down che può essere facilmente codificato.
Basi di Java Strutture base di Java. Basi di java ▪Variabili ▪Operatori ▪Condizioni e Cicli ▪Array.
Logica Lezione 11, Annuncio Non si terrà la lezione di Lunedì 16 Marzo.
Esercitazione guidata 1
Transcript della presentazione:

Semantica di linguaggi di programmazione Ne esistono differenti stili a seconda di paradigma di programmazione uso (validazione, prototyping, verifica di complessità...) gusto personale dellinventore 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 funzionali Buon supporto per interpretazioni di logiche

È logicamente sbagliato, cioè non fa quello che dovrebbe. Questo sarà largomento 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 dellutente degli errori commessi, presentando le nozioni minime alla comprensione Un programma può essere sbagliato a 3 livelli Non 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

Percorso Parser Stringhe Alberi (termini dellalgebra 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

Semantica statica Controlla 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 lesecuzione (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 dellutente

Exp Num::=….. 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. Allinizio del programma lambiente è vuoto (non ho ancora esaminato nessuna dichiarazione) Ogni dichiarazione (corretta) amplia lambiente. Unespressione è corretta se usa solo costanti già nellambiente.

Formalizzazione Voglio definire una funzione a valori booleani (che interpreterò come corretto/scorretto) sul linguaggio di tipo Prog [_] s P :L Prog (Exp) B Per poterlo fare ho bisogno di funzioni ausiliarie che verificano la correttezza dei sottoprogrammi. Queste hanno bisogno di e/o costruiscono lambiente [_] s E :L ExpNum (Exp) Env s B [_] s D :L Dec (Exp) Env s Env s (Ci sarebbero anche funzioni per Num e Id ma sono sempre vere) La informazioni da memorizzare nellambiente in questo caso così facile sono solo i nomi delle costanti già introdotte Env s = Fin (L Id (Exp) )

Definizione delle funzioni Le 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 lespressione da valutare: [dl eval e] s P = [e] s E ( [dl] s D ) ( ) Per valutare le dichiarazioni ho bisogno di un ambiente, allinizio sarà quello vuoto Per esattezza qui ci andrebbe la funzione sulle sequenze di dichiarazioni Notazione equivalente: [dl] s D ( ) = [e] s E ( ) = b [dl eval e] s P = b

Dichiarazioni Una dichiarazione incrementa lambiente [id = e] s D ( ) = {id} Questo va bene solo se lespressione è corretta Se [e] s E ( ) = 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. Env s = Fin (L Id (Exp) ) {err} Lerrore andrà, naturalmente propagato [d] s D (err ) = err [e] s E (err) = false Esercizio proposto (facile) che cosa va modificato per impedire doppie dichiarazioni della stessa costante? err

Espressioni Per 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 n L Num (Exp) Somma e prodotto propagano correttezza ed errori [e + e] s E ( ) = [e] s E ( ) [e] s E ( ) [e e] s E ( ) = [e] s E ( ) [e] s E ( ) Una costante è corretta se e solo se è nota nellambiente [id] s E ( ) = id

Esercizio Verificare che il seguente programma è staticamente corretto X =7; Y=X+8; eval X+Y Calcolo lambiente statico creato dalle dichiarazioni [X =7; Y=X+8;] s D ( ) = Per le regole sulle sequenze ( che non abbiamo mai dato ) [Y=X+8;] s D ([X =7; ] s D ( ) ) = [Y=X+8;] s D ({X})= {X,Y} Perché ([7] s E ( )=true, essendo err e 7 L Num (Exp) Perché ([ X+8 ] s E ( {X} )= ([ X ] s E ( {X} ) ([ 8 ] s E ( {X} )= true true Essendo X {X} essendo {X} err e 8 L Num (Exp) {X} Valuto lespressione nellambiente statico creato dalle dichiarazioni [X + Y] s E ({X,Y} )= ([ X ] s E ( {X,Y} ) ([ Y ] s E ( {X,Y} ) = true true = true

Esercizi Proposti Verificare che il seguente programma è staticamente corretto X =7 2; Z=X+X; X = 2; eval Z+X Verificare che il seguente programma non è staticamente corretto X =2; Z=Y+X; eval Z

Espressioni tipate Che 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 Env s = [L Id (Exp) P Types] Fin {err} Funzioni parziali a dominio finito Num::=….. Bool ::=tt | ff Exp::= Id | Num | Bool | Exp + Exp | Exp Exp| Exp &Exp …. Non vale la pena di distinguere lapplicazione 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 [_] s E :L Exp (Exp) Env s Types {err} Types = {int, bool}

Se [e] s E ( )=t Types, allora [id = e] s D ( ) = [t/id], altrimenti err Notazione per le funzioni parziali a dominio finito: [] funzione con dominio vuoto [a 1 /x 1,…, a n /x n ] con tutte le x i distinte funzione f con dominio {x 1,…,x n } definita da f(x i )=(a i ) [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 n L Num (Exp), altrimenti err Idem per le costanti booleane [b] s E ( ) = bool, se err e b L Bool (Exp), altrimenti err Somma e prodotto producono interi se applicati ad interi, errori altrimenti [e + e] s E ( ) = int, se [e] s E ( ) = int [e] s E ( ) = int, err altrimenti Analogamente per gli operatori boleani Una costante ha il tipo che risulta nellambiente oppure è ignota (err) [id] s E ( ) = (id) se id Dom( ), err altrimenti

Notazione equivalente e : t ________________________ t Types id = e [t/id] _ _ _ Env s L Dec (Exp) Env s {err} _ _:_ Env s L Exp (Exp) Types {err} e : err ________________________ id = e err ___________ err,n L Num (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 nellaltro stile si definiscono funzioni parziali senza err nel codominio _ _:_ Env s L Exp (Exp) Types {err} [_] s E : L Exp (Exp) Env s Types {err}

Ambienti locali Che 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é lambiente non compare nella conseguenza Complicazione ulteriore: vogliamo permettere di ridichiarare nellambiente 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

Due livelli di ambiente Dove serve distinguere fra ambiente locale e globale? Solo al momento di decidere se una dichiarazione è lecita. Basta quindi cambiare [_] s D :L Dec (Exp) Env s Env s Env s Ambiente globale usato ma non modificato Se [e] s E ( g l )=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 x dom( l ), e [ l ](x)= (x) altrimenti [ds] s D ( ) = l [e] s E ( l )=t __________________________________________ [let ds in e ] s E ( ) = t La dichiarazione locale copre (temporaneamente) quella globale, perché lidentificatore viene cercato prima nellambiente locale e solo se non lo si trova in quello globale

Riassunto delle regole di dichiarazione [id = e;] s D ( l ) = loc [ds] s D ( loc ) = 0 ________________________________________________________________ [id = e;ds] s D ( l ) = 0 [e] s E ( l )=t _________________________________ id Dom( l ) t Types [id = e;] s D ( l ) = l [t/id] [e] s E ( l ) = err _________________________________ [id = e;] s D ( l ) = err ___________________________ id Dom( l ) [id = e;] s D ( l ) = err

Esercizio In 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 ] s E ( 0 ) = t __________________________________________________________________________________________________________ [x=2; y=z+1; ] s D ( 0 ) = l [let x=x+y; in x*y ] s E ( 0 l ) = t _____________________________________________ ______________________________________________ T1T1 T2T2 0 err 0 (z) = int l = [int/x,int/y ]

[x=2; y=z+1; ] s D ( 0 ) = l ______________________________________________________________________________________________ [x=2;] s D ( 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] s E ( 0 int/x ) = t _______________________________ 0 err ______________________________________________________ t=int [z] s E ( 0 int/x ) = int [1] s E ( 0 int/x ) = int ____________________________ ____________________________ 0 int/x]](z) = int 0 (z) = int ____________________________ Perché 0 int/x]](z) = 0 (z), essendo z x Regole di correttezza dei numeri

[let x=x+y; in x*y ] s E ( 0 [int/x,int/y] ) = t _____________________________________________________________________________________________ [x=x+y;] s D ( 0 [int/x,int/y] )= t 1 /x][x*y ] s E ( 0 [int/x,int/y] t 1 /x )=t ________________________________________________ x = Dom([]) ____________________________________________ [x+y] s E ( 0 int/x,int/y ) = t 1 stesso albero di sinistra ___________________________________________ t 1 =int nello stesso ambiente, perché [x] s E ( 0 int/x,int/y ) = int [y] s E ( 0 int/x,int/y ) = int 0 [int/x,int/y] t 1 /x )= __________________________________ ____________________________ 0 [t 1 /x,int/y] 0 int/x,int/y (x)=int 0 int/x,int/y (y) = int 0 [int/x,int/y] __________________________________ ______________________________