Astrazione Dati Nicola Fanizzi Dipartimento di Informatica Università degli Studi di Bari Linguaggi di Programmazione [010194] 10 mag, 2016
Sommario 1 Astrazione dati Incapsulamento Esempio / ADT pila di interi 2 Information hiding Specifica di ADT Indipendenza dalla rappresentazione 3 Moduli ADT vs. Moduli Moduli generici Astrazione Dati 10 mag, 2016 2 / 30
Agenda 1 Astrazione dati Incapsulamento Esempio / ADT pila di interi 2 Information hiding 3 Moduli Astrazione Dati 10 mag, 2016 3 / 30
Incapsulamento e tipi Macchina fisica: dati = stringhe di bit Macchina astratta: valore di un determinato tipo capsula che riveste la stringa di bit trasparenza determinata dal sistema di tipi più opaca nei linguaggi sicuri Astrazione Dati 10 mag, 2016 4 / 30
Pila di interi in pseudo-c++ 1 type Int_Stack = struct { 2 int P[100]; // lo stack 3 int top; // I elem. leggibile 4 } 5 6 Int_Stack crea_pila() { 7 Int_Stack s = new Int_Stack(); 8 s.top = 0; 9 return s; 10 } 11 12 int top(int_stack s) { 13 return s.p[s.top]; 14 } 15 16 17 bool empty(int_stack s) { 18 return (s.top == 0); 19 } 20 21 Int_Stack push(int_stack s, int k) { 22 if (s.top == 100) errore(); 23 s.p[s.top] = k; 24 s.top = s.top + 1; 25 return s; 26 } 27 28 Int_Stack pop(int_stack s) { 29 if (s.top == 0) errore(); 30 s.top = s.top - 1; 31 return s; 32 } NB il linguaggio non dà alcuna garanzia sul fatto che la pila possa essere manipolata solo attraverso le funzioni definite Astrazione Dati 10 mag, 2016 5 / 30
Costruttori di tipo Veri e propri nuovi tipi? Generalmente i meccanismi di costruzione di tipi di dati (es. array, record) non consentono la definizione di operazioni sui valori che si rappresentano Esempio pila di interi realizzata con un array (Pascal, C,... ) operazioni: push, pop, empty, top Problema: nulla vieta la manipolazione diretta dell array 1 int second_from_top(int_stack c) { 2 return c.p[s.top - 1]; 3 } Astrazione Dati 10 mag, 2016 6 / 30
Astrazione dati Obiettivo rendere inaccessibile la rappresentazione Tipo di dato astratto (ADT): nome tipo implementazione dei valori (rappresentazione) insieme dei nomi delle operazioni per ogni operazione implementazione dell operazione che usi la rappresentazione capsula di sicurezza che separi nomi di tipi ed operazioni (interfaccia o segnatura) dalla loro implementazione (realizzazione) Nei linguaggi più evoluti, ADT come tipi predefiniti es. ML, CLU,... Astrazione Dati 10 mag, 2016 7 / 30
ADT pila di interi 1 abstype Int_Stack; 2 3 type Int_Stack = struct { 4 int P[100]; 5 int n; 6 int top; 7 } 8 9 signature 10 11 Int_Stack crea_pila(); 12 int top(int_stack s); 13 bool empty(int_stack s); 14 Int_Stack push(int_stack s,int k); 15 Int_Stack pop(int_stack s); 16 17 18 Astrazione Dati 10 mag, 2016 8 / 30
ADT pila di interi [... cont.] 19 operations 20 21 Int_Stack crea_pila() { 22 Int_Stack s = new Int_Stack(); 23 s.top = 0; 24 return s; 25 } 26 27 int top(int_stack s) { 28 return s.p[s.top]; 29 } 30 31 bool empty(int_stack s){ 32 return (s.n == 0); 33 } 34 35 36 Astrazione Dati 10 mag, 2016 9 / 30
ADT pila di interi [... cont.] 37 Int_Stack push(int_stack s,int k) { 38 if (s.top == 100) errore(); 39 s.p[s.top] = k; 40 s.top = s.top + 1; 41 return s; 42 } 43 44 Int_Stack pop(int_stack s) { 45 if (s.top == 0) errore(); 46 s.top = s.top - 1; 47 return s; 48 } Astrazione Dati 10 mag, 2016 10 / 30
ADT pila di interi [... cont.] Esempio nuovo tipo astratto per variabili intere implementato (in modo inefficiente) attraverso una pila Int_Stack 1 abstype Int_Var{ 2 3 type Int_Var = Int_Stack; 4 5 signature 6 7 Int_Var create_var(); 8 int deref(int_var v); 9 Int_Var assign(int_var v, int n); 10 11 operations 12 13 Int_Var create_var() { 14 return push(create_stack(),0); 15 } 16 Astrazione Dati 10 mag, 2016 11 / 30
ADT pila di interi [... cont.] 17 int deref(int_var v) { 18 return top(v); 19 } 20 21 Int_Var assign(int_var v, int n){ 22 return push(pop(v),n); 23 } 24 } nell implementazione di Int_Var, quella di Int_Stack è invisibile perché incapsulata Astrazione Dati 10 mag, 2016 12 / 30
Agenda 1 Astrazione dati 2 Information hiding Specifica di ADT Indipendenza dalla rappresentazione 3 Moduli Astrazione Dati 10 mag, 2016 13 / 30
Information hiding Information hiding separare interfaccia da implementazione astrazione sul controllo: nasconde codice del corpo astrazione dati: nasconde codice ma anche rappresentazione Il sistema dei tipi garantisce che l astrazione non venga violata vantaggi è possibile sostituire un implementazione mantenendo la stessa interfaccia es. pila realizzata con lista concatenata anziché con vettore Astrazione Dati 10 mag, 2016 14 / 30
Esempio nuova pila di interi Esempio 1 abstype Int_Stack{ 2 pila implementata come lista concatenata 3 type Int_Stack = struct{ 4 int info; 5 Int_Stack next; 6 } 7 8 signature 9 10 Int_Stack create_stack(); 11 Int_Stack push(int_stack s, int k); 12 int top(int_stack s); 13 Int_Stack pop(int_stack s); 14 bool empty(int_stack s); 15 16 17 Astrazione Dati 10 mag, 2016 15 / 30
Esempio nuova pila di interi [... cont.] 18 operations 19 20 Int_Stack create_stack(){ 21 return null; 22 } 23 24 Int_Stack push(int_stack s, int k){ 25 Int_Stack tmp = new Int_Stack(); // nuovo elem. 26 tmp.info = k; 27 tmp.next = s; // concatena alla pila 28 return tmp; 29 } 30 31 int top(int_stack s){ 32 return s.info; 33 } 34 35 Astrazione Dati 10 mag, 2016 16 / 30
Esempio nuova pila di interi [... cont.] 36 Int_Stack pop(int_stack s){ 37 return s.next; 38 } 39 40 bool empty(int_stack s){ 41 return (s == null); 42 } 43 } Astrazione Dati 10 mag, 2016 17 / 30
Specifica di ADT Descrizione della semantica delle operazioni di un ADT espressa attraverso relazioni generali astratte in linguaggio naturale, schemi semi-formali, linguaggi formalizzati manipolabili da theorem-prover,... es. ADT pila di interi crea_pila: crea una pila vuota push: inserisce un elemento sulla pila; top: restituisce l elemento in cima alla pila (non vuota) senza modificare la stessa pop: elimina l elemento in cima alla pila (non vuota) empty: vero sse pila vuota specifica = contratto tra cliente e ADT implementazione corretta deve corrispondere alla specifica Astrazione Dati 10 mag, 2016 18 / 30
Indipendenza dalla rappresentazione Due implementazioni corrette di una stessa specifica di un ADT risultano indistinguibili da parte dei clienti un cliente dell ADT non deve accorgersi in caso di cambiamento dell implementazione versione debole: sostituzione (senza errori di tipo) a parità di segnatura dimostrata come un teorema per linguaggi type-safe come CLU, ML,... Astrazione Dati 10 mag, 2016 19 / 30
Agenda 1 Astrazione dati 3 Moduli ADT vs. Moduli Moduli generici 2 Information hiding Astrazione Dati 10 mag, 2016 20 / 30
Moduli Programmazione in piccolo : ADT Programmazione in grande : modulo astrazione di più strutture dati correlate es. package Java; unit Pascal/Delphi partizionamento di un programma complesso in unità più semplici dichiarazioni dati: tipi, variabili,... operazioni: funzioni,... regole di visibilità: incapsulamento, occultamento dell informazione (information hiding) Astrazione Dati 10 mag, 2016 21 / 30
ADT vs. Moduli in teoria: nessuna differenza in pratica: moduli più flessibili permeabilità della capsula selezione degli operatori visibili e del loro grado di visibilità moduli generici (polimorfici) risoluzione al momento dell uso compilazione separata (unità di compilazione) Astrazione Dati 10 mag, 2016 22 / 30
Modulo Buffer, Counter e Queue 1 module Buffer imports Counter{ 2 public 3 type Buf; 4 void insert(reference Buf f, int n); 5 int get(buf b); 6 Count c; // quante volte e stato utilizzato 7 private imports Queue{ 8 type Buf = Queue; 9 void insert(reference Buf b, int n){ 10 inqueue(b,n); 11 inc(c); 12 } 13 int get(buf b){ 14 return dequeue(b); 15 inc(c); 16 } 17 init_counter(c); // inizializzazione del modulo 18 } Astrazione Dati 10 mag, 2016 23 / 30
Modulo Buffer, Counter e Queue [... cont.] 1 module Counter{ 2 public 3 type Count; 4 void init_counter(reference Count c); 5 int get(count c); 6 void inc(reference Count c); 7 private 8 type Count = int; 9 void init_counter(reference Count c){ 10 c=0; 11 } 12 int get(count c){ 13 return c; 14 } 15 void inc(reference Count c){ 16 c = c+1; 17 } 18 } Astrazione Dati 10 mag, 2016 24 / 30
Modulo Buffer, Counter e Queue [... cont.] 1 module Queue{ 2 public 3 type Queue; 4 inqueue(reference Queue q, int n); 5 int dequeue(reference Queue q); 6... 7 private 8 void bookkeep(reference Queue q){ 9... 10 } 11... 12 } Astrazione Dati 10 mag, 2016 25 / 30
Modulo Composizione parte pubblica: visibile all esterno parte privata: invisibile uso di un modulo: importazione spesso congiunto con il polimorfismo parametrico risolto a linking-time collegamento a funzioni precompilate di libreria Astrazione Dati 10 mag, 2016 26 / 30
Moduli generici module Buffer<T> imports Counter{ public type Buf; void insert(reference Buf f, <T> n); <T> get(buf b); Count c; // quante volte si e usato il buffer } private imports Queue<T>{ type Buf = Queue; void insert(reference Buf b, <T> n){ inqueue(b,n); inc(c); } <T> get(buf b){ return dequeue(b); inc(c); } Astrazione Dati 10 mag, 2016 27 / 30
Moduli generici [... cont.] module Counter{ public type Count; void init_counter(reference Count c); int get(count c); void inc(reference Count c); private type Count = int; void init_counter(reference Count c){ c = 0; } int get(count c){ return c; } void inc(reference Count c){ c = c+1; } } init_counter(c); // inizializzazione del modulo Astrazione Dati 10 mag, 2016 28 / 30
Moduli generici [... cont.] module Queue<S>{ public type Queue; inqueue(reference Queue q, <S> n); <S> dequeue(reference Queue q);... private void bookkeep(reference Queue q){... }... } Astrazione Dati 10 mag, 2016 29 / 30
Riferimenti Gabbrielli & Martini: Linguaggi di Programmazione, McGraw-Hill. 2a edizione. Cap. 11 Astrazione Dati 10 mag, 2016 30 / 30