composite objects learning outcomes at the end of this lecture you should be able to: identify when...

32
Composite Objects Learning Outcomes At the end of this lecture you should be able to: Identify when it is appropriate to use a composite object type Use the composite object operators (make, selection and mu) Add an invariant to a composite object type Use the composite object type to help model systems in VDM-SL Use a let…in clause to simplify expressions in VDM-SL

Upload: bartholomew-chad-hill

Post on 05-Jan-2016

212 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Composite Objects Learning Outcomes At the end of this lecture you should be able to: Identify when it is appropriate to use a composite object type Use

Composite Objects

Learning Outcomes

At the end of this lecture you should be able to:

• Identify when it is appropriate to use a composite object type

• Use the composite object operators (make, selection and mu)

• Add an invariant to a composite object type

• Use the composite object type to help model systems in VDM-SL

• Use a let…in clause to simplify expressions in VDM-SL

Page 2: Composite Objects Learning Outcomes At the end of this lecture you should be able to: Identify when it is appropriate to use a composite object type Use

Composite Types

So far, we have always associated a single type with each item of data in our VDM specifications.

temp: robot: Status permission: Aircraft-set

There will be occasions, however, when you need to associate more than one type with an object.

We call such a type a composite object type in VDM-SL.

Page 3: Composite Objects Learning Outcomes At the end of this lecture you should be able to: Identify when it is appropriate to use a composite object type Use

Defining Composite Object Types

To define a type to be composite we use a composite type definition.

TypeName :: fieldname1

fieldname2

:

: Type1

: Type2

Page 4: Composite Objects Learning Outcomes At the end of this lecture you should be able to: Identify when it is appropriate to use a composite object type Use

The Time Type

Assume that a time value consists of an hour, minute and second value. We can define the following type:

This Time type can now be used like any other type in your specification

Time :: hour

minute

second

: : :

importantTimes: Time-set

Page 5: Composite Objects Learning Outcomes At the end of this lecture you should be able to: Identify when it is appropriate to use a composite object type Use

The make function

The most important composite object operator is the make function that creates a new object of a given composite type.

mk-CompositeObjectTypeName (parameter list)

Returning to the Time example:

someTime = mk-Time ( )

16, 20, 44

Page 6: Composite Objects Learning Outcomes At the end of this lecture you should be able to: Identify when it is appropriate to use a composite object type Use

Adding invariants to composite objects

Not all combinations of hour/minute/time are valid. For example:

strangeTime = mk-Time (36, 20, 44)

Solution? add an invariant to the type definition:

Time:: hour: minute: second:

inv mk-Time (h, m, s) h < 24 m < 60 s < 60

Page 7: Composite Objects Learning Outcomes At the end of this lecture you should be able to: Identify when it is appropriate to use a composite object type Use

Composite object selectors

We can refer to a particular field of a composite object by using a selector operator.

Individual fields are selected by the dot operator '.' followed by the name of a field.

For example:

someTime.minute = 20

someTime.hour = 16

Page 8: Composite Objects Learning Outcomes At the end of this lecture you should be able to: Identify when it is appropriate to use a composite object type Use

The mu function

The mu function returns one composite object from another but with one or more fields changed.

For example, to change the hour of a particular time we may use the function as follows:

newTime = (someTime, hour 15)

More than one field may be changed in a mu function. For example

thisTime = (someTime, minute 0, second 0)

Page 9: Composite Objects Learning Outcomes At the end of this lecture you should be able to: Identify when it is appropriate to use a composite object type Use

The DiskScanner class

DiskScanner

damagedBlocks: Block [*]

addBlock(Integer, Integer)

removeBlock (Integer, Integer)

isDamaged(Integer, Integer): Boolean

getBadSectors(Integer): Integer [*]

Page 10: Composite Objects Learning Outcomes At the end of this lecture you should be able to: Identify when it is appropriate to use a composite object type Use

Analysing the Block type further

