Proofs: R+-tree
These are the human proofs of R+-tree, at full length.
The R+-tree operations keep the partition invariant, stop, and search reports each rectangle that meets the query exactly once full
This proof shows: correctness, termination.
Regions are half-open, with and , where the ends may be infinite; stored rectangles and the query are closed and not empty. A closed rectangle meets a region if . We prove that the invariant (R+) holds after every operation, that every operation stops, and that SEARCH is correct.
Lemma 1 (cut of a region). For a region and a line with , the halves and are regions, disjoint, with union . A closed rectangle meets if and only if it meets or . The same holds for .
Proof. Each point of has or , not both. Since , .
Lemma 2 (CUT). Let satisfy parts (1) to (3) of (R+) in its subtree, for some set of rectangles: each leaf below holds the rectangles of that meet its region. Then CUT returns nodes and with regions and of Lemma 1, whose subtrees satisfy (1) to (3) for , with leaves at the depth of the leaves of relative to , and each with at most as many entries as .
Proof. By induction on the height of . A leaf (line L12) gives two leaves with regions and , each with the entries of that meet it. A rectangle of that meets meets , so it is in , and so it is in : part (2) holds. Each half keeps at most the entries of . For an internal node (line L13), a child with region goes left if , right if , and otherwise, since , is cut by induction into and with regions and . The regions of the children of partition , so the regions of the new children of partition , and the same for : part (1) holds. Parts (2) and (3) hold in each child by induction. The number of children of is the number of children of with , which is at most the number of children of .
Guillotine partitions. A partition of a region into regions is guillotine if it is , or if a line cuts into the halves and of Lemma 1 so that every part lies in or in , and the parts in each half form a guillotine partition of that half. We call the line the top cut.
Lemma 3 (guillotine facts). (a) If a guillotine partition of has parts, its top cut is at a side of a part, lies strictly inside , crosses no part, and has parts on its sides with . (b) The intersection of a guillotine partition of with a half given by any line strictly inside (parts that cross the line replaced by their two halves, parts outside dropped) is a guillotine partition of . (c) Replacing one part of a guillotine partition by a guillotine partition of that part gives a guillotine partition.
Proof. (a) The parts in cover , which is not empty, so at least one part lies on each side; a part in that touches the line has its upper side at the line. (b) By induction on the number of parts. If the top cut is parallel to the new line, or the new line misses one of its halves, the new line meets one or both halves, and we apply induction in each; otherwise the top cut, restricted to , is a cut of , and we apply induction to each half. In every case the result is built by cuts. (c) By induction on the cut tree: the replaced part is a leaf of the tree, and we hang the tree of its partition below that leaf.
Lemma 4 (children are guillotine). In every internal node, the regions of the children form a guillotine partition of the region of the node.
Proof. We show that every operation keeps this. A new root made at line L8 has as children the pieces of a SPLIT-ALL of a node of the same region, and SPLIT-ALL makes its pieces by cuts, so they form a guillotine partition. At line L7, a child is replaced by the pieces of its SPLIT-ALL, a guillotine partition of the child, which keeps the property by Lemma 3(c). A CUT of an internal node (line L13) gives to the children of intersected with , which is guillotine by Lemma 3(b); a child cut downward is itself an internal node or a leaf, and its own children are treated the same way, by induction. DELETE does not change regions.
Lemma 5 (SPLIT-ALL). Let satisfy (1) to (3) for . Then SPLIT-ALL stops and returns nodes whose regions partition the region of by cuts, each satisfying (1) to (3) for . Every internal node returned has at most children, and every leaf returned with more than entries has no good cut. With clean cuts only, on an internal node with children, it returns fewer than pieces, each with at most children.
Proof. A good cut found by CHOOSE-CUT (lines L10 and L11) has , where and count exactly the entries that go to each side by Lemma 2: the leaf entries with meet and those with meet , and the children with go left and with go right. So both pieces are strictly smaller than , and the recursion stops. By Lemmas 1 and 2, the pieces partition the region of and satisfy (1) to (3). A node is returned unchanged only if it has at most entries or no good cut. An internal node with more than children has a good cut, by Lemma 4 and Lemma 3(a), so it is never returned with more than children; a leaf with more than entries is returned only with no good cut. With clean cuts only, the internal nodes in the recursion stay guillotine by Lemma 3(b), so a clean good cut exists while a node has more than children, and every cut splits the children of a node into two groups with sizes summing to . The pieces are the leaves of a binary tree of cuts in which each cut node has more than children. The two pieces of the last cut on any branch have sizes summing to more than , so not every piece has one child, and the number of pieces is less than .
The nodes below a returned node keep their properties. A piece of an internal node made by a downward cut has at most as many children as the node, by Lemma 2, so at most . A piece of a leaf with no good cut also has no good cut: its region lies in that of , so every candidate line strictly inside the piece is a candidate for , and if all entries of reach one side of the line, so do all entries of the piece. A piece of a leaf with at most entries has at most . So part (4) holds in the whole tree after each SPLIT-ALL, given that it held before.
INSERT. Let (R+) hold for and insert . Claim: the call on a node returns nodes whose regions partition the region of by cuts, whose subtrees satisfy (R+) for , with leaves at the old depth. By induction on height. At a leaf, is added if and only if the walk reached it. The walk goes into every child whose region meets (line L5), and by part (1) the union of the regions of the children is the region of the parent, so the leaves reached are exactly those whose regions meet . So each leaf holds the rectangles of that meet it (line L6). At an internal node, each child that meets is replaced by the pieces of the recursive call, whose regions partition the region of the child; so the children still partition the region of . Then SPLIT-ALL (line L7) keeps (R+) by Lemma 5 and the remark after it. At the root, if pieces come back, line L8 makes a new root over them. Its region is the plane, the pieces partition it, and every leaf goes one level deeper, so (1) to (3) hold. If the loop ends. Otherwise SPLIT-ALL with clean cuts returns fewer than pieces, each with at most children, by Lemma 5 with Lemma 4. So the number of pieces strictly decreases from one pass of line L8 to the next, and the loop ends with one root, and (R+) holds for .
DELETE. The walk of line L14 reaches every leaf whose region meets , by the argument above, and those are exactly the leaves that hold by part (2). Removing from each gives part (2) for ; parts (1) and (3) do not change, and a smaller node still satisfies (4).
SEARCH. Let meet , and let . Since and are closed and meet, . By part (1), applied from the root down, exactly one leaf has in its region. Its region meets and at , so is stored in by part (2), and every ancestor of has a region that contains , so it meets and the search goes into it (line L2). At , line L3 sees , and line L4 finds in the region and reports . In every other leaf the search sees , is not in the region, since the leaf regions are disjoint, so is not reported there. A rectangle that does not meet is never reported, by the test of line L3. So the output is exactly the rectangles of that meet , each once.
Termination. SEARCH and DELETE visit each node at most once, since the tree is finite. INSERT stops by Lemma 5 and the argument for line L8.