1 Astrazioni sui dati : Ragionare sui Tipi di Dato Astratti.

Slides:



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

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.
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.
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.
1 Programmazione = decomposizione basata su astrazioni (con riferimento a Java)
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.
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.
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.
Compitino del 2004 Alberi Generici. Idea Si vuole un tipo di dato astratto che definisca una struttura ad albero in cui nodi e foglie hanno associato.
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.
1 Progettare un Tipo di Dato Astratto. 2 Scelte di Progetto (astrazione) 4 Caratteristiche degli oggetti –Modificabilità 4 Scelta delle operazioni –Realizzare.
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.
LIP: 8 Marzo 2005 Vettori. Abbiamo visto L’uso di Vector come alternativa all’uso di arrays Rivediamo l’esercizio dell’altra volta.
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.
Cose nuove di Java (prima a chiacchiera, poi formalmente)
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.
Progettare una classe 21 Febbraio La classe BankAccount Vogliamo realizzare una classe i cui oggetti sono dei semplici conti bancari. * Identifichiamo.
1 Astrazioni sui dati : Specifica ed Implementazione di Tipi di Dato Astratti in Java.
1 Testing e debugging. 2 Validazione 4 vogliamo assicurarci che un programma funziona come vorremmo e scoprire perché non lo fa, se questo è il caso 4.
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.
Alcune Classi Standard Object, Vettori. Ereditarieta’ Abbiamo visto come tramite l’ereditarieta’ e’ possibile estendere classi esistenti -arricchendo.
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

2 Correttezza dell’implementazione 4 L’implementazione del tipo di dato soddisfa la specifica 4 Rispetto al caso delle procedure stand-alone piu’ complicato 1. Specifica: descrizione astratta degli oggetti + metodi pubblici e le loro proprieta’ 2. Implementazione: rappresentazione + implementazione dei metodi

3 Correttezza dell’implementazione Bisogna provare due cose: 1. La rappresentazione (implementazione) dei dati soddisfa le proprieta’ richieste nella OVERVIEW 2. I metodi soddisfano le loro specifiche (simile al caso delle procedure stand-alone)

4 Correttezza dell’implementazione Le due cose sono pero’ strettamente correlate 1. La correttezza dei metodi puo’ dipendere da proprieta’ della rappresentazione 1. La correttezza della rappresentazione dipende dai metodi, dato che i metodi creano e modificano gli oggetti

5 Servono altre informazioni 4 Funzione di astrazione: collega la rappresentazione degli oggetti con la loro descrizione astratta 4 Invariante di rappresentazione: specifica proprieta’ della rappresentazione degli oggetti

6 Primo problema 4 se vogliamo dimostrare che le implementazioni dei metodi soddisfano le rispettive specifiche 4 l’implementazione utilizza la rappresentazione –nel caso di IntSet –private Vector els; 4 le specifiche esprimono proprietà dei dati astratti, ovvero degli insiemi –nel caso di IntSet public boolean isIn (int x) // EFFECTS: se x appartiene a this ritorna // true, altrimenti false 4 Per sapere se l’implementazione la soddisfa devo sapere come è rappresentato un insieme

7 Cosa manca 4 Un modo per mettere in relazione tra loro i due “insiemi di valori” concreti ed astratti 4 valori concreti: stati degli oggetti della classe (espressi da un insieme di var d’istanza) 4 valori astratti: il tipo di dato specificato  nel caso di IntSet: devo collegare il vettore els all’insieme di interi che rappresenta

8 La funzione di astrazione 1 4 la funzione di astrazione cattura l’intenzione 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 dell’oggetto astratto

