47
Department of Computing Johannes Kepler University Linz, Austria Handbook: Formal Specification and Development of Software David Lightfoot [email protected] http://www.Brookes.ac.uk

Johannes Kepler University Linz, Austria Handbook: …ssw.jku.at/Teaching/Lectures/SpezialLVA/Lightfoot/2011/Handbook.pdf · Department of Computing Johannes Kepler University Linz,

  • Upload
    hamien

  • View
    221

  • Download
    0

Embed Size (px)

Citation preview

Page 1: Johannes Kepler University Linz, Austria Handbook: …ssw.jku.at/Teaching/Lectures/SpezialLVA/Lightfoot/2011/Handbook.pdf · Department of Computing Johannes Kepler University Linz,

Department of Computing

Johannes Kepler University Linz, Austria

Handbook: Formal Specification and Development of Software

David Lightfoot

[email protected] http://www.Brookes.ac.uk

Page 2: Johannes Kepler University Linz, Austria Handbook: …ssw.jku.at/Teaching/Lectures/SpezialLVA/Lightfoot/2011/Handbook.pdf · Department of Computing Johannes Kepler University Linz,

2

Contents 1. Example Formal Specification – Airport ............................................................3

2. Refinement ..........................................................................................................7

3. Implementation..................................................................................................10

4. Functions ...........................................................................................................12

5. Summary of function notation...........................................................................18

6. Collected Z notation ..........................................................................................19

7. Example specification in Abstract Machine Notation (‘B’) – Airport ..............24

8. Formal Specification Exercises 1 – Houses of Parliament................................25

9. Formal Specification Exercises 2 – Hotel .........................................................27

10. Formal Derivation – part 1: Introduction ..........................................................28

11. Formal Derivation – part 2: Selection and repetition ........................................33

12. Formal Derivation – part 3: Bound functions, arrays .......................................38

13. Exercises for Formal Derivation Part 1 .............................................................42

14. Exercises for Formal Derivation Part 2 .............................................................43

15. Exercises for Formal Derivation Part 3 .............................................................44

16. Formal Derivation: Larger Exercise 1...............................................................45

17. Formal Derivation: Larger Exercise 2...............................................................46

18. Formal Derivation Examination Questions .......................................................47

Note These notes are prepared for the lectures and exercise classes in Formal Specification and Development of Software of the Johannes Kepler University, Linz, Austria and are not to be used for other purposes without permission.

David Lightfoot May 2003

Page 3: Johannes Kepler University Linz, Austria Handbook: …ssw.jku.at/Teaching/Lectures/SpezialLVA/Lightfoot/2011/Handbook.pdf · Department of Computing Johannes Kepler University Linz,

3

1. Example Formal Specification – Airport

Introduction This is a very simple example of a formal (mathematical) specification in Z [1, 2]. The air-traffic control of an airport keeps a record of the planes waiting to land and the assignment of planes to gates on the ground. There are operations to accept a plane when it arrives in the airport’s waiting space, to assign a plane to a gate at the airport and to record that a plane leaves its gate. There is a limit to the number of planes that can be waiting.

A first version

Constant limit: N limit of planes waiting

The sets The sets used in this formal specification are:

[PLANE] the set of all possible, uniquely identified airplanes [GATE] the set of all gates at this airport

The state The state of the airport, at any time, can be expressed by this Z schema:

» AIRPORT _______________ Æwaiting: PPLANE Æassignment: GATE © PLANE «__________________ Æ#waiting ≤ limit Æwaiting I ran assignment = 0 –____________________

Each plane is assigned to at most one gate and each gate has at most one plane assigned to it. There must be no more than limit planes waiting. No plane is both waiting and assigned to a gate. The planes waiting are a set of planes (they are in no particular order). The assignment of planes to gates is an injective (one-to-one) function from gate to plane.

waiting assignment

Page 4: Johannes Kepler University Linz, Austria Handbook: …ssw.jku.at/Teaching/Lectures/SpezialLVA/Lightfoot/2011/Handbook.pdf · Department of Computing Johannes Kepler University Linz,

4

The initialisation operation » Init _______________ ÆAIRPORT' «__________________ Æwaiting' = 0 Æassignment' = 0 –____________________

The initialisation only deals with the after state, indicated by AIRPORT'. Initially there are no planes waiting or at any gate. The schema has access to the variables of the schema AIRPORT'. The (new value of the) set waiting' is the empty set. The (new value of the) function assignment' is an empty function.

The operations The subscript 0 in the names (Arrive0) indicates a first version of the operation schema.

Arrive0 The operation Arrive0 records the arrival of a plane p? in the airport’s waiting area:

» Arrive0 _______________ Æp?: PLANE ÆDAIRPORT «__________________ Æ#waiting Î limit Æp? ‰ (waiting U ran assignment) Æwaiting' = waiting U {p?} Æassignment' = assignment –____________________

