Discrete Structures
Prog. Correctness – Iterative Alg.
(Ch 5.5)*
CMPS 211 – American University of Beirut
* Extracted from Discrete Mathematics and It’s Applications book
slides
1
Program Correctness for
Iterative Algorithms
2
Program Correctness
Usually, we convince ourselves that our
programs are correct (debug, test, …)
We actually want to prove that our programs
are correct
i.e., : will give expected output (correct post-
condition) for all valid input (correct pre-
condition)
3
Program Correctness: what does it take?
Proving that a program is correct requires:
Finding appropriate propositions
Using appropriate inference rules
Similar to what we did in Chapter 1, Proving
that an English argument is valid requires:
Finding appropriate propositions
Using appropriate inference rules
4
Program Correctness: Relevant Inf. Rules
What are the constructs that are used in a
program
Assignment
Composition: statements in sequence
Conditional: if – then or if – then – else
Loops: while
We need relevant inference rules for each of
these constructs
5
Partial Correctness Definition
Let S denote a “segment of code” to which we “input” some
values, and S “outputs” a set of values
Let p be a proposition that depends on the input values to S
Let q be a proposition that depends on the output values of S
We say S is partially correct with respect to initial assertion p
and final assertion q if:
whenever p is true for the input values of S and S terminates
then q is true for the output values of S
Tony Hoare
1934 –
We write p{S}q
Turing Award Winner
This is the central feature in Hoare’s logic formal system, which is
used for correctness verification
p{S}q is known as a Hoare’s Triplet
We often need to find strongest p and q
6
Total Correctness
For total correctness, need to prove two
things:
1. Partial Correctness
p{S}q
2. That S terminates, i.e.,
Ø condition, after a finite number of iterations
Note: If S has no loops, then the second step
is not needed!
7
Easy Example
Let S be:
y := 2
z := x +
y
So, now we can let p and q be:
p: x is an integer
q: z is x + 2
Then p{S}q is true
However, assume q’ : “z is x + 5”
Then p{S}q’ would be false
8 What about q: z > x?; q: z < x ∨ z > x? q: true?
Not as Easy Example: Factorial
Let S be:
Procedure Factorial(n:
integer)
i := 1
f := 1
while i < n
begin
i := i +1
f := f * I
end
return f
For the factorial procedure to be correct, we
should have:
p: n ≥ 1
q: f = n!
But how can we prove p{S}q?
9
Inference Rule 1 - Composition
Let S be composed of sub-statements
S = {S1 ; S2}
Given that: p{S1}q
q{S2}r
\ p { S 1 ; S 2} r
¾¾¾¾¾¾
We can conclude:
And therefore: \ p{ S } r
Using Inference Rule (Composition)
10
Example - Composition
Consider the following program S
Procedure pro1(n:
integer)
x := n+5
n := n - 10
Now define S1, S2, p, q, r where:
p{S1}q is true
S1: x := n+5
S2: n := n-10
q{S2}r is true
p: n is an integer
q: x = n+5
\ p{S1 ; S2}r
¾¾¾¾¾¾
r: x = n + 15
\ p{ S } r
11
Understanding how we got r: x = n +
15
p: n is an integer Procedure pro1(n:
integer)
S1: x := n+5
S1 : x := n + 5
S2: n := n - 10
Then n is x – 5 (q: x = n +5)
S2 : n := n – 10
Then n is x – 5 – 10
Thus n is x – 15
and therefore r: x = n + 15
12
Inference Rule 2.1 - Simple if
Let S: if condition then S1
Given that:
(p Ù condition){S1} q
(p Ù Øcondition) ® q
\ p{if condition then S1}q
¾¾¾¾¾¾¾¾¾¾¾
We can conclude:
And therefore: \ p {S }q
13
Example – Simple if
Consider the following program segment S:
if x >y
We can set then
p: x is an integer y := x
condition: x >y
S1: y := x
q: y ³ x
Now:
(p Ù condition) {S1}: ((x is an integer ) Ù (x >y)) {y := x } q: y ³ x
(p Ù Øcondition): ((x is an integer ) Ù Ø(x >y)) q: y ³ x
By the inference rule on the previous slide, we can conclude that
p{S}q
14
Inference Rule 2.2- if then else
Let S : if condition then S1 else S2
Given that:
(p Ù condition){S1}q
(p Ù Øcondition){S2}q
\ p {if condition then S1 else S2}q
We can conclude:
¾¾¾¾¾¾¾¾¾¾¾
And therefore:
\ p{ S } q
15
Example – if then else
Consider the following program segment S:
We can set if x<0
p: x is an integer
then
a := -x
condition: x<0
Else
S : a := -x
1 a := x
S : a := x
2
q: a = |x|
Now:
(p Ù condition) {S }: ((x is an integer ) Ù (x < 0)) {a := -x } q: a
=|x|
1
(p Ù Øcondition) {S }: ((x is an integer ) Ù Ø(x<0)) {a := x} x ³
0 Ù a = x q: a =|x|
2
By the inference rule on the previous slide, we can
conclude that p{S}q
16
Inference Rules 3 - while
Let S : while condition S1
To be able to complete the proof, we need to define the
loop invariant
v is called a loop invariant if v remains true every time
S1is executed, i.e., (v Ù condition){S1}v
i.e. if v is true and condition is true just before executing
S1 , then v remains true just after executing S1
Inference Rule:
(v Ù condition){S1}v i.e., v is a loop invariant
\ v {while condition S1}(v Ù Øcondition)
¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾
17
Finding Loop Invariants
We have p{while condition S1}q, we need to
find v such that:
pv
(v Ù condition) {S1} v
(v Ù Øcondition) q
There isn’t a known recipe for finding loop
invariants
It would be very helpful to try to understand
what the loop is really doing, and what
variables it is changing, and then try to come
up with a loop invariant
18
Proving Loop Invariants
To prove correctness of a loop invariant, we need to prove
Initialization step
The loop invariant is true before the loop is executed
i.e.,: p v
Maintenance
If the loop invariant holds for the ith iteration, then it must hold after
the i+1th iteration;
i.e.,: (v Ù condition){S1} v
Termination
when the loop terminates, the loop invariant would still hold
i.e.,: (v Ù Øcondition) q
For total correctness, we will need to show that
eventually, the loop will terminate, i.e.,: Øcondition
Can use induction as well
19
Algorithm: Factorial
Consider the Procedure factorial(n:
following code integer)
p : n ³ 1 integer i := 1
q : f = n! f := 1
while i < n
We need to show p{S}q begin
i := i +1
Loop Invariant: f := f * i
basically, after each end
iteration, f = i! return f
v : (f = i! ) ∧ ( i ≤ n )
20
Factorial – Using Hoare Logic
v : (f = i! ) ∧ ( i ≤ n ) Procedure factorial(n:
integer)
{n ³ 1 }
i := 1
Initialization: f := 1
Just before the loop, i = 1,
{i = 1; f = 1; n ³ 1}
{v: f=i! Ù (i £ n)}
therefore v holds
while i < n
Maintenance:
begin
{v: f=i! Ù (i <n)}
At the beginning and end of
i := i +1
each loop, v holds
{f=(i-1)! Ù (i
£n)}
f := f * i
{f=(i-1)! * i Ù (i
Termination:
£n)}
{v: f=i! Ù (i £n)}
At the end of the loop, v holds
end
Proof Completed!
{v: f=i! Ù (i £n) Ù (i ≥ n)}
{f=i! Ù (i=n)}
{f=n!}
21
return f
Algorithm: Multiply
Consider the Procedure multiply (m, n:
following code
integers)
if n < 0 then a := -n
p: m,n integers else a := n
k := 0
q: x = mn
x := 0
We need to show p{S}q
while k < a
begin
x := x + m
k := k+ 1
Loop Invariant: end
basically, after each
if n < 0 then x := -x
iteration, x = mk
else x := x
v
return x
: (x = mk) ∧ (k ≤
a)
22
Multiply – Using Hoare Logic
Procedure multiply (m, n: integers)
if n < 0 then a := -n
{m, n are integers}
else a := n
k := 0
{a = |n|} – proven before
x := 0
Initializatio
while k < a n
{a = |n| ∧ k = 0 ∧ x = 0} {a = |n| ∧ k = 0 ∧ v: x = km ∧ k ≤ a}
Maintenance at start
begin
x := x + m
{a = |n| ∧ v: x = km ∧ k < a}
k := k+ 1
Maintenance at
{a = |n| ∧ x = km + m ∧ k < a} {a = |n| ∧ x = (k+1)m ∧ k < a}
end
{a = |n| ∧ v: x = km ∧ k ≤ a}
end
if n < 0 then x := -x Terminatio
{a = |n| ∧ v: x = km ∧ k ≤ a ∧ ¬(k < a) } {a = |n| ∧ x = km ∧ k = a = |n| ∧ x = am}
n
else x := x
{n < 0 ∧ a = |n| ∧ x = -am} {n = -a ∧ x = nm}
return x {x = nm}
{n ≥ 0 ∧ a = |n| ∧ x = am} {n = a ∧ x = nm}
23
Algorithm: Array Product
Write an algorithm, which given a sequence of
integers, returns the product of all elements in
the list
Procedure array_product(a1, a2, … ,an:
integers)
product := 1;
for i := 1 to n
product = product * ai ;
return product
Loop invariant:
P(i) = “Before the ith iteration, product is equal to the
product of all the elements a1, a2, …, ai-1
24 *Credits to Fatima Abu Salem, American University of Beirut
Array Product – Using Inductive Proof
Initialization: Show that P(1) holds
Before the first iteration, the elements a1, a2, …, ai-1 is
the empty set, so product should be equal to 1, which
is the case
Maintenance: Assume P(i) and show that P(i+1)
holds
Since P(i) is true, so before the ith iteration
product = a1* a2 * … * ai-1
In the body of the loop (at line 4 of the algorithm):
product = product * ai = a1* a2 * … * ai-1 * ai
Therefore, before the i+1st iteration, product is the
product of all the elements a1, a2, …, ai , so P(i+1) is true
Termination:
After n iterations, the loop will terminate and P(n) would
hold by induction
25 *Credits to Fatima Abu Salem, American University of Beirut
Array Product – Using Hoare Logic
Procedure array_product(a1, a2, … ,an : integers)
{n ≥ 0 ∧ a1, a2, …, an are integers}
product := 1;
i := 1;
{product = 1 ∧ i = 1}
{v: (product = a1, a2, …, ai-1∧ i ≤ n+1) ∧ i = 1}
while i ≤ n
{v: (product = a1, a2, …, ai-1 ∧ i ≤ n)}
product = product*ai ;
{product = a1, a2, …, ai∧ i ≤ n}
i := i+1
{v: (product = a1, a2, …, ai-1 ∧ i ≤ n + 1)}
{v: (product = a1, a2, …, ai-1 ∧ i ≤ n + 1) ∧ i ≥ n + 1}
{product = a1, a2, …, ai-1 ∧ i = n + 1}
{product = a1, a2, …, an}
return product
26
Section Summary
In this section, we have introduced methods
to prove correctness of iterative algorithms
Whenever a loop is present, we have to also
prove the correctness of the loop invariant to
complete the proof of the algorithms
To do so, we can use one of the two methods:
Hoare Logic
Inductive proof
27
Any Questions?
28