# Lecture 002

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

## Looking for Loop Invariant

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.

## Proving Loop Invariant is Actually Valid

### Operational Reasoning

:warning: the use of word never, always, each, and initially is considered operational reasoning.

### Point-to 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 (LI true initially) and PRES (preserve Loop Invariant)

INIT and PRES Example:

#### POS(EXIT) (loop guard and LI imply postconditions)

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

#### TERM (with operational proof that loop terminates)

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