Semantica denotazionale algebrica di LW

Slides:



Advertisements
Presentazioni simili
Esercitazione guidata 1
Advertisements

Semantica di linguaggi di programmazione Ne esistono differenti stili a seconda di paradigma di programmazione uso (validazione, prototyping, verifica.
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.
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
Elementi di semantica denotazionale ed operazionale
Damb Il funzionamento interno e le idee che stanno dietro Damb dalla Traduzione del File in Istruzioni, alle Analisi e le Soluzioni 14/09/2004.
Le funzioni in C++. Introduzione  Spesso alcuni gruppi di operazioni vengono ripetute in diverse parti all’interno del medesimo programma  Si pensi.
Fondamenti di Informatica - D. Talia - UNICAL 1 Fondamenti di Informatica FONDAMENTI DI INFORMATICA Domenico Talia
1 Elementi DI INFORMATICA Università degli Studi di Cagliari Corso di Laurea in Ingegneria Elettronica Linguaggio C A.A. 2011/2012
Fondamenti di Informatica A - Massimo Bertozzi LE FUNZIONI.
.  I tipi di dati non primitivi sono gli array, le struct e le union.  Gli array sono degli aggregati di variabili dello stesso tipo.  La dichiarazione.
CONTROLLO DELLA CONCORRENZA
Ereditarietà Uno dei principi della programmazione orientata agli oggetti (OOP) è il riuso Le classi dovrebbero essere progettate come componenti riutilizzabili.
© 2007 SEI-Società Editrice Internazionale, Apogeo
Alcune note, dalla rete, sui Sistemi cellulari
rielaborato da Atzeni-etal., Basi di dati, Capitolo 4
I Circuiti Sequenziali ed i Flip/Flop
10. Programmazione Ricorsiva Ing. Simona Colucci
Cluster Analysis Definizione di Classificazione: operazione concettuale condotta adottando un solo criterio (detto fondamento della divisione) per individuare.
Universita’ di Milano Bicocca Corso di Basi di dati 1 in eLearning C
Commenti Ogni riga che comincia con il simbolo # non viene letta dall’interprete per cui rappresenta un modo per commentare il listato # Questo è un esempio.
Insiemi di punti: altre caratteristiche
Le postcondizioni specificano l’output della funzione.
Universita’ di Milano Bicocca Corso di Basi di dati 1 in eLearning C
Universita’ di Milano Bicocca Corso di Basi di dati 1 in eLearning C
I vincoli di integrità Alcuni aspetti della realtà NON possono essere modellati solamente con entità, attributi e relazioni, per esempio i vincoli di integrità.
Tipo di dato: array Un array è un tipo di dato usato per memorizzare una collezione di variabili dello stesso tipo. Per memorizzare una collezione di 7.
Informatica per l’Ingegneria
Rielaborato da Atzeni et al., Basi di Dati, Mc-Graw Hill
Programmazione e Laboratorio di Programmazione
IL CONCETTO DI ALGORITMO
Programmazione e Laboratorio di Programmazione
Programmare.
I numeri relativi DEFINIZIONE. Si dicono numeri relativi tutti i numeri interi, razionali e irrazionali dotati di segno (positivo o negativo). ESEMPI Numeri.
Esercitazioni di C++ 31 dicembre 2018 Claudio Rocchini IGMI.
Sommario cos’è un tipo di dato astratto astrazione tramite specifica:
Ricorsione 16/01/2019 package.
Introduzione agli Algoritmi e alle Strutture Dati
© 2007 SEI-Società Editrice Internazionale, Apogeo
Esercitazione su Instruction Level Parallelism
APPUNTI SUL LINGUAGGIO C
APPUNTI SUL LINGUAGGIO C
Corso di Laurea Ingegneria Informatica Fondamenti di Informatica
Process synchronization
Corso di Laurea Ingegneria Informatica Fondamenti di Informatica
APPUNTI SUL LINGUAGGIO C
Astrazione e Concretizzazione
Interpretazione Astratta
Semantica dinamica Vogliamo definire una funzione che associ ad ogni termine corretto del mio linguaggio di programmazione un valore. Questa associazione.
Le stringhe in C++ Laboratorio 26 Aprile Dott. Serena Villata
Concorrenza e parallelismo
APPUNTI SUL LINGUAGGIO C Allocazione dinamica della memoria
Processi decisionali e funzioni di controllo
Programmazione e Laboratorio di Programmazione
Corso di Algoritmi e Strutture Dati APPUNTI SUL LINGUAGGIO C
Programmazione e Laboratorio di Programmazione
Esercitazione guidata 1
Programmazione e Laboratorio di Programmazione
Unità 1 Programmi base.
Programmazione e Laboratorio di Programmazione
Analisi composizionale e contestuale
Unità D2 Dal problema all’algoritmo
Programmazione e Laboratorio di Programmazione
Array e Stringhe Linguaggio C.
Semantica operazionale:
Programmazione e Laboratorio di Programmazione
Transcript della presentazione:

Semantica denotazionale algebrica di LW Idea intuitiva: i valori che vogliamo “denotare” sono: gli statements sono funzioni di trasformazioni di stato (interno) espressioni etc. producono valori (di base) a partire dalle informazioni sui valori degli identificatori Dichiarazioni etc. determinano quali sono gli identificatori usabili nel seguito (e per le sole funzioni quali sono i rispettivi valori), cioè creano/modificano gli ambienti Quindi i carrier dell’algebra semantica dovranno essere qualche tipo di funzioni aventi come argomenti le informazioni sui valori degli identificatori Le informazioni sui valori degli identificatori sono di due tipi: Ci sono identificatori associati a variabili, il cui valore cambia nel tempo durante l’esecuzione dei programmi. Altri associati a funzioni, il cui valore è costante per tutta la durata dell’esecuzione.

Modello ambiente/stato Locazioni + Valori costanti Valori base Identificatori ambiente stato Locazioni: astrazione del concetto di cella di memoria, per semplicità sono tipate, in modo che le locazioni per il tipo T siano abbastanza “grandi” da contenere un valore di tipo T Valori costanti. Siccome nel nostro linguaggio ci sono dichiarazioni di variabili di tipo base e di costante di tipo funzionale, avremo nei valori costanti funzioni e nell’immagine dello stato solo valori di tipo intero e booleano Ci dovranno essere dei vincoli di coerenza, cioè locazioni di tipo T dovranno essere associate a valori di tipo T (il suo “contenuto”)

Ambiente Un ambiente associa ad un identificatore un “valore” che resta costante per tutta la durata dell’esecuzione. Per gli identificatori di funzione si tratta della funzione descritta dal body. Per le variabili si tratta della locazione. Env = [LId(LW) p  ]Fin Fun Loc Le locazioni sono tipate: Loc = TBTypes LocT Non ci interessa dettagliare come siano fatte le locazioni di un dato tipo, ma assumiamo di averne a disposizione un numero illimitato Fun = [Arg p Res] Arg = [Z| B]+  States Stato al momento della chiamata, da usare per valutare variabili globali Res = [Z| B|{*}]  States Stato modificato dalla chiamata void

Stato Uno stato rappresenta una fotografia della memoria del programma ad un dato istante dell’esecuzione. Quindi associa ad ogni locazione (=cella) un valore. Solo alle locazioni inizializzate (che sono un numero finito) è associato un valore States = [Loc p Value]Fin Value = TBTypes [T] [T] è l’insieme dei valori di tipo T: [int] = Z, [bool] = B Siccome le locazioni sono tipate, l’associazione deve rispettare i tipi: Per ogni stato s, lLocT e s(l) definito implica s(l) [T]. Alternativamente Loc e Value possono essere visti come famiglie Loc = {LocT}TBtypes, Value = {[T]}TBtypes, ed s: Loc p Value come una famiglia di funzioni {sT: LocT p [T]}TBtypes Nomenclatura. Dato uno stato s Dom(s). Il dominio di s consiste di tutte le locazioni “riservate”, cioè associate ad un identificatore (ad un qualche livello più o meno locale) DDef(s). Il dominio di definizione di s consiste di tutte le locazioni inizializzate. Quindi DDef(s)  Dom(s)

Locazioni “nuove” int x = 3; x int y; l void f(bool x; int z;) f ... Nel seguito ci servirà allocare delle locazioni distinte da tutte quelle in uso (per evitare aliasing e cancellazione di dati). Dati un ambiente r ed uno stato s, quali sono le locazioni in uso? Tutte le locazioni nell’immagine di r sono sicuramente in uso, ma non sono le sole. Infatti, se abbiamo una dichiarazione locale di x che copre una dichiarazione globale di variabile per x, la locazione l associata ad x nell’ambiente globale non compare nell’immagine dell’ambiente aggiornato (risulta coperta dal nuovo valore associato a x), ma non per questo si può riassegnare. int x = 3; int y; void f(bool x; int z;) {if (x) {y=1;} else {y=z;}} x y z f ... 3 l ... Però in un caso come questo, l appartiene anche al dominio dello stato (non necessariamente al dominio di definizione). Quindi, definiamo il predicato Nuova  Loc  Env  States come Nuova(l,r,s) sse l (Im(r)  Dom(s))

Funzione(/i) Semantica(/he) Come nel caso della semantica statica, la semantica è una famiglia di funzioni indiciata sui non terminali (un omomorfismo) Dovremmo quindi definire ciascuna funzione. Definiremo solo quelle per tipi, liste di dichiarazioni, di statements, di espressioni e quella per il programma. Le altre si desumono da queste, perché il loro dominio è incluso in uno dei precedenti. Per i tipi l’abbiamo già vista (manca la regola [void]RType = {*} ) [_]RType:LRType(LW)  Set Le dichiarazioni modificano l’ambiente. [_]Decs:LDecs(LW)  Env  States  Env  States Lo stato serve (e può venir modificato) a causa delle dichiarazioni con inizializzazione, oltre che per individuare le locazioni libere. Gli statements modificano lo stato. [_]Stats:L Stats(LW)  Env  States  States Le espressioni producono un valore e(d eventualmente) modificano lo stato (side-effects). [_]Exps:L Exps(LW)  Env  States  Value+  States Nelseguito tralasceremo gli indici

Definizione delle funzioni semantiche Definiamo le funzioni semantiche per (mutua) ricorsione Possiamo indifferentemente usare la notazione “in linea” F(exp) = …. F(exp’)…. Oppure quella a regole F(exp) = ….A…. F(exp’) = A Vediamo quale è più conveniente. Ad esempio consideriamo il caso della concatenazione di dichiarazioni. L’idea intuitiva è di valutare la prima dichiarazione e usare il risultato come punto di partenza (= argomento) per valutare le restanti dichiarazioni: Notazione “in linea”: [d ds]Decs(r,s) = [ds]Decs([d]Decs(r,s)) [d ds]Decs(r,s) = (r”,s”) [d]Decs(r,s) = (r’,s’) [ds]Decs(r’,s’) = (r”,s”) Notazione a regole: Risulta più leggibile quella a regole. Quindi useremo questa.

Espressioni [e es] (r,s) = (v lv,s”) [e] (r,s) = (v,s’) Exps ::= Exp Exps [e es] (r,s) = (v lv,s”) [e] (r,s) = (v,s’) [es] (r,s’) = (lv,s”) Exp ::= Id Il risultato è il valore della variabile (se inizializzata) r(x) Loc [x](r,s) = (s(r(x)),s) Questo formalizza anche l’intuizione che leggere il valore di una cella non altera la memoria Exp ::= Id = Exp [e](r,s) = (v ,s’) [x = e](r,s) = (v,s’[v/r(x)]) Exp ::= Id(Exps) [es](r,s) = (lv ,s’) Scarichiamo le funzione base sull’interpretazione dei tipi base nell’algebra semantica Questa è una funzione per via della correttezza statica [f(es)](r,s) = r(f)(lv,s’) Exp ::= Exp + Exp [e + e’] (r,s) = (a,s”) [e] (r,s) = (v,s’) [e’] (r,s’) = (v’,s”) v + v’ = a

Esercizio Valutare la semantica della seguente espressione in ambiente r e stato s, assumendone la correttezza statica x = f(3,x) + 2 u1 + 2 s1 u1 + 2 [x = f(3,x)+2](r,s) = (v,s’[v/r(x)]) s1 [f(3,x)+2](r,s) = (v ,s’) 2 v= u1 + u2 2 s1 3 s(r(x)) s [f(3,x)](r,s) = (u1 ,s1) [2](r,s1) = (u2 ,s’) r(f)(lv, s’1)= (u1 ,s1) u2 = 2 s’= s1 3 s(r(x)) s [3,x](r,s) = (lv ,s’1) 3 s(r(x)) lv = v1 v2 3 s s s(r(x)) s s [3](r,s) = (v1 ,s”1) [x](r, s”1) = (v2 ,s’1) v1 = 3 s”1=s v2 = s”1(r(x)) s’1 = s”1 s Concludendo [x = f(3,x)+2](r,s) = (u1 + 2, s1[u1 + 2 /r(x)]) dove (u1 ,s1) = r(f)(3 s(r(x)), s) Convenzione: usiamo questa font per indicare valori ed operazioni nell’algebra semantica

Dichiarazioni di variabili Decs ::= Dec Decs [d ds] (r,s) = (r”,s”) [d] (r,s) = (r’,s’) [ds] (r’,s’) = (r”,s”) Dec ::= Type Id L’effetto deve essere di associare alla variabile una nuova locazione non inizializzata Nuova(l,r,s) [t x](r,s) = (r[l/x],s[/l]) Convenzione: Dom(s[/l])= Dom(s) {l} s[/l](y)= s(y) se yDDef(s) DDef(s[/l])= DDef(s) (opzionale) Dec ::= Type Id = Exp; [e](r,s) = (v ,s’) Nuova(l,r,s’) [t x = e](r,s) = (r[l/x],s’[v/l])

Dichiarazioni di funzioni 1 Consideriamo il caso più semplice possibile: procedurale, senza ricorsione e con un solo parametro. [void f(T x) {sts}] L’idea è: usare il parametro x per estendere ambiente (parametro formale) e lo stato al momento della chiamata (parametro attuale) e valutarvi il corpo ottenendo una funzione da associare a f nell’ambiente Lo stato non viene modificato. La locazione per il parametro viene allocata al momento di ogni chiamata [void f(T x) {sts}] (r, s) = (r[F/f],s) Parametro attuale Stato al momento della chiamata Stato prodotto dalla chiamata Dove F : [T]  States  {*}  States è definita da Maschero f, caso mai ci fosse nell’ambiente. Per il momento è inutile, perché sappiamo che f non è ricorsiva [sts] (r[/f,l/x],sc[v/l]) = s’ Nuova(l,r,sc) F(v,sc) = (*,s’) l è nuova rispetto al momento della chiamata

Dichiarazioni di funzioni ricorsive Si parte come nel caso non ricorsivo [void f(T x) {sts}](r,s) = (r[F/f],s) Dove F : [T]  States  {*}  States Il problema è la definizione di F: F(v,sc) = (*,s’) [sts] (r[/f,l/x],sc[v/l]) = s’ non so come fare le chiamate ricorsive perché f non compare in r[/f] Cambiamo approccio. F è definita induttivamente da tutte le regole della semantica più le seguenti due: Caso base: riesco a valutare il corpo(come nel caso non ricorsivo) Regola ad hoc per la chiamata di f F(v,sc) = (*,s’) [sts] (r[/f,l/x],sc[v/l]) = s’ [e](r[/f],s0) = (u ,s’) F(u,s’) = (*,s”) Nuova(l,r,sc) [f(e)] (r[/f],s0) = (*,s”)

Dichiarazioni di funzioni ricorsive 2 Cosa cambia nel caso in cui il tipo di ritorno non è void? [RT f(T x) {sts result e}](r,s) = (r[F/f],s) Dove F : [T]  States  [RT]  States La definizione di F si fa analogamente al caso void F è definita induttivamente da tutte le regole della semantica più le seguenti due: Caso base: riesco a valutare il corpo(come nel caso non ricorsivo) [sts] (r[/f,l/x],sc[v/l]) = s’ [e](r[/f,l/x], s’)= (a ,s”) Nuova(l,r,sc) F(v,sc) = (a,s”) Regola ad hoc per la chiamata di f [e](r[/f],s0) = (u ,s’) F(u,s’) = (a ,s”) [f(e)] (r[/f],s0) = (a ,s”)

Statements [if (e) {sts} else {sts’}](r,s) = s” Stats ::= Stat Stats Stat ::= Exp; Vogliamo considerare solo i side-effects della valutazione di un’espressione [st] (r,s) = s’ [sts] (r,s’) = s” [st sts ] (r,s) = s” [e](r,s) = (v ,s’) [e;](r,s) = s’ Stat ::= if (Exp) {Stats} else {Stats} Scelta condizionale usuale [if (e) {sts} else {sts’}](r,s) = s” [e](r,s) = (tt ,s’) [sts] (r,s’) = s” [if (e) {sts} else {sts’}](r,s) = s” [e](r,s) = (ff ,s’) [sts’] (r,s’) = s” [e](r,s) = (ff ,s’) Stat ::= while (Exp) {Stats} [while (e) {sts}](r,s) = s’ [while (e) {sts}](r,s”) = s0 [e](r,s) = (tt ,s’) [sts] (r,s’) = s” [while (e) {sts}](r,s) = s0

(i,o,m)[v/l]=(i,o,m[v/l]) Input e Output Finora abbiamo considerato solo programmi che modificano lo stato interno. Vogliamo permettere anche operazioni di input e output. Anzitutto bisogna introdurre i costrutti opportuni Stat ::= ... ?(Id) | !(Exp) Poi dovremo dare le ovvie regole di semantica statica (per esercizio) Ultimo problema: la semantica. Bisogna aggiungere allo stato le componenti per l’interazione col mondo esterno: States = Input  Output  [Loc p Value]Fin stato (vecchio) interno Nel nostro caso si leggono valori da assegnare alle variabili e si scrivono valori (valutazioni delle espressioni), quindi Input = Output = Value* Perché le regole vecchie abbiano senso bisogna estendere la notazione s[v/l] ai nuovi stati (i,o,m)[v/l]=(i,o,m[v/l]) [!(e)](r,s) =(i, v•o,m) [e](r,s) = (v,(i,o,m)) [?(x)](r,(v• i,o,m)) =(i,o,m[v/r(x)])