PCv1302pdf

You might also like

Download as pdf or txt
Download as pdf or txt
You are on page 1of 120

Program Correctness

Block 2

Jorge A. Pérez
(based on slides by Arnold Meijster)

Bernoulli Institute for Mathematics, Computer Science, and AI


University of Groningen, Groningen, the Netherlands

February 13, 2023


Outline

Recap
Programming Language
Exercise 5.6

While commands
A Rule Attempt
A Stronger Rule

Stepwise design of while programs


Exponentiation
Powers of 2
Euclid’s algorithm (gcd)

2 / 36
A Small Programming Language

Our language for expressions:


I Numerical expressions (E ; E 0 ; : : :), such as ‘42’ and ‘x + 21’.
I Boolean expressions (B ; B 0 ; : : :), such as ‘true’ and ‘x  42’
Our language for commands S ; T ; : : ::

Syntax Description
skip Does nothing
x := E Store E into the variable x
S; T Run S followed by T
if B then S else T end If B is true then run S else run T
while B do S end As long as B is true then run S

An admittedly rudimentary language, yet Turing complete:


it is as expressive as any computer machine.
3 / 36
Triples

A triple denotes a command with its precondition and postcondition:

fP g S fQ g
Intuitive reading:
I “If we execute S in any state in which (property) P holds,
then S will terminate in a state in which (property) Q holds”

In this course, we focus on total correctness: a command must


terminate to satisfy a specification.

4 / 36
Triples

A triple denotes a command with its precondition and postcondition:

fP g S fQ g
Intuitive reading:
I “If we execute S in any state in which (property) P holds,
then S will terminate in a state in which (property) Q holds”

In this course, we focus on total correctness: a command must


terminate to satisfy a specification.

Under partial correctness, we have a weaker requirement:


I “If we execute S in any state in which P holds, then S will reach
a state in which Q holds, provided it terminates”
Partial correctness is still useful and relevant.

4 / 36
Hoare Logic: Rules

fP g skip fP g
f[E x ]P g x := E fP g
=

P ) P 0 fP 0 g S fQ g fP g S fQ 0g Q 0 ) Q
fP g S fQ g fP g S fQ g
fP g S fQ g fQ g T fRg
fP g S ; T fRg
fP ^ B g S fQ g fP ^ :B g T fQ g
fP g if B then S else T end fQ g
I Given a precondition P and a precondition Q, our goal will be to
mechanically derive a command S such that fP g S fQ g.
I We recall some examples before giving the rule for while .
5 / 36
Exercise 5.6(a)
fx = 3  X 2Y +1 ^ y = Xg
S
fx = X ^ y = Y g
Implement S using an auxiliary variable:

fx = 3  X 2Y +1 ^ y = Xg
h := x;

x := y;

y := (3  x h + 1) div 2
fx = X ^ y = Y g
6 / 36
Exercise 5.6(a)
fx = 3  X 2Y +1 ^ y = Xg
S
fx = X ^ y = Y g
Implement S using an auxiliary variable:

fx = 3  X 2Y +1 ^ y = Xg
h := x;
fh = 3  X 2Y +1 ^ y = Xg
x := y;

y := (3  x h + 1) div 2
fx = X ^ y = Y g
6 / 36
Exercise 5.6(a)
fx = 3  X 2Y +1 ^ y = Xg
S
fx = X ^ y = Y g
Implement S using an auxiliary variable:

fx = 3  X 2Y +1 ^ y = Xg
h := x;
fh = 3  X 2Y +1 ^ y = Xg
x := y;
fh = 3  X 2  Y + 1 ^ x = Xg
(* calculus; substitute x = X *)
f2  Y = 3  x h + 1 ^ x = X g
(* calculus; (2  Y ) div 2 = Y *)
fY = (3  x h + 1) div 2 ^ x = X g
y := (3  x h + 1) div 2
fx = X ^ y = Y g
6 / 36
Exercise 5.6(a): Variation
fx = 3  X 2Y +1 ^ y = Xg
S
fx = X ^ y = Y g
An alternative solution would be:
fx = 3  X 2Y +1 ^ y = Xg

h := (3 y x + 1) div 2;

x := y;

y := h
fx = X ^ y = Y g
7 / 36
Exercise 5.6(a): Variation
fx = 3  X 2Y +1 ^ y = Xg
S
fx = X ^ y = Y g
An alternative solution would be:
fx = 3  X 2  Y + 1 ^ y = Xg
(* substitute y = X *)
fx = 3  y 2  Y + 1 ^ y = X g
(* calculus; (2  Y ) div 2 = Y *)
f(3  y x + 1) div 2 = Y ^ y = X g
h := (3  y x + 1) div 2;

x := y;

y := h
fx = X ^ y = Y g
7 / 36
Exercise 5.6(a): Variation
fx = 3  X 2Y +1 ^ y = Xg
S
fx = X ^ y = Y g
An alternative solution would be:
fx = 3  X 2  Y + 1 ^ y = Xg
(* substitute y = X *)
fx = 3  y 2  Y + 1 ^ y = X g
(* calculus; (2  Y ) div 2 = Y *)
f(3  y x + 1) div 2 = Y ^ y = X g
h := (3  y x + 1) div 2;
fh = Y ^ y = X g
x := y ;
fh = Y ^ x = X g
y := h
fx = X ^ y = Y g
7 / 36
Outline

Recap
Programming Language
Exercise 5.6

While commands
A Rule Attempt
A Stronger Rule

Stepwise design of while programs


Exponentiation
Powers of 2
Euclid’s algorithm (gcd)

8 / 36
Programs with Repetitions

Program A: Program B: Program C:


y := 1; while (true) do
y := x ; z := 0;
while (2  y ) do while (z 6= x ) do
skip
y := y 2 end
z := z + 1;
end y := y  z
end

9 / 36
Towards a Rule for While
We now consider the Hoare triple

fP g while B do S end fQ g

where B is a boolean condition and S is a command.

What should be the rule for repetitions?

10 / 36
Towards a Rule for While
We now consider the Hoare triple

fP g while B do S end fQ g

where B is a boolean condition and S is a command.

What should be the rule for repetitions?


I Intuitively, we should execute S as long as B holds;
we escape the loop as soon as :B holds.

10 / 36
Towards a Rule for While
We now consider the Hoare triple

fP g while B do S end fQ g

where B is a boolean condition and S is a command.

What should be the rule for repetitions?


