# The module

    <*PRAGMA LL*>

The Split interface provides the functionality that is common to all splits; for example, enumerating and deleting children.

This interface is for clients of splits; see the `VBTClass` and `ProperSplit` interfaces for information about implementing your own split classes.

    INTERFACE Split;

    IMPORT VBT, Point;

    TYPE T = VBT.Split;

    EXCEPTION NotAChild;

A `Split.T` is a `VBT` that divides its screen up between one or more child `VBTs`. The children of a split are ordered; they can be enumerated with the `Succ` and `Pred` procedures:

    PROCEDURE Succ(v: T; ch: VBT.T): VBT.T
    RAISES {NotAChild}; <* LL >= {VBT.mu} *>

Return the child of `v` that follows the child `ch`.

The successor of `NIL` is the first child; the successor of the last child is `NIL`; the successor of `NIL` is `NIL` if there are no children. The exception `NotAChild` is raised if `ch` is not a child of `v`.

    PROCEDURE Pred(v: T; ch: VBT.T): VBT.T
    RAISES {NotAChild}; <* LL >= {VBT.mu} *>

Return the child of `v` that precedes the child `ch`.

More precisely, `Pred(v,ch) = x` iff `Succ(v,x) = ch`. All of Trestle's standard splits implement `Succ` and `Pred` in constant time.

    PROCEDURE NumChildren(v: T): CARDINAL;
    <* LL >= {VBT.mu} *>

Return the number of children of `v`.

    PROCEDURE Nth(v: T; n: CARDINAL): VBT.T;
    <* LL >= {VBT.mu} *>

Return the child of `v` with index `n`.

More precisely, `Nth(v, n)` is the child of `v` with `n` predecessors, or `NIL` if `v` has at most `n` children. Warning: for Trestle's standard splits, `Nth` requires time proportional to `n`, so it would be wasteful to enumerate the children by calling it repeatedly; use `Succ` instead.

    PROCEDURE Index(v: T; ch: VBT.T): CARDINAL
    RAISES {NotAChild}; <* LL >= {VBT.mu} *>

Return the index of `v`'s child `ch`.

`Index(v, ch)` is the value `n` such that `Nth(v, n) = ch`. `Index(v, NIL)` equals `NumChildren(v)`.

    PROCEDURE Locate(v: T; READONLY pt: Point.T): VBT.T;
    <* LL.sup = VBT.mu *>

Return the child of `v` that controls the point `pt`, or `NIL` if there is no such child.

    PROCEDURE Delete(v: T; ch: VBT.T) RAISES {NotAChild};
    <* LL.sup = VBT.mu *>

Delete the child `ch` of the split `v`, detach `ch`, and mark `v` for redisplay.

    PROCEDURE Replace(v: T; ch, new: VBT.T)
    RAISES {NotAChild}; <* LL.sup = VBT.mu *>

Replace child `ch` of `v` with `new`, detach `ch` (which must not be `NIL`), and mark `v` for redisplay.

    PROCEDURE Insert(v: T; pred, new: VBT.T)
    RAISES {NotAChild}; <* LL.sup = VBT.mu *>

Add `new` as a child of `v` following `pred`.

Some split classes can accomodate only a bounded number of children (for example, filters). If `Insert(v, pred, new)` is applied to a split `v` that cannot accomodate an additional child, then `pred` (or the original first child, if `pred = NIL`) is deleted from the split and discarded. The precise semantics are defined by the individual splits. `Insert` raises `NotAChild` if `pred` isn't a child of `v`, and is a checked run-time error if `new` isn't detached.

    PROCEDURE Move(v: T; pred, ch: VBT.T)
    RAISES {NotAChild}; <* LL.sup = VBT.mu *>

Move child `ch` of `v` to follow `pred`. Both `ch` and (if non-`NIL`) `pred` must be children of `v`.

    PROCEDURE AddChildArray(v: T;
      READONLY new: ARRAY OF VBT.T);
    <* LL.sup = VBT.mu *>

Insert the non-`NIL` elements of `new` at the end of the `v`'s list of children.

`AddChildArray` is equivalent to

      pred := Pred(v, NIL);
      FOR i := 0 TO LAST(new) DO
        IF new[i] # NIL THEN
          InsertAfter(v, pred, new[i]);
          pred := new[i]
        END
      END

    PROCEDURE AddChild(v: T;
      v0, v1, v2, v3, v4, v5, v6, v7, v8, v9: VBT.T := NIL);
    <* LL.sup = VBT.mu *>

Add the given children to `v`.

`AddChild` is equivalent to

      AddChildArray(v,
        ARRAY OF VBT.T{v0, v1, ..., v9})

    END Split.