Proofs: X-tree
These are the human proofs of X-tree, at full length.
The X-tree operations keep the invariant, stop, and the searches return the right rectangles full
This proof shows: correctness, termination.
Let and . Heights count from the leaves: a leaf has height 0. The capacity of a leaf is , and of a directory node of blocks . For a node , let be the multiset of stored entries below and the rectangle kept at . We use the invariant (X): (1) all leaves at one depth; (2) every non-root node has at least entries and at most its capacity, and an internal root has at least 2 children and at most its capacity; leaves have one block; (3) is the MBR of the rectangles of the entries of , and so, by induction from the leaves, of the rectangles in .
Lemma 1 (recompute). If (3) holds at every child of , recomputing makes (3) hold at .
Proof. The MBR of a set is, axis by axis, the least lower end and the greatest upper end. For a union of sets, these are the least and the greatest over the parts, so the MBR of the children's rectangles is the MBR of .
Lemma 2 (split sizes). Let have entries, more than its capacity . If SPLIT returns two groups, they partition the entries, each has at least entries, and each fits in the blocks it is given. If it returns none, gains a block and then has capacity .
Proof. A topological split cuts a sorted list at with , where . The range is not empty: , and . An overlap-minimal split cuts at with and , if any such exists. So in both cases each group has at least entries. A new leaf gets one block and at most entries, since a leaf has . A directory group of entries gets blocks, whose capacity is at least . If no split is taken, which happens only at a directory node, had entries, since entries arrive one at a time and was within capacity before, so the new capacity .
Lemma 3 (INSERT). Let (X) hold and let be a stored entry (level 0) or a node of height whose subtree satisfies (X) inside, with at most the height of the tree. Then INSERT stops, and afterwards (X) holds for the old entries plus those of .
Proof. Lines L1 and L2 follow one child per level, from the root down to a node of height , in at most steps. Line L3 adds to , so the leaves of are at the same depth as the others. Line L4 walks from to the root, one level per step, so it stops. At each node on the walk, only one entry has been added since it was last within capacity: for , or the new sibling from a split of the child below. If it is over capacity, Lemma 2 applies. If two groups are made, and the new node have the same height and at least entries each, and either is added to the parent, the next node of the walk, or a new root with the two children and is made, which puts every leaf one level deeper and keeps (1). If no split is made, is a supernode within its new capacity and the parent gains nothing. Nodes off the walk keep their entries. So (1) and (2) hold at the end. For (3): the nodes whose entries change are those on the walk, the new nodes of splits, and a new root. Each is recomputed after its children are final: the groups of a split when they are made, the nodes of the walk at line L4, and the new root when it is made. By Lemma 1 and induction on height, (3) holds everywhere.
Lemma 4 (DELETE). Let (X) hold. DELETE stops, returns false if is not stored, and otherwise leaves (X) for the entries without it.
Proof. If is stored in a leaf , then by (3), for every node on the path to , so every such meets and the search of line L14 reaches ; it visits each node at most once, so it stops, and it reports the entry only if it is stored. Line L15 walks from to the root. A node with fewer than entries is removed from its parent, and its entries are kept with its height; a node that stays has at least entries, at most as many as before, and its blocks are set to , which keeps its capacity at least its size; it is recomputed by Lemma 1, the root last. Now (1) and (3) hold for the entries in the tree, and every non-root node satisfies (2). The root keeps an entry unless it was a leaf and is now empty, since a child of an internal root off the path is unchanged. Each kept entry came from a node of height below the root, so the tree still has height more than when it is reinserted, the height only growing during reinsertion, and Lemma 3 applies. Line L16 removes roots with one child, each step lowering every leaf by one level, which keeps (1) and gives an internal root at least 2 children. Every loop moves up a level or handles one of finitely many entries, so DELETE stops.
Theorem. SEARCH reports exactly the stored rectangles that meet . KNN returns entries in order of distance from , whose distances are the smallest. Both stop.
Proof. SEARCH. An entry is reported only if it meets . If a stored rectangle meets , then for every node above it, by (3), so every such meets , line L17 skips none of them, and the search reaches the leaf of and reports it. Each node is visited once, so the search stops.
KNN. A node has the key and an entry its distance . For every entry in , , so : the key of a node is a lower bound on the distances of the entries below it. When an entry is popped, every entry not yet output is in the queue, with key at least that of , or below a node in the queue, with , since the root starts the queue and every popped node pushes all its entries. So the entries come out in order of distance, each at most once, and the first are the nearest. Each node and entry is pushed once, so line L18 stops.