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

Program Correctness

Block 6

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

Bernoulli Institute for Mathematics, Computer Science, and AI


University of Groningen, Groningen, the Netherlands

March 10, 2023


Adding Information to the Invariant

I Following the roadmap entails determining an invariant J , a


guard B , and a postcondition Q such that

J ^ :B ) Q

2 / 45
Adding Information to the Invariant

I Following the roadmap entails determining an invariant J , a


guard B , and a postcondition Q such that

J ^ :B ) Q
I Adding conjuncts to J makes it stronger:

(|J ^ J1 ^{z    ^ Jn
}
) J)
J0

I This is safe:

(J ^ :B ) Q ) ^ (J ) J ) ) (J ^ :B ) Q )
0 0

We illustrate this technique on a number of examples.

2 / 45
Outline

Longest positive subsequence (LPS)

Exercise 10.1

Exercise 10.2

Exercise 10.13

3 / 45
Longest positive subsequence (LPS)

Given n 2 N+ and an array a [0::n ) of Z, compute the length of the


longest subsequence of [0::n ) for which a is positive.
Example: A simple array a [0::9):

-1 4 5 0 -3 6 4 2 0
0 1 2 3 4 5 6 7 8

4 / 45
Longest positive subsequence (LPS)

Given n 2 N+ and an array a [0::n ) of Z, compute the length of the


longest subsequence of [0::n ) for which a is positive.
Example: A simple array a [0::9):

-1 4 5 0 -3 6 4 2 0
0 1 2 3 4 5 6 7 8

Two positive subsequences: (4; 5) and (6; 4; 2).

4 / 45
Longest positive subsequence (LPS)

Given n 2 N+ and an array a [0::n ) of Z, compute the length of the


longest subsequence of [0::n ) for which a is positive.
Example: A simple array a [0::9):

-1 4 5 0 -3 6 4 2 0
0 1 2 3 4 5 6 7 8

Two positive subsequences: (4; 5) and (6; 4; 2).


A predicate to characterize the interval where the LPS occurs:
I C (p ; q )  (8i 2 [p ; q ) : a [i ] > 0) defines subsequences.
Above, we have C (1; 3) and C (5; 8).
Note: C (p ; p ) holds for any p.

4 / 45
LPS

How to define the LPS in terms of minimum and maximum?


I Consider the set below, with q being a fixed extreme for the
subsequences:

Min fp j p : 0  p  q ^ C (p q )g
;

Note: the minimum p gives us the longest subsequence for q.

5 / 45
LPS

How to define the LPS in terms of minimum and maximum?


I Consider the set below, with q being a fixed extreme for the
subsequences:

Min fp j p : 0  p  q ^ C (p q )g
;

Note: the minimum p gives us the longest subsequence for q.


I We need something more general, for arbitrary extremes:

Max fq p j p; q : 0  p  q  n ^ C (p q )g
;

Note: we maximize the difference between the extremes.

5 / 45
LPS

Using the predicate

C (p ; q )  (8i 2 [p q ) : a [i ]
; > 0)

we can now specify the problem as follows:

const n : N+ ; a : array [0::n ) of Z;


var z : Z;
fP : trueg
C
fQ : z = Max fq p j p ; q : 0  p  q  n ^ C (p q )gg;

6 / 45
LPS

Up to here we have

C (p ; q )  (8i
2 [p q ) : a [i ] 0)
; >

Q : z = Max fq p j p q : 0  p  q  n ^ C (p q )g
; ;

We replace the constant n by variable k in Q. We define:

L(k ) = Max fq p j p; q : 0  p  q  k ^ C (p q )g
;

and we rewrite Q as z = L(n ).

7 / 45
LPS: Rewriting L(k )

Let’s define (actually, recall) the following:

E (q ) = Min fp j p : 0  p  q ^ C (p q )g
;

8 / 45
LPS: Rewriting L(k )

Let’s define (actually, recall) the following:

E (q ) = Min fp j p : 0  p  q ^ C (p q )g
;

We can now rewrite L(k ):

L(k ) = Max fq p j p; q : 0  p  q  k ^ C (p q )g
;

8 / 45
LPS: Rewriting L(k )

Let’s define (actually, recall) the following:

E (q ) = Min fp j p : 0  p  q ^ C (p q )g
;

We can now rewrite L(k ):

L(k ) = Max fq p j p; q : 0  p  q  k ^ C (p q )g ;

= Max fMax fq p j p : 0  p  q ^ C (p q )g j q : q  k g
;

8 / 45
LPS: Rewriting L(k )

Let’s define (actually, recall) the following:

E (q ) = Min fp j p : 0  p  q ^ C (p q )g
;

We can now rewrite L(k ):

L(k ) = Max fq p j p; q : 0  p
 q  k ^ C (p q )g ;

= Max fMax fq p j p : 0  p  q ^ C (p q )g j q : q  k g
;

= Max fq + Max f p j p : 0  p  q ^ C (p q )g j q : q  k g
;

8 / 45
LPS: Rewriting L(k )

Let’s define (actually, recall) the following:

E (q ) = Min fp j p : 0  p  q ^ C (p q )g
;

We can now rewrite L(k ):

L(k ) = Max fq p j p; q : 0  p
 q  k ^ C (p q )g ;

= Max fMax fq p j p : 0  p  q ^ C (p q )g j q : q  k g
;

= Max fq + Max f p j p : 0  p  q ^ C (p q )g j q : q  k g
;

= Max fq Min fp j p : 0  p  q ^ C (p q )g j q : q  k g
;
| {z }
E (q )

8 / 45
LPS: Rewriting L(k )

Let’s define (actually, recall) the following:

E (q ) = Min fp j p : 0  p  q ^ C (p q )g
;

We can now rewrite L(k ):

L(k ) = Max fq p j p; q : 0  p
 q  k ^ C (p q )g ;

= Max fMax fq p j p : 0  p  q ^ C (p q )g j q : q  k g
;

= Max fq + Max f p j p : 0  p  q ^ C (p q )g j q : q  k g
;

= Max fq Min fp j p : 0  p  q ^ C (p q )g j q : q  k g
;
| {z }
E (q )
= Max fq E (q ) j q : q  kg

8 / 45
LPS: Examining L(k )

The idea is to increment k in each iteration.


Let us first examine L(k + 1):

9 / 45
LPS: Examining L(k )

The idea is to increment k in each iteration.


Let us first examine L(k + 1):

L(k + 1)
= {definition L}
Max fq E (q ) j q : q  k + 1g

9 / 45
LPS: Examining L(k )

The idea is to increment k in each iteration.


Let us first examine L(k + 1):

L(k + 1)
= {definition L}
Max fq E (q ) j q : q  k + 1g
= {split domain: q  k _ q = k + 1}
Max fq E (q ) j q : q  k g max (k +1 E (k + 1))

9 / 45
LPS: Examining L(k )

The idea is to increment k in each iteration.


Let us first examine L(k + 1):

L(k + 1)
= {definition L}
Max fq E (q ) j q : q  k + 1g
= {split domain: q  k _ q = k + 1}
Max fq E (q ) j q : q  k g max (k +1 E (k + 1))
= {definition L}
L(k ) max (k + 1 E (k + 1))

We now examine E (k + 1). Note that:


I C (p ; q + 1)  C (p ; q ) ^ a [q ] > 0
I E (q )  q (for every q  0)

9 / 45
LPS: Examining E (k ) (1/2)

E (k + 1)
= {definition E }
Min fp j p : 0  p  k + 1 ^ C (p k + 1)g
;

10 / 45
LPS: Examining E (k ) (1/2)

E (k + 1)
= {definition E }
Min fp j p : 0  p  k + 1 ^ C (p ; k + 1)g
= {assume k  0; split domain: p  k _ p = k + 1; use C (k + 1 k + 1)}
;

10 / 45
LPS: Examining E (k ) (1/2)

E (k + 1)
= {definition E }
Min fp j p : 0  p  k + 1 ^ C (p ; k + 1)g
= {assume k  0; split domain: p  k _ p = k + 1; use C (k + 1 k + 1)}
;

Min fp j p : 0  p  k ^ C (p ; k + 1)g min (k + 1)

10 / 45
LPS: Examining E (k ) (1/2)

E (k + 1)
= {definition E }
Min fp j p : 0  p  k + 1 ^ C (p ; k + 1)g
= {assume k  0; split domain: p  k _ p = k + 1; use C (k + 1; k + 1)}
Min fp j p : 0  p  k ^ C (p ; k + 1)g min (k + 1)
= {(8i 2 [p ; k + 1) : a [i ] > 0)  (a [k ] > 0 ^ (8i 2 [p ; k ) : a [i ] > 0))}
Min fp j p : 0  p  k ^ C (p ; k ) ^ a [k ] > 0g min (k + 1)

10 / 45
LPS: Examining E (k ) (1/2)

E (k + 1)
= {definition E }
Min fp j p : 0  p  k + 1 ^ C (p ; k + 1)g
= {assume k  0; split domain: p  k _ p = k + 1; use C (k + 1; k + 1)}
Min fp j p : 0  p  k ^ C (p ; k + 1)g min (k + 1)
= {(8i 2 [p ; k + 1) : a [i ] > 0)  (a [k ] > 0 ^ (8i 2 [p ; k ) : a [i ] > 0))}
Min fp j p : 0  p  k ^ C (p ; k ) ^ a [k ] > 0g min (k + 1)
= {assume a [k ] > 0}
Min fp j p : 0  p  k ^ C (p ; k )g min (k + 1)

10 / 45
LPS: Examining E (k ) (1/2)

E (k + 1)
= {definition E }
Min fp j p : 0  p  k + 1 ^ C (p ; k + 1)g
= {assume k  0; split domain: p  k _ p = k + 1; use C (k + 1; k + 1)}
Min fp j p : 0  p  k ^ C (p ; k + 1)g min (k + 1)
= {(8i 2 [p ; k + 1) : a [i ] > 0)  (a [k ] > 0 ^ (8i 2 [p ; k ) : a [i ] > 0))}
Min fp j p : 0  p  k ^ C (p ; k ) ^ a [k ] > 0g min (k + 1)
= {assume a [k ] > 0}
Min fp j p : 0  p  k ^ C (p ; k )g min (k + 1)
= {Min fp j p : 0  p  k ^ C (p ; k )g  k < k + 1}

10 / 45
LPS: Examining E (k ) (1/2)

E (k + 1)
= {definition E }
Min fp j p : 0  p  k + 1 ^ C (p ; k + 1)g
= {assume k  0; split domain: p  k _ p = k + 1; use C (k + 1; k + 1)}
Min fp j p : 0  p  k ^ C (p ; k + 1)g min (k + 1)
= {(8i 2 [p ; k + 1) : a [i ] > 0)  (a [k ] > 0 ^ (8i 2 [p ; k ) : a [i ] > 0))}
Min fp j p : 0  p  k ^ C (p ; k ) ^ a [k ] > 0g min (k + 1)
= {assume a [k ] > 0}
Min fp j p : 0  p  k ^ C (p ; k )g min (k + 1)
= {Min fp j p : 0  p  k ^ C (p ; k )g  k < k + 1}
Min fp j p : 0  p  k ^ C (p ; k )g

10 / 45
LPS: Examining E (k ) (1/2)

