Anda di halaman 1dari 50

1

The B-method: an Introduction


Sample solutions to exercises

This document contains sample solutions to the exercises in the book The
B-Method: an Introduction by Steve Schneider.
Steve Schneider
S.Schneider@rhul.ac.uk
June 2001

The B-Method: an Introduction


Sample solutions to exercises from Chapter 1
Exercise 1.1
reset =
b
PRE true
THEN serve , next := 0 , 0
END

Exercise 1.2
MACHINE Ticket
VARIABLES serve , next
INVARIANT serve N next N serve next next 501
INITIALISATION serve , next := 0 , 0
OPERATIONS
ss - serve next =
b
PRE serve < next
THEN ss , serve := serve + 1 , serve + 1
END

tt - take ticket =
b
PRE next 500
THEN tt , next := next , next + 1
END

END
Exercise 1.3
nn - query =
b
PRE true
THEN nn := next serve
END

Exercise 1.4
MACHINE Ticket14
VARIABLES serve , next , record
INVARIANT serve N next N record N serve next
INITIALISATION serve , next , record := 0 , 0 , 0
OPERATIONS
ss - serve next =
b
PRE serve < next
THEN ss , serve , record := serve + 1 , serve + 1 , 0
END

tt - take ticket =
b
PRE true
THEN tt , next , record := next , next + 1 , record + 1
END

rr - query record =
b
PRE true
THEN rr := record
END

END

Exercise 1.5
MACHINE Ticket
VARIABLES serve , next , lim
INVARIANT serve N next N lim N serve next next lim
INITIALISATION serve , next , lim := 0 , 0 , 500
OPERATIONS
ss - serve next =
b
PRE serve < next
THEN ss , serve := serve + 1 , serve + 1
END

tt - take ticket =
b
PRE next < lim
THEN tt , next := next , next + 1
END

limit ( nn ) =
b
PRE nn N next nn
THEN lim := nn
END

END
Exercise 1.6
No, this operation is not consistent with the invariant of the Ticket machine,
since it may be called in the state in which serve and next are both 0. It can be
made consistent by strengthening the precondition to serve > 0.

Exercise 1.7
MACHINE CarPark
VARIABLES contents
INVARIANT contents N contents 640
INITIALISATION contents := 0
OPERATIONS

enter =
b
PRE contents < 640
THEN contents := contents + 1
END

leave =
b
PRE contents > 0
THEN contents := contents 1
END

nn - query =
b
PRE true
THEN nn := contents
END

END

The B-Method: an Introduction


Sample solutions to exercises from Chapter 2
Exercise 2.1
1. { {}, {fred}, {ginger }, {fred, ginger }, {harold},
{fred, harold}, {ginger , harold}, {fred, ginger , harold}}
2. { (fred, fred), (fred, ginger ), (fred, harold),
(ginger , fred), (ginger , ginger ), (ginger , harold),
(harold, fred), (harold, ginger ), (harold, harold)}
3. 512(= 29 )
4. 256(= 2( 23 ))
Yes to both questions: {{fred}, {ginger }} PPMEMBER, and {{fred, ginger }}

PPMEMBER.

Exercise 2.2
{} {home, work} = {}. S T = T S if S = {} or T = {} or S = T .
Exercise 2.3
This is the set of cubes of size less than 100, which is { 0, 1, 8, 27, 64 }
Exercise 2.4
1. always true
2. not always true
3. always true
4. always true
5. not always true
6. always true
7. always true

The B-Method: an Introduction


Sample solutions to exercises from Chapter 3

Exercise 3.1

0, {}
0, {olly}
0, {pat }
0, {olly, pat }
1, {}
1, {olly}
1, {pat }
1, {olly, pat }
2, {olly, pat }
2, {olly}
2, {pat }
2, {}

0, {}

0, {}

0, {olly}

0, {olly}

0, {pat }

0, {pat }

0, {olly, pat }
1, {}

0, {olly, pat }
1, {}

1, {olly}

1, {olly}

1, {pat }

1, {pat }

1, {olly, pat }

1, {olly, pat }

2, {olly, pat }

2, {olly, pat }

2, {olly}

2, {olly}

2, {pat }

2, {pat }

2, {}

2, {}

Exercise 3.2

0, 0

0, 0

0, 1

0, 1

0, 2

0, 2

1, 0

1, 0

1, 1

1, 1

1, 2

1, 2

2, 0

2, 0

2, 1

2, 1

2, 2

2, 2

The states which reach a state in which x+y = 2 are (0, 2), (2, 2), (1, 2), (2, 1), (2, 0).
By calculation, we obtain:
[ IF x < y THEN y := y x ELSE x := x y END ](x + y = 2)
=

(x < y [y := y x](x + y = 2))

> 2 [x := x y](x + y = 2))


(x < y x + y x = 2)
(x > y x y + y = 2)
(x < y y = 2) (x > y x = 2)

(x
=
=
=

max(x, y) = 2

which yields the same states as obtained directly from the relation.

Exercise 3.3

IF E1 THEN S1

ELSIF E 2 THEN S2

ELSIF ...
P
ELSIF En THEN Sn

ELSE Sn+1

END

E1 [S1 ]P
(E1 E2 ) [S2 ]P
=

...
(E1 ... En1 En ) [Sn ]P
(E1 E2 ... En ) [Sn+1 ]P

Exercise 3.4

6 next
2. serve + new 6 next + 1

1. serve + new

3. z.(z N 7 < z 2 ) (= false)


4. house set {x, y} (x 1)..(y + 1) = house set x 1..y + 1
5. num = card(house set )
6. house set old set {new}
Exercise 3.5
If i is even then it sets ans to even, otherwise it sets it to odd. The weakest
precondition for it to establish that ans = even is that i mod 2 = 0.
Exercise 3.6
That (i + 2)/3 is not 2 or 3; i.e. that i < 4 or that i > 9.

The B-Method: an Introduction


Sample solutions to exercises from Chapter 4
Exercise 4.1
allmags =
b
PRE true
THEN magazines := papers
END

This operation is consistent with the invariant of Paperround.


Exercise 4.2
removehouse(hh) =
b
PRE hh papers
THEN papers := papers {hh} || magazines := magazines {hh}
END

The proof obligations for this operation are given by instantiating I P


[S ]I : in this case, that

6 60) hh papers
[papers := papers {hh} || magazines := magazines {hh}]
(papers 1..163 magazines papers card(papers) 6 60)

