Allocate nodes only as required, explicitly initializing every field:
PROCEDURE Make(VAR t: Trie);
VAR c: INTEGER;
BEGIN
  NEW(t); t.terminal := FALSE; c := 0;
  WHILE c < 26 DO t.child[c] := NIL; c := c+1 END
END Make;

PROCEDURE AddTail(VAR t: Trie; s: ARRAY OF CHAR; i: INTEGER);
BEGIN
  IF t = NIL THEN Make(t) END;
  IF s[i] = 0X THEN
    t.terminal := TRUE
  ELSE
    AddTail(t.child[Index(s[i])], s, i+1)
  END
END AddTail;

PROCEDURE Add(VAR t: Trie; s: ARRAY OF CHAR);
BEGIN
  AddTail(t, s, 0)
END Add;
Here 0X is the zero character, and s must contain its terminator within its array bounds. Make establishes that the first c child fields are NIL as its loop invariant. Passing t by reference lets the base allocation replace a missing root or child pointer.
For correctness, use induction on the number of characters before the terminator. At length zero, setting terminal adds exactly the empty suffix. Otherwise the chosen child stores exactly words with the required next letter, and the induction hypothesis adds the remaining suffix while preserving all other words. Thus the resulting set is the old set union the supplied word, ignoring case. Repeated insertion changes no word membership. A newly allocated path reaches the newly terminal node, preserving the canonical representation invariant after the procedure finishes. The running time is for a word of length , using call stack space without optimization.
AddTail in part (d) is already tail-recursive: the recursive call is the final action of its branch. The following loop follows a separate cursor so that the caller's root pointer is preserved:
PROCEDURE AddIter(VAR t: Trie; s: ARRAY OF CHAR);
VAR u: Trie; i, c: INTEGER;
BEGIN
  IF t = NIL THEN Make(t) END;
  u := t; i := 0;
  WHILE s[i] # 0X DO
    c := Index(s[i]);
    IF u.child[c] = NIL THEN Make(u.child[c]) END;
    u := u.child[c]; i := i+1
  END;
  u.terminal := TRUE
END AddIter;
The loop invariant is that u points to the node reached by the first i letters, all necessary nodes along that path exist, and no previously terminal node has lost its flag. Each iteration advances one character. At the terminator, marking u inserts exactly the desired string. Using t := t.child[c] as the cursor update would instead overwrite the caller's root through the VAR parameter. This version has running time and constant auxiliary space, apart from newly allocated nodes in the result.
For a proposed loop invariant , initial condition , guard , body , and postcondition , establish these Hoare logic obligations:
The first establishes before the loop; the second preserves it after each iteration; the third derives the desired result when the guard is false. Together they prove partial correctness. For total correctness, also prove algorithm termination, for example by a nonnegative integer loop variant that strictly decreases whenever the body executes. The loop invariant need not be the postcondition: it generally describes completed and unfinished work together.
Let denote the original array, used only in the proof. Save its first entry before overwriting it:
PROCEDURE LeftOne;
VAR saved: T; i: INTEGER;
BEGIN
  saved := a[0]; i := 0;
  WHILE i < N-1 DO
    a[i] := a[i+1]; i := i+1
  END;
  a[N-1] := saved
END LeftOne;
The loop invariant is saved = A[0], for , and for . Thus the next source is untouched, and the assignment extends the completed prefix. At exit, the saved entry supplies the last position. The loop variant is . The result is . This also handles , and uses exactly element reads and element writes, counting the saved read and final write, with one extra value of type T.
Save the last entry and shift in decreasing index order, so no source is overwritten before being used:
PROCEDURE RightOne;
VAR saved: T; i: INTEGER;
BEGIN
  saved := a[N-1]; i := N-1;
  WHILE i > 0 DO
    a[i] := a[i-1]; i := i-1
  END;
  a[0] := saved
END RightOne;
The loop invariant is saved = A[N-1], for , and for . The decreasing loop variant is . At exit the untouched saved value fills index zero. The result is , again with reads, writes, and one extra value of type T. Applying this after part (b) restores every original entry.
Normalize the amount to , with ; negative then naturally denotes a right rotation. When , return without touching the elements. Otherwise the map has disjoint permutation cycles, each of length . Use representatives :
PROCEDURE RotateLeft(k: INTEGER);
VAR r, g, x, y, h, s, j, next: INTEGER; saved: T;
BEGIN
  r := k MOD N;
  IF r # 0 THEN
    x := N; y := r;
    WHILE y # 0 DO h := x MOD y; x := y; y := h END;
    g := x; s := 0;
    WHILE s < g DO
      saved := a[s]; j := s;
      IF j >= N-r THEN next := j-(N-r) ELSE next := j+r END;
      WHILE next # s DO
        a[j] := a[next]; j := next;
        IF j >= N-r THEN next := j-(N-r) ELSE next := j+r END
      END;
      a[j] := saved; s := s+1
    END
  END