A block consists of a track and a sector number.

Block

track: Integersector: Integer

Page 11: Composite Objects Learning Outcomes At the end of this lecture you should be able to: Identify when it is appropriate to use a composite object type Use

Specifying the data model in VDM-SL

types

state DiskScanner ofdamagedBlocks:

init mk-DiskScanner (dB)

end

Block : : track: sector:

Block-set

dB = { }

Page 12: Composite Objects Learning Outcomes At the end of this lecture you should be able to: Identify when it is appropriate to use a composite object type Use

addBlock ( )

ext

pre

post

The addBlock operation

trackIn: , sectorIn:

damagedBlocks: Block-setwr

cksdamagedBlodamagedBlocks = { mk-Block (trackIn, sectorIn)}

mk-Block (trackIn, sectorIn) damagedBlocks

Page 13: Composite Objects Learning Outcomes At the end of this lecture you should be able to: Identify when it is appropriate to use a composite object type Use

removeBlock ( )

ext

pre

post

The removeBlock operation

trackIn: , sectorIn:

damagedBlocks: Block-setwr

cksdamagedBlodamagedBlocks = \ { mk-Block (trackIn, sectorIn)}

mk-Block (trackIn, sectorIn) damagedBlocks

Page 14: Composite Objects Learning Outcomes At the end of this lecture you should be able to: Identify when it is appropriate to use a composite object type Use

isDamaged ( )

ext

pre

post

The isDamaged operation

trackIn: , sectorIn: query:

damagedBlocks: Block-setrd

query

mk-Block (trackIn, sectorIn) damagedBlocks

TRUE

Page 15: Composite Objects Learning Outcomes At the end of this lecture you should be able to: Identify when it is appropriate to use a composite object type Use

getBadSectors ( )

ext

pre

post

The getBadSectors operation

trackIn: list: -set

damagedBlocks: Block-setrd

list = { | }

? ?

?

b damagedBlocks

b.track = trackInb.sector

TRUE

Page 16: Composite Objects Learning Outcomes At the end of this lecture you should be able to: Identify when it is appropriate to use a composite object type Use

A process management system

blockwakeup

timeout

dispatchterminateadmit

new ready terminatedrunning

blocked

Page 17: Composite Objects Learning Outcomes At the end of this lecture you should be able to: Identify when it is appropriate to use a composite object type Use

The ProcessManagement class

ProcessManagament

running: String

waiting: Process[*]

admit(String)

dispatch()

timeOut()

block()

wakeUp(String)

terminate()

Page 18: Composite Objects Learning Outcomes At the end of this lecture you should be able to: Identify when it is appropriate to use a composite object type Use

Analysing the types

Process

id: Stringstatus: Status

A process consists of an id and status

<<enumeration>>Status

READYBLOCKED

The status of a process is either ready or blocked.

Page 19: Composite Objects Learning Outcomes At the end of this lecture you should be able to: Identify when it is appropriate to use a composite object type Use

Specifying the types in VDM-SL

types

String = Char*

= <READY> | <BLOCKED>Status

Process :: id : Stringstatus : Status

Page 20: Composite Objects Learning Outcomes At the end of this lecture you should be able to: Identify when it is appropriate to use a composite object type Use

Specifying the state in VDM-SL

state ProcessManagement ofrunningwaiting

inv mk-ProcessManagement (run, wait) ( )

( )

init mk-ProcessManagement (run, wait) end

: [String]: Process*

run = nil wait = [ ]

run = nili inds wait wait(i).id = run no waiting id should match the running id

i,j inds wait i j wait(i).id wait(j).idthe ids in the waiting queue should be unique

Page 21: Composite Objects Learning Outcomes At the end of this lecture you should be able to: Identify when it is appropriate to use a composite object type Use

Specifying a findPos function

findPos(qIn : Process*, idIn : String) pos :

pre p elems qIn p.id = idIn

post qIn(pos).id = idIn

