| 
cs205: engineering software? | 
(none) 20 September 2010  | 
cs205 Data Abstraction Notes
(Friday 8 September - Monday 11 September)
What are the advantages and disadvantages of using abstract data types?
What are the minimal operations a (useful) data abstraction must provide?
Is it reasonable for a datatype to have no creators?
Is it reasonable for a datatype to have no observers?
public class SetWhat missing operations are needed for an adequate Set datatype?{ OVERVIEW: A Set is a mutable, unbounded set of objects of type T. A typical Set is {x_1, ..., x_n }. public Set() EFFECTS: Initializes this to an empty set: { }. public boolean add(T el) MODIFIES: this EFFECTS: Adds el to the elements of this: thispost = thispre U { el } Returns true iff el was not an element of thispre. public boolean contains(T el) EFFECTS: public void union(Set<T> t) 
Is it necessary to provide union?   
The Abstraction Function maps a concrete state to an abstract state:
AF: C → AIt is a function from concrete representation to the abstract notation introduced in overview specification.
   // AF (c) = { AFT (c.els[i]) | 0 <= i < c.els.size () }
Representation Invariant
The Representation Invariant expresses properties all legitimate objects of the ADT must satisfy. It is a function from concrete representation to boolean:
I: C → boolean
To check correctness we assume all objects passed in to a procedure satisfy the invariant and prove all objects satisfy the invariant before leaving the implementation code.
public class Set<T> {
   // OVERVIEW: A Set is a mutable, unbounded set of objects of type T.  
   //      A typical Set is {x_1, ..., x_n }.
   // Representation:
   private Vector<T> rep;
   // RepInvariant (c) = c.rep contains no duplicates && c.rep != null
   //                    && all elements of c.rep are of non-null 
If we instead used RepInvariant (c) = true which operations would be
easier to implement correctly?  Which would be harder? 
Where can an implementer of a datatype assume the rep invariant is true?
Where must an implementer of a datatype ensure the rep invariant is true?
public class Graph {
   // OVERVIEW: 
   //      A Graph is a mutable type that represents an undirected
   //      graph.  It consists of nodes that are named by Strings,
   //      and edges that connect a pair of nodes.
   //      A typical Graph is: < Nodes, Edges >
   //       where
   //         Nodes = { n1, n2, , nm }
   //       and 
   //         Edges = { {a_1, b_1}, ..., {a_n, b_n} }
   //         (note that the elements of Edges are unordered sets)
   // Creator
   public Graph () 
      // EFFECTS: Initializes this to a graph
      //      with no nodes or edges: < {}, {} >.
   // Mutators
   public void addNode (String name) throws DuplicateException
      // MODIFIES: this
      // EFFECTS: If name is in Nodes, throws DuplicateException.
      //    Otherwise, adds a node named name to this:
      //     this_post = < Nodes_pre U { name }, Edges_pre >
   public void addEdge (String fnode, String tnode) throws
      NoNodeException, DuplicateException
      // MODIFIES: this
      // EFFECTS: If s and t are not names of nodes in
      //    this, throws NoNodeException.  If there is already an edge
      //    between s and t, throws DuplicateEdgeException.
      //    Otherwise, adds an edge between s and t to this:
      //      thispost = < Nodespre, Edgespre U {fnode, tnode} >
   // Observers
   public boolean hasNode (String node)
      // EFFECTS: Returns true iff node is a node in this.
   Set getNeighbors (String node)
      // REQUIRES: node is a node in this
      // EFFECTS: Returns the set consisting of all nodes in this
      //      that are directly connected to node:
      //         { n | {node, n} is in this.edges }
}