END RotateLeft;
The conditional calculation of next implements addition modulo without first forming a possibly overflowing j+r. Oberon's MOD with positive divisor supplies the nonnegative remainder. The first loop is the Euclidean algorithm, with loop invariant and decreasing nonzero remainder.
For the outer loop, cycles with representatives below s are complete and every other cycle retains its original values. In one cycle, write . The inner loop invariant is saved = A[s], , and for , with the remaining sources still untouched. When the next index returns to s, the saved value closes the cycle. The cycle length is : writing and with , the least positive with is . Each residue class modulo is one cycle, justifying the chosen representatives.
Every element is read once and written once: element accesses, compared with for repetitions of part (b). The zero rotation uses none. The running time is and auxiliary space is constant; the original array is proof notation, not a copy made by the program.
Use the convention , as required by the paper's rotation example. Follow each permutation cycle once. Temporarily encode a visited value as , and restore the whole permutation before returning:
PROCEDURE Permute(VAR p: ARRAY OF INTEGER);
VAR s, j, next: INTEGER; saved: T;
BEGIN
  s := 0;
  WHILE s < N DO
    IF p[s] >= 0 THEN
      IF p[s] = s THEN
        p[s] := -p[s]-1
      ELSE
        saved := a[s]; j := s;
        next := p[j]; p[j] := -next-1;
        WHILE next # s DO
          a[j] := a[next]; j := next;
          next := p[j]; p[j] := -next-1
        END;
        a[j] := saved
      END
    END;
    s := s+1
  END;
  s := 0;
  WHILE s < N DO p[s] := -p[s]-1; s := s+1 END
END Permute;
Require LEN(p) >= N and that p[0..N) is the stipulated permutation. Its cells must be writable and distinct from the data array. The marking map is reversible and fits whenever the original valid indices and fit in the signed integer type.
At each outer test, all marked indices belong to fully completed cycles; all unmarked cycles still contain their original data and permutation entries. Within a cycle the same shifting loop invariant as part (d) applies, with successor given by the original p: all previously filled positions have their final values, and saved preserves the overwritten first source. A permutation has no path into a different cycle, so every new successor is unmarked until it returns to s; no encoded negative value is used as a source index. At outer-loop exit every index is marked and correct. The restoration loop has decoded precisely the indices below s.
The procedure uses one extra value of type T, time, and at most data reads plus data writes, with no data access for fixed points. It returns p unchanged, though it marks it temporarily. If p must remain read-only even during execution, test whether each index is its cycle's smallest member by traversing p before moving that cycle. That preserves constant space and the same optimal data accesses, but can require index-array accesses.
For integers not both zero, replace them first by their absolute values, then repeat integer division:
while b != 0:
    (a,b) := (b, a mod b)
return a
This is the Euclidean algorithm. Its loop invariant is that equals the original greatest common divisor. When , the new remainder lies in , so is a strictly decreasing nonnegative loop variant. At termination, , proving correctness, including the case where one original input is zero.
Use minimum search in a rotated distinct array, then return the cyclic predecessor of the minimum:
rotatedMaximum(A):
    n = length(A)                 # require n >= 1
    lo = 0
    hi = n - 1
    while lo < hi:
        mid = floor((lo + hi) / 2)
        if A[mid] > A[hi]:
            lo = mid + 1
        else:
            hi = mid
    return A[(lo + n - 1) mod n]
The loop invariant says that the minimum index lies in the inclusive interval. If A[mid] > A[hi], the rotation break lies to the right of mid; otherwise the segment from mid to hi is increasing and its indices after mid cannot be the minimum. Each update at least halves the interval. Distinct entries make the comparison decisive, including a completely unshifted array. The predecessor of the unique minimum is the maximum, and the one-element case returns that element. The running time is , with auxiliary space.
Propagate each carry into the next position, lengthening the array if necessary:
procedure Normal(var n: number)
    i := 0
    while i < len(n) do
        carry := floor(n[i] / base)
        n[i] := n[i] - carry*base
        if carry != 0 then
            if i+1 = len(n) then
                assert carry > 0
                Lengthen(n)
            n[i+1] := n[i+1] + carry
        i := i+1
