Lezione 15. Verifica (II) [GJM91, Cap. 6] [BB87] [P93] Appunti

Slides:



Advertisements
Presentazioni simili
Definitezza Vogliamo poter richiedere la “definitezza” delle funzioni
Advertisements

Strutture dati per insiemi disgiunti
Ricorrenze Il metodo di sostituzione Il metodo iterativo
ECTS: la conversione dei voti Maria Sticchi Damiani Parte IV Conservatorio di Musica “N. Paganini” Genova, 2 maggio
Process synchronization
PROGRAMMARE IN PASCAL (le basi)
Generazione di Codice Intermedio
Linguaggi a memoria condivisa Lidea è di aggiungere ad un linguaggio imperativo dei costrutti per rappresentare lesecuzione parallela di statements. Supponiamo.
Algoritmi e Programmazione
Informatica Generale Marzia Buscemi
Generalità Linguaggio e Macchina Astratta
1 Il punto di vista Un sistema è una parte del mondo che una persona o un gruppo di persone, durante un certo intervallo di tempo, sceglie di considerare.
Lez. 21 Universita' di Ferrara Facolta' di Scienze Matematiche, Fisiche e Naturali Laurea Specialistica in Informatica Algoritmi Avanzati Semantica assiomatica.
INFORMATICA Strutture iterative
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.
Cammini minimi con sorgente singola
1 Defect testing Lobiettivo: scoprire difetti in un programma Un test ha successo se forza il programma a comportarsi in modo anomalo I test provano la.
Reaching Definitions. Tino CortesiTecniche di Analisi di Programmi 2 Reaching definitions Dato un punto del programma, quali sono i comandi di assegnamento.
Semantica Denotazionale
Semantiche dei linguaggi di programmazione
Capitolo 3 Strutture dati elementari Algoritmi e Strutture Dati Camil Demetrescu, Irene Finocchi, Giuseppe F. Italiano.
Camil Demetrescu, Irene Finocchi, Giuseppe F. ItalianoAlgoritmi e strutture dati Copyright © The McGraw - Hill Companies, srl 1 Usa la tecnica del.
Camil Demetrescu, Irene Finocchi, Giuseppe F. ItalianoAlgoritmi e strutture dati Copyright © The McGraw - Hill Companies, srl 1 Ordinamenti ottimi.
Capitolo 4 Ordinamento Algoritmi e Strutture Dati.
Capitolo 3 Strutture dati elementari Algoritmi e Strutture Dati.
Camil Demetrescu, Irene Finocchi, Giuseppe F. ItalianoAlgoritmi e strutture dati Copyright © The McGraw - Hill Companies, srl 1 Usa la tecnica del.
Algoritmi e Strutture Dati Capitolo 2 Modelli di calcolo e metodologie di analisi.
Iterazione enumerativa (for)
Intelligenza Artificiale 1 Gestione della conoscenza lezione 8
DIPARTIMENTO DI ELETTRONICA E INFORMAZIONE Puntatori Marco D. Santambrogio – Ver. aggiornata al 21 Marzo 2013.
Algebra di Boole ed elementi di logica
1 Capitolo 2: Semplificazione, Ottimizzazione e Implicazione.
1 Esempi di consistenza sui limiti Non consistente sui limiti, considera Z=2, poi X-3Y=10 Ma il dominio qui sotto e consistente sui limiti: Confrontare.
Algoritmo di Ford-Fulkerson
Capitolo 4 Ordinamento Algoritmi e Strutture Dati.
A.S.E.8.1 ARCHITETTURA DEI SISTEMI ELETTRONICI LEZIONE N° 8 ALGEBRA BOOLEANA PostulatiPostulati Principio di dualitàPrincipio di dualità Teoremi fondamentaliTeoremi.
Corso di Laurea in Biotecnologie Informatica (Programmazione)
1 Corso di Informatica (Programmazione) Lezione 10 (12 novembre 2008) Programmazione in Java: espressioni booleane e controllo del flusso (selezione)
Corso di Informatica (Programmazione)
Corso di Laurea in Biotecnologie Informatica (Programmazione)
eliana minicozzi linguaggi1a.a lezione2
Algoritmi e Strutture Dati (Mod. B)
Programmazione Un programma descrive al computer, in estremo dettaglio, la sequenza di passi necessari a svolgere un particolare compito L’attività di.
Il linguaggio Fortran 90: 4. Array: Vettori e Matrici
Introduzione alla programmazione lll
DAL PROBLEMA ALL'ALGORITMO Problemi e Programmi Paolo Amico
Fondamentidi Programmazione Corso: Fondamenti di Programmazione Classe: PARI-DISPARI Docente: Prof. Luisa Gargano Testo: Aho, Ulman, Foundations of Computer.
Heap binomiali Gli heap binomiali sono strutture dati su cui si possono eseguire efficientemente le operazioni: Make(H) : crea uno heap vuoto Insert(H,
Unità Didattica 1 Algoritmi
Strutture di controllo in C -- Flow Chart --
Fondamenti di Informatica Algoritmi
Analisi di Immagini e Dati Biologici
Intelligenza Artificiale - AA 2001/2002 Logica formale (Parte 2) - 1 Intelligenza Artificiale Breve introduzione alla logica classica (Parte 2) Marco Piastra.
CODIFICA Da flow-chart a C++.
Algoritmi e Strutture Dati
Capitolo 3 Strutture dati elementari Algoritmi e Strutture Dati Camil Demetrescu, Irene Finocchi, Giuseppe F. Italiano.
14 marzo 2002 Avvisi:.
ND-partizione (A) n   A  somma  0 M  1/2 (  a i ) for i  1 to n do S[i]  choice ({true, false}) if S[i] then somma  somma + a i if somma > M then.
Fondamenti di Programmazione
Il linguaggio Fortran 90: 3. Procedure e Funzioni
JavaScript Generalità Cos'è JavaScript?
4/5/20151 Metodi formali nello sviluppo software a.a.2013/2014 Prof. Anna Labella.
Algebra di Boole.
Lez. 9 (13/14)Elementi di Programmazione1 Lezione 9 Valutazione di espressioni File di testo sequenziali.
Allievi Elettrici - AA Le funzioni ricorsive in C
1 Tipi di Dato §descrittori, tipi, controllo e inferenza dei tipi §specifica (semantica) e implementazione di tipi di dato l implementazioni “sequenziali”
1 Fabio Scotti – Università degli Studi di Milano Fabio Scotti ( ) Laboratorio di programmazione per la sicurezza Valentina Ciriani ( )
13 ottobre Decisioni F. Bombi 13 ottobre 2002.
PRIMI ELEMENTI DI PROGRAMMAZIONE
Informatica e Informatica di Base
Transcript della presentazione:

Lezione 15. Verifica (II) [GJM91, Cap. 6] [BB87] [P93] Appunti 1. Verifica di equivalenze per algebre di processo 2. Dimostrazione di correttezza di programmi 3. Esecuzione simbolica [P93] V. R. Pratt, ‘Logics of Programs’, in A. Ralston, E. D. Reilly (Eds.) Encyclopedia of Computer Science, IEEE Press, 1993 -- pp. 791

1. Verifica di equivalenze per algebre di processo La natura algebrica di questi linguaggi offre maggior varietà di strumenti di analisi rispetto ai modelli a stati finiti manipolazione e trasformazione di espressioni algebriche mediante leggi algebriche e assiomatizzazioni di relazioni manipolazione diretta di Labelled Transition Systems derivati dalla semantica formale

Tipico problema di verifica per specifiche LOTOS: verifica di equivalenza osservazionale fra specifiche sintatticamente diverse. Esempio dall’architettura OSI: a b UpperService hide c, d in ((P[a, c] ||| P[b, d]) |[c, d]| LowerService[c, d])  UpperService[a, b] ? P Entity P Entity c d LowerService

Equivalenza osservazionale Un pianista (= osservatore) prova un tasto alla volta… … che risulta premibile o bloccato in base alla partitura precedentemente inserita Bechstain  Bluthner se nessun pianista cieco li può distinguere Bechstain Bluthner do do do mi sol mi sol La classica equivalenza fra automi (come riconoscitori di linguaggi) è inadeguata: la musica possibile sui due strumenti è la stessa: {-, do, do-mi, do-sol}… … ma i comportamenti rispetto a deadlock sono diversi: do-mi può fallire sul Bluthner, non sul Bechstain

Action sequence: --- (1 ... n ) ---> [k  Gates i] mi 2 4 do mi 1 6 8 i i 3 5 do sol 7 Action sequence: --- (1 ... n ) ---> [k  Gates i] (1)---(do, mi)--->(4) (1)---(i, do)--->(5) (1)------>(1) Observable action sequence: === (a1 ... an ) ==> [ak  Gates] (1)==(do, mi)==>(4) (1)==(do, mi)==>(8) (1)====>(1) (1)====>(3)

Una relazione R fra stati di un LTS è una weak bisumulation se:  (p, q) R,  s Gates*  p’ tale che p==s==>p’ ( q’ tale che q==s==>q’ /\ (p’, q’)  R) /\  q’ tale che q==s==>q’ ( p’ tale che p==s==>p’ /\ (p’, q’)  R) p e q sono observation equivalent (p  q) se  una weak bisimulation R tale che (p, q)  R

Due LTS equivalenti e la loro bisimulazione P Q Bisimulazione R a a a c b i b i c c P  Q

B1 observation congruent B2 (B1 c B2) se per ogni contesto C[ ]: L’equivalenza fra stati di LTS ne induce una fra espressioni di algebre di processo Una congruenza è una equivalenza preservata quando si rimpiazza una sotto-espressione con un’altra sotto-espressione equivalente. Formalmente: Un contesto, denotato ‘C[ ]’, è una espressione in cui una sotto-espressione è rimpiazzata da un ‘segna-posto’ (‘[ ]’) B1 observation congruent B2 (B1 c B2) se per ogni contesto C[ ]: C[B1]  C[B2] (che implica C[B1] c C[B2]…)

c Se c Allora

Leggi della congruenza osservazionale Per CCS o Basic LOTOS non è possibile fornire una assiomatizzazione di c [M84] Invece, per ‘finitary LOTOS’ (e, analog., f. CCS), comprendente solo action prefix, choice, stop l’assiomatizzazione è possibile, mediante il sistema completo e consistente di leggi [HM85]: (a1) B [] (C [] D) = (B [] C) [] D (a1) B [] C = C [] B (a3) B [] B = B (a4) B [] stop = B (a5) B [] i; B = i; B (a6)  (B [] i; C) =  (B [] C) [] ; C [M84] R. Milner, Lectures on a Calculus for Communicating Systems, in International Summer School ‘Control Flow and Data Flow: Concepts of Distributed Programming’, Munich, Germany, July 31-August 12, 1984. [HM85] M. Hennessy, R. Milner, ‘Algebraic Laws for Nondeterminism and Concurrency’, Journal of the ACM, Vol. 32, No. 1, Jan. 1985.

c c    a; i; B = a; (B [] i; B) [a5] = a; (B [] B) [] a; B [a6] Esercizio: Dimostrare la legge (a7): a; i; B = a; B a; i; B = a; (B [] i; B) [a5] = a; (B [] B) [] a; B [a6] = a; B [] a; B [a3] = a; B [a3]

Esercizio di verifica di equivalenza Max3[in1, in2, in3, out] := in1; (in2; in3; out; stop [] in3; in2; out; stop ) [] in2; (in1; in3; out; stop [] in3; in1; out; stop [] in3; (in1; in2; stop [] in2; in1; stop Max3-composto[in1, in2, in3, out] := hide mid in Max2[in1; in2; mid] |[mid]| Max2[in3; mid; out] where Max2[in1; in2; out] := in1; in2; out [] in2; in1; out in2 in3 in2 in3 in1 Max3 out mid in1 out Max2 Max2 Per verificare Max3  Max3-composto: 1. Costruire i due alberi T3 e T3-composto 2. Collassare 6 sottoalberi di T3-composto usando (a7) 3. Collassare 2 nuovi sottoalberi, usando (a5) 4. Collassare 2 nuovi sottoalberi, usando (a7), ottenendo T3.

2. Dimostrazione di correttezza di programmi La dimostrazione formale di correttezza di programmi si basa sull’utilizzo di una logica per esprimere proprietà dei programmi, e di assiomi e regole per dimostrarle. McCarthy (1963) modella i programmi come funzioni ricorsive (esempio: definizione di append(list1, list2)), e ne dimostra proprietà per induzione Floyd (1967) definisce una logica per programmi imperativi espressi come flowchart. Associa asserzioni logiche (tags) agli archi, che devono essere vere ogni volta che il controllo li attraversa. Un tagged flowchart è dimostrato corretto quando, individualmente, ogni componente è corretta rispetto ai suoi input/output tags. Hoare (1969) raffina la logica di Floyd, trattando programmi imperativi in forma algebrica

Specifica logica (di una proprietà) del programma P Pre e Post sono formule logiche del primo ordine, in cui le variabili di input/output appaiono libere {Pre (i1, i2, …, in) } P {Post (o1, o2, …, om, i1, i2, …, in) }

Esempi di specifica logica di programmi { z (i1 = z*i2)} P {o1 = i1 / i2} {i1 > i2} P {i1 = i2*o1 + o2 /\ o2 > 0 /\ o2 < i2} {true} P {(o= i1 \/ o = i2) /\ o > i1 /\ o > i2} {i1 > 0 /\ i2 > 0} P {( z1, z2 (i1 = o * z1 /\ i2 = o * z2)) /\  ( h ( z1, z2 (i1 = h * z1 /\ i2 = h * z2) /\ h > o))}

Esempio di verifica di programma - esposizione informale Programma e proprietà {true} Begin read (a); read (b); x := a + b; write (x) end {o = i1 + i2} Dimostrazione o = i1 + i2 vale dopo write(x) sse immediatamente prima vale x = i1 + i2. Ma l’assegnamento x := a+b scrive a+b in x, quindi x = i1 + i2 vale subito dopo l’assegn. sse a+b = i1+i2 vale subito prima. Poiché read(a) e read(b) danno ad a e b i valori dei due input i1 e i2, a+b = i1+i2 deve valere prima dell’assegnamento []

Le regole della logica di Hoare Applicabili a un linguaggio di programmazione con i costrutti: - x := exp (assegnamento) - begin a1; a2; …; an end - if p then a1 else a2 - while p do a {p}a1{q}, {q}a2{r} 3. ------------------------------------ {p}a1;a2{r} {p /\ r}a1{q}, {p /\ ¬r}a2{q} 4. ------------------------------------ {p} if r then a1 else a2 {q} p’  p, {p}a{q}, q  q’ 1. ------------------------------------ {p’}a{q’} 2. ------------------------------------ {p[exp/x]} x := exp {p(x)} {p /\ q}a{p} 5. ------------------------------------ {p} while q do a {p /\ ¬q} (NB: le graffe sono usate in modo inverso rispetto a [GJM91]

Esempio di verifica: fattoriale di y Programma: A: x:=1; B B: while y>0 do C C: x:=y*x; y:=y-1 i) y>0 /\ x*y!=n! x:=y*x y>0 /\ x*(y-1)!= n! first: y>0 /\ x*y! = n! ==> y>0 /\ (y*x)*(y-1)! = n! then: y>0 /\ (y*x)*(y-1)! = n! x:=y*x y>0 /\ x*(y-1)!= n! [rule 2, substituting x for y*x] ii) y>0 /\ x*(y-1)!= n! y:=y-1 y>0 /\ x*y!= n! first: y>0 /\ x*(y-1)! = n! ==> (y-1) > 0 /\ x*(y-1)! = n! then: (y-1) > 0 /\ x*(y-1)! = n! y:=y-1 y>0 /\ x*y!= n! [rule 2, substituting y for y-1] (iii) y>0 /\ x*y!=n! C y>0 /\ x*y!= n! [rule 3, with (i) and (ii)]

(Programma: A: x:=1; B B: while y>0 do C C: x:=y*x; y:=y-1) (iii) y>0 /\ x*y!=n! C y>0 /\ x*y!= n! (iv) y>0 /\ y=n /\ x=1 B x= n! y >0 /\ y=n /\ x=1 ==> p (let p = y >0 /\ x*y! = n!) Let q = y > 0 then: (iii) becomes: q /\ p C p which yields: p while q do C p /\ ¬q [by rule 5] that is p B p /\ ¬q p /\ ¬q = y >0 /\ x*y! = n! /\ y < 0 ==> y=0 /\ x=n! ==> x=n! In conclusion: y >0 /\ y=n /\ x=1 ==> p, p B p /\ ¬q, p /\ ¬q ==> x=n!, thus (iv) [by rule 1] (v) y>0 /\ y=n x := 1 y>0 /\ y=n /\ x=1 since p x := 1 p /\ x=1 [by rule 2] (vi) y>0 /\ y=n A x=n! [rule 3 to (v) and (iv)] []

3. Esecuzione simbolica Una tecnica a metà fra analisi di correttezza (statica) e testing (dinamica) Si consideri questo programma P, e il suo grafo control-flow annotato 1. x := y + 2; 2. if [x > a] then 3. a := a + 2; else 4. y := x + 3; endif; 5. x := x + a + y. 3 y := x + 3 4 1 x := y + 2 x:= x + a + y [x > a] 2 a := a + 2 Esecuzione simbolica: si associano valori iniziali simbolici alle variabili di programma (stato simbolico iniziale), poi...: init. 1. 2. 3. 4. 5. [Y+2<A] x X Y+2 2*Y+A+7 y Y Y+5 a A

[a = A, y = Y+5, x = 2*Y+A+7], stato simbolico finale (SSfin) L’esecuzione simbolica ha prodotto la tripla: [a = A, y = Y+5, x = 2*Y+A+7], stato simbolico finale (SSfin) (assegnamento di espressioni simboliche, contenenti variabili simboliche (maiuscole), alle variabili di P (minuscole). <1, 3, 4>, execution path cammino lungo il control flow graph di P [Y+2<A] path condition predicato sulle variabili simboliche che garantisce la eseguibilità del path L’altra tripla possibile è < [a = A+2, y = Y, x = 2*Y+A+4], <1, 2, 4>, [Y+2>A] > La corrispondenza biunivoca fra execution path e path condition cade per i linguaggi nondeterministici

Quando si incontra nel programma una condizione cond, come in input e output file sono trattati come sequenze (i1, i2,…) e (o1, o2, …) di var. di programma. Inizialmente: i1 = I1, i2 = I2, … o1 = nil, o2 = nil, … Il primo Read (x) viene interpretato come x := i1, dunque la sua esecuzione simbolica produce: x = ValSimb(i1) = I1 Il primo Write (E) viene interpretato come o1 := E, dunque la sua esecuzione simbolica produce: o1 = ValSimb(E) (in termini dello stato simbolico corrente) Quando si incontra nel programma una condizione cond, come in if cond then S1 else S2 endif while cond Loop … si considera ValSimb(cond): se il risultato è TRUE o FALSE indipendentemente dai valori delle variabili simboliche, si procede secondo il ramo corrispondente se no, si sceglie nondeterministicamente TRUE (risp. FALSE), e si aggiorna la path condition PC: PC := PC /\ ValSimb(cond) (resp. PC := PC /\ ¬ValSimb(cond) )

Verifica tramite esecuzione simbolica In generale, per ogni programma P si hanno molte, o infinite triple P programma inp = (inp1, ..., inpn) tupla di variabili in input per P I = (I1, ..., In) una corrispondente tupla di variabili simboliche out = (out1, ..., outn) tupla di variabili in output per P < Per verificare {Pre(inp)}P{Post(out)} con esecuzione simbolica: calcolare tutte le triple (SSFini, ExecPathi, PathCondi(I)). Per ogni i: usare sempre la stessa Path Condition iniziale: Pre(I) assumendo SSFini = (out1= Exp1i(I)), ..., (outn = Expni(I)) e definendo il predicato PEi come: PEi(I) = Post(Exp1i(I)/out1, ..., Expni(I)/outn) verificare che PathCondi(I) ==> PEi(I) (Trattazione semplificata, senza rappresentazione delle variabili interne di P.)

Backward symbolic execution (of protocols) [G. Holzmann, PSTV IV, 1985] E’ una variante di reachability analysis: dato uno stato finale indesiderabile Sx, calcola transizioni a ritroso fino, possibilmente, a S0 Il sistema distribuito -- un protocollo -- viene descritto con un linguaggio simile al CSP di Hoare: qname !mname output; appende mess. mname in coda a qname qname ?mname input; eseguibile se mess. mname è correntemente in cima a qname (con cancellazione) v1 := v2 assegnamento v1 è una var., v2 è una var. o una costante v++ incrementa di 1 la variabile v v-- decrementa di 1 la variabile v [v1 R v2] condizione, dove R è =, , , , <=, >=; eseguibile se i due operandi (var. o costanti) sono in relazione R I do loops (do…od), sono interrotti dal comando break. Skip è il comando vuoto. :: individua scelte non deterministiche

Esempio - Protocollo con memoria condivisa (M, N)

Due processi A e B condividono le code A (verso A) e B (verso B). Il processo A si rifornisce dalla coda TOB di messaggi che vorrebbe mandare al processo B attraverso la coda B. B si comporta simmetricamente. La variabile condivisa N è incrementata dal processo A quando un messaggio è appeso alla coda B, ed è decrementata dal processo B quando un messaggio viene cancellato. Simmetricamente, la variabile condivisa M è incrementata dal processo B quando un messaggio è appeso alla coda A (verso A), ed è decrementata dal processo A quando un messaggio viene cancellato. Il protocollo forza ciascun processo a ritardare il trasferimento di messaggi verso l’altro quando le code sono sature (2 messaggi)

Vogliamo verificare se dallo stato globale iniziale S1: N = 0, M = 0 TOB = (msg, msg), TOA = (msg, msg) A = ( ), B = ( ) ...si puo’ arrivare allo stato di deadlock S2: N = 2, M = 2 TOB = ( ), TOA = ( ) A = (msg, msg ), B = (msg, msg) Anziché esplorare tutti i cammini da S1 fino a trovare eventualmente S2, si puo’ partire da S2 e vedere se S1 è raggiungibile a ritroso. Inoltre, la esecuzione a ritroso (inversa) della specifica originale equivale a una esecuzione diretta della specifica inversa così costruita:

Scambiare send con receive (? con !) Scambiare incrementi con decrementi (++ con --) Invertire il flusso di controllo Scambiare condizioni con assegnamenti (= con :=) ma usando anche assegnamenti con range di valori (tipico della esecuzione simbolica): Condizione Assegnamento ------------------------------------------- [N > 5] ==> N := (>5) [N  2] ==> N := 2 La specifica originale del processo A è convertita in una tabella a stati, che viene invertita ed eseguita in maniera diretta, a partire dallo stato S2.

La specifica originale del processo A è convertita nella tabella a stati: La specifica inversa è rappresentata da questa tabella; la sottolineatura distingue i nuovi elementi dai vecchi

Effettivamente si scopre che, attraverso un doppio ciclo nel grafo degli stati globali, il deadlock è raggiungibile. La tecnica di esplorazione viene detta simbolica perché viene concettualmente esplorato il programma, visto come lista di statements lo stato è la posizione nel programma, ma puo’ essere parzialmente identificato anche da predicati sui valori di alcune variabili (come M ed N), che ne ‘sfuocano’ la rappresentazione. Sfortunatamente la esecuzione inversa non è sempre vantaggiosa rispetto a quella diretta [cfr. Holzmann 85] Un piu’ recente approccio alla interpretazione simbolica a ritroso, chiamato Compositional backward technique, è descritto in [Staunstrup+, IEEE Computer, Maggio 2000]