Proofs: Funnelsort
These are the human proofs of Funnelsort, at full length.
Funnelsort returns the stable sort of its input full
This proof shows: correctness.
We use the line numbers of the pseudocode. For a sequence , write for its stable sort. For sorted sequences , the stable merge is : the items in non-decreasing order, and equal items in the order of and of their positions. The cache bound is not proved here; see the cache-oblivious model page.
The funnel
For an inner node of a funnel, let be the sequence of all items that line L9 appends to the buffer of , over all calls of FILL, in order. For a leaf , let be its input, which is sorted. Let be the leaves below , from left to right.
Lemma 1. Each call FILL ends. At any time, the items that has appended form a prefix of . When is marked exhausted, this prefix is all of .
Proof. By induction on the height of . A leaf is exhausted from the start, and its buffer holds its whole sorted input, so the claim holds.
Let be an inner node with children and , and let of the leaves below and the same for . By induction, the items that has appended form a prefix of , and its buffer holds the part of this prefix that has not yet taken, in order. So at each moment, the items that has taken from are a prefix of , and the head of the buffer of , if any, is the next item of .
Termination. Each pass of the loop of line L6 either returns at line L8 or moves one item at line L9. The number of items is finite, and each inner call of line L7 ends by induction, so FILL ends.
Prefix. Line L7 fills each child buffer that is empty and whose child is not exhausted. By induction, a call FILL ends with a full buffer or with exhausted. If it ends exhausted with an empty buffer, then has taken all of . So after line L7, for each , either the buffer of holds the next item of , or has taken all of . Line L9 then appends the smaller of the two next items, or the left one on ties, or the only one. This is exactly the next step of the stable merge of and , because and are sorted and every item of comes before the equal items of in . And , because the leaves below are and those below are for some .
Exhaustion. Line L8 marks exhausted only when both child buffers are empty after line L7. By the argument above, has then taken all of and all of , so it has appended all of .
Lemma 2. In line L4, FILL(root) leaves in the root buffer the sequence , where are the sorted parts from left to right.
Proof. The empty leaves that round up to a power of 2 add no items. The root buffer holds items, the number of all items. By Lemma 1, the loop of line L6 appends a prefix of , and it stops when the buffer is full, which is after all items, or when the root is exhausted, which by Lemma 1 is also after all items. Nothing removes items from the root buffer.
The sort
Theorem. FUNNELSORT leaves in .
Proof. By strong induction on . If , line L1 uses insertion sort, which is stable. Else, and each part of line L2 has at most items, so by induction line L3 replaces the part by . The parts are consecutive, so : an item of comes before an equal item of in exactly when . By Lemma 2, line L4 computes this sequence, and line L5 writes it to .