PolyFun
Dare implementazione,funzione di astrazione, invarianti della rappresentazione. Provare che i metodi apply e bind preservano gli invarianti. public class PolyFun { // OVERVIEW: un PolyFun è una funzione // parziale(a dominio finito) da un tipo // qualunque a qualunque altro. Non è // modificabile.Dominio e codominio devono // essere omogenei. // Costruttore public PolyFun (Class dt, Class ct) // EFFECTS: costruisce una nuova PolyFun // avente come dominio dt e come codominio // ct e indefinita per tutti gli argomenti.
// metodi public boolean defined (Object o) // EFFECTS: se this è definita per l'argomento // o ritorna true altrimenti ritorna false. public Object apply (Object o) throws UndefinedException // EFFECTS: se la funzione this è definita per // l'oggetto o restituisce this(o) altrimenti // solleva l'eccezione (unchecked) // UndefinedException.
public PolyFun bind (Object d, Object c) throws DuplicateException, ClassCastException, NullPointer Exception { // EFFECTS: restituisce una funzione // diversa da this solo perché definita anche // per d e applicata a d restituisce c. // Se this è già definita per d, // solleva DuplicateException; se d e c // solleva NullPointer Exception; se d e c // non sono dello stesso tipo di dominio // e codominio solleva ClassCastException. }
Implementazione Si utilizzano due variabili (di tipo class) che memorizzano il tipodel dominio e il tipo del codominio(inizializzate dal costruttore). Per rappresentare la funzione si utilizza un vettore di coppie (argomento, valore). Esempio: {((x1, f(x1)),((x2, f(x2)),… }. Per le coppie usiamo il tipo Pair. Si deve garantire che dominio e codominio siano omogenei.
Classe PolyFun public class PolyFun { // OVERVIEW: un PolyFun è una funzione // parziale(a dominio finito) da un tipo // qualunque a qualunque altro. Non è // modificabile. Dominio e codominio // devono essere omogenei. protected vector v; Protected Class dom; protected Class cod;
Classe PolyFun, costruttore // Costruttore public PolyFun (Class dt, Class ct) // EFFECTS: costruisce una nuova PolyFun // avente dominio dt e codominio ct // e indefinita per tutti gli argomenti. {v = new vector; dom = dt; cod = ct; }
Classe PolyFun, metodo defined // metodi public boolean defined (Object o) // EFFECTS: se this è definita per // l'argomento o ritorna true altrimenti // ritorna false. if (v.size = 0) return false; for(int i = 0; i < v.size(); i++) { Pair p = (Pair)v.get(i); if (o.equals(p.left()))return true;} return false;}
Classe PolyFun, metodo apply public Object apply (Object o) throws UndefinedException // EFFECTS: se la funzione this è definita // per l'oggetto o restituisce this(o) // altrimenti solleva l'eccezione // (unchecked) UndefinedException. if (!defined(o)throw UndefinedException (PolyFun.apply); for(int i = 0; i < v.size(); i++) { Pair p = (Pair)v.get(i); if(o.equals(p.left())) return p.right;}
Classe PolyFun, metodo bind public PolyFun bind (Object d, Object c) throws DuplicateException, ClassCastException, NullPointerException { // EFFECTS: restituisce una funzione // diversa da this perché definita anche // per d e applicata a d restituisce c. // Se this è già definita per d, // solleva DuplicateException; se d e c sono null // solleva NullPointer Exception; se d e c // non sono dello stesso tipo di dominio // e codominio solleva ClassCastException. if (d == null ||c == null) throw NullPointerException(PolyFun.bind); if (defined(d)) throw DuplicateException(PolyFun.bind); if ( (d.getclass() != dom || c.getclass() != cod throw ClassCastException(PolyFun.bind); Pair p = new Pair(c,d); v.add(p); }
Funzione di astrazione Alpha PolyFun (c) = f : c.cod ---> c.cod Tale che f(x) = y sse esiste i, 0 <= i <c.v.size(): c.v.get(i).left() = x c.v.get(i).right() = y
Invariante I PolyFun (c) = per ogni i, 0 <= i <c.v.size() c.v.get(i) non null and c.v.get(i).left().getclass()= c.dom and c.v.get(i).right().getclass()= c.cod and per ogni i, 0 <= i < c.v.size() i != j c.v.get(i).left() != c.v.get(j).left()
Sottoclasse SubPolyFun public class SubPolyFun extends PolyFun { //OVERVIEW: una SubPolyFun è una // sottoclasse di funzioni parziali a // dominio finito da un sottotipo di // oggetti confrontabili a un tipo // qualunque.
SubPolyFun, costruttore // costruttore public SubPolyFun (Comparable d, Object c ) // EFFECTS: costruisce una nuova // SubPolyFun che ha come dominio il tipo di d // e come codominio il tipo di c indefinita // per tutti gli argomenti
SubPolyFun, bind // metodo overriden public PolyFun bind (Object d, Object c) throw DuplicateException, ClassCastException // REQUIRES: d deve essere un sottotipo di // Comparable. // EFFECTS: restituisce una funzione diversa // da this solo perché definita anche per d e // applicata a d restituisce c. Se this è // già definita per d, solleva // DuplicateException; se d e c non sono dello // stesso tipo di dominio e codominio solleva // ClassCastException. Gli elementi di d sono // mantenuti in ordine crescente // rispetto allordinamento.
SubPolyFun, copy // metodi extra public SubPolyFun copy ( ) // EFFECTS: restituisce una copia della // funzione this
SubPolyFun, update public void update (Comparable d, Object c) throws ClassCastException, UndefinedException // MODIFIES: this // EFFECTS: modifica this così da // restituire il valore c, // se applicata a d ; se c non è dello // stesso tipo del codominio di this solleva // ClassCastException, se this non è // definita per d solleva UndefinedException.