"Abstraction of [[ordinal types|Ordinal]] 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`."
see (`class Range`, 
     `function span`, `function measure`)
shared interface Enumerable<Other> of Other
        satisfies Ordinal<Other>
        given Other satisfies Enumerable<Other> {
    
    "The indirect successor or predecessor at the given
     [[offset]], where:
     
     - `x.neighbour(0) == x`,
     - `x.neighbour(i+1) == x.neighbour(i).successor`, and
     - `x.neighbour(i-1) == x.neighbour(i).predecessor`."
    throws (`class OverflowException`, 
            "if the neighbour cannot be represented as an 
             instance of the type")
    since("1.1.0")
    shared formal Other neighbour(Integer offset);
    
    shared actual default Other successor => neighbour(1);
    shared actual default Other predecessor => neighbour(-1);
    
    "Compute the offset from the given value, where:
     
     - `x.offset(x) == 0`, and
     - `x.successor.offset(x) == 1` if `x!=x.successor`."
    throws (`class OverflowException`,
            "if the offset cannot be represented as an 
             integer")
    since("1.1.0")
    shared formal Integer offset(Other other);
    
    "The sign of the offset from the given value."
    since("1.1.0")
    shared default Integer offsetSign(Other other)
            => offset(other).sign;
    
}