I Intuitively, we should execute S as long as B holds;
we escape the loop as soon as :B holds.
I A first rule attempt:

fJ ^ B g S fJ g
fJ g while B do S end fJ ^ :B g

10 / 36
Towards a Rule for While
We now consider the Hoare triple

fP g while B do S end fQ g

where B is a boolean condition and S is a command.

What should be the rule for repetitions?


I Intuitively, we should execute S as long as B holds;
we escape the loop as soon as :B holds.
I A first rule attempt:

fJ ^ B g S fJ g
fJ g while B do S end fJ ^ :B g
I Above, J is the (loop) invariant: a condition that holds
regardless of how many times we repeat S .
I Is this enough?
10 / 36
The Rule Attempt in Action: Program A
var x : Z;

y := x;

while (2  y ) do

y := y 2

end

11 / 36
The Rule Attempt in Action: Program A
var x : Z;
fx  0g
y := x;

while (2  y ) do

y := y 2

end

11 / 36
The Rule Attempt in Action: Program A
var x : Z;
fx  0g
f[y =x ](x = y ^ y  0)g
y := x ;

while (2  y ) do

y := y 2

end

11 / 36
The Rule Attempt in Action: Program A
var x : Z;
fx  0g
f[y =x ](x = y ^ y  0)g
y := x ;
fx = y ^ y  0g

while (2  y ) do

y := y 2

end

11 / 36
The Rule Attempt in Action: Program A
var x : Z;
fx  0g
f[y =x ](x = y ^ y  0)g
y := x ;
fx = y ^ y  0g
(* logic: setting up the invariant *)
fJ : 9n : (x = y + (2  n ) ^ y  0)g
while (2  y ) do

y := y 2

end

11 / 36
The Rule Attempt in Action: Program A
var x : Z;
fx  0g
f[y =x ](x = y ^ y  0)g
y := x ;
fx = y ^ y  0g
(* logic: setting up the invariant *)
fJ : 9n : (x = y + (2  n ) ^ y  0)g
while (2  y ) do
fJ ^ (2  y )g

y := y 2

end

11 / 36
The Rule Attempt in Action: Program A
var x : Z;
fx  0g
f[y =x ](x = y ^ y  0)g
y := x ;
fx = y ^ y  0g
(* logic: setting up the invariant *)
fJ : 9n : (x = y + (2  n ) ^ y  0)g
while (2  y ) do
fJ ^ (2  y )g
f9n : (x = y + (2  n ) ^ y  2)g

y := y 2

end

11 / 36
The Rule Attempt in Action: Program A
var x : Z;
fx  0g
f[y =x ](x = y ^ y  0)g
y := x ;
fx = y ^ y  0g
(* logic: setting up the invariant *)
fJ : 9n : (x = y + (2  n ) ^ y  0)g
while (2  y ) do
fJ ^ (2  y )g
f9n : (x = y + (2  n ) ^ y  2)g
(* logic: prepare for loop body *)
f9n : (x = y + (2  n ) ^ y 2  0)g
y := y 2

end

11 / 36
The Rule Attempt in Action: Program A
var x : Z;
fx  0g
f[y =x ](x = y ^ y  0)g
y := x ;
fx = y ^ y  0g
(* logic: setting up the invariant *)
fJ : 9n : (x = y + (2  n ) ^ y  0)g
while (2  y ) do
fJ ^ (2  y )g
f9n : (x = y + (2  n ) ^ y  2)g
(* logic: prepare for loop body *)
f9n : (x = y + (2  n ) ^ y 2  0)g
f[(y 2)=y ]9n : (x = y + (2  n ) ^ y  0)g
y := y 2

end

11 / 36
The Rule Attempt in Action: Program A
var x : Z;
fx  0g
f[y =x ](x = y ^ y  0)g
y := x ;
fx = y ^ y  0g
(* logic: setting up the invariant *)
fJ : 9n : (x = y + (2  n ) ^ y  0)g
while (2  y ) do
fJ ^ (2  y )g
f9n : (x = y + (2  n ) ^ y  2)g
(* logic: prepare for loop body *)
f9n : (x = y + (2  n ) ^ y 2  0)g
f[(y 2)=y ]9n : (x = y + (2  n ) ^ y  0)g
y := y 2
fJ : 9n : (x = y + (2  n ) ^ y  0)g
end

11 / 36
The Rule Attempt in Action: Program A
var x : Z;
fx  0g
f[y =x ](x = y ^ y  0)g
y := x ;
fx = y ^ y  0g
(* logic: setting up the invariant *)
fJ : 9n : (x = y + (2  n ) ^ y  0)g
while (2  y ) do
fJ ^ (2  y )g
f9n : (x = y + (2  n ) ^ y  2)g
(* logic: prepare for loop body *)
f9n : (x = y + (2  n ) ^ y 2  0)g
f[(y 2)=y ]9n : (x = y + (2  n ) ^ y  0)g
y := y 2
fJ : 9n : (x = y + (2  n ) ^ y  0)g
end
fJ ^ :(2  y )g

11 / 36
The Rule Attempt in Action: Program A
var x : Z;
fx  0g
f[y =x ](x = y ^ y  0)g
y := x ;
fx = y ^ y  0g
(* logic: setting up the invariant *)
fJ : 9n : (x = y + (2  n ) ^ y  0)g
while (2  y ) do
fJ ^ (2  y )g
f9n : (x = y + (2  n ) ^ y  2)g
(* logic: prepare for loop body *)
f9n : (x = y + (2  n ) ^ y 2  0)g
f[(y 2)=y ]9n : (x = y + (2  n ) ^ y  0)g
y := y 2
fJ : 9n : (x = y + (2  n ) ^ y  0)g
end
fJ ^ :(2  y )g
f9n : (x = y + (2  n ) ^ y  0) ^ (y < 2)g
11 / 36
The Rule Attempt in Action: Program A
var x : Z;
fx  0g
f[y =x ](x = y ^ y  0)g
y := x ;
fx = y ^ y  0g
(* logic: setting up the invariant *)
fJ : 9n : (x = y + (2  n ) ^ y  0)g
while (2  y ) do
fJ ^ (2  y )g
f9n : (x = y + (2  n ) ^ y  2)g
(* logic: prepare for loop body *)
f9n : (x = y + (2  n ) ^ y 2  0)g
f[(y 2)=y ]9n : (x = y + (2  n ) ^ y  0)g
y := y 2
fJ : 9n : (x = y + (2  n ) ^ y  0)g
end
fJ ^ :(2  y )g
f9n : (x = y + (2  n ) ^ y  0) ^ (y < 2)g
(* logic: y is either 0 or 1 *)
11 / 36
The Rule Attempt in Action: Program A
var x : Z;
fx  0g
f[y =x ](x = y ^ y  0)g
y := x ;
fx = y ^ y  0g
(* logic: setting up the invariant *)
fJ : 9n : (x = y + (2  n ) ^ y  0)g
while (2  y ) do
fJ ^ (2  y )g
f9n : (x = y + (2  n ) ^ y  2)g
(* logic: prepare for loop body *)
f9n : (x = y + (2  n ) ^ y 2  0)g
f[(y 2)=y ]9n : (x = y + (2  n ) ^ y  0)g
y := y 2
fJ : 9n : (x = y + (2  n ) ^ y  0)g
end
fJ ^ :(2  y )g
f9n : (x = y + (2  n ) ^ y  0) ^ (y < 2)g
(* logic: y is either 0 or 1 *)
f(y = 0 ^ isEven (x )) _ (y = 1 ^ isOdd (x ))g 11 / 36
Verifying the Infinite Loop

