CSCE 235
Light
Bulb 5
February 26, 2002
1. What is the use of Induction? There are many ways in which Induction is useful. Here, we talk about one useful application (as suggested by Prof. Vinod Variyam). That is, we can use induction in the analysis of loop invariants.
What are loop invariants? First, what is a loop? In computer programming, we have for and while loops; in circuitry, we have closed circuits; in business or systems, we have feedback loops, quality control loops, product design loops, R&D loops; in control systems, we have adjustment loops to make sure the systems are within a targeted zone; and so on. In the following, we will use a while as an example. But keep in mind that there are loop invariants in other types of loops as well.
When we debug a loop, we usually check to see whether it is an infinite loop—i.e., whether it terminates. Sometimes, this is difficult to do when the loop is very complex! This is when loop invariant analysis can help.
There are several definitions for a loop invariant:
From http://www.cs.duke.edu/~ola/patterns/plopd/invariant.html:
A loop invariant is a Boolean expression that is true each time the
loop guard is evaluated. Typically the Boolean expression is composed of
variables used in the loop. The invariant is true every time the loop guard is
evaluated. In particular, the initial establishment of the truth of the
invariant helps determine the proper initial values of variables used in the
loop guard and body. In the loop body, some statements make the invariant
false, and other statements must then re-establish the invariant so that it is
true before the loop guard is evaluated again.
From http://www.cs.miami.edu/~burt/learning/Math120.1/Notes/LoopInvar.html:
A loop invariant is a formal statement about the relationship
between variables in your program which holds true just before the loop is ever
run (establishing the invariant) and is true again at the bottom of the loop,
each time through the loop (maintaining the invariant).
So, here is an example:
…
// make
sure that the loop invariant is true before the loop
while (test
condition is true) {
…
…
// bottom of the loop
// make sure that the loop invariant is
true here
…
}
//
termination + loop invariant = goal
Now, how can Induction be of help?
For example, let the loop’s objective be “Compute the factorial.” Now we have the following:
…
int i =
1;
int
product_so_far = 1;
while (i
<= N) { // test condition, where N is the number to
//
to compute the factorial for
product_so_far = i*product_so_far;
i = i + 1;
}
printf(“factorial
of %d = %d\n”,n,product_so_far);
…
Here is the loop invariant: i and product_so_far. We set the invariant true before the loop by:
int
i = 1;
int product_so_far = 1;
And then inside the loop, we update product_so_far and then increment i to keep the loop invariant true: product_so_far = i*product_so_far! That is, for all i, product_so_far[i] = i*product_so_far[i-1]. The termination condition is when i > N.
And when we get out of the loop, we must have met the termination condition and the loop invariant must be true. And thus, we have our goal: the factorial of N.
So, what does this have to do with Induction?
Well, the initial setup of the loop invariant before the while loop is the setup of the Basis for Induction. The handling of the loop invariant at the bottom of the while loop is the Induction step. In the basis, we say that product_so_far is 1 when i is 1. In the induction step, we say that if product_so_far[i] = i*product_so_far[i-1], then product_so_far[i+1] = (i+1)*product_so_far[i]. This is induction!
In other words, we can actually identify the loop invariant of a problem by going the proof by induction process! Not only that, the proof by induction process also identifies how to initialize the loop invariant before the loop, and how to keep the loop invariant true at the bottom of the loop!! Remember this: the Basis becomes the initialization, and the induction step becomes the increment and update step.
So, we can use Induction in loop invariant:
(1) To decompose a complex problem into the basis for induction and the induction step, which in turn allows us to define the loop invariant initialization (before the loop) and loop invariant increment and update (inside the loop).
(2) To debug a loop to find out whether it is logically or mathematically sound—to find out whether the goal is what we want to achieve.
(3) To find out whether the behavior of a process is as expected, according to what can be induced. Note that in the real world, what can be proved through induction may not hold true – for example, heating water. Suppose we heat up a glass of water, whose temperature is set at 30 degrees initially. If we keep adding heat to the water, it heats up. If we provide constant heat energy to it, it will heat up constantly. And we can induce what the water temperature is a minute into the future given what the current water temperature is. However, what happens when the current water temperature is 100 degrees Celcius? Based on past numbers, we can induce that the next temperature measurement should read 100+. However, since water turns into steam at 100 degrees Celcius, the temperature does not increase past that!!! Thus, the conclusion we have drawn using Induction does not hold true any more. This is one of the elegant applications of Induction. It allows us to predict some behavior and test for that behavior. If that behavior is not observed, then we know something unexpected has occurred. That prompts discovery!
2. In industrial process or system evaluation and refinement, feedback loops are usually used. There, we also have to identify the loop invariant: how to initialize it, and how to increment and update it within the loop, so that it will hold true, and the loop will be able to terminate and the goal can be achieved. For example, if we want to find out the breaking point of a steel cable. We can first set the initial tension at 10 lbs. and then measure the stress on the steel cable as a function of the tension. The termination condition is when the stress exceeds a certain safety standard value. Then at the bottom of the loop, we update the stress and increment the tension, say, by 10 lbs. By the principle of well-ordering and law of physics, we know that at some point, the stress on the cable is going to exceed the safety standard. That is when we get out of the loop. And we know that by the principle of mathematical induction, we will achieve our goal—that is to find out the breaking point of the steel cable.
3. We can also use induction in scalability analysis. If a solution works for n = 1, n = 2, n = 4, n = 8, and so on. Can we safely say that the solution works for any n that is a power of 2? We may be able to induce that. But can we guarantee that? This is why we induce, and then set up the experiments according to our induction process, and test our conclusion. A network that can support 100 phone calls at the same time may not be able to support 101 phone calls at the same time because it has only a limited number of switches. A classroom that can hold up to 50 students may not be able to hold 51 students because of fire code restriction. A web server may be able to handle 100 customers a day, but can be completely shut down if 100 customers log on at the same time. Induction takes place here.
4. The above examples may seem trivial and meaningless. But remember that most problems are complex and so complicated that it is not easy to identify the loop invariant; and it is sometimes even difficult to figure out how to initialize the loop invariant, and how to increment and update it. That is where Induction comes in.