The integer division identity gives a normalized remainder in . The local rewrite preserves value because a carry at position contributes exactly what was removed at position . The loop invariant is that the represented value is fixed and every position below i is normalized. Under the stated nonnegative-digit assumption all carries are nonnegative. Carries eventually stop beyond the finite radix expansion of the represented integer; scanning any spare allocated zeros then terminates.
This implementation also accepts signed temporary coefficients when their total represented value is nonnegative, using floor division rather than truncation toward zero. A negative carry out of the final position would make the entire represented value negative, since the already normalized lower part is smaller than the next radix power. Thus the assertion cannot fail for a nonnegative represented value. This extended carry normalization of a digit array also makes the arithmetic routines below robust to such temporary representations.
Use three-way array partitioning around a saved pivot value:
procedure Partition(var a; l, r; var m, n)
    x := a[Pivot(a,l,r)]
    m := l
    k := l
    n := r
    while k < n do
        if a[k] < x then
            swap(a[k], a[m])
            m := m+1
            k := k+1
        else if a[k] > x then
            n := n-1
            swap(a[k], a[n])
        else
            k := k+1
Assume a total ordering on the element keys. The loop invariant partitions the original segment into
with and the segment's multiset unchanged. A smaller entry exchanges with the first equality position; the displaced equal entry is accounted for when both indices advance. A greater entry exchanges with the last unclassified position, so k must stay to inspect the incoming entry. The loop variant decreases by one in every branch.
At termination the equality interval is . It is nonempty because the pivot value came from the segment and swaps preserve the bag. The stronger strict outer-region conditions therefore imply the requested overlapping inequalities and . Storing the pivot value avoids following an array position whose contents may move.
Figure 1.
Four-region invariant for duplicate-aware array partitioning
. The unclassified interval shrinks at every comparison. On completion, the equal interval remains nonempty and both outer intervals can be discarded or searched by rank. Details.
Each recursive call is a tail call: nothing remains to be computed after it returns. Replace it by an update of the retained bounds:
function Select(i; var a; N): T
    require 1 <= i <= N
    target := i-1
    l := 0
    r := N
    while true do
        Partition(a,l,r,m,n)
        if target < m then
            r := m
        else if target >= n then
            l := n
        else
            return a[target]
The loop invariant retains the target order statistic in with . Each nonreturning iteration strictly decreases , because is nonempty. This proves termination and replaces recursive stack space by auxiliary space, apart from the pivot routine's own storage.
Remember the minimum node while scanning the remaining suffix:
function FindMin(xs: List): List
    require xs != nil
    best := xs
    p := xs.next
    while p != nil do
        if p.x < best.x then best := p
        p := p.next
    return best
The loop invariant says that the processed prefix is nonempty, best is a node of that prefix, and its key is no greater than any other processed key. The links are unchanged. Advancing p extends the prefix by one; the number of unprocessed nodes decreases. When it reaches nil, best is the minimum of the whole finite singly linked list. Strict comparison retains the first minimum among ties.
Treat removal of the first node separately; otherwise find its predecessor:
procedure Remove(x: List; var xs: List)
    require x is a node reachable from xs
    if xs = x then
        xs := x.next
    else
        p := xs
        while p.next != x do
            p := p.next
        p.next := x.next
    x.next := nil
In the search branch the loop invariant says that p is before x in the original linked list, x is reachable from p.next, and no links have yet changed. The remaining link distance to x decreases at every advance, so membership of x guarantees a predecessor is found. Bypassing it removes exactly that cell, rather than an arbitrary equal-valued cell. Detaching x.next leaves a standalone removed node and preserves the relative order and object identities of all retained nodes.
A sentinel node is a permanent header whose key is ignored and whose next field holds the first data node. Every data node then has a predecessor, including the first, so unlinking always updates a predecessor's next field.
function DelMin(hd: List): List
    require hd != nil and hd.next != nil
    bestPrev := hd
    p := hd.next
    while p.next != nil do
        if p.next.x < bestPrev.next.x then
            bestPrev := p
        p := p.next
    result := bestPrev.next
    bestPrev.next := result.next
    result.next := nil
    return result