E (k + 1)
= {definition E }
Min fp j p : 0  p  k + 1 ^ C (p ; k + 1)g
= {assume k  0; split domain: p  k _ p = k + 1; use C (k + 1; k + 1)}
Min fp j p : 0  p  k ^ C (p ; k + 1)g min (k + 1)
= {(8i 2 [p ; k + 1) : a [i ] > 0)  (a [k ] > 0 ^ (8i 2 [p ; k ) : a [i ] > 0))}
Min fp j p : 0  p  k ^ C (p ; k ) ^ a [k ] > 0g min (k + 1)
= {assume a [k ] > 0}
Min fp j p : 0  p  k ^ C (p ; k )g min (k + 1)
= {Min fp j p : 0  p  k ^ C (p ; k )g  k < k + 1}
Min fp j p : 0  p  k ^ C (p ; k )g
= {definition E }
E (k )

10 / 45
LPS: Examining E (k ) (2/2)

11 / 45
LPS: Examining E (k ) (2/2)

E ( k + 1)
= {see previous slide}
Min fp j p : 0  p  k ^ C (p k ) ^ a [k ]
; > 0g min (k + 1)

11 / 45
LPS: Examining E (k ) (2/2)

E ( k + 1)
= {see previous slide}
Min fp j p : 0  p  k ^ C (p ; k ) ^ a [k ] > 0g min (k + 1)
= {assume a [k ]  0}
Min fp j p : falseg min (k + 1)

11 / 45
LPS: Examining E (k ) (2/2)

E ( k + 1)
= {see previous slide}
Min fp j p : 0  p  k ^ C (p ; k ) ^ a [k ] > 0g min (k + 1)
= {assume a [k ]  0}
Min fp j p : falseg min (k + 1)
= {Minimum over empty domain is 1}
k +1

11 / 45
LPS: Recurrences

For the following definitions

L(k ) = Max fq E (q ) j q : q  k g
E (k ) = Min fp j p : 0  p  k ^ C (p k )g
;

C (p q )  (8i 2 [p q ) : a [i ] 0)
; ; >

We found the recurrences:

L(0) = 0
E (0) = 0
k 0 ) L( k+ 1) = L(k ) max (k + 1 E (k + 1))
k 0 ) E (k + 1) = (a [k ] 0 ? E (k ) : k + 1)
>

12 / 45
LSP: Invariant & Variant
0 We decide that we need a while-program.

1 Choose an invariant J and guard B .


Since Q  z = L(n ), we want to keep z = L(k ) invariant, while
we increment k :

J : z = L(k ) ^ 0  k  n ^ y = E (k )
Clearly, we choose B 6 n, such that J ^ :B ) Q.
: k=

13 / 45
LSP: Invariant & Variant
0 We decide that we need a while-program.

1 Choose an invariant J and guard B .


Since Q  z = L(n ), we want to keep z = L(k ) invariant, while
we increment k :

J : z = L(k ) ^ 0  k  n ^ y = E (k )
Clearly, we choose B 6 n, such that J ^ :B ) Q.
: k=
2 Initialization: The initialization is easy.
fP : trueg
(* base cases recurrences; calculus; n 2 N+ *)
f0 = L(0) ^ 0  0  n ^ 0 = E (0)g
z := 0; k := 0; y := 0;
fJ : z = L(k ) ^ 0  k  n ^ y = E (k )g
13 / 45
LSP: Invariant & Variant
0 We decide that we need a while-program.

1 Choose an invariant J and guard B .


Since Q  z = L(n ), we want to keep z = L(k ) invariant, while
we increment k :

J : z = L(k ) ^ 0  k  n ^ y = E (k )
Clearly, we choose B 6 n, such that J ^ :B ) Q.
: k=
2 Initialization: The initialization is easy.
fP : trueg
(* base cases recurrences; calculus; n 2 N+ *)
f0 = L(0) ^ 0  0  n ^ 0 = E (0)g
z := 0; k := 0; y := 0;
fJ : z = L(k ) ^ 0  k  n ^ y = E (k )g
3 Variant function: vf =n k 2 Z. Clearly, J ^ B ) vf  0.
13 / 45
LPS: Body of the Loop

fJ ^ B ^ vf = V g

fJ ^ vf < Vg

14 / 45
LPS: Body of the Loop

fJ ^ B ^ vf = V g
(* definitions J , B , and vf *)
f z = L( k ) ^ 0  k < n ^ y = E (k ) ^n k = Vg

fJ ^ vf < Vg

14 / 45
LPS: Body of the Loop

fJ ^ B ^ vf = V g
(* definitions J , B , and vf *)
f z = L( k ) ^ 0  k < n ^ y = E (k ) ^n k = Vg

y := (a [k ] > 0?y :k + 1);

z := z max (k + 1 y );

k := k + 1;

fJ ^ vf < Vg

14 / 45
LPS: Body of the Loop

fJ ^ B ^ vf = V g
(* definitions J , B , and vf *)
f z = L( k ) ^ 0  k < n ^ y = E (k ) ^ n k = Vg
(* recurrence (a [k ] > 0 ? E (k ) : k + 1) = E (k + 1); substitution *)
fz = L(k ) ^ 0  k < n ^ (a [k ] > 0 ? y : k + 1) = E (k + 1) ^ n k = Vg
y := (a [k ] > 0 ? y : k + 1);

z := z max (k + 1 y );

k := k + 1;

fJ ^ vf < Vg

14 / 45
LPS: Body of the Loop

fJ ^ B ^ vf = V g
(* definitions J , B , and vf *)
f z = L( k ) ^ 0  k < n ^ y = E (k ) ^ n k = Vg
(* recurrence (a [k ] > 0 ? E (k ) : k + 1) = E (k + 1); substitution *)
fz = L(k ) ^ 0  k < n ^ (a [k ] > 0 ? y : k + 1) = E (k + 1) ^ n k = Vg
y := (a [k ] > 0 ? y : k + 1);
fz = L(k ) ^ 0  k < n ^ y = E (k + 1) ^ n k = V g

z := z max (k + 1 y );

k := k + 1;

fJ ^ vf < Vg

14 / 45
LPS: Body of the Loop

fJ ^ B ^ vf = V g
(* definitions J , B , and vf *)
f z = L( k ) ^ 0  k < n ^ y = E (k ) ^ n k = Vg
(* recurrence (a [k ] > 0 ? E (k ) : k + 1) = E (k + 1); substitution *)
fz = L(k ) ^ 0  k < n ^ (a [k ] > 0 ? y : k + 1) = E (k + 1) ^ n k = V g
y := (a [k ] > 0 ? y : k + 1);
fz = L(k ) ^ 0  k < n ^ y = E (k + 1) ^ n k = V g
(* recurrence L(k + 1) = L(k ) max (k + 1 E (k + 1)); substitution *)
fz max (k + 1 y ) = L(k + 1) ^ 0  k < n ^ y = E (k + 1) ^ n k = V g
z := z max (k + 1 y );

k := k + 1;

fJ ^ vf < Vg

14 / 45
LPS: Body of the Loop

fJ ^ B ^ vf = V g
(* definitions J , B , and vf *)
f z = L( k ) ^ 0  k < n ^ y = E (k ) ^ n k = Vg
(* recurrence (a [k ] > 0 ? E (k ) : k + 1) = E (k + 1); substitution *)
fz = L(k ) ^ 0  k < n ^ (a [k ] > 0 ? y : k + 1) = E (k + 1) ^ n k = V g
y := (a [k ] > 0 ? y : k + 1);
fz = L(k ) ^ 0  k < n ^ y = E (k + 1) ^ n k = V g
(* recurrence L(k + 1) = L(k ) max (k + 1 E (k + 1)); substitution *)
fz max (k + 1 y ) = L(k + 1) ^ 0  k < n ^ y = E (k + 1) ^ n k = V g
z := z max (k + 1 y );
fz = L(k + 1) ^ 0  k < n ^ y = E (k + 1) ^ n k = V g

k := k + 1;

fJ ^ vf < Vg

14 / 45
LPS: Body of the Loop

fJ ^ B ^ vf = V g
(* definitions J , B , and vf *)
f z = L( k ) ^ 0  k < n ^ y = E (k ) ^ n k = Vg
(* recurrence (a [k ] > 0 ? E (k ) : k + 1) = E (k + 1); substitution *)
fz = L(k ) ^ 0  k < n ^ (a [k ] > 0 ? y : k + 1) = E (k + 1) ^ n k = V g
y := (a [k ] > 0 ? y : k + 1);
fz = L(k ) ^ 0  k < n ^ y = E (k + 1) ^ n k = V g
(* recurrence L(k + 1) = L(k ) max (k + 1 E (k + 1)); substitution *)
fz max (k + 1 y ) = L(k + 1) ^ 0  k < n ^ y = E (k + 1) ^ n k = V g
z := z max (k + 1 y );
fz = L(k + 1) ^ 0  k < n ^ y = E (k + 1) ^ n k = V g
(* prepare k := k + 1 *)
fz = L(k + 1) ^ 0  k + 1  n ^ y = E (k + 1) ^ n (k + 1) < V g
k := k + 1;

fJ ^ vf < Vg

14 / 45
LPS: Body of the Loop

fJ ^ B ^ vf = V g
(* definitions J , B , and vf *)
f z = L( k ) ^ 0  k < n ^ y = E (k ) ^ n k = Vg
(* recurrence (a [k ] > 0 ? E (k ) : k + 1) = E (k + 1); substitution *)
fz = L(k ) ^ 0  k < n ^ (a [k ] > 0 ? y : k + 1) = E (k + 1) ^ n k = V g
y := (a [k ] > 0 ? y : k + 1);
fz = L(k ) ^ 0  k < n ^ y = E (k + 1) ^ n k = V g
(* recurrence L(k + 1) = L(k ) max (k + 1 E (k + 1)); substitution *)
fz max (k + 1 y ) = L(k + 1) ^ 0  k < n ^ y = E (k + 1) ^ n k = V g
z := z max (k + 1 y );
fz = L(k + 1) ^ 0  k < n ^ y = E (k + 1) ^ n k = V g
(* prepare k := k + 1 *)
fz = L(k + 1) ^ 0  k + 1  n ^ y = E (k + 1) ^ n (k + 1) < V g
k := k + 1;
fz = L(k ) ^ 0  k  n ^ y = E (k ) ^ n k < V g
fJ ^ vf < Vg

14 / 45
LPS: Body of the Loop

fJ ^ B ^ vf = V g
(* definitions J , B , and vf *)
f z = L( k ) ^ 0  k < n ^ y = E (k ) ^ n k = Vg
(* recurrence (a [k ] > 0 ? E (k ) : k + 1) = E (k + 1); substitution *)
fz = L(k ) ^ 0  k < n ^ (a [k ] > 0 ? y : k + 1) = E (k + 1) ^ n k = V g
y := (a [k ] > 0 ? y : k + 1);
fz = L(k ) ^ 0  k < n ^ y = E (k + 1) ^ n k = V g
(* recurrence L(k + 1) = L(k ) max (k + 1 E (k + 1)); substitution *)
fz max (k + 1 y ) = L(k + 1) ^ 0  k < n ^ y = E (k + 1) ^ n k = V g
z := z max (k + 1 y );
fz = L(k + 1) ^ 0  k < n ^ y = E (k + 1) ^ n k = V g
(* prepare k := k + 1 *)
fz = L(k + 1) ^ 0  k + 1  n ^ y = E (k + 1) ^ n (k + 1) < V g
k := k + 1;
fz = L(k ) ^ 0  k  n ^ y = E (k ) ^ n k < V g
(* definitions J , and vf *)
fJ ^ vf < V g
14 / 45
LPS: Conclusion