The waiting area must not be full and the plane must be neither already waiting nor assigned to a gate. The schema has access to the before and after (') values of the schema AIRPORT. The new value of the set waiting is the same as before but with p? added. (The question mark in p? signifies an input parameter). The new value of the function assignment is the same as the old value of assignment. Note that it is necessary to state this apparently redundant information.

Assign0 The operation Assign0 records the assignment of a plane p? to a free gate g?:

» Assign0 _______________ Æp?: PLANE Æg?: GATE ÆDAIRPORT «__________________ Æp? e waiting Æg? ‰ dom assignment Æassignment' = assignment U {g? å p?} Æwaiting' = waiting \ {p?} –____________________

The plane must be waiting and the gate must be free. The pairing between gate g? and plane p? is added to assignment. Plane p? is removed from waiting.

Page 5: Johannes Kepler University Linz, Austria Handbook: …ssw.jku.at/Teaching/Lectures/SpezialLVA/Lightfoot/2011/Handbook.pdf · Department of Computing Johannes Kepler University Linz,

5

Leave0 The operation Leave0 records the plane p? leaving its gate:

» Leave0 _______________ Æp?: PLANE ÆDAIRPORT «__________________ Æp? e ran assignment Æassignment' = assignment u {p?} Æwaiting' = waiting –____________________

The plane p? must be assigned to a gate. The assignment for plane p? is removed. The waiting planes are unaffected.

Handling errors So far we have indicated the preconditions for successful operations, but have not said what will happen if these preconditions are not satisfied. We can do this by using separate error-handling schemas. Firstly we introduce a type for a result message:

RESULT ::= OK | full | badAircraft | notWaiting | gateNotFree | notAtGate

Operations We introduce a further, output (!) parameter, reply! to each error schema: The X in front of the schema name XAIRPORT signifies that there will be no change to the state of the airport and thus no need to state what does not change.

ArriveErr This schema handles the cases where the preconditions of Arrive are not satisfied:

» ArriveErr ______________ Æp?: PLANE Æreply!: RESULT ÆXAIRPORT «__________________ Æ#waiting = limit ¶ reply! = full Æv Æp? e (waiting U ran assignment) ¶ reply! = badAircraft –____________________

AssignErr The operation AssignErr handles the cases where the preconditions of Assign are not satisfied:

» AssignErr _____________ Æp?: PLANE Æg?: GATE Æreply!: RESULT ÆXAIRPORT «__________________ Æp? ‰ waiting ¶ reply! = notWaiting Æv Æg? e dom assignment ¶ reply! = gateNotFree –____________________

Page 6: Johannes Kepler University Linz, Austria Handbook: …ssw.jku.at/Teaching/Lectures/SpezialLVA/Lightfoot/2011/Handbook.pdf · Department of Computing Johannes Kepler University Linz,

6

LeaveErr The operation LeaveErr handles the cases where the preconditions of Leave are not satisfied:

» LeaveErr ____________ Æp?: PLANE Æreply!: RESULT ÆXAIRPORT «__________________ Æp? ‰ ran assignment ¶ reply! = notAtGate –____________________

Fully specified operations Finally we use schema calculus to put together the schemas to give fully specified operations. We start with a small schema OKMessage that simply produces the reply! OK:

OKMessage == [reply!: RESULT | reply! = OK] Then we combine schemas using Boolean operators, overloaded to apply to schemas:

The operations Arrive The operation Arrive records the arrival of a plane p? in the airport’s waiting area:

Arrive == Arrive0 ¶ OKMessage v ArriveErr

Assign The operation Assign records the assignment of a plane p? to a free gate g?:

Assign == Assign0 ¶ OKMessage v AssignErr

Leave0 The operation Leave records the plane p? leaving its gate:

Leave == Leave0 ¶ OKMessage v LeaveErr

Page 7: Johannes Kepler University Linz, Austria Handbook: …ssw.jku.at/Teaching/Lectures/SpezialLVA/Lightfoot/2011/Handbook.pdf · Department of Computing Johannes Kepler University Linz,

7

2. Refinement Refinement is the term used for the formal derivation of a version of the specification that is closer to what is easy to represent on a computer. Where an abstract specification uses sets and functions, an refinement might use sequences. These can easily be implemented by arrays, or linked lists or files. In this example we represent the set waiting by an injective sequence waitList:

waitList: iseq PLANE and the constraint

#waitList ≤ limit We further choose to represent

assignment: GATE © PLANE by two sequences

gatesUsed: iseq GATE and

planesAt: iseq PLANE The sequences are injective because there can be no duplicates in either sequence. Between them the two sequences hold the same information as assignment. Clearly the sequences must be the same length. For example:

assignment = {g1 å p1, g3 å p23, g15 å p21} is represented by:

gatesUsed = „g1, g3, g15Ò and

planesAt = „p1, p23, p21Ò We use the following schema for the refined version of the airport:

» AIRPORTREF _______________ ÆwaitList: iseq PLANE ÆgatesUsed: iseq GATE ÆplanesAt: iseq PLANE «__________________ Æ#waitList ≤ limit Æ#gatesUsed = #planesAt Æran waitList I ran planesAt = 0 –____________________

Abstraction function The abstraction function relates the concrete state to the abstract state that it refines. To understand this relationship in this case, let’s look at the example again:

gatesUsed = „g1, g3, g15Ò and

planesAt = „p1, p23, p21Ò The sequences can be regarded as functions (as can all sequences):

gatesUsed = {1 å g1, 2 å g3, 3 å g15} and

planesAt = {1 å p1, 2 å p23, 3 å p21}

Page 8: Johannes Kepler University Linz, Austria Handbook: …ssw.jku.at/Teaching/Lectures/SpezialLVA/Lightfoot/2011/Handbook.pdf · Department of Computing Johannes Kepler University Linz,

8

The function gatesUsed can be seen as this:

g1 g3 g15

↑ ↑ ↑

1 2 3 and planesAt as:

1 2 3

↓ ↓ ↓

p1 p23 p21

The inverse of gatesUsed, gatesUsed-1, can be seen as:

g1 g3 g15

↓ ↓ ↓

1 2 3

and so the composition of the inverse of gatesUsed and planesAt is equivalent to assignment:

g1 g3 g15

↓ ↓ ↓

1 2 3 (these indexes are no longer seen)

↓ ↓ ↓

p1 p23 p21 So the abstraction function in this example is:

» ABS _______________ ÆAIRPORT ÆAIRPORTREF «__________________ Æran waitList = waiting ÆgatesUsed-1 ; planesAt = assignment –____________________

we also observe that:

ran gatesUsed = dom assignment and

ran planesAt = ran assignment The sequence gatesUsed can be regarded as a function from the integers to a gate. Its inverse, gatesUsed-1, relates the gate to its corresponding integer position in the sequence. This position is then used to find the plane at that position in the sequence planesAt. This effect is achieved by composing the inverse of gatesUsed with planesAt, which contains the same information as the original function assignment.

1. The initial state » InitRef _______________ ÆAIRPORTREF «__________________ ÆwaitList = „ Ò ÆgatesUsed = „ Ò ÆplanesAt = „ Ò –____________________

Page 9: Johannes Kepler University Linz, Austria Handbook: …ssw.jku.at/Teaching/Lectures/SpezialLVA/Lightfoot/2011/Handbook.pdf · Department of Computing Johannes Kepler University Linz,

9

The operations ConcArrive0 The operation ConcArrive0 records the arrival of a plane p? in the waiting area:

» ConcArrive0 _______________ Æp?: PLANE ÆDAIRPORTREF «__________________ Æ#waitList Î limit Æp? ‰ (ran waitList U ran planesAt) ÆwaitList' = waitList ^ „p?Ò ÆgatesUsed' = gatesUsed ÆplanesAt' = planesAt –____________________

Note that we have decided to append the new plane to the list of waiting planes. This is arbitrary; and we have removed some non-determinacy. We could have added the new plane to any position in the list. In fact we could define the operation to have: ran waitlist’ = ran waitList U {p}

ConcAssign0 » ConcAssign0 _______________ Æp?: PLANE Æg?: GATE ÆDAIRPORTREF «__________________ Æp? e ran waitList Æg? ‰ ran gatesUsed ÆgatesUsed' =gatesUsed ^ „g?Ò ÆplanesAt' = planesAt ^ „p?Ò ÆwaitList' = squash(waitList u {p?}) –____________________

Again it is arbitrary to append the new values to gatesUsed and planesAt. The values can be added to any position in the list, so long as it is the same position in both lists.

ConcLeave0 » ConcLeave0 _______________ Æp?: PLANE ÆDAIRPORTREF «__________________ Æp? e ran planesAt ÆgatesUsed' = squash ((planesAt-1 p?) y gatesUsed) ÆplanesAt' = squash (planesAt u {p?}) ÆwaitList' = waitList –____________________

The range co-restriction (y) removes the plane from the sequence gatesUsed, but this leaves a gap, and so gatesUsed will no longer be a sequence. The predefined function squash closes up the gap.

Page 10: Johannes Kepler University Linz, Austria Handbook: …ssw.jku.at/Teaching/Lectures/SpezialLVA/Lightfoot/2011/Handbook.pdf · Department of Computing Johannes Kepler University Linz,

10

3. Implementation In order to indicate how a possible implementation would look, one is expressed here in a supposed self-explanatory syntax (Oberon-2):

Definition of interface DEFINITION Airport; (* dl Oct 1998 -- Implements formally specified airport *) CONST OK = 0; full = 1; badAircraft = 2; notWaiting = 3; gateNotFree = 4; notAtGate = 5; limit = 100; numGates = 10; TYPE Plane = ARRAY 32 OF CHAR; Gate = ARRAY 32 OF CHAR; PROCEDURE ShowWaitList; PROCEDURE Show; PROCEDURE Arrive (p: Plane; VAR reply: INTEGER); PROCEDURE Assign (p: Plane; g: Gate; VAR reply: INTEGER); PROCEDURE Leave (p: Plane; VAR reply: INTEGER); END Airport.

Implementation MODULE Airport; (** dl Oct 1998 -- Implements formally specified airport *) IMPORT Out; CONST OK* = 0; full* = 1; badAircraft* = 2; notWaiting* = 3; gateNotFree* = 4; notAtGate* = 5; limit* = 100; numGates* = 10; TYPE Plane* = ARRAY 32 OF CHAR; Gate* = ARRAY 32 OF CHAR; VAR waitList: ARRAY limit+1 OF Plane; numWaiting: INTEGER; planesAt: ARRAY numGates+1 OF Plane; gatesUsed: ARRAY numGates+1 OF Gate; numGatesUsed: INTEGER; PROCEDURE PosInWaitList (p: Plane): INTEGER; VAR i: INTEGER; BEGIN i := 0; waitList[numWaiting] := p; WHILE waitList[i] # p DO INC(i) END; RETURN i END PosInWaitList; PROCEDURE InWaitList (p: Plane): BOOLEAN; BEGIN RETURN PosInWaitList(p) # numWaiting END InWaitList; PROCEDURE PosInPlanesAt (p: Plane): INTEGER; VAR i: INTEGER;

BEGIN i := 0; planesAt[numGatesUsed] := p; WHILE planesAt[i] # p DO INC(i) END; RETURN i END PosInPlanesAt; PROCEDURE GateOfPlane (p: Plane; VAR g: Gate); BEGIN g := gatesUsed[PosInPlanesAt(p)] END GateOfPlane; PROCEDURE AtGate (p: Plane): BOOLEAN; BEGIN RETURN PosInPlanesAt(p) # numGatesUsed END AtGate; PROCEDURE GateInUse (g: Gate): BOOLEAN; VAR i: INTEGER; BEGIN i := 0; gatesUsed[numGatesUsed] := g; WHILE gatesUsed[i] # g DO INC(i) END; RETURN i # numGatesUsed END GateInUse; PROCEDURE AppendToWaitList (p: Plane); BEGIN waitList[numWaiting] := p; INC(numWaiting) END AppendToWaitList; PROCEDURE AppendGateAndPlane (g: Gate; p: Plane); BEGIN gatesUsed[numGatesUsed] := g; planesAt[numGatesUsed] := p; INC(numGatesUsed) END AppendGateAndPlane;

Page 11: Johannes Kepler University Linz, Austria Handbook: …ssw.jku.at/Teaching/Lectures/SpezialLVA/Lightfoot/2011/Handbook.pdf · Department of Computing Johannes Kepler University Linz,

11

PROCEDURE RemoveFromWaiting (p: Plane); VAR pos: INTEGER; BEGIN pos := PosInWaitList(p); DEC(numWaiting); waitList[pos] := waitList[numWaiting] END RemoveFromWaiting; PROCEDURE RemoveGateAndPlane (g: Gate; p: Plane); VAR pos: INTEGER; BEGIN pos := PosInPlanesAt(p); DEC(numGatesUsed); gatesUsed[pos] := gatesUsed[numGatesUsed]; planesAt[pos] := planesAt[numGatesUsed] END RemoveGateAndPlane; PROCEDURE ShowWaitList*; VAR i: INTEGER; BEGIN Out.String("waitList"); Out.Ln; FOR i := 0 TO numWaiting-1 DO Out.String(waitList[i]); Out.Ln END END ShowWaitList; PROCEDURE ShowGatesAndPlanes; VAR i: INTEGER; BEGIN Out.String("gates and planes"); Out.Ln; FOR i := 0 TO numGatesUsed-1 DO Out.String(gatesUsed[i]); Out.String(planesAt[i]); Out.Ln END END ShowGatesAndPlanes;

PROCEDURE Show*; BEGIN ShowWaitList; ShowGatesAndPlanes END Show; PROCEDURE Arrive* (p: Plane; VAR reply: INTEGER); BEGIN IF numWaiting = limit THEN reply := full ELSIF InWaitList(p) OR AtGate(p) THEN reply := badAircraft ELSE AppendToWaitList(p); reply := OK END END Arrive; PROCEDURE Assign* (p: Plane; g: Gate; VAR reply: INTEGER); BEGIN IF ~InWaitList(p) THEN reply := notWaiting ELSIF GateInUse(g) THEN reply := gateNotFree ELSE AppendGateAndPlane (g, p); RemoveFromWaiting(p); reply := OK END END Assign; PROCEDURE Leave* (p: Plane; VAR reply: INTEGER); VAR g: Gate; BEGIN IF ~AtGate(p) THEN reply := notAtGate ELSE GateOfPlane(p, g); RemoveGateAndPlane(g, p); reply := OK END END Leave; BEGIN numWaiting := 0; numGatesUsed := 0 END Airport.

References [1] Formal Specification Using Z David Lightfoot Macmillan 1991 [2] La Spécification Formelle avec Z David Lightfoot Traduit par Henri Habrias et Pierre-Marie Delpech Teknea 1994

Page 12: Johannes Kepler University Linz, Austria Handbook: …ssw.jku.at/Teaching/Lectures/SpezialLVA/Lightfoot/2011/Handbook.pdf · Department of Computing Johannes Kepler University Linz,

12

4. Functions A function is a relation In a programming language a function is a way of specifying some processing which produces a value as a result. In Z a function is a data structure. These two views are not incompatible; the programming language view is just a restricted form of the Z view and in both cases a function provides a result value, given an input value or values.

A function is a special case of a relation in which there is at most one value in the range for each value in the domain. A function with a finite domain is also known as a mapping.

X Y

f

x2 y2

y3x4

x6

x1

dom f ran fy1

y4

x3

x5

Note that in the diagram the lines converge from left to right.

In Z a function f from the type X to the type Y is declared by:

f: X ß Y

and is pronounced “the function f, from X to Y”. This is equivalent to the relation f from X to Y:

f : X ↔ Y

with the restriction that for each x, f relates it to at most one y:

x ∈ dom f ⇒ ∃ 1 y: Y • x f y

Examples of functions The relation between persons and identity numbers:

identityNo: PERSON ↔ N

is a function if there is a rule that a person may only have one identity number. In this case it would be declared:

identityNo: PERSON ß N

There would probably also be a rule that only one identity number may be associated with any person, but this is not indicated here.

Note that there is no restriction that the function must map different values of the source on to different values of the target. So one could have the function giving a person’s mother:

isMotherOf: PERSON ß PERSON

since any person can have only one mother, but several people may have the same mother.

Page 13: Johannes Kepler University Linz, Austria Handbook: …ssw.jku.at/Teaching/Lectures/SpezialLVA/Lightfoot/2011/Handbook.pdf · Department of Computing Johannes Kepler University Linz,

13

Function application All the concepts which pertain to relations are also applicable to functions. In addition, however, a function may be applied. Since there will be at most one value in the range for a given x it is possible to designate that value directly. The value of f applied to x is the value in the range of the function f corresponding to the value x in its domain. The application is meaningless if the value of x is not in the domain of f.

The application of the function f to the value x (called its argument) is written:

f x

and pronounced “f of x” or “f applied to x”.

Some people put brackets around the argument, as in:

f(x)

but although this is correct, it is not necessary.

Total and partial functions The functions given as examples above have been shown as partial, which means that there are some values of the source which are not in the domain of the function. A total function is one where there is a value for every possible value of x, so f x is always defined. The domain is the whole of the source.

A total function is declared by

f: X → Y

and is pronounced “f is a total function from X to Y”. It is equivalent to

f : X ß Y

“f is the partial function from X to Y”, with the restriction that

dom f = X

Examples of total functions The function age, from PERSON to natural numbers, is total since every person has an age:

age: PERSON → N

The function isMotherOf given above, is total since for any person there is exactly one person who is or was that person’s mother:

isMotherOf: PERSON → PERSON

Other classes of functions As well as their being either total or partial, other sorts of functions can be distinguished:

Injection An injection, or injective function, is a function that maps different values of the source on to different values of the target. The inverse relation of an injective function f, from X to Y, f~, is itself a function, from Y to X:

f~ ∈ Y ß X

An injective function may be partial or total. Injective functions are sometimes described as “one to one”.

Since it is likely that each number is associated with only one person, the function identityNo given above would be injective.

Page 14: Johannes Kepler University Linz, Austria Handbook: …ssw.jku.at/Teaching/Lectures/SpezialLVA/Lightfoot/2011/Handbook.pdf · Department of Computing Johannes Kepler University Linz,

14

Surjection A surjection, or surjective function, is a function for which there is a value in the range for every value of the target; the range of the function is the target. The surjective function f from X to Y has the property that:

ran f = Y

A surjective function may be partial or total.

Bijection A bijection, or bijective function, is one which maps every element of the source on to every element of the target in a one-to-one relationship. It is therefore: injective, total and surjective.

Arrow symbols These classes of functions are distinguished by further arrow shapes.

partial function ß

total function f

partial injection ©

total injection ƒ

partial surjection ˚

total surjection ∆

bijection ¬

Constant functions Some functions are used as a means of providing a value, given a parameter or parameters. These are usually functions which maintain a constant mapping from their input parameters to their output values. If the value of the mapping is known, a value can be given to the function by an axiomatic definition. For example to define the function square:

Æ square: Z → Z «__________________ Æ∀ n: Z • square n = n x n

Where convenient, several functions can be combined in one definition: Æ square: Z → Z Æ cube: Z → Z «__________________ Æ∀ n: Z • ∀ n: Z • Æ square n = n x n ∧ Æ cube n = n x n x n

Functional overriding A function can be modified by adding mapping pairs to it or by removing pairs. It can also be modified so that for a particular set of values of the domain it has new values in the range. This is called overriding. The function f overridden by the function g is written:

f ⊕ g

Page 15: Johannes Kepler University Linz, Austria Handbook: …ssw.jku.at/Teaching/Lectures/SpezialLVA/Lightfoot/2011/Handbook.pdf · Department of Computing Johannes Kepler University Linz,

15

It is the same as f for all values which are not in the domain of g and the same as g for all values which are in the domain of g:

If

x ∈ dom f ∧ x ∉ dom g

then

f ⊕ g x = f x

But if

x ∈ dom g

then

f ⊕ g x = g x

An alternative definition is:

f ⊕ g = (dom g y f ) ∪ g

If f and g have disjoint domains

dom f ∪ dom g = Ø

then

f ⊕ g = f ∪ g

Z also allows overriding for relations.

Example of overriding The recorded age of person p? is increased by 1:

age ⊕ {p? å age p? + 1}

The function age is overridden by the function with only p? in its domain which maps to the former value plus one.

Example from business – stock control A warehouse holds stocks of various items carried by an organization. A computer system records the level of all items carried, the withdrawal of items from stock and the delivery of stock. Occasionally a new item will be carried and items will be discontinued, provided that their stock level is zero.

[ITEM] the set of all items (item codes) » Warehouse _________ Æcarried: PITEM Ælevel: ITEM ß N «_____________ Æ dom level = carried –_______________

Every item carried has a level, even if it is zero. » Init __________ Æ Warehouse «_________ Æ carried = Ø Æ level = Ø –____________

Initially there are no items.

Page 16: Johannes Kepler University Linz, Austria Handbook: …ssw.jku.at/Teaching/Lectures/SpezialLVA/Lightfoot/2011/Handbook.pdf · Department of Computing Johannes Kepler University Linz,

16

» Withdraw ____________ Æ DWarehouse Æ ?: ITEM Æ qty?: N «_______________ Æ i? ∈ carried Æ level i? ≤ qty? Æ level' = level ⊕ {i? å (level i? – qty?)} Æ carried' = carried –_________________

For a quantity of an item to be withdrawn, the item must be carried and there must be enough stock » Deliver ____________ Æ DWarehouse Æ ?: ITEM Æ qty?: N «________________ Æ i? ∈ carried Æ level' = level ⊕ {i? å (level i? + qty?)} Æ carried' = carried –________________

Only deliveries for carried items are accepted. There is no upper limit on stock held. » CarryNewItem ____________ Æ DWarehouse Æ ?: ITEM «__________________ Æ i? ∉ carried Æ level' = level ∪ {i? å 0} Æ carried' = carried ∪ {i?} –____________________

A new item must not already be carried and will initially have a level of zero. » Discontinue ____________ Æ DWarehouse Æ ?: ITEM «__________________ Æ i? ∈ carried Æ level i? = 0 Æ level' = {i?} y level Æ carried' = carried \ {i?} –___________________

An item to be discontinued must currently be carried and must have a level of zero.

Note: errors have not been handled in this simple version.

Example from data processing

Indexed-sequential files In the programming language COBOL a type of data file called an indexed-sequential file is available. In principle an indexed-sequential file is a sequence of records which can be accessed in any order by specifying the value of a field of the desired record, called the key. There is at most one record in the file for any value of the key.

Page 17: Johannes Kepler University Linz, Austria Handbook: …ssw.jku.at/Teaching/Lectures/SpezialLVA/Lightfoot/2011/Handbook.pdf · Department of Computing Johannes Kepler University Linz,

17

Operations are available to read, write, insert and delete records (using the COBOL instructions READ, REWRITE, WRITE and DELETE respectively). The behaviour of these operations can be specified as follows:

[KEY] set of all keys for this file

[DATA] remaining fields of record (other than key) » ISFile ____________ Æ file: KEY ß DATA –_______________

The file is regarded as a function from a key to the rest of the data in the record. The function is partial since there may be values of the key for which there is no record on the file.

Read operation The operation Read is a function application:

» Read ____________ Æ ΞISFile Æ k?: KEY Æ result!: DATA «______________ Æ k? ∈ dom file Æ result! = file k? –________________

The value of result! is the data of the record with the key k?, if there is one. The file is unchanged.

Rewrite operation The operation Rewrite is a functional overriding:

» Rewrite ____________ Æ DISFile Æ k?: KEY Æ new?: DATA «______________ Æ k? ∈ dom file Æ file' = file ⊕ {k? å new?} –________________

The function is changed only for the value of k? in the domain, which now maps to the new data new?.

Write operation The operation Write is a functional (relational) union:

» Write ____________ Æ DISFile Æ k?: KEY Æ new?: DATA «______________ Æ k? ∉ dom file Æ file' = file ∪ {k? å new?} –________________

Page 18: Johannes Kepler University Linz, Austria Handbook: …ssw.jku.at/Teaching/Lectures/SpezialLVA/Lightfoot/2011/Handbook.pdf · Department of Computing Johannes Kepler University Linz,

18

Delete operation The operation Delete is a functional (relational) domain anti-restriction:

» Delete ____________ Æ DISFile Æ k?: KEY «______________ Æ k? ∈ dom file Æ file' = {k?} y file –________________

Error conditions The handling of errors has not been included here, to keep the specification simple. The schemas could easily be extended to include a report of success or failure.

Further facilities The COBOL language allows further operations on indexed-sequential files that make use of the fact that the records of such a file are held in order (ordered on the key). Clearly the specification used above would not suffice to specify those operations. However it gives a very concise explanation of the simple operations.

5. Summary of function notation X ß Y the set of partial functions from X to Y:

== { f: X ↔Y | ( ∀ x: X | x ∈ dom f.• ( ∃ 1 y: Y • x f y))}

X → Y the set of total functions from X to Y: == { f: X ßY | dom f = X • f}

f x or f(x) the function f applied to x

f ⊕ g functional overriding == (dom g y f ) ∪ g

Page 19: Johannes Kepler University Linz, Austria Handbook: …ssw.jku.at/Teaching/Lectures/SpezialLVA/Lightfoot/2011/Handbook.pdf · Department of Computing Johannes Kepler University Linz,

19

6. Collected Z notation

General

[X] the basic type X data type ::= member1 | member2 | … | membern

X == Y abbreviation definition – X stands for Y

Sets

Z the set of integers (whole numbers)

N the set of natural numbers (˘ 0)

N1 the set of positive natural numbers (˘ 1)

t ∈ S t is an element of S

t ∉ S t is not an element of S

S ⊆ T S is contained in T. S ⊂ T S is strictly contained in T. (S Î T)

Ø or { } the empty set {t1, t2, … tn} the set containing t1, t2, … tn PS Powerset: the set of all subsets of S

S the set of finite subsets of S

S ∪ T Union: elements that are either in S or T

∪ SS the distributed union of the set of sets SS

Logic

true, false logical constants

¬ P negation: “not P”

P ∧ Q conjunction: “P and Q”

P ∨ Q disjunction: “P or Q”

P ⇒ Q implication: “P implies Q” or “if P then Q”

P ⇔ Q equivalence: “P is logically equivalent to Q”

t1 = t2 equality between terms t1 Î t2 ¬(t1 = t2)

Schemas

S Í T schema definition: S is the same schema as T

Page 20: Johannes Kepler University Linz, Austria Handbook: …ssw.jku.at/Teaching/Lectures/SpezialLVA/Lightfoot/2011/Handbook.pdf · Department of Computing Johannes Kepler University Linz,

20

» SchemaName ____________ Æ declarations «______________ Æ predicate –________________

SchemaName == [ declarations | predicate ]

Axiomatic definition

Æ declarations «______________ Æ predicate

Inclusion » S ____________ Æ a, b: N «______________ Æ a < b –________________ » IncludeS ____________ Æ c: N Æ S «______________ Æ c < 10 –________________

== » IncludeS ____________ Æ c, a, b: N «______________ Æ c < 10 ∧ a < b –________________

Conjunction » T ____________ Æ b, c: N «______________ Æ b < c –________________

SandT == S ∧ T

== » SandT ____________ Æ a, b, c: N «______________ Æ a < b ∧ b < c –________________

Page 21: Johannes Kepler University Linz, Austria Handbook: …ssw.jku.at/Teaching/Lectures/SpezialLVA/Lightfoot/2011/Handbook.pdf · Department of Computing Johannes Kepler University Linz,

21

Disjunction

SorT == S ∨ T

== » SorT ____________ Æ a, b, c: N «______________ Æ a < b ∨ b < c –________________

Implication

SimplT fi S ⇒ T

== » SimplT ____________ Æ a, b, c: N «______________ Æ a < b ⇒ b < c –________________

Equivalence

SeqT == S ⇔ T

== » SeqT ____________ Æ a, b, c: N «______________ Æ a < b ⇔ b < c –________________

Decoration » S' ____________ Æ a', b': N «______________ Æ a' < b' –________________

Predicates and their use with schemas

∀ x: T • Px Universal quantification:

“for all x of type T, Px holds”

∃ x: T • Px Existential quantification:

“there exists an x of type T, where Px holds”

∃ 1 x: T • Px Unique existence:

“there exists a unique x of type T, such that Px holds”

== (∃ x: T.• Px ∧ ¬(∃ y: T | x Î y • Py ))

S[new / old,…] schema renaming S \ (x1, x2,… xn) schema hiding

Page 22: Johannes Kepler University Linz, Austria Handbook: …ssw.jku.at/Teaching/Lectures/SpezialLVA/Lightfoot/2011/Handbook.pdf · Department of Computing Johannes Kepler University Linz,

22

S ¡ (x1, x2,… xn) schema projection

pre S precondition of S

S T schema composition: S, then T

Relations

X × Y the set of ordered pairs of X’s and Y’s X ↔ Y the set of relations from X to Y: == P(X × Y)

x R y x is related by R to y: == (x, y) ∈ R x å y == (x, y)

{ x1å y1, x2 å y2,…, xn åyn}

== the relation { ( x1, y1), (x2, y2), …, (xn, yn) }

relating x1 to y1, x2 to y2, …, xn to yn

dom R the domain of a relation

== {x: X | (∃ y: Y . x R y) • x}

ran R the range of a relation

== {y: Y | (∃ x: X . x R y) • y}

R · S ‚ the relational image of S in R

S r R the relation R domain restricted to S

R t S the relation R range restricted to S

S y R the relation R domain anti-restricted to S

R u S the relation R range anti-restricted to S

R ; Q the forward composition of R with Q Q ° R the backward composition of Q with R

R+ the repeated self-composition of R

R* the repeated self-composition of R

== R+ ∪ id X id X {x: X • x å x}

R~ the inverse of R

Functions

X ß Y the set of partial functions from X to Y:

== { f: X ↔Y | ( ∀ x: X | x ∈ dom f.• ( ∃ 1 y: Y • x f y))}

X → Y the set of total functions from X to Y: == { f: X ßY | dom f = X • f}

f x or f(x) the function f applied to x

Page 23: Johannes Kepler University Linz, Austria Handbook: …ssw.jku.at/Teaching/Lectures/SpezialLVA/Lightfoot/2011/Handbook.pdf · Department of Computing Johannes Kepler University Linz,

23

f ⊕ g functional overriding == (dom g y f ) ∪ g

Sequences

seq X the set of sequences whose elements are

drawn from X == {S: N ß X | dom S = 1 .. #S}

seq1 X set of non-empty sequences

iseq X set of injective sequences (no duplicates)

#S the length of the sequence S

⟨ ⟩ the empty sequence { } ⟨ x1, … xn ⟩ == { 1 å x1, …, n å xn}

⟨ x1, … xn ⟩ ^ ⟨ y1, … yn ⟩

concatenation: == ⟨ x1, … xn , y1, … yn ⟩

head S == S 1

last S == S #S tail ⟨ x ⟩ ^ S == S

front S ^ ⟨ x ⟩ == S

squash f the function f squashed into a sequence S ¡ s the sequence S filtered to those elements in s

== squash (S t s)

rev S the sequence S in reverse order

Page 24: Johannes Kepler University Linz, Austria Handbook: …ssw.jku.at/Teaching/Lectures/SpezialLVA/Lightfoot/2011/Handbook.pdf · Department of Computing Johannes Kepler University Linz,

24

7. Example specification in Abstract Machine Notation (‘B’) – Airport

The Abstract Machine Notation (AMN) is the basis of the ‘B’ method developed by J.-R. Abrial, who also devised Z. As you can see it more closely resembles a computer program, though it is nonetheless a specification. It is provided here as a comparison with Z. MACHINE Airport (PLANE, GATE) VARIABLES waiting, assigned INVARIANT waiting e PPLANE ¶ assigned e GATE © PLANE ¶ waiting I ran assigned = { } INITIALISATION waiting, assigned := { }, { } OPERATIONS arrive (pp) Í PRE pp e PLANE - (waiting U ran assigned) THEN waiting := waiting U{pp} END; assign (pp, gg) Í PRE pp e waiting ¶ gg ‰ dom assigned THEN assigned(gg) := pp || waiting := waiting - {pp} END; leave (pp) Í PRE pp e ran assigned THEN assigned := assigned u {pp} END; END

Page 25: Johannes Kepler University Linz, Austria Handbook: …ssw.jku.at/Teaching/Lectures/SpezialLVA/Lightfoot/2011/Handbook.pdf · Department of Computing Johannes Kepler University Linz,

25

8. Formal Specification Exercises 1 – Houses of Parliament

Introduction The Houses of Parliament (HP) consist of Members of Parliament (MPs), some of whom are in the Cabinet. There is an MP called the Prime Minister (PM) who is in the Cabinet.

Types [PERSON] the set of all persons

The state The schema HP describes the state of the Houses of Parliament:

» HP ___________ ÆMPs: PPERSON ÆCabinet: PPERSON ÆPM: PERSON «____________ ÆCabinet z MPs ÆPM e Cabinet –______________

Question 1 Does the specification state that the Prime Minister has to be a Member of Parliament? If so how?

Question 2 What would you add to the schema HP to have a Deputy Prime Minister (DPM), who is also in the Cabinet?

Operations An operation ReplacePM replaces the Prime Minister with a person newPM?. (The “?” signifies an input value.)

» ReplacePM ______ ÆDHP ÆnewPM?: PERSON «____________ ÆnewPM? e MPs ÆnewPM?Î PM ÆCabinet’ = Cabinet U {newPM?} ÆPM’ = newPM? ÆMPs’ = MPs –______________

Page 26: Johannes Kepler University Linz, Austria Handbook: …ssw.jku.at/Teaching/Lectures/SpezialLVA/Lightfoot/2011/Handbook.pdf · Department of Computing Johannes Kepler University Linz,

26

Question 3 Why does the schema include the line:

newPM? Î PM

Question 4 Does the new Prime Minister have to be chosen from the Cabinet?

Question 5 Does the outgoing Prime Minister have to leave the Cabinet?

Further operations Two operations are proposed. They are ChangeCabinet1 and ChangeCabinet2:

» ChangeCabinet1 ______ ÆDHP ÆnewCab?: PPERSON «____________ ÆnewCab? z MPs ÆCabinet’ = newCab? ÆPM’ = PM ÆMPs’ = MPs –______________

» ChangeCabinet2 ______ ÆDHP ÆnewCab?: PPERSON «____________ ÆnewCab? z MPs ÆnewCab? I Cabinet = 0 ÆCabinet’ = newCab? ÆPM’ = PM ÆMPs’ = MPs –______________

Question 6 Explain why the schema includes the line:

newCab? z MPs

Question 7 Explain the difference between the effect of ChangeCabinet1 and ChangeCabinet2.

Question 8 Explain the logical error in ChangeCabinet2.

Page 27: Johannes Kepler University Linz, Austria Handbook: …ssw.jku.at/Teaching/Lectures/SpezialLVA/Lightfoot/2011/Handbook.pdf · Department of Computing Johannes Kepler University Linz,

27

9. Formal Specification Exercises 2 – Hotel A system records the bookings of hotel rooms on one night.

Given the basic types:

[ROOM] the set of all the rooms in the hotel

[PERSON] the set of all possible persons

the state of the hotel’s bookings can be represented by the following schema:

» Hotel ____________ Æ bookedTo: ROOM ß PERSON –________________

1) Explain why bookedTo is a function.

2) Explain why the function is partial.