The rule attempt works. What about Program C?

ftrueg
while (true) do

skip

end

12 / 36
Verifying the Infinite Loop

The rule attempt works. What about Program C?

ftrueg
while (true) do
ftrue ^ trueg
skip

end

12 / 36
Verifying the Infinite Loop

The rule attempt works. What about Program C?

ftrueg
while (true) do
ftrue ^ trueg
skip
ftrue ^ trueg
end

12 / 36
Verifying the Infinite Loop

The rule attempt works. What about Program C?

ftrueg
while (true) do
ftrue ^ trueg
skip
ftrue ^ trueg
ftrueg
end

12 / 36
Verifying the Infinite Loop

The rule attempt works. What about Program C?

ftrueg
while (true) do
ftrue ^ trueg
skip
ftrue ^ trueg
ftrueg
end
ftrue ^ :trueg

12 / 36
Verifying the Infinite Loop

The rule attempt works. What about Program C?

ftrueg
while (true) do
ftrue ^ trueg
skip
ftrue ^ trueg
ftrueg
end
ftrue ^ :trueg
ffalseg
I Starting with precondition true, we obtain a postcondition false.

12 / 36
Verifying the Infinite Loop

The rule attempt works. What about Program C?

ftrueg
while (true) do
ftrue ^ trueg
skip
ftrue ^ trueg
ftrueg
end
ftrue ^ :trueg
ffalseg
I Starting with precondition true, we obtain a postcondition false.
I At first, false as postcondition may be puzzling;
actually, it says that the loop must have never terminated.

12 / 36
We Need a Stronger Rule

I The rule attempt

fJ ^ B g S fJ g
fJ g while B do S end fJ ^ :B g
works fine for partial correctness but not for total correctness.

13 / 36
We Need a Stronger Rule

I The rule attempt

fJ ^ B g S fJ g
fJ g while B do S end fJ ^ :B g
works fine for partial correctness but not for total correctness.
I The issue is termination. Recall the reading of the Hoare triple:

fP g while B do S end fQ g

“If we execute the loop while B do S end in any state in which


P holds, then the loop will terminate in a state in which Q holds”

13 / 36
We Need a Stronger Rule

I The rule attempt

fJ ^ B g S fJ g
fJ g while B do S end fJ ^ :B g
works fine for partial correctness but not for total correctness.
I The issue is termination. Recall the reading of the Hoare triple:

fP g while B do S end fQ g

“If we execute the loop while B do S end in any state in which


P holds, then the loop will terminate in a state in which Q holds”

We need a stronger rule, in which


I The invariant J operates just as above, and is coupled with
I a variant function that ensures termination.
13 / 36
The Variant Function

We write vf to denote a function that maps program states to Z.

14 / 36
The Variant Function

We write vf to denote a function that maps program states to Z.


Some assumptions:
I vf = K , for some K 2 N, just before the loop starts.

14 / 36
The Variant Function

We write vf to denote a function that maps program states to Z.


Some assumptions:
I vf = K , for some K 2 N, just before the loop starts.
I vf decreases after every execution of S , the body of the loop:

8V 2 Z : fvf = V g S fvf < Vg

I J ^ B ) vf  0.

14 / 36
The Variant Function

We write vf to denote a function that maps program states to Z.


Some assumptions:
I vf = K , for some K 2 N, just before the loop starts.
I vf decreases after every execution of S , the body of the loop:

8V 2 Z : fvf = V g S fvf < Vg

I J ^ B ) vf  0.
This way, the loop will surely terminate within K iterations.

14 / 36
Rule for Loops

To enforce total correctness, we extend the premises in the rule for


partial correctness with the variant function vf (and its assumptions):

fJ ^ B g S fJ g
fJ g while B do S end fJ ^ :B g
Assumptions for vf :
1. vf 2Z
2. vf = K (for some K2 N) before the loop starts.
3. 8V 2 Z : fvf = V g S fvf V g
<

15 / 36
Rule for Loops

To enforce total correctness, we extend the premises in the rule for


partial correctness with the variant function vf (and its assumptions):

fJ ^ B g S fJ g
fJ g while B do S end fJ ^ :B g
Assumptions for vf :
1. vf 2Z
2. J ^ B ) vf  0.
3. 8V 2 Z : fvf = V g S fvf < Vg

15 / 36
Rule for Loops

To enforce total correctness, we extend the premises in the rule for


partial correctness with the variant function vf (and its assumptions):

vf 2 Z fJ ^ B g S fJ g
fJ g while B do S end fJ ^ :B g
Assumptions for vf :
1. vf 2ZX
2. J ^ B ) vf  0.
3. 8V 2 Z : fvf = V g S fvf < Vg

15 / 36
Rule for Loops

To enforce total correctness, we extend the premises in the rule for


partial correctness with the variant function vf (and its assumptions):

vf 2 Z J ^ B ) vf  0 fJ ^ B g S fJ g
fJ g while B do S end fJ ^ :B g
Assumptions for vf :
1. vf 2ZX
2. J ^ B ) vf  0. X
3. 8V 2 Z : fvf = V g S fvf < Vg

15 / 36
Rule for Loops

To enforce total correctness, we extend the premises in the rule for


partial correctness with the variant function vf (and its assumptions):

