<*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.

INTERFACEASplit ; IMPORT VBT, Point; TYPE T = VBT.Split; EXCEPTION NotAChild;

`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} *>

The successor ofReturn the child of`v`

that follows the child`ch`

.

`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} *>

More precisely,Return the child of`v`

that precedes the child`ch`

.

`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} *>

More precisely,Return the child of`v`

with index`n`

.

`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 *>

Some split classes can accomodate only a bounded number of children (for example, filters). IfAdd`new`

as a child of`v`

following`pred`

.

`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 ENDPROCEDURE 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 toAddChildArray(v, ARRAY OF VBT.T{v0, v1, ..., v9})END Split.