Abstract data type

from Wikipedia, the free encyclopedia

An Abstract Data Type ( ADT ) is a group of data together with the definition of all permitted operations that access them.

description

Since access is only possible via the specified operations, the data is encapsulated from the outside .

An ADT describes what the operations do (semantics), but not yet how they should do it (implementation). The concept of the ADT can also be specified differently and an ADT can be noted in different ways, for example using pseudocode or a mathematical description. However, more modern programming languages ​​specifically support the creation of ADTs.

Object-oriented programming languages support the creation of ADTs through their class concept, since data and operations are linked here, the data can be protected and the permitted operations can be specified. Some modular programming languages such as Ada or Modula-2 also specifically support the creation of ADTs. Usually it is possible to define an ADT by defining the data and the signatures of the operations, while the semantics are described as comment text.

example
Java supports ADTs through classes, abstract classes and interfaces . Only data and signatures of the operations are defined in an interface, a defined class implements the interface first. In general, a class defines the data and the operations permitted on it.


Specifications

An abstract data type can be indicated by different specifications. A specification consists of a signature and semantics that define the meaning and interaction of the operations.

From a mathematical point of view, it is the specification of a term algebra through signature , generator and axioms. This results in the first type of specification, the mathematical-axiomatic.

Another possibility is the mathematical-algebraic specification, which differs from the axiomatic specification only in the specification of the semantics. The meaning of the content of the operations is defined by mathematical means, matrices, vectors, sequences, etc.

In addition, there are special forms, such as the informal method of specification - by specifying an interface of a programming language, for example as a Java interface or the implementation of the data type in a functional programming language such as Haskell  - which is initially contradicting the attempt to make the data type independent of a To make implementation. The implementation in a functional programming language, however, serves as a specification for ADTs, which are ultimately implemented in procedural or object-oriented languages. The advantage of this specification is that it can be tested immediately whether the specification makes sense, which is not easily possible with the other options, especially the axiomatic ones.

example

In the following, the ADTs stack storage ( stack , works according to the last-in-first-out principle) and queue ( queue , works according to the first-in-first-out principle) are defined in the four specifications mentioned.

signature

Mathematical-axiomatic and -algebraic method

STACK (wird hier definiert)
ELEMENT (ein hier nicht definierter ADT, mit dem der Stack arbeitet)
BOOL
emptyStack: → STACK (erzeugt einen leeren Stack)
isStackEmpty: STACK → BOOL (fragt nach, ob der Stack leer ist)
push: ELEMENT × STACK → STACK (packt ein Element oben auf den Stack)
pop: STACK → STACK (entfernt das oberste Element und gibt den neuen Stack zurück)
top: STACK → ELEMENT (gibt das oberste Element zurück, ohne es zu entfernen)
QUEUE
ELEMENT
BOOL
emptyQueue: → QUEUE
isQueueEmpty: QUEUE → BOOL
enqueue: ELEMENT × QUEUE → QUEUE (fügt ein Element hinten an)
dequeue: QUEUE → QUEUE (entfernt das vorderste Element)
head: QUEUE → ELEMENT (gibt das vorderste Element zurück, ohne es zu entfernen)

Informal method (Java)

public interface IStack<E> {

    public boolean isStackEmpty();
    public IStack<E> push(E elem);
    public IStack<E> pop();
    public E top();
}

public interface IQueue<E> {

    public boolean isQueueEmpty();
    public IQueue<E> enqueue(E elem);
    public IQueue<E> dequeue();
    public E head();
}

Specification by a functional programming language (Haskell)

data Stack e = E | S e (Stack e)
isStackEmpty :: Stack a  Bool
push :: e  Stack e  Stack e
pop :: Stack e  Stack e
top :: Stack e  e

data Queue e = E | Q (Queue e) e
isQueueEmpty :: Queue e  Bool
enqueue :: e  Queue e  Queue e
dequeue :: Queue e  Queue e
head :: Queue e  e

semantics

Even with a closer look at the (identical) signatures, no differences between the data types can be seen. Only when the semantics are defined do differences arise.

Mathematical-axiomatic method

 x: ELEMENT
 s: STACK
 isStackEmpty(emptyStack()) = TRUE
 isStackEmpty(push(x,s)) = FALSE
 pop(emptyStack()) = ERROR
 pop(push(x,s)) = s
 top(emptyStack()) = ERROR
 top(push(x,s)) = x
 push(top(s),pop(s)) = s, falls s nicht leer
 x: ELEMENT
 q: QUEUE
 isQueueEmpty(emptyQueue()) = TRUE
 isQueueEmpty(enqueue(x,q)) = FALSE
 head(emptyQueue()) = ERROR
 head(enqueue(x,q)) = IF isQueueEmpty(q) THEN x ELSE head(q)
 dequeue(emptyQueue()) = ERROR
 dequeue(enqueue(x,q)) = IF isQueueEmpty(q) THEN q ELSE enqueue(x, dequeue(q))

Mathematical-algebraic method

SETS ELEMENT = E (Menge der Elemente) 
     STACK = S = 