(papers 1..163 magazines papers card(papers)

or, using the weakest precondition rule for assignment, that


(papers 1..163 magazines papers card(papers)

6 60) hh papers

(papers {hh} 1..163 magazines {hh} papers {hh}


card(papers {hh})

6 60)

which is true by elementary logic and set theory.


Exercise 4.3
The operations addmagazine and remove are not consistent with the new
invariant. Their preconditions require strengthening, for example as follows:
addmagazine ( hh ) =
b
PRE hh papers card ( magazines ) < card ( papers ) / 2
THEN magazines := magazines { hh }
END

remove ( hh ) =
b
PRE hh 1 . . 163
card ( magazines { hh } ) card ( papers { hh } ) / 2

10
THEN

papers := papers { hh } k magazines := magazines { hh }

END

Exercise 4.4
The operation board is consistent with the invariant of Bus. The other two
operations, buy and double are not consistent.
The machine can be amended by strengthening the invariant so that tickets
passengers is a clause; and by altering the precondition of buy to ensure the
(new) invariant is met, resulting in the following machine:

MACHINE Bus
VARIABLES tickets , passengers
INVARIANT tickets N passengers N tickets passengers
INITIALISATION tickets , passengers := 0 , 0
OPERATIONS
buy ( mm ) =
b
PRE mm N tickets + mm passengers
THEN tickets := tickets + mm
END

board ( nn ) =
b
PRE nn N
THEN passengers := passengers + nn
END

double =
b
PRE true
THEN tickets , passengers := 2 tickets , 2 passengers
END

END

With the additional clause passengers


tickets + 45 in the invariant, the
operations board and double which increase the number of passengers require stronger preconditions to prevent violation of this new clause. The new
precondition for board is
nn N passengers + nn

6 tickets + 45

The new precondition for double is


passengers

6 tickets + 22

11

The B-Method: an Introduction


Sample solutions to exercises from Chapter 5
Exercise 5.1
The proof obligations are:
1. ITEM , sample, num.ITEM {} sample ITEM num N num >
card(ITEM ). This proof obligation is true. Observe that the set ITEM must
be non-empty, and is an implicit clause of the constraint.
2. (ITEM {} sample ITEM num N num > card(ITEM ))
storage.storage N1 storage
num. This proof obligation is also
true.

3. (ITEM {} sample ITEM num N num > card(ITEM )


storage N1 storage
num) existscurrent , nextprevious.current
ITEM next ITEM previous ITEM next previous. This proof
obligation is not true in the case where ITEM is a singleton set. Thus it is
not universally true, and hence the machine clauses are not all consistent.

Exercise 5.2

>

The initialisation is consistent with the invariant, constraints and properties,


since num 2 follows from them.
input is not consistent, since nn = next is a permitted input, resulting in
a state which violates the invariant.
output is not consistent, since it also reaches a state in which next
current , violating the invariant.
increment is consistent.

12

The B-Method: an Introduction


Sample solutions to exercises from Chapter 6
Exercise 6.1
1.

ian

eggs

jim

cheese

ken

salad

lisa

pizza
eats

C eats = {ian eggs, ian cheese, ian pizza}


3. {jim}
C eats = { ian eggs, ian cheese, ian pizza
2. {ian}

ken pizza, lisa cheese, lisa salad, lisa pizza}

B {cheese, pizza} = { ian cheese, ian pizza,


}
ken pizza, lisa cheese, lisa pizza
5. dom(eats C {eggs}) = {ian, jim}
6. dom(eats C {eggs, pizza})
7. dom(eats C {cheese}) dom(eats C {pizza})

4. eats

Exercise 6.2
1. eats[{ian, lisa}] = {eggs, cheese, pizza, salad}
2. eats 1 = { eggs ian, cheese ian, pizza ian,
eggs jim, salad jim, pizza ken,
cheese lisa, salad lisa, pizza lisa}
3. eats 1[{cheese, eggs}] = {ian, jim, lisa}
4. eats ; cost = { ian cheap, ian expensive, jim cheap,

kenmapstoexpensive, lisa cheap, lisa expensive}

5. eats ; (cost {expensive}) = {ian cheap, jim cheap, lisa cheap}


6.

eats 1[cost 1 [{expensive}]] =

{ian, ken, lisa}

7. eats <+ {lisa steak} = { ian eggs, ian cheese, ian pizza,
jim eggs, jim salad, ken pizza, lisa steak}

13

Exercise 6.3
The invariant becomes
access USER PRINTER uu . (uu USER card(access[{uu}])

6 6)

Two operations are no longer consistent with this strengthened invariant: add,
and unify.
In order to regain consistency of the machine, the precondition of add can
be strengthened to
uu USER pp PRINTER card(access[{uu}]) < 6
and the precondition of unify can be strengthened to
u1 USER u2 USER card(access[{u1}]) + card(access[{u2}])

66

.
Exercise 6.4
exchange ( u1 , u2 ) =
b
PRE u1 USER u2 USER
THEN access := access <+ ( { u1 } access [ { u2 } ] { u2 } access [ { u1 } ] )
END

Exercise 6.5
maintenance ( pp , alt ) =
b
PRE pp PRINTER alt PRINTER
THEN access := access { pp } access
END

[ { pp } ] { alt }

Exercise 6.6
The variable barred and associated conditions and operations are incorporated
into the machine below. The operations which require strengthened preconditions are again add and unify. all other operations are consistent with the next
invariant and remain unchanged from their description in the original Access
machine.
MACHINE Access
SETS USER ; PRINTER ; OPTION ; PERMISSION = { ok , noaccess }
CONSTANTS options
PROPERTIES options PRINTER OPTION

14

dom ( options ) = PRINTER ran ( options ) = OPTION


VARIABLES access , barred
INVARIANT access USER PRINTER barred USER OPTION
( access ; options ) barred = {}
INITIALISATION access , barred := {} , {}
OPERATIONS
addbar ( uu , oo ) =
b
PRE uu USER oo OPTION
THEN barred := barred { uu oo } k access := access { uu } options
END

[ { oo } ]

removebar ( uu , oo ) =
b
PRE uu USER oo OPTION uu oo barred
THEN barred := barred { uu oo }
END

add ( uu , pp ) =
b
PRE uu USER pp PRINTER options [ { pp } ] barred [ { uu } ] = {}
THEN access := access { uu pp }
END

unify ( u1 , u2 ) =
b
PRE u1 USER u2 USER access ; options [ { u1 , u2 } ] barred [ { u1 , u2 } ] = {}
THEN access := access { u1 } access [ { u2 } ] { u2 } access [ { u1 } ]
END

END

15

The B-Method: an Introduction


Sample solutions to exercises from Chapter 7
Exercise 7.1
MACHINE Reading
SETS READER ; BOOK ; COPY ; RESPONSE = { yes , no }
VARIABLES books , copies , copyof , hasread , reading
INVARIANT copyof copies
books
books BOOK copies COPY
hasread READER books
reading READER 7 copies
( reading ; copyof ) hasread = {}
INITIALISATION copyof := {} k books := {} k copies := {}
k hasread := {} k reading := {}
OPERATIONS
addcopy ( cc , bb ) =
b
PRE cc COPY bb BOOK cc 6 copies
THEN copies := copies { cc } k books := books { bb }
k copyof := copyof { cc bb }

END

start ( rr , cc ) =
b
PRE rr READER cc copies copyof ( cc ) 6 hasread [ { rr } ]
rr 6 dom ( reading ) cc 6 ran ( reading )
THEN reading := reading { rr cc }
END

finished ( rr , cc ) =
b
PRE rr READER cc copies cc = reading ( rr )
THEN hasread := hasread { rr copyof ( cc ) }
k reading := { rr } reading
END

resp - precurrentquery ( rr ) =
b
PRE rr READER
THEN
IF rr dom ( reading )
THEN resp := yes
ELSE resp := no
END
END

bb - currentquery ( rr ) =
b
PRE rr READER rr dom ( reading )
THEN bb := copyof ( reading ( rr ) )
END

resp - hasreadquery ( rr , bb ) =
b
PRE rr READER bb BOOK

16
THEN
IF bb hasread [ { rr } ]
THEN resp := yes
ELSE resp := no
END
END

END
Exercise 7.2
pp - position ( rr ) =
b
PRE rr ran ( finish )
THEN pp := finish 1 ( rr )
END

remove ( rr ) =
b
PRE rr ran ( finish )
THEN

pp
BE pp = finish
LET
IN

( rr )

finish := finish pp 1

END
END

a ( finish pp )

17

The B-Method: an Introduction


Sample solutions to exercises from Chapter 8
Exercise 8.1
[a(i) := 5](a(j ) = a(k)
=

(a <+ {i 5})(j ) = (a <+ {i 5})(k)

i =j i =k
i = j i k a(k) = 5
i j i = k a(j ) = 5
i j i k a(j ) = a(k)

Exercise 8.2
a := x . (x dom(a) | 2 x)
Exercise 8.3
betterswap ( rr , ss ) =
b
PRE

rr ROOM ss ROOM
( rr small numbers ( ss ) 4 )
( ss small numbers ( rr ) 4 )
THEN numbers := numbers <+ { rr numbers ( ss ) , ss numbers ( rr ) }
END

Exercise 8.4
step =
b
guests := xx . ( xx

N xx + 1 ROOM

| guests ( xx + 1 ) )

Exercise 8.5
MACHINE Hotelguests ( sze )
CONSTRAINTS sze N1
SETS NAME ; REPORT = { present , notpresent }
CONSTANTS empty , ROOM
PROPERTIES card ( ROOM ) = sze empty NAME ROOM
VARIABLES pguests
INVARIANT pguests ROOM
7 NAME
INITIALISATION pguests := {}
OPERATIONS
guestcheckin ( rr , nn ) =
b

18

rr ROOM nn NAME
THEN pguests ( rr ) := nn

PRE

END

guestcheckout ( rr ) =
b
PRE rr ROOM
THEN pguests := { rr } pguests

END

nn - guestquery ( rr ) =
b
PRE rr ROOM
THEN IF rr dom ( pguests )
THEN nn := pguests ( rr )
ELSE nn := empty
END

END

rr - presentquery ( nn ) =
b
PRE nn NAME
THEN IF nn ran ( pguests )
THEN rr := present
ELSE rr := notpresent
END

END

guestswap ( rr , ss ) =
b
PRE rr ROOM ss ROOM
THEN
IF rr dom ( pguests )

ss dom ( pguests )
THEN pguests := pguests <+ { rr pguests ( ss ) , ss pguests ( rr ) }
ELSE pguests := { rr } pguests { ss pguests ( rr ) }

THEN IF

END

ELSE IF ss dom ( pguests )


THEN

pguests := { ss } pguests { rr pguests ( ss ) }

END
END
END

step =
b
pguests := xx . ( xx
END

N xx + 1 dom ( pguests )

| pguests ( xx + 1 ) )

19

The B-Method: an Introduction


Sample solutions to exercises from Chapter 9
Exercise 9.1
ANY nn

WHERE nn : N
THEN square := nn nn
END
Exercise 9.2
This operation adds some arbitrary value between 1 and 5 to total.
[ ANY a WHERE a N1 a
=

6 5 [total := total + a](total > 8))


a 6 5 total + a > 8)

a . (a N1 a

a . (a N1

total

>8

6 5 THEN total := total + 5 END ](total > 8)

Exercise 9.3
This statement picks an arbitrary set of up to three numbers between 1 and N .
[ ANY s WHERE s 1..N card(s)
=
=
=

6 3 THEN myset := s END ](i.(i myset | i) < 40)

6 3 [myset := s](i.(i myset | i) < 40)


s . s 1..N card(s) 6 3 (i.(i s | i) < 40)
N 6 14
s . s 1..N card(s)

The statement is guaranteed to achieve the postcondition provided the numbers comprising the set are all no greater than 14.
Exercise 9.4
ANY nn WHERE nn 1..49 card(nn) = 6 THEN ticket := nn END
Exercise 9.5
ANY d WHERE d : order [{p}] THEN delivery := d END

[ ANY d WHERE d : order [{p}] THEN delivery := d END ](delivery fridge)


=

d.(d : order [{p}] [delivery := d](delivery fridge))

d.(d : order [{p}] d fridge))

fridge 6 order [{p}]

20

Exercise 9.6
CHOICE salary := salary 1.03 OR salary := salary + 400 END

[ CHOICE salary := salary 1.03 OR salary := salary + 400 END ](salary > 14000)
=

[salary := salary 1.03](salary > 14000) [salary := salary + 400](salary > 14000]

(salary 1.03 > 14000) (salary > 13600)

salary > 13592 salary > 13600

salary > 13600

Exercise 9.7
1.

SELECT albert here THEN hh := albert

WHEN betty here THEN hh := betty

WHEN clarissa here THEN hh := clarissa

ELSE hh := fido END


=

(hh = clarissa)

albert here [hh := albert ](hh = clarissa)


(betty here [hh := betty](hh = clarissa))
(clarissa here [hh := clarissa](hh = clarissa)
(albert 6 here betty 6 here clarissa 6 here [hh := fido](hh = clarissa)

albert here false


(betty here false
(clarissa here true
(albert 6 here betty 6 here clarissa 6 here false

albert 6 here betty 6 here clarissa here

2.

SELECT albert here THEN hh := albert

WHEN betty here THEN hh := betty

WHEN clarissa here THEN hh := clarissa

ELSE hh := fido END


=

(hh albsert )

albert here [hh := albert ](hh albert )


(betty here [hh := betty](hh albert ))
(clarissa here [hh := clarissa](hh albert )
(albert 6 here betty 6 here clarissa 6 here [hh := fido](hh albert )

albert here false


(betty here true

21

(clarissa here true


(albert 6 here betty 6 here clarissa 6 here true
=

albert 6 here

3.

SELECT albert here THEN hh := albert

WHEN betty here THEN hh := betty

WHEN clarissa here THEN hh := clarissa

ELSE hh := fido END


=

(hh fido)

albert here [hh := albert ](hh fido)


(betty here [hh := betty](hh fido))
(clarissa here [hh := clarissa](hh fido)
(albert 6 here betty 6 here clarissa 6 here [hh := fido](hh fido)

albert here true


(betty here true
(clarissa here true
(albert 6 here betty 6 here clarissa 6 here false

albert here betty here clarissa here

Exercise 9.8
MACHINE Deliveries
SETS ITEM ; ADDRESS
VARIABLES van , nogo
INVARIANT van ADDRESS ITEM nogo ADDRESS
INITIALISATION van := {} k nogo : P ( ADDRESS )
OPERATIONS
load ( aa , ii ) =
b
PRE aa ADDRESS ii ITEM
THEN van := van { aa ii }
END

aa , ii - drop =
b
PRE van {}
THEN

ad , it
ad ADDRESS it ITEM ad it van
THEN aa := ad k ii := it
ANY

WHERE
END
END

warning ( aa ) =
b
PRE aa ADDRESS
THEN IF aa nogo

22

van := { aa } van
OR nogo := nogo { aa }

THEN CHOICE
END

ELSIF aa 6 dom ( van )


THEN nogo := nogo { aa }
END
END

END

23

The B-Method: an Introduction


Sample solutions to exercises from Chapter 10
Exercise 10.1
The included machine Locks provides no single operation for closing a door
and locking it, and Safes can only call one operation from Locks in any of its
own operations.
The new operation for Locks is
quickclose ( dd ) =
b
PRE dd DOOR position ( dd ) = open
THEN closedoor ( dd ) k status ( dd ) := locked
END

;
The new operation for Safes is

quickcloseandlock ( dd ) =
b
PRE dd DOOR position ( dd ) = open
THEN quickclose ( dd ) k removekey ( unlocks
END

( dd ) )

Exercise 10.2
MACHINE Safes
INCLUDES Locks , Keys
PROMOTES opendoor , closedoor , lockdoor
CONSTANTS unlocks
PROPERTIES unlocks KEY DOOR
VARIABLES masterkey
INVARIANT status 1 [ { unlocked } ] unlocks [ keys ]
masterkey DOOR card ( masterkey ) 1
status 1 [ { unlocked } ] masterkey
INITIALISATION masterkey := {}
OPERATIONS
insertmaster ( dd ) =
b
PRE dd DOOR masterkey = {}
THEN masterkey := { dd }

END

removemaster =
b
PRE status [ masterkey ] = { locked }
THEN masterkey := {}
END

insert ( kk , dd ) =
b
PRE kk KEY dd DOOR unlocks ( kk ) = dd

24

insertkey ( kk )

THEN
END

extract ( kk , dd ) =
b
PRE kk KEY dd DOOR unlocks ( kk ) = dd status ( dd ) = locked
THEN removekey ( kk )
END

unlock ( dd ) =
b
PRE dd DOOR unlocks
THEN unlockdoor ( dd )
END

( dd ) keys dd masterkey

quicklock ( dd ) =
b
PRE dd DOOR position ( dd ) = closed
THEN lockdoor ( dd ) k removekey ( unlocks

( dd ) )

END

END

Exercise 10.3
MACHINE Safes
INCLUDES Locks , Keys
PROMOTES opendoor , closedoor , lockdoor
VARIABLES unlocks
INVARIANT status 1 [ { unlocked } ] unlocks [ keys ]
unlocks KEY 7 DOOR keys dom ( unlocks )
INITIALISATION unlocks := {}
OPERATIONS
allocate ( kk , dd ) =
b
PRE kk KEY kk 6 dom ( unlocks ) dd DOOR dd 6 ran ( unlocks )
THEN unlocks ( kk ) := dd

END

deallocate ( kk , dd ) =
b
PRE kk KEY dd DOOR kk dd unlocks kk 6 keys status ( dd ) = locked
THEN unlocks := { kk } unlocks
END

insert ( kk , dd ) =
b
PRE kk KEY dd DOOR unlocks ( kk ) = dd
THEN insertkey ( kk )
END

extract ( kk , dd ) =
b
PRE kk KEY dd DOOR unlocks ( kk ) = dd status ( dd ) = locked
THEN removekey ( kk )
END

unlock ( dd ) =
b
PRE dd DOOR unlocks

( dd ) keys

25

unlockdoor ( dd )

THEN
END

quicklock ( dd ) =
b
PRE dd DOOR position ( dd ) = closed dd ran ( unlocks )
THEN lockdoor ( dd ) k removekey ( unlocks 1 ( dd ) )
END

END

Exercise 10.4
MACHINE RobustLocks
INCLUDES Locks
SETS REPORT = { ok , error }
OPERATIONS
rep - robustopen ( dd ) =
b
PRE dd DOOR
THEN IF status ( dd ) = unlocked
THEN opendoor ( dd ) k rep := ok
ELSE rep := error
END
END

rep - robustclose ( dd ) =
b
PRE dd DOOR
THEN closedoor ( dd ) k rep := ok
END

rep - robustunlock ( dd ) =
b
PRE dd DOOR
THEN unlockdoor ( dd ) k rep := ok
END

rep - robustlock ( dd ) =
b
PRE dd DOOR
THEN IF position ( dd ) = closed
THEN lockdoor ( dd ) k rep := ok
ELSE rep := error
END
END

END

Exercise 10.5
MACHINE Hotelregister ( sze )
INCLUDES Hotel ( sze ) , Hotelguests ( sze )
PROMOTES guestquery , presentquery , roomquery , vacancies , totalguests
INVARIANT guests 1 [ { empty } ] = numbers 1 [ { 0 } ]

26

OPERATIONS
fullcheckin ( room , name , number ) =
b
PRE name NAME number 1 . . 6
room ROOM guests ( room ) = empty name empty
( room small number 4 )
THEN checkin ( room , number ) k guestcheckin ( room , name )
END

fullcheckout ( room ) =
b
PRE room ROOM
THEN checkout ( room ) k guestcheckout ( room )
END

fullswap ( room1 , room2 ) =


b
PRE room1 ROOM room2 ROOM room1 small ( room2 small )
THEN swap ( room1 , room2 ) k guestswap ( room1 , room2 )
END

END

27

The B-Method: an Introduction


Sample solutions to exercises from Chapter 11
Exercise 11.1
MACHINE Limit
SEES Goods
VARIABLES limit
INVARIANT limit GOODS N1
INITIALISATION limit : GOODS
OPERATIONS
setlimit ( gg , pp ) =
b
PRE gg GOODS pp N1
THEN limit ( gg ) := pp
END

N1

pp - limitquery ( gg ) =
b
PRE gg GOODS THEN pp := limit ( gg ) END
END
MACHINE Customer
SEES Price , Goods , Limit
VARIABLES purchases
INVARIANT purchases GOODS
INITIALISATION purchases := {}
OPERATIONS
pp - buy ( gg ) =
b
PRE gg GOODS price ( gg ) limit ( gg )
THEN purchases := purchases { gg } k pp - pricequery ( gg )
END

END

Exercise 11.2
change ( nn ) =
b
PRE nn PERSON nn male female
THEN IF nn male
THEN female := female { nn } k male := male { nn }
ELSE male := male { nn } k female := female { nn }
END
END

The sexchange operation must take into account the possibility that
the person nn is married. Here we simply include as a precondition that
nn should not be married. Thus the function marriage will not change. An

28

alternative would be to accept married nn as well as unmarried, and update


the function marriage by removing nn from it.
sexchange ( nn ) =
b
PRE nn male female nn 6 dom ( marriage ) nn 6 ran ( marriage )
THEN change ( nn )
END

Exercise 11.3
MACHINE Voters
USES Life
SETS RESPONSES = { listed , notlisted }
VARIABLES voters
INVARIANT voters male female
INITIALISATION voters := {}
OPERATIONS
addvoter ( nn ) =
b
PRE nn male female
THEN voters := voters { nn }
END

removevoter ( nn ) =
b
PRE nn male female
THEN voters := voters { nn }
END

resp - voterquery ( nn ) =
b
PRE nn PERSON
THEN IF nn voters
THEN resp := listed
ELSE resp := notlisted
END
END

END
In fact, Voters can be included in Registrar, and all its operations can be
promoted, so the extends clause is used. The dies operation requires amendment: when a person dies then they should also be removed from the electoral
roll.
MACHINE Registrar
EXTENDS Marriage , Voters
INCLUDES Life
PROMOTES born
OPERATIONS
dies ( nn ) =
b

29

nn male female

PRE
THEN

die ( nn ) k removevoter ( nn ) k
IF nn dom ( marriage )
THEN part ( nn , marriage ( nn ) )
ELSIF nn ran ( marriage )
THEN part ( marriage 1 ( nn ) , nn )
END
END

END

Exercise 11.4
MACHINE Fullregistrar
INCLUDES Registrar
PROMOTES partner
SETS STATUS = { bachelor , spinster , married , divorced , widow , widower }
VARIABLES status
INVARIANT status male female STATUS
status 1 [ { married } ] = dom ( marriage ) ran ( marriage )
INITIALISATION status := {}
OPERATIONS
birth ( nn , ss ) =
b
PRE nn PERSON nn 6 ( male female ) ss SEX
THEN born ( nn , ss )
k IF ss = boy
THEN status ( nn ) := bachelor
ELSE status ( nn ) := spinster
END
END

death ( nn ) =
b
PRE nn PERSON nn male female
THEN dies ( nn )
k IF status ( nn ) married
THEN status := { nn } status
ELSE IF nn male
THEN status := { nn } status <+ { marriage ( nn ) widow }
ELSE status := { nn } status <+ { marriage 1 ( nn ) widower }

END

C
C

END
END

marry ( mm , ff ) =
b
PRE mm male mm 6 dom ( marriage ) ff female ff 6 ran ( marriage )
THEN wed ( mm , ff )

30

k status := status <+ { mm married , ff married }


END

divorce ( mm , ff ) =
b
PRE mm male ff female mm ff marriage
THEN part ( mm , ff )
k status := status <+ { mm divorced , ff divorced }
END

ss - maritalstatus ( nn ) =
b
PRE nn male female
THEN ss := status ( nn )
END

END

31

The B-Method: an Introduction


Sample solutions to exercises from Chapter 12
Exercise 12.1
1. aa 1..300
7 N ran(aa) = orders

 N ran(aa) = orders

2. aa 1..300 7

3. ll seq(N) ran(ll) = orders

4. ll iseq(N) ran(ll) = orders


5.

ll seq(N) ran(ll) = orders


ii, jj . (ii : dom(ll) jj dom(ll) (ii < jj ll(ii) < ll(jj )

Exercise 12.2
The first refinement uses an 11-place array.

REFINEMENT PlayerR
REFINES Player
VARIABLES teamr
INVARIANT teamr 1 . . 11
PLAYER ran ( teamr ) = team
PLAYER
INITIALISATION teamr : 1 . . 11
OPERATIONS
substitute ( pp , rr ) =
b

BEGIN

teamr ( teamr
END

( pp ) ) := rr

aa - query ( pp ) =
b
IF pp ran ( teamr )
THEN aa := in
ELSE aa := out
END

END
The second refinement uses an array indexed by the players, recording for
each whether he is in or out of the team.

REFINEMENT PlayerR2
REFINES Player
VARIABLES teamr
INVARIANT teamr PLAYER ANSWER team = teamr 1 [ { in } ]
INITIALISATION ANY tr WHERE tr PLAYER ANSWER card ( tr
THEN teamr := tr

[ { in } ] ) = 11

32
END

OPERATIONS
substitute ( pp , rr ) =
b
BEGIN

teamr ( pp ) := out ;
teamr ( rr ) := in
END

aa - query ( pp ) =
b aa := teamr ( pp )
END
Exercise 12.3
In the abstract machine:
jumpqueue ( ss , qq ) =
b
PRE ss SHIP ss 6 ran ( waiting ) ss 6 ran ( docked )
qq QUAY qq 6 dom ( docked )
THEN docked ( qq ) := ss
END

In the refinement:
jumpqueue ( ss , qq ) =
b insert ( ss , qq ) ;

33

The B-Method: an Introduction


Sample solutions to exercises from Chapter 13
Exercise 13.1
First style of refinement:

REFINEMENT JobshopR
REFINES Jobshop
VARIABLES jobarr
INVARIANT jobarr 1 . . limit
7 JOB ran ( jobarr ) = jobs
INITIALISATION jobarr := {}
OPERATIONS
take ( jj ) =
b
ANY tmp WHERE tmp 1 . . limit tmp 6 dom ( jobarr ) THEN
jobarr ( tmp ) := jj
END

jj - process =
b
ANY tmp WHERE tmp dom ( jobarr ) THEN
jj := jobarr ( tmp ) ;
jobarr := { tmp } jobarr
END

prioritise ( jj ) =
b jobarr := jobarr { jj }
END

REFINEMENT JobshopRR
REFINES Jobshop
VARIABLES jobarr , counter
INVARIANT jobarr 1 . . limit JOB counter 0 . . limit
jobarr [ 1 . . counter ] = jobs counter = card ( jobs )
INITIALISATION jobarr : 1 . . limit JOB ; counter := 0
OPERATIONS
take ( jj ) =
b
BEGIN

counter := counter + 1 ; jobarr ( counter ) := jj


END

jj - process =
b
BEGIN

jj := jobarr ( counter ) ;
counter := counter 1
END

prioritise ( jj ) =
b
ANY ii WHERE ii 1 . . counter jobarr ( ii ) = jj THEN

34

jobarr ( ii ) := jobarr ( counter ) ; counter := counter 1


END

END
Exercise 13.2

REFINEMENT BoothR
REFINES Booth
VARIABLES reserved , ticketsr
INVARIANT ticketsr SEAT
7 CUSTOMER
cc . ( cc CUSTOMER card ( ticketsr

= card ( tickets

[ { cc } ] )

[ { cc } ] ) + reserved ( cc ) )

INITIALISATION reserved := CUSTOMER { 0 } k ticketsr := {}


OPERATIONS
reserve ( cc , nn ) =
b
BEGIN

reserved ( cc ) := reserved ( cc ) + nn k
ANY ss WHERE ss SEAT card ( ss ) = nn ss dom ( ticketsr ) = {} THEN
ticketsr := ticketsr ss { cc }
END
END

collect ( cc ) =
b reserved ( cc ) := 0
END

35

The B-Method: an Introduction


Sample solutions to exercises from Chapter 14
Exercise 14.1
There are no sets and constants of ColoursR2 so there are no proof obligations
associated with sets and constants.
ColoursR2 has no state, and hence no initialisation. However, it does have a
non-trivial invariant J which requires that red cols, so it will have a proof obligations associated with initialisation. The initialisation of Colours2 is equivalent to skip, so the proof obligation that concrete initialisation refines abstract
initialisation is:
[skip][cols : P(COLOUR {blue})](red cols)
=
=

( cols P(COLOUR {blue}) . red 6 cols)


cols . (cols P({red, green}) red cols)

i.e. there is some subset of {red, green}) which contains redand this proof
obligation is true.
Each operation PRE P1 THEN S 1 END which refines PRE P THEN S END
will have the proof obligation that I J P [S 1[out /out ]][S ](J
out = out ), where I is the invariant of Colours. For each operation in turn we
calculate [S 1[out /out ]][S ](J out = out ) and show that it is implied by
I J P.
add(cc): This operation does not have any outputs.
[S 1][S ]J
=

[skip][cols := cols {cc}](red cols)

red (cols {cc})

red cols

I J P

(= J )

cc - query:
[S 1[out /out ]][S ]J
=

[cc := red][cc : cols](red cols cc = cc)

( cc . cc cols (red cols red = cc))

cc . (cc cols (red cols red = cc))

red cols

I J P

(= J )

change: This operation has no outputs:


[S 1][S ]J
=

[skip][cols : P(COLOUR) {cols}](red cols)

36

( cs . (cs P(COLOUR) {cols} (red cs)))

cs . (cs P(COLOUR) {cols} red cs)

true

I J P

The penultimate line follows from the fact that there will always be some subset
of COLOUR other than cols which contains red (since there are 4 such subsets
altogether).
Thus all proof obligations are discharges, establishing that ColoursR2 is a
refinement of Colours.
If the invariant is simply true then the query operations proof obligations
will not discharge. This linking invariant is not strong enough to establish that
ColoursR2 is a refinement of Colours.

Exercise 14.2
There are no sets or constants introduced by TeamR, so there are no proof
obligations generated there.
The proof obligation for initialisation is as follows:
[teamr := nn . (nn 1..11 | nn)]
[team := 1..11]
(teamr 1..11
=

 1..22 ran(teamr = team))


 1..22)

( nn . (nn 1..11 | nn) 1..11

ran( nn . (nn 1..11 | nn) = 1..11


(which is true)
The proof obligation for substitute is
I J P [teamr (teamr 1(pp)) := rr ]
[team := team {rr } {pp}]

 1..22 ran(teamr = team))


(pp) rr } 1..11  1..22

(teamr 1..11
=

I J P
(teamr <+ {teamr 1

ran(teamr <+ {teamr 1 (pp) rr } = team {rr } {pp}))


(which is true)
The proof obligation for query is
I J
[ IF pp ran(teamr ) THEN aa := in ELSE aa := out END ]
[ IF pp team THEN aa := in ELSE aa := out END ]
(J aa = aa)

37

I J
[ IF pp ran(teamr ) THEN aa := in ELSE aa := out END ]
J (pp team aa = in
pp 6 team aa = out )

I J
J (pp ran(teamr ) pp team in = in
pp 6 ran(teamr ) pp team out = in
pp ran(teamr ) pp 6 team in = out
pp 6 ran(teamr ) pp 6 team out = out )

(and this is true, since J implies ran(teamr ) = team.)


Exercise 14.3
No, it is not possible. If ColoursR is in the state colour = blue, then this is
related to four states of Colours, including {blue} and {blue, green}. In the first
case, alter will result in the state {blue, red} and in the second case {green}.
Thus any possible resulting state of alter in the refinement ColoursR must
match both of these states, since it must refine alter called from either of them.
But this is not possible, since there is no resulting value for colour which is in
both sets.
Exercise 14.4

REFINEMENT Colours2R
REFINES Colours2
VARIABLES in , out
INVARIANT in cols out COLOUR
( cols COLOUR out COLOUR cols ) in out
INITIALISATION in := red k out := blue
OPERATIONS
add ( cc ) =
b BEGIN IF cc = out THEN out : COLOUR { in , out } END
cc - inquery =
b cc := in ;
cc - outquery =
b cc := out ;
change =
b skip ;
invert =
b VAR tt IN tt := in ; in := out ; out := tt
END

END

END

38

The B-Method: an Introduction


Sample solutions to exercises from Chapter 15
Exercise 15.1
e := 1;
i := 0;
WHILE i < b
DO i := i + 1; e := e 2
INVARIANT i 0..b e = 2i
VARIANT b i
END
establishes postcondition e = 2b .
e := 1;
i := 0;
WHILE i < b
DO i := i + 1; e := e a
INVARIANT i 0..b e = a i
VARIANT b i
END
establishes postcondition e = a b .
Exercise 15.2
i := 0;
WHILE i < N
DO i := i + 1; arr (i) := i
INVARIANT i 0..N dom(arr ) 1..N VARIANT N i
((1..i)
END

C arr ) = j .(j 1..i | j )

establishes postcondition arr = j .(j 1..i | j ), provided initially dom(arr )


1..N .
Exercise 15.3
The proof obligations are:
1. (r + (q a) = a r > b [q := q + 1; r := r a](r + (q a) = a)
2. (r + (q a) = a (r > b) (q = a div b r = a mod b)
3. r + (q b) = a r N

39

4. (r + (q b) = a r > b r = ) [q := q + 1; r := r b](r < )


5. [r := a; q := 0](r + (q b) = a)

The first and the fifth are true. The second is false in the case where r = b or
r < 0. The third is falser could be negative. The fourth is false when b 0,
since then r b does not decrease r . The third and fourth indicate that the
invariant requires strengthening to state that b > 0 and that r 0. The second
proof obligations indicates that the guard of the loop should be r
b rather
than r > b.

>

>

Thus the loop should be as follows:


r := a; q := 0;
WHILE r

>b

DO q := q + 1; r := r b

INVARIANT r N b N1 r + (q b) = a
VARIANT r
END

Since the invariant must be true when the loop is started, it requires that a

N b N1 .

Exercise 15.4
ans := TRUE
j := 2
WHILE j < n
DO IF n mod j = 0 THEN ans := FALSE END ; j := j + 1
INVARIANT ans = TRUE ( i.(i 2..j 1 n mod i 0)) j
VARIANT n j
END

Exercise 15.5
i := 0;
maximum := 0;
WHILE i < N
DO i := i + 1;
IF arr (i) > maximum THEN maximum := arr (i) END
INVARIANT maximum = max(arr [1..i] {0}) i 0..N
VARIANT N i
END

6n

40

Exercise 15.6
We first calculate
[ IF i = 0 THEN rep := FALSE ELSE rep := TRUE END ](rep = TRUE p ran(a))
=

i = 0 (FALSE = TRUE p ran(a))


i 0 (TRUE = TRUE p ran(a))

(i = 0 p 6 ran(a)) (i 0 p ran(a))

(=

P)

This is the postcondition for the loop section of the program. The proof conditions for the loop are therefore:
1. (p 6 a[(i + 1)..N ] i
a[(i + 1)..N ] i N)

i > 0 a(i) p) [i := i 1](p 6

2. (p 6 a[(i + 1)..N ] i N (i > 0 a(i) p)) P

3. (p 6 a[(i + 1)..N ] i N i N

4. (p 6 a[(i + 1)..N ] i N i > 0 a(i) 6 p i = [i := i 1](i < )


5. [i := N ](p 6 a[(i + 1)..N ] i N)

These are all straightforward to establish, except the second, which bears
closer examination:
(p 6 a[(i + 1)..N ] i N (i > 0 a(i) p))
=

(p 6 a[(i + 1)..N ] i N (i = 0 a(i) = p))

i = 0 p 6 a[(i + 1)..N ]
a(i) = p p 6 a[(i + 1)..N ]

i = 0 p 6 ran(a)
a(i) = p i 0 p ran(a)

Thus the postcondition of the loop is established.


Exercise 15.7
i := 1;
j := 1;
WHILE a(i) b(j )
DO IF a(i) < b(j )THEN i := i + 1ELSE j := j + 1END
INVARIANT ran(a (i 1)) ran(b (j 1)) {}

6 a(x + 1))
x . (x dom(b) x size(b) b(x) 6 b(x + 1))
x . (x dom(a) x size(a) a(x)

VARIANT size(a) + size(b) i j


END

41

Exercise 15.8
i := a;
j := b;
k := a;
l := b;
WHILE i j
DO IF i < j
THEN j := j i; l := l + k
ELSE i := i j ; k := k + l
END
INVARIANT (i l) + (j k) = 2 a b
VARIANT i + j
END ;
gcd := i;
x := (k + l)/2
The value of x at the end of the loop is (k + l)/2, and i = j = gcd(a, b). Since
the invariant il + jk = 2ab is true on termination, i.e. gcd(a, b) (l + k) = 2ab,
we have that (k + l)/2 = ab/gcd(a, b) = lcm(a, b), i.e. x is the lowest common
multiple of a and b: the smallest number that they both divide into.

42

The B-Method: an Introduction


Sample solutions to exercises from Chapter 16

Exercise 16.1

We must establish that I J P [S 1[out /out ]][S 1]J , where S 1 and S


are the bodies of the implementation and specification respectively of add.

[ VAR nn IN nn - number ;

IF nn < cap

END ]

THEN rr := ok; input (ee); inc


ELSE rr := failed
END
[ IF size(queue) < cap THEN rr := ok k queue := queue ee ELSE rr := failed END ]
(counter = size(contents) contents = queue rr = rr )
=

[ VAR nn IN nn - number ;

END ]

IF nn < cap
THEN rr := ok; input (ee); inc
ELSE rr := failed
END
(size(queue) < cap (counter = size(contents) contents = queue ee rr = ok)
size(queue)
=

> cap (counter = size(contents) contents = queue rr

[ VAR nn IN nn := counter ;
IF nn < cap
THEN rr := ok;
PRE ee ELEM size(contents < cap)
THEN contents := contents ee
END ;
counter := counter + 1
ELSE rr := failed
END
END ]
(size(queue) < cap ( counter = size(contents)
contents = queue ee
rr = ok)

size(queue)

> cap ( counter = size(contents)


contents = queue
rr = failed)

= failed)

43

counter < cap (size(queue) < cap ( counter + 1 = size(contents ee)


contents ee = queue ee
ok = ok)

size(queue)

> cap ( counter + 1 = size(contents)


contents ee = queue

counter

> cap

ok = failed))
(size(queue) < cap ( counter = size(contents)
contents = queue ee
failed = ok)

size(queue)

> cap ( counter = size(contents)


contents = queue
failed = failed))

counter < cap size(queue) < cap (counter + 1 = size(contents ee)


contents ee = queue ee)

counter

> cap

size(queue)

> cap (counter = size(contents)

contents = queue)

counter = size(contents) contents = queue

I J P

as required.
Exercise 16.2
MACHINE RussianMult
OPERATIONS
rr - mult ( aa , bb ) =
b
PRE aa N1 bb N1
THEN rr := aa bb
END

END

IMPLEMENTATION RussianMultI
REFINES RussianMult
IMPORTS RussianBody
OPERATIONS
rr - mult ( aa , bb ) =
b
VAR xx , yy , total IN
xx := aa ;
yy := bb ;
total := 0 ;
WHILE xx > 0
DO xx , yy , total - body ( xx , yy , total )

44
INVARIANT
VARIANT
END

total + xx yy = aa bb xx

N yy N total N

xx

rr := total
END

END
MACHINE RussianBody
OPERATIONS
dd , ee , tt - body ( xx , yy , ss ) =
b
PRE xx N yy N ss N
THEN
IF xx mod 2 = 1 THEN

tt := ss + yy END

k dd := xx / 2
k ee := yy 2
END

END
Exercise 16.3

IMPLEMENTATION DateI
REFINES Date
SEES DateFields
PROPERTIES
DATE = { dd , mm , yy | dd DAY mm MONTH yy YEAR
( mm { April , June , September , November } dd 30 )
( mm = February dd 29 )
( mm = February ( yy YEAR yy mod 4 0 }
( yy mod 100 = 0 yy mod 400 0 ) )
dd 28 )
END
MACHINE DateFields
SETS DAY ; YEAR ;
MONTH = { January , February , March , April , May , June ,
July , August , September , October , November , December }
PROPERTIES DAY = 1 . . 31 YEAR = N
END

45

The B-Method: an Introduction


Sample solutions to exercises from Chapter 17
Exercise 17.1
IMPLEMENTATION HeapI
...
OPERATIONS
insert ( nn ) =
b
BEGIN

inc ;
VAR ii , rep IN

ii - number ;
rep := TRUE ;
append ( nn ) ;
WHILE ii > 1 rep = TRUE
DO rep - siftup ( ii ) ; ii := ii / 2
INVARIANT ii 1 . . counter counter = size ( queue ) + 1
( xx , yy ) . ( xx 2 . . counter 1 yy 1 . . counter 1
( xx yy parent *
( rep = FALSE
xx . ( xx

xx ii ) heaparray ( yy ) heaparray ( xx ) ) )
card ( heaparray

[ { xx } ] )

= card ( ( queue nn) 1 [ { xx } ] ) )


VARIANT

ii

END
END
END

MACHINE Heaparray
...
rr - siftup ( ii ) =
b
PRE ii 2 . . size ( heaparray )
THEN IF heaparray ( ii / 2 ) > heaparray ( ii )
THEN heaparray := heaparray <+ { ii / 2 heaparray ( ii ) , ii heaparray ( ii / 2 ) }
k rr := TRUE
ELSE rr := FALSE
END
END

Exercise 17.2
sort ( ii , jj ) =
b
PRE ii 1 . . cap jj 1 . . cap ii < jj

46
THEN
ANY

pp

pp ii . . jj ii . . jj
nn . ( nn ii . . jj 1 pp ; aa ( nn ) pp ; aa ( nn + 1 ) )
THEN aa := aa <+ ( pp ; aa )

WHERE

END
END

IMPLEMENTATION SortarrayI
...
sort ( ii , jj ) =
b
BEGIN

cc , nn IN
cc := ii 1 ;
WHILE cc < jj
DO cc := cc + 1 ;
nn - get ( cc ) ;
insert ( nn )
INVARIANT cc ii 1 . . jj
pp . ( pp ii . . cc 1 . . cc ( ii 1 ) ( pp ; queue ) = ii . . cc
array = aa
VARIANT jj cc

VAR

C array )

END
END

cc , nn IN
cc := ii 1 ;
WHILE cc < jj
DO cc := cc + 1 ;
nn - extract ;
set ( cc , nn )
INVARIANT cc N cc cap

VAR

pp . ( pp ii . . jj ii . . jj ( pp ; queue ( ii . . cc array ) ) = ii . . jj
xx . ( xx ii . . cc 1 array ( xx ) array ( xx + 1 ) )
( xx , yy ) . ( xx ran ( queue ) yy array [ ii . . cc ] yy xx )
VARIANT cap cc
END
END
END

END

C aa )

47

The B-Method: an Introduction


Sample solutions to exercises from Chapter 18
Exercise 18.1
The constraints clause CONSTRAINTS
maximum < 2146483646 must be
added to SizeCounter, in order to make use of an Nvar machine.

IMPLEMENTATION SizeCounterI
REFINES SizeCounter
IMPORTS sze Nvar ( maximum )
INVARIANT sze Nvar = sze
INITIALISATION sze STO NVAR ( 0 )
OPERATIONS
szeinc =
b sze INC NVAR ;
szedec =
b sze DEC NVAR ;
ss - szeget =
b ss - sze VAL NVAR
END

Exercise 18.2
MACHINE Checkouts
...
OPERATIONS
closeandmove ( co1 , co2 ) =
b
PRE co1 COUNTER co2 COUNTER
THEN opencounters := opencounters { co1 }

k queues := { co1 } queues <+ { co2 ( queues ( co2 )


END

...
IMPLEMENTATION CheckoutsI
...
closeandmove ( co1 , co2 ) =
b
VAR tt1 , tt2 , bb IN
tt1 - get ( co1 ) ;
tt2 - get ( co2 ) ;
bb - queues APP SEQ OBJ ( tt2 , tt1 ) ;
queues KIL SEQ OBJ ( tt1 ) ;
remove ( co1 )
END

...

a queues ( co1 ) ) }

48

Exercise 18.3
Specification:
jumpqueue ( co , cu ) =
b
PRE

co opencounters cu CUSTOMER
S
cu 6 cc . ( cc dom ( queues ) | ran ( queues ( cc ) ) )
THEN queues ( co ) := cu queues ( co )

END

Implementation:
jumpqueue ( co , cu ) =
b
VAR pp , bb IN
pp - get ( co ) ;
queues REV SEQ OBJ ( pp ) ;
bb - queues PSH SEQ OBJ ( pp , cu ) ;
queues REV SEQ OBJ ( pp )

END

Exercise 18.4
rep - present ( cu ) =
b
PRE cu CUSTOMER
THEN
IF cu

cc . ( cc dom ( queues ) | ran ( queues ( cc ) ) )


THEN rep := TRUE
ELSE rep := FALSE
END
END

;
Implementation:

rep - present ( cu ) =
b
VAR nn , pp , bb , ii , ans IN
nn , pp - queues FIRST SEQ OBJ ;
ans := FALSE ;
WHILE nn > 0
DO bb , ii - queues MBR SEQ OBJ ( pp , cu ) ;
IF bb = TRUE THEN ans := TRUE END ;
nn , pp - queues NEXT SEQ OBJ ( nn , pp )
INVARIANT nn N
VARIANT nn
END

rep := ans
END

49

Exercise 18.5
mm - maximum =
b
VAR vv , ii , msf IN
msf := 0 ;
ii - marks CRD SET ;
WHILE ii > 0
DO vv - marks VAL SET ( ii ) ;
IF vv > msf THEN msf := vv END ;
ii := ii 1
INVARIANT

ii N
msf = max ( marks ordn [ ii + 1 . . card ( marks ) ] { 0 } )
marks sset = marks

VARIANT

ii
END

mm := msf
END

Exercise 18.6

IMPLEMENTATION BasketsI
REFINES Baskets
IMPORTS
Baskets set obj ( GOODS , 1000 , 1000 ) ,
Baskets set ctx , Pfun ( CUSTOMER , Baskets SETOBJ ) , Bool TYPE
INVARIANT ( pfun ; Baskets setstruct ) = baskets
ran ( pfun ) = Baskets settok
OPERATIONS
enter ( cu ) =
b
VAR bb , pp IN
bb , pp - Baskets CRE SET OBJ ;
set ( cu , pp )
END

add ( cu , gg ) =
b
VAR pp , bb IN
pp - get ( cu ) ;
bb - Baskets ENT SET OBJ ( pp , gg )
END

nn - checkout ( cu ) =
b
VAR pp , ll , ii , total , vv IN
pp - get ( cu ) ;

50

ll - Baskets CRD SET OBJ ( pp ) ;


ii := 0 ;
total := 0 ;
WHILE ii < ll
DO ii := ii + 1 ;
vv - Baskets VAL SET OBJ ( pp , ii ) ;
total := total + price ( vv )
INVARIANT

ii 0 . . ll
P
total =
jj . ( jj Baskets setord ( pp ) [ 1 . . ii ] | price ( jj ) )
VARIANT ll ii
END

nn := total ;
Baskets KIL SET OBJ ( pp )
END

END

Anda mungkin juga menyukai