We derived the program fragment:

const n : N+ ; a : array [0::n ) of Z;


var z ; k ; y : Z;
fP : trueg
z := 0; k := 0; y := 0;
fJ : z = L(k ) ^ 0  k  n ^ y = E (k )g
(* vf = n k *)
while k 6= n do
y := (a [k ] > 0 ? y : k + 1);
z := z max (k + 1 y );
k := k + 1;
end;
fQ : z = Max fq p j p ; q : 0  p  q  n ^ (8i 2 [p q ) : a [i ]
; > 0)gg

15 / 45
Outline

Longest positive subsequence (LPS)

Exercise 10.1

Exercise 10.2

Exercise 10.13

16 / 45
Exercises 10.1, 10.2, and 10.3

We now move on to discuss further exercises:


I Exercise 10.1 shows how a careful development of the
recurrence relation leads to substantial improvements in time
complexity.
I Exercise 10.2 presents clear differences wrt previous exercises,
and is arguably the most interesting one.
I Exercise 10.3 involves two different arrays.

17 / 45
Exercise 10.1

Derive a command to compute

(a [i ]  a [j ]  a [k ] j i ; j;k : 0  i < j k < n)

18 / 45
Exercise 10.1

Derive a command to compute

(a [i ]  a [j ]  a [k ] j i ; j;k : 0  i < j k < n)

Formally, find a command C that satisfies the specification:

const n : N+ ; a : array [0::n ) of Z;


var s : Z;
fP : trueg
C
fQ : s = (a [i ]  a [j ]  a [k ] j i ; j ; k : 0  i < j k < n )g

18 / 45
Exercise 10.1: Naive Solution
const n : N+ ; a : array [0::n ) of Z;
var i ; j ; k ; s : Z;
fP : trueg
s := 0; i := 0;
while i < n 1 do
j := i + 1;
while j < n do
k := j ;
while k < n do
s := s + a [i ]  a [j ]  a [k ];
k := k + 1;
end;
j := j + 1;
end;
i := i + 1;
end;
fQ : s = (a [i ]  a [j ]  a [k ] j i ; j ; k : 0  i < j k < n )g

Time complexity is O (n 3 ). We can do better!


19 / 45
Exercise 10.1: Guard & First Invariant

We start by introducing

S (x ) = (a [i ]  a [j ]  a [k ] j i ; j ; k : 0  i < j k < x)

We can rewrite the postcondition: Q : s = S (n )

20 / 45
Exercise 10.1: Guard & First Invariant

We start by introducing

S (x ) = (a [i ]  a [j ]  a [k ] j i ; j ; k : 0  i < j k < x)

We can rewrite the postcondition: Q : s = S (n )


0 We decide that we need a while-program.

1 Choose an invariant J and guard B .


As a first attempt we introduce a variable x and try to maintain

J :s = S (x ) ^ 1  x  n
Clearly, we choose B : x 6= n, such that J ^ :B ) Q.

20 / 45
Exercise 10.1: Guard & First Invariant

We start by introducing

S (x ) = (a [i ]  a [j ]  a [k ] j i ; j ; k : 0  i < j k < x)

We can rewrite the postcondition: Q : s = S (n )


0 We decide that we need a while-program.

1 Choose an invariant J and guard B .


As a first attempt we introduce a variable x and try to maintain

J :s = S (x ) ^ 1  x  n
Clearly, we choose B : x 6= n, such that J ^ :B ) Q.
We will examine the definition of S (x ) to strengthen J .

20 / 45
Exercise 10.1: Examining S (x )

The loop will proceed by incrementing x , so we first have a look at S (x + 1):

S (x + 1)
= {definition S }
(a [i ]  a [j ]  a [k ] j i ; j ; k : 0  i < j k < x + 1)

21 / 45
Exercise 10.1: Examining S (x )

The loop will proceed by incrementing x , so we first have a look at S (x + 1):

S (x + 1)
= {definition S }
(a [i ]  a [j ]  a [k ] j i ; j ; k : 0  i < j  k < x + 1)
= {assume x  1; split domain: k < x _ k = x }
(a [i ]  a [j ]  a [k ] j i ; j ; k : 0  i < j  k < x )
+
(a [i ]  a [j ]  a [x ] j i j : 0  i
; < j  x)

21 / 45
Exercise 10.1: Examining S (x )

The loop will proceed by incrementing x , so we first have a look at S (x + 1):

S (x + 1)
= {definition S }
(a [i ]  a [j ]  a [k ] j i ; j ; k : 0  i < j  k < x + 1)
= {assume x  1; split domain: k < x _ k = x }
(a [i ]  a [j ]  a [k ] j i ; j ; k : 0  i < j  k < x )
+
(a [i ]  a [j ]  a [x ] j i j : 0  i
; < j  x)

= {definition S and calculus}


S (x ) + a [x ]  (a [i ]  a [j ] j i ; j : 0  i < j  x)

21 / 45
Exercise 10.1: Examining S (x )

The loop will proceed by incrementing x , so we first have a look at S (x + 1):

S (x + 1)
= {definition S }
(a [i ]  a [j ]  a [k ] j i ; j ; k : 0  i < j  k < x + 1)
= {assume x  1; split domain: k < x _ k = x }
(a [i ]  a [j ]  a [k ] j i ; j ; k : 0  i < j  k < x )
+
(a [i ]  a [j ]  a [x ] j i j : 0  i
; < j  x)

= {definition S and calculus}


S (x ) + a [x ]  (a [i ]  a [j ] j i ; j : 0  i < j  x)
= {we prefer half-open intervals}
S (x ) + a [x ]  (a [i ]  a [j ] j i ; j : 0  i < j < x + 1)

21 / 45
Exercise 10.1: Examining S (x )

The loop will proceed by incrementing x , so we first have a look at S (x + 1):

S (x + 1)
= {definition S }
(a [i ]  a [j ]  a [k ] j i ; j ; k : 0  i < j  k < x + 1)
= {assume x  1; split domain: k < x _ k = x }
(a [i ]  a [j ]  a [k ] j i ; j ; k : 0  i < j  k < x )
+
(a [i ]  a [j ]  a [x ] j i j : 0  i
; < j  x)

= {definition S and calculus}


S (x ) + a [x ]  (a [i ]  a [j ] j i ; j : 0  i < j  x )
= {we prefer half-open intervals}
S (x ) + a [x ]  (a [i ]  a [j ] j i ; j : 0  i < j < x + 1)
= {introduce T }
S (x ) + a [x ]  T (x + 1) where T (x ) = (a [i ]  a [j ] j i ; j : 0  i < j < x)

So, if we want to increment x , we need T (x + 1).


21 / 45
Exercise 10.1: Examining T (x + 1)

T (x + 1)
= {definition T }
(a [i ]  a [j ] j i ; j : 0  i < j < x + 1)

22 / 45
Exercise 10.1: Examining T (x + 1)

T (x + 1)
= {definition T }
(a [i ]  a [j ] j i ; j : 0  i < j < x + 1)
= {assume x  1; split domain: j < x _ j = x }
(a [i ]  a [j ] j i ; j ; k : 0  i < j < x ) + (a [i ]  a [x ] j i : 0  i < x)

22 / 45
Exercise 10.1: Examining T (x + 1)

T (x + 1)
= {definition T }
(a [i ]  a [j ] j i ; j : 0  i < j < x + 1)
= {assume x  1; split domain: j < x _ j = x }
(a [i ]  a [j ] j i ; j ; k : 0  i < j < x ) + (a [i ]  a [x ] j i : 0  i < x)
= {definition T ; calculus}
T (x ) + a [x ]  (a [i ] j i : 0  i < x )

22 / 45
Exercise 10.1: Examining T (x + 1)

T (x + 1)
= {definition T }
(a [i ]  a [j ] j i ; j : 0  i < j < x + 1)
= {assume x  1; split domain: j < x _ j = x }
(a [i ]  a [j ] j i ; j ; k : 0  i < j < x ) + (a [i ]  a [x ] j i : 0  i < x)
= {definition T ; calculus}
T (x ) + a [x ]  (a [i ] j i : 0  i < x )
= {introduce U }
T (x ) + a [x ]  U (x ) where U (x ) = (a [i ] j i : 0  i < x )

22 / 45
Exercise 10.1: Examining T (x + 1)

T (x + 1)
= {definition T }
(a [i ]  a [j ] j i ; j : 0  i < j < x + 1)
= {assume x  1; split domain: j < x _ j = x }
(a [i ]  a [j ] j i ; j ; k : 0  i < j < x ) + (a [i ]  a [x ] j i : 0  i < x)
= {definition T ; calculus}
T (x ) + a [x ]  (a [i ] j i : 0  i < x )
= {introduce U }
T (x ) + a [x ]  U (x ) where U (x ) = (a [i ] j i : 0  i < x )

We also have a look at U (x + 1):


U (x + 1)
= {definition U }
(a [i ] j i : 0  i < x + 1)

22 / 45
Exercise 10.1: Examining T (x + 1)

T (x + 1)
= {definition T }
(a [i ]  a [j ] j i ; j : 0  i < j < x + 1)
= {assume x  1; split domain: j < x _ j = x }
(a [i ]  a [j ] j i ; j ; k : 0  i < j < x ) + (a [i ]  a [x ] j i : 0  i < x)
= {definition T ; calculus}
T (x ) + a [x ]  (a [i ] j i : 0  i < x )
= {introduce U }
T (x ) + a [x ]  U (x ) where U (x ) = (a [i ] j i : 0  i < x )

We also have a look at U (x + 1):


U (x + 1)
= {definition U }
(a [i ] j i : 0  i < x + 1)
= {assume x  0; split domain: i < x _ i = x}
(a [i ] j i : 0  i < x ) + a [x ]

22 / 45
Exercise 10.1: Examining T (x + 1)

T (x + 1)
= {definition T }
(a [i ]  a [j ] j i ; j : 0  i < j < x + 1)
= {assume x  1; split domain: j < x _ j = x }
(a [i ]  a [j ] j i ; j ; k : 0  i < j < x ) + (a [i ]  a [x ] j i : 0  i < x)
= {definition T ; calculus}
T (x ) + a [x ]  (a [i ] j i : 0  i < x )
= {introduce U }
T (x ) + a [x ]  U (x ) where U (x ) = (a [i ] j i : 0  i < x )

We also have a look at U (x + 1):


U (x + 1)
= {definition U }
(a [i ] j i : 0  i < x + 1)
= {assume x  0; split domain: i < x _ i = x}
(a [i ] j i : 0  i < x ) + a [x ]
= {definition U }
U (x ) + a [x ]
22 / 45
Exercise 10.1: Recurrences
Summing up, we started from
S (x ) = (a [i ]  a [j ]  a [k ] j 0  i < j k < x)
and expressed it in terms of
T (x ) = (a [i ]  a [j ] j i j : 0  i
; < j < x)
U (x ) = (a [i ] j i : 0  i x ) <

23 / 45
Exercise 10.1: Recurrences
Summing up, we started from
S (x ) = (a [i ]  a [j ]  a [k ] j 0  i < j k < x)
and expressed it in terms of
T (x ) = (a [i ]  a [j ] j i j : 0  i
; < j < x)
U (x ) = (a [i ] j i : 0  i x ) <

We found the recurrences:


x < 1) S (x ) =0
x 1) S (x+ 1) = S (x ) + a [x ]  T (x + 1)
x 1)< T (x ) =0
x 1) T (x + 1) = T (x ) + a [x ]  U (x )
x 0) U (x ) =0
x 1) U (x + 1) = a [x ] + U (x )
23 / 45
Exercise 10.1: Invariant & Variant
S (x ) = (a [i ]  a [j ]  a [k ] j 0  i < j k < x)
T (x ) = (a [i ]  a [j ] j i ; j : 0  i < j < x)
U (x ) = (a [i ] j i : 0  i < x)

2 Initialization:
B :x 6= n
J :s = S (x ) ^ 1  x  n

24 / 45
Exercise 10.1: Invariant & Variant
S (x ) = (a [i ]  a [j ]  a [k ] j 0  i < j k < x)
T (x ) = (a [i ]  a [j ] j i ; j : 0  i < j < x)
U (x ) = (a [i ] j i : 0  i < x)

2 Initialization: We now strengthen the invariant and initialize it.


B : x 6= n
J :s = S (x ) ^ t = T (x ) ^ u = U (x ) ^ 1  x  n

24 / 45
Exercise 10.1: Invariant & Variant
S (x ) = (a [i ]  a [j ]  a [k ] j 0  i < j k < x)
T (x ) = (a [i ]  a [j ] j i ; j : 0  i < j < x)
U (x ) = (a [i ] j i : 0  i < x)

2 Initialization: We now strengthen the invariant and initialize it.


B : x 6= n
J :s = S (x ) ^ t = T (x ) ^ u = U (x ) ^ 1  x  n
fP : trueg

fJ : s = S (x ) ^ t = T (x ) ^ u = U (x ) ^ 1  x  n g
24 / 45
Exercise 10.1: Invariant & Variant
S (x ) = (a [i ]  a [j ]  a [k ] j 0  i < j k < x)
T (x ) = (a [i ]  a [j ] j i ; j : 0  i < j < x)
U (x ) = (a [i ] j i : 0  i < x)

2 Initialization: We now strengthen the invariant and initialize it.


B : x 6= n
J :s = S (x ) ^ t = T (x ) ^ u = U (x ) ^ 1  x  n
fP : trueg

x := 1; s := 0; t := 0; u := a [0];
fJ : s = S (x ) ^ t = T (x ) ^ u = U (x ) ^ 1  x  n g
24 / 45
Exercise 10.1: Invariant & Variant
S (x ) = (a [i ]  a [j ]  a [k ] j 0  i < j k < x)
T (x ) = (a [i ]  a [j ] j i ; j : 0  i < j < x)
U (x ) = (a [i ] j i : 0  i < x)

2 Initialization: We now strengthen the invariant and initialize it.


B : x 6= n
J :s = S (x ) ^ t = T (x ) ^ u = U (x ) ^ 1  x  n
fP : trueg

f0 = S (1) ^ 0 = T (1) ^ a [0] = U (1) ^ 1  1  n g


x := 1; s := 0; t := 0; u := a [0];
fJ : s = S (x ) ^ t = T (x ) ^ u = U (x ) ^ 1  x  n g
24 / 45
Exercise 10.1: Invariant & Variant
S (x ) = (a [i ]  a [j ]  a [k ] j 0  i < j k < x)
T (x ) = (a [i ]  a [j ] j i ; j : 0  i < j < x)
U (x ) = (a [i ] j i : 0  i < x)

2 Initialization: We now strengthen the invariant and initialize it.


B : x 6= n
J :s = S (x ) ^ t = T (x ) ^ u = U (x ) ^ 1  x  n
fP : trueg
(* base cases recurrences; n 2 N+ *)
f0 = S (1) ^ 0 = T (1) ^ 1  1  n g
(* U (1) = a [0] + U (0) = a [0] *)
f0 = S (1) ^ 0 = T (1) ^ a [0] = U (1) ^ 1  1  n g
x := 1; s := 0; t := 0; u := a [0];
fJ : s = S (x ) ^ t = T (x ) ^ u = U (x ) ^ 1  x  n g
24 / 45
Exercise 10.1: Invariant & Variant
S (x ) = (a [i ]  a [j ]  a [k ] j 0  i < j k < x)
T (x ) = (a [i ]  a [j ] j i ; j : 0  i < j < x)
U (x ) = (a [i ] j i : 0  i < x)

2 Initialization: We now strengthen the invariant and initialize it.


B : x 6= n
J :s = S (x ) ^ t = T (x ) ^ u = U (x ) ^ 1  x  n
fP : trueg
(* base cases recurrences; n 2 N+ *)
f0 = S (1) ^ 0 = T (1) ^ 1  1  n g
(* U (1) = a [0] + U (0) = a [0] *)
f0 = S (1) ^ 0 = T (1) ^ a [0] = U (1) ^ 1  1  n g
x := 1; s := 0; t := 0; u := a [0];
fJ : s = S (x ) ^ t = T (x ) ^ u = U (x ) ^ 1  x  n g
3 Variant function: vf =n x 2 Z. Then J ^ B ) vf  0.
24 / 45
Exercise 10.1: Body of the Loop
fJ ^ B ^ vf = Vg

fJ ^ vf < Vg

25 / 45
Exercise 10.1: Body of the Loop
fJ ^ B ^ vf = V g
(* definitions J , B , and vf *)
fs = S (x ) ^ t = T (x ) ^ u = U (x ) ^ 1  x < n ^ n x = Vg

fJ ^ vf < Vg

25 / 45
Exercise 10.1: Body of the Loop
fJ ^ B ^ vf = V g
(* definitions J , B , and vf *)
fs = S (x ) ^ t = T (x ) ^ u = U (x ) ^ 1  x < n ^ n x = Vg

t := t + a [x ]  u;

s := s + a [x ]  t;

u := u + a [x ];

x := x + 1;

fJ ^ vf < Vg

25 / 45
Exercise 10.1: Body of the Loop
fJ ^ B ^ vf = V g
(* definitions J , B , and vf *)
fs = S (x ) ^ t = T (x ) ^ u = U (x ) ^ 1  x n ^ n x = V g
<
(* recurrence T (x + 1) = T (x ) + a [x ]  U (x ); substitution; logic *)
fs = S (x ) ^ t + a [x ]  u = T (x + 1) ^ u = U (x ) ^ 1  x n ^ < n x = Vg
t := t + a [x ]  u ;

s := s + a [x ]  t;

u := u + a [x ];

x := x + 1;

fJ ^ vf < Vg

25 / 45
Exercise 10.1: Body of the Loop
fJ ^ B ^ vf = V g
(* definitions J , B , and vf *)
fs = S (x ) ^ t = T (x ) ^ u = U (x ) ^ 1  x n ^ n x = V g
<
(* recurrence T (x + 1) = T (x ) + a [x ]  U (x ); substitution; logic *)
fs = S (x ) ^ t + a [x ]  u = T (x + 1) ^ u = U (x ) ^ 1  x n ^ n
< x = Vg
t := t + a [x ]  u ;
fs = S (x ) ^ t = T (x + 1) ^ u = U (x ) ^ 1  x n ^ n x = V g
<

s := s + a [x ]  t;

u := u + a [x ];

x := x + 1;

fJ ^ vf < Vg

25 / 45
Exercise 10.1: Body of the Loop
fJ ^ B ^ vf = V g
(* definitions J , B , and vf *)
fs = S (x ) ^ t = T (x ) ^ u = U (x ) ^ 1  x n ^ n x = V g
<
(* recurrence T (x + 1) = T (x ) + a [x ]  U (x ); substitution; logic *)
fs = S (x ) ^ t + a [x ]  u = T (x + 1) ^ u = U (x ) ^ 1  x n ^ n x = V g
<
t := t + a [x ]  u ;
fs = S (x ) ^ t = T (x + 1) ^ u = U (x ) ^ 1  x n ^ n x = V g
<
(* recurrence S (x + 1) = S (x ) + a [x ]  T (x + 1); substitution *)
fs + a [x ]  t = S (x + 1) ^ t = T (x + 1) ^ u = U (x ) ^ 1  x n ^ n x = V g
<
s := s + a [x ]  t ;

u := u + a [x ];

x := x + 1;

fJ ^ vf < Vg

25 / 45
Exercise 10.1: Body of the Loop
fJ ^ B ^ vf = V g
(* definitions J , B , and vf *)
fs = S (x ) ^ t = T (x ) ^ u = U (x ) ^ 1  x n ^ n x = V g
<
(* recurrence T (x + 1) = T (x ) + a [x ]  U (x ); substitution; logic *)
fs = S (x ) ^ t + a [x ]  u = T (x + 1) ^ u = U (x ) ^ 1  x n ^ n x = V g
<
t := t + a [x ]  u ;
fs = S (x ) ^ t = T (x + 1) ^ u = U (x ) ^ 1  x n ^ n x = V g
<
(* recurrence S (x + 1) = S (x ) + a [x ]  T (x + 1); substitution *)
fs + a [x ]  t = S (x + 1) ^ t = T (x + 1) ^ u = U (x ) ^ 1  x n ^ n x = V g
<
s := s + a [x ]  t ;
fs = S (x + 1) ^ t = T (x + 1) ^ u = U (x ) ^ 1  x n ^ n x = V g
<

u := u + a [x ];

x := x + 1;

fJ ^ vf < Vg

25 / 45
Exercise 10.1: Body of the Loop
fJ ^ B ^ vf = V g
(* definitions J , B , and vf *)
fs = S (x ) ^ t = T (x ) ^ u = U (x ) ^ 1  x n ^ n x = V g
<
(* recurrence T (x + 1) = T (x ) + a [x ]  U (x ); substitution; logic *)
fs = S (x ) ^ t + a [x ]  u = T (x + 1) ^ u = U (x ) ^ 1  x n ^ n x = V g
<
t := t + a [x ]  u ;
fs = S (x ) ^ t = T (x + 1) ^ u = U (x ) ^ 1  x n ^ n x = V g
<
(* recurrence S (x + 1) = S (x ) + a [x ]  T (x + 1); substitution *)
fs + a [x ]  t = S (x + 1) ^ t = T (x + 1) ^ u = U (x ) ^ 1  x n ^ n x = V g
<
s := s + a [x ]  t ;
fs = S (x + 1) ^ t = T (x + 1) ^ u = U (x ) ^ 1  x n ^ n x = V g
<
(* recurrence U (x + 1) = U (x ) + a [x ] *)
fs = S (x + 1) ^ t = T (x + 1) ^ u + a [x ] = U (x + 1) ^ 1  x n ^ n x = V g
<
u := u + a [x ];

x := x + 1;

fJ ^ vf < Vg

25 / 45
Exercise 10.1: Body of the Loop
fJ ^ B ^ vf = V g
(* definitions J , B , and vf *)
fs = S (x ) ^ t = T (x ) ^ u = U (x ) ^ 1  x n ^ n x = V g
<
(* recurrence T (x + 1) = T (x ) + a [x ]  U (x ); substitution; logic *)
fs = S (x ) ^ t + a [x ]  u = T (x + 1) ^ u = U (x ) ^ 1  x n ^ n x = V g
<
t := t + a [x ]  u ;
fs = S (x ) ^ t = T (x + 1) ^ u = U (x ) ^ 1  x n ^ n x = V g
<
(* recurrence S (x + 1) = S (x ) + a [x ]  T (x + 1); substitution *)
fs + a [x ]  t = S (x + 1) ^ t = T (x + 1) ^ u = U (x ) ^ 1  x n ^ n x = V g
<
s := s + a [x ]  t ;
fs = S (x + 1) ^ t = T (x + 1) ^ u = U (x ) ^ 1  x n ^ n x = V g
<
(* recurrence U (x + 1) = U (x ) + a [x ] *)
fs = S (x + 1) ^ t = T (x + 1) ^ u + a [x ] = U (x + 1) ^ 1  x n ^ n x = V g
<
u := u + a [x ];
fs = S (x + 1) ^ t = T (x + 1) ^ u = U (x + 1) ^ 1  x n ^ n x = V g
<