FUNCTIONS
    emptyStack      = 
    isStackEmpty(S) = 
    push(S,x)       = , falls 
                    = , falls 
    top(S)          = , falls 
                    = , falls 
    pop(S)          = , falls 
                    = , falls 
                    = , falls 
SETS ELEMENT = E (Menge der Elemente) 
     QUEUE = Q = 
FUNCTIONS
    emptyQueue      = 
    isQueueEmpty(Q) = 
    enqueue(Q,x)    = , falls 
                    = , falls 
    head(Q)         = , falls 
                    = , falls 
    dequeue(Q)      = , falls 
                    = , falls 
                    = , falls 

Informal method (Java)

Semantics: by specifying the prerequisite and effect / result of the method (with object-oriented programming there is usually no need to state the existence of the data structure as a prerequisite, since the method is linked to an object that already exists).

public interface IStack<E> {
    // Konstruktor in der konkreten Klasse

    // Ergebnis: true, wenn der Stack leer ist, false andernfalls
    public boolean isStackEmpty();

    // Effekt: Der Stack enthält das Element elem als oberstes Element.
    // Ergebnis: Der Stack nach dem Einfügen des Elements elem.
    public IStack<E> push(E elem);

    // Voraussetzung: Der Stack ist nicht leer.
    // Effekt: Das oberste Element wird vom Stack gelöscht.
    // Ergebnis: Der Stack nach dem Löschen.
    public IStack<E> pop();

    // Voraussetzung: Der Stack ist nicht leer.
    // Ergebnis: Das oberste Element.
    public E top();
}
public interface IQueue<E> {
    public boolean isQueueEmpty();
    public IQueue<E> enqueue(E elem);
    public IQueue<E> dequeue();
    public E head();
}

Specification by a functional programming language (Haskell)

emptyStack = E
isStackEmpty E = True
isStackEmpty (S x xs) = False
push e xs = S e xs
pop (S x xs) = xs
top (S x xs) = x

emptyQueue = E
isQueueEmpty E = True
isQueueEmpty (Q xs x) = False
enqueue e xs = Q xs e
dequeue E = E
dequeue (Q (E) x) = E
dequeue (Q (Q ys y) x) = enqueue x (dequeue (Q ys y))
head E = error "Queue ist leer."
head (Q (E) x) = x
head (Q (Q ys y) x) = head (Q ys y)

Desired properties

The desired properties of a well-programmed ADT and usually a well-specified data structure are:

  • Universality (implementation independence): Once the ADT has been designed and implemented, it can be included and used in any program (e.g. in the form of a unit ).
  • Precise specification: The interface between implementation and application must be clear and complete.
  • Simplicity : In the application, the inner realization of the ADT is of no interest, the ADT takes over its representation and administration in the memory itself.
  • Encapsulation : The interface should be seen as a hermetic boundary. The user should know exactly what an ADT is doing, but not how he is doing it.
  • Protection (integrity): The user cannot intervene in the internal structure of the data. This significantly reduces the risk of unintentionally deleting or changing data and of making programming errors.
  • Modularity : The modular principle allows clear and therefore safe programming and easy exchange of program parts. Individual modules can be viewed in isolation when troubleshooting . Many improvements can be subsequently adopted via ADTs in all environment or application programs without the slightest change.

If programming is object-oriented , these properties can be fulfilled particularly easily because the object-oriented paradigm naturally supports the creation of ADTs. Another possibility for creating ADTs (also in connection with object-oriented programming) are generic types .

literature

  • Barbara Liskov , Stephen Zilles: Programming with abstract data types . In: SIGPLAN Notices , Vol. 9, No. 4, 1974, pp. 50-59
  • John Guttag : Abstract Data Types and the Development of Data Structures . In: Communications of the ACM , Vol. 20, 1977, No. 6, pp. 396-404.
  • JA Goguen, JW Thatcher, EW Wagner: An Initial Algebra Approach to the Specification, Correctness and Implementation of Abstract Data Types . In: RT Yeh (Ed.): Current Trends on Programming Methodology , Vol. IV, 1978, Prentice-Hall Int.
  • Hartmut Ehrig, Bernd Mahr: Fundamentals of Algebraic Specification 1 - Equations and Initial Semantics . Springer-Verlag, 1985
  • Luca Cardelli, Peter Wegner: On Understanding Types, Data Abstraction, and Polymorphism . In: Computing Surveys , Vol. 17, No. 4, December 1985, pp. 470-522
  • John C. Mitchell, Gordon D. Plotkin: Abstract Data Types Have Existential Type . In: ACM Transaction on Programming Languages ​​ans Systems , Vol. 10, No. 3, July 1988, pp. 470-502.
  • Peter Müller: Introduction to Object-Oriented Programming Using C ++ . Chapter on ADT
  • Jorge Martinez: Ordered algebraic structures: proceedings of the Gainesville conference sponsored by the University of Florida 28th February-3rd Marchf, 200 . Kluwer Academic Publishers, Dordrecht; Boston 2002, ISBN 978-1-4020-0752-1 ( limited preview in Google Book Search [accessed July 5, 2010]).
  • Rolke, Sennholz: Basic and advanced course in computer science . Cornelsen, Düsseldorf 1992, ISBN 3-464-57312-5 .