Download presentation
Presentation is loading. Please wait.
Published byBartholomew Chad Hill Modified over 9 years ago
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 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
2
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.
3
Defining Composite Object Types To define a type to be composite we use a composite type definition. TypeName:: fieldname1 fieldname2 : : Type1 : Type2
4
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
5
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
6
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
7
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
8
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)
9
The DiskScanner class DiskScanner damagedBlocks: Block [*] addBlock(Integer, Integer) removeBlock (Integer, Integer) isDamaged(Integer, Integer): Boolean getBadSectors(Integer): Integer [*]
10
Analysing the Block type further A block consists of a track and a sector number. Block track: Integer sector: Integer
11
Specifying the data model in VDM-SL types state DiskScanner of damagedBlocks: init mk-DiskScanner (dB) end Block : : track: sector: Block-set dB = { }
12
addBlock ( ) ext pre post The addBlock operation trackIn: , sectorIn: damagedBlocks: Block-set wr damagedBlocks = { mk-Block (trackIn, sectorIn)} mk-Block (trackIn, sectorIn) damagedBlocks
13
removeBlock ( ) ext pre post The removeBlock operation trackIn: , sectorIn: damagedBlocks: Block-set wr damagedBlocks = \ { mk-Block (trackIn, sectorIn)} mk-Block (trackIn, sectorIn) damagedBlocks
14
isDamaged ( ) ext pre post The isDamaged operation trackIn: , sectorIn: query: damagedBlocks: Block-set rd query mk-Block (trackIn, sectorIn) damagedBlocks TRUE
15
getBadSectors ( ) ext pre post The getBadSectors operation trackIn: list: -set damagedBlocks: Block-set rd list = { | } ?? ? b damagedBlocks b.track = trackIn b.sector TRUE
16
A process management system block wakeup timeout dispatch terminate admit new ready terminated running blocked
17
The ProcessManagement class ProcessManagament running: String waiting: Process[*] admit(String) dispatch() timeOut() block() wakeUp(String) terminate()
18
Analysing the types Process id: String status: Status A process consists of an id and status > Status READY BLOCKED The status of a process is either ready or blocked.
19
Specifying the types in VDM-SL types String= Char* = <READY> | <BLOCKED> Status Process :: id : String status : Status
20
Specifying the state in VDM-SL state ProcessManagement of running waiting inv mk-ProcessManagement (run, wait) ( ) init mk-ProcessManagement (run, wait) end : [String] : Process* run = nil wait = [ ] run = nil i 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).id the ids in the waiting queue should be unique
21
Specifying a findPos function findPos(qIn : Process*, idIn : String) pos : pre p elems qIn p.id = idIn post qIn(pos).id = idIn
22
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>
23
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
24
admit( idIn: String) ext pre post The admit operation waiting: Process* wr running: [String] rd waiting = ^ [mk-Process(idIn, )] (running = nil idIn running ) p elems waiting p.id idIn
25
dispatch() ext pre post The dispatch operation running: [String] waiting: Process* wr running = (findNext( )).id waiting = remove(, findNext( )) running = nil p elems waiting p.status = <READY>
26
timeOut() ext pre post The timeOut operation running: [String] waiting: Process* wr waiting = ^ [mk-Process(, )] running = nil running nil
27
block() ext pre post The block operation running: [String] waiting: Process* wr waiting = ^ [mk-Process(, )] running = nil running nil
28
wakeUp( idIn: String) ext pre post The wakeUp operation waiting: Process* wr waiting = † {findPos(, idIn) mk-Process(idIn, )} waiting(findPos(waiting, idIn)).status = <BLOCKED>
29
terminate() ext pre post The terminate operation running: [String] wr running = nil running nil
30
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 letname = sub-expression inexpression(name)
31
Re-writing postcondition of dispatch postrunning = ( findNext( ) ).id waiting = remove(, findNext( )) post let next = findNext( ) in running = ( next ).id waiting = remove(, next)
32
Nested let…in clauses post let pos = findPos(, idIn) in let wakeProcess = mk-Process(idIn, ) inwaiting = † {pos wakeProcess } post waiting = † {findPos(, idIn) mk-Process(idIn, )}
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.