Reputation:
From the following code, I need to deduce/choose a loop invariant.
(|true|)
x = 0 ;
s = 0 ;
while ( x <= n ) {
s = s + x ;
x = x + 1 ;
}
(|s = n(n + 1)/2|)
Solution given was
I don't quite understand how it has reached the solution above.
Please, help me with how to derive such solution or other loop invariant from the code.
Upvotes: 1
Views: 608
Reputation: 17945
Given the invariant, you can easily check that it is true before, within, and after the loop (yes, adding up integers from 1 to n inclusive gives you (n+1)*n/2 - see triangular numbers ). Since it covers all relevant variables in the loop (x
and s
), and cannot be further refined (well, you could add ^ x >= 0
), it is indeed the invariant.
To deduce it by yourself, I am afraid that you need to know about triangular numbers (or the half-the-square) formula beforehand. You can of course write out that s = sum of integers from 1 to x
for that part, and I for one would take it as a valid invariant. The part where x <= n+1
is comparatively easy.
A layman's way of finding invariants is to try to write out what the variables of the loop do during their lifetime inside the loop:
And then writing it out in math.
Upvotes: 1