Verification of object-oriented programs with invariants by M. Barnett, R. DeLine, M. Fähndrich, K.R.M. Leino, W. Schulte Bordignon Claudio Zampieron Elisa.

Slides:



Advertisements
Presentazioni simili
Programmazione ad oggetti
Advertisements

Informatica Recupero debito quarto anno Terzo incontro.
Informatica 2 Lezione 4 Corso di laurea in matematica Informatica 2 Dott. Ing. Leonardo Vito Corso di laurea matematica indirizzo matematica per le applicazioni.
Type Checking (1° parte)
Algoritmi e Programmazione
Differenze nei vari linguaggi di Elisa Trifirò e Barbara Tacchino
1 Astrazioni sui dati : Specifica ed Implementazione di Tipi di Dato Astratti in Java.
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.
MultiSet, Liste Ordinate
Le gerarchie di tipi.
Esercitazione Frame. Argomento Realizzazione di un tipo di dato astratto Usare le eccezioni per segnalare situazioni particolari Invariante e funzione.
1 Le gerarchie di tipi: implementazioni multiple e principio di sostituzione.
1 Astrazioni sui dati : Ragionare sui Tipi di Dato Astratti.
LIP: 1 Marzo 2005 Classe Object e Vettori. Partiamo da Lesercizio dellultima esercitazione realizzato tramite array Vedremo come si puo fare in modo piu.
Paola Spinazzé, Luca Leonardi, Linguaggio di specifica Permette di descrivere analiticamente proprietà di codice Java Descrizione di pre.
1 Programmazione ad oggetti in Java E.Mumolo, DEEI
1 Corso di Laurea in Biotecnologie Informatica (Programmazione) Introduzione a JAVA Anno Accademico 2009/2010.
Testing e Debugging.
Specifiche senza JML: uso delle asserzioni. 2 Asserzioni in Java Dal jdk 1.4 (da Febbraio 2002) cè meccanismo per gestire asserzioni Asserzione: espressione.
1 Le gerarchie di tipi. 2 Supertipi e sottotipi 4 un supertipo –class –interface 4 può avere più sottotipi –un sottotipo extends il supertipo ( class.
nome: sequenza di caratteri usata per denotare un oggetto
Type int_stack = struct { int top; int P[100]; } int_stack creapila() { int_stack s = new int_stack; s.top = 0; return s; } int_stack push(int_stack s,
Type int_stack = struct { int top; int P[100]; } int_stack creapila() { int_stack s = new int_stack; s.top = 0; return s; } int_stack push(int_stack s,
Eccezioni.
Le classi Definizione di classe Attributi e metodi di una classe Costruttori e distruttori Private e public Funzioni friend Il puntatore this.
Java base IV: Java e la programmazione O.O.
Componenti A.Natali Marzo Oggetti u Un oggetto possiede stato, funzionamento e identita'. u Struttura e funzionamento di oggetti simili sono.
AN FI Un denominatoe comune Comandi u notazioni che esprimono azioni che, una volta eseguite, comportano una modifica permanente dello stato interno.
FUNZIONI: IL MODELLO APPLICATIVO 1) Valutazione, nellenvironment corrente, del simbolo che denota il nome della funzione; 2) Valutazione, nellenvironment.
AN FI Un denominatoe comune Lo stile funzionale Concetti fondamentali.
IL TEMA DELLA RIUSABILITÀ Si vuole riusare tutto ciò che può essere riusato (componenti, codice, astrazioni) Non è utile né opportuno modificare codice.
Ereditarietà e Polimorfismo
Introduzione alla programmazione Object Oriented
1 Astrazioni sui dati : Ragionare sui Tipi di Dato Astratti dispense prof. G. Levi.
Astrazione procedurale ed eccezioni
1 Un esempio con iteratore: le liste ordinate di interi.
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.
Fondamenti di Informatica II Ingegneria Informatica (A-I) Prof. M.T. PAZIENZA a.a – 3° ciclo.
Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 7 Tipi di dato e strutture dati Specifica e realizzazione di strutture informative come classi.
1 Tipi di Dato §descrittori, tipi, controllo e inferenza dei tipi §specifica (semantica) e implementazione di tipi di dato l implementazioni “sequenziali”
Fondamenti di informatica Oggetti e Java Luca Cabibbo Luca Cabibbo – Fondamenti di informatica: Oggetti e Java Copyright © 2004 – The McGraw-Hill Companies.
1 Astrazione sul controllo: gli iteratori. 2 Perché vogliamo iterarare “in modo astratto” 4 problema: iterare su tipi di dato arbitrari  esempio: procedura.
Liste di Interi Esercitazione. Una variante Liste concatenate di Integers Non modificabile Costruttori per creare la lista vuota o un nodo Metodi d’istanza.
1 Progettazione dettagliata di un Tipo di Dato Astratto: l’ambiente di metodi.
Ripasso su Java. Introduzione Per risolvere problemi complessi, i linguaggi di programmazione forniscono costrutti per realizzare nuove funzioni che trasformino.
Liste di Interi Esercitazione. IntList Lista di interi Una lista è una disposizione ordinata di elementi ( non in modo crescente-descrescente, ma per.
1 Astrazione sul controllo: gli iteratori. 2 Gli iteratori 4 perché vogliamo iterarare “in modo astratto” 4 iteratori e generatori in Java –specifica.
1 Progettare un Tipo di Dato Astratto. 2 Scelte di Progetto (astrazione) 4 Caratteristiche degli oggetti –Modificabilità 4 Scelta delle operazioni –Realizzare.
1 Astrazioni sui dati : Ragionare sui Tipi di Dato Astratti.
1 Un esempio: le liste ordinate di interi. 2 Liste ordinate  OrderedIntList 4 lista ordinata di interi –modificabile.
1 Semantica Operazionale di un frammento di Java: le regole di transizione estensione (con piccole varianti) di quella in Barbuti, Mancarella, Turini,
Ese 3 (del 3 Aprile 2003). Testo Progettare la specifica e l’implementazione del tipo di dato astratto modificabile Stack, supponendo che gli elementi.
Metodologie di Programmazione Esercizi sulla semantica di Java.
1 Le gerarchie di tipi: implementazioni multiple e principio di sostituzione.
1 Le s-espressioni. 2  Sexpr 4 alberi binari (possibilmente “vuoti”) che hanno sulle foglie atomi (stringhe) 4 sono la struttura dati base del linguaggio.
PolyFun. Dare implementazione,funzione di astrazione, invarianti della rappresentazione. Provare che i metodi apply e bind preservano gli invarianti.
LIP: 2 Maggio 2008 Classi Astratte. Cos’e’ una Classe Astratta una classe astratta e’ un particolare tipo di classe permette di fornire una implementazione.
Sommario Oggetti immutabili e non Tipi Primitivi: String, Arrays.
Esercitazione. Problema Vogliamo definire in modo gerachico un tipo di dato che definisce Tabelle multi-dimensionali con un numero di righe variabili.
Progettare una classe 21 Febbraio La classe BankAccount Vogliamo realizzare una classe i cui oggetti sono dei semplici conti bancari. * Identifichiamo.
LIP: 11 Maggio 2007 Classi Astratte. Cos’e’ una Classe Astratta una classe astratta e’ un particolare tipo di classe permette di fornire una implementazione.
1 Semantica Operazionale di un frammento di Java: intro estensione (con piccole varianti) di quella di FP | v |
1 Un esempio con iteratore: le liste ordinate di interi.
LIP: 4 Maggio 2007 Interfacce. Cos’e’ una Interfaccia una interfaccia e’ un particolare tipo di classe contiene solo la specifica non ha implementazione.
LIP: 18 Aprile 2008 Interfacce. Rappresentazione Lista val next vuota Lista vuota: any true Lista non vuota: any true 154 false 24 false.
Ex.1 - Astrazioni su Dati Si abbia il tipo di dato stack di interi, IntStack, specificato sotto: public class IntStack { \\ OVERVIEW: uno Stack è una collezione.
Corso di Algoritmi e Strutture Dati con Laboratorio Richiami di Java – parte II.
Transcript della presentazione:

Verification of object-oriented programs with invariants by M. Barnett, R. DeLine, M. Fähndrich, K.R.M. Leino, W. Schulte Bordignon Claudio Zampieron Elisa

Introduzione Scopo: fornire una metodologia di programmazione che sfrutta gli invarianti La metodologia utilizza il design-by-contract determina in quale stato un oggetto può essere modificato; permette lobject-composition e il subclassing; estesa per permette il multithreading;

Introduzione: Design-By-Contract Il Design By Contract (DBC) è una metodologia inventato da Betrand Meyer e integrata in Eiffel Consiste nel considerare un'interfaccia (insieme dei metodi esposti da una classe) come un contratto fra chi la invoca (client) e chi la implementa (classe) Vengono quindi definiti i termini del contratto utilizzando 4 elementi: Pre-condizioni: i requisiti minimi che devono essere soddisfatti dal cliente affinché il metodo possa andare a buon fine Post-condizioni: i requisiti per cui lesecuzione del metodo si può ritenere corretta e che il metodo si impegna quindi a rispettare Clausule di modifica: una lista dei campi della classe che vengono modificati dallimplementazione del metodo Invarianti: condizioni che devono essere sempre valide.

I termini del contratto Le pre e post-condizioni riguardano quindi un metodo: le pre-condizioni vincolano il chiamante le post-condizioni vincolano il metodo Gli invarianti sono invece un vincolo a livello dellintera classe: devono valere prima che una qualunque invocazione di metodo avvenga e alla fine dellesecuzione del metodo stesso possono non essere validi temporaneamente durante lesecuzione di un metodo

Esempio class SquareRootable feature value: Real; sqrt is require value >= 0; do value :=....; ensure value >= 0; value <= old value; end; invariant value >= 0; end ; Pre-condizione: un'espressione boolean valutata prima del codice di un metodo; è introdotta a mezzo della parola chiave require e può comporsi di una o più espressioni boolean separate da ; Post-condizione: un'espressione boolean valutata al termine di un metodo; è introdotta a mezzo della parola chiave ensure Invariante di classe: è una condizione che, ogni volta che viene valutata, deve valere true; è introdotta a mezzo della parola chiave invariant

Invarianti… Spesso vengono usati come sostitutivi di pre e post-condizioni: Quindi non sono necessarie pre e post-condizioni ? class C{ private int x, y; invariant 0 x < y; public C(){ x = 0; y = 1; } public void M() modifies x, y { assert y – x 0; x = x + 3; y = 4 * y; } Linvariante è soddisfatto prima dellincremento di x Stato delloggetto CONSISTENTE Linvariante potrebbe non valere Stato delloggetto INCONSISTENTE Linvariante è ristabilito dopo lassegnamento di y Torniamo ad uno stato CONSISTENTE

E se il metodo invoca P()? class C{ private int x, y; invariant 0 x < y; public C(){ x = 0; y = 1; } public void M() modifies x, y { assert y – x 0; x = x + 3; P(); y = 4 * y; } public P() { /*…*/; M(); } } Si assume che linvariante sia soddisfatta allentrata del metodo Qui linvariante potrebbe non valere temporaneamente Linvariante deve essere valida alluscita dal metodo Cosa succede se P() esegue una chiamata ricorsiva? Linvariante deve essere soddisfatta alluscita del costrutture Linvariante è qui ripristinata

Specifichiamo i dettagli del contratto class C{ private int x, y; invariant 0 x < y; public C() ensures 0 x < y; { x = 0; y = 1; } public M() requires 0 x < y; modifies x, y ensures 0 x < y { assert y – x 0; x = x + 3; P(); Y = 4 * y; } public P() { /*…*/ M(); } Il metodo P() invoca M(), quindi deve garantire le precondizioni. Esprimere linvariante come pre e post condizione viola linformation-hiding La metodologia quindi dovrà: specificare SE LINVARIANTE E SODDISFATTO RISPETTARE LINFORMATION HIDING

Validità dellinvariante 1/2 Introduciamo un campo speciale st:{Invalid, Valid} compare solo nelle pre e post-condizioni; non può essere modificato nel corpo dei metodi ma solo dai comandi pack e unpack; Definiamo il predicato Inv T (o) loggetto o di tipo T soddisfa gli invarianti della classe T Vogliamo che, in ogni punto del programma, valga: ( o : T | o.st = Invalid Inv T (o))

Validità dellinvariante 2/2 o.st = Invalid loggetto o è invalido linvariante potrebbe non essere soddisfatto i campi delloggetto possono essere modificati un oggetto viene allocato inizialmente nello stato invalid o.st = Valid loggetto o è valido linvariante è soddisfatto loggetto non è modificabile pack o assert o null assert o.st = Invalid; assert Inv T (o); o.st := Valid; unpack o assert o null assert o.st = Valid; o.st := Invalid;

Esempio class C{ private int x, y; invariant 0 x < y; public C() ensures st = Valid; { x = 0; y = 1; pack this; } public M() requires st = Valid; modifies x, y; { assert y – x 0; unpack this ; x = x + 3; Y = 4 * y; pack this; } Alluscita dal costruttore loggetto deve essere valido, questo è garantito dal comando pack La pre-condizione indica che loggetto deve essere valido a tempo di invocazione. Il comando pack mi garantisce la validità in uscita

Estensione object-composition Problema linvariante potrebbe dipendere dai componenti quindi laggiornamento dei campi può portare a invalidità information hiding Introduciamo un modificatore rep Nuovo range {Valid, Invalid, Committed} per st Ridefiniamo le operazioni pack e unpack Istanziamo nuovi oggetti con stato invalid

Object-composition: Pack / Unpack pack controlla linvariante e imposta il campo st dei componenti allo stato committed e varia o.st allo stato di valid unpack modifica il campo o.st delloggetto e delle sue componenti rispettivamente allo stato invalid e valid pack o assert o null assert o.st = Invalid; assert Inv T (o); foreach p є Comp T (o) { assert(p = null p.st = Valid)}; foreach p є Comp T (o) { if(p null) p.st := Committed}; o.st := Valid; unpack o assert o null assert o.st = Valid; o.st := Invalid; foreach p є Comp T (o) { if(p null) {p.st := Valid}};

Object-composition Se T ha due campi rep, per esempio, x e y e o è di tipo T, allora: Vogliamo che, in ogni punto del programma, valga: ( o : T | o.st = Invalid Inv T (o) ( p є Comp T (o) p = null p.st = Committed)) pack o assert o null o.st = Invalid; assert Inv T (o); assert (o.x = null o.x.st = Valid) (o.y = null o.y.st = Valid); if(o.x null) { o.x.st := Committed }; if(o.y null) { o.y.st := Committed }; o.st := Valid;

Esempio 1/3 class C { method m0(k) requires k.st=Valid … { unpack k ; k.d.m1() ; k.s.m2() ; pack k; } class E { method m2(s) requires s.st=Valid … s d C k E D Valid Committed

Esempio 2/3 class C { method m0(k) requires k.st=Valid … { unpack k ; k.d.m1() ; k.s.m2() ; pack k; } class E { method m2(s) requires s.st=Valid … s d C k E D Invalid Valid Committed

Esempio 3/3 class C { method m0(k) requires k.st=Valid … { unpack k ; k.d.m1() ; k.s.m2() ; pack k; } class E { method m2(s) requires s.st=Valid … s d C k E D Valid Committed

Estensione per Subclasses 1/2 I campi sono ereditati dai vari class frames Ciascun frame contiene nuovi campi Loggetto può essere valid/invalid per ciascun class frame Object U Y T K W Dato un oggetto o:W o puo essere invalido per K e W Loggetto o puo essere valido per T Se o è valido per T non puo essere invalido per Y!!!

Estensione per Subclasses 2/2 Ridefiniamo st con due campi speciali inv (lultima classe per la quale sono soddisfatti gli invarianti) committed (boolean: indica se loggetto è committed; true se inv = tipo dinamico delloggetto) Ridefiniamo i comandi pack e unpack: pack o as T assert o null o.inv = Superclasse(T); assert Inv T (o); foreach p є Comp T (o){assert(p = null p.inv = type(p) p.committed)} foreach p є Comp T (o) { if(p != null) p.committed := true}; o.inv := T; unpack o from T assert o null o.inv = T o.committed; o.inv := Superclasse(T); foreach p є Comp T (o) { if(p != null) p.committed := false};

Esempio Class Frames class C extends B y:Y invariant u, v, x, y class B extends A x:X invariant u, v, x class A extends object u:U, v:V invariant u, v object Il tipo dinamico C ha 4 class frames Aggiorniamo il campo c.y: /* inv == C */ unpack c from B /* inv == B */ c.y = 5; pack this as C /* inv == C */ pack o as C controlla linvariante per ciascun componente p, setta p.committed = true setta o.inv = C unpack o from C setta o.inv = B per ciascun componente p, setta p.commited = false

Correttezza La correttezza della metodologia è dimostrata dalle seguenti condizioni che valgono in tutto il programma 1. ( o,T o.committed o.inv = type(o) ) 2. ( o,T o.inv <: T Inv T (o) ) 3. ( o,T o.inv <: T ) ( p Comp T (o) p = null p.committed )) 4. ( o,T, o,T, q ( p Comp T (o), p Comp T (o) o.inv <: T o.inv <: T q.committed p = p = q o = o T = T )) Dimostriamo che questi 4 condizioni sono mantenute da ogni comandi che possono modificare i valori dei campi Costruttore Comando pack Comando unpack Aggiornamento dei campi

Correttezza del costruttore (1) ( o,T o.committed o.inv = type(o) )(2) ( o,T o.inv <: T Inv T (o) ) (3) ( o,T o.inv <: T ) ( p Comp T (o) p = null p.committed )) (4) ( o,T, o,T, q ( p Comp T (o), p Comp T (o) o.inv <: T o.inv <: T q.committed p = p = q o = o T = T )) La (1) è soddisfatta perché per definizione il costruttore setta il campo committed a false per ogni nuovo oggetto allocato Il costruttore setta o.inv a object e questo dimostra la (2) La (3) e la (4) sono verificate in quanto il tipo object non ha rep-fields

Correttezza del comando pack pack o as T assert o null o.inv = Superclasse(T); assert Inv T (o); foreach p є Comp T (o){assert(p = null p.inv = type(p) p.committed)} foreach p є Comp T (o) { if(p != null) p.committed := true}; o.inv := T; Ogni componente (in cui modifichiamo lo stato) è valida quindi viene soddisfatta la (1) (1) ( o,T o.committed o.inv = type(o) ) Sia T<:S. lasserzione precedente alla verifica degli invarianti garantisce che portando o.inv da T a S venga soddisfatta la (2) (2) ( o,T o.inv <: S Inv S (o) ) Porre allo stato committed solo gli oggetti non nulli soddisfa la (3) (3) ( o,T o.inv <: T ) ( p Comp T (o) p = null p.committed )) (4) ( o,T, o,T, q ( p Comp T (o), p Comp T (o) o.inv <: T o.inv <: T q.committed p = p = q o = o T = T )) Possiamo dimostrare che pack rispetta la (4) analizzando i due casi q.committed è false la premessa è falsa => implicazione vera se la premessa è verificata, per come è definito il comando pack o e o sono lo stesso oggetto

Correttezza del comando unpack La (1) è soddisfatta perché il comando cambia solo il valore di oggetti non committed La (2) è soddisfatta perché il comando indebolisce il predicato La (3) è soddisfatta perché il foreach modifica solo le componenti di p e lassegnamento a o.inv antecedente il ciclo falsifica le premesse del predicato => limplicazione è vera (1) ( o,T o.committed o.inv = type(o) )(2) ( o,T o.inv <: T Inv T (o) )(3) ( o,T o.inv <: T ) ( p Comp T (o) p = null p.committed )) (4) ( o,T, o,T, q ( p Comp T (o), p Comp T (o) o.inv <: T o.inv <: T q.committed p = p = q o = o T = T )) unpack o from T assert o null o.inv = T o.committed; o.inv := Superclasse(T); foreach p є Comp T (o) { if(p != null) p.committed := false}; La (4) è soddisfatta perché il comando indebolisce il predicato

Correttezza nellaggiornamento dei campi I comandi di aggiornamento non possono modificare i valori di inv e committed, questo mantiene la (1) Le precondizioni per laggiornamento dei campi (dato x:T implica che (x.inv <: T) ) fanno fallire le premesse di (2) (3) e (4), per la semantica dellimplicazione quindi queste sono verificate (1) ( o,T o.committed o.inv = type(o) ) (2) ( o,T o.inv <: T Inv T (o) ) (3) ( o,T o.inv <: T ) ( p Comp T (o) p = null p.committed )) (4) ( o,T, o,T, q ( p Comp T (o), p Comp T (o) o.inv <: T o.inv <: T q.committed p = p = q o = o T = T ))

Estensione per il Multithreaded Lo scopo è sviluppare una tecnica per la verifica della consistenza degli oggetti su un programma OO multithreaded. Formalizziamo lo stato consistente di un oggetto attraverso luso degli invarianti. In un linguaggio Multithreaded linterleaving può causare la violazione degli invarianti e quindi inconsistenza.

Esempio class Account { int balance; } Account act = …; int b0 = act.balance; act.balance += 50; int b1 = act.balance; Linterleavings tra due tread concorrenti possono portare violazioni dellinvariante Non è garantito che b1 == b Introduce Mutua esclusione Aggregate objects Object invariants

Mutua esclusione In ciascun oggetto, si introduce un campo owner che può essere Null se loggetto o non è componente di nessun altro oggetto Object se loggetto o è una componente Thread se loggetto o è posseduto da un thread Prima che il thread t acceda al campo o.f, si controlla che o.owner == t Quando il thread t crea un oggetto o, setta o.owner = t; Il campo owner può essere modificato solo dai comandi: acquire o; attende finchè o.owner == null e poi setta o.owner = t; release o; controlla che o.owner == t e poi setta o.owner = null;

Esempio class Account { int balance; } Account act = new Account(); act.balance = 5; release act; … acquire act; act.balance++; release act;

Aggregate objects Gli aggregate objects vengono trattati come se fossero una unica entità Manteniamo modificatore rep Un thread può modificare un aggregate object tramite comando unpack Il comando pack trasferisce le proprietà ritornandole allaggregate object Introduciamo in ciascun oggetto un campo boolean inv che indica quando loggetto è stato modificato il campo inv è settato dal comando pack e ripristinato dal comando unpack finchè !inv, i modificatori rep sono vuoti

Aggregate objects [[ o = new C; ]] o = new C; o.owner = t; o.inv = false; [[ x = o.f; ]] assert o.owner == t; x = o.f; [[ o.f = x; ]] assert o.owner == t; assert !o.inv; o.f = x; [[ acquire o; ]] lock (o) { while (o.owner != null) Monitor.Wait(o); o.owner = t; } [[ release o; ]] assert o.owner == t; assert o.inv; lock (o) { o.owner = null; Monitor.Pulse(o); //(*) }

Aggregate objects [[ pack o; ]] assert o.owner == t; assert !o.inv; for each rep field o.f: if (o.f != null) { assert o.f.owner == t; assert o.f.inv; } for each rep field o.f: if (o.f != null) o.f.owner = o; o.inv = true; [[ unpack o; ]] assert o.owner == t; assert o.inv; for each rep field o.f: if (o.f != null) o.f.owner = t; o.inv = false;

il thread t crea loggetto o modificato dal thread t Ciclo di vita di un oggetto o.Owned = thread o è mutable o.Owned = thread o è consistente o.Owned = null o è free e consistente o.Owned = object o è consistente e sigillato thread t esegue pack o acquire dal tread t release dal thread t thread t esegue unpack o thread t esegue unpack owner p thread t esegue pack object p e p.f = o e f è un campo rep

Esempio 1/7 Thread 1 class Agg { rep Rep f; } class Rep {} Agg a = new Agg; Rep r = new Rep; pack r; a.f = r; pack a; release a;

Esempio 2/7 Thread 1 a class Agg { rep Rep f; } class Rep {} Agg a = new Agg; Rep r = new Rep; pack r; a.f = r; pack a; release a;

Esempio 3/7 Thread 1 a r class Agg { rep Rep f; } class Rep {} Agg a = new Agg; Rep r = new Rep; pack r; a.f = r; pack a; release a;

Esempio 4/7 Thread 1 a r class Agg { rep Rep f; } class Rep {} Agg a = new Agg; Rep r = new Rep; pack r; a.f = r; pack a; release a;

Esempio 5/7 Thread 1 a r class Agg { rep Rep f; } class Rep {} Agg a = new Agg; Rep r = new Rep; pack r; a.f = r; pack a; release a;

Esempio 6/7 Thread 1 a r class Agg { rep Rep f; } class Rep {} Agg a = new Agg; Rep r = new Rep; pack r; a.f = r; pack a; release a;

Esempio 7/7 Thread 1 a r class Agg { rep Rep f; } class Rep {} Agg a = new Agg; Rep r = new Rep; pack r; a.f = r; pack a; release a;

Object Invariants Ciascuna classe può dichiarare un invariante Linvariante può menzionare solo campi this.f1.f2.….fn.g dove f1, f2, …, fn sono campi rep Il comando pack controlla linvariante: di conseguenza, linvariante vale quando inv è true Il comando release controlla inv di conseguenza, aggregates liberi soddisfano i loro invarianti

Related Work idiomi valid in ESC/Modula-3 dichiarazione di invariant in ESC/Java e JML Spec# assicura che laccesso dei campi avviene tramite operazioni thread-local supporta aggregate objects gli invarianti sono rispettati applicazione completamente dinamica utilizza operazioni acquire e release

Conclusioni Invarianti differenti dalle pre/post-conditions Program invariants mantenuti in ogni punto di programma Uso di comandi pack / unpack I campi possono essere liberamente letti (vincoli solo per aggiornamento di campi) Estensione per il multhitreaded Supporto per aggregate objects Correttezza

Riferimenti Verification of object-oriented programs with invariants Mike Barnett, Robert DeLine, Manuel Fähndrich, K. Rustan M. Leino, Wolfram Schulte Microsoft Research, Redmond, WA, USA Journal of Object Technology ( Verification of multithreaded object-oriented programs with invariants Bart Jacobs (Dept. of Computer Science Katholieke Universiteit Leuven), K. Rustan M. Leino, Wolfram Schulte (Microsoft Research, Redmond, WA, USA) Modular verification of global module invariants in OO programs K. Rustan M. Leino and Peter Müller Technical Report 459, ETH Zürich, 2004 K. Rustan M. Leino Mike Barnett Robert DeLine Manuel Fähndrich Wolfram Schulte