vf 2Z J ^ B ) vf  0 fJ ^ B ^ vf = V g S fJ ^ vf < Vg
fJ g while B do S end fJ ^ :B g

Assumptions for vf :
1. vf 2ZX
2. J ^ B ) vf  0. X
3. 8V 2 Z : fvf = V g S fvf < Vg X

15 / 36
Hoare Logic: The Complete Rules

fP g skip fP g
f[E x ]P g x := E fP g
=

P ) P 0 fP 0 g S fQ g fP g S fQ 0g Q 0 ) Q
fP g S fQ g fP g S fQ g
fP g S fQ g fQ g T fRg
fP g S ; T fRg
fP ^ B g S fQ g fP ^ :B g T fQ g
fP g if B then S else T end fQ g
J ^ B ) vf  0 fJ ^ B ^ vf = V g S fJ ^ vf < Vg
fJ g while B do S end fJ ^ :B g
16 / 36
Taking Stock

I A complete set of Hoare logic rules for the complete language,


including repetitions (while loops).

17 / 36
Taking Stock

I A complete set of Hoare logic rules for the complete language,


including repetitions (while loops).
I The use of an invariant J for proving partial correctness of
repetitions:

fJ ^ B g S fJ g
fJ g while B do S end fJ ^ :B g

17 / 36
Taking Stock

I A complete set of Hoare logic rules for the complete language,


including repetitions (while loops).
I The use of an invariant J for proving partial correctness of
repetitions:

fJ ^ B g S fJ g
fJ g while B do S end fJ ^ :B g
I The need for a variant function vf for enforcing loop termination
and thus total correctness:
J ^ B ) vf  0 fJ ^ B ^ vf = V g S fJ ^ vf < Vg
fJ g while B do S end fJ ^ :B g

17 / 36
Taking Stock

I A complete set of Hoare logic rules for the complete language,


including repetitions (while loops).
I The use of an invariant J for proving partial correctness of
repetitions:

fJ ^ B g S fJ g
fJ g while B do S end fJ ^ :B g
I The need for a variant function vf for enforcing loop termination
and thus total correctness:
J ^ B ) vf  0 fJ ^ B ^ vf = V g S fJ ^ vf < Vg
fJ g while B do S end fJ ^ :B g
I Today: A stepwise roadmap for designing repetitions, by
example.

17 / 36
Outline

Recap
Programming Language
Exercise 5.6

While commands
A Rule Attempt
A Stronger Rule

Stepwise design of while programs


Exponentiation
Powers of 2
Euclid’s algorithm (gcd)

18 / 36
Stepwise design of a while program
The starting point is the specification fP g T fQ g.

19 / 36
Stepwise design of a while program
The starting point is the specification fP g T fQ g.
0 Based on the specification, we decide that we need a loop.

19 / 36
Stepwise design of a while program
The starting point is the specification fP g T fQ g.
0 Based on the specification, we decide that we need a loop.
1 Choose an invariant J and a guard B such that
J ^ :B ) Q (aka finalization)

19 / 36
Stepwise design of a while program
The starting point is the specification fP g T fQ g.
0 Based on the specification, we decide that we need a loop.
1 Choose an invariant J and a guard B such that
J ^ :B ) Q (aka finalization)
2 Initialization: Find a command T0 such that
fP g T0 fJ g

19 / 36
Stepwise design of a while program
The starting point is the specification fP g T fQ g.
0 Based on the specification, we decide that we need a loop.
1 Choose an invariant J and a guard B such that
J ^ :B ) Q (aka finalization)
2 Initialization: Find a command T0 such that
fP g T0 fJ g
3 Variant function: Choose a vf 2 Z and prove
J ^ B ) vf  0

19 / 36
Stepwise design of a while program
The starting point is the specification fP g T fQ g.
0 Based on the specification, we decide that we need a loop.
1 Choose an invariant J and a guard B such that
J ^ :B ) Q (aka finalization)
2 Initialization: Find a command T0 such that
fP g T0 fJ g
3 Variant function: Choose a vf 2 Z and prove
J ^ B ) vf  0
4 Body of the loop: Find a command S such that
fJ ^ B ^ vf = V g S fJ ^ vf < Vg

19 / 36
Stepwise design of a while program
The starting point is the specification fP g T fQ g.
0 Based on the specification, we decide that we need a loop.
1 Choose an invariant J and a guard B such that
J ^ :B ) Q (aka finalization)
2 Initialization: Find a command T0 such that
fP g T0 fJ g
3 Variant function: Choose a vf 2 Z and prove
J ^ B ) vf  0
4 Body of the loop: Find a command S such that
fJ ^ B ^ vf = V g S fJ ^ vf < Vg
5 Conclude that
fP g T0; while B do S end fQ g
19 / 36
Example: Exponentiation

Consider the following specification:

const x : R;
var y : R; n : Z;
fP : n  0 ^ x n = Yg
S
fQ : y = Y g

Clearly, S computes x n .
We illustrate the five phases in the design roadmap, step by step.

Recall the recurrence relation for exponentiation:

x0 = 1
n > 0 ) xn = x  xn 1

20 / 36
Example: Designing a loop (1/4)

fP : n  0 ^ x n = Y g S fQ : y = Yg
0 We assume there is no function that computes y = x n directly.
We decide that we need a while-program.

21 / 36
Example: Designing a loop (1/4)

fP : n  0 ^ x n = Y g S fQ : y = Yg
0 We assume there is no function that computes y = x n directly.
We decide that we need a while-program.
1 Choose an invariant J and a guard B such that J ^ :B ) Q.

21 / 36
Example: Designing a loop (1/4)

fP : n  0 ^ x n = Y g S fQ : y = Yg
0 We assume there is no function that computes y = x n directly.
We decide that we need a while-program.
1 Choose an invariant J and a guard B such that J ^ :B ) Q.
It’s useful to involve both x and y to define J :

21 / 36
Example: Designing a loop (1/4)

fP : n  0 ^ x n = Y g S fQ : y = Yg
0 We assume there is no function that computes y = x n directly.
We decide that we need a while-program.
1 Choose an invariant J and a guard B such that J ^ :B ) Q.
It’s useful to involve both x and y to define J : y  x n = Y .
We can use n = 0 to escape the loop.

21 / 36
Example: Designing a loop (1/4)

