Proofs: Event queue
These are the human proofs of Event queue, at full length.
The event queue keeps one entry per point and pops the smallest point with all its payloads full
This proof shows: correctness.
We use the pseudocode of the page. The queue has a binary heap (an array with the heap order on the sweep order , a total order on points) and a map from points to lists of payloads. The abstract state of the queue is a finite set of points and, for each , a list . The empty queue has .
The abstract operations are defined as follows. INSERT sets ; if was not in it sets ; then, if NIL, it appends to . POP-MIN, for , returns with and sets . CONTAINS returns whether , and IS-EMPTY returns whether .
Invariant. The concrete state represents when:
(R1) the entries of are pairwise distinct, and the set of entries of equals the set of keys of , which equals ;
(R2) has the heap order: for each index , ;
(R3) for each .
Claim. If the queue starts empty, then after each sequence of operations (R1) to (R3) hold for the abstract state reached by the same sequence, and each operation returns the abstract result.
Proof. By induction on the number of operations.
Base. The empty queue has empty and empty. Both sets are , so (R1) holds; (R2) holds with no index ; (R3) holds with no .
Step. Assume (R1) to (R3) hold before an operation. We show that they hold after it, for the new abstract state, and that the result is right.
- INSERT, case . By (R1), is a key of , so line L1 is true. Line L2 appends to when NIL, which is what the abstract INSERT does to . and the set of keys of do not change, and the abstract does not change, so (R1) and (R2) hold. (R3) holds for by the above and for the other points because nothing else changed.
- INSERT, case . By (R1), is not a key of and not an entry of , so line L1 is false. Line L3 makes a key with the list , or if $a = $ NIL, which is the new . Line L4 adds to . The entries of stay pairwise distinct because was not one of them, and the sets of entries and of keys both become , so (R1) holds. HEAP-INSERT restores the heap order (R2); this is the standard property of the sift-up of a binary heap (CLRS, Section 6.5). (R3) holds as in the first case.
- POP-MIN, with . By (R1), is not empty. By (R2) and the transitivity of , each entry is at least the root, because the path from the root to it is non-decreasing. So the root is of the entries of , which by (R1) is , and line L5 returns this and leaves a heap of the other entries in heap order (the sift-down of CLRS, Section 6.2 and 6.5). Since the entries were distinct, no longer occurs in . Line L6 reads by (R3) and removes the key . Both sets are now , so (R1) and (R2) hold, (R3) holds for the remaining points, and line L7 returns as required.
- CONTAINS. Line L8 returns whether is a key of , which by (R1) is whether . Nothing changes.
- IS-EMPTY. Line L9 returns whether is empty, which by (R1) is whether . Nothing changes.
So the invariant holds after each operation, and each result equals the abstract result.
Consequence for a sweep. Let a sweep insert only points that are larger than the last popped point. Then the sequence of popped points is strictly increasing. Let be a popped point and the next one. Just after the pop of , each point of is larger than , because was the minimum of a set of distinct points and was removed. Each point inserted after that is larger than by the rule. So at the next pop. A popped point is then never inserted again, since each later insert is larger than it. So each event point is popped exactly once, with the payloads of all the inserts of that point.