x := x + 1;

fJ ^ vf < Vg

25 / 45
Exercise 10.1: Body of the Loop
fJ ^ B ^ vf = V g
(* definitions J , B , and vf *)
fs = S (x ) ^ t = T (x ) ^ u = U (x ) ^ 1  x n ^ n x = V g
<
(* recurrence T (x + 1) = T (x ) + a [x ]  U (x ); substitution; logic *)
fs = S (x ) ^ t + a [x ]  u = T (x + 1) ^ u = U (x ) ^ 1  x n ^ n x = V g
<
t := t + a [x ]  u ;
fs = S (x ) ^ t = T (x + 1) ^ u = U (x ) ^ 1  x n ^ n x = V g
<
(* recurrence S (x + 1) = S (x ) + a [x ]  T (x + 1); substitution *)
fs + a [x ]  t = S (x + 1) ^ t = T (x + 1) ^ u = U (x ) ^ 1  x n ^ n x = V g
<
s := s + a [x ]  t ;
fs = S (x + 1) ^ t = T (x + 1) ^ u = U (x ) ^ 1  x n ^ n x = V g
<
(* recurrence U (x + 1) = U (x ) + a [x ] *)
fs = S (x + 1) ^ t = T (x + 1) ^ u + a [x ] = U (x + 1) ^ 1  x n ^ n x = V g
<
u := u + a [x ];
fs = S (x + 1) ^ t = T (x + 1) ^ u = U (x + 1) ^ 1  x n ^ n x = V g
<
(* prepare x := x + 1 *)
fs = S (x + 1) ^ t = T (x + 1) ^ u = U (x + 1) ^ 1  x + 1  n ^ n (x + 1) V g
<
x := x + 1;

fJ ^ vf < Vg

25 / 45
Exercise 10.1: Body of the Loop
fJ ^ B ^ vf = V g
(* definitions J , B , and vf *)
fs = S (x ) ^ t = T (x ) ^ u = U (x ) ^ 1  x n ^ n x = V g
<
(* recurrence T (x + 1) = T (x ) + a [x ]  U (x ); substitution; logic *)
fs = S (x ) ^ t + a [x ]  u = T (x + 1) ^ u = U (x ) ^ 1  x n ^ n x = V g
<
t := t + a [x ]  u ;
fs = S (x ) ^ t = T (x + 1) ^ u = U (x ) ^ 1  x n ^ n x = V g
<
(* recurrence S (x + 1) = S (x ) + a [x ]  T (x + 1); substitution *)
fs + a [x ]  t = S (x + 1) ^ t = T (x + 1) ^ u = U (x ) ^ 1  x n ^ n x = V g
<
s := s + a [x ]  t ;
fs = S (x + 1) ^ t = T (x + 1) ^ u = U (x ) ^ 1  x n ^ n x = V g
<
(* recurrence U (x + 1) = U (x ) + a [x ] *)
fs = S (x + 1) ^ t = T (x + 1) ^ u + a [x ] = U (x + 1) ^ 1  x n ^ n x = V g
<
u := u + a [x ];
fs = S (x + 1) ^ t = T (x + 1) ^ u = U (x + 1) ^ 1  x n ^ n x = V g
<
(* prepare x := x + 1 *)
fs = S (x + 1) ^ t = T (x + 1) ^ u = U (x + 1) ^ 1  x + 1  n ^ n (x + 1) V g
<
x := x + 1;
fs = S (x ) ^ t = T (x ) ^ u = U (x ) ^ 1  x  n ^ n x V g<

fJ ^ vf V g
<

25 / 45
Exercise 10.1: Body of the Loop
fJ ^ B ^ vf = V g
(* definitions J , B , and vf *)
fs = S (x ) ^ t = T (x ) ^ u = U (x ) ^ 1  x n ^ n x = V g
<
(* recurrence T (x + 1) = T (x ) + a [x ]  U (x ); substitution; logic *)
fs = S (x ) ^ t + a [x ]  u = T (x + 1) ^ u = U (x ) ^ 1  x n ^ n x = V g
<
t := t + a [x ]  u ;
fs = S (x ) ^ t = T (x + 1) ^ u = U (x ) ^ 1  x n ^ n x = V g
<
(* recurrence S (x + 1) = S (x ) + a [x ]  T (x + 1); substitution *)
fs + a [x ]  t = S (x + 1) ^ t = T (x + 1) ^ u = U (x ) ^ 1  x n ^ n x = V g
<
s := s + a [x ]  t ;
fs = S (x + 1) ^ t = T (x + 1) ^ u = U (x ) ^ 1  x n ^ n x = V g
<
(* recurrence U (x + 1) = U (x ) + a [x ] *)
fs = S (x + 1) ^ t = T (x + 1) ^ u + a [x ] = U (x + 1) ^ 1  x n ^ n x = V g
<
u := u + a [x ];
fs = S (x + 1) ^ t = T (x + 1) ^ u = U (x + 1) ^ 1  x n ^ n x = V g
<
(* prepare x := x + 1 *)
fs = S (x + 1) ^ t = T (x + 1) ^ u = U (x + 1) ^ 1  x + 1  n ^ n (x + 1) V g
<
x := x + 1;
fs = S (x ) ^ t = T (x ) ^ u = U (x ) ^ 1  x  n ^ n x V g<
(* definitions J , and vf *)
fJ ^ vf V g
<

25 / 45
Exercise 10.1: Conclusion

const n : N+ ; a : array [0::n ) of Z;


var x ; s ; t ; u : Z;
fP : trueg
s := 0; t := 0; u := a [0]; x := 1;
fJ : s = S (x ) ^ t = T (x ) ^ u = U (x ) ^ 1  x  ng
(* vf = n x *)
while x < n do
t := t + a [x ]  u ;
s := s + a [x ]  t ;
u := u + a [x ];
x := x + 1;
end;
fQ : s = (a [i ]  a [j ]  a [k ] j i ; j ; k : 0  i < j  k < n )g

Complexity is O (n ): a major improvement over the O (n 3 ) algorithm.

26 / 45
Outline

Longest positive subsequence (LPS)

Exercise 10.1

Exercise 10.2

Exercise 10.13

27 / 45
Exercise 10.2
Derive a command to compute

(a [i ]  a [j ]  a [k ] j i ; j;k : 0i j < n ^ i k < n)

28 / 45
Exercise 10.2
Derive a command to compute

(a [i ]  a [j ]  a [k ] j i ; j;k : 0i j < n ^ i k < n)

We start by introducing:

L(x ) = (a [i ]  a [j ]  a [k ] j i ; j ; k : x i j < n ^ i k < n)

Note the x in the lower bound!

We want to find a command C that satisfies the specification:

const n : N+ ; a : array [0::n ) of Z;


var s : Z;
fP : trueg
C
fQ : s = L(0)g
28 / 45
Exercise 10.2: Guard & First Invariant

P : true
Q :s= L(0)
L(x ) =(a [i ]  a [j ]  a [k ] j i ; j;k : x i j < n ^ i k < n)

0 We decide that we need a while-program.

1 Choose an invariant J and guard B .


As a first attempt we introduce a variable x and try to maintain

J : s = L(x ) ^ 0  x  n
Clearly, we choose B : x 6= 0, such that J ^ :B ) Q.
As before, we can safely add conjuncts to J .
29 / 45
Exercise 10.2: Examining L(x )

The loop will decrement x , so we first examine L(x 1), for x > 0.

L(x 1)
= {definition L}
(a [i ]  a [j ]  a [k ] j i ; j ; k : x 1i j < n ^ i k < n)

30 / 45
Exercise 10.2: Examining L(x )

The loop will decrement x , so we first examine L(x 1), for x > 0.

L(x 1)
= {definition L}
(a [i ]  a [j ]  a [k ] j i ; j ; k : x 1  i  j < n ^ i  k < n )
= {split domain: x  i _ i = x 1}
(a [i ]  a [j ]  a [k ] j i ; j ; k : x  i  j < n ^ i  k < n ) +
(a [x 1]  a [j ]  a [k ] j j ; k : x 1  j < n ^ x 1  k < n )

30 / 45
Exercise 10.2: Examining L(x )

The loop will decrement x , so we first examine L(x 1), for x > 0.

L(x 1)
= {definition L}
(a [i ]  a [j ]  a [k ] j i ; j ; k : x 1  i  j < n ^ i  k < n )
= {split domain: x  i _ i = x 1}
(a [i ]  a [j ]  a [k ] j i ; j ; k : x  i  j < n ^ i  k < n ) +
(a [x 1]  a [j ]  a [k ] j j ; k : x 1  j < n ^ x 1  k < n )
= {definition L; calculus}
L(x ) + a [x 1] 
(a [j ]  a [k ] j j ; k : x 1  j < n ^ x 1  k < n )

30 / 45
Exercise 10.2: Examining L(x )

The loop will decrement x , so we first examine L(x 1), for x > 0.

L(x 1)
= {definition L}
(a [i ]  a [j ]  a [k ] j i ; j ; k : x 1  i  j < n ^ i  k < n )
= {split domain: x  i _ i = x 1}
(a [i ]  a [j ]  a [k ] j i ; j ; k : x  i  j < n ^ i  k < n ) +
(a [x 1]  a [j ]  a [k ] j j ; k : x 1  j < n ^ x 1  k < n )
= {definition L; calculus}
L(x ) + a [x 1] 
(a [j ]  a [k ] j j ; k : x 1  j < n ^ x 1  k < n )
= {introduce T }
L(x ) + a [x 1]  T (x 1)

where T (x ) = (a [j ]  a [k ] j j ; k : x j < n ^ x k < n ).

30 / 45
Exercise 10.2: Examining T (x )
T (x ) = (a [j ]  a [k ] j j ; k : x j < n ^ x k < n)
So, if we want to decrement x , we need T (x 1) for x > 0:
T (x 1)

31 / 45
Exercise 10.2: Examining T (x )
T (x ) = (a [j ]  a [k ] j j ; k : x j < n ^ x k < n)
So, if we want to decrement x , we need T (x 1) for x > 0:
T (x 1)
= {definition T }
(a [j ]  a [k ] j j ; k : x 1j < n ^ x 1k < n)

31 / 45
Exercise 10.2: Examining T (x )
T (x ) = (a [j ]  a [k ] j j ; k : x j < n ^ x k < n)
So, if we want to decrement x , we need T (x 1) for x > 0:
T (x 1)
= {definition T }
(a [j ]  a [k ] j j ; k : x 1  j < n ^ x 1  k < n )
= {split domain: x  j _ j = x 1}
(a [j ]  a [k ] j j ; k : x  j < n ^ x 1  k < n ) +
(a [x 1]  a [k ] j k : x 1  k < n )