An initial state is:

» Init ____________ Æ Hotel «______________ Æ bookedTo = Ø –________________

and a first version of the operation to accept a booking is:

» AcceptBooking0 ____________ ÆDHotel Æp?: PERSON Ær?: ROOM «______________ Æ r? ∉ dom bookedTo Æ bookedTo' = bookedTo ∪ {r? å p?} –________________

3) Explain the meaning and purpose of each line of the schema AcceptBooking0.

4) Write a schema CancelBooking0 which cancels a booking made for a given a given room. It should deal with error conditions in the same manner as AcceptBooking0.

5) Explain the meaning and purpose of each line of your schema CancelBooking0.

Page 28: Johannes Kepler University Linz, Austria Handbook: …ssw.jku.at/Teaching/Lectures/SpezialLVA/Lightfoot/2011/Handbook.pdf · Department of Computing Johannes Kepler University Linz,

28

10. Formal Derivation of Programs – part 1 How to write programs that you know will work first time

Part 1 • Why be formal? An example with a moral. • Specification: pre-+ postconditions. • Programming rules.

Part 2 • Selections and repetitions. • Invariants and partial correctness. • Strategies for finding invariants.

Part 3 • Repetitions and arrays. • Bound functions. • Total correctness.

Part 4 • Examples.

Books • Systematic Programming N.Wirth Prentice Hall • The Science of Programming David Gries Springer-Verlag • Program Construction and Verification Roland C. Backhouse Prentice Hall • A Method of Programming EW Dijkstra + WHJ Feijen Addison Wesley