9 Esempio public class IntSet { // OVERVIEW: un IntSet è un insieme modificabile // di interi di dimensione qualunque private Vector els; // la rappresentazione 4  deve mappare vettori di interi in insiemi 4  ([1,2]) = {1,2} 4  ([3,1]) = {1,3} 4  ([1,3,2]) = {1,2,3}

10 La funzione di astrazione 2  la funzione di astrazione è generalmente una funzione molti-a-uno public class IntSet { // OVERVIEW: 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}

11 Come definire la funzione di astrazione? 4 il problema è che non abbiamo una rappresentazione esplicita dei valori astratti (solo specifica informale) 4 l’oggetto da rappresentare può essere descritto da un oggetto astratto tipico della classe dato nella OVERVIEW della specifica. 4 per dare la funzione possiamo usare la notazione matematica e la notazione del linguaggio di programmazione con opportune abbreviazioni.

12 La funzione di astrazione di IntSet public class IntSet { // OVERVIEW: un IntSet è un insieme modificabile // di interi di dimensione qualunque // un tipico IntSet è {x1,,xn } private Vector els; // la rappresentazione  (c) = { c.els.get(i).intValue() | 0 <= i < c.els.size() } C metavariabile che rappresenta un oggetto generico di IntSet

13 La funzione di astrazione di Poly public class Poly { // OVERVIEW: 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  rappresentiamo il polinomio con –array che ha la dimensione del grado piu’ uno –l’elemento in posizione n contiene il coefficiente del termine che ha esponente n (eventualmente 0) –deg contiene il grado del polinomio 4 La funzione di astrazione collega l’array al polinomio

14 La funzione di astrazione di Poly public class Poly { // OVERVIEW: un Poly è un polinomio a // cofficienti interi non modificabile // un tipico Poly: c0+ c1 x + c2 x private int[] termini; // la rappresentazione private int deg; // la rappresentazione  (c) = c0+ c1 x + c2 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 dall’array termini che utilizziamo nello stato concreto per questioni di efficienza

15 Un altro problema 4 non tutti gli stati concreti “rappresentano” correttamente uno stato astratto 4 infatti gli oggetti concreti soddisfano delle proprieta’, sono costruiti in modo opportuno 4 queste proprieta’ servono tipicamente sia per la correttezza della rappresentazione sia per quella dei metodi 4 Da cosa derivarle

16 Esempio public class IntSet { // OVERVIEW: un IntSet è un insieme modificabile // di interi di dimensione qualunque // un tipico IntSet è {x1,,xn } 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 o contenere valori non di tipo Integer –questo sarebbe coerente con la funzione di astrazione –ma non rispecchierebbe la nostra scelta di progetto ( riflessa nell’implementazione dei metodi, vedi per esempio size, remove)

17 L’invariante di rappresentazione 4 l’invariante di rappresentazione (rep invariant) è un predicato I : C --> boolean che è vero per gli stati concreti che sono rappresentazioni legittime di uno stato astratto 4 esprime le proprieta’ fondamentali della rappresentazione (implementazione) degli oggetti in base alle quali abbiamo definito i metodi

18 L’invariante di rappresentazione 4 l’invariante 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 l’invariante

19 L’invariante di rappresentazione di IntSet 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 sono tutti distinti 4 gli elementi del vettore devono essere Integer –assunti soddisfatti in 

20 L’invariante di rappresentazione di Poly public class Poly { 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 // l’invariante 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 4 Il grado e’ l’esponente massimo con coefficiente non zero 4 Il grado (deg) deve essere uguale alla lunghezza dell’array -1 4 Il polinomio vuoto e’ rappresentato da un array di un elemento

21 Validita’ dell’invariante 4 Come facciamo a dimostrare formalmente che tutti gli oggetti del nuovo tipo di dato soddisfano l’invariante? 4 Notiamo che, dato che la rappresentazione e’ invisibile, nuovi oggetti possono essere creati solo coi costruttori e manipolati solo attraverso metodi pubblici della classe 4 Questo suggerisce che per provare la validita’ dell’invariante si puo’ procedere per induzione sul tipo di dato

22 Induzione sui dati 4 induzione sul numero di invocazioni di metodi usati per produrre il valore corrente dell’oggetto 4 Caso Base: dimostriamo che l’invariante vale per gli oggetti restituiti dai costruttori

23 Caso induttivo 4 per tutti i metodi produttori o modificatori separatamente facciamo vedere che 4 assumendo che l’invariante valga (IPOTESI INDUTTIVA) per this per tutti gli argomenti del tipo per gli oggetti del tipo ritornati o modificati da altre chiamate di metodi interne 4 allora quando il metodo termina l’invariante vale per this per tutti gli argomenti del tipo per gli oggetti del tipo ritornati

24 Commenti 4 Notate che questo ragionamento induttivo non sarebbe possibile se la rappresentazione fosse visibile 4 Chi ci garantirebbe che qualcuno non faccia qualche pasticcio nella rappresentazione dall’esterno? 4 Altro vantaggio di questo stile di programmazione, piu’ sicuro, piu’ facile ragionare sulla correttezza

25 4 Caso Base: il costruttore 4 Caso induttivo: per i modificatori insert e remove assumiamo che this soddisfi l’invariante e facciamo vedere che la soiddisfano anche dopo 4 Notate che gli altri metodi non modificatori preservano banalmente l’invariante (non modificano this) IntSet

26 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 l’invariante perché restituisce un Vector vuoto (non null)

27 IntSet 2 // 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 preserva l’invariante perché aggiunge x a this solo se x non è già in this, e lo aggiunge come Integer

28 IntSet 3 // 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 preserva l’invariante perché rimuove solo

29 Correttezza 4 dopo avere dimostrato l’invariante possiamo provare la correttezza dei metodi 4 per ogni metodo separatamente, facciamo vedere che l’implementazione soddisfa la specifica –usando il fatto che gli oggetti concreti soddisfano l’invariante –usando la funzione di astrazione per collegare dati concreti ed astratti –assumendo che le chiamate di altri metodi della classe interne siano corrette

30 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 () // EFFECTS: inizializza this a vuoto {els = new Vector();} 4 l’astrazione di un vettore vuoto è proprio l’insieme vuoto

31 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 () // EFFECTS: ritorna la cardinalità di this {return els.size(); } 4 il numero di elementi del vettore è la cardinalità dell’insieme perché –la funzione di astrazione mappa gli elementi del vettore in quelli dell’insieme –il rep invariant garantisce che non ci sono elementi duplicati in els Possiamo usare size() di Vector

32 Correttezza di IntSet 3 public void remove (int x) // MODIFIES: this // EFFECTS: 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 all’insieme  se x occorre nel vettore lo rimuove –e quindi in base alla funzione di astrazione x non appartiene all’insieme modificato

33 Correttezza di IntSet 4 public void remove (int x) // MODIFIES: this // EFFECTS: toglie x da this {int i = getIndex(new Integer(x)); if (i < 0) return; els.remove(i);} 4 Il rep invariant garantisce che non ci sono elementi duplicati (getIndex ritorna l’unico indice in cui occorre l’elemento se compare)

34 Eccezioni 4 L’invariante garantisce anche che il vettore non sia null 4 Di conseguenza nei metodi, quando si accede al vettore, non viene sollevata una eccezione (che sarebbe sbagliata, perche’ non prevista nella specifica)

35 Come scegliere l’invariante? 4 L’invariante riflette le scelte fatte nella rappresentazione 4 Deve valere per tutti gli oggetti del tipo (ragionando in modo induttivo) 4 Deve contenere abbastanza informazione per derivare le proprieta’ richieste nella specifica, sia dei dati che dei metodi 4 Per esempio: per la correttezza di remove e size e’ necessario sapere che nel vettore non ci sono occorrenze multiple (queste condizioni sono esattamente catturate dal rep invariant)

36 Invariante e f di astrazione 4 Devono sempre essere inserite come commento all’implementazione 4 Sono fondamentali per ragionare sulla correttezza dell’implementazione del tipo di dato astratto 4 Possono anche essere implementate ed utilizzate da programmi test per verificare le proprieta’ a run-time

37 Funzione di astrazione 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) = { c.els.get(i).intValue() | 0 <= i < c.els.size() }

38 toString per IntSet //  (c) = { 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);}

39 Invariante di rappresentazione 4 Usiamo un metodo repOk che verifica l’invariante pubblico perché deve poter essere chiamato da fuori della sua classe 4 ha sempre la seguente specifica public boolean rep0k () // EFFECTS: ritorna true se il rep invariant // vale per this, altrimenti ritorna false

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

41 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()

42 repOK per IntSet 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; }