31 / 45
Exercise 10.2: Examining T (x )
T (x ) = (a [j ]  a [k ] j j ; k : x j < n ^ x k < n)
So, if we want to decrement x , we need T (x 1) for x > 0:
T (x 1)
= {definition T }
(a [j ]  a [k ] j j ; k : x 1  j < n ^ x 1  k < n )
= {split domain: x  j _ j = x 1}
(a [j ]  a [k ] j j ; k : x  j < n ^ x 1  k < n ) +
(a [x 1]  a [k ] j k : x 1  k < n )
= {split domain of 1st term: k = x  k _ k = x 1}
(a [j ]  a [k ] j j ; k : x  j < n ^ x  k < n ) +
(a [j ]  a [x 1] j j : x  j < n ) +
(a [x 1]  a [k ] j k : x 1  k < n )

31 / 45
Exercise 10.2: Examining T (x )
T (x ) = (a [j ]  a [k ] j j ; k : x j < n ^ x k < n)
So, if we want to decrement x , we need T (x 1) for x > 0:
T (x 1)
= {definition T }
(a [j ]  a [k ] j j ; k : x 1  j < n ^ x 1  k < n )
= {split domain: x  j _ j = x 1}
(a [j ]  a [k ] j j ; k : x  j < n ^ x 1  k < n ) +
(a [x 1]  a [k ] j k : x 1  k < n )
= {split domain of 1st term: k = x  k _ k = x 1}
(a [j ]  a [k ] j j ; k : x  j < n ^ x  k < n ) +
(a [j ]  a [x 1] j j : x  j < n ) +
(a [x 1]  a [k ] j k : x 1  k < n )
= {definition T ; calculus} 
T (x ) + a [x 1]  (a [k ] j k : x 1  k < n ) + (a [j ] j j : x j < n)

31 / 45
Exercise 10.2: Examining T (x )
T (x ) = (a [j ]  a [k ] j j ; k : x j < n ^ x k < n)
So, if we want to decrement x , we need T (x 1) for x > 0:
T (x 1)
= {definition T }
(a [j ]  a [k ] j j ; k : x 1  j < n ^ x 1  k < n )
= {split domain: x  j _ j = x 1}
(a [j ]  a [k ] j j ; k : x  j < n ^ x 1  k < n ) +
(a [x 1]  a [k ] j k : x 1  k < n )
= {split domain of 1st term: k = x  k _ k = x 1}
(a [j ]  a [k ] j j ; k : x  j < n ^ x  k < n ) +
(a [j ]  a [x 1] j j : x  j < n ) +
(a [x 1]  a [k ] j k : x 1  k < n )
= {definition T ; calculus} 
T (x ) + a [x 1]  (a [k ] j k : x 1  k < n ) + (a [j ] j j : x  j < n )
= {rename bound variable: k j } 
T (x ) + a [x 1]  (a [j ] j j : x 1  j < n ) + (a [j ] j j : x  j < n )

31 / 45
Exercise 10.2: Examining T (x )
T (x ) = (a [j ]  a [k ] j j ; k : x j < n ^ x k < n)
So, if we want to decrement x , we need T (x 1) for x > 0:
T (x 1)
= {definition T }
(a [j ]  a [k ] j j ; k : x 1  j < n ^ x 1  k < n )
= {split domain: x  j _ j = x 1}
(a [j ]  a [k ] j j ; k : x  j < n ^ x 1  k < n ) +
(a [x 1]  a [k ] j k : x 1  k < n )
= {split domain of 1st term: k = x  k _ k = x 1}
(a [j ]  a [k ] j j ; k : x  j < n ^ x  k < n ) +
(a [j ]  a [x 1] j j : x  j < n ) +
(a [x 1]  a [k ] j k : x 1  k < n )
= {definition T ; calculus} 
T (x ) + a [x 1]  (a [k ] j k : x 1  k < n ) + (a [j ] j j : x  j < n )
= {rename bound variable: k j } 
T (x ) + a [x 1]  (a [j ] j j : x 1  j < n ) + (a [j ] j j : x  j < n )
= {introduce U (x ) = (a [i ] j i : x  i < n )}
T (x ) + a [x 1]  (U (x 1) + U (x ))
31 / 45
Exercise 10.2: Examining U (x )

U (x ) = (a [i ] j i : x i < n)

We now look into U (x 1), for x > 0:

U (x 1)

32 / 45
Exercise 10.2: Examining U (x )

U (x ) = (a [i ] j i : x i < n)

We now look into U (x 1), for x > 0:

U (x 1)
= {definition U }
(a [i ] j i : x 1  i < n)

32 / 45
Exercise 10.2: Examining U (x )

U (x ) = (a [i ] j i : x i < n)

We now look into U (x 1), for x > 0:

U (x 1)
= {definition U }
(a [i ] j i : x 1  i < n )
= {split domain: x  i _ i = x 1}
(a [i ] j i : x  i < n ) + a [x 1]

32 / 45
Exercise 10.2: Examining U (x )

U (x ) = (a [i ] j i : x i < n)

We now look into U (x 1), for x > 0:

U (x 1)
= {definition U }
(a [i ] j i : x 1  i < n )
= {split domain: x  i _ i = x 1}
(a [i ] j i : x  i < n ) + a [x 1]
= {definition U }
U (x ) + a [x 1]

32 / 45
Exercise 10.2: Recurrences

Summing up, for the following definitions

L(x ) = (a [i ]  a [j ]  a [k ] j i j k : x  i  j n ^ i  k
; ; < < n)
T (x ) = (a [j ]  a [k ] j j k : x  j n ^ x  k n )
; < <

U (x ) = (a [i ] j i : x  i n ) <

We found the recurrences:

x =n ) L(x ) = T (x ) = U (x ) = 0
x > 0 ) L( x 1) = L(x ) + a [x 1]  T (x 1)
x > 0 ) T (x 1) = T (x ) + a [x 1]  (U (x 1) + U (x ))
x > 0 ) U (x 1) = a [x 1] + U (x )

33 / 45
Exercise 10.2: Invariant & Variant

2 Initialization:
B :x 6= 0
J :s = L( x ) ^ 0  x  n

34 / 45
Exercise 10.2: Invariant & Variant

2 Initialization: We now strengthen the invariant and initialize it.


B : x 6= 0
J :s = L(x ) ^ t = T (x ) ^ u = U (x ) ^ 0  x  n

34 / 45
Exercise 10.2: Invariant & Variant

2 Initialization: We now strengthen the invariant and initialize it.


B : x 6= 0
J :s = L(x ) ^ t = T (x ) ^ u = U (x ) ^ 0  x  n
fP : trueg

fJ : s = L(x ) ^ t = T (x ) ^ u = U (x ) ^ 0  x  n g

34 / 45
Exercise 10.2: Invariant & Variant

2 Initialization: We now strengthen the invariant and initialize it.


B : x 6= 0
J :s = L(x ) ^ t = T (x ) ^ u = U (x ) ^ 0  x  n
fP : trueg

s := 0; t := 0; u := 0; x := n ;
fJ : s = L(x ) ^ t = T (x ) ^ u = U (x ) ^ 0  x  n g

34 / 45
Exercise 10.2: Invariant & Variant

2 Initialization: We now strengthen the invariant and initialize it.


B : x 6= 0
J :s = L(x ) ^ t = T (x ) ^ u = U (x ) ^ 0  x  n
fP : trueg
(* base cases recurrences; calculus; n 2 N+ *)
f0 = L(n ) ^ 0 = T (n ) ^ 0 = U (n ) ^ 0  n  n g
s := 0; t := 0; u := 0; x := n ;
fJ : s = L(x ) ^ t = T (x ) ^ u = U (x ) ^ 0  x  n g

34 / 45
Exercise 10.2: Invariant & Variant

2 Initialization: We now strengthen the invariant and initialize it.


B : x 6= 0
J :s = L(x ) ^ t = T (x ) ^ u = U (x ) ^ 0  x  n
fP : trueg
(* base cases recurrences; calculus; n 2 N+ *)
f0 = L(n ) ^ 0 = T (n ) ^ 0 = U (n ) ^ 0  n  n g
s := 0; t := 0; u := 0; x := n ;
fJ : s = L(x ) ^ t = T (x ) ^ u = U (x ) ^ 0  x  n g
3 Variant function: vf = x 2 Z. Clearly, J ^ B ) vf  0.

34 / 45
Exercise 10.2: Body of The Loop (1/2)

fJ ^ B ^ vf = V g
(* definitions J , B , and vf ; logic *)
fs = L(x ) ^ t = T (x ) ^ u = U (x ) ^ 0<x = V  ng

35 / 45
Exercise 10.2: Body of The Loop (1/2)

fJ ^ B ^ vf = V g
(* definitions J , B , and vf ; logic *)
fs = L(x ) ^ t = T (x ) ^ u = U (x ) ^ 0 < x = V  n g
(* recurrence T (x 1) = T (x ) + a [x 1]  (U (x 1) + U (x )); substitution *)
fs = L(x ) ^ t + a [x 1]  (U (x 1) + u ) = T (x 1) ^ u = U (x ) ^ ::::g

35 / 45
Exercise 10.2: Body of The Loop (1/2)

fJ ^ B ^ vf = V g
(* definitions J , B , and vf ; logic *)
fs = L(x ) ^ t = T (x ) ^ u = U (x ) ^ 0 < x = V  n g
(* recurrence T (x 1) = T (x ) + a [x 1]  (U (x 1) + U (x )); substitution *)
fs = L(x ) ^ t + a [x 1]  (U (x 1) + u ) = T (x 1) ^ u = U (x ) ^ ::::g
(* calculus *)
fs = L(x ) ^ t + a [x 1]  u + a [x 1]  U (x 1) = T (x 1) ^ ::::g

35 / 45
Exercise 10.2: Body of The Loop (1/2)

fJ ^ B ^ vf = V g
(* definitions J , B , and vf ; logic *)
fs = L(x ) ^ t = T (x ) ^ u = U (x ) ^ 0 < x = V  n g
(* recurrence T (x 1) = T (x ) + a [x 1]  (U (x 1) + U (x )); substitution *)
fs = L(x ) ^ t + a [x 1]  (U (x 1) + u ) = T (x 1) ^ u = U (x ) ^ ::::g
(* calculus *)
fs = L(x ) ^ t + a [x 1]  u + a [x 1]  U (x 1) = T (x 1) ^ ::::g
t := t + a [x 1]  u ;
fs = L(x ) ^ t + a [x 1]  U (x 1) = T (x 1) ^ u = U (x ) ^ 0 < x = V  n g

35 / 45
Exercise 10.2: Body of The Loop (1/2)

fJ ^ B ^ vf = V g
(* definitions J , B , and vf ; logic *)
fs = L(x ) ^ t = T (x ) ^ u = U (x ) ^ 0 < x = V  n g
(* recurrence T (x 1) = T (x ) + a [x 1]  (U (x 1) + U (x )); substitution *)
fs = L(x ) ^ t + a [x 1]  (U (x 1) + u ) = T (x 1) ^ u = U (x ) ^ ::::g
(* calculus *)
fs = L(x ) ^ t + a [x 1]  u + a [x 1]  U (x 1) = T (x 1) ^ ::::g
t := t + a [x 1]  u ;
fs = L(x ) ^ t + a [x 1]  U (x 1) = T (x 1) ^ u = U (x ) ^ 0 < x = V  n g
(* recurrence U (x 1) = U (x ) + a [x 1] *)
fs = L(x ) ^ t + a [x 1]  U (x 1) = T (x 1) ^ u + a [x 1] = U (x 1) ^ ::::g

35 / 45
Exercise 10.2: Body of The Loop (1/2)