Introduction Very often even experienced programmers make small mistakes when writing programs. Unfortunately, small mistakes often have major consequences. In most branches of engineering there are mathematical techniques which allow the engineer to calculate whether the design is adequate. Such techniques are now available for software engineering. They are based on simple mathematics (much simpler that the mathematics needed for structural engineering). These notes offer an introduction to these techniques. No specific mathematical knowledge is expected, other than familiarity with simple Boolean algebra and school-level algebra.

Exercise: DivMod Write a program (fragment) which sets q to the quotient and r to the remainder of x divided by y, all integers. Do not use DIV, MOD or /.

Solution VAR x, y, q, r: INTEGER; … r := x; q := 0; WHILE r > y DO r := r-y; q := q+1 END

Testing x=23, y=4

results in q=5, r=3

What is wrong? How do you know?

Page 29: Johannes Kepler University Linz, Austria Handbook: …ssw.jku.at/Teaching/Lectures/SpezialLVA/Lightfoot/2011/Handbook.pdf · Department of Computing Johannes Kepler University Linz,

29

Solution r := x; q := 0; WHILE r >= y DO r := r-y; q := q+1 END

Testing x = 23, y =-2

doesn’t terminate!

What is the precondition? What (Boolean expression) must be true for the program to work?

x >= 0 & y > 0

