131 105 4MB
English Pages 228 [231] Year 1990
Programming
Prent1ce Hall Internattonal Senes m Computer Sctence C. A. R. Hoare, Series Editor BACKHOUSE, R. C., Program CotlstructiOII and Vui{ica11a11 BACKHOUSE. R. C., Symax of Progrommmg Languages: Theory and practice oeBAKKER, J. W., /llothemotlcal Theory of Program Correcmess BARR, M. and WELLS, C.. Category Theory for Complllmg Setence BEN-ARI. M., Prtnc1ples ofConcurrem and Distribwecl Programmmg BIRD, R. and WADLER. P .• lmrodnctlonto Fuuct1ouo/ Progrommmg BJORNER, D. and JONES. C. B.. Formal Specification and SofiiVare De••elopmeut BORNAT, R.• Programmmgfrom First Prmetples BUSTARD. D .• ELDER, J. and WELSH. J .• Concurrem Program Stmcwres CLARK, K. L., and McCABE. F. G .. nucro-Prolog: Programmmg mlog1c CROOKES, D .• lntrocluctlonto Programmmg 111 Prolog DROMEY, R. G .. HolV to Solve tl by Compmu DUNCAN. F .• Microprocessor Programmmg and Software Development ELDER, J., Constmction of Dora Processmg Software ELLIOlT, R. J. and HOARE. C. A. R.• (cds. i. Sclellli/ic Applications of Multiprocessors
GOLDSCHLAGER. L. and LISTER. A.. Compwer Sctence: A modem mtroductlon (2nd edn}
GORDON, M. J. C.. Programmmg Language 71reon• om/ irs lmplemetllllllan HAYES. I. (cd. ), Speci{ico/lon Case Stnclies HEHNER. E. C. R., The Log1c of Progrommmg HENDERSON, P., Funcllonol Programmmg: ApJtlicwwn amllmlllemelllatlon HOARE. C. A. R .• Commnmcatmg Sequential Processes HOARE. C. A. R., and JONES, C. B. (ed.). EssCI)'S 111 Com(mtmg Saence HOARE. C. A. R., and SHEPHERDSON. J. C. (cds.J. Mothemmrcal Log1c aiul Programmmg Languages
HUGHES, J. G., Databe~se Technology: A softlVure cmgmeumg apwoe~ch !NMOS LTO, occam2 Reference Manual JACKSON, M.A .• System De••e/opmem JOHNSTON, H., Leammg to Program JONES, C. B.• Systematic So{tiVare Deve/opme/11 usmg VDM (2nd edn} JONES, C. B. and SHAW. R. C. F. (cds.). Case Stmlies 111 S)'stemllltc Softw11re Developmelll
JONES, G., Progrommmg 111 occam JONES, G. and GOLDSMITH, M., Progrommmg 111 occnm2 JOSEPH, M., PRASAD. V. R. and NATARAJAN. N.,A Muhiprocessor Operatmg System
KALDEWAIJ, A., Progrommmg: The DmvCitlan of Algorithms LEW, A., Compwer Sc1ence: A mathematical introdl/c/lall MARTIN, J. J., Data Types oud Data Stmcmres MEYER, B.,/lllroduc/lonto the Theory of Programmmg Languages MEYER, B., Obiect-oTielllated Software Constmctlon MILNER, R., Ca1111n11111Cat1on and Concurrency MORGAN, C., Programmmgfrom Specifications PEYTON JONES, S. L., The lmplememotlon of Functional Progrmnmmg Languages POMBERGER, G., Sofnvare Eugmeumg and /IJ01/u/a-2 POTTER. B., SINCLAIR. J .• TILL, D., Atllmroductlal/ to Formal Sfleci{icatlon oud 2 REYNOLDS, i. C., The Craft of Programmmg RYDEHEARD, D. E. AND BURSTALL, R. M., Comp111at1onnl Category Theory SLOMAN, M. and KRAMER, J., Distributed Systems am/ ComJmler Networks SPIVEY, J. M., The Z Notation: A reference manna/ TENNENT, R. D .• Prmcrples of Progrmnmmg Longunges WATT. D. A., Progrommmg Languages Concepts and Parmligms WATT, D. A., WICHMANN, B. A. and FINDLAY, W.,ADA: Lungnagenml methodology
WELSH, J. and ELDER,J.,/ntroductlonto Moclu/11-2 WELSH, J. and ELDER. J.,lntrodnctlonto Pascal (3,/ e1lnJ WELSH. J., ELDER, j,, and BUSTARD, D., Se1fuewie~l Pmgram Strncmres WELSH, J. and HAY, A., A Moclellmplemelllalllm ofStwulurcl Pusml WELSH, J. and McKEAG, M., Stmcmred S1·~·rem Progrmmnmg WIKSTROM, A., Fimctlonnl Programmmg usmg Stwulnrd AIL
Programming The Derivation of Algorithms
A. Kaldewaij Eindhoven University of Technology
Prentice Hall New York London Toronto Sydney Tokyo Singapore
First published 1990 by Prcnnce Hall lnternauomll (UKJ Ltd 66 Wood Lane End, Hcmel Hemps11:11d Hertfordshire HP2 4RG A division of Simon & Schuster lnternnt•onal Group
o Prcnucc Hall lntcrnauonal (UK) Ltd. 1990 All nghls reserved. No part of this publicallon mny he reproduced, stored inn rctncval system. or lransmlllcd, many form. or by any means. elect rome. mcchamcnl. photocopymg. recording or otherwise, wilho111 prior pcrm1ss1on. m writing. from the publisher. For perm1ss1on within lhe United States of Amcnca conlncl Prcnucc Hall Inc .. Englewood Cliffs. NJ 117632. Pnntcd and bound in Grca1 Bntam by Do1cs1os Pnn1crs Limllcd. Trowbridge. Willshire Library of Congress Catalogumg-m-Puhlicuuon 0 wp.skip.Q) A {B => wp.(S ;DO).Q) { [-.B VB tmej, definitions of skip and catenation} (-.B => Q) A {B => tup.S.(wp.DO.Q)) { predicate calculus } (B v Q) A (-.B V wp.S.(wp.DO.Q))
=
Hence,
(wp.DO.Q
=
(B V Q) A (-.B V wp.S.(wp.DO.Q)) I
i.e., wp.DO.Q is a solution of the following equation in predicate X:
X : [X ::: (B v Q) A (-.B
v wp.S.X)]
This is a so-called !_e~l!i~egua~C!I.!: We define wp.(do B- S od).Q as the strongest solution of this equation (it can be shown that a strongest solution exists). With this definition the Invariance Theorem can be proved. Such a proof, however, is beyond the scope of this book.
As an example, we compute wp.(do n =f: 0 - n:= n-2 od).(n = 0). For this specific choice the equation is X: (X:= (n#0Vn=O)A{n=0Vwp.(n:=n-2).X)] which may be simplified to X~ (X
= n = OV X(n:=n-2)]
The strongest solution of this equation can be obtained by successive approximation, starting with false {the strongest predicate o£ all). Define fork ;?: 0 predicate Xk by
36
The Guarded Command La.nguage
[Xo
=
false! [Xk+l = n = 0 V Xk{n := n-2)] then the strongest solution is
Starting with f.X0
= fa1sel we have
{definition of Xk, {Xo := false] } n=OVfalse { predicate calculus } n=O and
{definition of Xk, [XI := n = 0)} n = 0 V (n = O){n := n-2) {substitution} n=0Vn=2
.,
=
Similarly, we have [X3 n = 0 V n = 2 V n = 41 and with induction one can prove [Xk 0 5 n < 2k 1\ nmod2 = 01. This result yields
=
wp.{do n :F 0--+ n:= n-2 od).(n = 0) {strongest solution of the equation J (3 k: 0 ~ k; Xk) {substitute xk } (3 k: 0 $ ic ; 0 ~ n < 2k 1\. n mod2 = 0) {calculus} 0$ n 1\. nmod2 = 0
=
0$ n 1\ nmod2 = 0 j. It is easy Hence, (wp.(do n :F 0-+ n:= n-2 od).(n = 0) to verify that 0 $ n 1\ n mod 2 = 0 1s indeed a solution of
X; (X:= n=OVX{n:=n-2)).
Repetition
Exercises Prove the correctness of the following programs 0. I( var z, N: int; {N 2! 0} z:=O ; do z -::/= N- :~: := z+1 od {z=N}
ll1. I[ var z,y, N: int; {N 2! 0}
z,y:=O,l ; do z "IN--+ z,y:= z+l,y+y od
{y =
2N}
ll· 2. I[ vary, N; int; {N 2! 0} y:= 1 ;doy < N- y:=y+y od {y 2! N A (3 k ; k 2! 0 : y = 21.:)}
ll· 3. l[var z,y,N: int; {N 2! 0} z,y:=O,O ; do z "I 0 - z := z-1 0 y'#N-+z,y:=N,y+1 od {z = 0 A y =N}
Jl. 4. I[ var z, y, z: int; {true}
do z < y - z := :~:+1 0 y < z - y := y+1 0 z < :c - t z:= z+1 od {:c=y=z}
ll-
37
Tile Guarded Command Language
38
5. The following program may be used to compute (non-deterministically) natural numbers x and y such that x * y = N. Prove: J[varp,x,y,N:mt; {N~ H p,x,y:=N-1,1,1 {N=x*y+p} ;dop#O --+if pmodx = 0 _.. y,p:= y+l,p-x Dpmody = 0--+ x,p:= x+l,p-y fi
6. For natural a and b, agcdb denotes the greatest common divisor of a and b. By definition 0 gcd a = a 1\ a gcd 0 = a. Prove
(i) agcdb = bgcd(amodb) for
a~ b
> 0.
(ii) J( var x, y, A, B: int; {A~ B > 0} x,y:=A,B ; do y /-0--+ x,y:= y,xmody ad {x= AgcdB}
.,
D-
2.6
Constants, Inner Blocks, and Arrays
A possible specification for a program for the computation of the greatest commori divisor of two positive integers IS '
I[ var A, B, x: int; {A-> 0 1\ B > 0} gcd {x=AgcdB}
11·
·~
This specification, however, has A, B, X:= 1, 1,1 as possible solution. or course, tb~ solution is not what we have in mind. To exclude such solutions, we might change tl~ specification to }
Constants, Inner Blocks, and Arrays
39
I[ var A, B,x : int; {A= A0 A B = B0 A A> 0 A B > 0} gcd
{x = AgcdB
A
A= Ao A B = Bq}
]1. expressing that the final values of A and B equal their initial values. This specification still allows assignments to A and B. We use in the declaration con instead of var to express the fact that no value should be assigned to the listed names. Hence, a specification that avoids the problems mentioned above is
l(conA,B: int {A> 0 A B > 0}; var x: int;
gcd {x=AgcdB}
u. Variables defined as con may not occur on the left-hand side of an assignment. Assertions about constants, such as A > 0 A B > 0, should not be repeated in annotations and should not be part of an invariant. They are 'universally invariant' smce the values of constants do not change. Assertions about constants provide a context of the program and may be used in proofs whenever appropriate. Constants are not part of the state space. Another addition to the guarded command language are so-called inner blocks. These are used to extend the state space (locally) by means of new variables. An inner block has the form I[ var .. · ; SJI. For variables introduced in an inner block, we use fresh names. As an example, we present a solution to gcd;
I[ con A,B: int; {A> 0 A B > 0} var x: int; I[ var y : int; x,y:=A,B ; do x > y -+ x := x-y Y > X - Y := y-x od {x = AgcdB A y = AgcdB}
n
] {x=AgcdB}
B-
40
Tl1e Guarded Command Language
In the mner block variable y of type int occurs. Between the inner scope symbols I[ and Dthe state space has two coordinates, :candy. Outside the inner block the state space has one coordinate, :c. We formulate a rule for inner blocks for the CllSe that the state space is extended with (fresh) variable y: For predicates P and Q in wh1ch y does not occur
{P} I[ vary: int ;S 11 {Q} is equivalent to '\
{P} S {Q}
Note that {P} I[ vary : int ; S 11 { Q} is an assertion involving the states of the original state space, whereas {P} S {Q} is an assertion over the state space extended withy. In terms of weakest pre-conditions, it IS defined by
fwp.l[ vary: int; SJ.Q
= (Vy: y e .Z : wp.S.Q)]
The universal quantification over y guarantees that (V y ~ y E .Z : wp.S.Q) depends on the vanables of the origmal state space only. It says that, no matter what initial vulue y has, S should lead to a state satisfying Q. Arrays are the final subject that we discuss in this chapter. Often arrays are. considered as an abbreviation for a set of variables. We view arrays as functions on a· finite consecutive subset of the integers. Such a subset is also called a segment. For p ~ q the segment consisting of all' satisfymg p ~ l < q is denoted by [p .. q). It has. length q - p. The statement
f, array[p .. q)ofint defines a program variable f which has as value a function: (p .. q)- Z. For the tim~· being we use arrays defined as con only, and we restrict the operations on arrays to function application. For integer expression E, J.E denotes J applied to E. Of course/ f.E is only defined when p $ E < q, i.e., [def.(J.E)
=
def.E i\ p ~ E < qj
We also use notation such as [p.. qj, (p.. qj, and (p .. q). The sentence 'integer array:: /(O .. N)' is short for'/ of type array (O.. N) ofint'. Instead of "
f : array [O .. N) of array f.O .. M) of int we may also write
f . array [O .. N) x [O..M) of int.
12
Predicate Calculus 7. Disprove
((3 i . R ; P) A (3 i : R : Q) :
(3 i ; R : P A Q))
8. Perform the following subsmutions:
(i) (:c 2 + 2:c + 1)(:c := :z:+a) (ii) (:z:2 :;?: y)(:z:,y:= y+l,:t-1) (iii) x 2 :;?: y(:c,y:= y+l,:z:-1) (iv) (:z: ~ y+l 1\y ~ z)(:z:,y:= :z:+ 3u,:z:- y + 1)
(v) (a
=b)(a:= a= b)
9. Simplify the following expressions
(i) (3 i : i :;?: 0 : :z: = 2 * i) (ii) (Vi : i :;?: a : :z:
:5 i)
(iii) (3i: i ~ 0: (3J: 0
5. j Qol implies {P} S {Q0 } {P}S{Q} and {P}S{R} isequivalentto {P}S{QAR} {P}S{Q} and {R}S{Q} isequivalentto {PVR}S{Q}
43
Chapter 3 Quantifications Many practical programming problems involve the computation of a function over d sequence, such as the ma.xnnum element of a sequence of integers, the conjunction ol a sequence of booleans, the sum of a sequence of integers, etc.. In order to specify such computations, we introduce a uniform notation, which is similar to that used foi universal and existential quantification. Let X be a set and Jet EB be a bmary operator on X such that EB is commutativ~ associative and has e as identity, i.e., .\
xEBy=yEBx x EB (y EB z) = (x EBy) EBz ee>x=xEBe=x for all x, y, and z in X. For sequence x.i, 0
~
z, and natural number n, we write
x.O EB · · · EB x.{n-1) as {EB z : 0 5 i < n : x.i) for wJlich we have
.,' "!
{EBi~O~i '-· 3. Solve .?,.,-;r- 3J···.• -r) '""
l(conA,B: int{A var x: int; lcm {x= AlcmB}
>0
AB
•
--
.
I
> 0};
Jl. where lcm denotes the least common multiple, i.e., for A
AlcmB
= (mini; 1 ~ i
1\
imodA = 0 A imodB
> 0 A B > 0:
=0: i)
Replacing constants by variables
4.2
57
Replacing cpnstants by variables
We consider the computation of A to the power B for given naturals A and B. Th1s problem is formally specified as
I[ con A,B: mt{A ~ 0 A B?: 0}; varr: int; exponentiation
{r = A 8 } ][, where, by definition, (jl = 1. There is no obvious way in which the post-condition can be weakened to a suitable invariant. In the state space defined by r predicate r = A 8 corresponds to a single point. \¥hen we extend the state space by introducing a fresh variable x, say, the state space defined by r and x contains the entire line satisfying r = A 8 and in this space this relation may be more easily established. A way in which fresh variables can be introduced is by repJacing constants by variables. Such a replacement yields a possible invariant. For this specification possible choices are
We use the invariant
Then P0 A x :::: B implies the post-condition, and Po is established by r, x := 1, 0. Furthermore, we specify an upper bound for x and add to the invariant
This yields the program scheme r,x;:::: l,O{Po A P 1} ;do x ~ B-+ S od{r:::: A 8 } We investigate the effect of increasing x by 1 1n S' Po(x:=x+ 1) { substitution}
Hence, {r
= A"'+l} x ;:::: x+1 {Po}.
Assuming Po A P1 A x ~ B, we have
58
General Programming Techniques
[calculus} A•A:r: =
{Po} A*r
from which we conclude
[Po A Pi Ax i: B}r:= A•r {r
= A~ 1 } ;x:= x+l {Po}
The invariance of P., Le.,
is easily proved and we obtain the following solution for exponentiation
I[ var x : int; r,:r::= 1,0 {invariant: P0 A P 11 bound: B - x} ;dox i: B - {Po A P1 A x .P B} r:= r *A ;x:= x+l {Po A P1} od {Po A Pi A :r: = B, hence, r = A 8 }
This program has time complexity O(B). In Section 4.4 we derive a solution that has time complexity O(log B). Constants are usually denoted by capital letters, and we often use the same letter in lower-case for a variable that replaces a constant. As a final example, we derive a solution to summation, which is specified below. To show how e.'tercises should be worked out, we present a 'model solution' to the problem. Here is tbe specification:
I! conN : int {N ~ 0}; f ; array (O.. N} ofint; var x: int; summation {:r: = (Ei: 0 $,
]1.
< N ; j.i}}
Replacing constants by variables
59
The quantification that appears in the post·condition has two constants: 0 and N. Let us replace N by variable a.nd propose invariant
n
x = {Ei: 0 ~ i < n: j.i)
Po:
Then, by construction, P0 A n = N implies the post-condition. Summation over an empty range equals 0, hence, Po is established by n, x := 0, 0. We investigate an increase of n by 1 and we derive, assuming P0 A n :f: N:
{I: i : 0 ~ i < n+l ~ J.i) {split off i = n, 0 ~ n < n+ 1 : see below } + J.n
=
{Ei: 0 ~ i < n ~ f.i) = {Po} x+f.n
Evidently, 0 :5 n is needed in the derivation above, which must be added to Po. From this derivation we conclude
{Po
A
0 ~ n} :r: := x + f.n {Po(n := n+l)}
As a bound funtion N -n seems appropriate; for the proof of termination we strengthen Po with n :5 N as well. We now show how the soiution is presented. Solution: Replacing constant N by variable n gives rise to the following invariants.
P0
x = (I: z : 0 ~ z < n : f.i) 0 ~ n$. N
,
P,: ProofO:
(Po
A
PI)(n,:r::= 0,0)
{substitution} 0 = (E i : 0 ~ i < 0 : J.i) A 0 ~ 0 ~ N { 0 is identity of + } O=OAO~O~N
{ predicate calculus } O~N
General Programming Techniques
60
Proof 1: Assummg Po A P 1 A n
0 $ z < n+l : f.i) {split off z = n, 0 5 n < n+l} (E z : 0 $ i < n f.i) + f.n {Po} (E~:
=
x+f.n and
O$n+l$N
( definition of Po } X=
(Ei: 0$ i < N: f.i)
Proof 3:
Pt =>
f. N,
{ definition of P1 } N-n?.O
and
N- (n+l) < C O} (ii) {P} :z: := :z: * :z: {:z: > 0} (iii) {P}:z::= :z: *:z:* :z:- 2 *:z: + 4{:z: > 0} (iv) {P} :z: := :z:+l {:z:3
-
5:z:2 + 2:z: > 0}
(v) {P}:z::= :z: *:z:* :z:- 2*:z: +4 {:z:3 -5:z: 2 +2:z: > o} (vi) {P} :z: := :z:+l {:z: = :z:+I} (vii) {P}x:=E{:z:=E}
~
(viii) {P} :z::= :z:mod2 (x = :z:mod2} (ix) {P}:z:,y:=:z:+I,y-l{:z:+y>O} {x) {P}:z:,y:=y+I,:z:-1 {:z: > 0}
(xi) {P}:z:,y:=y*:z:,:z:*y{:z:+y>O} (xii) {P}a:=a
= b{a}
(xiii) {P}a:=a=> b{aVb} t
1. Show that execution of :z: := :z:+l terminates.
\
-~'l·.-c
-
....... ,_,-t
2. Prove for b ::!: 0:
(i) (amodb)modb = amodb {ii) amodb = amod{-b) (iii) (a modb + cmodb) mod b =(a+ c) modb
2.3
Catenation
Catenation allows us to describe sequences of actions. The catenation of S and T is denoted asS ;T. Its operational interpretation is: first Sis executed after \Vhich Tis executed. To prove {P} S;T{Q}, we have to invent predicate Rsuch that {P} S {R} and {R} T { Q} hold. Then execution of S starting in a state satisfying P terminates in a state satisfying R, and execution ofT starting in that state terminates in a state satisfying Q. This leads to the following ruie:
General Programm1ng Techniques
64
fib.(n+2) {definition of fib, n fib.n + fib.(n+l) {P0 andQ} = x+y =
~
0}
This leads to the following solution: l[varn,y: int; {N ~ 0} n,:z:,y:= 0,0, 1 {invariants: Po A P1 A Q, bound: N- n} ;don :FN -+ x,y:=y,x+y ;n:=n+l od {x = fib.N A y = fib.(N+l)}
II {x = fib.N}, a program that has time complexity O(N). In Chapter 5 we derive a program for Fibonacci that has time complexity O(log N). As a second example, we derive, given array f(O .. N) 1 a program for the computation of the number of pairs (i,j) for which 0::; 1 < J < N A f.i::; 0 A J.j ~ 0. A formal specification is
I[ conN: lnt {N ~ 0};
f; array(O.. N)ofint;
var r: int;
s {r = (#t,j: 0::; i < j < N: J.i $. 0 A J.j ;: :_ 0)}
l Replacing constant N by variable n gives rise to invariants
Po : r
= (#i,j: 0 $. i
< J < n ~ j.1 $. 0
A
f.j;::: 0)
Strengthening invariants
65
which are initialized by n, r := 0, 0 , since number-of quantification over an empty range is 0. Assuming Po 1\ PJ. 1\ n 1- N, we have
=
(# z,J ; 0 5 z < j < n+l ; f.z 501\ J.i ~ 0) {splitofFj=n} (#i,j: 0 5 z < J < n · f.i 501\ f.j?. O) + (#z: 0 5 i < n: /.z 501\ f.n
=
~
0)
{Po}
r + (#i: 0:::;;; i < n: f.i 501\ f.n ~ O) = { case analysis } r if f.n < 0 r + (# i : 0 5 i < n : f.i 5 OJ if J.n ?. 0 = {introduction of s with invariant Q, see below} if f.n < 0 r { r + s if f.n ?. 0
f l
where s satisfies Q: s = ( # i : 0 5 i < n : j.i 5 0) Substitution of n = 0 yields that Q is established by n, s := 0, 0. For the in variance of Q, we derive, assuming P1 1\ Q 1\ n 1- N,
=
:::::;
(#i: 0 5 i < n+l; /.i 5O) (split off i :::::: n, 0 5 n < n+1 5 N} (# i: 0 5 i < n 'f.i 50)+# .(J.n 50)
{Q}
s + # .(J.n 5 0) = {definition of # } s if f.n > 0 { s + 1 if f.n 50 These derivations yield a program that solves the problem:
66
General Programming Techniques l[varn,s:int; {N~O} n, r, s := 0, 0, 0 {invariant: P0 A P 1 A Q, bound: N- n} ;don~N -+
{Po A P1 A Q An~ N} if f.n < 0 -+ skip n f.n ~ 0 -+ r := r+s fi
{P0 (n := n+l) A P1 A Q An=/: N} ; if f.n > 0 -+ skip O f.n ~ 0-+ s := s+l fi {(Po A P1 A Q)(n:= n+l)} ;n:= n+l
od
ll
{r = (#&,j: 0 ~ i < j < N: f.i
~0 A
f.j
The reader may verify that the two selections if f.n < 0 -> skip 0 f.n ~ 0 -+ r := r+s fi ;if f.n > 0-+ skip 0 f.n ~ 0 -+ s := s+ 1 fi
~ 0)}.
\
can be replaced by if f.n 0 f.n 0 f.n fi
< 0-> s:= s+l
= 0-> r,s:= r+s,s+l >0
-+
r:= r+s
due to the fact that Po A P 1 A Q A n ::F N can be used as assumption for all the derivations. In the calculations we derived that the value of (#i: 0 ~ i < n: f.i ~ 0) is needed for the invariance of P0 • We could have decided to introduce another repetition in wliich
Strengthening invariants
67
this value is computed, i.e.,, a repetition that establishes s = (#': 0 S' < n; f.i S 0). This naive approach leads to an O(JV2) algorithm instead of the O(N) algorithm presented above. Finally, we mention that the introduction of variables is always based upon some reasoning or derivation. They are not introduced by magic. In the following example we consider the problem of the maximal sum of the elements of segments A[p.. q) of a given integer array A. A fonnal specification for this problem is
I[ conN: int {N ~ 0}; A: array (O..N) ofint; varr: int; ma.xsegsum
{r = (maxp,q: 0 S p S q S N: (I:i: pSi< q: A.i))}
]1. To make the expression in the post-condition more manageable, we define, for 0 .S p .S q ~ N: S.p.q = (I:' : p S '
< q : A.i)
Post-condition R becomes
R:
r
= (maxp,q: 0 ,Sp .S q .S N; S.p.q)
Replacing constant N by variable n yields invariants P0 and P 1 : Po : r = (maxp, q : 0 .S p .S q S n ; S.p.q)
wbich are initialized by n, r ~= 0, 0 1 since S.O.O = 0. Assuming Po 1\ P1 derive
1\
n
:!- N, we
(maxp, q: 0 ~ p .S q .S n+l : S.p.q) {split off q = n+l} (maxp, q: 0 S p S q S n: S.p.q) max (maxp ~ 0 ~ p S n+l; S.p.(n+l)) = {Po} r max (maxp: 0 S p S n+l ; S.p.(n+l)) At this point it seems appropriate to introduce the variable s and accompanying invariant
68
General Programming Teclmiques
s = (maxp ~ 0 ~ p
~
n+I ; S.p.(n+l))
However, for n=N (which is not excluded by P 1) this predicate is not defined. Replacing all occurrences of n by n-1 yields an expression that is defined for all n, 0 ~ n ~ N. Thus, if we define additional invariant Q by
Q: s = (maxp : 0 ~ p
~ n ; S.p.n)
then Q(n := n+l) equals the relation that is needed, i.e.,
(maxp, q: 0 ~ p =
~ q~
n+l : S.p.q)
{see previous derivation } r max (maxp: 0 ~ p ~ n+l . S.p.(n+I))
{assume Q(n:=n+l)}
rmaxs This leads to a solution of the following form
II var n, s : int; 'establish Po 1\ P 1 1\ Q' N ..... 'establish Q(n := n+l)'
;don~
;r:=rmaxs ;n:= n+l od
II· where 'establish Q(n := n+ll' is formally specified as
II conN, n, r : int; A ~
array [O.. N) ofint;
{Po A P1 A n ~ N} var s: int;
{Q}
s
{Q(n:=n+I)}
II· For Q(n := n+l), we derive, assuming P0 A P1 1\ Q A n # N:
Strengtl1ening invariants (maxp; 0 ~ p ~ n+l ; S.p.(n+l)) = {split off p = n+l, 0 ~ n+l ~ N} (maxp: 0 5 p ~ n: S.p.(n+l)) max S.(n+l).(n+l) = {definition of S, summation over an empty range is 0} (maxp: 0 ~ p :5 n: S.p.(n+l)) max 0 = {definition of S} - (maxp: 0 ~ p ~ n; S.p.n + A.n) max 0 = {+ distributes over max when the range is non-empty, 0 ((maxp: 0 ~ p ~ n; S.p.n) + A.n) max 0 = {Q} (s + A.n) maxO
~
69
n}
From this derivation it follows that Q(n:= n+l) is established by s := (s+A.n) maxO. Thus, we arrive at the following non-annotated solution to maxsegsum:
I[ var n, s : int; n,r,s := 0,0,0 ;don:# N - s:= (s+A.n)maxO ;r:= rmaxs ;n:=n+l od A nice solution to a not so simple problem. In order to get used to the calculations that are performed in such derivations, the reader should thoroughly analyse the derivation of this program. In these derivations we used the following properties of S: S.n.n = 0 for 0 5 n ~ N S.p.(n+l) = S.p.n + A.n for 0 5 p
~
n y F.:z:.(y-:z:) if y > :z:
which is an example of a so-called tail recursive definition. A repetition for the computation of F.A.B is obtained by choosing as invariant
F.:z:.y = F.A.B as we did for the algorithm in Section 2.5. As another example, consider
II conN : int {N ~ 0}; A ; array [O.. NI ofint.; varr: int;
s {r = (max1 : 0 :5 i :5 N: A.i)} l Define, for 0 :5 :z:::::; y::::; N, the function F by
F.:z:.y
= (max1 : x::::; 1 :5 y : A.i)
Tail invanants
73
Then the post-condition of t,his specification can be written as
R: r=F.O.N and F has the following properties:
(i)
:~:
(ii) 3:
= y
~
F.z.y
= A.:~:
< y => { F.x.y =F.(:~:+ I ).y F.z.y =
F.:~:.(y-1)
if A.:~:~ A.y if A.y ~ A.z
A repetition based on (i) and (ii) bas invanant
P:
F.:~:.y =
F.O.N A 0
~ :~: ~
y
~
N
and its coding is straightforward: l[var:~:,y: int;
{N
~
0}
:~:,y:=
O,N {invariant P: F.z.y = F.O.N A 0 ~ z ;do:~: =F y - i f A.z ~ A.y .-. z:= z+l
DJ\.y
~
y
~
N, bound: y- z}
~A.:~:- y:= y-1
6.
od {PAz= y, hence, ;r:=A.z
II {r =(maxi: 0
~i ~
A.:~:=
F.O.N}
N; A.i)}.
The general setting of tail recursion is as follows. A funct10n F is given for which
(i) F.z = lt.:~: (ii) F.z = F.(g.x)
if
b.:~:
if -.b.z
and one is asked to derive a program that establishes
r
= F.X for some X.
Taking
74
General Programming Techniques
P: F.x=F.X as a so-called tail mvanant, yields
l[varz; z:=X {invariant: F.z = F.X} ;do -.b.z--+ :z::= g.z od ;r:=h.z 11
{r= F.X} provided that the repetition terminates.
Solving a problem by tail recursion amounts to finding a suitable function F. A special case of tail recursion is the following. An assoc1ative operator 1B is given with identity e. A function G has the following properties: (0) G.z = a
(1) G.z= h.z 1B G.(g.z)
if b.z if -,b,:z:
and one is asked to derive a program with post-condition r be solved by a tail invariant of the form
P;
= G.X. This problem may
G.X=riBG.z
which may be interpreted as 'the result' = 'what has been computed'
m'what still has to be computed'
Invariant P is stablished by r, :z: := e, X, Furthermore, if b.z holds, then G.X=r(BG.z { b.:z:, use {0) }
G.X=rea and, for -.b.z
Th.il invariants
75
G.X =rEBG.x { -.b.x, use (1)} G.X = r E9 (h.x E9 G.(g.x)) { E9 is associative } G.X = (r E9 lt.x) E9 G.(g.x) {definition of P} '
P(r, x := r E9 h.x, g.x)
This yields the following program scheme
If E9 is associative and has identity e, and G is such that (0) (1)
G.x= a G.x = h.x E9 G.(g.x)
if b.x if -.b.x
then {true}
l[varx; x,r~= X,e {invariant: G.X = r E9 G.x} ; do -.b.x--+ x, r := g.x, r E9 h.x od {G.X=rE9a} ;r:=rE9a
ll {r= G.X} provided that the repetition terminates.
Note that m almost each line of the derivation above 'G.X ='occurs. When applymg tail invariants, we only derive the relevant parts, leading to derivations of the following form: If b.x holds, then
=
r(BG.x { b.x, use (0)} rEBa
and, for -.b.x
76
General Programming Techniques rEBG.:r: ( -.b.:r:, use (1 J } rEB (l&.:r: EB G.(g.:r:)) = { EB is associative I (7· ED IL.:r:) EB G.(g.:r:)
We illustrate tail recursion by two examples. For natural number :r:, G.:r: is the sum of the dec1mals of :r:, defined by G.O=O G.:r: = :r: mod 10 + G.(:r: div 10) for :r:
>0
We are asked for a program witb post-condition r = G.N for natural number N. The program scbeme presented above yields as tail invariant
Po , G.N = r
+ G.:r:
and as a lower bound for :r:, we add
For :r: = 0, we bave r
+ G.:r: = r
and for :r: > 0:
r+G.:r: {definition of G, :r: > 0 l r + (:r: mod 10 + G.(:r: div 10)) = {+ is associative } (7· + :r: mod 10) + G.(:r: div 10)
leading to
l[var:r:: int; {N ~OJ :r:, r := N, 0 {invariant: Po 1\ P1, bound: :r: l ;do :r: -=f:. 0-. x, r:= :r:div10 1 r +xmod 10 od
] {r = G.N}. Note that a bound function nation follows from
JS
specified to satisfy the termination requirement. Termi-
Thil invariants
=
xdiv10 < x [ heading for the definition of div } 10 * (x div 10) < 10 * x {calculus} xmod10 + 10• (xdiv10) < xmod10 + 10 •x {definition of div and mod } X < X mod 10 + 10 * X {xmodlO ~ 0} x < 10•x {calculus I O 0 1\ y mod 2 = 0 ==> P0 (x, y := x * x, y div 2)
77
78
General ProgramrmiJg Techniques
Po A y
>0
A ymod2 = 1 ~ Po(r,y:= T* z,y-1)
resulting in
l(varz,y: int; {A~ OAB ~ 0} r,x,y:= 1,A,B {invariant: r * xY = A 8 f\ 0 S y, bound: y} ;doy~O
- i f ymod2 = 0 - x,y:= X* x,ydiv2 0 ymod2 = 1 - r,y:= r * x,y-1 fi od {r * xY = A 8
f\
y = 0, hence, r
=A8 }
Since y halves at least every other step_ of the repetition, the time complexity of this program is O(log B). The purpose of this section is not to explain how a specific problem can be formulated in terms ofF or G. In practice, we do not always define For G explicitly. For mstance, the exponentiatiOn program would be introduced by 'We choose a tail invariant P, defined by
and we choose as guard y -# 0'. In later chapters we will see many applications of the tail invariant techmque.
Exercises 0. Derive a program for the computation of A * B where A and B are natural nuu1bers. Apart from div 2, mod 2, and *2 only addition and subtraction are allowed. 1. Derive a program for the computation of the number of factors 3 of natural positive number N.
26
The Guarded Command Language
{:c = 0} if true--+ {x = O}x:= 1 {:c = 1 V :c = -1, Proof 0} 0 true--+ {:c = 0} :c := -1 {:c = 1 V :c = -1, Proof 1} fi {:c = 1 V x = -1, Proof 2} ProofO:
*'
(x = 1 V :c = -1}{:c := 1) (substitution} 1 = 1 v 1 = -1 {calculus} true predicate calculus } :c=O
{
Proof 1: Similarly. Proof 2:
*'
true V true { predicate calculus } true predicate calculus } :c=O
{
Hence, execution of this selection is guaranteed to terminate in a state satisfying :c = 1 V :c = -1, but neither termination in a. state satisfying x = 1 nor termination in a state satisfying :c = -1 can be guaranteed.
In terms of weakest pre-conditions selection is characterized by (wp.(if Bo - t So 0B1 ._ 81 fi).Q =: def.B0 A def.Bt A {Bo V B1) A {Bo => wp.So.Q) A {B1 => wp.S•. Q}] Since for most expressions B [def.BJ holds, we usually omit def.B0 A def.B1 in calculations with this weakest pre-condition.
80
General Progromming TeciJniqnes 5. An /a-sequence is either a sequence consisting of the single element 0 or it is a 1, followed by two h-sequences. Syntactically, h-seqnences may be defined by
= o 1 1 (h) (h)
(It}
Solve
I[ conN: int {N ~ 0}; A; array[0.. 2*N+I)of (O.. lj; var r: boot;
s {r
= A is an it-sequence}
]1.
4.5
Summary
In this chapter we discnssed some general techmques tbat show bow a suitable invan ant may be denved from a given pre- and post-condition. We summarize these ideas.
Taking conjuncts When the post-condition is a conjunction of predicates, take some of the conjuncts as invariants and take the negations of the other conjuncts as guards for a repetition. As a special case, one can try true as invariant and the negation of the post-condition as guard.
Replacmg constants by variables. The replacement of one or more constants by variables yields a possible invariant for a repetition.
Strengthening invariants. When a choice for an mvariant has been made, calculations may lead to an expression E that is neither easily computed nor easily expressed in terms of the program variables. The extension of the state space with a variable and the addition of an invariant that expresses that this variable equals E may help obtain a solution to the problem.
Summary Tail invanants The general setting of tail recursion is as follows. A function F is given for which
F.x F.x
= h.x
= F.(g.x)
if b.x if -,b.x
and one is asked to derive a program that establishes r = F.X for some X. Then F.x = F.X is a good candidate as invariant for a repetition that solves this problem. A special case of tail recursion is applicable to tbe problem of computing G.X, where G is such that (0)
(1)
G.x= a G.x= lt.x ED G.(g.x)
if b.x if -,b.x
in wh1ch ED is an associative operator with identity e. Then G.X is good candidate for an invariant.
Exercises Derive solutions to the following programming problems.
0. I[ conN: int{N var b: bool;
s {b
~
1}; A· array(O.. N)ofint;
=(3p, q: 0 $. p < q < N; A.p- A.q $. 2)}
D.i:)conN: int{N ,__.. var r : int;
~ 1}; A;
array(O.. N)ofint;
s {r = (#i: 0 $.1 < N: (\t'p: j $. p < N, A.i ~ A.p))}
II2. The function A is defined on the natural numbers by
7
A.O=l A.(2n) = 2 * A.n, for n ~ 1 A.(2n+1) = n + A.(2n), for n ~ 0
= rEDG.x
81
Generai Programmmg Ted1wques
82
Derive a program for the computation of A.N, N ;:::: 0. 3. I[ conN: int {N;:::: 2}; A; array (o •. N) ofint; var z, y : int;
s {0 ~ z
y { definition of P } x>OAy>OA:r:~dy=X~dYA:r:>y ~
( (2)} 1\ y > 0 A (x- y) gcdy =X gcd Y A :r; { arithn1etic } :r;- y > 0 A y > 0 A (x- y) gcdy =X gcd Y [ definition of P} P(:r::= x- y)
:r;
>0
Hence, [P A z > y}x:= Finally, we derive P A
-.(:r;
> y)
:r;-
A -.(y
>y
y {P} and by symmetry {PAy> x}y:= y- x{P}.
> x)
{arithmetic} PA :r:=y { definition of P } :r;gcd:r; =X gcd Y :r;
{ (0)} = Xgcdl'
Application of the rule for repetition yields
(P} do :r; > y - :r; := x- y {x = XgcdY}
0 y > x --+ y := y -
x od
provided that this repetition terminates.
> 0 A y > 0 is stronger than P; we also have
Since :r; = X A y = Y A :r;
{x =X A y
=Y
A
do :r; > y - x := :r; {x =XgcdY}
-
:r;
>0
y
A y
> 0}
0 y > x --+ y := y -
x od
provided that tins repetition terminates. Termmation of a repetition is proved by means of an integer function on the state space that is bounded from below and that decreases in eacl1 step of the repetition. Such a function IS called a. bound function. For the repetition above, a suitable bound function
90
DerJVing Efficient Programs
This Jeads to the following program:
n,x,y:= N,O, 1 ;A:= (
~ ~
)
;don ;of 0 -. ifnmod2 =0-> A:= A*A ;n:= ndiv2
0 nmod2=1->
(;):=A(:) ;n:=n-1
fi
od {x = fib.N} A
nex~
(~
(
step is tbe elimination of the matrix operations. We compute some powers of
~ )=
(~ !)2=(~ ~)(~ ~)=(~ ~) (~ ~)4=(~ ~)(~ ~)=(~ :) This leads to the conjecture tbat all these powers are of the form ( :
where p
= a2 + 62 and q = ab + ba + 62 ,
a!b ) . Indeed,
Hence, matrix A may be represented by two
integers: tJair {a, b) represents matriX ( :
a! b ) . Then
A:= A * A corresponds to a, b := a * a + b * b, a * b + b * a + b * b and
Fibonacci The final solution is
prese~ted
91
below.
{N~o}
I[ var a, b, n, y : int; a, b,x,y,n:= 0, 1,0, 1, N ;don~ 0
if n mod 2 = 0 nmod2 = 6
0 --+ 1--+
a, 6 := a * a+ b * b, a* b + b * a + b * b ; n := n div 2 x,y:= a*x+b*y,b*x+ a*y+ b* y ;n:= n-1
od {x = fib.N}
l Needless to say that this program cannot be easily understood without its derivation.
Exercises Solve 0. I[ con A,B,N: int {N ~ 0}; var x: int;
s (x
= (I::i: 0 $l $
N: AN-• * B')}
]1. 1. I[ conN: int {N ~ 1}; var x; int;
Fibolucci {x = (Ei: 0 $l $ N: fib.i*Jib.(N-i)}
H. where fib is defined by
fib.O = 0, fib.1 = 1, and fib.(n+2) = fib.n + fib.(n+l) for n
~
0.
Chapter 6 Searching
I 6.0
Introduction
Many programmmg problems can be viewed as a so-called searching problem. For instance, the square root problem of Section 4.1 may be formulated as 'search for the max1mal natural number i for which i 2 $ N', i.e., establish post-condition :z;
= (maxt: 0 $ 1 II i 2 $
N: i}
It may also be formulated as
:z: =(mint: 0$ ill (i+l) 2 > N:i) I.e., search for the minimal natural number t for which (i+1)2 > N. In Section 6.1 we discuss a simple program called Linear SearciL The Bounded Linear Search IS presented in Section 6.2. In Section 6.3 we consider a more efficient scl1eme which is applicable to a large class of search problems. That program is known as the BinanJ Search. In Section 6.4 we disc11SS a less well-known program scheme called Searchzng by Elimmation.
6.1
Linear Search
We consider the following problem. For integer variable :z:, b.:t is a boolean expression such that (3 i : 0 $
1 :
b.i)
An example of such an expression 1s (:z:+l) * (x+ll > N. We are interested in the smallest natural i for which b.i holds. A formai specification of this problem is
92
Linear Seard1
93
ftvarx: int; {(3i: 0 ~ i : b.i)} Linear Search
(x =(mini: 0 ~ i
1\
b.i: i)}
n. We rewnte the post-condition: R:
0
~
x
1\
b.x
1\
A possible invanant
p : 0~
1\
X
(Vi: 0 IS
~
1
< x · -.b.i)
obtamed by the technique of taking a conjunct: we define P by
(Vi : 0 ~ ~ < X
'
-.b,i)
which is initialized by x := 0. As guard we choose, of course, -.b.x. Investigation of x := :c + 1 leads to
P(x:=x+ll {definition of P } 0 ~ X + 1 1\ (Vi : 0 ~ ! < X + 1 : -.b.i)
(Vi: 0
~ Z 1\ i r := r -1 od {r =(maxi : 0 ~ i < N 1\ A.t < A.(i+1) : i)}
S:
Proof:
< N; A.i;:: A.(i+l))
C'fi: 0 ~ i
=>
{ transitivity of ~ } A.O~A.N
Hence,
A.O < A.N => (3i: 0 ~ i < N: A.i
< A.(i+l))
The program with its accompanying proof is all one has to provide as solution to the problem.
6.2
Bounded Linear Search
Tbe Bounded Linear Search is a solution to the following problem. Given integer N, N ~ 0, and boolean array b(O.. N), one is asked to derive a program that assigns to variable :z; the least number i in [O •• N) for which b.i holds. If no such number exists in this domain, N should be assigned to :z;. A solution with invariant 0
~
:z:
~
N
1\ (Vi : 0 ~ i
< :z: : -.b.i)
and program :z::= 0 ;do -.b.:z: 1\ :z; =F N -> :z;:= x+l od
is not correct, since N does not belong to the domain of b and :z; = N is not excluded by the invariant.
A formal specification of the problem is
I[ conN: int {N ~ 0}; b: array{O.. N) ofbool; var :z;: int; bounded lineu search. {x =(maxi: 0 SiS N A (V j: 0 S 3
ll·
< i; -.b.j): i)}
96
Searching
When we define (without, of course, actually cbanging b) b.N as true, the post-condition may be written as
R.
0 S :r S N A (Vi: 0 Sa< x: -,b.i) A b.x
As explamed above, a repetition with -.b.:~: as guard IS not possible. When we tal\e b.x as part of the mvariant, it should be established by x := N, since N is tbe only v";ljjji!-for whicb it is known that b has the value true. On the other band, the first two conjuncts of R reqUJre x := 0 as initialization. This 'conflict' is solved by the mtroduction of integer variable y: we choose as invanant Po : 0:::; x:::; N A (Vi: 0:::; i
< x • -.b.i) A b.y
Then Po is established by x, y := 0, N and Po A x = y implies R. Hence, we choose x :F y as guard for the repetition and y-x as bound function. As bounds for y we add
P1
:
xSySN
to the mvanant. Then Po A p,_ A x #: y ~ 0 :::; x < N, aud, hence, b.x may occur in the statement of the repetition. It IS now easy to derive Po APt A x:f:y A -.b.x ~(Po A PJ)(x:=x+I) and Po A P, A x :f: y A b.x ~ (Po A P.)(y := x) This leads to the following solution: Bounded Linear Search
II conN: int {N ~ 0};
b: array IO.. N) of boot; var x: int; II var y : int; x,y:=O,N ;dox-:1-y -+if -.b.x - x := x+ 1 0 b.x -+y:=x fi od 11
{x =(maxi: 0:::; t S N A (V 1: 0 S j (Vi: p $ i $ q: A.p.i) for 0 $ p.::;; q $ N
(A is prefix-closed)
and A is postji:£-ciosed: (2)
A.p.q
=> (Vi: p $
i
$ q: A.i.q) for 0 $ p $ q $ N
(A is postfix-closed)
Segment Problems
112
Since the term, X.1 = 0, in A neither depends on p nor on q, it does not matter whether we replace in R the constant 0 or the constant N by a variable. We propose as mvariants P0 and P 1 defined by P0
·
r =
(maxp, q : 0 5 p :5 q :5 n
1\ A.p.q: q-p)
(
and
For the mitlalization, we de1·ive (maxp, q: 0::;; p::;; q::;; 0 1\ A.p.q: q-p) = {calculus} (maxp, q: p = 0 1\ q = 0 1\ A.p.q: q-p) = {A.O.O, cf. (0)} 0
t~ed (0).
from which we infer that P0 1\ P1 is initialized by n, r := 0, 0. Note that we For an mcrease of n by 1 we derive, assuming P0 1\ P, 1\ n =F N, \
=
=
(maxp,q: 0:5 p :5 q :5 n+l 1\ A.p.q: q-p) {split off q = n+1} (maxp, q: 0 ::;; p::;; q::;; n 1\ A.p.q: q-p) max (maxp: 0 :5 p :5 n+l 1\ A.p.(n+l): n+l-p)
·
{Po}
0 :5 p :5 n+l 1\ A.p.(n+l): n+l-p) {+distributes over max for a non-empty range, A.(n+l).(n+l), cf. (0)} r max (n + 1 + (maxp: 0:5 p :5 n+l/\ A.p.(n+l), -p) = { property of max and min } r max (n + 1- (minp: 0::;; p::;; n+1A A.p.(n+l): p)) r max (maxp:
=
leading to the introduction of integer variable s and accompanying invariant
Q : s = (minp : 0 :5 p :5 n
1\ A.p.n: p)
(Why iss not defined as s = (minp: 0::;; p::;; n+l (minp · 0 ::;;
p::;; 0 1\ A.p.O: p) = 0
1\
A.p.(n+l): p) ?) From
Constants, Inner Blocks, and Arrays
39
I[ var A, B,x : int; {A= A0 A B = B0 A A> 0 A B > 0} gcd
{x = AgcdB
A
A= Ao A B = Bq}
]1. expressing that the final values of A and B equal their initial values. This specification still allows assignments to A and B. We use in the declaration con instead of var to express the fact that no value should be assigned to the listed names. Hence, a specification that avoids the problems mentioned above is
l(conA,B: int {A> 0 A B > 0}; var x: int;
gcd {x=AgcdB}
u. Variables defined as con may not occur on the left-hand side of an assignment. Assertions about constants, such as A > 0 A B > 0, should not be repeated in annotations and should not be part of an invariant. They are 'universally invariant' smce the values of constants do not change. Assertions about constants provide a context of the program and may be used in proofs whenever appropriate. Constants are not part of the state space. Another addition to the guarded command language are so-called inner blocks. These are used to extend the state space (locally) by means of new variables. An inner block has the form I[ var .. · ; SJI. For variables introduced in an inner block, we use fresh names. As an example, we present a solution to gcd;
I[ con A,B: int; {A> 0 A B > 0} var x: int; I[ var y : int; x,y:=A,B ; do x > y -+ x := x-y Y > X - Y := y-x od {x = AgcdB A y = AgcdB}
n
] {x=AgcdB}
B-
Segment Problems
114
t.e., only values p for which s ~ p ~ n+l have to be investigated. For p = n+l we know that A.p.(n+ll holds, so we usually start our investigations with the calculation of A.p.(n+l) for s ~ p ~ rt. (Vi •· p ~ 1 < q • X:i = 0), and we We return to all zeros, for which A.p.q compute A.p.(n+l) for s ~ p ~ n:
=
A.p.(n+l) { definition of A} (Vi: p ~ z < n+l, X.i = 0) { split ofh = n, p ~ n } (Vi : p ~ 1 < n ; X.t = 0) A X.n { definition of A } A.p.n A X.n = 0
{ =0
Hence,
Q A X.n=O ::::> Q(n:=n+l) and
X.n =F 0 ::::> (Vp: s ~ p ~ n; .... A,p.(n+l)) from which we infer, smce A.(n+l).(n+l) holds
X.n =F 0
=?
Q(n := n+I)(s := n+I)
This leads to the following solution to all zeros;
I[ var n, s : int; n, r, s := 0, 0, 0 ;don =f: N --+ if X.n = 0 -skip 0 X.n =f: 0 --> s := n+l fi ;r:= rmax(n+l-s) ;n:= n+l od
]1. Note that we did not use the postfix-closedness of A.
Longest segruents
7.1.1
115
Left-minimal segments
As another example of the approach outlined in the previous section, we consider the problem of the computation of the length of a longest segment that formal specification is
IS
left-minimal. Its
I[ con N : int { N ;;?. 0}; X : array (O.• N) of int; varr: int;
s {r
= (max p, q : 0 :5 p :5 q :5 N
A (Vi : p :5
l
< q : X.p 5 X.i) : q-p)}
D· As before, we start with the introduction of A and define for 0 :5 p :5 q 5 N
A.p.q ;;;; (Vi: p :5 l < q: X.p :5 X.i) Evidently, the term in A.p.q depends on p and does not depend on q. However, the folloWing properties of A.p.q do hold:
A.n.n
(0)
(A holds for empty segments)
for 0 :5 n :5 N
o·.-);
and
A.p.q
(1)
~
(Vi: p :51 :5 q: A.p.i) for 0 5 p :5 N
JJ.rrl-1)."1'
(A is prefix-closed)
But A is not postfix-closed and the derivation of a program based on a replacement of the constant 0 by a variable is quite difficult, as the reader may verify. As in the previous section we define P 0 , Ph and Q (the conjunction of Qo, Q 11 and Q2l as
P0
.
r
= {maxp, q: 0 5 p 5
q :5 n A A.p.q: q-p)
P1' 0:5n:5N Qo; 0:5 8:5 n Ql: A.s.n Q2: (Vp: 0 :5 p < 8 ~ -..A.p.n) Since A is prefix-closed, we have, as before, Qo A Q2 A A.s.(n+l) ~ Q(n:= n+l) We derive, assuming Q A 0 :5 n
< N, for s :5 p 5 n
Segment Problems
116
.A.p.(n+l) {definition of A f ('IIi: p ~' < n+l ; X.p ~ X.i) {split offt = n, p 5 n < n+l ('IIi: p ~ i < n: X.p ~ X.i) { definition of A }
.A.p.n A X.p
~
A
f
X.p
~
X.n
X.n
hence, Q A X.s
5 X.n => Q(n:=n+l)
When X.n < X.s, we have, starting with the last line of tbe denvation above,
A.p.n 1\ X.p ~ X.n (X.n < X.s f => X.p U(h:= h-1) U 1\ h :f; 8 1\ X.(Ja-1) = X.n => U(8 :=h)
Longes t segme nts and we obtain as solution:
I[ var n, s : int; n,r,s := 0,0,0 ;don: F:N --+ I[ var h : int; h:=n ; doh.,! : s --+ifX .(h-1 )#X.n ->h:= h-l 0 X.(ll- 1) = X.n - s := h fl.
od
II ;r:= rmax (n+1- s) ;n:=n +1
od
IIThis program has time complexity O(N2).
Exer cises Derive an O(N) solution to
I[ con N : int {N ~ 1}; X : array [O .. N) ofint; varr: int;
s {r = (maxp , q: 0 :5 p :5 q :5 N A A.p.q: q-p)}
II·
,
where A.p.q is defined as
o.
(Vi,J: p :5 i :5 j < q: X.t
= X.j)
@x(p..q) is mcreasing. 2. (Vi: p :5 i < q: X.i :5 X.(q-1 )) 3. (#i: p :5 i
< q: X.i =
0)
=2
121
Segment Problems
122
' 4. \The product of any two elements of X(p .. q)
IS
at least zero.
I
5. X(p ..q)
IS
6. (Ei :11 ~
monotonic (i.e. ascending or descending). ~
< q: X.i)mod3 = 0
Tbe following exerciSes are more cotnplicated and may be skipped at first reading. 7. X(p .. q) contains at most two distinct values.
IX.pi ~ X.i)
8. (Vi : p ~ 7. < q :
< q : 0 ~ X., - X.;
9. (Vi, 1 : p ~ i ~ j
~
10. (Vi,J: p ~' ~1
< q: IX-'- X.j,
~ 1)
11. (Vi,J : p ~ i ~ i
< q : X.i- X.;
1)
7.2
~
(
I)
)
Shortest segments
We present only one example of a shortest segment problem. In this section we show that the approach for longest segment problems may lead to rather complicated solutions when applied to a shortest segment problem. This section may be skipped at first reading: tn Chapter 8 the same problem is solved m a much better way. The problem is to compute the length of a shortest segment that contains at least two zeros. It 1s formally specified as
I[ con N : mt {N
~
0}; X : array 1:0 •.N) of int;
varr: int;
s
{r = (minp,q: 0 ~ p ~ q ~ N 1\ A.p.q: q- p)}
ll· where, for 0 ~ p
A.p.q
=
~
q ~ N,
(#,:p~& X)
i.e., when f.O.N >X then the search area may be reduced to (O.. .MJ x (O.. N-1[. Since
I is ascending in its second argument, we have f.O.N
= (maxj : 0 $ 1 ~ N : J.O.j)
)
hence,
f.O.N
< X => (V j
: 0 $ j $ N : j.O.j
< X)
,·
i.e., when f.O.N < X then the search area may be reduced to [l...MJ x [O .. JVl. We fonnalize this discussion as follows. Let I and J be such that 0$
I $ M A 0 $ J $ N A f.I.J =X
The 'search area' is charactenzed by (I, J) E fa ..MJ X l.O •• bJ or, equivalently, we choose as invariant for a repetition
which is established by a, b := 0, N. The reduction of the search area in tenns of P is given by the following derivations.
f.a.bX { f is ascending in its first argument, a ~ I} j.I.b >X
{f.I.J=X} b >F J { P, m particular, J
~
b}
J~b-1
We conclude
PAj.a.bX
=?
P(b:=b-1)
This yields tbe followmg solution:
a, b := 0, N {invariant: P, bound: N - a+ b} ;do f.a.b X-+ b:= b-1 od {J.a.b=X} This program bas time complexity O(.M +N}. A stmilar program is obtamed when we choose (M, 0) as starting pomt. An operational interpretation of this technique is the following. Tbe three-dimensional surface z. = j.z.y has as lowest point (0, 0, f.O.O) and as ·highest point (llf, N, J.M.N). Somewhere in between position X occurs. To find that position one should not start at a m1nimum or at a maximum, but somewhere in between, for instance, at (0, N, f.O.N) or at (M, 0, J.M.O), and move along the slope of the surface in such a way that position X IS approximated as well as possible, i.e., by going down when the value is too high and by going up when the value is too low. Because of this interpretation, which will not be pursued any further, this technique JS called Slope Search. Note that tbe points where f attains its minimum or its maximum are not important. The other two points, that are either tbe maximum of a row and the minimum of a column, or the minimum of a row and the maxJmum of a column, are useful. When, for instance, f is ascending in its first argument and descending in its second argument, suitable invariants are 0 S a S I A 0 S b S J or I S a S M A J S 6 S N _ The reduction of the search area, i.e., tbe reduction of the problem to a smaller problem of the same form, usually leads to the introduction of a tail invariant. For the above program, we have
Slope SearciJ
130
(3 i,] : 0 ~ I ~ M A 0 ~] ~ N: f.~.] =X) (3i,J; a.$ i $ M A 0 ~ 3 ~ b ~ f.i.J =X) as tail invariant. In the following sections we use tail Invariants of this form.
8.1.0
Searching
t
In the previous section we solved the problem of searching for a value in twodimensional array, given that the value occurs in the array. In this section we cJ..nsider the followmg problem: we are given mtegers M and N, M ~ 0 A N ~ 0, and integer array f(O .. M)xfO.. N) such that f IS ascending in both arguments. We are asked to determine whether value X occurs m f. A formal specification IS
I( con M,N,X: int{M ~ 0
AN~
Of; f: array(O.. M)x(O.. N)ofint;
[I is ascending in both arguments I
)
varr: boot;
s {T
= (3 i,] : 0 ~
I
< M A 0 ~ ] < N - f.,.] =X)}
/
l Followmg tbe strategy explained in the previous section, we define 'tail' G.a.b for 0 $ a $ M A 0 ~ b ~ N by _,.
In terms of G, t.he post-condition of U1e specification may be written as R,
r::: G.O.N
We introduce integers a and b and define tail invariant P0 by
Po :
T
V
G.a.b
= G.O.N
The bounds for a and b are specified by mvariant P 1 .
A proper initialization of Po A Pt is a, b, r := 0, N, false. For a = Af V b = 0 the range of the quantification in G is empty, hence,
Tlie basic principle P0 A (a= =?
131
M V b = O)
{definitions of P 0 and G } r V false G.O.N {predicate calculus} r::: G.O.N {definition of R }
=
R Furthermore, wllen r is true, then r V G.a.b r V
= r, hence,
G.a.b ::: G.O.N
{ r V G.a.b r::: G.O.N
=
r}
and we conclude P A (a= M V b = 0 V r) =? R. Thus, we choose
a:;!:MAb:;!:OA-.r
as guard of a repetition. We investigate an increase of a by 1. Assuming 0 5 a< M A 0 < b 5 N, then G.a.b
{ definition of G J (3 i, 1 : a 5 t < M 1\ 0 5 J {split off t =a}
< b : f.i.j = X)
G.(a+l).b V (3J : 0 5 J < b · J.a.J =X) { f is ascending in its second argument, 0 5 b-1, assuming f.a.(b-1) < X } G.(a+l).b V false {predicate calculus } G.(a+l).b
Hence, f.a.(b-1) X} G.a.(b-1) V false _ { predicate calculus } G.a.(b-1)
(
Hence, f.a.(b-1) >X => (G.a.b
=
G.a.(b-1))
For the remaining case /.a.(b-1) =X, we dertve for 0
Po
~a
{ definition of G l r V true G.O.N { predicate calculus } true V G.a.b := G.O.N {definition of Po } Po(r := true) 1\
=
These derivations lead to the following solution
I[ var a, b : int; a, b, r := 0, N, false {invaiiant: Po 1\ Ph bound: M- a+ b + # .(-.r)} ;doa:FM A b*O A -.r -+if f.a.{b-1) X-. b:= b-1 0 /.a.(b-1) =X-+ r:= true fi
od
fl.
The basic prinCiple
133
This program has optimal time complexity O(M+N), which is proved as follows. Let h(O •. NJ be an integer arr~y, then a program for the computation of
(3i: 0 SiS. N: h.t =X) has at least time complexity O(N), since any correct program will inspect all h.i in the case that X does uot occur m h. Define array f(O .. NJx[O .. Nl by f.i.j = - ( X I ifi+JN f.i.j = h.i ift+j = N Then f is ascending in both arguments and a correct program for "the computation of (3i,j: 0 S. iS N A 0 S. j S. N f.i.j =X) will inspect all j.i.(N-i) m the case that X does not occur in
8.1.1
J.
Decomposition in a sum of two squares
As our second example, we derive a program for tbe computation of the number of ways in which a natural number N can be written as the sum of two squares. We supply an annotated program together with its numbered derivations. The first thing to do is to supply a formal specification: [conN: int {N ~ 0}; varr: int;
s {r ]J •.
= (# x, y : 0 S. x S. y : x 2 + y 2 = N)}
Since x 2 +y2 is increasing in both arguments on the domain 0 S. x as
G.a.b = (#:c,y: aS. x S. y 5 b: x 2 +y2
= N)
and we choose as invariants
Po: r+G.a.b= (#:c,y: 0 S. x S. y: x2 +y2 =N) P1: OS,a
5 y, we define G.a.b
Slope Search
134
In tbe followmg proofs we present the calculations for a solution. ProofO G.a.b
{ definition of G J ~ y ~ b ; x 2 + y2 { provided a > b }
(# x, y : a ~ x =
= N)
0 Hence, Po
1\
(
a > b 1mplies the post-condition.
Proof 1 For tbe initialization, we derive for 0
~
6
G.O.b
=
{definition of G }
(# x, y ; 0 ~ x ~ y ~ !I : x 2 + y 2
\
= N)
( range split I (# x, y : 0 ~ X ~ y : x 2 + y 2 =
=
(#
)
N) - (# x, y : 0 ~ ( provided b2 ~ N, 0 ~ b } x, y : 0 ~ x ~ y : x 2 + y 2 = N)
X
~ y II y > b : x 2 + y 2 =·-fin
Hence, r=OIIa=0/\0~6Ab2 ~N ~
{see above } r+G.a.b=(#x,y:O~x~y:x2 +y 2 =N) 1\ O~a
=
{definitions of Po and P, }
Po
1\
P1
Proof2 We mvesLigate an mcrease of a by 1. For 0 G.a.b
{ definition of G }
(#x,y: a~ x ~ y ~ 6: x 2 + y 2 { split off x = a I
= N)
~
a
~
b, we denve
The bas1c prinCJpie
135
G.(a+I).b + (#y: a-~ y ~ b: a 2 + y2 = N) = {a2 + y2 is increasing in y, a ~ b} G.(a+l).6 + 0 if a 2 + 62 < N { G.(a+l).6 + 1 if a 2 + 62 = N Proof3 We
inves~igate
a decrease of 6 by 1. For 0
~
a
~
6, we derive
G.a.b {definition of G} (#x,y: a~ x ~ y ~ b: x 2 + y2 = N) {split off y = 6 } G.a.(6-1) + (#x: a~ x ~ b: x2 + 62 = N) = (x 2 + 62 15 Increasing in x, a 5 b ~ G.a.(b-1) + 0 if a 2 + b2 > N { G.a.(b-1) + 1 if a 2 + 62 = N
Solution: [ var a, b : iut;
r,a:=O,O {Linear Search: l ;6:= 0 ;do 6*6 < N-+ 6:= 6+1 od {invariiiJlt: P 0 1\ P1, Proof 1, bound: 6- a} ;doa~b
_.. if a* a+ b * b < N-+ a:= a+ 1 {Proof 2} 0 a* a+ h b > N- 6 := 6-1 {Proof 3} 0 a*a+b*6=N-r,a:=r+1,a+l {Proof2} 0a*a+6*6=N-+r,6:=r+l,b-l {Proof3~ fi
od {r = (#x,y: 0 ~ x ~ y :x2 +y2 =N), ProofO}
D· This coucludes the presentation of tbe solution. This program has time complexity 0( ,fN). Initializing 6 by b := N leads to a program tbat has time complexity O(N) which 1s as bad as a brute force search In the area [0.. v'N] x [0.. v'NI.
Slope Search
136
One may wonder whether the two guarded commands
a* a+ b * b = N-+ r,a:=r+1,a+1 a* a+ b* b = N-+ r,b:=r+1,b-1 may be replaced by
a• a+ b* b = N-+ r,a,b:=r+1,a+1,b-l The only way to find out is by calculation: assume 0 :5 a :5 b A a 2 + b2
G.a.b {definition of G} (# x, y : a :5 x :5 y :5 b: x 2 + y 2 = N) = { split off y = b } G.a.(b-1) + (#x: a :5 x :5 b: x 2 + b2 = N) = (split off x =a in G.a.(b-1)} G.(a+1).(b-1) + (#y: a :5 y :5 b-1; a 2 + y 2 = N) + (# x : a :5 x :5 b : x 2 + b2 = N) = {a2 +b2 = N} G.(a+1).(b-1) + 1
= N, then
(
)
Hence, this replacement is allowed, leading to
I[ var a, b : int; r,a:= 0,0 ;b:= 0 ;do b*b < N-+ b:= b+l od ;do a :5 b -+ if a * a + b * b < N-+ a:= a+ 1 Ua* a + b * b > N-+ b := b-1 Ua* a+ b*b = N .- r,a,b:= r+1,a+1,b-1 fi od
].
8.1.2
Minimal distance
Our next example is the derivation of a program for the computation of the mmimal distance of two ascending sequences. It is specified by
Tl1e basic prinCJple
137
l[conM,N:int{M~O 1\ N~O};
J ~ array {O..M) ofint {! is ascending}; g : array fO .. N) ofint VVT':
{g is ascending};
int;
s {r = (minx,y: 0 5 x < M
1\ 0
5 y < N; lf.x- g.yl)}
BNote that J.x-g.y is ascending in x and descending in y and g.y- f.x is descending in x and ascending in y. The expression lf.x-g.yl, being equal to (J.x- g.y)max(g.yf.x), does not have these properties. However, as will emerge from the derivations, a slope search still is possible. Since f.x - g.y and g.y - J.x have both ascending and descending properties, we define G.a.b for 0 5 a 5 M 1\ 0 5 b 5 N as:
G.a.b = (minx,y; a 5 x < M
1\
b 5 y < N; lf.x- g.yl)
The post-condition may be written as
R,
r=G.O.O
and we propose as invariants
Po: rminG.a.b = G.O.O P1; 05a5MA05b5N These are initialized by a, b, r := 0, 0, oo. Furthermore,
Po A (a= M V b = N)
=>
{minimum over an empty range is oo }
rminoo = G.O.O {calculus} r= G.O.O
This yields as guard a =I= M 1\ b-:/:. N. For 0
5 a (V s: p $ s S q: .A.p.s)
the empty segment is an .A-segment .A is prefix-closed
We derive a program that has post-condition R: ,. = (maxp,q: 0
Sp S q$ N
1\ .A.p.q: q-p)
Since q-p is ascending in q and descending in p, we define G.a.b for 0 $a. S b S N by G.a..b = (maxp, q: aSpS q S N 1\ b S q S N 1\ .A.p.q: q-p)
Then R may be formulated as
R;
,. = G.O.O
As invariants for a repetition we choose
50
Qua.otifica.tions 3. The greatest common divisor of natural numbers By definition 0 gcd 0 = 0.
:1:
andy is denoted by :~:gcdy.
(i) Give a. forma! definition of gcd .
(iil Show that gcd is commutative and IISSociative. (iii} Prove that gcd h!IS an identity. (iv) Investigate whether* or+ distribute over gcd. 4. Prove
j[ conN: int {N
~
1};
f:
array (O •. N) ofint;
var :1:: int; [vary: int; :~:,y:= O,N-1 ;do:~:~y
..... if f.:J: ~ f.y ..... 3: := :~:+1 0 f.y ~ j.:J: ..... y:= y-1 fi od
] {f.:~:= {max~ : 0 ~
Jl.
&
< N ' f.i)}
Longest aud shortest segments
143
G.a.b {definition of G, split off p = a} G.(a+l).b max (maxq: a~ q ~ N A b ~ q ~ N A A.a.q: q-a.l
=
(a~b}
G.(a+l).b max (maxq: b ~ q ~ N 1\ A.a.q: q-a) ( (1), -.A.a.b, hence, (V q : b ~ q ~ N ; -.A.a.q)} G.(a+l).b Hence,
-.A.a.b => G.a.b = G.(a+l).b This concludes our derivation. The program scheme for ma:z:seg is shown below. As bound function, 2N - a - b will do.
maxseg: I[ var a,ll : int; a,b,r~= 01 0,0 ; do 6 '# N V -.A.a.b ->if A.a.b-+ r:= rmax(b-a) ;6:= b+l 0-.A.a.b --+ a:= a+1 ft
od
;r:= rmax(N-a) {r= (maxp,q: 0 ~p ~
q~
N 1\ A.p.q: q-p).
B·
Note that we did not use the fact that q - p is ascending in q, only that it as descending in p. A closer look at the range of the quantification in the post-condition (using the fact that A is prefix-closed) reveals that on tlae one band the descendingness plays a role and on the other hand the specific form of the range is important. To obtain a final program, one has to replace A.a.b by a booiean expression. For instance, we may try to add invariant c = A.a.b, which is initialized by c := true. Since 0 ~ a ~ 6 ~ N, this invanant is well defined.
Slope Searcl1
144
8.2.1
Shortest segments
We now consider mmseg and we assume that A satisfies (01) -.A.p.p
the empty segment is a -.A-segment '
(2') -.A.p.q ~ (V s : p S s S q : -.A.s.q) -.A is postfix-closed
The following derivation is almost a copy of the derivation presented in the previous subsection and the reader is advised to compare both texts carefully. We define G.a.b for OSaSbSN by
G.a.b
= (minp,q: aSpS qS NAbS q SN A
A.p.q: q-p)
Then post-condition R may be formulated as R:
r=G.O.O
As invariants we propose Po: rminG.a.b = G.O.O
P,; OSaSbSN which are established by a, b, r := 0, 0, oo . We derive
G.a.N { definition of G }
(minp: aSpS N A A.p.N: N-p) {assume -.A.a.N, -.A is postfix-closed} 00
Hence, Po A P1 A 6 = N A -.A.a.b
~
R
which yields b :f: N V A.a.b as guard of the repetition. To determine a condition under which b may be increased, we derive for 0 Sa S b < N:
G.a.b
=
{definition of G, split off q = b}
G.a.(b+l} min (minp: aSpS 6 A A.p.b: 6-p) = (assume -.A.a.b, -.A is postfix-closed } G.a.(b+l)
Longest and sl1ortest segments
145
Hence,
-..A.a.b => G.a.b = G.a.(b+l) Note that
P A (b :I= NV A.a.b) A -..A.a.b => b < N Fbr the case A.a.b we investigate an increase in a. Due to (0'), we have A.a.b => a :I= b, hence a 5 b is not violated by a:= a+1 in this case. We derive for 0 5 a 5 b 5 N A .A.a.b
=
G.a.b {definition of G, split off p = a} G.(a+l).b min (minq: a 5 q 5 N A b 5 q 5 N A A.a.q: q-a) {a5 b} G.(a+l).b min (minq: b 5 q 5 N A A.a.q: q-a) { A.a.b, q - a is ascending in q} G.(a+l).b min (b- a}
Hence,
.A.a.b => G.a.b = G.(a+1).b min (b- a} This concludes our derivation. The program scheme for minseg is shown below. As bound function, 2N - a - b will do. minseg:
[ var a, b : int; a,b,r:= O,O,oo ; do b ::f: N V A.a.b -+ if -.A.a.b -+ b := b+ 1 0 A.a.b-+ r:= rmin(b-a} ;a:= a+1 fl od {r=(minp,q:05p5q5N A A.p.q:q-p)}
J.
Slope Searcll
146
At least two zeros revisited
8.2.2
In this subsection we apply the scheme for mmseg to obtain an algorithm for the computation of the length of a shortest segment of integer array XIO .. N) that contains ' . at least two zeros. For this problem
A.a.b
= (#z:
a~
z < b: X.z = 0)
~ 2
Then -.A holds for empty segments and -.A is postfix-closed. To express A.a.b as boolean expression, we introduce integer variable c and accompanying invariant
Q' c = (#z: Then A.a.b
a~
=c
z < b: X.z
~ 2
= O)
and -.A.a.b - c < 2. This leads to the followmg solution.
I[ var a, b, c : mt; r,a,b,c:=oo,O,O,O ; do b f. N V c ~ 2 -+ if c < 2-+ if X.b = 0-+ c:= c+l U X.b f. 0 _,skip fi
;b:= b+l r min (b- a) ; if X.a = 0-+ c:= c-1 U X.a =F 0-+ skip fi ;a:= a+l
U c ~ 2-+ r :=
fi od
]1. Compare this program with the one derived in Chapter 7.
Exercises 0. I[ conN: mt {N ~ 0}; X • array(O .. N) ofint; {(Vi: 0 $ z < N: X.i ~ 1)} var r: int;
s {r = (minp, q: 0 ~ p ~ q $. N A (Ez: p ~ t < q: X.i) ~ N: q- p)}
Jl.
Longest CUJd shortest segments
147
1. If conN: int {N ~ lj; X· array[O.. N) ofint; var r: mt;
s
{r = (maxp,q: 0 :S p < q :S N A A.p.q: q- p)}
l where A.p.q := (#a: p < i
< q: X.a = X.(i-1)) = 37
2. l[conN:iut{N~OJ;X array(O.. N)ofint; {(Vi: 0 :S I< N: X.i ~ 0)} var r: int;
s {r = (maxp,q: 0 :S p :S q :S N
1\
(Ei: p :S 1 < q: X.i) :S 3: q- p)}
l How would you solve this problem if each element of X 1nay be inspected only once? 3. Let N ~ 0 and let X(O.. N) be an integer array. Oenve a program for the computation of the length of n shortest segment that contains values 0,1, and 2.
General Programming Techniques
52
consider a. program consisting of a repetition of a statement which requires, in isolation, one second for each execution. The program contains integer N as constant. The executiOn time of the program is shown below for the cases that the repetition performs 2logN, ../N, N, and N 2 steps.
= 1000000
number of steps
N= 1000
N
2 logN
10 seconds 30 seconds 15 minutes 300 hours
20 seconds 15 minutes 300 hours 30000 years
-IN N N2
If we succeed in speeding up the hardware such that execution of S takes a millisecond, i..e., we improve it by a factor 1000, then we obtain the following figures.
= 1000
number of steps
N
2 logN
0.01 seconds 0.03 seconds 1 second 15 minutes
.JN N N2
N
= 1000000
0.02 seconds 1 second 15 minutes 30 years
A significant improvement of a program is not obtained by tricky adaptations that, for instance, save a variable or save an assignment within a repetition. Such changes often destroy the elegance and clarity of the original algorithm. Similarly, case analysis in which 'easy to compute' cases are treated separately does not really help. A huge improvement is a. reduction from, for instance, O(N) to O(log N). Such an Improvement is obtained by transforming the program into a more efficient one, or by derivmg a completely different program. Examples of this are discussed in Chapter 5.
4.1
Taking conjuncts as invariant
When post-condition R is of the form P 1\ Q 1 one may try to take one of the conjuncts, say P, as an invariant, and the other one as negation of the guard of a repetition, leading to
{P} do ..,Q--+ S od {P 1\ Q} In its simplest form this method yields, taking true as invariant, {true} do ..,R--+ Sod {R}
Mixed Problems
1 Q(h:= h(E:F))J where, as usual, Q(h := h(E:F)} denotes Q 111 which h IS replaced by h(E:F). As an example of the use of the rule of the array nss1gnrnent, we prove
{h.O
=1 A
h.1 = 1} h.(h.1) := 0 {h.(h.1)
Proof: Assume h.O
= 1 A h.l =
1. We derive
(h.(h.l}}(h := h(h.1:0)} {substitution} h(h.1:0l.(h(h.l:0).1) {h.1 = 1} h(1:0).(h(l:O).l) = {definition of h(x:A), 1 = 1} h(l:O).O {definition of h(x:A), 1 # 0} h.O { h.O = 1 ~
=
1
= 1}
154
Array Manipuiations
It can be seen that for many array assignments, it is difficult to predict the outcome without calculations. Fortunately, there are many cases m which the effect of h.E := F can be easily computed. /.../
In the definition of :z: := E conjunct def.E occurs. For array assignment h.E := F we require that E and F are well defined, and that the value of E is in the -range of h. More formally, def.(h.E) is defined by (def.(h.E)
=def.E
A 0
$ E
< Nl
and the formal definition of h.E := F is
{P} h.E := F {Q} is equivalent to (P ~ def.F A def.{h.E) A Q(h:= h(E:F)))
In terms of weakest pre-conditions we have [wp.(h.E:= F).Q := def.F A def.(h.E) A Q(h:= h(E:F)))
In calculations conjunct Q(h := h(E:F)) is the starting point. One should, however, be aware of the other two conjuncts too. Multiple array assignments are not allowed. If they were the program fragment
:z:,y:= o,o
;h.:z:,h.y:= o, 1
=
would establish h.O = 0 or h.O 1. This problem may be solved by the definition of an order {for Instance, from left to right) in which substitutions are performed. We prefer to avoid it by not allowing multiple assignments in which an array assignment occurs. We present two examples in which we use the formal definition of the array assignment. Then, at the end of this section, we present the 'simple array assignment rule' which simplifies calculations in certain cases.
As a first example of tl1e derivation of a program in which array assignments are used, we solve all zeros specified by
I[ con N : int {N 2: 0}; var h: array(O •. N)ofint;
all zeros {(Vi: 0$ i < N: h.i
II-
= 0)}
Array assignments Replacemetlt of the
co~stant
155
N by the integer vanable n leads to mvariants Po and
P,. Po : (Vi : 0 :::; ~ < n ; h.1. = 0) P1
:
0:5n:5N
which are established by n := 0. We Investigate an increase of n by 1 and we derive, assummg Po A P1 A n :/:. N,
(Vi: 0:::; i < n+l: /u = 0) {split off i = n, 0 :::; n } (Vi : 0 :::; i < n ; h.1. = 0) A h.n = 0
{Po} (Vi : 0 :::; 1. < n ; h.1. = h.i) A h.n = 0 {definition of h(x:A)} (Vi: 0:::; 1. < n: h.&= h(n:O).i) A h.n = h(n:O).n { import 1. = n } (Vi:
0:::; i < n+l: h.1. = h(n: O).i)
The last line says that replacing h by h(n:O), i.e., h.n:= 0, establishes P0 (n:= n+l). This yields as solution to all zeros
I[ var n : int; n:=O ;don:/:. N --+ h.n:=O ;n:=n+! od
As a second exatnple we consider the problem of computing a frequency table for a series of outcomes of an expenment of throwing a die. A formal specification is
I[ cooN : int {N ~ 0}; X ; array {O ..N) ofint; {(Vi: 0 :5 i < N; 1:::; X.1.:::; 6)} var h : array [1..61 ofint;
frequency table {(Vi: 1 :5 i:::; 6: h.1. = (:fl:k: 0:::; k < N; X.k
D-
= i))}
Taking conjuncts as invariant
55
In the next chapter we sho~ that, if one allows div 2 and mod 2 as operators as well, a program can be derived that has time comptexity O(log(A div B)).
As another exampte, we derive a program for the computation of the square root, rounded down, of a natura! number. It is specified by
I[ conN: int{N ~ 0}; varx: int; square root {:z:2 ::; N A (:z:+l) 2
n.
> N}
We try as invariant P : z 2 ::; N, which is established by :z: := 0. Negation of (x+I) 2 > N yields (:z:+I) 2 ::; N as guard, teading to
x := 0 {P} ;do (x+l) * (x+l)::; N-+ Sod {:z:2 :5 N A (:z:+l) 2 > N} Since P implies N - x 2 ~ 0, N - :c2 seems appropriate as bound function. However, N - z2 decreases for increasing :z: if and onty if 0 ::; :z:, which cannot be inferred from P A B. This problem is solved by specifying a bound for :z:; strengthen P to
We investigate an increase of :z: by 1: P(x:=:z:+l) { substitution } 0 :5 :c + 1 A (x+I) 2 :5 N h=YX This yields the following solution: A,U1 V1 B:= IJ,X, Y,IJ {invanant P 1 bound: l.U + I. V}
;doUj6(] A 1'1"[) - i f l.U
~
l.V -+
'split U : U
= U0 U1 A
{h = AUoU1 VB
l.U1 = 1.\f'
A YX
= AVUoU1B}
A YX
= .t1VUoU1 B~
;SWAP.U1.V
{1& = AU0 VU1B ;U,B:= Uo,UlB
{h=AUVB A YX=AVUB}
0 l.V ~ l.U __, 'split V. V
= VQV1 A l.VQ = l.U'
{h = AUVoV.B A YX = AVQV.UB} ;SWAP.U.Vo {h = AVQUV.B A YX = AVoV.UB} ;A, V ==AVo, V,. {h = AUVB A YX = AVUB} fi
od {h = YX}. To encode Uns algorithm 111 terms of array h 1 we represent sequences A, U, V 1 and B by integer values a, b, k, and l, such that A= h{_O .. a)
B U V
= J&(b..N) = h(a..a+k), hence, l.U = k = h{b-l..b), hence, l. V = I
Swaps
167
=
These relations are called coupling anvariants. Note that a+k b-l should be a coupling invariant as well. In terms of a, b, k, and i, the algorithm is
I[ var a, b, k, l : int; a,b,k,l:= O,N,N-K,l( ;do k j 0 A l ¥: 0 -tifk~l
I[ var n: int ;n := b-l ;don~ b-+ swap.n.(n-l) ;n := n+l od)l ; k := k-l i b == b-l 0l ~ k -+ l[varn: int ;n:= a;do n :F a+k- swap.n.(n+k) ;n:= n+l odD ;l:= l-k ;a:= a+k fi -+
od
»· To determine the time complexity of this program, we add the auxiliary variable t to record the number of swaps performed during its execution. We leave out the vanables that are not relevant to this discussion. This y1elds
I[ var k, L, t : int; k,l:= N-K, [( ;t:= 0 ;dok:;&O A t:;&O -t
if k ~ l
-+
0L ~ k -
t := t+l ; k := k-l t := t+k ; l := l-k
fi
od
In this program, we recogmze the algorithm for the computation of a greatest common divisor. Note that t + k +lis constant during execution of the repetition. Initially, it bas value 0 + /( + N- [( = N, hence,
t+k+l=N is an invariant of the repetition. What can be said about the finai values of k and l '? With respect to k and !, we b.ave as invariant
kgcdl
= /(gcd(N-[()
Array Mampulations
168
and, since Ogcdx = k+ l
:~:gcdO
= :z: = z+O, we have as post-condition
= /( gcd{N-/() = /( gcdN
and, smce t + k + l
= N, we conclude that N- (I< gcd N) swaps are performed.
Exercises Derive solutions, with time complexity O(N), to the following problems. The only array manipulations allowed are swaps. 0.
I( conN: int{N ~ 0}; var h : array (O .. N) of int;
s {{3 p: 0 :S p $ N : {Vi : 0 $ 1 < p: /u :S 0) A (Vi : p $ 1 < N : h.i ~ 0))}
D1. 1[ conN : mt {N;::: 0};
var h ; array [O.. N) of int;
s
{(Vi: 0$1 < N A tmod2 = 0: ll.imod2 = O) v (Vi : 0 $ 1 < N A 1mod 2 = 1 ; /u mod 2 = 1)
l H2.l(conk,N:int{O$k 0. We formulate this result as follows. A comparison-based sorting algorithm has time complexity of at least O(N log N). In Section 11.2 we present O(N log N) sorting algorithms. An example of a noncompartson-based algorithm is bucket sort. This algorithm is applicable when the values of h are within a small range, say [O •• J(). Using a frequency table (cf. Section 10.1), the frequency of each value that occurs in h can be computed and these values are assigned to /& m ascending order, leading to an algorithm that has time complexity
O(N+l(). The sorting problem discussed in tlus chapter has the following specification:
I[ conN: int {N 2: 1}; var h = array 1:0.. N) of int; sort {(Vi,J: 0 ~ t ~ 3
< N.
h.i ~ h.j)}
D in which only swap operations are allowed on h. In solutions to this problem, we often encounter the following statement (0 ~ 1 < N and 0 ~ j < N):
if h.a ~ h.j -. skip 0 /u > /&.j -. swap.i.j fi for which we have
{P} if h..a ~ h.J 0 h.i > h.j fi
-> -o
skip swap.a.J
{Q} is equivalent to
1:P
~ Q(h:= h(i,J: h.iminh.J,h.amaxh.j))]
172
Sorting
11.1
Quadratic sorting algorithms
[n this sectaon we denve some O(.N2) sorting algorithms, not becaU!Ie of the1r usefulness, but to illustrate the ways m wbicla they may be denved and to show wbat kinds of problems are related to sorting. Oue should not try lo memonze them and we do not supply average-case tame complexity denvations, nor do we supply figures that compare these sorting algorithms with respect to some test mputs. The post-condition R of the specilicataon of sort may be rewritten for instance, as
111
several ways,
< & < N: ll.(i-1) ~ /a.i) < N: ia.i $h.j) (Vi: 0 S 1 < N-1: (Vj :a~ 1 < N: /uS h.i))
(Vi: 0
(Vi,] :0~ • z) 1\
Hence, h[O ..r) and h[w ..N) still have to be sorted, i.e., this post-condition 1mplies his ascending
=
h[O .. r) is ascending 1\ h{w .. N) is ascending
We n1ay apply a similar splitting to lt(O..r) and h[w .. N), leading to four smaller parts that still have to be sorted. A generalization of this idea IS expressed by the followmg Invariant:
P:
h(O ..N) is ascending
=
(Vv: v
e V; It is ascending on v)
where V is a set of disjoint subsegments of (O .•N) and where for subsegment v:
his ascending on v
= (Vi,J: i e v 1\ 1 e v 1\
A program based on P is presented below.
1
~ 1:
/u
~
h.j)
Sorting
180
V·= {(O •. N)} ;do v~ 0 -+ 'choose a E V' ;if lcngth.a ~ 1-+ V := V \ {af 0 le11gth.a ~ 2 -+ 'choose J E a' ;z:=h.] ; 'pcrfonn DNF with z on a' {a= /J-r6 1\ (Vi: t E fJ: /u < z) A (Vi: t E "'/: /u = .:::) A (Vi: t E 6: h.t > ::.)
I
; \' := {V \ {a}) u {f.l I u {6} fi
od (Why docs it termmntc?) To obtnm n program 1n tbe guarded command language, we bnve lo find n suitable representation for \1 , nnd we have to refine 'choose a E \'' and 'choose 3 E a'. The set V can be represented by two mtcgcr arrays :z: andy, aml an mtegcr vnnnblc k, such tbnt
v=
{(:z:.t..y.i) 1o ~,
lete program is presented below.
182
Sorting
Quicksort
,,
I[ var n, m : int; n, m := 0, l { m = 2n} ;do m < N--+ n,m:= n+1,m*2od {n ~ 21ogN} ; I[ var fc, p, q: mt; x, y ; array (O ..n) ofint; k,p,q:=O,O,N ; do k :F 0 V q-p ~ 2 -+if q-p 51-+ k:= k-1; p,q:= x.k,y.k 0 q-p ~ 2-+ l[var r,w, b,z: int; z := h.((p+q) div2) ;r,w,b:=p,p,q ;dow ~b-+ if h.w
z--+ b:= b-1; swap.b.w ft od ; if r-p 5 q-w -+ x.k := w; y.k := q; q := r 0q-w 5 r-p -+ x.k := p; y.k := r; p := w fi ;k:= k+1
ll fi
od
B.
Jl
Exercises 0. Let N ~ 1 and Jet h(O .. N) be an array of integers. Derive a program for the computation of the unique element of h that occupies position k when h Is sorted (0 S k < N), without sorting the entire array h.. (Hint: use the DNF part of Quicksort).
Advanced sorting algoritl1ms
183
Mergesort.
11.2.1
Mergesort is based on the fact tbat two ascending sequences can be merged JDto one ascending sequence in linear time. To define the merge m of integer sequences x and y, we use the followJDg notation: for integer a and sequence :z:, tbe sequence consisting of a followed by sequence :z: is denoted as a:z:. The merge of two sequences IS defined by
= :z: my = y
if y is the empty sequence
:z: my :z:
a:z:m by
=
if :z: is the empty sequence
a(:z:mby} iCa:=;b { b(a:z:my) ifb::; a
Then m has the following properties: :z:
IS
ascending A y is ascending ~ :z: my is ascending
The bag of elements of :z: m y is the sum of the bags of elements of :z: and y These properties enable us to use merge in a sorting algorithm. Let us first present an algorithm for the computation of the merge of two sequences. Program merge IS specified by
I[ con M, N: int {M 2: 0 A N 2: 0}; :z:: array [O.. M) ofint; var z : array (O.. M +N) of int;
y : array [O.. N) ofint;
merge
(z =:z:my}
n.
From the definition of 1n we infer that a tail invariant is appropriate (cf. Section 4.4). Denoting catenation of sequences :z: and y by :z: # y, we define Po by
P0
z(O..c) # (:z:(a..M) m y(b .. N))
;
Pt .
0 ::;
a::; M
A 0 ::;
b~ N
= :z: my
A 0~c~
.AHN
Then
P0
A
(a=M V b=N)
~
z(O..c)#:z:(a.. M)#y(b.. N)
= :z:my
Strengthening invariants
65
which are initialized by n, r := 0, 0 , since number-of quantification over an empty range is 0. Assuming Po 1\ PJ. 1\ n 1- N, we have
=
(# z,J ; 0 5 z < j < n+l ; f.z 501\ J.i ~ 0) {splitofFj=n} (#i,j: 0 5 z < J < n · f.i 501\ f.j?. O) + (#z: 0 5 i < n: /.z 501\ f.n
=
~
0)
{Po}
r + (#i: 0:::;;; i < n: f.i 501\ f.n ~ O) = { case analysis } r if f.n < 0 r + (# i : 0 5 i < n : f.i 5 OJ if J.n ?. 0 = {introduction of s with invariant Q, see below} if f.n < 0 r { r + s if f.n ?. 0
f l
where s satisfies Q: s = ( # i : 0 5 i < n : j.i 5 0) Substitution of n = 0 yields that Q is established by n, s := 0, 0. For the in variance of Q, we derive, assuming P1 1\ Q 1\ n 1- N,
=
:::::;
(#i: 0 5 i < n+l; /.i 5O) (split off i :::::: n, 0 5 n < n+1 5 N} (# i: 0 5 i < n 'f.i 50)+# .(J.n 50)
{Q}
s + # .(J.n 5 0) = {definition of # } s if f.n > 0 { s + 1 if f.n 50 These derivations yield a program that solves the problem:
Advanced sorting algocitl1ms
=
185
Po(k:=k•2l {substitution I (Vi: 0::; i: hfi•k•2 .. (i+l)•k•2l is ascending)
= { ::> = (
calcub1s I (Vi : 0 I : h(2i•k .• {2i + 2)•k )Is ascending) calculus } (Vi: 0::; 1 1\ 1mod2 = 0: hli•k .. (i+2)•k)ls nsceudiug)
=
lienee, Po(k := h2l is established by mecg1ng, for all t, 0 ::; 1/\ amod 2 0, sequences h[i•k •. (i+l}•k)aud h((i+ll•k •• (i+2)ok), and assigning the result to h(i•k •. (i+2J•k). For this purpose, we Introduce integer vanahle n for a repetition that has anvann11t Po 1\ Qo 1\ Qa. where
Qu ; (Vi: 0 ::; 1 < n Q1 . o::;n
1\
1mod 2 = 0: /ali•k .. (i+2l•k)ls ascending)
wbicl1 are established by n := 0. Furthermore,
For the sake of convemeuce, we mtroduce vanables a, b, and c, sucl1 that a= r1ok 1\ b = (n+l)•k 1\ c = ((n+2l•kl minN 1111d we arrive at tlae folloiVIDg solution to 'establish P0 (k := k•2)': [wr·n,a,b,c: mt; n,a,b,c:= O,O,k, {2•k)mlnN ;dob < N _, hfa ••c) := h(a •. b) m h(b.. c) ;n,a,b,c:= n + 2, a+ 2•k,b+ 2•k,(c+ 2•k) minN od
J. Eacl1 step or this repetition takes 2k steps; since b is incremented by 2k, the total number of steps IS at most N. Since k as doubled at eaclt step or the outer repet.itlon, the time complexity of Mergesort is O(N log N). From the program Fragment above, vanable n may be reanoved.
Sorting
186
The computation of lt(a •. b) m h(b•• c) is not performed m situ: we introduce auxiliary array z(a..c) and h[a .•c) := lt[a.. b) m h(b ..c) IS implemented by 1, z(a .. c) := h(a .•b) m lt(b •. c) ; h(a .. c) := z1:a..c) The complete program is presented below. Mergesort
I[ var k : int; k:= 1
;dok< N-+ I[ var a, b, c : int; a,b,c:= 0, k, (2*k) minN
;dobC-closed, this
IS
Q1: A.a.(b-1) to the invariants. Initially Q1 holds, the increase of b by 1 bns guard .A.a.b and, since A 1!1 postfa-closed, it IS not violated by a:= a+ 1. For the case a+1 = b, we have
A.(a+l).b
= {a+1 = b, definition of A! tn1c =
{ (Vi : o ::5 i < N , X.i ~ 0) ) X.(b-1) ~ 0
=
{a+l=b! X.(b-1) ~ b-a-1
and we conclude that, m either case, A.(a+1).b
=X.(b-1)
~
b-a-1.
T/1e lenst/1 or a longest common subsequence
201
The mlroduclion or Q1 may be surprismg. It1s, however, [rom the general program scheme o[,maxseg Immediately clear lhal for postfix-closed .A, Ql IS an mvarianl. In many applications or this program scheme, the mvariance or .A.a.(6-1) turns out to be cruaal. The statements needed [or the 1nvanance or Q0 are easily derived, and we obtam the [ollOWing program.
Kvar a, 6 : 1nl; c : bool; f : array IO..Nj ofinl; a,6, r, c:= 0,0, O,lme
;J(vark: inl; k:= O;do k
~
N+l-t f.k:= O;k:= k+1 od)
;do6~NV-.c
_, if c _, r := r rnax(6-a) ;c.:= f.(b-a) = 0 1\ X.6 2' 6+1-a ; if X.6 ~ N _, f.(X.6) := /.(X.6) + 1 0X.6 > N _, skip fi ;6:=6+1 0-.c _, c:= X.(6-1)2' 6-a-1 ; if X.a ~ N _, f.(X.o.l := f.(X.o.)-! 0X.o. > N _, skip ft ;a:=a+1
6 od ;r:= rrnax(N-a)
].
12.2 The length of a longest common subsequence Our next example is a program [or the com{lulalion or the length of a longest common subsequence or two sequences. A subseq_uence of sequence s IS oblamed by removmg zero or more elements or B. A common subseq.uence or sequences s and t is a subsequence of both s and t. Tbe length or a sequence IS its number or elements. We consider two Integer sequences, represented by mleger arrays XJO .. M) and Y[O•• N) [or which the length or a longest common subse'\uence bas to be c~m{lllted. Let lcs.m.n (0 ~ m ~ M 1\ 0 ~ n ~ N) denote the length or a longest common subsequence of X(O•.m) and YJO .. n). Then lcs.m.O=O lcs.O.n =0
202
AIL"tiliary Arrnys
For 0 S m < M 11 0 S n < N, we express lcs.(m+l).(n+l) D9 follows. When X.m = Y.n, ench common subsequence o£ XIO ..m) nod Y(O.. nJ can be e.'Cteuded by X.m, beuce,
X.m = Y.n => lcs.(m+l).(n+l) = 1 + lcs.m.n
'·
When X.m i- Y.n tben each common subsequence o£ X(O .. m+l) nod l'[O .. n+ll IS either a common subsequence o£ X(O .. m+l) nud Y[O ..n) or n common subsequeuc~ of X[O ..m) and YI.O .. n+l), beuce,
X.m-# l':n
=1-
lcs.(m+lJ.(n+l) = lcs.(m+l).n max lcs.m.(n+l)
We conclude that ics
IS
formally deliued by
lcs.m.O=O ics.O.n=O lcs.(m+l). ( n+l) = {
.l + lcs.m.n ifX.m=Y.n ( lcs. m+l).n max lcs.m.(n+l) if X.m;l; Y.n
A fonunl specification o£ tl1e problem 1s
I[ con M,N: 10t{M 0!: 0
I\ N :2: OJ; X ; array [O.. M) ofiut; Y: arrayfO .. N)ofint; var r: mt;
s {r = lcs.M.Nl
J. In tbe post.-coudition two constants (M and N) occur. We may replace botb of tbem by vanables and try as mvarJunt r=
lcs.m.n
Tbis Invariant. 1s establislled by, for JDstance, r, m, n := 0, 0, 0, r, m, n := 0, .A-1, 0, or r, m, n := 0, 0, N. This mdicates Lbnt this mvarlant is mtber weak. Moreover, DS guard of u repeLitiou, we would bave m ;!:. M V n ;I; N and, hence, JDspectiou of X.m or Y.n bas to be guarded. In view o£ these problems, we replace only one o£ tbe ~'Oustants by n vunable (Lhereby destroying the symmetry} and we consider mvanuut r
= lcs.m.N
The /engtl1 of a longest common subsequence
203
which is established by r, m := 0, 0. An mcrcase of m by! yields expressJoulcs.(m+1 ).N and, according to the delinilion of lcs, lcs.m.(N-1), lcs.m.N, and lcs.(m+l).(N-1) arc needed for its computation. Tbe last expression g~ves rise to ics.m.(N -2), etc. Therefore, we introduce integer array h(O ..NI and 'accompanymg invanant Po. (Vi: 0 S • S N: h.• = lcs.m.') where the bounds for rn are g1ven by
Tben P0 (m:=0): (Vi:O.S•SN:h.z=O) and Po II rn = M
'* h.N =k.s.M.N
FUrthenuore, we have
5
Po(m:=m+1) { dclinition of Po } (Vi: 0 S 1 S N: h.z = lcs.(m+l).i)
which IS established by another repetition, replaaug constant N by variable n with Invariants Q0 • (Vi: 0 S • S n: h.• = lcs.(m+l}.i) II (Vi: n < • S N: h.z = lcs.m.i) Q•. OSn S N for which we have Po ~ Q0 (n:= O) and Q0 II n = N ~ P0 (m:= m+1). For 0 S f1 < N, we derive
:: 5
Qo(n:= n+l) { delinition of Q0 ~ (Vi: 0 S 1 S n+l: h..1 = lcs.(m+l).i) II (Vi: u+l < • S N: h..•= lcs.nd) {split off i = n+l I (Vi: 0 S • S n: h.1 = lcs.(m+l).i) II (Vi: n+l < • S N: h..z = lcs.m.i) II h.(n+l) = lcs.(m+l).(n+l)
204
Auxiliary Arrays
The first two conJUncts of the lost predicate are implied by Q0 , hence, h.(n+l) = lts.(m+l).{n+ll bas to be established, for which we have
,.
lts.(m+l).(n+11 {definition of Its I ifX.m=Y.n 1 +lcs.m.n { lcs.(m+l).n max.lcs.m.(n+11 if X.m >/< Y.n {Qa I ifX.m=Y.n J 1 +lts.m.n l h.n max h.(n+l) if X.m of< Y.n Evidently, we need lcs.m.n aa well, and we add to the invanants
Q2 ; a = lcs.m.n The &ovaniLIIce of Q2
IS
no problem: Q0 Implies h.(n+1) = lcs.rn.(n+1). Thus, we have
{Qo 1\ Q1/\ Q2/\ n~Nl iF X.m = Y.n--+ a, h.(n+l) := l&{n+1),1+a 0 X.m ,& Y.n -o a,h.(n+l):= /&{n+l),l&.nmax.h.(n+l) fl {(Qo 1\ Ql 1\ Q2)(n:=n+l) Since multiple 115Signmeots are not allowed when arrays are Involved, local variable b mtroduced. The resulting program is presented below.
15
Tbc lcngtl1 of a longest common subsequence
Kvar m : iut; h : array [O ••Nl ofiut; m:=O
;l(k: mt;k:= O;dok 'f. N+l-o h.k:= O;k:= k+lodJ {Po 1\ Pa} ;dom>FM -+ I[ var n, a : mt; n,a:=O,O {Qo 1\ Q, 1\ Q2J ;don>#N -+l(vaE"b:mt; b:=h.(n+ll ;if X.m = Y.n -+/i.(n+l) := 1 +a 0 X.m 'f. Y.n...., l1.(n+1) := h.nmaxl1.(n+ll fl ;a:=il
I ;n:=n+l
od ;m:=m+l od
;r:=h.N
J.
205
206
Auxiliary Arrays
12.3
A shortest segment problem
In our final example, we dea1ousLrat.e how llD efficleuL soiuLioa Lo a programmmg problem can be obLamed in a number or sLeps. These sLeps arc noL specific for Lbjs parUcnlnr problem buL Lhey occur Ia denvaLions or many oLher programmmg problems as well. To illusLraLe Lhese sLeps, we use Lhe rollowmg segmenL problem. For mLeger array X(O.. N), N 2: 1, we wisb Lo derive a program for the com{>ULaLion or Lbe leogLh or a sbort.esL segmenL in which Lhe maximum value on Lhat segmeuL occurs exacUy L\VIce. A ronnal s{>ecificaLiou is
I( conN: mL {N 2: ll; X: arrayj.O•• N)ofiuL; var r: mL;
s {r = (minp,q: 0 S p S q S N
I\
A.p.q: q-pl}
B where
A.p.q:: (#i:p!f1