CSC 161  Grinnell College  Spring, 2010 
Imperative Problem Solving and Data Structures  
This laboratory exercise introduces the concept of loop invariants and provides some practice in using loop invariants in developing programs.
Problem: Read a (nonzero) number r from the keyboard and compute (and print) r^{0}, r^{1}, r^{2}, r^{3}, ..., r^{10}.
Solutions: Program loopinvariants1.c shows three correct solutions to this problem, illustrating that even a simple problem may be solved in a rather large number of ways. Since each code segment represents a somewhat different way of thinking about problem solving and loops, the following discussion considers each solution in some detail.
printf ("First Solution\n"); prod = 1; i = 0; while (i <= 10) { printf ("\t%6.2lf", prod); prod *= r; i++; } printf("\n");
In this first approach, at the top of the loop, i represents an exponent and prod represents an r^{i} value that is ready to be printed. Initially, i=0 and prod=1, which sets up the values for the first pass through the loop.
Within the loop, the previously computed values are printed, and then both i and prod are updated for the next time.
To review, the code executes correctly because the following ideas work together properly.
In the statement while (i <= 10), the test (i <= 10) is sometimes called a loopcontinue condition; the loop continues as long as this condition is true. In contrast, the negative of this expression i > 10 is sometimes call a exit condition.
In contrast, statement A above is called a loop invariant. A loop invariant is a statement about variables and relationships among them, where the statement is to be true every time the machine gets to the very top or bottom of a loop (whether the loop continues or not). For a while loop, therefore, a loop invariant is a statement that is true every time the Boolean expression is evaluated.
printf ("Second Solution\n"); printf ("\t%6.2lf", 1.0); prod = 1; i = 0; do { i++; prod *= r; printf ("\t%6.2lf", prod); } while (i < 10); printf("\n");
This approach illustrates a different meaning for the variables i and prod. Here, at the top of the loop, i represents an exponent and prod represents the r^{i} value that has most recently been printed. Thus, in this approach, i and prod are initialized to 0 and 1=r^{0}, and these values are printed before the loop. Then, within the loop, the i and prod are updated before the new values are printed. With this perspective of i, processing continues until i=10, since this is the last desired output value.
As with the previous code segments, we can summarize why the code works correctly with four statements.
Here, once again, Statement A is called a loop invariant, and that statement is true at the start, each time through the loop (at the top of the loop), and at the end. This notion of a loop invariant, therefore, applies to any type of loop construct, not just for while loops. In the current context, for a dowhile loop, a loop invariant is a statement that is true every time the computer gets to the do and the statement is also true when execution of the loop is over.
printf ("Third Solution\n"); printf ("\t%6.2lf", 1.0); prod = r; printf ("\t%6.2lf", prod); i = 0; while (i < 9) { i++; prod *= r; printf ("\t%6.2lf", prod); } printf("\n");
A loop invariant for this Code Segment might be described as follows:
From this perspective, the first two cases, r^{0} and r^{1}, do not require any multiplications of r by itself and so are handled as part of initialization. Also, the final desired value, r^{10}, requires only 9 multiplications, so processing should halt when this number of multiplications has been performed.
In developing correct code, our discussion has emphasized four points.
This laboratory exercise is based on part of an ongoing project of introducing the concepts of assertions and loop invariants informally in CS1 and CS2 courses. Early funding for this work came, in part, from NSF Grant CDA 9214874, "Integrating ObjectOriented Programming and Formal Methods into the Computer Science Curriculum". Henry M. Walker worked as Senior Investigator on this portion of that effort.
This document is available on the World Wide Web as
http://www.cs.grinnell.edu/~walker/courses/161.sp10/readings/readingloopinvariants.shtml
created 25 October 2007 last revised 27 February 2010 

For more information, please contact Henry M. Walker at walker@cs.grinnell.edu. 