fP : n  0 ^ x n = Y g S fQ : y = Yg
0 We assume there is no function that computes y = x n directly.
We decide that we need a while-program.
1 Choose an invariant J and a guard B such that J ^ :B ) Q.
It’s useful to involve both x and y to define J : y  x n = Y .
We can use n = 0 to escape the loop. Therefore:

J : y  xn = Y ^n 0
B :n 6= 0

21 / 36
Example: Designing a loop (1/4)

fP : n  0 ^ x n = Y g S fQ : y = Yg
0 We assume there is no function that computes y = x n directly.
We decide that we need a while-program.
1 Choose an invariant J and a guard B such that J ^ :B ) Q.
It’s useful to involve both x and y to define J : y  x n = Y .
We can use n = 0 to escape the loop. Therefore:

J : y  xn = Y ^n 0
B :n 6= 0
From y  x n = Y and n = 0 we conclude y = Y:

J ^ : B  (n  0 ^ y  x n = Y ) ^ n = 0
y =Y ^n =0
)Q
21 / 36
Example: Designing a loop (2/4)
Up to here:
P :n  0 ^ xn = Y
J : n  0 ^ y  xn = Y
B :n =6 0
2 Initialization: Find a T0 such that fP g T0 fJ g.

22 / 36
Example: Designing a loop (2/4)
Up to here:
P :n  0 ^ xn = Y
J : n  0 ^ y  xn = Y
B :n =6 0
2 Initialization: Find a T0 such that fP g T0 fJ g.
P and J are equivalent if y = 1. We deduce T0 :
fP : n  0 ^ xn = Yg

fJ : n  0 ^ y  x n = Y g

22 / 36
Example: Designing a loop (2/4)
Up to here:
P :n  0 ^ xn = Y
J : n  0 ^ y  xn = Y
B :n =6 0
2 Initialization: Find a T0 such that fP g T0 fJ g.
P and J are equivalent if y = 1. We deduce T0 :
fP : n  0 ^ xn =Yg
(* calculus; prepare y := 1 *)
fn  0 ^ 1  x n = Y g
fJ : n  0 ^ y  x n = Y g

22 / 36
Example: Designing a loop (2/4)
Up to here:
P :n  0 ^ xn = Y
J : n  0 ^ y  xn = Y
B :n =6 0
2 Initialization: Find a T0 such that fP g T0 fJ g.
P and J are equivalent if y = 1. We deduce T0 :
fP : n  0 ^ xn = Yg
(* calculus; prepare y := 1 *)
fn  0 ^ 1  x n = Y g
y := 1;
fJ : n  0 ^ y  x n = Y g

22 / 36
Example: Designing a loop (2/4)
Up to here:
P :n  0 ^ xn = Y
J : n  0 ^ y  xn = Y
B :n =6 0
2 Initialization: Find a T0 such that fP g T0 fJ g.
P and J are equivalent if y = 1. We deduce T0 :
fP : n  0 ^ xn = Yg
(* calculus; prepare y := 1 *)
fn  0 ^ 1  x n = Y g
y := 1;
fJ : n  0 ^ y  x n = Y g
3 Variant function: Choose a vf 2 Z and prove J ^ B ) vf  0.
Because J entails n  0, we can simply choose vf = n.
Clearly, we have: J ^ B ) J ) n  0  vf  0.
22 / 36
Example: Designing a loop (3/4)

4 Body of the loop: Find a command S such that

fJ ^ B ^ vf = V g S fJ ^ vf < Vg

Because vf = n must decrease, it is natural to use n := n 1:


fJ ^ B ^ vf = Vg

fJ ^ vf < V g
23 / 36
Example: Designing a loop (3/4)

4 Body of the loop: Find a command S such that

fJ ^ B ^ vf = V g S fJ ^ vf < Vg

Because vf = n must decrease, it is natural to use n := n 1:


fJ ^ B ^ vf = Vg
(* definitions J , B , and vf *)
fn  0 ^ y  x n = Y ^ n 6= 0
| {z }
^ n = Vg
J

fJ ^ vf < V g
23 / 36
Example: Designing a loop (3/4)

4 Body of the loop: Find a command S such that

fJ ^ B ^ vf = V g S fJ ^ vf < Vg

Because vf = n must decrease, it is natural to use n := n 1:


fJ ^ B ^ vf = Vg
(* definitions J , B , and vf *)
fn  0 ^ y  x n = Y ^ n 6= 0
| {z }
^ n = Vg

(* prepare n := n 1; calculus; n  0 ^ n 6= 0 ) n > 0 *)


J

fn 1  0 ^ y  x  xn 1 = Y ^ n 1 < V g

fJ ^ vf < V g
23 / 36
Example: Designing a loop (3/4)

4 Body of the loop: Find a command S such that

fJ ^ B ^ vf = V g S fJ ^ vf < Vg

Because vf = n must decrease, it is natural to use n := n 1:


fJ ^ B ^ vf = Vg
(* definitions J , B , and vf *)
fn  0 ^ y  x n = Y ^ n 6= 0
| {z }
^ n = Vg

(* prepare n := n 1; calculus; n  0 ^ n 6= 0 ) n > 0 *)


J

fn 1  0 ^ y  x  xn 1 = Y ^ n 1 < V g
y := y  x ;
fn 1  0 ^ y  x n 1 = Y ^ n 1 < V g

fJ ^ vf < V g
23 / 36
Example: Designing a loop (3/4)
4 Body of the loop: Find a command S such that

fJ ^ B ^ vf = V g S fJ ^ vf < Vg

Because vf = n must decrease, it is natural to use n := n 1:


fJ ^ B ^ vf Vg=
(* definitions J , B , and vf *)
fn  0 ^ y  x n = Y ^ n 6= 0
| {z }
^ n = Vg

(* prepare n := n 1; calculus; n  0 ^ n 6= 0 ) n > 0 *)


J

fn 1  0 ^ y  x  x n 1 = Y ^ n 1 < V g
y := y  x ;
fn 1  0 ^ y  x n 1 = Y ^ n 1 < V g
n := n 1
fn  0 ^ y  x n = Y ^ n < V g
| {z }
J

fJ ^ vf < V g
23 / 36
Example: Designing a loop (3/4)
4 Body of the loop: Find a command S such that

fJ ^ B ^ vf = V g S fJ ^ vf < Vg

Because vf = n must decrease, it is natural to use n := n 1:


fJ ^ B ^ vf Vg =
(* definitions J , B , and vf *)
fn  0 ^ y  x n = Y ^ n 6= 0
| {z }
^ n = Vg

