Abstraction of ordinal types whose values may be used as endpoints of a span() or measure().

An Enumerable type is characterized by each element having well-defined offset and neighbour() functions. Given an instance x of an enumerable type X:

• for any integer-valued offset, there is a unique neighbour y of X with that offset, and
• if y is an instance of X, then there is a well-defined integer-valued offset of x from y.

The offset function must satisfy:

• x.offset(x) == 0, and
• x.successor.offset(x) == 1 if x!=x.successor.

The neighbour function must satisfy:

• x.neighbour(0) == x,
• x.neighbour(n-1) == x.neighbour(n).predecessor, and
• x.neighbour(n+1) == x.neighbour(n).successor.

Of course, it follows that:

• x.neighbour(-1) == x.predecessor, and
• x.neighbour(1) == x.successor.

An enumerable type may be linear or recursive. If X is a linear enumerable type, then the offset function satisfies:

• x.predecessor.offset(x) == -1 if x!=x.predecessor,
• x.offset(y) == -y.offset(x) for any instance y of X, and
• x.offset(y) == x.offset(z) + z.offset(y).

Otherwise, X is a recursive enumerable type with a finite list of enumerated instances of size count, and its offset and neighbour functions must satisfy:

• x.neighbour(count)==x,
• x.offset(y) >= 0 for any instance y of X, and
• x.predecessor.offset(x) == count - 1.

A range of values of an enumerable type may be specified using:

• the span operator, written first..last, or
• the segment operator, written first:length.