Page 22: Composite Objects Learning Outcomes At the end of this lecture you should be able to: Identify when it is appropriate to use a composite object type Use

Specifying a findNext function

findNext( )

pre

post

qIn : Process* pos :

qIn(pos).status = <READY>

i {1,…,pos-1} qIn(i).status = <READY>

p elems qIn p.status = <READY>

Page 23: Composite Objects Learning Outcomes At the end of this lecture you should be able to: Identify when it is appropriate to use a composite object type Use

remove(qIn : Process*, posIn : ) qOut : Process*

pre posIn inds qIn

post qOut = qIn(1,…, posIn-1) ^ qIn(posIn+1,…,len qIn)

Specifying a remove function

Page 24: Composite Objects Learning Outcomes At the end of this lecture you should be able to: Identify when it is appropriate to use a composite object type Use

admit( idIn: String)

ext

pre

post

The admit operation

waiting: Process*wr

running: [String]rd

waitingwaiting = ^ [mk-Process(idIn, <READY>)]

(running = nil idIn running )

p elems waiting p.id idIn

Page 25: Composite Objects Learning Outcomes At the end of this lecture you should be able to: Identify when it is appropriate to use a composite object type Use

dispatch()

ext

pre

post

The dispatch operation

running: [String]

waiting: Process*

wr

wr

waitingwaitingrunning = (findNext( )) .id

waiting waiting waiting = remove( , findNext( ))

running = nil

p elems waiting p.status = <READY>

Page 26: Composite Objects Learning Outcomes At the end of this lecture you should be able to: Identify when it is appropriate to use a composite object type Use

timeOut()

ext

pre

post

The timeOut operation

running: [String]

waiting: Process*

wr

wr

waitingrunning

waiting = ^ [mk-Process( , <READY>)]

running = nil

running nil

Page 27: Composite Objects Learning Outcomes At the end of this lecture you should be able to: Identify when it is appropriate to use a composite object type Use

block()

ext

pre

post

The block operation

running: [String]

waiting: Process*

wr

wr

waitingrunning

waiting = ^ [mk-Process( , <BLOCKED>)]

running = nil

running nil

Page 28: Composite Objects Learning Outcomes At the end of this lecture you should be able to: Identify when it is appropriate to use a composite object type Use

wakeUp( idIn: String)

ext

pre

post

The wakeUp operation

waiting: Process*wr

waitingwaiting

waiting = † {findPos( , idIn)

mk-Process(idIn, <READY>)}

waiting(findPos(waiting, idIn)).status = <BLOCKED>

Page 29: Composite Objects Learning Outcomes At the end of this lecture you should be able to: Identify when it is appropriate to use a composite object type Use

terminate()

ext

pre

post

The terminate operation

running: [String]wr

running = nil

running nil

Page 30: Composite Objects Learning Outcomes At the end of this lecture you should be able to: Identify when it is appropriate to use a composite object type Use

The let…in clause

To improve readability expressions, local names can be given to sub-expressions and these names can then be used in place of the longer sub-expression.

These local names are created in let…in clauses.

A let…in clause takes the following general form

let name = sub-expression

in expression(name)

Page 31: Composite Objects Learning Outcomes At the end of this lecture you should be able to: Identify when it is appropriate to use a composite object type Use

Re-writing postcondition of dispatch

post running = ( findNext( ) ).id

waiting = remove( , findNext( ))

waiting waiting

waiting waiting

post let next = findNext( )

in running = ( next ) .id

waiting = remove( , next)

waiting

waiting

waiting

Page 32: Composite Objects Learning Outcomes At the end of this lecture you should be able to: Identify when it is appropriate to use a composite object type Use

Nested let…in clauses

post let pos = findPos( , idIn)

in let wakeProcess = mk-Process(idIn, <READY>)

in waiting = † {pos wakeProcess }

waiting

waiting

post waiting = † {findPos( , idIn)

mk-Process(idIn, <READY>)}

waitingwaiting