Abstract variable An abstract variable may be regarded as the simplest non-trivial ADT, with the semantics of an imperative variable. It admits two operations, and . Operational definitions are often written in terms of abstract variables. In the axiomatic semantics, letting V be the type of the abstract variable and X be the type of its contents, is a function V \to X and is a function of type V \times X \to V. The main constraint is that always returns the value
x used in the most recent operation on the same variable
V, i.e. . We may also require that overwrites the value fully, . In the operational semantics, (
V) is a procedure that returns the current value in the location
V, and (
V,
x) is a procedure with return type that stores the value
x in the location
V. The constraints are described informally as that reads are consistent with writes. As in many programming languages, the operation (
V,
x) is often written
V ←
x (or some similar notation), and (
V) is implied whenever a variable
V is used in a context where a value is required. Thus, for example,
V ←
V + 1 is commonly understood to be a shorthand for (
V,(
V) + 1). In this definition, it is implicitly assumed that names are always distinct: storing a value into a variable
U has no effect on the state of a distinct variable
V. To make this assumption explicit, one could add the constraint that: • if
U and
V are distinct variables, the sequence { (
U,
x); (
V,
y) } is equivalent to { (
V,
y); (
U,
x) }. This definition does not say anything about the result of evaluating (
V) when
V is
un-initialized, that is, before performing any operation on
V. Fetching before storing can be disallowed, defined to have a certain result, or left unspecified. There are some algorithms whose efficiency depends on the assumption that such a is legal, and returns some arbitrary value in the variable's range.
Abstract stack An abstract
stack is a last-in-first-out structure, It is generally defined by three key operations: , that inserts a data item onto the stack; , that removes a data item from it; and or , that accesses a data item on top of the stack without removal. A complete abstract stack definition includes also a
Boolean-valued function (
S) and a () operation that returns an initial stack instance. In the axiomatic semantics, letting S be the type of stack states and X be the type of values contained in the stack, these could have the types push : S \to X \to S, pop : S \to (S,X), top : S \to X, create : S, and empty : S \to \mathbb{B}. In the axiomatic semantics, creating the initial stack is a "trivial" operation, and always returns the same distinguished state. Therefore, it is often designated by a special symbol like
Λ or "()". The operation predicate can then be written simply as s = \Lambda or s \neq \Lambda. The constraints are then , , () = T (a newly created stack is empty), ((
S,
x)) = F (pushing something into a stack makes it non-empty). These axioms do not define the effect of (
s) or (
s), unless
s is a stack state returned by a . Since leaves the stack non-empty, those two operations can be defined to be invalid when
s = Λ. From these axioms (and the lack of side effects), it can be deduced that (Λ,
x) ≠ Λ. Also, (
s,
x) = (
t,
y)
if and only if x =
y and
s =
t. As in some other branches of mathematics, it is customary to assume also that the stack states are only those whose existence can be proved from the axioms in a finite number of steps. In this case, it means that every stack is a
finite sequence of values, that becomes the empty stack (Λ) after a finite number of s. By themselves, the axioms above do not exclude the existence of infinite stacks (that can be ped forever, each time yielding a different state) or circular stacks (that return to the same state after a finite number of s). In particular, they do not exclude states
s such that (
s) =
s or (
s,
x) =
s for some
x. However, since one cannot obtain such stack states from the initial stack state with the given operations, they are assumed "not to exist". In the operational definition of an abstract stack, (
S,
x) returns nothing and (
S) yields the value as the result but not the new state of the stack. There is then the constraint that, for any value
x and any abstract variable
V, the sequence of operations { (
S,
x);
V ← (
S) } is equivalent to
V ←
x. Since the assignment
V ←
x, by definition, cannot change the state of
S, this condition implies that
V ← (
S) restores
S to the state it had before the (
S,
x). From this condition and from the properties of abstract variables, it follows, for example, that the sequence: : { (
S,
x); (
S,
y);
U ← (
S); (
S,
z);
V ← (
S);
W ← (
S) } where
x,
y, and
z are any values, and
U,
V,
W are pairwise distinct variables, is equivalent to: : {
U ←
y;
V ←
z;
W ←
x } Unlike the axiomatic semantics, the operational semantics can suffer from aliasing. Here it is implicitly assumed that operations on a stack instance do not modify the state of any other ADT instance, including other stacks; that is: • For any values
x,
y, and any distinct stacks
S and
T, the sequence { (
S,
x); (
T,
y) } is equivalent to { (
T,
y); (
S,
x) }.
Boom hierarchy A more involved example is the Boom hierarchy of the
binary tree,
list,
bag and
set abstract data types. All these data types can be declared by three operations:
null, which constructs the empty container,
single, which constructs a container from a single element and
append, which combines two containers of the same type. The complete specification for the four data types can then be given by successively adding the following rules over these operations: : Access to the data can be specified by pattern-matching over the three operations, e.g. a
member function for these containers by: : Care must be taken to ensure that the function is invariant under the relevant rules for the data type. Within each of the equivalence classes implied by the chosen subset of equations, it has to yield the same result for all of its members.
Common ADTs Some common ADTs, which have proved useful in a great variety of applications, are •
Collection •
Container •
List •
String •
Set •
Multiset •
Map •
Multimap •
Graph •
Tree •
Stack •
Queue •
Priority queue •
Double-ended queue •
Double-ended priority queue Each of these ADTs may be defined in many ways and variants, not necessarily equivalent. For example, an abstract stack may or may not have a operation that tells how many items have been pushed and not yet popped. This choice makes a difference not only for its clients but also for the implementation. ; Abstract graphical data type An extension of ADT for computer graphics was proposed in 1979: an
abstract graphical data type (AGDT). It was introduced by
Nadia Magnenat Thalmann, and
Daniel Thalmann. AGDTs provide the advantages of ADTs with facilities to build graphical objects in a structured way. ==Implementation==