Proofs: R-tree
These are the human proofs of R-tree, at full length.
The R-tree operations keep the invariant, and search reports exactly the rectangles that meet the query full
This proof shows: correctness, termination.
We use the names of the pseudocode. A rectangle is closed. For a node let be the set of leaf entries in the subtree of . The invariant (R) says: (1) all leaves are at one depth; (2) each non-root node has between and entries, and an internal root has between 2 and ; (3) the rectangle of each internal entry is .
Lemma 1 (containment). Under (R) part 3, for each internal entry and each leaf entry in , . Proof. By induction on the height of . If is a leaf, is the rectangle of an entry of , and contains it. If is internal, is below some entry of ; by induction , and .
SEARCH. Each reported entry is a leaf entry whose rectangle meets (lines L1 and L2). Each node is reached by one path from the root, so no entry is reported twice. Conversely, let be stored with , and let be the internal entries on the path from the root to its leaf. By Lemma 1, , so for each . By induction on , line L3 enters : the root is reached, and if the node holding is reached, the test of line L1 passes. In the leaf, line L1 passes for and line L2 reports it. The tree is finite and each node is entered once, so SEARCH stops.
Lemma 2 (split). The quadratic split of entries returns two disjoint groups whose union is the input, each with at least entries. Proof. Each step moves one entry from the rest to a group, so the groups stay disjoint and the union is kept. Each group starts with one seed. Before each step, if a group has , all of the rest goes to , which then has entries. Otherwise both groups satisfy , and one entry is moved, which lowers by at most 1 for each group, so both sums stay at least . When the rest is empty, each group has . At the start , so the induction starts. The other group has at least entries because .
INSERT. Assume (R) holds before the call, and let be the height. CHOOSE-LEAF follows one entry per level to a leaf (lines L4 and L5), and line L6 adds the new entry. Only the nodes on the path from to the root can now break (R): may hold entries, and the rectangles on the path may no longer be MBRs.
Claim: at the start of each pass of line L7 with node at height , (R) holds at every node except that may have entries and the rectangles of the entries for and its ancestors may be wrong; all rectangles inside the subtree of are correct, and all leaves are at depth . This holds for the leaf. If has entries, line L8 splits them by Lemma 2 into and a new node of the same kind, each with to entries; the children moved to keep their subtrees, so all rectangles inside the subtrees of and stay correct, and the leaves below keep their depth. If is the root, line L10 makes a root with two correct entries for and ; the new root is internal with 2 entries, and every leaf is now at depth , so (R) holds everywhere and INSERT stops. Otherwise line L9 adds a correct entry for to the parent , so may hold entries. In both cases line L11 sets the rectangle of the entry for in to , so all rectangles inside the subtree of are correct, and the claim holds for at height . When line L7 passes the root, the root has at most entries and all rectangles are correct, so (R) holds. Each pass goes up one level, so INSERT stops after at most passes.
The same argument holds when INSERT is called by line L15 to put an entry at height : CHOOSE-LEAF stops at a node of height , the subtree of has height , so its leaves land at depth , and the rest of the claim is the same.
DELETE. By Lemma 1, the leaf that holds is below entries whose rectangles contain , so line L12 finds it if it is stored, and it answers false only when the entry is not stored. Line L13 removes the entry. CONDENSE-TREE (line L14) goes up the path from that leaf. At each non-root node on the path: if has fewer than entries, it is removed from its parent, and its subtree is kept in with its height; else the rectangle for in its parent is set to , which is correct, since the rectangles below are correct by induction from the leaf up. After line L14, each remaining node has a correct rectangle, each remaining non-root node has between and entries (the nodes on the path that kept at least were not underfull, and the other nodes did not change), and all remaining leaves are at depth . The root may now have only one entry, and if the root is a leaf it may have fewer.
Line L15 reinserts each entry of each node of at the height of that node. By the claim above, each such INSERT keeps parts 1 to 3, except for the possible root with one entry, which INSERT does not create but does not repair either. Each entry of a removed node goes back once, so the set of stored objects is the old set minus . Line L16 replaces an internal root with one entry by its child, which lowers every leaf depth by one and keeps parts 1 and 3; it stops because the height drops by one each time. After it, an internal root has at least 2 entries, and (R) holds.
Termination of DELETE. Line L12 visits each node at most once. Line L14 makes one step per level. Line L15 runs finitely many INSERTs, each of which stops. Line L16 runs at most times.