One way to prove a loop halts is to identify some integer variable (not necessarily explicitly in the program) that always decreases each time the loop is executed, and that once that variable is less than zero, the loop will terminate. We can call this variable a loop variant.
Consider the following little snippet:
var x := 20;
while (x >= 0) {
x := x - 1
}
Here, we can see that x decreases each time the loop is executed, and that the loop will exit once x < 0 (obviously, this isn't very rigorous, but you get the idea). Therefore, we can use x as a variant.
What about a more complicated example? Consider a finite list of integers, L = [L[0], L[1], ..., L[n]]. in(L, x)
is true if x is a member of L. Now consider the following program:
var x := 0;
while (in(L, x)) {
x := x + 1
}
This will search through the natural numbers (0, 1, 2, ...), and stop once it has found a value for x that is not in L. So, how do we prove that this terminates? There has to a maximal value in L -- call it max(L). We can then define our variant as max(L) - x
. To prove termination, we first have to prove that max(L) - x
is always decreasing -- not too hard since we can prove x is always increasing. We then to have prove that the loop will terminate when max(L) - x < 0
. If max(L) - x < 0
, then max(L) < x
, which means that x cannot possibly be in L, and so the loop will terminate.