(* prepare n := n 1; calculus; n  0 ^ n 6= 0 ) n > 0 *)


J

fn 1  0 ^ y  x  x n 1 = Y ^ n 1 < V g
y := y  x ;
fn 1  0 ^ y  x n 1 = Y ^ n 1 < V g
n := n 1
fn  0 ^ y  x n = Y ^ n < V g
| {z }
J
(* definitions J and vf *)
fJ ^ vf < V g
23 / 36
Example: Designing a loop (4/4)

5 We conclude that the following program solves the problem:


fP : n  0 ^ xn = Y g
y := 1;
fJ : n  0 ^ y  x n = Y g
(* vf = n *)
while n 6= 0 do
y := y  x ;
n := n 1
end
fQ : y = Y g
Only precondition, invariant, variant function, and postcondition
are shown.

24 / 36
Example: Powers of 2

Compute the smallest power of 2 greater than a given natural x > 0:

const x : Z;
var i ; y : Z;
fP : x > 0g
T
fQ : x < y  2  x ^ y = 2i g
Examples:
I If x = 1 then y = 21 = 2.
I If x = 14 then y = 24 = 16.

25 / 36
Example: Designing a loop (1/4)

fP : x > 0g T fQ : x < y  2  x ^ y = 2i g
0 We assume that we repeatedly have to multiply y by 2.
We decide that we need a while-program.

26 / 36
Example: Designing a loop (1/4)

fP : x > 0g T fQ : x < y  2  x ^ y = 2i g
0 We assume that we repeatedly have to multiply y by 2.
We decide that we need a while-program.

1 Choose an invariant J and a guard B such that J ^ :B ) Q.


P is not very informative. We choose a part of Q:

J : y 2x ^ y = 2i

26 / 36
Example: Designing a loop (1/4)

fP : x > 0g T fQ : x < y  2  x ^ y = 2i g
0 We assume that we repeatedly have to multiply y by 2.
We decide that we need a while-program.

1 Choose an invariant J and a guard B such that J ^ :B ) Q.


P is not very informative. We choose a part of Q:

J : y 2x ^ y = 2i

For B , we choose :(x < y ):

B : y x
Clearly, we have: J ^ :B  Q.
26 / 36
Example: Designing a loop (2/4)
2 Initialization: Find a T0 such that

fP : x > 0g T0 fJ : y  2  x ^ y = 2i g
We proceed from bottom to top:
fx > 0g

fy  2  x ^ y = 2i g

27 / 36
Example: Designing a loop (2/4)
2 Initialization: Find a T0 such that

fP : x > 0g T0 fJ : y  2  x ^ y = 2i g
We proceed from bottom to top:
fx > 0g

f1  2  x ^ 1 = 2i g
y := 1
fy  2  x ^ y = 2i g

27 / 36
Example: Designing a loop (2/4)
2 Initialization: Find a T0 such that

fP : x > 0g T0 fJ : y  2  x ^ y = 2i g
We proceed from bottom to top:
fx > 0g
f1  2  x ^ 1 = 20g
i := 0;
f1  2  x ^ 1 = 2i g
y := 1
fy  2  x ^ y = 2i g

27 / 36
Example: Designing a loop (2/4)
2 Initialization: Find a T0 such that

fP : x > 0g T0 fJ : y  2  x ^ y = 2i g
We proceed from bottom to top:
fx > 0g
(* calculus *)
f1  2  x ^ 1 = 20g
i := 0;
f1  2  x ^ 1 = 2i g
y := 1
fy  2  x ^ y = 2i g

27 / 36
Example: Designing a loop (2/4)
2 Initialization: Find a T0 such that

fP : x > 0g T0 fJ : y  2  x ^ y = 2i g
We proceed from bottom to top:
fx > 0g
(* calculus *)
f1  2  x ^ 1 = 20g
i := 0;
f1  2  x ^ 1 = 2i g
y := 1
fy  2  x ^ y = 2i g
3 Variant function: Choose a vf 2 Z and prove J ^ B ) vf  0.
B : y  x implies that the program terminates if x y < 0.
To decrease x y in every step, we choose vf = x y 2 Z.
Since B  vf  0, it is clear that J ^ B ) vf  0 27 / 36
Example: Designing a loop (3/4)
4 Body of the loop: Find a S such that

fJ ^ B ^ vf = V g S fJ ^ vf < Vg

fJ ^ B ^ vf = V g

28 / 36
Example: Designing a loop (3/4)
4 Body of the loop: Find a S such that

fJ ^ B ^ vf = V g S fJ ^ vf < Vg

fJ ^ B ^ vf = V g
(* definitions J , B , and vf *)
fy|  2  x {z^ y = 2i ^ y  x
} | {z }
^ x y = Vg
J B

28 / 36
Example: Designing a loop (3/4)
4 Body of the loop: Find a S such that

fJ ^ B ^ vf = V g S fJ ^ vf < Vg

fJ ^ B ^ vf = V g
(* definitions J , B , and vf *)
fy|  2  x {z^ y = 2i ^ y  x
} | {z }
^ x y = Vg

(* calculus; logic; y = 2i ) y > 0; so x 2  y


J B
< x y *)
f2  y  2  x ^ 2  y = 2i +1 ^ x 2  y < V g

28 / 36
Example: Designing a loop (3/4)
4 Body of the loop: Find a S such that

fJ ^ B ^ vf = V g S fJ ^ vf < Vg

fJ ^ B ^ vf = V g
(* definitions J , B , and vf *)
fy|  2  x {z^ y = 2i ^ y  x
} | {z }
^ x y = Vg

(* calculus; logic; y = 2i ) y > 0; so x 2  y


J B
< x y *)
f2  y  2  x ^ 2  y = 2i +1 ^ x 2  y < V g
y := 2  y ;

28 / 36
Example: Designing a loop (3/4)
4 Body of the loop: Find a S such that

fJ ^ B ^ vf = V g S fJ ^ vf < Vg

fJ ^ B ^ vf = V g
(* definitions J , B , and vf *)
fy|  2  x {z^ y = 2i ^ y  x
} | {z }
^ x y = Vg

(* calculus; logic; y = 2i ) y > 0; so x 2  y


J B
< x y *)
f2  y  2  x ^ 2  y = 2i +1 ^ x 2  y < V g
y := 2  y ;
fy  2  x ^ y = 2i +1 ^ x y < V g

