[an error occurred while processing this directive]
int sumFrom( int a, int b )
  sum ← 0
  i   ← a
  while (i < b)
    sum ← sum+i
    i   ← i+1
  return sum

[First you'll need to add comments saying what this function does, and then you'll need to phrase its purpose in terms of functions, summation-notation, sets, whatever -- something that we can reason about mathematically.]

Let's walk through the thought process. We might realize partway through, we need to go back and tweak things.

Attempt 1

What does the code do? Stupid programmer, they didn't provide a description!

/** sumFrom: int, int --> int,  with a ≤ b.
 * Return ∑[a,b).
 * (Using half-open intervals is often handy, to avoid
 *  lots of adding-or-subtracing-by-one-to-get-interval-correct.)
 * Note that if a = b, this interval is empty,
 * so we appropriately return 0.
 */

Next we need to determine the parts of our proof: G, L1, C.

Okay, now we're ready to begin, and it should be smooth sailing.

Attempt 2 — success

Here is the same proof, re-written to use L in all the parts. Happily, we are typing our solution, so it's easy to use an editor to patch up our solution. We also re-write it to make the presentation cleaner. (Re-writing for clarity is a routine part of doing proofs!)

/** sumFrom: int, int --> int,  with a ≤ b.
 * Return ∑[a,b).
 * (Using half-open intervals is often handy, to avoid
 *  lots of adding-or-subtracing-by-one-to-get-interval-correct.)
 * Note that if a = b, this interval is empty,
 * so we appropriately return 0.

int sumFrom( int a, int b )
  sum ← 0
  i   ← a
  while (i < b)
    sum ← sum+i
    i   ← i+1
  return sum
Okay, now we're ready to begin, and it's smooth sailing.

Attempt 3 — perfection!

Exercise We can actually remove the requirement ``ab''. One approach would be to have a big two-case proof, depending on whether a≤b initially. But slightly more cleanly, the two cases can be subsumed within our proof structure. Your task: Come up with a statement L3 — a strengthened version of L — such that the proof works for this third invariant.
/** sumFrom: int, int --> int
 * Return ∑[a,b).
 * (Using half-open intervals is often handy, to avoid
 *  lots of adding-or-subtracing-by-one-to-get-interval-correct.)
 * Note that if a ≥ b, this interval is empty,
 * so we appropriately return 0.
 */
define sumFrom( int a, int b )
  sum ← 0
  i   ← a
  while (i < b)
    sum ← sum+i
    i   ← i+1
  return sum

Further practice

Lots of tweaks here, if you want to give other things a try:
¹A comment on the "obvious" fact that a′=a: Just because a doesn't appear in the code isn't quite enough; we are also realizing that we're not calling a different function (which might change the value of our a.) By the way, functions are being called — the built-in function is being called. Furthermore, in languages like C++ where you can overload assignment (or addition), suddenly you need to prove that that code isn't modifying our variable. To make things worse in C++, you can't just argue "the other function doesn't have the variable a in scope, so it can't modify it", because in C++ writing off the end of an array can change arbitrary memory locations. Proofs for C++ programs are difficult; and it's not coincidence that buggy C++ programs are very easy to write. [back] ²Keep in mind that it's not sufficient to say that a value just increases w/o specifying a minimum amount: e.g. the series 1/2,3/4,7/8,… is always increasing but will never exceed 2. [back] [an error occurred while processing this directive] [an error occurred while processing this directive]