fJ ^ B ^ vf = V g
(* definitions J , B , and vf ; logic *)
fs = L(x ) ^ t = T (x ) ^ u = U (x ) ^ 0 < x = V  n g
(* recurrence T (x 1) = T (x ) + a [x 1]  (U (x 1) + U (x )); substitution *)
fs = L(x ) ^ t + a [x 1]  (U (x 1) + u ) = T (x 1) ^ u = U (x ) ^ ::::g
(* calculus *)
fs = L(x ) ^ t + a [x 1]  u + a [x 1]  U (x 1) = T (x 1) ^ ::::g
t := t + a [x 1]  u ;
fs = L(x ) ^ t + a [x 1]  U (x 1) = T (x 1) ^ u = U (x ) ^ 0 < x = V  n g
(* recurrence U (x 1) = U (x ) + a [x 1] *)
fs = L(x ) ^ t + a [x 1]  U (x 1) = T (x 1) ^ u + a [x 1] = U (x 1) ^ ::::g
u := u + a [x 1];
fs = L(x ) ^ t + a [x 1]  U (x 1) = T (x 1) ^ u = U (x 1) ^ : : :g
(* substitution *)
fs = L(x ) ^ t + a [x 1]  u = T (x 1) ^ u = U (x 1) ^ 0 < x = V  n g

35 / 45
Exercise 10.2: Body of The Loop (1/2)

fJ ^ B ^ vf = V g
(* definitions J , B , and vf ; logic *)
fs = L(x ) ^ t = T (x ) ^ u = U (x ) ^ 0 < x = V  n g
(* recurrence T (x 1) = T (x ) + a [x 1]  (U (x 1) + U (x )); substitution *)
fs = L(x ) ^ t + a [x 1]  (U (x 1) + u ) = T (x 1) ^ u = U (x ) ^ ::::g
(* calculus *)
fs = L(x ) ^ t + a [x 1]  u + a [x 1]  U (x 1) = T (x 1) ^ ::::g
t := t + a [x 1]  u ;
fs = L(x ) ^ t + a [x 1]  U (x 1) = T (x 1) ^ u = U (x ) ^ 0 < x = V  n g
(* recurrence U (x 1) = U (x ) + a [x 1] *)
fs = L(x ) ^ t + a [x 1]  U (x 1) = T (x 1) ^ u + a [x 1] = U (x 1) ^ ::::g
u := u + a [x 1];
fs = L(x ) ^ t + a [x 1]  U (x 1) = T (x 1) ^ u = U (x 1) ^ : : :g
(* substitution *)
fs = L(x ) ^ t + a [x 1]  u = T (x 1) ^ u = U (x 1) ^ 0 < x = V  n g
t := t + a [x 1]  u ;
fs = L(x ) ^ t = T (x 1) ^ u = U (x 1) ^ 0 < x = V  n g

35 / 45
Exercise 10.2: Body of The Loop (2/2)

fs = L(x ) ^ t = T (x 1) ^ u = U (x 1) ^ 0<x = V  ng

36 / 45
Exercise 10.2: Body of The Loop (2/2)

fs = L(x ) ^ t = T (x 1) ^ u = U (x 1) ^ 0 < x = V  n g
(* recurrence L(x 1) = L(x ) + a [x 1]  T (x 1); substitution *)
fs + a [x 1]  t = L(x 1) ^ t = T (x 1) ^ u = U (x 1) ^ 0 < x = V  ng

36 / 45
Exercise 10.2: Body of The Loop (2/2)

fs = L(x ) ^ t = T (x 1) ^ u = U (x 1) ^ 0 < x = V  n g
(* recurrence L(x 1) = L(x ) + a [x 1]  T (x 1); substitution *)
fs + a [x 1]  t = L(x 1) ^ t = T (x 1) ^ u = U (x 1) ^ 0 < x = V  ng
s := s + a [x 1]  t ;
fs = L(x 1) ^ t = T (x 1) ^ u = U (x 1) ^ 0 < x = V  n g

36 / 45
Exercise 10.2: Body of The Loop (2/2)

fs = L(x ) ^ t = T (x 1) ^ u = U (x 1) ^ 0 < x = V  n g
(* recurrence L(x 1) = L(x ) + a [x 1]  T (x 1); substitution *)
fs + a [x 1]  t = L(x 1) ^ t = T (x 1) ^ u = U (x 1) ^ 0 < x = V  ng
s := s + a [x 1]  t ;
fs = L(x 1) ^ t = T (x 1) ^ u = U (x 1) ^ 0 < x = V  n g
(* calculus *)
fs = L(x 1) ^ t = T (x 1) ^ u = U (x 1) ^ 0  x 1  n ^ x 1 < Vg

36 / 45
Exercise 10.2: Body of The Loop (2/2)

fs = L(x ) ^ t = T (x 1) ^ u = U (x 1) ^ 0 < x = V  n g
(* recurrence L(x 1) = L(x ) + a [x 1]  T (x 1); substitution *)
fs + a [x 1]  t = L(x 1) ^ t = T (x 1) ^ u = U (x 1) ^ 0 < x = V  ng
s := s + a [x 1]  t ;
fs = L(x 1) ^ t = T (x 1) ^ u = U (x 1) ^ 0 < x = V  n g
(* calculus *)
fs = L(x 1) ^ t = T (x 1) ^ u = U (x 1) ^ 0  x 1  n ^ x 1 < Vg
x := x 1;
fs = L(x ) ^ t = T (x ) ^ u = U (x ) ^ 0  x  n ^ x < V g

36 / 45
Exercise 10.2: Body of The Loop (2/2)

fs = L(x ) ^ t = T (x 1) ^ u = U (x 1) ^ 0 < x = V  n g
(* recurrence L(x 1) = L(x ) + a [x 1]  T (x 1); substitution *)
fs + a [x 1]  t = L(x 1) ^ t = T (x 1) ^ u = U (x 1) ^ 0 < x = V  ng
s := s + a [x 1]  t ;
fs = L(x 1) ^ t = T (x 1) ^ u = U (x 1) ^ 0 < x = V  n g
(* calculus *)
fs = L(x 1) ^ t = T (x 1) ^ u = U (x 1) ^ 0  x 1  n ^ x 1 < Vg
x := x 1;
fs = L(x ) ^ t = T (x ) ^ u = U (x ) ^ 0  x  n ^ x < V g
(* definitions J , and vf *)
fJ ^ vf < V g

36 / 45
Exercise 10.2: Conclusion
We derived the program fragment:

const n : N+ ; a : array [0::n ) of Z;


var x ; s ; t ; u : Z;
fP : trueg
s := 0; t := 0; u := 0; x := n ;
fJ : s = L(x ) ^ t = T (x ) ^ u = U (x ) ^ 0  x  n g
(* vf = x *)
while x 6= 0 do
t := t + a [x 1]  u ;
u := u + a [x 1];
t := t + a [x 1]  u ;
s := s + a [x 1]  t ;
x := x 1;
end;
fQ : s = (a [i ]  a [j ]  a [k ] j i ; j ; k : 0  i  j < n ^ i  k < n )g

37 / 45
Outline

Longest positive subsequence (LPS)

Exercise 10.1

Exercise 10.2

Exercise 10.13

38 / 45
Exercise 10.13
Given are two arrays declared in
const n : N; a ; b : array [0::n ) of R;
Determine a command S to compute
(a [i ]  b [j ] j i j : 0  j  i n )
; <

The time complexity of S should be O (n ). First derive recurrence


relations for relevant functions and give a formal specification.

39 / 45
Exercise 10.13
Given are two arrays declared in
const n : N; a ; b : array [0::n ) of R;
Determine a command S to compute
(a [i ]  b [j ] j i j : 0  j  i n )
; <

The time complexity of S should be O (n ). First derive recurrence


relations for relevant functions and give a formal specification.

We introduce S (k ) = (a [i ]  b [j ] j i ; j : 0j i < k ). We want a


command that satisfies:
const n :N ; a; b : array [0::n ) of R;
var x : Z;
fP : trueg
S;
fQ : x = S (n )g
39 / 45
Exercise 10.13: Examining S (x )

S (k ) = (a [i ]  b [j ] j i ; j : 0j i < k)


Clearly, 0 = S (0).
We need to increment k . We examine S (k + 1), for k < n:
S (k + 1)

40 / 45
Exercise 10.13: Examining S (x )

S (k ) = (a [i ]  b [j ] j i ; j : 0j i < k)


Clearly, 0 = S (0).
We need to increment k . We examine S (k + 1), for k < n:
S (k + 1)
= {definition S }
(a [i ]  b [j ] j i ; j : 0j i < k + 1)

40 / 45
Exercise 10.13: Examining S (x )

S (k ) = (a [i ]  b [j ] j i ; j : 0j i < k)


Clearly, 0 = S (0).
We need to increment k . We examine S (k + 1), for k < n:
S (k + 1)
= {definition S }
(a [i ]  b [j ] j i ; j : 0  j  i < k + 1)
= {split domain: i < k _ i = k }

40 / 45
Exercise 10.13: Examining S (x )

S (k ) = (a [i ]  b [j ] j i ; j : 0j i < k)


Clearly, 0 = S (0).
We need to increment k . We examine S (k + 1), for k < n:
S (k + 1)
= {definition S }
(a [i ]  b [j ] j i ; j : 0  j  i < k + 1)
= {split domain: i < k _ i = k }
(a [i ]  b [j ] j i ; j : 0  j  i < k ) + (a [k ]  b [j ] j j : 0  j  k)

40 / 45
Exercise 10.13: Examining S (x )

S (k ) = (a [i ]  b [j ] j i ; j : 0j i < k)


Clearly, 0 = S (0).
We need to increment k . We examine S (k + 1), for k < n:
S (k + 1)
= {definition S }
(a [i ]  b [j ] j i ; j : 0  j  i < k + 1)
= {split domain: i < k _ i = k }
(a [i ]  b [j ] j i ; j : 0  j  i < k ) + (a [k ]  b [j ] j j : 0  j  k)
= {definition S ; calculus}

40 / 45
Exercise 10.13: Examining S (x )

S (k ) = (a [i ]  b [j ] j i ; j : 0j i < k)


Clearly, 0 = S (0).
We need to increment k . We examine S (k + 1), for k < n:
S (k + 1)
= {definition S }
(a [i ]  b [j ] j i ; j : 0  j  i < k + 1)
= {split domain: i < k _ i = k }
(a [i ]  b [j ] j i ; j : 0  j  i < k ) + (a [k ]  b [j ] j j : 0  j  k)
= {definition S ; calculus}
S (k ) + a [k ]  (b [j ] j j : 0  j  k )

40 / 45
Exercise 10.13: Examining S (x )

S (k ) = (a [i ]  b [j ] j i ; j : 0j i < k)


Clearly, 0 = S (0).
We need to increment k . We examine S (k + 1), for k < n:
S (k + 1)
= {definition S }
(a [i ]  b [j ] j i ; j : 0  j  i < k + 1)
= {split domain: i < k _ i = k }
(a [i ]  b [j ] j i ; j : 0  j  i < k ) + (a [k ]  b [j ] j j : 0  j  k)
= {definition S ; calculus}
S (k ) + a [k ]  (b [j ] j j : 0  j  k )
= {use half-open intervals}

40 / 45
Exercise 10.13: Examining S (x )

S (k ) = (a [i ]  b [j ] j i ; j : 0j i < k)