28 / 36
Example: Designing a loop (3/4)
4 Body of the loop: Find a S such that

fJ ^ B ^ vf = V g S fJ ^ vf < Vg

fJ ^ B ^ vf = V g
(* definitions J , B , and vf *)
fy|  2  x {z^ y = 2i ^ y  x
} | {z }
^ x y = Vg

(* calculus; logic; y = 2i ) y > 0; so x 2  y


J B
< x y *)
f2  y  2  x ^ 2  y = 2i +1 ^ x 2  y < V g
y := 2  y ;
fy  2  x ^ y = 2i +1 ^ x y < V g
i := i + 1;

28 / 36
Example: Designing a loop (3/4)
4 Body of the loop: Find a S such that

fJ ^ B ^ vf = V g S fJ ^ vf < Vg

fJ ^ B ^ vf = V g
(* definitions J , B , and vf *)
fy|  2  x {z^ y = 2i ^ y  x
} | {z }
^ x y = Vg

(* calculus; logic; y = 2i ) y > 0; so x 2  y


J B
< x y *)
f2  y  2  x ^ 2  y = 2i +1 ^ x 2  y < V g
y := 2  y ;
fy  2  x ^ y = 2i +1 ^ x y < V g
i := i + 1;
fy  2  x ^ y = 2i ^ x y < V g
| {z }
J

28 / 36
Example: Designing a loop (3/4)
4 Body of the loop: Find a S such that

fJ ^ B ^ vf = V g S fJ ^ vf < Vg

fJ ^ B ^ vf = V g
(* definitions J , B , and vf *)
fy|  2  x {z^ y = 2i ^ y  x
} | {z }
^ x y = Vg

(* calculus; logic; y = 2i ) y > 0; so x 2  y


J B
< x y *)
f2  y  2  x ^ 2  y = 2i +1 ^ x 2  y < V g
y := 2  y ;
fy  2  x ^ y = 2i +1 ^ x y < V g
i := i + 1;
fy  2  x ^ y = 2i ^ x y < V g
| {z }
J
(* definitions J and vf *)
fJ ^ vf < Vg
28 / 36
Example: Designing a loop (4/4)

5 We conclude that the following program solves the problem:


fP : x > 0g
i := 0;
y := 1;
fJ : y  2  x ^ y = 2i g
(* vf = x y *)
while y  x do
y := 2  y ;
i := i + 1
end
fQ : x < y  2  x ^ y = 2i g

29 / 36
Example: Euclid’s algorithm (gcd)

We consider the following specification for computing the greatest


common divisor of x and y, denoted gcd(x ; y ):

var x ; y : Z;
fP : x > 0 ^ y > 0 ^ gcd(x ; y ) = Z g
S
fQ : x = Z g

30 / 36
Example: Euclid’s algorithm (gcd)

Before we derive an algorithm, recall that if x ; y 2 Z and y > 0, then


x div y and x mod y are integers that satisfy

(x = y  (x div y ) + x mod y ) ^ 0  x mod y < y

31 / 36
Example: Euclid’s algorithm (gcd)

Before we derive an algorithm, recall that if x ; y 2 Z and y > 0, then


x div y and x mod y are integers that satisfy

(x = y (x div y ) + x mod y ) ^ 0  x mod y y <

Also, if z divides y, then (z divides i  y + j )  (z divides j ).

31 / 36
Example: Euclid’s algorithm (gcd)

Before we derive an algorithm, recall that if x ; y 2 Z and y > 0, then


x div y and x mod y are integers that satisfy

(x = y (x div y ) + x mod y ) ^ 0  x mod y y <

Also, if z divides y, then (z divides i  y + j )  (z divides j ).


Using these facts, we can prove that
- every common divisor of x and y > 0
is also
- a common divisor of y and x mod y (and vice versa).

31 / 36
Example: Euclid’s algorithm (gcd)

Before we derive an algorithm, recall that if x ; y 2 Z and y > 0, then


x div y and x mod y are integers that satisfy

(x = y (x div y ) + x mod y ) ^ 0  x mod y y <

Also, if z divides y, then (z divides i  y + j )  (z divides j ).


Using these facts, we can prove that
- every common divisor of x and y > 0
is also
- a common divisor of y and x mod y (and vice versa).

We can therefore use the recurrence:

x > 0 ) gcd(x ; 0) = x
y > 0 ) gcd(x ; y ) = gcd(y ; x mod y )

31 / 36
Example: Designing a loop (1/4)
fP : x > 0^y > 0 ^ gcd(x ; y ) = Z g
S
fQ : x = Zg
0 We decide that we need a while: Using the recurrence we
expect to decrease the values of x and y iteratively.

32 / 36
Example: Designing a loop (1/4)
fP : x > 0^y > 0 ^ gcd(x ; y ) = Z g
S
fQ : x = Zg
0 We decide that we need a while: Using the recurrence we
expect to decrease the values of x and y iteratively.
1 Choose an invariant J and a guard B such that J ^ :B ) Q.
J :x > 0^y  0 ^ gcd(x ; y) = Z
B :y 6= 0
Notice:
J ^ :B  x > 0^y  0 ^ gcd(x ; y) = Z ^y =0
flogic; substitution y = 0g
) x 0 ^ gcd(x 0) = Z
> ;

f gcd(x 0) = x g
;

)Q : x =Z
32 / 36
Example: Designing a loop (2/4)

Up to here:

P :x > 0^y > 0 ^ gcd(x ; y ) = Z


J :x > 0^y  0 ^ gcd(x ; y) = Z
B :y 6= 0
2 Initialization: Find a command T0 such that fP g T0 fJ g.
Because y > 0 ) y  0, we have P ) J .
Therefore, initialization is not necessary, and T0 = skip.
3 Variant function: Choose a vf 2 Z and prove J ^ B ) vf  0
Since J ensures y  0, we can simply choose vf = y.
Clearly, we have: J ^ B ) J ) y  0  vf  0.

33 / 36
Example: Designing a loop (3/4)
4 Body: Find S such that fJ ^ B ^ vf = V g S fJ ^ vf < Vg

fJ ^ B ^ vf = Vg

fJ ^ vf < Vg
34 / 36
Example: Designing a loop (3/4)
4 Body: Find S such that fJ ^ B ^ vf = V g S fJ ^ vf < Vg
fJ ^ B ^ vf =Vg
(* definitions J , B , and vf *)
fx > 0 ^ y  0 ^ gcd(x ; y ) = Z
| {z }
^ y =6 0 ^ y = V g
J