The processed data prefix ends at p. Its minimum is bestPrev.next, and bestPrev remains that node's actual predecessor. This loop invariant is initialized by the first node and preserved when a strictly smaller next node is found. The unprocessed suffix length is a loop variant. At exit, the final splice removes the first minimum in one uniform case. This is linked-list minimum extraction; it requires at least one data node, rather than treating the dummy header as an element.
Repeatedly detach the minimum and append that very node to a separate output chain:
function Sort(xs: List): List
    allocate dummy headers remaining and output
    remaining.next := xs
    output.next := nil
    tail := output
    while remaining.next != nil do
        p := DelMin(remaining)
        tail.next := p
        tail := p
    return output.next
The loop invariant says that the output and remaining chains contain disjoint subsets of the original data nodes, together containing every original node exactly once. The output is nondecreasing, its final key is no larger than any remaining key, and tail points to its final node, or to the dummy header when empty. Its outgoing link is nil because DelMin detaches the returned node. Appending the remaining minimum preserves all these properties; the remaining node count decreases by one.
At exit the output is the complete sorted bag. This iterative selection sort preserves duplicate occurrences and, with first-minimum tie handling, their original relative order. It uses time and auxiliary nodes. “Increasing” here means nondecreasing when equal keys occur.
Use the iterative Euclidean algorithm for a nonnegative numerator and positive denominator:
function GCD(m,n): integer
    a := m
    b := n
    while b != 0 do
        r := a mod b
        a := b
        b := r
    return a

procedure Reduce(var m,n)
    require m >= 0 and n > 0
    d := GCD(m,n)
    m := m div d
    n := n div d
The loop invariant is with . The nonnegative loop variant is : when positive, the new remainder is strictly smaller. Thus the final is the positive greatest common divisor. Dividing both numerator and denominator by it preserves the rational number and makes them coprime. The stated proper fraction case is included, but the same code works for every nonnegative numerator, a fact useful in part (d). In particular, zero reduces to .
Accumulate denominators while reducing the positive residual:
procedure fromRat(m,n; var e)
    require 0 <= m < n
    e.i := 0
    while m > 0 do
        q := n div m
        if n mod m != 0 then q := q+1
        assert e.i < N
        e.x[e.i] := q
        e.i := e.i+1
        m := m*q-n
        n := n*q
        Reduce(m,n)
The quotient-and-remainder calculation implements the ceiling exactly. With original inputs , the loop invariant is
All stored denominators are positive; e.i counts precisely the initialized entries. Part (b) makes a strictly decreasing nonnegative loop variant. At termination the residual is zero, so the stored Egyptian fraction has the original value. The promised capacity bound justifies the array assertion. Denominators can grow rapidly, so the integer operations require exact sufficiently large storage.
Add the unit fractions one at a time, reducing after each addition:
procedure toRat(e; var m,n)
    require 0 <= e.i <= N and every stored denominator is positive
    m := 0
    n := 1
    j := 0
    while j < e.i do
        q := e.x[j]
        m := m*q+n
        n := n*q
        Reduce(m,n)
        j := j+1
The loop invariant is that is the reduced fraction equal to the sum of the first terms, with . The update is exactly , and the greatest common divisor reduction preserves it. The loop variant decreases to zero. The empty sum gives .
An arbitrary stored Egyptian sum can be at least one, so this uses the broader nonnegative-numerator contract of the implementation in part (a), not an unjustified assumption that every intermediate fraction is proper.
These methods consume the receiver's remaining sequence; exists stops as soon as it finds a witness:
trait RichIter[T] extends Iter[T] {
  def foreach(f: T => Unit): Unit = {
    while (hasNext) f(next())
  }

  def exists(p: T => Boolean): Boolean = {
    while (hasNext) {
      if (p(next())) return true
    }
    false
  }

  def foldLeft[U](x: U)(f: (U,T) => U): U = {
    var result = x
    while (hasNext) result = f(result, next())
    result
  }
}
After consumed elements, foreach has invoked its callback on exactly that prefix, exists has found no witness in it unless it has already returned, and the left fold accumulator is the fold of that prefix in its original order. These loop invariants prove the finite-sequence results. On an infinite sequence, exists may still terminate when it reaches a witness; a full traversal or fold generally does not. To retain the original cursor, a caller can invoke the operation on a suitable copy.