Proofs: Interval tree search
These are the human proofs of Interval tree search, at full length.
Interval tree search reports exactly the matches and expands at most (k + 1) h nodes full
This proof shows: correctness, termination.
We use the pseudocode of the page. is a binary search tree of intervals whose in-order sequence is sorted by left end, so every interval in the left subtree of a node has and every interval in its right subtree has . Each node has equal to the largest right end in its subtree, and . The test is upward closed, so and give ; the test is downward closed, so and give . An interval matches when and . The height is the number of nodes on a longest root-to-leaf path.
Lemma 1 (pruning by max). If fails, no interval below matches.
Proof. Each right end below has . If held, upward closure would give .
Lemma 2 (pruning by order). If fails, then and every interval of its right subtree fail .
Proof. Each such interval has . If held, downward closure would give .
Theorem 1 (REPORT). REPORT appends exactly the matching intervals below , each once, in in-order, and terminates.
Proof. By induction on the number of nodes below . Each call either returns at line L1 or makes calls only on the two children, which have fewer nodes, so the recursion terminates. If nothing is appended, which is right. If line L1 returns because fails, nothing matches below by Lemma 1. Otherwise line L2 appends the matches of the left subtree, by induction. If line L3 returns, then and its right subtree have no match by Lemma 2. Otherwise holds, so matches if and only if , the test of line L4, and line L5 appends the matches of the right subtree by induction. The left subtree, and the right subtree are disjoint and appended in in-order.
Theorem 2 (SEARCH). SEARCH returns a matching interval if one exists and nil otherwise, after at most passes of the loop.
Proof. Invariant: if some interval of matches, then one lies in the subtree of , where the subtree of nil is empty. It holds with the root. Suppose it holds and the loop body runs, so does not match.
Line L8 goes left. Then holds, so the left subtree has an interval with and . If no interval of the left subtree matches, this one fails . Then and the intervals of the right subtree have and fail by downward closure, so nothing below matches; by the invariant nothing in matches, and the invariant holds for the left child. If some interval of the left subtree matches, it holds as well.
Line L8 goes right. Then the left subtree is empty or fails, and by Lemma 1 nothing in it matches; does not match. So any match below is in the right subtree.
Each pass moves one level down, so there are at most passes. If the loop stops at a node, the test of line L7 says that it matches. If it stops at nil, the invariant says that nothing matches.
Theorem 3 (cost of REPORT). Suppose REPORT outputs intervals. Call a node expanded if a call on it passes line L1. Then at most nodes are expanded, and at most calls are made.
Proof. Let be the first node in in-order whose interval fails , if there is one. Since is downward closed and the in-order sequence is sorted by left end, the nodes that pass are exactly the nodes before in in-order, a prefix.
Let be expanded. Then holds, so some node below , possibly itself, has .
Case 1: holds. Then matches. By Theorem 1 applied to the call on , is output, so is an ancestor of an output, or the output itself.
Case 2: fails. Then exists, and is or comes before in in-order. We show that lies below . The nodes below form a contiguous block of the in-order sequence, and is in it. If is on the leftmost path from the root, the block is a prefix of the in-order sequence, and it contains , which is at or before . Otherwise let be the lowest ancestor of such that is in the right subtree of . Then is the node just before the block in in-order. The call on the right child of was made at line L5, so line L3 passed at , and holds. So is before , and , which is at or before , is after : it lies in the block. In both cases is an ancestor of or itself.
Each node has at most ancestors including itself. So at most nodes fall in Case 1 and at most in Case 2, which gives at most expanded nodes. No node is called twice, so at most are expanded. Each call is the root call or is made by an expanded node, which makes at most two calls, so there are at most calls, and each call does work besides its calls.