fJ ^ vf < Vg 34 / 36
Example: Designing a loop (3/4)
4 Body: Find S such that fJ ^ B ^ vf = V g S fJ ^ vf < Vg
fJ ^ B ^ vf Vg
=
(* definitions J , B , and vf *)
fx > 0 ^ y  0 ^ gcd(x ; y ) = Z
| {z }
^ y =6 0 ^ y = V g
0 ) gcd(x ; y ) = gcd(y ; x mod y ) *)
J
(* recurrence; y >

fJ ^ vf < Vg 34 / 36
Example: Designing a loop (3/4)
4 Body: Find S such that fJ ^ B ^ vf = V g S fJ ^ vf < Vg
fJ ^ B ^ vf =Vg
(* definitions J , B , and vf *)
fx > 0 ^ y  0 ^ gcd(x ; y ) = Z
| {z }
^ y =6 0 ^ y = V g
(* recurrence; y > 0 ) gcd(x ; y ) = gcd(y ; x mod y ) *)
J

fy > 0 ^ gcd(y ; x mod y ) = Z ^ 0  x mod y < y = V g

fJ ^ vf < Vg 34 / 36
Example: Designing a loop (3/4)
4 Body: Find S such that fJ ^ B ^ vf = V g S fJ ^ vf < Vg
fJ ^ B ^ vf =Vg
(* definitions J , B , and vf *)
fx > 0 ^ y  0 ^ gcd(x ; y ) = Z
| {z }
^ y =6 0 ^ y = V g
(* recurrence; y > 0 ) gcd(x ; y ) = gcd(y ; x mod y ) *)
J

fy > 0 ^ gcd(y ; x mod y ) = Z ^ 0  x mod y < y = V g


m := x mod y ;
fy > 0 ^ gcd(y ; m ) = Z ^ 0  m < y = V g

fJ ^ vf < Vg 34 / 36
Example: Designing a loop (3/4)
4 Body: Find S such that fJ ^ B ^ vf = V g S fJ ^ vf < Vg
fJ ^ B ^ vf =Vg
(* definitions J , B , and vf *)
fx > 0 ^ y  0 ^ gcd(x ; y ) = Z
| {z }
^ y =6 0 ^ y = V g
(* recurrence; y > 0 ) gcd(x ; y ) = gcd(y ; x mod y ) *)
J

fy > 0 ^ gcd(y ; x mod y ) = Z ^ 0  x mod y < y = V g


m := x mod y ;
fy > 0 ^ gcd(y ; m ) = Z ^ 0  m < y = V g
(* logic *)
fy > 0 ^ gcd(y ; m ) = Z ^ m  0 ^ m < V g

fJ ^ vf < Vg 34 / 36
Example: Designing a loop (3/4)
4 Body: Find S such that fJ ^ B ^ vf = V g S fJ ^ vf < Vg
fJ ^ B ^ vf =Vg
(* definitions J , B , and vf *)
fx > 0 ^ y  0 ^ gcd(x ; y ) = Z
| {z }
^ y =6 0 ^ y = V g
(* recurrence; y > 0 ) gcd(x ; y ) = gcd(y ; x mod y ) *)
J

fy > 0 ^ gcd(y ; x mod y ) = Z ^ 0  x mod y < y = V g


m := x mod y ;
fy > 0 ^ gcd(y ; m ) = Z ^ 0  m < y = V g
(* logic *)
fy > 0 ^ gcd(y ; m ) = Z ^ m  0 ^ m < V g
x := y ;
fx > 0 ^ gcd(x ; m ) = Z ^ m  0 ^ m < V g

fJ ^ vf < Vg 34 / 36
Example: Designing a loop (3/4)
4 Body: Find S such that fJ ^ B ^ vf = V g S fJ ^ vf < Vg
fJ ^ B ^ vf =Vg
(* definitions J , B , and vf *)
fx > 0 ^ y  0 ^ gcd(x ; y ) = Z
| {z }
^ y =6 0 ^ y = V g
(* recurrence; y > 0 ) gcd(x ; y ) = gcd(y ; x mod y ) *)
J

fy > 0 ^ gcd(y ; x mod y ) = Z ^ 0  x mod y < y = V g


m := x mod y ;
fy > 0 ^ gcd(y ; m ) = Z ^ 0  m < y = V g
(* logic *)
fy > 0 ^ gcd(y ; m ) = Z ^ m  0 ^ m < V g
x := y ;
fx > 0 ^ gcd(x ; m ) = Z ^ m  0 ^ m < V g
y := m ;
fx > 0 ^ gcd(x ; y ) = Z ^ y  0 ^ y < V g
fJ ^ vf < Vg 34 / 36
Example: Designing a loop (3/4)
4 Body: Find S such that fJ ^ B ^ vf = V g S fJ ^ vf < Vg
fJ ^ B ^ vf = Vg
(* definitions J , B , and vf *)
fx > 0 ^ y  0 ^ gcd(x ; y ) = Z
| {z }
^ y =6 0 ^ y = V g
(* recurrence; y > 0 ) gcd(x ; y ) = gcd(y ; x mod y ) *)
J

fy > 0 ^ gcd(y ; x mod y ) = Z ^ 0  x mod y < y = V g


m := x mod y ;
fy > 0 ^ gcd(y ; m ) = Z ^ 0  m < y = V g
(* logic *)
fy > 0 ^ gcd(y ; m ) = Z ^ m  0 ^ m < V g
x := y ;
fx > 0 ^ gcd(x ; m ) = Z ^ m  0 ^ m < V g
y := m ;
fx > 0 ^ gcd(x ; y ) = Z ^ y  0 ^ y < V g
(* definitions J and vf *)
fJ ^ vf < V g 34 / 36
Example: Designing a loop (4/4)

5 We found the following program fragment (Euclid’s algorithm):


var x ; y ; m : Z;
fP : x > 0 ^ y > 0 ^ gcd(x ; y ) = Z g
fJ : x > 0 ^ y  0 ^ gcd(x ; y ) = Z g
(* vf = y *)
while y 6= 0 do
m := x mod y ;
x := y ;
y := m ;
end;
fQ : x = Z g

35 / 36
The End
I Up to here we have covered until Section 6.4 of the reader
Don’t forget to attend the tutorials!
I Next time: Active finalization, heuristics for finding invariants

36 / 36

You might also like