The invariant of interest is:

append(reverse(L), R) == reverse(L0)

The verification conditions are:

  1. (L == L0
    and R' == nil
    and L' == L)
    implies
    append(reverse(L'), R') == reverse(L0)
  2. (append(reverse(L), R) == reverse(L0)
    and !isEmpty(L)
    and R' == cons(first(L), R)
    and L' == rest(L))

    implies
    append(reverse(L'), R') == reverse(L0)
  3. (append(reverse(L), R) == reverse(L0)
    and !(!isEmpty(L)))
    implies
    R == reverse(L0)

Proofs of the verification conditions:

  1. After substitution of L0 for L' and nil for R', the right-hand side of the implication becomes:

    append(reverse(L0), nil) == reverse(L0)

    which simplifies to:

    reverse(L0) == reverse(L0)

    which is true.
  2. After making substitutions on the right-hand side of the implication, we have, to be shown:

    append(reverse(rest(L)), cons(first(L), R)) == reverse(L0)

    and we are given append(reverse(L), R) == reverse(L0) on the left-hand side. So all we have to do is show:

    append(reverse(L), R) == append(reverse(rest(L)), cons(first(L), R))

    under the assumption that !isEmpty(L). If we write L = [x1, x2, x3, …., xn], then what is to be shown is equivalent to:

    append([xn, xn-1, …., x2, x1], R) == append ([xn, xn-1, …., x2], cons(x1, R))

    The left-hand side of this equation can be expressed
    [xn, xn-1, …., x2, x1 | R]
    while the right-hand side is [xn, xn-1, …., x2 | [x1 | R]]
    which is clearly equivalent to the left-hand by the definition of the list-construction operations.

  3. Starting from the left-hand side, !(!isEmpty(L)) is a double negation, which means that isEmpty(L), i.e. L == nil. When we substitute for L in

    append(reverse(L), R) == reverse(L0)

    we get

    append(reverse(nil), R) == reverse(L0).

    But reverse(nil) == nil, so we have

    append(nil, R) == reverse(L0).

    But append(nil, R) == R, so we have

    R == reverse(L0),

    which is the right-hand side of the implication.

Thus all verification conditions have been proved.

The energy function is e(L, R) = length(L). Clearly e(L, R) is a natural number. Also, each time through the loop e(L, R) decreases by 1 due to the statement L = rest(L). Therefore the program terminates.