What is the postcondition? What will be true afterwards if the program has worked?

x = q*y + r But we mean the old values of x and y so we put precondition

x= x0 & y = y0 and either set postcondition as

x0 = q*y0 + r or require that x and y do not change, so postcondition is

x = q*y + r & x = x0 & y = y0

Test again x=23, y=4 q=6, r=-1 x=q*y + r & 0<=r x=23, y=4 q=4, r=7

Postcondition So postcondition should be

x=q*y + r & 0 <= r < y & x = x0 & y = y0

Moral Decide what you are going to do before you do it. Specify, then implement.

TRUE and FALSE In a precondition TRUE means that the program will always work. That is, it works in circumstances where TRUE is true; FALSE means that the program will never work. That is, it works in circumstances where FALSE is true.

Formal specification One means of providing a formal specification for a program is to give its precondition and its postcondition:

(* pre *) Program (*post *)

Specification of DivMod (*x <= 0 & y>0*) DivMod (*x=q*y + r & 0 <= r < y & x = x0 & y = y0*)

Derivation techniques Techniques exist to derive programs that satisfy postcondition given precondition. These are well established and rely on simple mathematics. They make programming easier! Hoare 1968 Dijkstra 1973

Page 30: Johannes Kepler University Linz, Austria Handbook: …ssw.jku.at/Teaching/Lectures/SpezialLVA/Lightfoot/2011/Handbook.pdf · Department of Computing Johannes Kepler University Linz,

30

A better solution Here is a very efficient solution for the same specification:

r := x; q := 0; w := y; WHILE w <=r DO w :=SHIFT(w, 1) (*w := w *2*) END; WHILE w # y DO q := SHIFT(q, 1); w := SHIFT(w, -1); (*q := q*2; w := w DIV 2*) IF w <= r THEN r := r-w; INC(q) END END

Is this correct? How can you tell, without really understanding it? Application of the techniques presented here makes this possible.

Notation Predicate calculus Includes propositional calculus “Boolean Algebra”.

∧ & AND ∨ OR ≠ # <> ¬ ~ NOT

“Short-cut” or “McCarthy” evaluation of Boolean expressions p cand q

means if p then q else false

and p cor q

means if p then true else q

C, Modula-2, Oberon, Java, C# AND and OR are cand and cor

Ada and Eiffel and then for cand or else for cor

Pascal “implementation-dependent” For current purposes assume Pascal and, or are cand, cor.

Example In:

CONST N= (*?N>0*); VAR a: ARRAY N OF INTEGER; (* a is indexed from 0 to N-1 *) x, i: INTEGER; ... i := 0; WHILE (i # N) & (a[i]#x) DO i := i+1 END

& must be short-cut AND.

Page 31: Johannes Kepler University Linz, Austria Handbook: …ssw.jku.at/Teaching/Lectures/SpezialLVA/Lightfoot/2011/Handbook.pdf · Department of Computing Johannes Kepler University Linz,

31

Quantifiers in all examples that follow:

CONST N = (* N > 0 *); VAR a: ARRAY N OF INTEGER; (* a is indexed from 0 to N-1 *)

Universal quantifier ∀ means for all

∀ i: 0 <= i < N: a[i] = 0 all elements of a are zero

∀ i: 0 < i < N: a[i-1] <= a[i] a is in ascending order

Existential quantifier ∃ means there exists (at least one)

∃ i: 0 <= i < N: a[i] = NUL

Counting quantifier N means the number of

Ni: 0 <= i < N: a[i] = x count of x's in a

Summing quantifier Σ means the sum of

Σ i: 0 <= i < N: a[i] the sum of the elements of a

Verification Rules Assignment

(*P[varexp ]*) var := exp (*P*)

Precondition is P with all (free) occurrences of var replaced by exp. Example: precondition of program

y := x + 1 having postcondition

y = 3 is

x + 1 = 3, that is, x = 2 Example: precondition of program

y := 4 having postcondition

y = 5 is

4 = 5, that is, FALSE

Compound (*P*) S1 (*Q*) if we can prove (*Q*) S2 (*R*) and we can prove ___________ (*P*) S1; S2 (*R*) then it follows

If doing S1 when P is true makes Q true and doing S2 when Q is true makes R true, then doing S1; S2 when P is true makes R true.

Conditional (*P & B*) S1 (*Q*) P & ¬ B => Q ___________ (*P*) IF B THEN S1 END (*Q*)

Page 32: Johannes Kepler University Linz, Austria Handbook: …ssw.jku.at/Teaching/Lectures/SpezialLVA/Lightfoot/2011/Handbook.pdf · Department of Computing Johannes Kepler University Linz,

32

If doing S1 when P is true and B is true makes Q true and doing nothing when P is true and B is false makes Q true, then doing IF B THEN S1 END when P is true makes Q true.

Selection (*P & B*) S1 (*Q*) (*P & ¬ B*) S2 (*Q*) ___________ (*P*) IF B THEN S1 ELSE S2 END (*Q*)

If doing S1 when P is true and B is true makes Q true and doing S2 when P is true and B is false makes Q true, then doing IF B THEN S1 ELSE S2 END when P is true makes Q true.

Multiple selection (*P & (i in LLk)*) SSk (*Q*) for all k ___________ (*P*) CASE i OF LL1: S1 | LL2: S2 | … LLn: Sn END (*Q*)

If doing SSk when P is true and i is in the case label list LLk makes Q true, for all values of k, then doing the case statement above when P is true will make Q true.

Repetitive (*P & B*) S (*P*) __________ (*P*) WHILE B DO S END (*P & ¬B*)

If doing S when P is true and B is true makes P true again, then doing WHILE B DO S END will make P true and B false (if it terminates).

(*P*) S (*Q*) (*Q & ¬B*) S (*Q*) __________ (*P*) REPEAT S UNTIL B (*Q & B*)

If doing S when P is true makes Q true and doing S when Q is true and B is false makes Q true then doing REPEAT S UNTIL B makes Q and B true (if it terminates).

Page 33: Johannes Kepler University Linz, Austria Handbook: …ssw.jku.at/Teaching/Lectures/SpezialLVA/Lightfoot/2011/Handbook.pdf · Department of Computing Johannes Kepler University Linz,

33

11. Formal Derivation of Programs – part 2: Selection and repetition

Selection We can use the selection rule to derive a program: For example: Max

(* TRUE *) Max (* (z = x & x >= y) OR ( z = y & x <= y) *) Suppose we suspect that the program

z := x will sometimes do it but are not sure when; let’s find the precondition for this:

(* pre *) z := x (* (z = x & x >= y) OR ( z = y & x >= y) *)

Using the assignment rule gives pre: (x = x & x >= y) OR ( x = y & x _ y)

which simplifies to (x >= y) OR ( x = y)

which simplifies to (x >= y)

so (* x >= y *) z := x (* (z = x & x >= y) OR ( z = y & x <= y) *)

Similarly we can discover (* x <= y *) z := y (* (z = x & x >= y) OR ( z = y & x <= y) *)

The selection rule If we can show that

(* P & B *) S1 (* Q *) and we can show that

(* P & ~B*) S2 (*Q *) then it follows that

(* P *) IF B THEN S1 ELSE S2 END (* Q *)

Back to the example In this case it will be OK to use

~(x >= y) as the precondition of

z :=y if we have covered the x = y case with z := x ; so

P = TRUE and

B = (x >= y)

Page 34: Johannes Kepler University Linz, Austria Handbook: …ssw.jku.at/Teaching/Lectures/SpezialLVA/Lightfoot/2011/Handbook.pdf · Department of Computing Johannes Kepler University Linz,

34

The derived program (* TRUE *) IF x >= y THEN (* x >= y *) z := x ELSE (* ~x >= y *) z := y END (* (z = x & x >= y) OR ( z = y & x <= y) *)

Further example The program Abs is specified as:

(* x = x0 *) Abs (* (x0 >=0 & x = x0) OR (x0 < 0& x = -x0) *)

We can show that setting x := -x satisfies postcondition if x < y and that doing nothing implies postcondition if x >= 0 , using other rule:

(*P & ~B => Q *) and

(* P & B *) S (* Q *) with

P = TRUE and

B = x < y we can derive

(* x = x0 *) IF x < 0 THEN x := -x END (* (x >= 0 & x = x0) OR (x < 0 & x = -x0) *)

A very useful example A procedure is required to read an integer by accepting digits from the input and must not result in integer overflow. It will need to contain a selection of the form:

IF xWillRemainInRange THEN (* xWillRemainInRange *) x := x*10 + ORD(ch) - ORD(‘0’) (* x <= MAX(INTEGER) *) ELSE (* ~xWillRemainInRange *) overflow := TRUE END

What is the condition xWillRemainInRange? Calculate the precondition of

x := x*10 + ORD(ch) - ORD(‘0’) (* x <= MAX(INTEGER) *)

Using the assignment rule gives x*10 + ORD(ch) - ORD(‘0’) <= MAX(INTEGER)

which can be rearranged to give x*10 <= MAX(INTEGER) - ORD(ch) + ORD(‘0’)

which gives x <= (MAX(INTEGER) - ORD(ch) + ORD(‘0’)) DIV 10

Resulting program

IF x <= (MAX(INTEGER) - ORD(ch) + ORD(‘0’)) DIV 10 THEN (* xWillRemainInRange *) x := x*10 + ORD(ch) - ORD(‘0’) (* x <= MAX(INTEGER) *) ELSE (* ~xWillRemainInRange *)

Page 35: Johannes Kepler University Linz, Austria Handbook: …ssw.jku.at/Teaching/Lectures/SpezialLVA/Lightfoot/2011/Handbook.pdf · Department of Computing Johannes Kepler University Linz,

35

overflow := TRUE END

Repetition Let’s consider a very simple example: to write “Hello” n times, where n >= 0

(* n >= 0 *) WriteHellos (* “Hello” has been written n times *)

This clearly needs a repetition. We can write “Hello” once then twice until we reach n. If we use a variable i as a counter then each time round the repetition we will have written i “Hello”s. This is called the repetition invariant:. It is true before the repetition starts, before its body, after its body and after it finishes. After the repetition, the invariant and the negation of the continuation condition must imply the postcondition.:

Rule for repetition (* pre *) initialisation (* invariant *) WHILE guard DO (* invariant & guard *) body (* invariant *) END (* invariant & ~guard => post*)

Back to the example If invariant is “i Hellos written” and at the start no “Hellos” have been written then we derive the fact that i must be initially zero:

(* n >= 0 *) i := 0; (* i Hellos written *)

We can further derive that the negation of the continuation condition must be i = n

since i "hellos" written & i = n implies n hellos written

If the negation of the continuation condition is i = n

then the continuation condition must be ~(i = n)

or i # n

Thus we derive WHILE i # n DO (* inv & i # n body (* inv *)

Clearly we make progress in the repetition by writing one “Hello”: (* inv & i # n*) WriteString(“Hello”) (* i+1 Hellos written *)

To restore the invariant we must replace the value of i by i plus 1, so the body becomes: (* inv & i # n*) WriteString(“Hello”) (* i+1 Hellos written *) i := i + 1 (* i Hellos written *)

Page 36: Johannes Kepler University Linz, Austria Handbook: …ssw.jku.at/Teaching/Lectures/SpezialLVA/Lightfoot/2011/Handbook.pdf · Department of Computing Johannes Kepler University Linz,

36

The program at last (* pre: n >= 0*) i := 0; (* inv *) WHILE i # n DO (* inv & i # n *) WriteString(“Hello”); i := i + 1 (* inv *) END; (* inv & i = n => post: “n Hellos written” *)

This program is correct (partially) The program has been derived from its specification and thus is correct. Actually only its partial correctness has been established, since we have not show that the repetition terminates. It does actually, but we’ll deal with that properly later.

Finding an invariant Finding a suitable invariant is the hard part of programming. You use your skill and judgement. There are however some strategies:

Strategy for finding invariant – replace a constant by a variable In this example we replaced the constant n in the postcondition, by the variable i to make the invariant, and used

i =n as the negation of the continuation condition so that

i = n and the invariant would imply the postcondition.

Another example The program DivMod is specified as:

(* x >= 0 & y > 0 *) DivMod (* x = q*y + r & 0 <= r < y *)

A suitable invariant for the repetition is (* x = q*y + r & 0 <= r *)

Note that the r < y

part has been omitted from the postcondition to give the invariant.

Initialisation Setting

r := x; q := 0; makes the invariant true.

Continuation After the repetition, the invariant and r < y must imply the postcondition; so the continuation condition is

~ (r < y) or

r >= y Thus we get

WHILE r >= y DO

The body The body of the repetition must reduce r, so that eventually it will be less than y, while maintaining the invariant.. This can be done by

(* inv & r >= y *) r := r-y; q := q+1 (* inv *)

The proof of this is one of the exercises.

Page 37: Johannes Kepler University Linz, Austria Handbook: …ssw.jku.at/Teaching/Lectures/SpezialLVA/Lightfoot/2011/Handbook.pdf · Department of Computing Johannes Kepler University Linz,

37

The program (* pre: x >= 0 & y > 0 *) r := x; q := q+1 (* inv: x = q*y + r & 0 <= r *) WHILE r >= y DO (* inv & r <= y*) r := r-y; q := q+1 (* inv *) END; (* inv & ~ (r >= y) => post: x = q*y + r & 0 <= r < y *)

Partial correctness This program has been derived from its specification, by deriving a repetition invariant from its postcondition and its partial correctness has been established

Strategies for finding invariants – delete a conjunct The AND (&) operation is called conjunction and in an expression of the form

A AND B A and B are conjuncts. The strategy used to obtain the invariant from the postcondition in this example was to delete a conjunct from the postcondition, in this case

r < y

What is still to do So far we have not considered examples using arrays. Furthermore we have not dealt with showing that repetitions terminate and thus are totally correct.

Page 38: Johannes Kepler University Linz, Austria Handbook: …ssw.jku.at/Teaching/Lectures/SpezialLVA/Lightfoot/2011/Handbook.pdf · Department of Computing Johannes Kepler University Linz,

38

12. Formal Derivation of Programs – part 3: Bound functions, arrays

DayInYear Given a valid date in the form day, month, year and a function dm(month, year) which delivers the number of days in a valid month of a valid year, set dInY to the day-in-year of day, month, year. (Assume all years valid). (day in year of 1, 1, 1992 is 1, of 31,12,1992 is 366).

Specification of dm (This is a function heading in Modula-2 or Oberon)

(* pre: 1 <= month <= 12 *) PROCEDURE dm (month, year: INTEGER): INTEGER; (* dm(month, year) = "number of days in that month of that year" *)

Specification of DayInYear (* day, month, year designate a valid date *) DayInYear (* dInY = "position of date day, month, year in year *)

Alternative Specification of DayInYear (* day, month, year designate a valid date *) DayInYear (* dInY = day + sum of days in months before month *)

or (* 1 <= month <= 12 & 1 <= day <= dm(month, year) *) DayInYear (* dInY = day + Σj: 1 <= j <= month -1. dm(j, year) *)

Finding an invariant Clearly, this cannot be done in one statement; we need a repetition. What shall be its invariant?

Strategy replace constant month by variable m.. Then use

m = month as terminating condition, hence

m # month as continuation condition.

Invariant dInY = day + Σj: 1 <= j <= m -1. dm(j, year)

Initialisation m := 1; dInY := day;

Check that this satisfies the invariant

Continuation condition WHILE m # month DO

Body We need to add the days in the month m to dInY, then increase m by 1:

dInY := dInY + dm(m, year); m := m+1 Check that this satisfies the invariant.

Page 39: Johannes Kepler University Linz, Austria Handbook: …ssw.jku.at/Teaching/Lectures/SpezialLVA/Lightfoot/2011/Handbook.pdf · Department of Computing Johannes Kepler University Linz,

39

Resulting program (* 1 <= month <= 12 & 1 <= day <= dm(month, year) *) m := 1; dInY := day; (* inv: dInY = day + Σj: 1 <= j <= m -1. dm(j, year) WHILE m # month DO (* inv & m # month *) dInY := dInY + dm(m, year); m := m+1 (* inv *) END (* dInY = day + Σj: 1 <= j <= month -1. dm(j, year) *)

Exercise Does dm ever get called when its precondition is not satisfied? Need to include precondition in invariant.

Strictly invariant is 1 <= month <= 12 & 1 <= day <= dm(month, year) & dInY = day + Σj: 1 <= j <= m -1. dm(j, year)

Bound function The proof of the full correctness of a program which involves a repetition requires that the repetition be proved to terminate. This is done by discovering a bound function, or bound: a function of the variables which is initially non-negative, and which is strictly reduced by each iteration of the repetition.

Example A bound function for the program WriteHellos is n - i

WriteHellos with full proof (* pre: n >= 0*) i := 0; (* inv & n - i >= 0 *) WHILE i # n DO (* inv & bound = n - i & i # n *) WriteString(“Hello”); i := i + 1 (* inv & n - i < bound*) END; (* inv & i = n => post: “n Hellos written” *)

Example A bound function for the program DivMod is r:

DivMod with full proof (* pre: x >= 0 & y > 0 *) r := x; q := 0; (* inv: x = q*y + r & 0 <= r & bound = r >= 0*) WHILE r >= y DO (* inv & bound = r & r >= y*) r := r-y; q := q+1 (* inv & 0 <= r < bound*) END; (* inv & ~(r >= y) => post: x = q*y + r & 0 <= r < y *)

Arrays When using arrays there is an extra precondition that any access to the array must be within range. That is, if the array is declared:

VAR a: ARRAY[m..n] OF T; then any access

a[exp] must have a value of exp such that

m <= exp <= n

Page 40: Johannes Kepler University Linz, Austria Handbook: …ssw.jku.at/Teaching/Lectures/SpezialLVA/Lightfoot/2011/Handbook.pdf · Department of Computing Johannes Kepler University Linz,

40

Note: Most languages impose the syntactic restriction: m <= n

Most language implementations provide run-time checking that array accesses are within bounds.

Oberon In Oberon arrays are declared

VAR a: ARRAY N OF T where

N > 0 and the value of exp must be

0 <= exp < N

Specifications with arrays The universal and existential quantifiers are useful when specifying programs with arrays.

Example VAR a: ARRAY N OF T; (* pre: TRUE *) SetAllToZero (* post: ∀ j: 0 <= j < N. a[j] = 0 *)

∀ is universal quantifier – “for all”

Example VAR a: ARRAY N OF T; (* pre: ∃ j: 0 <= j < N. a[j] = x *) SetKToPosOfAnX (* post: 0 <= k < N & a[k] = x *)

Example VAR a: ARRAY N OF T; (* pre: ∃ j: 0 <= j < N. a[j] = x *) SetKToPosOfFirstX (* post: 0 <= k < N & a[k] = x & ∀ j: 0 <= j < k . a[j] # x *)

Programs with arrays Example – SetAllToZero

VAR a: ARRAY N OF T; (* pre: TRUE *) SetAllToZero (* post: ∀ j: 0 <= j < N. a[j] = 0 *)

Invariant ∀ j: 0 <= j < i <= N. a[j] = 0

Strategy – replace constant by variable Bound

N - i Initialisation

i := 0 Body

a[i] := 0; i := i+1

Program – SetAllToZero VAR a: ARRAY N OF T; (* pre: TRUE *) i := 0; (* inv: ∀ j: 0 <= j < i <= N. a[j] = 0 & bound = N - i *) WHILE i # N DO (* inv & i # N & bound = N - i *) a[i] := 0; i := i+1 (* inv & N - i < bound *) END

Page 41: Johannes Kepler University Linz, Austria Handbook: …ssw.jku.at/Teaching/Lectures/SpezialLVA/Lightfoot/2011/Handbook.pdf · Department of Computing Johannes Kepler University Linz,

41

(* inv & i = N => post: ∀ j: 0 <= j < N. a[j] = 0 *)

Example – SetKTOPosOfFirst VAR a: ARRAY N OF T; (* pre: ∃ j: 0 <= j < N. a[j] = x *) SetKToPosOfFirstX (* post: 0 <= k < N & a[k] = x & ∀ j: 0 <= j < k . a[j] # x *)

Invariant ∃ j: 0 <= j < N. a[j] = x & 0 <= k < N & ∀ j: 0 <= j < k . a[j] # x

Bound N - k

Strategy – delete conjunct a[k] = x

Initialisation k:= 0

Program – SetKToPosOfFirstX VAR a: ARRAY N OF T; (* pre: ∃ j: 0 <= j < N. a[j] = x *) k := 0; (* inv: ∃ j: 0 <= j < N. a[j] = x & 0 <= k < N & ∀ j: 0 <= j < k . a[j] # x & bound = N - k *) WHILE a[k] # x DO (* inv & a[k] # x & bound = N - k *) k := k + 1 (* inv & N - k < bound *) END (* inv & a[k] = x => post: 0 <= k < N & a[k] = x & ∀ j: 0 <= j < k . a[j] # x *)

Note – sentinel search This linear search technique depends on there being at least one x in a. It is so simple that it is often worth extending the array by one element

VAR a: ARRAY N+1 OF T; and setting

a[N+1] := x at the start. Then you are sure to find x. If afterwards

k = N+1 then you didn’t really find it.

Summary Use of these techniques can improve the correctness of your programs and significantly reduce the time spent on debugging. For safety-critical software their use is obligatory. Naturally it takes time and practice to become proficient in their use – keep doing the exercises and ask for help if you need it. Even if you don’t subsequently apply the techniques to all your programming, you will have learned some useful ideas concerned with reasoning about programs.

Page 42: Johannes Kepler University Linz, Austria Handbook: …ssw.jku.at/Teaching/Lectures/SpezialLVA/Lightfoot/2011/Handbook.pdf · Department of Computing Johannes Kepler University Linz,

42

13. Exercises for Formal Derivation of Programs Part 1

Show all your working.

a Specifications Give a specification in the form

(* pre *) ProgramName (* post *) for each of the following (assume all variables integer): a1. Program ZisXPlus1: sets z to one more than the value of x. a2.. Program SafeZisXPlus1: sets z to one more than value of x, only when x is less than the largest integer – MAX(INTEGER). a3. Program Max: sets z to larger of x and y (whole numbers). a4. Program Sqrt: sets z to square-root of x (real numbers). (Do not use √) a5. Program IntSqrt: sets z to “integer square-root” of x, that is, the largest integer which does not exceed √x.

b Calculating preconditions – assignment For each of the following, give the (simplest) precondition (pre) for the program to achieve its postcondition. b1. (* pre *) x := x + 1 (* x = 4 *) b2. (* pre *) z := 3 (* z = 4 *) b3. (* pre *) z := 4 (* z = 4 *) b4. (* pre *) r := r - y (* x = q*y + r *) b5. (* pre *) z := x*10 + ORD(ch) - ORD(‘0’) (* z <= MAX(INTEGER) *)

c Calculating preconditions – assignment and composition For each of the following, give the (simplest) precondition (pre) for the program to achieve its postcondition. c1. (* pre *) y := x + 1; z := y + 3 (* z = 4 *) c2. (* pre *) t := x; x := y; y := t (* x = y0 & y = x0 *) c3. (* pre *) x := x+y; y := x-y; x := x-y (* x = y0 & y = x0 *) c4. (* pre *) r := r-y (* x = q*y + r & r >= 0 *) c5. (* pre *) q := q+1; r := r-y (* x = q*y + r & r >= 0 *)

Page 43: Johannes Kepler University Linz, Austria Handbook: …ssw.jku.at/Teaching/Lectures/SpezialLVA/Lightfoot/2011/Handbook.pdf · Department of Computing Johannes Kepler University Linz,

43

14. Exercises for Formal Derivation of Programs Part 2

Show all your working.

d Selection In the program:

(* x <= 0 *) IF (a > 7) & (z <= p) THEN (* P1 *) S1 ELSE (* P2 *) S2 END

d1. What is P1? d2 What is P2? In the program

(* TRUE *) IF (x # 2) OR (x # 6) THEN (* P1 *) S1 ELSE (*P2*) S2 END

d3. What is P1? d4. What is P2? In the program:

(* 0 <= x <= 100 *) IF x < 40 THEN S1 ELSIF x < 60 THEN S2 ELSIF x < 70 THEN (*R*) S3 ELSE S4 END

d5 What is R?

e Repetition On a computer with no multiply instruction, multiplication is to be emulated by repeated addition. A program sets y to z*n, where n >= 0. e1. Give the specification of this program. e2. Find an invariant for the repetition and state the strategy used to find it. e3. Give initialisation statements. e4. Give the continuation condition for a while repetition. e5. Give the body of the repetition and show that it maintains the invariant.

f Repetition again f1. Prove that

(* x>= 0 & y>0 *) r :=x; q := 0 (* x = q*y + r & 0 <= r*) A program containing the declaration

VAR x, n: INTEGER; is required to set z to x to the power of n (n >= 0) The program can change the values of x and n, so explicit names are included in the precondition for their initial values. The precondition is

x = x0 & n = n0 & n >= 0 The postcondition is: z = x0^n0 A suitable repetition invariant is

z * x^n = x0^n0 f2. Give an initialisation which will establish the invariant, given the precondition. f3. What condition Q must be true as well as the invariant, to imply the postcondition? f4 Give the continuation condition of the (while) repetition. f5. Give the body of the repetition and prove that it maintains the invariant.

Page 44: Johannes Kepler University Linz, Austria Handbook: …ssw.jku.at/Teaching/Lectures/SpezialLVA/Lightfoot/2011/Handbook.pdf · Department of Computing Johannes Kepler University Linz,

44

15. Exercises for Formal Derivation of Programs Part 3

Show all your working.

g Dates Devise an inverse to the program DayInYear, called DayInYearToDate. Given a valid day-in-year and year, discover that date. g1. Specification g2 Invariant and strategy g3 Continuation condition g4 Body g5 Bound

h Bounds Find bound functions for and fully annotate, the programs of h1. exercise e h2. exercise f

i Binary search A rival has written this program to perform a binary search. Criticise it on grounds of correctness. Apply the techniques of this part of the module where you can.

VAR a: ARRAY [1..N] OF T; (* N>=1 *) x: T; L, R, m, k: INTEGER; (* pre: ascending(a) *) L := 1; R := N; WHILE L < R DO m := (L+R) DIV 2; IF a[m] < x THEN L := m ELSE R := m END END; IF x = a[m] THEN k := m ELSE k := 0 END (* post: (1 <= k <= N & a[k] = x) OR (k = 0 & ∀ j: 1<= j <= N. a[j] # x) *)

Note: ascending(a): ∀ j: 2 <= j <= N. a[j-1] <= a[j]

Hint 1 (* pre: L < R *) m := (L+R) DIV 2 (* post ? *)

Hint 2 Consider case where

L = p (some arbitrary p) and

R = p+1 and for these values

a[m] < x

Page 45: Johannes Kepler University Linz, Austria Handbook: …ssw.jku.at/Teaching/Lectures/SpezialLVA/Lightfoot/2011/Handbook.pdf · Department of Computing Johannes Kepler University Linz,

45

16. Formal Derivation: Larger Exercise 1 Task Derive a program hand-in-hand with developing a proof of its (total) correctness for the following, informal specification, using the techniques presented on this module. Present the program in a suitable notation (Oberon, Modula-2, Pascal) with the proof as annotations (in comments) in a clear, unambiguous notation – be as formal as you feel able.

Particular requirements You answer should include statements of all of the following: • The variable declarations of the program. • The precondition of the program. • The postcondition of the program • The invariant of the repetition. • Strategy used to obtain the invariant. • Initialisation statements, which establish invariant. • Condition for continuation of repetition. • Body of repetition, showing that it maintains the invariant. • The bound function of the repetition.

Informal specification An array a consists of N integers ( N >= 1 ), indexed from 0 to N-1 and you may assume that some values have somehow been given to all the elements of a. The program should set the values of two integer variables, high and low, to the highest and lowest values respectively, found in the array a.

Hints • What is value of the largest (smallest) of no numbers? • It is easiest to use a while statement for the repetition. • A useful formulation for annotations is:

“high is largest value in a[m..n]” meaning “high is the largest value in the array a from positions m to n inclusive”.

(0 <= m <= n < N & ∀ j: m <= j <= n . high >= a[j])

Page 46: Johannes Kepler University Linz, Austria Handbook: …ssw.jku.at/Teaching/Lectures/SpezialLVA/Lightfoot/2011/Handbook.pdf · Department of Computing Johannes Kepler University Linz,

46

17. Formal Derivation: Larger Exercise 2 Task Derive a program hand-in-hand with developing a proof of its (total) correctness for the following, informal specification, using the techniques presented on this module. Present the program in a suitable notation (Oberon, Modula-2, Pascal) with the proof as annotations (in comments) in a clear, unambiguous notation – be as formal as you feel able.

Particular requirements You answer should include statements of all of the following: • The variable declarations of the program. • The precondition of the program. • The postcondition of the program. • The invariant of the repetition. • Strategy used to obtain the invariant. • Initialisation statements, which establish invariant. • Condition for continuation of repetition. • Body of repetition, showing that it maintains the invariant. • The bound function of the repetition.

Informal specification An array a, declared:

CONST N = ?? (* N > 0 *); VAR a: ARRAY [1..N] OF INTEGER; ascends: BOOLEAN;

is said to be ascending if Ascending(a, 1, N) holds, where: Ascending(a, m, n) = (1 <= m <= n <= N & ∀ j: m <= j <= n-1: a[j] <= a[j+1])

The program should assign the value TRUE to ascends if the array a is ascending, otherwise FALSE.

Hints Include your explanation of what Ascending means in your documentation. It is easiest to use a while statement for the repetition.

Page 47: Johannes Kepler University Linz, Austria Handbook: …ssw.jku.at/Teaching/Lectures/SpezialLVA/Lightfoot/2011/Handbook.pdf · Department of Computing Johannes Kepler University Linz,

47

18. Formal Derivation Examination Questions 1) a) Explain what is meant by the partial correctness of a program fragment containing a repetition. 5 marks A procedure Length finds the length of a string held in an array. The characters of the string are followed immediately by one nul character (designated 0X). The length of the array s is given by LEN(s):

PROCEDURE Length(s: ARRAY OF CHAR): INTEGER; CONST nul = 0X; VAR i: INTEGER; BEGIN i := 0; WHILE s[i] # nul DO i := i+1 END; RETURN i END Length;

The invariant for the repetition, inv, is: ∃ k: 0 <= k < LEN(s): s[k] = nul & ∀ j: 0 <= j < i <= LEN(s): s[j] # nul

b) Explain what the invariant means. 7 marks c) State the precondition for the procedure Length, both in English and formally. 6 marks d) State the postcondition of the procedure Length, both in English and formally. 8 marks e) Annotate the body of the procedure Length, to prove its partial correctness. 7 marks total 33 marks 2) a) Explain the difference between testing a program and deriving it formally hand in hand with proving it correct. 6 marks The program fragment below takes a randomly generated number x and obtains the number rn, which must finally lie in the range

0.1 <= rn < 1.0 Fragment:

rn := x; REPEAT rn := rn / 10.0 UNTIL rn < 1.0

b) Give a general rule for rewriting repetitions using the repeat statement as repetitions using the while statement. 5 marks c) Rewrite the fragment using a while repetition so that it has identical effect. 6 marks d) Given the repetition invariant, inv:

0.1 <= rn & ∃ k: 0 <= k : rn ∗ 10k = x state the precondition pre which must hold if the postcondition, post is

inv & 0.1 <= rn < 1.0 8 marks e) Using rn as a bound, state under what circumstances the repetition terminates. 8 marks 33 marks