int pow(int a, int b)
//@requires b>= 0;
{
if (b == 0) return 1;
return pow(a, b-1) *a;
}
:warning: check what pow(a, b-1) returns when b==0; we certainly want it to return a value other than 1 and a function. The function above will return 1 and exit.
int f(int x, int y)
//@requires y>=0
//@ensures \result == pow(a, b)
{
int a = x;
int b = y;
int r = 1;
while (y>1) {
if (y % 2 == 1) {
r = x*r;
}
x = x*x;
y = y/2;
}
}
@loop_invariant
We need to care about:
correctness: correct postconditions given correct precondition
LI^~C -> Pos
(^ is the and
symbol)safe function call: input satisfy precondition
point-to reasoning
b | e | r |
---|---|---|
2 | 8 | 1 |
4 | 4 | 1 |
16 | 2 | 1 |
In this case, r and b^e is loop invariant. | ||
Loop invariant is a Boolean statement, it was checked before the first iteration of the loop |
b | e | r | b^e |
---|---|---|---|
2 | 7 | 1 | 128 |
4 | 3 | 2 | 64 |
16 | 1 | 8 | 16 |
In this case r(b^e) is constant |
we should always find loop invariant, but finding the interesting one is more important
Why use //@requires ? Because we can debug with them and not using them in run-time.
:warning: loop invariant is checked before the loop guard (the statement in while
or for
), including the last check when the loop guard is false, so loop invariant always hold at the end of the loop. When it skip loop. loop invariant is also checked.
:warning: the use of word
never
, always
, each
, and initially
is considered operational reasoning.
Using first false
result of loop guard to infer loop invariant
INIT: show loop invariant is true
initially
PRES: show loop invariant is preserved by an arbitrary iteration of the loop (only one iteration)
INIT and PRES Example:
POS After the Loop:
e=0 causes a bug, this can happen only when e=0 in the input
Fixing the bug:
@requires change -> passing down special case to parent (X)
adding special case -> difficult to prove
using POW instead -> not efficient
Proving loop must terminate:
e
must getting smaller
e
>= 0 (integer division always rounding down toward negative)
we mush show that it terminate AND WITH CORRECT ANSWER (we prove that with loop_invariant)
show correctness if loop do terminate
TODO: listen to the beginning of the lecture about 10min
Table of Content