Example 0: Sum of [0..N).
/* Returns the sum of the natural numbers in range [0..n] ** pre: n≥0 */ public static int sumUpTo(int n) { if (n == 0) { return 0; } else { int prevSum = sumUpTo(n-1); // assert prevSum = 0 + 1 + ... + (n-1) return n + prevSum; } } |
Example 1: Selection Sort
/* Rearranges the elements of the given array ** so that they are in ascending order. */ public static void selectSort(int[] a) { selectSortAux(a, a.length); } /* Rearranges the elements of the given array ** segment (a[0..n)) so that they are ascending. ** so that they are in ascending order. */ private static void selectSortAux(int[] a, int n) { if (n > 1) { int locOfMax = locOfMax(a, n); // assert (∀i | 0 ≤ i < n : a[locOfMax] ≥ a[i]) swap(a, locOfMax, n-1); // assert (∀i | 0 ≤ i < n : a[n-1] ≥ a[i]) selectSortAux(a, n-1); // assert isAscending(a,n-1) ∧ (∀i | 0 ≤ i < n : a[n-1] ≥ a[i]); // therefore isAscending(a,n) } else { // assert isAscending(a,n) (vacuously) } } /* Returns k such that b[k] is the largest value ** in the array segment b[0..n). ** pre: n > 0 */ private static int locOfMax(int[] b, int n) { if (n == 1) { return 0; } else { int k = locOfMax(b, n-1); // assert (∀i | 0≤i<n-1 : b[k] ≥ b[i]) if (b[k] >= b[n-1]) { // assert (∀i | 0≤i<n-1 : b[k] ≥ b[i]) ∧ b[k] >= b[n-1]; // therefore, (∀i | 0≤i<n : b[k] ≥ b[i]) return k; } else { // assert b[n-1] > b[k] ∧ (∀i | 0≤i<n-1 : b[k] ≥ b[i]); // therefore, (∀i | 0≤i<n : b[n-1] ≥ b[i]) return n-1; } } } |
The predicate isRootOfMaxHeap(a,k,n) says that, within array a[], interpreted as a complete binary tree, the descendants of node k, up to but not including node n, form a max-heap, meaning that no child node has a value exceeding the value in its parent node.
public static void heapSort(int[] a) { heapify(a); deconstructHeap(a); } private static void heapify(int[] b) { final int N = b.length; int k = (N-1)/2; // loop invariant: (∀i | k < i < N : isRootOfMaxHeap(b,i,N)) while (k != -1) { siftDown(b, k, N); k = k-1; } // assert (∀i | -1 < i < N : isRootOfMaxHeap(b,i,N)) } /* pre: isRootOfMaxHeap(b,2k+1,n) ∧ isRootOfMaxHeap(b,2k+2,n) ** post: isRootOfMaxHeap(k,n) */ private static void siftDown(int[] b, int k, int n) { int leftChildLoc = 2*k + 1; if (leftChildLoc >= n) { } // node k is a leaf else { int m; // id of child node of k having larger value if (leftChildLoc == b.length-1 || b[leftChildLoc] > b[leftChildLoc+1]) m = leftChildLoc; } else m = leftChildLoc + 1; } if (b[k] < b[m]) { swap(b,k,m); siftDown(b, m, n); } } } /* pre: isRootOfMaxHeap(b,0,N) */ private static void deconstructHeap(int[] b) { final int N = b.length; int k = N; // loop invariant: isAscending(b[k..N)) ∧ // (∀i,j | 0≤i<k≤j : b[i] ≤ b[j]) while (k != 1) { k = k-1; swap(b,0,k); siftDown(b,0,k); } } |