Clearly, 0 = S (0).
We need to increment k . We examine S (k + 1), for k < n:
S (k + 1)
= {definition S }
(a [i ]  b [j ] j i ; j : 0  j  i < k + 1)
= {split domain: i < k _ i = k }
(a [i ]  b [j ] j i ; j : 0  j  i < k ) + (a [k ]  b [j ] j j : 0  j  k)
= {definition S ; calculus}
S (k ) + a [k ]  (b [j ] j j : 0  j  k )
= {use half-open intervals}
S (k ) + a [k ]  (b [j ] j j : 0  j < k + 1)

40 / 45
Exercise 10.13: Examining S (x )

S (k ) = (a [i ]  b [j ] j i ; j : 0j i < k)


Clearly, 0 = S (0).
We need to increment k . We examine S (k + 1), for k < n:
S (k + 1)
= {definition S }
(a [i ]  b [j ] j i ; j : 0  j  i < k + 1)
= {split domain: i < k _ i = k }
(a [i ]  b [j ] j i ; j : 0  j  i < k ) + (a [k ]  b [j ] j j : 0  j  k)
= {definition S ; calculus}
S (k ) + a [k ]  (b [j ] j j : 0  j  k )
= {use half-open intervals}
S (k ) + a [k ]  (b [j ] j j : 0  j < k + 1)
= {introduce T (k ) = (b [j ] j j : 0  j < k ) }
S (k ) + a [k ]  T (k + 1)

40 / 45
Exercise 10.13: Examining S (x )

S (k ) = (a [i ]  b [j ] j i ; j : 0j i < k)


Clearly, 0 = S (0).
We need to increment k . We examine S (k + 1), for k < n:
S (k + 1)
= {definition S }
(a [i ]  b [j ] j i ; j : 0  j  i < k + 1)
= {split domain: i < k _ i = k }
(a [i ]  b [j ] j i ; j : 0  j  i < k ) + (a [k ]  b [j ] j j : 0  j  k)
= {definition S ; calculus}
S (k ) + a [k ]  (b [j ] j j : 0  j  k )
= {use half-open intervals}
S (k ) + a [k ]  (b [j ] j j : 0  j < k + 1)
= {introduce T (k ) = (b [j ] j j : 0  j < k ) }
S (k ) + a [k ]  T (k + 1)
We encountered the function T (k ) before, so without proof:
T (0) = 0; T (k + 1) = b [k ] + T (k )
40 / 45
Exercise 10.13: Recurrences

For the following definitions

S (k )= (a [i ]  b [j ] j i j : 0  j  i
; < k)
T (k ) = (b [j ] j j : 0  j k ) <

We found the recurrences:

S (0) = T (0) = 0
0k < n ) S (k+ 1) = S (k ) + a [k ]  T (k + 1)
0k < n ) T (k + 1) = b [k ] + T (k )

41 / 45
Exercise 10.13: Invariant & Initialization
1 Choose an invariant J and guard B .
Since Q  x = S (n ), we keep x = S (k ) invariant while
incrementing k :

J : x = S (k ) ^ 0  k  n ^ y = T (k )
Clearly, we choose B 6 n, such that J ^ :B ) Q.
: k=

42 / 45
Exercise 10.13: Invariant & Initialization
1 Choose an invariant J and guard B .
Since Q  x = S (n ), we keep x = S (k ) invariant while
incrementing k :

J : x = S (k ) ^ 0  k  n ^ y = T (k )
Clearly, we choose B 6 n, such that J ^ :B ) Q.
: k=
2 Initialization: The initialization is easy:
fP : trueg
(* base cases recurrences; n 2 N *)
f0 = S (0) ^ 0  0  n ^ 0 = T (0)g
k := 0; x := 0; y := 0;
fJ : x = S (k ) ^ 0  k  n ^ y = T (k )g

42 / 45
Exercise 10.13: Invariant & Initialization
1 Choose an invariant J and guard B .
Since Q  x = S (n ), we keep x = S (k ) invariant while
incrementing k :

J : x = S (k ) ^ 0  k  n ^ y = T (k )
Clearly, we choose B 6 n, such that J ^ :B ) Q.
: k=
2 Initialization: The initialization is easy:
fP : trueg
(* base cases recurrences; n 2 N *)
f0 = S (0) ^ 0  0  n ^ 0 = T (0)g
k := 0; x := 0; y := 0;
fJ : x = S (k ) ^ 0  k  n ^ y = T (k )g
3 Variant function: vf =n k 2 Z. Clearly, J ^ B ) vf  0.
42 / 45
Exercise 10.13: Body of the Loop

fx = S (k ) ^ 0  k < n ^ y = T (k ) ^ n k = Vg

fJ ^ vf < Vg

43 / 45
Exercise 10.13: Body of the Loop

fx = S (k ) ^ 0  k n ^ y = T (k ) ^ n k = V g
<

(* 0  k n ) T (k + 1) = b [k ] + T (k ); substitution *)
<

fx = S (k ) ^ 0  k n ^ y + b [k ] = T (k + 1) ^ n k = V g
<

fJ ^ vf < Vg

43 / 45
Exercise 10.13: Body of the Loop

fx = S (k ) ^ 0  k n ^ y = T (k ) ^ n k = V g
<

(* 0  k n ) T (k + 1) = b [k ] + T (k ); substitution *)
<

fx = S (k ) ^ 0  k n ^ y + b [k ] = T (k + 1) ^ n k = V g
<

y := y + b [k ];

x := x + a [k ]  y ;

k := k + 1;

fJ ^ vf < Vg

43 / 45
Exercise 10.13: Body of the Loop

fx = S (k ) ^ 0  k n ^ y = T (k ) ^ n k = V g
<

(* 0  k n ) T (k + 1) = b [k ] + T (k ); substitution *)
<

fx = S (k ) ^ 0  k n ^ y + b [k ] = T (k + 1) ^ n k = V g
<

y := y + b [k ];
fx = S (k ) ^ 0  k < n ^ y = T (k + 1) ^ n k = Vg

x := x + a [k ]  y ;

k := k + 1;

fJ ^ vf < Vg

43 / 45
Exercise 10.13: Body of the Loop

fx = S (k ) ^ 0  k n ^ y = T (k ) ^ n k = V g
<

(* 0  k n ) T (k + 1) = b [k ] + T (k ); substitution *)
<

fx = S (k ) ^ 0  k n ^ y + b [k ] = T (k + 1) ^ n k = V g
<

y := y + b [k ];
fx = S (k ) ^ 0  k < n ^ y = T (k + 1) ^ n k = Vg
(* 0  k < n ) S (k + 1) = S (k ) + a [k ]  T (k + 1); substitution *)
fx + a [k ]  y = S (k + 1) ^ 0  k < n ^ y = T (k + 1) ^ n k = V g
x := x + a [k ]  y ;

k := k + 1;

fJ ^ vf < Vg

43 / 45
Exercise 10.13: Body of the Loop

fx = S (k ) ^ 0  k n ^ y = T (k ) ^ n k = V g
<

(* 0  k n ) T (k + 1) = b [k ] + T (k ); substitution *)
<

fx = S (k ) ^ 0  k n ^ y + b [k ] = T (k + 1) ^ n k = V g
<

y := y + b [k ];
fx = S (k ) ^ 0  k < n ^ y = T (k + 1) ^ n k = Vg
(* 0  k < n ) S (k + 1) = S (k ) + a [k ]  T (k + 1); substitution *)
fx + a [k ]  y = S (k + 1) ^ 0  k < n ^ y = T (k + 1) ^ n k = V g
x := x + a [k ]  y ;
fx = S (k + 1) ^ 0  k < n ^ y = T (k + 1) ^ n k = V g

k := k + 1;

fJ ^ vf < Vg

43 / 45
Exercise 10.13: Body of the Loop

fx = S (k ) ^ 0  k n ^ y = T (k ) ^ n k = V g
<

(* 0  k n ) T (k + 1) = b [k ] + T (k ); substitution *)
<

fx = S (k ) ^ 0  k n ^ y + b [k ] = T (k + 1) ^ n k = V g
<

y := y + b [k ];
fx = S (k ) ^ 0  k < n ^ y = T (k + 1) ^ n k = Vg
(* 0  k < n ) S (k + 1) = S (k ) + a [k ]  T (k + 1); substitution *)
fx + a [k ]  y = S (k + 1) ^ 0  k < n ^ y = T (k + 1) ^ n k = V g
x := x + a [k ]  y ;
fx = S (k + 1) ^ 0  k < n ^ y = T (k + 1) ^ n k = V g
(* calculus *)
fx = S (k + 1) ^ 0  k + 1  n ^ y = T (k + 1) ^ n (k + 1) < V g
k := k + 1;

fJ ^ vf < Vg

43 / 45
Exercise 10.13: Body of the Loop

fx = S (k ) ^ 0  k n ^ y = T (k ) ^ n k = V g
<

(* 0  k n ) T (k + 1) = b [k ] + T (k ); substitution *)
<

fx = S (k ) ^ 0  k n ^ y + b [k ] = T (k + 1) ^ n k = V g
<

y := y + b [k ];
fx = S (k ) ^ 0  k < n ^ y = T (k + 1) ^ n k = Vg
(* 0  k < n ) S (k + 1) = S (k ) + a [k ]  T (k + 1); substitution *)
fx + a [k ]  y = S (k + 1) ^ 0  k < n ^ y = T (k + 1) ^ n k = V g
x := x + a [k ]  y ;
fx = S (k + 1) ^ 0  k < n ^ y = T (k + 1) ^ n k = V g
(* calculus *)
fx = S (k + 1) ^ 0  k + 1  n ^ y = T (k + 1) ^ n (k + 1) < V g
k := k + 1;
fx = S (k ) ^ 0  k  n ^ y = T (k ) ^ n k < V g
fJ ^ vf < Vg

43 / 45
Exercise 10.13: Body of the Loop

fx = S (k ) ^ 0  k n ^ y = T (k ) ^ n k = V g
<

(* 0  k n ) T (k + 1) = b [k ] + T (k ); substitution *)
<

fx = S (k ) ^ 0  k n ^ y + b [k ] = T (k + 1) ^ n k = V g
<

y := y + b [k ];
fx = S (k ) ^ 0  k < n ^ y = T (k + 1) ^ n k = Vg
(* 0  k < n ) S (k + 1) = S (k ) + a [k ]  T (k + 1); substitution *)
fx + a [k ]  y = S (k + 1) ^ 0  k < n ^ y = T (k + 1) ^ n k = V g
x := x + a [k ]  y ;
fx = S (k + 1) ^ 0  k < n ^ y = T (k + 1) ^ n k = V g
(* calculus *)
fx = S (k + 1) ^ 0  k + 1  n ^ y = T (k + 1) ^ n (k + 1) < V g
k := k + 1;
fx = S (k ) ^ 0  k  n ^ y = T (k ) ^ n k < V g
(* definitions of J ; vf *)
fJ ^ vf < V g

43 / 45
Exercise 10.13: Conclusion

const n : N; a : array [0::n ) of R;


var k : N; x ; y : R;
fP : trueg
k := 0; x := 0; y := 0;
fJ : x = S (k ) ^ 0  k  n ^ y = T (k )g
(* vf = n k *)
while k 6= n do
y := y + b [k ];
x := x + a [k ]  y ;
k := k + 1;
end;
fQ : x = (a [i ]  b [j ] j i ; j : 0  j  i < n ) g

44 / 45
The End

45 / 45

You might also like