1 Astrazioni sui dati : Ragionare sui Tipi di Dato Astratti dispense prof. G. Levi.

Slides:



Advertisements
Presentazioni simili
1 Astrazioni sui dati : Specifica ed Implementazione di Tipi di Dato Astratti in Java.
Advertisements

29 febbraio 2008 Progettare tipi di dato astratti.
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.
LIP: 19 Aprile Contenuto Soluzione Compitino Tipo di dato MultiSet, estensione con sottoclasse.
Metodologie di Programmazione = decomposizione basata su astrazioni
1 Le gerarchie di tipi: implementazioni multiple e principio di sostituzione.
PolyFun. Dare implementazione,funzione di astrazione, invarianti della rappresentazione. Provare che i metodi apply e bind preservano gli invarianti.
1 Astrazioni sui dati : Ragionare sui Tipi di Dato Astratti.
Liste Ordinate 3 Maggio Ultima Lezione Abbiamo visto i tipi di dato astratti IntList e StringList Realizzano liste di interi e di stringhe Realizzati.
LIP: 1 Marzo 2005 Classe Object e Vettori. Partiamo da Lesercizio dellultima esercitazione realizzato tramite array Vedremo come si puo fare in modo piu.
Astrazioni sul controllo Iteratori. 2 Nuove iterazioni Definendo un nuovo tipo come collezione di oggetti (p. es., set) si vorrebbe disporre anche di.
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.
Le classi Definizione di classe Attributi e metodi di una classe Costruttori e distruttori Private e public Funzioni friend Il puntatore this.
Java Collections.
1 Programmazione = decomposizione basata su astrazioni (con riferimento a Java)
Astrazione procedurale ed eccezioni
1 Un esempio con iteratore: le liste ordinate di interi.
Esercitazione su Vector. Permette di definire collezioni di dati generiche, che sono in grado di memorizzare elementi di ogni sottotipo di Object Definito.
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.
Astrazione di dati Dati Astratti: cosa e perchè Dati Astratti: due meccanismi differenti Dati Astratti: due meccanismi differenti Astrazione e incapsulamento.
1 Astrazioni polimorfe. 2 Perché il polimorfismo 4 non vogliamo definire versioni differenti dell’astrazione corrispondente ad una collezione di elementi.
Astrazione di dati Esercizio 1. Si completi l’implementazione Poly.add data a lezione con la specifica e l’implementazione degli ausiliari min e max data.
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 Problema tipico: memorizzare una sequenza di valori [6,0,9,3….9] Vediamo un tipo di dato utile.
Liste Concatenate 11 Aprile E’ una delle strutture dati fondamentali in tutti i linguaggi di programmazione di alto livello Una Lista Concatenata.
Liste di Interi Esercitazione. IntList Lista di interi Una lista è una disposizione ordinata di elementi ( non in modo crescente-descrescente, ma per.
1 Gerarchie e polimorfismo: liste. 2 Generalizzare le liste di interi  List 4 lista di oggetti –non modificabile 4 vorremo poi definire un sottotipo.
Esercitazione Object, Vettori, Liste. Ereditarieta’ Abbiamo visto come tramite l’ereditarieta’ e’ possibile estendere classi esistenti -arricchendo lo.
1 Laboratorio di Introduzione alla Programmazione §II MODULO §3 crediti §Esame e voto unico (su 6 crediti totali)
1 Astrazione sul controllo: gli iteratori. 2 Gli iteratori 4 perché vogliamo iterarare “in modo astratto” 4 iteratori e generatori in Java –specifica.
LIP: 9 Maggio Esercizi Riprendiamo un esercizio proposto Definire un tipo di dato Persona che definisce oggetti che rappresentano le informazioni.
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.
Ese 3 (del 3 Aprile 2003). Testo Progettare la specifica e l’implementazione del tipo di dato astratto modificabile Stack, supponendo che gli elementi.
1 Astrazione sul controllo: gli iteratori. 2 Perché vogliamo iterarare “in modo astratto” 4 problema: iterare su tipi di dato arbitrari  esempio: procedura.
1 Le gerarchie di tipi: implementazioni multiple e principio di sostituzione.
Ese 3 (del 3 Aprile 2003). Testo Progettare la specifica e l’implementazione del tipo di dato astratto modificabile Stack, supponendo che gli elementi.
Ese 3 (del 31 Marzo 2004). Testo Dare rappresentazione e realizzazione dei metodi della seguente classe QueueWithPriority. Nella risposta, non riportare.
LIP: 22 Marzo 2005 Eccezioni. Eccezioni-Richiami Come si definiscono eccezioni Come si lanciano Come si gestiscono (gestione esplicita o di default)
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.
Esercizio 3. Testo Dare rappresentazione e realizzazione dei metodi della seguente classe QueueWithPriority. Nella risposta, non riportare i commenti.
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.
1 Astrazione sul controllo: gli iteratori. 2 Perché vogliamo iterare “in modo astratto” 4 problema: iterare su tipi di dato arbitrari  esempio: procedura.
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.
Primo Compitino Terzo Esercizio Implementare il tipo di dato astratto Table un oggetto di tipo Table ha due colonne e un numero variabile di righe.
1 Astrazioni sui dati : Specifica ed Implementazione di Tipi di Dato Astratti in Java.
1 Metodologie di Programmazione = decomposizione basata su astrazioni.
Ese 1 e 3 (del 6 Aprile 2005). Primo Ese Si identifichino gli errori che il compilatore segnalerebbe per il seguente programma Tipi Legami tra dichiarazioni.
1 Astrazioni sui dati : Specifica ed Implementazione di Tipi di Dato Astratti in Java.
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.
Esercitazione 14 Marzo Esercizio dell’altra volta Definire un tipo di dato Abbonato i cui oggetti descrivono le informazioni relative ad un abbonato.
Esercitazione del 9 marzo 2007 Ereditarieta’. Richiami Definire sottoclassi (ereditarieta’) Overriding Specificatori di accesso (private, protected) Principio.
Liste Concatenate 28 Marzo Avviso Martedi’ 4 Aprile: Verifica di LIP Per iscriversi (obbligatorio) inviare un e- mail entro venerdi’ 31 Marzo a.
1 Astrazioni polimorfe. 2 Perché il polimorfismo 4 Abbiamo visto come si definiscono insiemi di stringhe, insiemi di interi, insiemi di caratteri, etc.
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: 15 Marzo 2005 Vettori di interi. Esercizio proposto Definire una classe VectorInt i cui oggetti sono vettori omogenei di interi ordinati in modo.
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.
Sommario cos’è un tipo di dato astratto astrazione tramite specifica:
Transcript della presentazione:

1 Astrazioni sui dati : Ragionare sui Tipi di Dato Astratti dispense prof. G. Levi

2 Ragionare sui Tipi di Dato Astratti 4 proprietà dellastrazione –modificabilità –categorie di operazioni –dimostrare proprietà dellastrazione 4 dimostrare proprietà dellimplementazione –funzione di astrazione –invariante di rappresentazione –dimostrazione mediante induzione sui dati

3 Modificabilità 1 4 i tipi non modificabili sono più sicuri –la condivisione di sottostrutture non crea problemi 4 i tipi non modificabili sono spesso più inefficienti –la necessità di costruire spesso copie di oggetti può complicare la vita al garbage collector 4 la scelta dovrebbe comunque tener conto delle caratteristiche dei concetti matematici o degli oggetti del mondo reale modellati dal tipo –gli interi non sono modificabili –gli insiemi sono modificabili –i conti correnti sono modificabili –....

4 Modificabilità 2 4 un tipo non modificabile può essere implementato utilizzando strutture modificabili –arrays, vectors, tipi record, tipi astratti modificabili public class Poly { // SCOPO: un Poly è un polinomio a // cofficienti interi non modificabile // esempio: c 0 + c 1 *x + c 2 *x private int[] termini; // la rappresentazione private int deg; // la rappresentazione 4 attenzione comunque agli effetti laterali nascosti –un metodo può restituire la rappresentazione modificabile (esporre la rep) –un tipo non modificabile può contenere un tipo modificabile che può essere restituito da un metodo (e poi modificato)

5 Categorie di operazioni 1 4 creatori –creano oggetti del loro tipo dal nulla sicuramente costruttori non tutti i costruttori sono creatori –possono avere come argomenti oggetti del loro tipo public IntSet () // POST: inizializza this a vuoto 4 produttori –prendono come argomenti oggetti del loro tipo e ne costruiscono altri possono essere costruttori o metodi public Poly sub (Poly q) throws NullPointerException // POST: q=null solleva NullPointerException // altrimenti ritorna this - q

6 Categorie di operazioni 2 4 modificatori –modificano gli oggetti del loro tipo public void insert (int x) // MODIFICA: this // POST: aggiunge x a this 4 osservatori –prendono oggetti del loro tipo e restituiscono valori di altri tipi per ottenere informazioni sugli oggetti public boolean isIn (int x) // POST: se x appartiene a this ritorna // true, altrimenti false public int coeff (int d) // POST: ritorna il coefficiente del // termine in this che ha come esponente d

7 Categorie di operazioni 3 4 i modificatori –modificano gli oggetti del loro tipo –per tipi modificabili 4 i produttori –prendono come argomenti oggetti del loro tipo e ne costruiscono altri –per tipi non modificabili 4 svolgono funzioni simili

8 Categorie di operazioni 4 4 quali e quante operazioni in una astrazione? –almeno un creatore –qualche produttore, se il tipo non è modificabile –qualche modificatore, se il tipo è modificabile attraverso creatori e produttori (o modificatori) dovremmo essere in grado di generare tutti i valori astratti –qualche osservatore 4 certe operazioni possono essere definite –nella classe (come primitive) –fuori della classe (nuovi metodi) 4 la scelta bilanciando efficienza dellimplementazione dei metodi e complessità della classe

9 Dimostrare proprietà dellastrazione 4 è spesso utile poter dimostrare proprietà delle astrazioni –anche per quelle procedurali –ma più interessante per le astrazioni sui dati 4 per dimostrare la proprietà dobbiamo utilizzare le specifiche 4 vediamo un esempio

10 Dimostrariamo una proprietà di IntSet 1 public class IntSet { // SCOPO: un IntSet è un insieme modificabile // di interi di dimensione qualunque public IntSet () // POST: inizializza this a vuoto public void insert (int x) // MODIFICA: this // POST: aggiunge x a this public void remove (int x) // MODIFICA: this // POST: toglie x da this vogliamo dimostrare che per ogni IntSet la sua size è >= 0 4 basta convincerci che questo è vero per i costruttori ed i modificatori

11 Dimostriamo una proprietà di IntSet 2 per ogni IntSet la sua size è >= 0 per il costruttore public IntSet () // POST: inizializza this a vuoto 4 linsieme vuoto ha cardinalità 0

12 Dimostriamo una proprietà di IntSet 3 per ogni IntSet la sua size è >= 0 4 per ogni modificatore public void insert (int x) // MODIFICA: this // POST: aggiunge x a this 4 se la proprietà vale prima dellinserimento, vale anche dopo perché linserimento può solo incrementare la cardinalità

13 Dimostriamo una proprietà di IntSet 4 per ogni IntSet la sua size è >= 0 4 per ogni modificatore public void remove (int x) // MODIFICA: this // POST: toglie x da this 4 se la proprietà vale prima della rimozione, vale anche dopo perché la rimozione può ridurre la cardinalità solo se lelemento era contenuto al momento della chiamata

14 Correttezza dellimplementazione 4 se vogliamo dimostrare che le implementazioni dei metodi soddisfano le rispettive specifiche –non possiamo utilizzare la metodologia appena vista 4 limplementazione utilizza la rappresentazione –nel caso di IntSet –private Vector els; 4 le specifiche esprimono proprietà dellastrazione –nel caso di IntSet public boolean isIn (int x) // POST: se x appartiene a this ritorna // true, altrimenti false 4 è necessario mettere in relazione tra loro i due insiemi di valori

15 La funzione di astrazione 1 4 la funzione di astrazione cattura lintenzione del progettista nello scegliere una particolare rappresentazione 4 la funzione di astrazione : C --> A porta da uno stato concreto –lo stato di un oggetto della classe C a uno stato astratto –lo stato delloggetto astratto public class IntSet { // SCOPO: un IntSet è un insieme modificabile // di interi di dimensione qualunque private Vector els; // la rappresentazione 4 porta vettori in insiemi

16 La funzione di astrazione 2 4 la funzione di astrazione è generalmente una funzione molti-a-uno public class IntSet { // SCOPO: un IntSet è un insieme modificabile // di interi di dimensione qualunque private Vector els; // la rappresentazione –piú stati concreti (vettori di interi) vengono portati nello stesso stato astratto (insieme ) – ([1,2]) = {1,2} – ([2,1]) = {1,2} 4 la funzione di astrazione deve sempre essere definita ed inserita come commento allimplementazione –perché è una parte importante delle decisioni relative allimplementazione Loggetto da rappresentare può essere descritto da un oggetto astratto tipico della classe dato nella OVERVIEW della specifica. Possiamo usare la notazione matematica e la notazione del linguaggio di programmazione con opportune abbreviazioni.

17 La funzione di astrazione 3 4 la funzione di astrazione deve sempre essere definita ed inserita come commento allimplementazione –perché è una parte importante delle decisioni relative allimplementazione 4 il problema è che non abbiamo una rappresentazione esplicita dei valori astratti 4 diamo (nella DESCRIZIONE) la descrizione di un tipico stato astratto 4 esempi –nella definizione della funzione di astrazione, useremo la notazione del linguaggio di programmazione

18 La funzione di astrazione di IntSet public class IntSet { // DESCRIZIONE: un IntSet è un insieme modificabile // di interi di dimensione qualunque // un tipico IntSet è {x 1, …, x n } private Vector els; // la rappresentazione // la funzione di astrazione // (c) = { (Integer)c.els.get(i).intValue() | 0 <= i < c.els.size() }

19 La funzione di astrazione di Poly public class Poly { // DESCRIZIONE: un Poly è un polinomio a // cofficienti interi non modificabile // un tipico Poly: c 0 + c 1 *x + c 2 *x private int[] termini; // la rappresentazione private int deg; // la rappresentazione // la funzione di astrazione // (c) = c 0 + c 1 *x + c 2 *x tale che // c i = c.termini[i] se 0 <= i < c.termini.length // = 0 altrimenti 4 notare che il valore di deg non ha nessuna influenza sulla funzione di astrazione –è una informazione derivabile dallarray termini che utilizziamo nello stato concreto per questioni di efficienza

20 La funzione di astrazione può essere implementata 4 la funzione di astrazione deve sempre essere definita ed inserita come commento allimplementazione 4 non avendo una rappresentazione esplicita dei valori astratti, possiamo rappresentarli come stringhe 4 a questo punto, possiamo implementare la funzione di astrazione, che è esattamente il metodo toString –utile per stampare valori astratti // (c) = { (Integer)c.els.get(i).intValue() | 0 <= i < c.els.size() } // (c) = c 0 + c 1 *x + c 2 *x tale che // c i = c.termini[i] se 0 <= i < c.termini.size() // = 0 altrimenti

21 toString per IntSet // (c) = { (Integer)c.els.get(i).intValue() | 0 <= i < c.els.size() } public String toString () {String s = "{"; for (int i = 0; i < els.size() - 1; i++) { s = s + els.get(i).toString() + ","; } if (els.size() > 0) { s = s + els.get(els.size() - 1).toString(); } s = s + "}"; return (s);}

22 Verso linvariante di rappresentazione 4 non tutti gli stati concreti rappresentano correttamente uno stato astratto public class IntSet { // DESCRIZIONE: un IntSet è un insieme modificabile // di interi di dimensione qualunque // un tipico IntSet è {x 1, …, x n } private Vector els; // la rappresentazione // la funzione di astrazione // (c) = { c.els.get(i).intValue() | 0 <= i < c.els.size() } 4 il vettore els potrebbe contenere più occorrenze dello stesso elemento –questo sarebbe coerente con la funzione di astrazione –ma non rispecchierebbe la nostra scelta di progetto riflessa nellimplementazione dei metodi

23 Linvariante di rappresentazione 4 linvariante di rappresentazione (rep invariant) è un predicato I : C --> boolean che è vero per gli stati concreti che sono rappresentazioni legittime di uno stato astratto 4 linvariante di rappresentazione, insieme alla funzione di astrazione, riflette le scelte relative alla rappresentazione –deve essere inserito nella documentazione della implementazione come commento 4 la funzione di astrazione è definita solo per stati concreti che soddisfano linvariante

24 Linvariante di rappresentazione di IntSet public class IntSet { // DESCRIZIONE: un IntSet è un insieme modificabile // di interi di dimensione qualunque // un tipico IntSet è {x 1, …, x n } private Vector els; // la rappresentazione // la funzione di astrazione: // (c) = { c.els.get(i).intValue() | 0 <= i < c.els.size() } // linvariante di rappresentazione: // I (c) = c.els != null e // per ogni intero i, c.els.get(i) è un Integer // e per tutti gli interi i,j, tali che // 0 <= i < j < c. els.size(), // c.els.get(i).intValue() != // c.els.get(j).intValue() 4 il vettore non deve essere null 4 gli elementi del vettore devono essere Integer –assunti soddisfatti in 4 tutti gli elementi sono distinti

25 Una diversa implementazione per IntSet 1 public class IntSet { // DESCRIZIONE: un IntSet è un insieme modificabile // di interi di dimensione qualunque // un tipico IntSet è {x 1, …, x n } private boolean[100] els; private Vector altriels; private int dim; 4 linserimento di un elemento n compreso tra 0 e 99 viene realizzato mettendo a true els[n] gli elementi maggiori di 99 sono inseriti nel vettore altriels gestito come nellimplementazione precedente 4 dim contiene esplicitamente la cardinalità –che sarebbe complessa da calcolare a partire da els 4 implementazione sensata solo se la maggior parte degli elementi sono compresi nellintervallo 0-99

26 Una diversa implementazione per IntSet 2 public class IntSet { // DESCRIZIONE: un IntSet è un insieme modificabile // di interi di dimensione qualunque // un tipico IntSet è {x 1, …, x n } private boolean[100] els; private Vector altriels; private int dim; // la funzione di astrazione: // (c) = { c.altriels.get(i).intValue() | // 0 <= i < c.altriels.size() } + // {j | 0 <= j < 100 e c.els[j] }

27 Una diversa implementazione per IntSet 3 public class IntSet { // DESCRIZIONE: un IntSet è un insieme modificabile // di interi di dimensione qualunque // un tipico IntSet è {x 1, …, x n } private boolean[100] els; private Vector altriels; private int dim; // linvariante di rappresentazione: // I (c) = c.els != null e // c.altriels != null e // els.length = 100 e // per ogni intero i, // c.altriels.get(i) è un Integer, // c.altriels.get(i).intValue() non appartiene // allintervallo 0-99, e // per tutti gli interi i,j, tali che // 0 <= i < j < c.altriels.size(), // c.altriels.get(i).intValue() != // c.altriels.get(j).intValue() e // c.dim = c.altriels.size() + conta(c.els,0)

28 Una funzione ausiliaria nel rep invariant dove conta(a,i) = if (i >= a.length) return 0; else if (a[i]) return (1 + conta(a, i-1)) else return (conta(a, i-1))

29 Linvariante di rappresentazione di Poly public class Poly { // DESCRIZIONE: un Poly è un polinomio a // cofficienti interi non modificabile // un tipico Poly: c 0 + c 1 *x + c 2 *x private int[] termini; // la rappresentazione private int deg; // la rappresentazione // la funzione di astrazione // (c) = c 0 + c 1 *x + c 2 *x tale che // c i = c.termini[i] se 0 <= i < c.termini.size() // = 0 altrimenti // linvariante di rappresentazione: // I (c) = c.termini != null e // c.termini.length >= 1 e // c.deg = c.termini.length-1 e // c.deg > 0 ==> c.termini[deg] != 0

30 Linvariante di rappresentazione può essere implementato 1 4 il metodo repOk che verifica linvariante dovrebbe essere fornito da ogni astrazione sui dati –pubblico perché deve poter essere chiamato da fuori della sua classe 4 ha sempre la seguente specifica public boolean rep0k () // POST: ritorna true se il rep invariant // vale per this, altrimenti ritorna false

31 repOK 4 può essere usato da programmi di test per verificare se una implementazione preserva linvariante 4 può essere usato dentro le implementazioni di costruttori e metodi –creatori, modificatori e produttori dovrebbero chiamarlo prima di ritornare per assicurarsi che per loggetto costruito o modificato vale linvariante per esempio, dovrebbero chiamarlo insert e remove di IntSet, add, mul, minus di Poly 4 se linvariante non vale si dovrebbe sollevare FailureException

32 repOK per Poly public class Poly { private int[] termini; // la rappresentazione private int deg; // la rappresentazione // I (c) = c.termini != null e // c.termini.length >= 1 e // c.deg = c.termini.length-1 e // c.deg > 0 ==> c.termini[deg] != 0 public boolean repOk() { if (termini == null || deg != termini.length - 1 || termini.length == 0) return false; if (deg == 0) return true; return termini[deg] != 0; }

33 repOK per IntSet public class IntSet { private Vector els; // la rappresentazione // I (c) = c.els != null e // per ogni intero i, c.els.get(i) è un Integer // e per tutti gli interi i,j, tali che // 0 <= i < j < c. els.size(), // c.els.get(i).intValue() != // c.els.get(j).intValue() public boolean repOk() { if (els == null) return false; for (int i = 0; i < els.size(); i++) { Object x = els.get(i); if (! (x instanceof Integer)) return false; for (int j = i + 1; j < els.size(); j++) if (x.equals (els.get(j))) return false; } return true; }

34 Correttezza di una implementazione invece di eseguire repOk (controllo dinamico), possiamo dimostrare formalmente che, ogniqualvolta un oggetto del nuovo tipo è manipolato allesterno della classe, esso soddisfa linvariante –induzione sul tipo di dato 4 dobbiamo poi dimostrare, per ogni metodo, che limplementazione soddisfa la specifica –usando la funzione di rappresentazione

35 Soddisfacimento del rep invariant 4 per prima cosa, dimostriamo che linvariante vale per gli oggetti restituiti dai costruttori 4 in modo induttivo, dimostriamo che vale per tutti i metodi (produttori e modificatori) –assumiamo che linvariante valga per this e per tutti gli argomenti del tipo –dimostriamo che vale quando il metodo ritorna per this per tutti gli argomenti del tipo per gli oggetti del tipo ritornati 4 induzione sul numero di invocazioni di metodi usati per produrre il valore corrente delloggetto –la base dellinduzione riguarda i costruttori

36 Correttezza di IntSet 1 public class IntSet { private Vector els; // la rappresentazione // I (c) = c.els != null e // per ogni intero i, c.els.get(i) è un Integer // e per tutti gli interi i,j, tali che // 0 <= i < j < c. els.size(), // c.els.get(i).intValue() != // c.els.get(j).intValue() public IntSet () {els = new Vector();} il costruttore soddisfa linvariante perché restituisce un Vector vuoto

37 Correttezza di IntSet 2 public class IntSet { private Vector els; // la rappresentazione // I (c) = c.els != null e // per ogni intero i, c.els.get(i) è un Integer // e per tutti gli interi i,j, tali che // 0 <= i < j < c. els.size(), // c.els.get(i).intValue() != // c.els.get(j).intValue() public void insert (int x) {Integer y = new Integer(x); if (getIndex(y) < 0) els.add(y); } private int getIndex (Integer x) // EFFECTS: se x occorre in this ritorna la // posizione in cui si trova, altrimenti -1 il metodo insert soddisfa linvariante perché aggiunge x a this solo se x non è già in this

38 Correttezza di IntSet 3 public class IntSet { private Vector els; // la rappresentazione // I (c) = c.els != null e // per ogni intero i, c.els.get(i) è un Integer // e per tutti gli interi i,j, tali che // 0 <= i < j < c. els.size(), // c.els.get(i).intValue() != // c.els.get(j).intValue() public void remove (int x) {int i = getIndex(new Integer(x)); if (i < 0) return; els.set(i, els.lastElement()); els.remove(els.size() - 1);} il metodo remove soddisfa linvariante perché rimuove x da this solo se x è in this

39 Correttezza di Poly 1 public class Poly { private int[] termini; // la rappresentazione private int deg; // la rappresentazione // I (c) = c.termini != null e // c.termini.length >= 1 e // c.deg = c.termini.length-1 e // c.deg > 0 ==> c.termini[deg] != 0 public Poly () {termini = new int[1]; deg = 0; } il primo costruttore soddisfa linvariante perché restituisce un Array di un elemento e deg = 0

40 Correttezza di Poly 2 public class Poly { private int[] termini; // la rappresentazione private int deg; // la rappresentazione // I (c) = c.termini != null e // c.termini.length >= 1 e // c.deg = c.termini.length-1 e // c.deg > 0 ==> c.termini[deg] != 0 public Poly (int c, int n) throws NegativeExponentExc if (n < 0) throw new NegativeExponentExc (Poly(int,int) constructor); if (c == 0) {termini = new int[1]; deg = 0; return; } termini = new int[n+1]; for (int i = 0; i < n; i++) termini[i] = 0; termini[n] = c; deg = n; } il secondo costruttore soddisfa linvariante perché testa esplicitamente il caso c=0

41 Correttezza di Poly 3 public class Poly { private int[] termini; // la rappresentazione private int deg; // la rappresentazione // I (c) = c.termini != null e // c.termini.length >= 1 e // c.deg = c.termini.length-1 e // c.deg > 0 ==> c.termini[deg] != 0 public Poly sub (Poly q) throws NullPointerException {return add(q.minus()); } il metodo sub soddisfa linvariante perché –lo soddisfano q e this –lo soddisfano add e minus

42 Le implementazioni dei metodi soddisfano la specifica 4 si ragiona usando la funzione di astrazione –un metodo alla volta 4 ciò è possibile solo perché abbiamo già dimostrato che il rep invariant è soddisfatto da tutte le operazioni –il rep invariant cattura le assunzioni comuni fra le varie operazioni –permette di trattarle separatamente

43 Correttezza di IntSet 1 public class IntSet { private Vector els; // la rappresentazione // la funzione di astrazione // (c) = { c.els.get(i).intValue() | 0 <= i < c.els.size() } public IntSet () // POST: inizializza this a vuoto {els = new Vector();} 4 lastrazione di un vettore vuoto è proprio linsieme vuoto

44 Correttezza di IntSet 2 public class IntSet { private Vector els; // la rappresentazione // la funzione di astrazione // (c) = { c.els.get(i).intValue() | 0 <= i < c.els.size() } public int size () // POST: ritorna la cardinalità di this {return els.size(); } 4 il numero di elementi del vettore è la cardinalità dellinsieme perché –la funzione di astrazione mappa gli elementi del vettore in quelli dellinsieme –il rep invariant garantisce che non ci sono elementi duplicati in els senza dover andare a guardare come è fatta insert

45 Correttezza di IntSet 3 public class IntSet { private Vector els; // la rappresentazione // la funzione di astrazione // (c) = { c.els.get(i).intValue() | 0 <= i < c.els.size() } public void remove (int x) // MODIFICA: this // POST: toglie x da this {int i = getIndex(new Integer(x)); if (i < 0) return; els.set(i, els.lastElement()); els.remove(els.size() - 1);} se x non occorre nel vettore non fa niente –corretto perché in base alla funzione di astrazione x non appartiene allinsieme se x occorre nel vettore lo rimuove –e quindi in base alla funzione di astrazione x non appartiene allinsieme modificato